Skip to content

Commit

Permalink
feat: code splitting and bump playwright to v1.34.0
Browse files Browse the repository at this point in the history
  • Loading branch information
sand4rt committed May 20, 2023
1 parent 5f88cd2 commit b490100
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 114 deletions.
2 changes: 1 addition & 1 deletion ct-web-lit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"devDependencies": {
"@sand4rt/experimental-ct-web": "*",
"@playwright/test": "^1.33.0",
"@playwright/test": "^1.34.0",
"typescript": "^4.9.5",
"vite": "^4.1.4"
}
Expand Down
2 changes: 1 addition & 1 deletion ct-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
},
"devDependencies": {
"@sand4rt/experimental-ct-web": "*",
"@playwright/test": "^1.33.0",
"@playwright/test": "^1.34.0",
"typescript": "^4.9.5",
"vite": "^4.1.4"
}
Expand Down
8 changes: 4 additions & 4 deletions playwright-ct-web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sand4rt/experimental-ct-web",
"version": "1.33.1",
"version": "1.34.0",
"description": "Playwright Component Testing for Web Components",
"homepage": "https://playwright.dev",
"repository": {
Expand Down Expand Up @@ -43,14 +43,14 @@
}
},
"dependencies": {
"@playwright/test": "1.33.0",
"@playwright/experimental-ct-core": "^1.33.0"
"@playwright/test": "1.34.0",
"@playwright/experimental-ct-core": "^1.34.0"
},
"devDependencies": {
"vite": "^4.3.5"
},
"peerDependencies": {
"@playwright/test": ">=1.33.0"
"@playwright/test": ">=1.34.0"
},
"bin": {
"playwright": "./cli.js"
Expand Down
79 changes: 56 additions & 23 deletions playwright-ct-web/registerSource.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,58 @@
// This file is injected into the registry as text, no dependencies are allowed.

/** @typedef {import('@playwright/experimental-ct-core/types/component').Component} Component */
/** @typedef {import('@playwright/experimental-ct-core/types/component').JsxComponent} JsxComponent */
/** @typedef {import('@playwright/experimental-ct-core/types/component').ObjectComponent} ObjectComponent */
/** @typedef {new (...args: any[]) => HTMLElement} FrameworkComponent */

/** @type {Map<string, () => Promise<FrameworkComponent>>} */
const __pwLoaderRegistry = new Map();
/** @type {Map<string, FrameworkComponent>} */
const registry = new Map();
const listeners = new Map();
const __pwRegistry = new Map();
const __pwListeners = 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))
registry.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)))
}

/**
Expand All @@ -45,8 +85,8 @@ function __pwUpdateProps(webComponent, props = {}) {
*/
function __pwRemoveEvents(webComponent, events = {}) {
for (const [key] of Object.entries(events)) {
webComponent.removeEventListener(key, listeners.get(key));
listeners.delete(key);
webComponent.removeEventListener(key, __pwListeners.get(key));
__pwListeners.delete(key);
}
}

Expand All @@ -57,7 +97,7 @@ function __pwUpdateEvents(webComponent, events = {}) {
for (const [key, listener] of Object.entries(events)) {
const fn = event => listener(/** @type {CustomEvent} */ (event).detail);
webComponent.addEventListener(key, fn);
listeners.set(key, fn);
__pwListeners.set(key, fn);
}
}

Expand Down Expand Up @@ -114,35 +154,27 @@ function __pwCreateSlot(value) {
* @param {Component} component
*/
function __pwCreateComponent(component) {
let Component = registry.get(component.type);
if (!Component) {
// Lookup by shorthand.
for (const [name, value] of registry) {
if (component.type.endsWith(`_${name}`)) {
Component = value;
break;
}
}
}

const Component = __pwRegistry.get(component.type);
if (!Component)
throw new Error(
`Unregistered component: ${
component.type
}. Following components are registered: ${[...registry.keys()]}`
}. Following components are registered: ${[...__pwRegistry.keys()]}`
);

return new Component();
const webComponent = new Component();
__pwUpdateProps(webComponent, component.options?.props);
__pwUpdateSlots(webComponent, component.options?.slots);
__pwUpdateEvents(webComponent, component.options?.on);
return webComponent;
}

window.playwrightMount = async (component, rootElement, hooksConfig) => {
await __pwResolveComponent(component);
if (component.kind !== 'object')
throw new Error('JSX mount notation is not supported');

const webComponent = __pwCreateComponent(component);
__pwUpdateProps(webComponent, component.options?.props);
__pwUpdateSlots(webComponent, component.options?.slots);
__pwUpdateEvents(webComponent, component.options?.on);

for (const hook of window['__pw_hooks_before_mount'] || [])
await hook({ hooksConfig });
Expand All @@ -154,6 +186,7 @@ window.playwrightMount = async (component, rootElement, hooksConfig) => {
};

window.playwrightUpdate = async (rootElement, component) => {
await __pwResolveComponent(component);
if (component.kind === 'jsx')
throw new Error('JSX mount notation is not supported');

Expand Down
Loading

0 comments on commit b490100

Please sign in to comment.