mirror of
https://github.com/microsoft/playwright.git
synced 2025-01-05 19:04:43 +03:00
feat(ct): code split for better performance and isolation (#22494)
This commit is contained in:
parent
d34c4e99f5
commit
44e56d2404
@ -322,9 +322,9 @@ function vitePlugin(registerSource: string, relativeTemplateDir: string, buildIn
|
||||
for (const [alias, value] of componentRegistry) {
|
||||
const importPath = value.isModuleOrAlias ? value.importPath : './' + path.relative(folder, value.importPath).replace(/\\/g, '/');
|
||||
if (value.importedName)
|
||||
lines.push(`import { ${value.importedName} as ${alias} } from '${importPath}';`);
|
||||
lines.push(`const ${alias} = () => import('${importPath}').then((mod) => mod.${value.importedName});`);
|
||||
else
|
||||
lines.push(`import ${alias} from '${importPath}';`);
|
||||
lines.push(`const ${alias} = () => import('${importPath}').then((mod) => mod.default);`);
|
||||
}
|
||||
|
||||
lines.push(`pwRegister({ ${[...componentRegistry.keys()].join(',\n ')} });`);
|
||||
|
@ -21,48 +21,74 @@ import * as __pwReact from 'react';
|
||||
import { createRoot as __pwCreateRoot } from 'react-dom/client';
|
||||
|
||||
/** @typedef {import('../playwright-ct-core/types/component').Component} Component */
|
||||
/** @typedef {import('../playwright-ct-core/types/component').JsxComponent} JsxComponent */
|
||||
/** @typedef {import('../playwright-ct-core/types/component').ObjectComponent} ObjectComponent */
|
||||
/** @typedef {import('react').FunctionComponent} FrameworkComponent */
|
||||
|
||||
/** @type {Map<string, () => Promise<FrameworkComponent>>} */
|
||||
const __pwLoaderRegistry = new Map();
|
||||
/** @type {Map<string, FrameworkComponent>} */
|
||||
const __pwRegistry = new Map();
|
||||
/** @type {Map<Element, import('react-dom/client').Root>} */
|
||||
const __pwRootRegistry = new Map();
|
||||
|
||||
/**
|
||||
* @param {{[key: string]: FrameworkComponent}} components
|
||||
* @param {{[key: string]: () => Promise<FrameworkComponent>}} components
|
||||
*/
|
||||
export function pwRegister(components) {
|
||||
for (const [name, value] of Object.entries(components))
|
||||
__pwRegistry.set(name, value);
|
||||
__pwLoaderRegistry.set(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Component} component
|
||||
* @returns {component is JsxComponent | ObjectComponent}
|
||||
*/
|
||||
function isComponent(component) {
|
||||
return !(typeof component !== 'object' || Array.isArray(component));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Component} component
|
||||
*/
|
||||
async function __pwResolveComponent(component) {
|
||||
if (!isComponent(component))
|
||||
return
|
||||
|
||||
let componentFactory = __pwLoaderRegistry.get(component.type);
|
||||
if (!componentFactory) {
|
||||
// Lookup by shorthand.
|
||||
for (const [name, value] of __pwLoaderRegistry) {
|
||||
if (component.type.endsWith(`_${name}`)) {
|
||||
componentFactory = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!componentFactory && component.type[0].toUpperCase() === component.type[0])
|
||||
throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`);
|
||||
|
||||
if(componentFactory)
|
||||
__pwRegistry.set(component.type, await componentFactory())
|
||||
|
||||
if ('children' in component)
|
||||
await Promise.all(component.children.map(child => __pwResolveComponent(child)))
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Component} component
|
||||
*/
|
||||
function __pwRender(component) {
|
||||
if (typeof component !== 'object' || Array.isArray(component))
|
||||
if (!isComponent(component))
|
||||
return component;
|
||||
|
||||
let componentFunc = __pwRegistry.get(component.type);
|
||||
if (!componentFunc) {
|
||||
// Lookup by shorthand.
|
||||
for (const [name, value] of __pwRegistry) {
|
||||
if (component.type.endsWith(`_${name}`)) {
|
||||
componentFunc = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!componentFunc && component.type[0].toUpperCase() === component.type[0])
|
||||
throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`);
|
||||
|
||||
const componentFuncOrString = componentFunc || component.type;
|
||||
const componentFunc = __pwRegistry.get(component.type);
|
||||
|
||||
if (component.kind !== 'jsx')
|
||||
throw new Error('Object mount notation is not supported');
|
||||
|
||||
return __pwReact.createElement(componentFuncOrString, component.props, ...component.children.map(child => {
|
||||
return __pwReact.createElement(componentFunc || component.type, component.props, ...component.children.map(child => {
|
||||
if (typeof child === 'string')
|
||||
return child;
|
||||
return __pwRender(child);
|
||||
@ -74,6 +100,7 @@ function __pwRender(component) {
|
||||
}
|
||||
|
||||
window.playwrightMount = async (component, rootElement, hooksConfig) => {
|
||||
await __pwResolveComponent(component);
|
||||
let App = () => __pwRender(component);
|
||||
for (const hook of window.__pw_hooks_before_mount || []) {
|
||||
const wrapper = await hook({ App, hooksConfig });
|
||||
@ -105,6 +132,7 @@ window.playwrightUnmount = async rootElement => {
|
||||
};
|
||||
|
||||
window.playwrightUpdate = async (rootElement, component) => {
|
||||
await __pwResolveComponent(component);
|
||||
const root = __pwRootRegistry.get(rootElement);
|
||||
if (root === undefined)
|
||||
throw new Error('Component was not mounted');
|
||||
|
@ -22,46 +22,72 @@ import __pwReact from 'react';
|
||||
import __pwReactDOM from 'react-dom';
|
||||
|
||||
/** @typedef {import('../playwright-ct-core/types/component').Component} Component */
|
||||
/** @typedef {import('../playwright-ct-core/types/component').JsxComponent} JsxComponent */
|
||||
/** @typedef {import('../playwright-ct-core/types/component').ObjectComponent} ObjectComponent */
|
||||
/** @typedef {import('react').FunctionComponent} FrameworkComponent */
|
||||
|
||||
/** @type {Map<string, FrameworkComponent>} */
|
||||
/** @type {Map<string, () => Promise<FrameworkComponent>>} */
|
||||
const __pwLoaderRegistry = new Map();
|
||||
/** @type {Map<string, FrameworkComponent} */
|
||||
const __pwRegistry = new Map();
|
||||
|
||||
/**
|
||||
* @param {{[key: string]: FrameworkComponent}} components
|
||||
* @param {{[key: string]: () => Promise<FrameworkComponent>}} components
|
||||
*/
|
||||
export function pwRegister(components) {
|
||||
for (const [name, value] of Object.entries(components))
|
||||
__pwRegistry.set(name, value);
|
||||
__pwLoaderRegistry.set(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Component} component
|
||||
* @returns {component is JsxComponent | ObjectComponent}
|
||||
*/
|
||||
function isComponent(component) {
|
||||
return !(typeof component !== 'object' || Array.isArray(component));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Component} component
|
||||
*/
|
||||
async function __pwResolveComponent(component) {
|
||||
if (!isComponent(component))
|
||||
return
|
||||
|
||||
let componentFactory = __pwLoaderRegistry.get(component.type);
|
||||
if (!componentFactory) {
|
||||
// Lookup by shorthand.
|
||||
for (const [name, value] of __pwLoaderRegistry) {
|
||||
if (component.type.endsWith(`_${name}`)) {
|
||||
componentFactory = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!componentFactory && component.type[0].toUpperCase() === component.type[0])
|
||||
throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`);
|
||||
|
||||
if(componentFactory)
|
||||
__pwRegistry.set(component.type, await componentFactory())
|
||||
|
||||
if ('children' in component)
|
||||
await Promise.all(component.children.map(child => __pwResolveComponent(child)))
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Component} component
|
||||
*/
|
||||
function __pwRender(component) {
|
||||
if (typeof component !== 'object' || Array.isArray(component))
|
||||
if (!isComponent(component))
|
||||
return component;
|
||||
|
||||
let componentFunc = __pwRegistry.get(component.type);
|
||||
if (!componentFunc) {
|
||||
// Lookup by shorthand.
|
||||
for (const [name, value] of __pwRegistry) {
|
||||
if (component.type.endsWith(`_${name}`)) {
|
||||
componentFunc = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!componentFunc && component.type[0].toUpperCase() === component.type[0])
|
||||
throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`);
|
||||
|
||||
const componentFuncOrString = componentFunc || component.type;
|
||||
|
||||
const componentFunc = __pwRegistry.get(component.type);
|
||||
|
||||
if (component.kind !== 'jsx')
|
||||
throw new Error('Object mount notation is not supported');
|
||||
|
||||
return __pwReact.createElement(componentFuncOrString, component.props, ...component.children.map(child => {
|
||||
return __pwReact.createElement(componentFunc || component.type, component.props, ...component.children.map(child => {
|
||||
if (typeof child === 'string')
|
||||
return child;
|
||||
return __pwRender(child);
|
||||
@ -73,6 +99,7 @@ function __pwRender(component) {
|
||||
}
|
||||
|
||||
window.playwrightMount = async (component, rootElement, hooksConfig) => {
|
||||
await __pwResolveComponent(component);
|
||||
let App = () => __pwRender(component);
|
||||
for (const hook of window.__pw_hooks_before_mount || []) {
|
||||
const wrapper = await hook({ App, hooksConfig });
|
||||
@ -92,5 +119,6 @@ window.playwrightUnmount = async rootElement => {
|
||||
};
|
||||
|
||||
window.playwrightUpdate = async (rootElement, component) => {
|
||||
await __pwResolveComponent(component);
|
||||
__pwReactDOM.render(__pwRender(/** @type {Component} */(component)), rootElement);
|
||||
};
|
||||
|
@ -21,17 +21,57 @@ import { render as __pwSolidRender, createComponent as __pwSolidCreateComponent
|
||||
import __pwH from 'solid-js/h';
|
||||
|
||||
/** @typedef {import('../playwright-ct-core/types/component').Component} Component */
|
||||
/** @typedef {import('../playwright-ct-core/types/component').JsxComponent} JsxComponent */
|
||||
/** @typedef {import('../playwright-ct-core/types/component').ObjectComponent} ObjectComponent */
|
||||
/** @typedef {() => import('solid-js').JSX.Element} FrameworkComponent */
|
||||
|
||||
/** @type {Map<string, () => Promise<FrameworkComponent>>} */
|
||||
const __pwLoaderRegistry = new Map();
|
||||
/** @type {Map<string, FrameworkComponent>} */
|
||||
const __pwRegistry = new Map();
|
||||
|
||||
/**
|
||||
* @param {{[key: string]: FrameworkComponent}} components
|
||||
* @param {{[key: string]: () => Promise<FrameworkComponent>}} components
|
||||
*/
|
||||
export function pwRegister(components) {
|
||||
for (const [name, value] of Object.entries(components))
|
||||
__pwRegistry.set(name, value);
|
||||
__pwLoaderRegistry.set(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Component} component
|
||||
* @returns {component is JsxComponent | ObjectComponent}
|
||||
*/
|
||||
function isComponent(component) {
|
||||
return !(typeof component !== 'object' || Array.isArray(component));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Component} component
|
||||
*/
|
||||
async function __pwResolveComponent(component) {
|
||||
if (!isComponent(component))
|
||||
return
|
||||
|
||||
let componentFactory = __pwLoaderRegistry.get(component.type);
|
||||
if (!componentFactory) {
|
||||
// Lookup by shorthand.
|
||||
for (const [name, value] of __pwLoaderRegistry) {
|
||||
if (component.type.endsWith(`_${name}`)) {
|
||||
componentFactory = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!componentFactory && component.type[0].toUpperCase() === component.type[0])
|
||||
throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`);
|
||||
|
||||
if(componentFactory)
|
||||
__pwRegistry.set(component.type, await componentFactory())
|
||||
|
||||
if ('children' in component)
|
||||
await Promise.all(component.children.map(child => __pwResolveComponent(child)))
|
||||
}
|
||||
|
||||
function __pwCreateChild(child) {
|
||||
@ -45,19 +85,7 @@ function __pwCreateComponent(component) {
|
||||
if (typeof component !== 'object' || Array.isArray(component))
|
||||
return component;
|
||||
|
||||
let Component = __pwRegistry.get(component.type);
|
||||
if (!Component) {
|
||||
// Lookup by shorthand.
|
||||
for (const [name, value] of __pwRegistry) {
|
||||
if (component.type.endsWith(`_${name}`)) {
|
||||
Component = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!Component && component.type[0].toUpperCase() === component.type[0])
|
||||
throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`);
|
||||
const componentFunc = __pwRegistry.get(component.type);
|
||||
|
||||
if (component.kind !== 'jsx')
|
||||
throw new Error('Object mount notation is not supported');
|
||||
@ -69,15 +97,16 @@ function __pwCreateComponent(component) {
|
||||
return children;
|
||||
}, []);
|
||||
|
||||
if (!Component)
|
||||
if (!componentFunc)
|
||||
return __pwH(component.type, component.props, children);
|
||||
|
||||
return __pwSolidCreateComponent(Component, { ...component.props, children });
|
||||
return __pwSolidCreateComponent(componentFunc, { ...component.props, children });
|
||||
}
|
||||
|
||||
const __pwUnmountKey = Symbol('unmountKey');
|
||||
|
||||
window.playwrightMount = async (component, rootElement, hooksConfig) => {
|
||||
await __pwResolveComponent(component);
|
||||
let App = () => __pwCreateComponent(component);
|
||||
for (const hook of window.__pw_hooks_before_mount || []) {
|
||||
const wrapper = await hook({ App, hooksConfig });
|
||||
|
@ -21,18 +21,58 @@
|
||||
import { detach as __pwDetach, insert as __pwInsert, noop as __pwNoop } from 'svelte/internal';
|
||||
|
||||
/** @typedef {import('../playwright-ct-core/types/component').Component} Component */
|
||||
/** @typedef {import('../playwright-ct-core/types/component').JsxComponent} JsxComponent */
|
||||
/** @typedef {import('../playwright-ct-core/types/component').ObjectComponent} ObjectComponent */
|
||||
/** @typedef {any} FrameworkComponent */
|
||||
/** @typedef {import('svelte').SvelteComponent} SvelteComponent */
|
||||
|
||||
/** @type {Map<string, () => Promise<FrameworkComponent>>} */
|
||||
const __pwLoaderRegistry = new Map();
|
||||
/** @type {Map<string, FrameworkComponent>} */
|
||||
const __pwRegistry = new Map();
|
||||
|
||||
/**
|
||||
* @param {{[key: string]: FrameworkComponent}} components
|
||||
* @param {{[key: string]: () => Promise<FrameworkComponent>}} components
|
||||
*/
|
||||
export function pwRegister(components) {
|
||||
for (const [name, value] of Object.entries(components))
|
||||
__pwRegistry.set(name, value);
|
||||
__pwLoaderRegistry.set(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Component} component
|
||||
* @returns {component is JsxComponent | ObjectComponent}
|
||||
*/
|
||||
function isComponent(component) {
|
||||
return !(typeof component !== 'object' || Array.isArray(component));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Component} component
|
||||
*/
|
||||
async function __pwResolveComponent(component) {
|
||||
if (!isComponent(component))
|
||||
return
|
||||
|
||||
let componentFactory = __pwLoaderRegistry.get(component.type);
|
||||
if (!componentFactory) {
|
||||
// Lookup by shorthand.
|
||||
for (const [name, value] of __pwLoaderRegistry) {
|
||||
if (component.type.endsWith(`_${name}_svelte`)) {
|
||||
componentFactory = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!componentFactory)
|
||||
throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`);
|
||||
|
||||
if(componentFactory)
|
||||
__pwRegistry.set(component.type, await componentFactory())
|
||||
|
||||
if ('children' in component)
|
||||
await Promise.all(component.children.map(child => __pwResolveComponent(child)))
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,20 +109,9 @@ function __pwCreateSlots(slots) {
|
||||
const __pwSvelteComponentKey = Symbol('svelteComponent');
|
||||
|
||||
window.playwrightMount = async (component, rootElement, hooksConfig) => {
|
||||
let componentCtor = __pwRegistry.get(component.type);
|
||||
if (!componentCtor) {
|
||||
// Lookup by shorthand.
|
||||
for (const [name, value] of __pwRegistry) {
|
||||
if (component.type.endsWith(`_${name}_svelte`)) {
|
||||
componentCtor = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!componentCtor)
|
||||
throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`);
|
||||
|
||||
await __pwResolveComponent(component);
|
||||
const componentCtor = __pwRegistry.get(component.type);
|
||||
|
||||
if (component.kind !== 'object')
|
||||
throw new Error('JSX mount notation is not supported');
|
||||
|
||||
@ -115,6 +144,7 @@ window.playwrightUnmount = async rootElement => {
|
||||
};
|
||||
|
||||
window.playwrightUpdate = async (rootElement, component) => {
|
||||
await __pwResolveComponent(component);
|
||||
const svelteComponent = /** @type {SvelteComponent} */ (rootElement[__pwSvelteComponentKey]);
|
||||
if (!svelteComponent)
|
||||
throw new Error('Component was not mounted');
|
||||
|
@ -21,18 +21,58 @@ import { createApp as __pwCreateApp, setDevtoolsHook as __pwSetDevtoolsHook, h a
|
||||
import { compile as __pwCompile } from '@vue/compiler-dom';
|
||||
import * as __pwVue from 'vue';
|
||||
|
||||
/** @typedef {import('@playwright/test/types/experimentalComponent').Component} Component */
|
||||
/** @typedef {import('../playwright-ct-core/types/component').Component} Component */
|
||||
/** @typedef {import('../playwright-ct-core/types/component').JsxComponent} JsxComponent */
|
||||
/** @typedef {import('../playwright-ct-core/types/component').ObjectComponent} ObjectComponent */
|
||||
/** @typedef {import('vue').Component} FrameworkComponent */
|
||||
|
||||
/** @type {Map<string, () => Promise<FrameworkComponent>>} */
|
||||
const __pwLoaderRegistry = new Map();
|
||||
/** @type {Map<string, FrameworkComponent>} */
|
||||
const __pwRegistry = new Map();
|
||||
|
||||
/**
|
||||
* @param {{[key: string]: FrameworkComponent}} components
|
||||
* @param {{[key: string]: () => Promise<FrameworkComponent>}} components
|
||||
*/
|
||||
export function pwRegister(components) {
|
||||
for (const [name, value] of Object.entries(components))
|
||||
__pwRegistry.set(name, value);
|
||||
__pwLoaderRegistry.set(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Component} component
|
||||
* @returns {component is JsxComponent | ObjectComponent}
|
||||
*/
|
||||
function isComponent(component) {
|
||||
return !(typeof component !== 'object' || Array.isArray(component));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Component} component
|
||||
*/
|
||||
async function __pwResolveComponent(component) {
|
||||
if (!isComponent(component))
|
||||
return
|
||||
|
||||
let componentFactory = __pwLoaderRegistry.get(component.type);
|
||||
if (!componentFactory) {
|
||||
// Lookup by shorthand.
|
||||
for (const [name, value] of __pwLoaderRegistry) {
|
||||
if (component.type.endsWith(`_${name}_vue`)) {
|
||||
componentFactory = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!componentFactory && component.type[0].toUpperCase() === component.type[0])
|
||||
throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`);
|
||||
|
||||
if(componentFactory)
|
||||
__pwRegistry.set(component.type, await componentFactory())
|
||||
|
||||
if ('children' in component)
|
||||
await Promise.all(component.children.map(child => __pwResolveComponent(child)))
|
||||
}
|
||||
|
||||
const __pwAllListeners = new Map();
|
||||
@ -95,23 +135,7 @@ function __pwCreateComponent(component) {
|
||||
if (typeof component === 'string')
|
||||
return component;
|
||||
|
||||
/**
|
||||
* @type {import('vue').Component | string | undefined}
|
||||
*/
|
||||
let componentFunc = __pwRegistry.get(component.type);
|
||||
if (!componentFunc) {
|
||||
// Lookup by shorthand.
|
||||
for (const [name, value] of __pwRegistry) {
|
||||
if (component.type.endsWith(`_${name}_vue`)) {
|
||||
componentFunc = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!componentFunc && component.type[0].toUpperCase() === component.type[0])
|
||||
throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`);
|
||||
|
||||
componentFunc = componentFunc || component.type;
|
||||
|
||||
const isVueComponent = componentFunc !== component.type;
|
||||
@ -223,6 +247,7 @@ const __pwAppKey = Symbol('appKey');
|
||||
const __pwWrapperKey = Symbol('wrapperKey');
|
||||
|
||||
window.playwrightMount = async (component, rootElement, hooksConfig) => {
|
||||
await __pwResolveComponent(component);
|
||||
const app = __pwCreateApp({
|
||||
render: () => {
|
||||
const wrapper = __pwCreateWrapper(component);
|
||||
@ -248,7 +273,8 @@ window.playwrightUnmount = async rootElement => {
|
||||
app.unmount();
|
||||
};
|
||||
|
||||
window.playwrightUpdate = async (rootElement, options) => {
|
||||
window.playwrightUpdate = async (rootElement, component) => {
|
||||
await __pwResolveComponent(component);
|
||||
const wrapper = rootElement[__pwWrapperKey];
|
||||
if (!wrapper)
|
||||
throw new Error('Component was not mounted');
|
||||
@ -256,7 +282,7 @@ window.playwrightUpdate = async (rootElement, options) => {
|
||||
if (!wrapper.component)
|
||||
throw new Error('Updating a native HTML element is not supported');
|
||||
|
||||
const { slots, listeners, props } = __pwCreateComponent(options);
|
||||
const { slots, listeners, props } = __pwCreateComponent(component);
|
||||
|
||||
wrapper.component.slots = __pwWrapFunctions(slots);
|
||||
__pwAllListeners.set(wrapper, listeners);
|
||||
|
@ -21,17 +21,57 @@
|
||||
import __pwVue, { h as __pwH } from 'vue';
|
||||
|
||||
/** @typedef {import('../playwright-ct-core/types/component').Component} Component */
|
||||
/** @typedef {import('../playwright-ct-core/types/component').JsxComponent} JsxComponent */
|
||||
/** @typedef {import('../playwright-ct-core/types/component').ObjectComponent} ObjectComponent */
|
||||
/** @typedef {import('vue').Component} FrameworkComponent */
|
||||
|
||||
/** @type {Map<string, () => Promise<FrameworkComponent>>} */
|
||||
const __pwLoaderRegistry = new Map();
|
||||
/** @type {Map<string, FrameworkComponent>} */
|
||||
const __pwRegistry = new Map();
|
||||
|
||||
/**
|
||||
* @param {{[key: string]: FrameworkComponent}} components
|
||||
* @param {{[key: string]: () => Promise<FrameworkComponent>}} components
|
||||
*/
|
||||
export function pwRegister(components) {
|
||||
for (const [name, value] of Object.entries(components))
|
||||
__pwRegistry.set(name, value);
|
||||
__pwLoaderRegistry.set(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Component} component
|
||||
* @returns {component is JsxComponent | ObjectComponent}
|
||||
*/
|
||||
function isComponent(component) {
|
||||
return !(typeof component !== 'object' || Array.isArray(component));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Component} component
|
||||
*/
|
||||
async function __pwResolveComponent(component) {
|
||||
if (!isComponent(component))
|
||||
return
|
||||
|
||||
let componentFactory = __pwLoaderRegistry.get(component.type);
|
||||
if (!componentFactory) {
|
||||
// Lookup by shorthand.
|
||||
for (const [name, value] of __pwLoaderRegistry) {
|
||||
if (component.type.endsWith(`_${name}_vue`)) {
|
||||
componentFactory = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!componentFactory && component.type[0].toUpperCase() === component.type[0])
|
||||
throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`);
|
||||
|
||||
if(componentFactory)
|
||||
__pwRegistry.set(component.type, await componentFactory())
|
||||
|
||||
if ('children' in component)
|
||||
await Promise.all(component.children.map(child => __pwResolveComponent(child)))
|
||||
}
|
||||
|
||||
/**
|
||||
@ -59,25 +99,7 @@ function __pwComponentHasKeyInProps(Component, key) {
|
||||
* @param {Component} component
|
||||
*/
|
||||
function __pwCreateComponent(component) {
|
||||
/**
|
||||
* @type {import('vue').Component | string | undefined}
|
||||
*/
|
||||
let componentFunc = __pwRegistry.get(component.type);
|
||||
if (!componentFunc) {
|
||||
// Lookup by shorthand.
|
||||
for (const [name, value] of __pwRegistry) {
|
||||
if (component.type.endsWith(`_${name}_vue`)) {
|
||||
componentFunc = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!componentFunc && component.type[0].toUpperCase() === component.type[0])
|
||||
throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`);
|
||||
|
||||
componentFunc = componentFunc || component.type;
|
||||
|
||||
const componentFunc = __pwRegistry.get(component.type) || component.type;
|
||||
const isVueComponent = componentFunc !== component.type;
|
||||
|
||||
/**
|
||||
@ -157,6 +179,7 @@ const instanceKey = Symbol('instanceKey');
|
||||
const wrapperKey = Symbol('wrapperKey');
|
||||
|
||||
window.playwrightMount = async (component, rootElement, hooksConfig) => {
|
||||
await __pwResolveComponent(component);
|
||||
let options = {};
|
||||
for (const hook of window.__pw_hooks_before_mount || [])
|
||||
options = await hook({ hooksConfig, Vue: __pwVue });
|
||||
@ -185,6 +208,7 @@ window.playwrightUnmount = async rootElement => {
|
||||
};
|
||||
|
||||
window.playwrightUpdate = async (element, options) => {
|
||||
await __pwResolveComponent(options);
|
||||
const wrapper = /** @type {any} */(element)[wrapperKey];
|
||||
if (!wrapper)
|
||||
throw new Error('Component was not mounted');
|
||||
|
@ -17,3 +17,4 @@
|
||||
import '../src/common.css';
|
||||
import '../src/theme.ts';
|
||||
import '../src/third_party/vscode/codicon.css';
|
||||
import '../src/third_party/vscode/colors.css';
|
||||
|
Loading…
Reference in New Issue
Block a user