chore(ct): do not clash internals with userland (#21774)
This commit is contained in:
		
							parent
							
								
									36a1055524
								
							
						
					
					
						commit
						d806c98009
					
				|  | @ -14,6 +14,6 @@ | |||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| export default function register( | ||||
| export default function pwRegister( | ||||
|   components: { [key: string]: any }, | ||||
| ): void | ||||
|  |  | |||
|  | @ -14,8 +14,8 @@ | |||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| import { register } from './registerSource.mjs'; | ||||
| import { pwRegister } from './registerSource.mjs'; | ||||
| 
 | ||||
| export default components => { | ||||
|   register(components); | ||||
|   pwRegister(components); | ||||
| }; | ||||
|  |  | |||
|  | @ -17,36 +17,36 @@ | |||
| // @ts-check
 | ||||
| // This file is injected into the registry as text, no dependencies are allowed.
 | ||||
| 
 | ||||
| import * as React from 'react'; | ||||
| import { createRoot } from 'react-dom/client'; | ||||
| import * as __pwReact from 'react'; | ||||
| import { createRoot as __pwCreateRoot } from 'react-dom/client'; | ||||
| 
 | ||||
| /** @typedef {import('../playwright-test/types/component').Component} Component */ | ||||
| /** @typedef {import('react').FunctionComponent} FrameworkComponent */ | ||||
| 
 | ||||
| /** @type {Map<string, FrameworkComponent>} */ | ||||
| const registry = new Map(); | ||||
| const __pwRegistry = new Map(); | ||||
| /** @type {Map<Element, import('react-dom/client').Root>} */ | ||||
| const rootRegistry = new Map(); | ||||
| const __pwRootRegistry = new Map(); | ||||
| 
 | ||||
| /** | ||||
|  * @param {{[key: string]: FrameworkComponent}} components | ||||
|  */ | ||||
| export function register(components) { | ||||
| export function pwRegister(components) { | ||||
|   for (const [name, value] of Object.entries(components)) | ||||
|     registry.set(name, value); | ||||
|     __pwRegistry.set(name, value); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * @param {Component} component | ||||
|  */ | ||||
| function render(component) { | ||||
| function __pwRender(component) { | ||||
|   if (typeof component !== 'object' || Array.isArray(component)) | ||||
|     return component; | ||||
| 
 | ||||
|   let componentFunc = registry.get(component.type); | ||||
|   let componentFunc = __pwRegistry.get(component.type); | ||||
|   if (!componentFunc) { | ||||
|     // Lookup by shorthand.
 | ||||
|     for (const [name, value] of registry) { | ||||
|     for (const [name, value] of __pwRegistry) { | ||||
|       if (component.type.endsWith(`_${name}`)) { | ||||
|         componentFunc = value; | ||||
|         break; | ||||
|  | @ -55,17 +55,17 @@ function render(component) { | |||
|   } | ||||
| 
 | ||||
|   if (!componentFunc && component.type[0].toUpperCase() === component.type[0]) | ||||
|     throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...registry.keys()]}`); | ||||
|     throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`); | ||||
| 
 | ||||
|   const componentFuncOrString = componentFunc || component.type; | ||||
| 
 | ||||
|   if (component.kind !== 'jsx') | ||||
|     throw new Error('Object mount notation is not supported'); | ||||
| 
 | ||||
|   return React.createElement(componentFuncOrString, component.props, ...component.children.map(child => { | ||||
|   return __pwReact.createElement(componentFuncOrString, component.props, ...component.children.map(child => { | ||||
|     if (typeof child === 'string') | ||||
|       return child; | ||||
|     return render(child); | ||||
|     return __pwRender(child); | ||||
|   }).filter(child => { | ||||
|     if (typeof child === 'string') | ||||
|       return !!child.trim(); | ||||
|  | @ -74,21 +74,21 @@ function render(component) { | |||
| } | ||||
| 
 | ||||
| window.playwrightMount = async (component, rootElement, hooksConfig) => { | ||||
|   let App = () => render(component); | ||||
|   let App = () => __pwRender(component); | ||||
|   for (const hook of window.__pw_hooks_before_mount || []) { | ||||
|     const wrapper = await hook({ App, hooksConfig }); | ||||
|     if (wrapper) | ||||
|       App = () => wrapper; | ||||
|   } | ||||
| 
 | ||||
|   if (rootRegistry.has(rootElement)) { | ||||
|   if (__pwRootRegistry.has(rootElement)) { | ||||
|     throw new Error( | ||||
|         'Attempting to mount a component into an container that already has a React root' | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   const root = createRoot(rootElement); | ||||
|   rootRegistry.set(rootElement, root); | ||||
|   const root = __pwCreateRoot(rootElement); | ||||
|   __pwRootRegistry.set(rootElement, root); | ||||
|   root.render(App()); | ||||
| 
 | ||||
|   for (const hook of window.__pw_hooks_after_mount || []) | ||||
|  | @ -96,18 +96,18 @@ window.playwrightMount = async (component, rootElement, hooksConfig) => { | |||
| }; | ||||
| 
 | ||||
| window.playwrightUnmount = async rootElement => { | ||||
|   const root = rootRegistry.get(rootElement); | ||||
|   const root = __pwRootRegistry.get(rootElement); | ||||
|   if (root === undefined) | ||||
|     throw new Error('Component was not mounted'); | ||||
| 
 | ||||
|   root.unmount(); | ||||
|   rootRegistry.delete(rootElement); | ||||
|   __pwRootRegistry.delete(rootElement); | ||||
| }; | ||||
| 
 | ||||
| window.playwrightUpdate = async (rootElement, component) => { | ||||
|   const root = rootRegistry.get(rootElement); | ||||
|   const root = __pwRootRegistry.get(rootElement); | ||||
|   if (root === undefined) | ||||
|     throw new Error('Component was not mounted'); | ||||
| 
 | ||||
|   root.render(render(/** @type {Component} */ (component))); | ||||
|   root.render(__pwRender(/** @type {Component} */ (component))); | ||||
| }; | ||||
|  |  | |||
|  | @ -14,6 +14,6 @@ | |||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| export default function register( | ||||
| export default function pwRegister( | ||||
|   components: { [key: string]: any }, | ||||
| ): void | ||||
|  |  | |||
|  | @ -14,8 +14,8 @@ | |||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| import { register } from './registerSource.mjs'; | ||||
| import { pwRegister } from './registerSource.mjs'; | ||||
| 
 | ||||
| export default components => { | ||||
|   register(components); | ||||
|   pwRegister(components); | ||||
| }; | ||||
|  |  | |||
|  | @ -17,34 +17,35 @@ | |||
| // @ts-check
 | ||||
| // This file is injected into the registry as text, no dependencies are allowed.
 | ||||
| 
 | ||||
| import React from 'react'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| // Don't clash with the user land.
 | ||||
| import __pwReact from 'react'; | ||||
| import __pwReactDOM from 'react-dom'; | ||||
| 
 | ||||
| /** @typedef {import('../playwright-test/types/component').Component} Component */ | ||||
| /** @typedef {import('react').FunctionComponent} FrameworkComponent */ | ||||
| 
 | ||||
| /** @type {Map<string, FrameworkComponent>} */ | ||||
| const registry = new Map(); | ||||
| const __pwRegistry = new Map(); | ||||
| 
 | ||||
| /** | ||||
|  * @param {{[key: string]: FrameworkComponent}} components | ||||
|  */ | ||||
| export function register(components) { | ||||
| export function pwRegister(components) { | ||||
|   for (const [name, value] of Object.entries(components)) | ||||
|     registry.set(name, value); | ||||
|     __pwRegistry.set(name, value); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * @param {Component} component | ||||
|  */ | ||||
| function render(component) { | ||||
| function __pwRender(component) { | ||||
|   if (typeof component !== 'object' || Array.isArray(component)) | ||||
|     return component; | ||||
| 
 | ||||
|   let componentFunc = registry.get(component.type); | ||||
|   let componentFunc = __pwRegistry.get(component.type); | ||||
|   if (!componentFunc) { | ||||
|     // Lookup by shorthand.
 | ||||
|     for (const [name, value] of registry) { | ||||
|     for (const [name, value] of __pwRegistry) { | ||||
|       if (component.type.endsWith(`_${name}`)) { | ||||
|         componentFunc = value; | ||||
|         break; | ||||
|  | @ -53,17 +54,17 @@ function render(component) { | |||
|   } | ||||
| 
 | ||||
|   if (!componentFunc && component.type[0].toUpperCase() === component.type[0]) | ||||
|     throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...registry.keys()]}`); | ||||
|     throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`); | ||||
| 
 | ||||
|   const componentFuncOrString = componentFunc || component.type; | ||||
| 
 | ||||
|   if (component.kind !== 'jsx') | ||||
|     throw new Error('Object mount notation is not supported'); | ||||
| 
 | ||||
|   return React.createElement(componentFuncOrString, component.props, ...component.children.map(child => { | ||||
|   return __pwReact.createElement(componentFuncOrString, component.props, ...component.children.map(child => { | ||||
|     if (typeof child === 'string') | ||||
|       return child; | ||||
|     return render(child); | ||||
|     return __pwRender(child); | ||||
|   }).filter(child => { | ||||
|     if (typeof child === 'string') | ||||
|       return !!child.trim(); | ||||
|  | @ -72,24 +73,24 @@ function render(component) { | |||
| } | ||||
| 
 | ||||
| window.playwrightMount = async (component, rootElement, hooksConfig) => { | ||||
|   let App = () => render(component); | ||||
|   let App = () => __pwRender(component); | ||||
|   for (const hook of window.__pw_hooks_before_mount || []) { | ||||
|     const wrapper = await hook({ App, hooksConfig }); | ||||
|     if (wrapper) | ||||
|       App = () => wrapper; | ||||
|   } | ||||
| 
 | ||||
|   ReactDOM.render(App(), rootElement); | ||||
|   __pwReactDOM.render(App(), rootElement); | ||||
| 
 | ||||
|   for (const hook of window.__pw_hooks_after_mount || []) | ||||
|     await hook({ hooksConfig }); | ||||
| }; | ||||
| 
 | ||||
| window.playwrightUnmount = async rootElement => { | ||||
|   if (!ReactDOM.unmountComponentAtNode(rootElement)) | ||||
|   if (!__pwReactDOM.unmountComponentAtNode(rootElement)) | ||||
|     throw new Error('Component was not mounted'); | ||||
| }; | ||||
| 
 | ||||
| window.playwrightUpdate = async (rootElement, component) => { | ||||
|   ReactDOM.render(render(/** @type {Component} */(component)), rootElement); | ||||
|   __pwReactDOM.render(__pwRender(/** @type {Component} */(component)), rootElement); | ||||
| }; | ||||
|  |  | |||
|  | @ -14,6 +14,6 @@ | |||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| export default function register( | ||||
| export default function pwRegister( | ||||
|   components: { [key: string]: any }, | ||||
| ): void | ||||
|  |  | |||
|  | @ -14,8 +14,8 @@ | |||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| import { register } from './registerSource.mjs'; | ||||
| import { pwRegister } from './registerSource.mjs'; | ||||
| 
 | ||||
| export default components => { | ||||
|   register(components); | ||||
|   pwRegister(components); | ||||
| }; | ||||
|  |  | |||
|  | @ -17,38 +17,38 @@ | |||
| // @ts-check
 | ||||
| // This file is injected into the registry as text, no dependencies are allowed.
 | ||||
| 
 | ||||
| import { render as solidRender, createComponent as solidCreateComponent } from 'solid-js/web'; | ||||
| import h from 'solid-js/h'; | ||||
| import { render as __pwSolidRender, createComponent as __pwSolidCreateComponent } from 'solid-js/web'; | ||||
| import __pwH from 'solid-js/h'; | ||||
| 
 | ||||
| /** @typedef {import('../playwright-test/types/component').Component} Component */ | ||||
| /** @typedef {() => import('solid-js').JSX.Element} FrameworkComponent */ | ||||
| 
 | ||||
| /** @type {Map<string, FrameworkComponent>} */ | ||||
| const registry = new Map(); | ||||
| const __pwRegistry = new Map(); | ||||
| 
 | ||||
| /** | ||||
|  * @param {{[key: string]: FrameworkComponent}} components | ||||
|  */ | ||||
| export function register(components) { | ||||
| export function pwRegister(components) { | ||||
|   for (const [name, value] of Object.entries(components)) | ||||
|     registry.set(name, value); | ||||
|     __pwRegistry.set(name, value); | ||||
| } | ||||
| 
 | ||||
| function createChild(child) { | ||||
|   return typeof child === 'string' ? child : createComponent(child); | ||||
| function __pwCreateChild(child) { | ||||
|   return typeof child === 'string' ? child : __pwCreateComponent(child); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * @param {Component} component | ||||
|  */ | ||||
| function createComponent(component) { | ||||
| function __pwCreateComponent(component) { | ||||
|   if (typeof component !== 'object' || Array.isArray(component)) | ||||
|     return component; | ||||
| 
 | ||||
|   let Component = registry.get(component.type); | ||||
|   let Component = __pwRegistry.get(component.type); | ||||
|   if (!Component) { | ||||
|     // Lookup by shorthand.
 | ||||
|     for (const [name, value] of registry) { | ||||
|     for (const [name, value] of __pwRegistry) { | ||||
|       if (component.type.endsWith(`_${name}`)) { | ||||
|         Component = value; | ||||
|         break; | ||||
|  | @ -57,43 +57,43 @@ function createComponent(component) { | |||
|   } | ||||
| 
 | ||||
|   if (!Component && component.type[0].toUpperCase() === component.type[0]) | ||||
|     throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...registry.keys()]}`); | ||||
|     throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`); | ||||
| 
 | ||||
|   if (component.kind !== 'jsx') | ||||
|     throw new Error('Object mount notation is not supported'); | ||||
| 
 | ||||
|   const children = component.children.reduce((/** @type {any[]} */ children, current) => { | ||||
|     const child = createChild(current); | ||||
|     const child = __pwCreateChild(current); | ||||
|     if (typeof child !== 'string' || !!child.trim()) | ||||
|       children.push(child); | ||||
|     return children; | ||||
|   }, []); | ||||
| 
 | ||||
|   if (!Component) | ||||
|     return h(component.type, component.props, children); | ||||
|     return __pwH(component.type, component.props, children); | ||||
| 
 | ||||
|   return solidCreateComponent(Component, { ...component.props, children }); | ||||
|   return __pwSolidCreateComponent(Component, { ...component.props, children }); | ||||
| } | ||||
| 
 | ||||
| const unmountKey = Symbol('unmountKey'); | ||||
| const __pwUnmountKey = Symbol('unmountKey'); | ||||
| 
 | ||||
| window.playwrightMount = async (component, rootElement, hooksConfig) => { | ||||
|   let App = () => createComponent(component); | ||||
|   let App = () => __pwCreateComponent(component); | ||||
|   for (const hook of window.__pw_hooks_before_mount || []) { | ||||
|     const wrapper = await hook({ App, hooksConfig }); | ||||
|     if (wrapper) | ||||
|       App = () => wrapper; | ||||
|   } | ||||
| 
 | ||||
|   const unmount = solidRender(App, rootElement); | ||||
|   rootElement[unmountKey] = unmount; | ||||
|   const unmount = __pwSolidRender(App, rootElement); | ||||
|   rootElement[__pwUnmountKey] = unmount; | ||||
| 
 | ||||
|   for (const hook of window.__pw_hooks_after_mount || []) | ||||
|     await hook({ hooksConfig }); | ||||
| }; | ||||
| 
 | ||||
| window.playwrightUnmount = async rootElement => { | ||||
|   const unmount = rootElement[unmountKey]; | ||||
|   const unmount = rootElement[__pwUnmountKey]; | ||||
|   if (!unmount) | ||||
|     throw new Error('Component was not mounted'); | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,8 +14,8 @@ | |||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| import { register } from './registerSource.mjs'; | ||||
| import { pwRegister } from './registerSource.mjs'; | ||||
| 
 | ||||
| export default components => { | ||||
|   register(components); | ||||
|   pwRegister(components); | ||||
| }; | ||||
|  |  | |||
|  | @ -18,28 +18,28 @@ | |||
| 
 | ||||
| // This file is injected into the registry as text, no dependencies are allowed.
 | ||||
| 
 | ||||
| import { detach, insert, noop } from 'svelte/internal'; | ||||
| import { detach as __pwDetach, insert as __pwInsert, noop as __pwNoop } from 'svelte/internal'; | ||||
| 
 | ||||
| /** @typedef {import('../playwright-test/types/component').Component} Component */ | ||||
| /** @typedef {any} FrameworkComponent */ | ||||
| /** @typedef {import('svelte').SvelteComponent} SvelteComponent */ | ||||
| 
 | ||||
| /** @type {Map<string, FrameworkComponent>} */ | ||||
| const registry = new Map(); | ||||
| const __pwRegistry = new Map(); | ||||
| 
 | ||||
| /** | ||||
|  * @param {{[key: string]: FrameworkComponent}} components | ||||
|  */ | ||||
| export function register(components) { | ||||
| export function pwRegister(components) { | ||||
|   for (const [name, value] of Object.entries(components)) | ||||
|     registry.set(name, value); | ||||
|     __pwRegistry.set(name, value); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * TODO: remove this function when the following issue is fixed: | ||||
|  * https://github.com/sveltejs/svelte/issues/2588
 | ||||
|  */ | ||||
| function createSlots(slots) { | ||||
| function __pwCreateSlots(slots) { | ||||
|   const svelteSlots = {}; | ||||
| 
 | ||||
|   for (const slotName in slots) { | ||||
|  | @ -52,27 +52,27 @@ function createSlots(slots) { | |||
|   function createSlotFn(element) { | ||||
|     return function() { | ||||
|       return { | ||||
|         c: noop, | ||||
|         c: __pwNoop, | ||||
|         m: function mount(target, anchor) { | ||||
|           insert(target, element, anchor); | ||||
|           __pwInsert(target, element, anchor); | ||||
|         }, | ||||
|         d: function destroy(detaching) { | ||||
|           if (detaching) detach(element); | ||||
|           if (detaching) __pwDetach(element); | ||||
|         }, | ||||
|         l: noop, | ||||
|         l: __pwNoop, | ||||
|       }; | ||||
|     }; | ||||
|   } | ||||
|   return svelteSlots; | ||||
| } | ||||
| 
 | ||||
| const svelteComponentKey = Symbol('svelteComponent'); | ||||
| const __pwSvelteComponentKey = Symbol('svelteComponent'); | ||||
| 
 | ||||
| window.playwrightMount = async (component, rootElement, hooksConfig) => { | ||||
|   let componentCtor = registry.get(component.type); | ||||
|   let componentCtor = __pwRegistry.get(component.type); | ||||
|   if (!componentCtor) { | ||||
|     // Lookup by shorthand.
 | ||||
|     for (const [name, value] of registry) { | ||||
|     for (const [name, value] of __pwRegistry) { | ||||
|       if (component.type.endsWith(`_${name}_svelte`)) { | ||||
|         componentCtor = value; | ||||
|         break; | ||||
|  | @ -81,7 +81,7 @@ window.playwrightMount = async (component, rootElement, hooksConfig) => { | |||
|   } | ||||
| 
 | ||||
|   if (!componentCtor) | ||||
|     throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...registry.keys()]}`); | ||||
|     throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`); | ||||
| 
 | ||||
|   if (component.kind !== 'object') | ||||
|     throw new Error('JSX mount notation is not supported'); | ||||
|  | @ -94,11 +94,11 @@ window.playwrightMount = async (component, rootElement, hooksConfig) => { | |||
|     target: rootElement, | ||||
|     props: { | ||||
|       ...component.options?.props, | ||||
|       $$slots: createSlots(component.options?.slots), | ||||
|       $$slots: __pwCreateSlots(component.options?.slots), | ||||
|       $$scope: {}, | ||||
|     } | ||||
|   })); | ||||
|   rootElement[svelteComponentKey] = svelteComponent; | ||||
|   rootElement[__pwSvelteComponentKey] = svelteComponent; | ||||
| 
 | ||||
|   for (const [key, listener] of Object.entries(component.options?.on || {})) | ||||
|     svelteComponent.$on(key, event => listener(event.detail)); | ||||
|  | @ -108,14 +108,14 @@ window.playwrightMount = async (component, rootElement, hooksConfig) => { | |||
| }; | ||||
| 
 | ||||
| window.playwrightUnmount = async rootElement => { | ||||
|   const svelteComponent = /** @type {SvelteComponent} */ (rootElement[svelteComponentKey]); | ||||
|   const svelteComponent = /** @type {SvelteComponent} */ (rootElement[__pwSvelteComponentKey]); | ||||
|   if (!svelteComponent) | ||||
|     throw new Error('Component was not mounted'); | ||||
|   svelteComponent.$destroy(); | ||||
| }; | ||||
| 
 | ||||
| window.playwrightUpdate = async (rootElement, component) => { | ||||
|   const svelteComponent = /** @type {SvelteComponent} */ (rootElement[svelteComponentKey]); | ||||
|   const svelteComponent = /** @type {SvelteComponent} */ (rootElement[__pwSvelteComponentKey]); | ||||
|   if (!svelteComponent) | ||||
|     throw new Error('Component was not mounted'); | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ | |||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| export default function register( | ||||
| export default function pwRegister( | ||||
|   components: { [key: string]: any }, | ||||
|   options?: { | ||||
|     createApp: any, | ||||
|  |  | |||
|  | @ -14,8 +14,8 @@ | |||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| import { register } from './registerSource.mjs'; | ||||
| import { pwRegister } from './registerSource.mjs'; | ||||
| 
 | ||||
| export default components => { | ||||
|   register(components); | ||||
|   pwRegister(components); | ||||
| }; | ||||
|  |  | |||
|  | @ -17,32 +17,32 @@ | |||
| 
 | ||||
| // This file is injected into the registry as text, no dependencies are allowed.
 | ||||
| 
 | ||||
| import { createApp, setDevtoolsHook, h } from 'vue'; | ||||
| import { compile } from '@vue/compiler-dom'; | ||||
| import * as Vue from 'vue'; | ||||
| import { createApp as __pwCreateApp, setDevtoolsHook as __pwSetDevtoolsHook, h as __pwH } from 'vue'; | ||||
| import { compile as __pwCompile } from '@vue/compiler-dom'; | ||||
| import * as __pwVue from 'vue'; | ||||
| 
 | ||||
| /** @typedef {import('@playwright/test/types/component').Component} Component */ | ||||
| /** @typedef {import('vue').Component} FrameworkComponent */ | ||||
| 
 | ||||
| /** @type {Map<string, FrameworkComponent>} */ | ||||
| const registry = new Map(); | ||||
| const __pwRegistry = new Map(); | ||||
| 
 | ||||
| /** | ||||
|  * @param {{[key: string]: FrameworkComponent}} components | ||||
|  */ | ||||
| export function register(components) { | ||||
| export function pwRegister(components) { | ||||
|   for (const [name, value] of Object.entries(components)) | ||||
|     registry.set(name, value); | ||||
|     __pwRegistry.set(name, value); | ||||
| } | ||||
| 
 | ||||
| const allListeners = new Map(); | ||||
| const __pwAllListeners = new Map(); | ||||
| 
 | ||||
| /** | ||||
|  * @param {Component | string} child | ||||
|  * @returns {import('vue').VNode | string} | ||||
|  */ | ||||
| function createChild(child) { | ||||
|   return typeof child === 'string' ? child : createWrapper(child); | ||||
| function __pwCreateChild(child) { | ||||
|   return typeof child === 'string' ? child : __pwCreateWrapper(child); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  | @ -57,7 +57,7 @@ function createChild(child) { | |||
|  * | ||||
|  * @param {string} html | ||||
|  */ | ||||
| function createSlot(html) { | ||||
| function __pwCreateSlot(html) { | ||||
|   let template = html.trim(); | ||||
|   const hasWrappingTemplate = template && template.startsWith('<template'); | ||||
| 
 | ||||
|  | @ -65,12 +65,12 @@ function createSlot(html) { | |||
|   if (!hasWrappingTemplate) | ||||
|     template = `<template #default="params">${template}</template>`; | ||||
| 
 | ||||
|   const { code } = compile(`<transition>${template}</transition>`, { | ||||
|   const { code } = __pwCompile(`<transition>${template}</transition>`, { | ||||
|     mode: 'function', | ||||
|     prefixIdentifiers: false | ||||
|   }); | ||||
|   const createRenderFunction = new Function('Vue', code); | ||||
|   const renderFn = createRenderFunction(Vue); | ||||
|   const renderFn = createRenderFunction(__pwVue); | ||||
|   return (ctx = {}) => { | ||||
|     const result = renderFn(ctx); | ||||
|     const slotName = Object.keys(result.children)[0]; | ||||
|  | @ -78,12 +78,12 @@ function createSlot(html) { | |||
|   }; | ||||
| } | ||||
| 
 | ||||
| function slotToFunction(slot) { | ||||
| function __pwSlotToFunction(slot) { | ||||
|   if (typeof slot === 'string') | ||||
|     return createSlot(slot)(); | ||||
|     return __pwCreateSlot(slot)(); | ||||
| 
 | ||||
|   if (Array.isArray(slot)) | ||||
|     return slot.map(slot => createSlot(slot)()); | ||||
|     return slot.map(slot => __pwCreateSlot(slot)()); | ||||
| 
 | ||||
|   throw Error(`Invalid slot received.`); | ||||
| } | ||||
|  | @ -91,17 +91,17 @@ function slotToFunction(slot) { | |||
| /** | ||||
|  * @param {Component} component | ||||
|  */ | ||||
| function createComponent(component) { | ||||
| function __pwCreateComponent(component) { | ||||
|   if (typeof component === 'string') | ||||
|     return component; | ||||
| 
 | ||||
|   /** | ||||
|    * @type {import('vue').Component | string | undefined} | ||||
|    */ | ||||
|   let componentFunc = registry.get(component.type); | ||||
|   let componentFunc = __pwRegistry.get(component.type); | ||||
|   if (!componentFunc) { | ||||
|     // Lookup by shorthand.
 | ||||
|     for (const [name, value] of registry) { | ||||
|     for (const [name, value] of __pwRegistry) { | ||||
|       if (component.type.endsWith(`_${name}_vue`)) { | ||||
|         componentFunc = value; | ||||
|         break; | ||||
|  | @ -110,7 +110,7 @@ function createComponent(component) { | |||
|   } | ||||
| 
 | ||||
|   if (!componentFunc && component.type[0].toUpperCase() === component.type[0]) | ||||
|     throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...registry.keys()]}`); | ||||
|     throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`); | ||||
| 
 | ||||
|   componentFunc = componentFunc || component.type; | ||||
| 
 | ||||
|  | @ -131,9 +131,9 @@ function createComponent(component) { | |||
|       if (typeof child !== 'string' && child.type === 'template' && child.kind === 'jsx') { | ||||
|         const slotProperty = Object.keys(child.props).find(k => k.startsWith('v-slot:')); | ||||
|         const slot = slotProperty ? slotProperty.substring('v-slot:'.length) : 'default'; | ||||
|         slots[slot] = child.children.map(createChild); | ||||
|         slots[slot] = child.children.map(__pwCreateChild); | ||||
|       } else { | ||||
|         children.push(createChild(child)); | ||||
|         children.push(__pwCreateChild(child)); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|  | @ -154,9 +154,9 @@ function createComponent(component) { | |||
|     // Vue test util syntax.
 | ||||
|     for (const [key, value] of Object.entries(component.options?.slots || {})) { | ||||
|       if (key === 'default') | ||||
|         children.push(slotToFunction(value)); | ||||
|         children.push(__pwSlotToFunction(value)); | ||||
|       else | ||||
|         slots[key] = slotToFunction(value); | ||||
|         slots[key] = __pwSlotToFunction(value); | ||||
|     } | ||||
|     props = component.options?.props || {}; | ||||
|     for (const [key, value] of Object.entries(component.options?.on || {})) | ||||
|  | @ -175,7 +175,7 @@ function createComponent(component) { | |||
|   return { Component: componentFunc, props, slots: lastArg, listeners }; | ||||
| } | ||||
| 
 | ||||
| function wrapFunctions(slots) { | ||||
| function __pwWrapFunctions(slots) { | ||||
|   const slotsWithRenderFunctions = {}; | ||||
|   if (!Array.isArray(slots)) { | ||||
|     for (const [key, value] of Object.entries(slots || {})) | ||||
|  | @ -190,23 +190,23 @@ function wrapFunctions(slots) { | |||
|  * @param {Component} component | ||||
|  * @returns {import('vue').VNode | string} | ||||
|  */ | ||||
| function createWrapper(component) { | ||||
|   const { Component, props, slots, listeners } = createComponent(component); | ||||
| function __pwCreateWrapper(component) { | ||||
|   const { Component, props, slots, listeners } = __pwCreateComponent(component); | ||||
|   // @ts-ignore
 | ||||
|   const wrapper = h(Component, props, slots); | ||||
|   allListeners.set(wrapper, listeners); | ||||
|   const wrapper = __pwH(Component, props, slots); | ||||
|   __pwAllListeners.set(wrapper, listeners); | ||||
|   return wrapper; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * @returns {any} | ||||
|  */ | ||||
| function createDevTools() { | ||||
| function __pwCreateDevTools() { | ||||
|   return { | ||||
|     emit(eventType, ...payload) { | ||||
|       if (eventType === 'component:emit') { | ||||
|         const [, componentVM, event, eventArgs] = payload; | ||||
|         for (const [wrapper, listeners] of allListeners) { | ||||
|         for (const [wrapper, listeners] of __pwAllListeners) { | ||||
|           if (wrapper.component !== componentVM) | ||||
|             continue; | ||||
|           const listener = listeners[event]; | ||||
|  | @ -219,44 +219,44 @@ function createDevTools() { | |||
|   }; | ||||
| } | ||||
| 
 | ||||
| const appKey = Symbol('appKey'); | ||||
| const wrapperKey = Symbol('wrapperKey'); | ||||
| const __pwAppKey = Symbol('appKey'); | ||||
| const __pwWrapperKey = Symbol('wrapperKey'); | ||||
| 
 | ||||
| window.playwrightMount = async (component, rootElement, hooksConfig) => { | ||||
|   const app = createApp({ | ||||
|   const app = __pwCreateApp({ | ||||
|     render: () => { | ||||
|       const wrapper = createWrapper(component); | ||||
|       rootElement[wrapperKey] = wrapper; | ||||
|       const wrapper = __pwCreateWrapper(component); | ||||
|       rootElement[__pwWrapperKey] = wrapper; | ||||
|       return wrapper; | ||||
|     } | ||||
|   }); | ||||
|   setDevtoolsHook(createDevTools(), {}); | ||||
|   __pwSetDevtoolsHook(__pwCreateDevTools(), {}); | ||||
| 
 | ||||
|   for (const hook of window.__pw_hooks_before_mount || []) | ||||
|     await hook({ app, hooksConfig }); | ||||
|   const instance = app.mount(rootElement); | ||||
|   rootElement[appKey] = app; | ||||
|   rootElement[__pwAppKey] = app; | ||||
| 
 | ||||
|   for (const hook of window.__pw_hooks_after_mount || []) | ||||
|     await hook({ app, hooksConfig, instance }); | ||||
| }; | ||||
| 
 | ||||
| window.playwrightUnmount = async rootElement => { | ||||
|   const app = /** @type {import('vue').App} */ (rootElement[appKey]); | ||||
|   const app = /** @type {import('vue').App} */ (rootElement[__pwAppKey]); | ||||
|   if (!app) | ||||
|     throw new Error('Component was not mounted'); | ||||
|   app.unmount(); | ||||
| }; | ||||
| 
 | ||||
| window.playwrightUpdate = async (rootElement, options) => { | ||||
|   const wrapper = rootElement[wrapperKey]; | ||||
|   const wrapper = rootElement[__pwWrapperKey]; | ||||
|   if (!wrapper) | ||||
|     throw new Error('Component was not mounted'); | ||||
| 
 | ||||
|   const { slots, listeners, props } = createComponent(options); | ||||
|   const { slots, listeners, props } = __pwCreateComponent(options); | ||||
| 
 | ||||
|   wrapper.component.slots = wrapFunctions(slots); | ||||
|   allListeners.set(wrapper, listeners); | ||||
|   wrapper.component.slots = __pwWrapFunctions(slots); | ||||
|   __pwAllListeners.set(wrapper, listeners); | ||||
| 
 | ||||
|   for (const [key, value] of Object.entries(props)) | ||||
|     wrapper.component.props[key] = value; | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ | |||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| export default function register( | ||||
| export default function pwRegister( | ||||
|   components: { [key: string]: any }, | ||||
|   options?: { | ||||
|     createApp: any, | ||||
|  |  | |||
|  | @ -14,8 +14,8 @@ | |||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| import { register } from './registerSource.mjs'; | ||||
| import { pwRegister } from './registerSource.mjs'; | ||||
| 
 | ||||
| export default components => { | ||||
|   register(components); | ||||
|   pwRegister(components); | ||||
| }; | ||||
|  |  | |||
|  | @ -18,27 +18,27 @@ | |||
| 
 | ||||
| // This file is injected into the registry as text, no dependencies are allowed.
 | ||||
| 
 | ||||
| import Vue, { h } from 'vue'; | ||||
| import __pwVue, { h as __pwH } from 'vue'; | ||||
| 
 | ||||
| /** @typedef {import('../playwright-test/types/component').Component} Component */ | ||||
| /** @typedef {import('vue').Component} FrameworkComponent */ | ||||
| 
 | ||||
| /** @type {Map<string, FrameworkComponent>} */ | ||||
| const registry = new Map(); | ||||
| const __pwRegistry = new Map(); | ||||
| 
 | ||||
| /** | ||||
|  * @param {{[key: string]: FrameworkComponent}} components | ||||
|  */ | ||||
| export function register(components) { | ||||
| export function pwRegister(components) { | ||||
|   for (const [name, value] of Object.entries(components)) | ||||
|     registry.set(name, value); | ||||
|     __pwRegistry.set(name, value); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * @param {Component | string} child | ||||
|  */ | ||||
| function createChild(child) { | ||||
|   return typeof child === 'string' ? child : createWrapper(child); | ||||
| function __pwCreateChild(child) { | ||||
|   return typeof child === 'string' ? child : __pwCreateWrapper(child); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  | @ -48,7 +48,7 @@ function createChild(child) { | |||
|  * @param {string} key | ||||
|  * @return {boolean} | ||||
|  */ | ||||
| function componentHasKeyInProps(Component, key) { | ||||
| function __pwComponentHasKeyInProps(Component, key) { | ||||
|   if (Array.isArray(Component.props)) | ||||
|     return Component.props.includes(key); | ||||
| 
 | ||||
|  | @ -58,14 +58,14 @@ function componentHasKeyInProps(Component, key) { | |||
| /** | ||||
|  * @param {Component} component | ||||
|  */ | ||||
| function createComponent(component) { | ||||
| function __pwCreateComponent(component) { | ||||
|   /** | ||||
|    * @type {import('vue').Component | string | undefined} | ||||
|    */ | ||||
|   let componentFunc = registry.get(component.type); | ||||
|   let componentFunc = __pwRegistry.get(component.type); | ||||
|   if (!componentFunc) { | ||||
|     // Lookup by shorthand.
 | ||||
|     for (const [name, value] of registry) { | ||||
|     for (const [name, value] of __pwRegistry) { | ||||
|       if (component.type.endsWith(`_${name}_vue`)) { | ||||
|         componentFunc = value; | ||||
|         break; | ||||
|  | @ -74,7 +74,7 @@ function createComponent(component) { | |||
|   } | ||||
| 
 | ||||
|   if (!componentFunc && component.type[0].toUpperCase() === component.type[0]) | ||||
|     throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...registry.keys()]}`); | ||||
|     throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`); | ||||
| 
 | ||||
|   componentFunc = componentFunc || component.type; | ||||
| 
 | ||||
|  | @ -97,9 +97,9 @@ function createComponent(component) { | |||
|       if (typeof child !== 'string' && child.type === 'template' && child.kind === 'jsx') { | ||||
|         const slotProperty = Object.keys(child.props).find(k => k.startsWith('v-slot:')); | ||||
|         const slot = slotProperty ? slotProperty.substring('v-slot:'.length) : 'default'; | ||||
|         nodeData.scopedSlots[slot] = () => child.children.map(c => createChild(c)); | ||||
|         nodeData.scopedSlots[slot] = () => child.children.map(c => __pwCreateChild(c)); | ||||
|       } else { | ||||
|         children.push(createChild(child)); | ||||
|         children.push(__pwCreateChild(child)); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|  | @ -108,7 +108,7 @@ function createComponent(component) { | |||
|         const event = key.substring('v-on:'.length); | ||||
|         nodeData.on[event] = value; | ||||
|       } else { | ||||
|         if (isVueComponent && componentHasKeyInProps(componentFunc, key)) | ||||
|         if (isVueComponent && __pwComponentHasKeyInProps(componentFunc, key)) | ||||
|           nodeData.props[key] = value; | ||||
|         else | ||||
|           nodeData.attrs[key] = value; | ||||
|  | @ -120,7 +120,7 @@ function createComponent(component) { | |||
|     // Vue test util syntax.
 | ||||
|     const options = component.options || {}; | ||||
|     for (const [key, value] of Object.entries(options.slots || {})) { | ||||
|       const list = (Array.isArray(value) ? value : [value]).map(v => createChild(v)); | ||||
|       const list = (Array.isArray(value) ? value : [value]).map(v => __pwCreateChild(v)); | ||||
|       if (key === 'default') | ||||
|         children.push(...list); | ||||
|       else | ||||
|  | @ -147,9 +147,9 @@ function createComponent(component) { | |||
|  * @param {Component} component | ||||
|  * @returns {import('vue').VNode} | ||||
|  */ | ||||
| function createWrapper(component) { | ||||
|   const { Component, nodeData, slots } = createComponent(component); | ||||
|   const wrapper = h(Component, nodeData, slots); | ||||
| function __pwCreateWrapper(component) { | ||||
|   const { Component, nodeData, slots } = __pwCreateComponent(component); | ||||
|   const wrapper = __pwH(Component, nodeData, slots); | ||||
|   return wrapper; | ||||
| } | ||||
| 
 | ||||
|  | @ -159,12 +159,12 @@ const wrapperKey = Symbol('wrapperKey'); | |||
| window.playwrightMount = async (component, rootElement, hooksConfig) => { | ||||
|   let options = {}; | ||||
|   for (const hook of window.__pw_hooks_before_mount || []) | ||||
|     options = await hook({ hooksConfig, Vue }); | ||||
|     options = await hook({ hooksConfig, Vue: __pwVue }); | ||||
| 
 | ||||
|   const instance = new Vue({ | ||||
|   const instance = new __pwVue({ | ||||
|     ...options, | ||||
|     render: () => { | ||||
|       const wrapper = createWrapper(component); | ||||
|       const wrapper = __pwCreateWrapper(component); | ||||
|       /** @type {any} */ (rootElement)[wrapperKey] = wrapper; | ||||
|       return wrapper; | ||||
|     }, | ||||
|  | @ -190,7 +190,7 @@ window.playwrightUpdate = async (element, options) => { | |||
|     throw new Error('Component was not mounted'); | ||||
| 
 | ||||
|   const component = wrapper.componentInstance; | ||||
|   const { nodeData, slots } = createComponent(options); | ||||
|   const { nodeData, slots } = __pwCreateComponent(options); | ||||
| 
 | ||||
|   for (const [name, value] of Object.entries(nodeData.on || {})) { | ||||
|     component.$on(name, value); | ||||
|  |  | |||
|  | @ -307,8 +307,9 @@ function vitePlugin(registerSource: string, relativeTemplateDir: string, buildIn | |||
|       const indexTs = path.join(relativeTemplateDir, 'index.ts'); | ||||
|       const indexTsx = path.join(relativeTemplateDir, 'index.tsx'); | ||||
|       const indexJs = path.join(relativeTemplateDir, 'index.js'); | ||||
|       const indexJsx = path.join(relativeTemplateDir, 'index.jsx'); | ||||
|       const idResolved = path.resolve(id); | ||||
|       if (!idResolved.endsWith(indexTs) && !idResolved.endsWith(indexTsx) && !idResolved.endsWith(indexJs)) | ||||
|       if (!idResolved.endsWith(indexTs) && !idResolved.endsWith(indexTsx) && !idResolved.endsWith(indexJs) && !idResolved.endsWith(indexJsx)) | ||||
|         return; | ||||
| 
 | ||||
|       const folder = path.dirname(id); | ||||
|  | @ -323,7 +324,7 @@ function vitePlugin(registerSource: string, relativeTemplateDir: string, buildIn | |||
|           lines.push(`import ${alias} from '${importPath}';`); | ||||
|       } | ||||
| 
 | ||||
|       lines.push(`register({ ${[...componentRegistry.keys()].join(',\n  ')} });`); | ||||
|       lines.push(`pwRegister({ ${[...componentRegistry.keys()].join(',\n  ')} });`); | ||||
|       return { | ||||
|         code: lines.join('\n'), | ||||
|         map: { mappings: '' } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue