diff --git a/ct-web-lit/package.json b/ct-web-lit/package.json index d6f71d1..b1c6cec 100644 --- a/ct-web-lit/package.json +++ b/ct-web-lit/package.json @@ -14,7 +14,7 @@ }, "devDependencies": { "@sand4rt/experimental-ct-web": "workspace:*", - "@playwright/test": "^1.41.0", + "@playwright/test": "^1.41.1", "typescript": "^5.1.3", "vite": "^4.4.7" } diff --git a/ct-web/package.json b/ct-web/package.json index e1ed333..76e893e 100644 --- a/ct-web/package.json +++ b/ct-web/package.json @@ -11,7 +11,7 @@ }, "devDependencies": { "@sand4rt/experimental-ct-web": "workspace:*", - "@playwright/test": "^1.41.0", + "@playwright/test": "^1.41.1", "typescript": "^5.1.3", "vite": "^4.4.7" } diff --git a/playwright-ct-web/package.json b/playwright-ct-web/package.json index 74e9c3a..7e1b32b 100644 --- a/playwright-ct-web/package.json +++ b/playwright-ct-web/package.json @@ -1,6 +1,6 @@ { "name": "@sand4rt/experimental-ct-web", - "version": "1.41.0", + "version": "1.41.1", "description": "Playwright Component Testing for Web Components", "homepage": "https://playwright.dev", "repository": { @@ -43,13 +43,13 @@ } }, "dependencies": { - "@playwright/experimental-ct-core": "^1.41.0" + "@playwright/experimental-ct-core": "^1.41.1" }, "devDependencies": { - "@playwright/test": "1.41.0" + "@playwright/test": "1.41.1" }, "peerDependencies": { - "@playwright/test": ">=1.41.0" + "@playwright/test": ">=1.41.1" }, "bin": { "playwright": "./cli.js" diff --git a/playwright-ct-web/registerSource.mjs b/playwright-ct-web/registerSource.mjs index 57db21c..83b0905 100644 --- a/playwright-ct-web/registerSource.mjs +++ b/playwright-ct-web/registerSource.mjs @@ -17,59 +17,21 @@ // @ts-check // 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 Promise>} */ -const __pwLoaderRegistry = new Map(); -/** @type {Map} */ -const __pwRegistry = new Map(); const __pwListeners = new Map(); /** - * @param {Record Promise>} components + * @param {any} component + * @returns {component is ObjectComponent} */ -export function pwRegister(components) { - for (const [name, value] of Object.entries(components)) - __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 isObjectComponent(component) { + return ( + typeof component === 'object' && + component && + component.__pw_type === 'object-component' + ); } /** @@ -95,7 +57,7 @@ function __pwRemoveEvents(webComponent, events = {}) { */ function __pwUpdateEvents(webComponent, events = {}) { for (const [key, listener] of Object.entries(events)) { - const fn = event => listener(/** @type {CustomEvent} */ (event).detail); + const fn = (event) => listener(/** @type {CustomEvent} */ (event).detail); webComponent.addEventListener(key, fn); __pwListeners.set(key, fn); } @@ -114,11 +76,15 @@ function __pwUpdateSlots(webComponent, slots = {}) { slotElements = value.map(__pwCreateSlot); if (!slotElements) - throw new Error(`Invalid slot with name: \`${key}\` supplied to \`mount()\``); + throw new Error( + `Invalid slot with name: \`${key}\` supplied to \`mount()\``, + ); for (const slotElement of slotElements) { if (!slotElement) - throw new Error(`Invalid slot with name: \`${key}\` supplied to \`mount()\``); + throw new Error( + `Invalid slot with name: \`${key}\` supplied to \`mount()\``, + ); if (key === 'default') { webComponent.appendChild(slotElement); @@ -127,7 +93,7 @@ function __pwUpdateSlots(webComponent, slots = {}) { if (slotElement.nodeName === '#text') { throw new Error( - `Invalid slot with name: \`${key}\` supplied to \`mount()\`, expected \`HTMLElement\` but received \`TextNode\`.` + `Invalid slot with name: \`${key}\` supplied to \`mount()\`, expected \`HTMLElement\` but received \`TextNode\`.`, ); } @@ -143,42 +109,22 @@ function __pwUpdateSlots(webComponent, slots = {}) { */ function __pwCreateSlot(value) { return /** @type {?HTMLElement} */ ( - document - .createRange() - .createContextualFragment(value) - .firstChild + document.createRange().createContextualFragment(value).firstChild ); } -/** - * @param {Component} component - */ -function __pwCreateComponent(component) { - const Component = __pwRegistry.get(component.type); - if (!Component) - throw new Error( - `Unregistered component: ${ - component.type - }. Following components are registered: ${[...__pwRegistry.keys()]}` - ); - - 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') + if (!isObjectComponent(component)) throw new Error('JSX mount notation is not supported'); - const webComponent = __pwCreateComponent(component); - for (const hook of window['__pw_hooks_before_mount'] || []) await hook({ hooksConfig }); + console.log(component) + const webComponent = new component(); + __pwUpdateProps(webComponent, component.props); + __pwUpdateSlots(webComponent, component.slots); + __pwUpdateEvents(webComponent, component.on); rootElement.appendChild(webComponent); for (const hook of window['__pw_hooks_after_mount'] || []) @@ -186,17 +132,16 @@ window.playwrightMount = async (component, rootElement, hooksConfig) => { }; window.playwrightUpdate = async (rootElement, component) => { - await __pwResolveComponent(component); - if (component.kind === 'jsx') + if (!isObjectComponent(component)) throw new Error('JSX mount notation is not supported'); const webComponent = /** @type {?HTMLElement} */ (rootElement.firstChild); if (!webComponent) throw new Error('Component was not mounted'); - __pwUpdateProps(webComponent, component.options?.props); - __pwUpdateSlots(webComponent, component.options?.slots); - __pwRemoveEvents(webComponent, component.options?.on); - __pwUpdateEvents(webComponent, component.options?.on); + __pwUpdateProps(webComponent, component.props); + __pwUpdateSlots(webComponent, component.slots); + __pwRemoveEvents(webComponent, component.on); + __pwUpdateEvents(webComponent, component.on); }; window.playwrightUnmount = async (rootElement) => { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f707455..82869c5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,8 +11,8 @@ importers: ct-web: devDependencies: '@playwright/test': - specifier: ^1.41.0 - version: 1.41.0 + specifier: ^1.41.1 + version: 1.41.1 '@sand4rt/experimental-ct-web': specifier: workspace:* version: link:../playwright-ct-web @@ -30,8 +30,8 @@ importers: version: 2.6.1 devDependencies: '@playwright/test': - specifier: ^1.41.0 - version: 1.41.0 + specifier: ^1.41.1 + version: 1.41.1 '@sand4rt/experimental-ct-web': specifier: workspace:* version: link:../playwright-ct-web @@ -45,12 +45,12 @@ importers: playwright-ct-web: dependencies: '@playwright/experimental-ct-core': - specifier: ^1.41.0 - version: 1.41.0 + specifier: ^1.41.1 + version: 1.41.1 devDependencies: '@playwright/test': - specifier: 1.41.0 - version: 1.41.0 + specifier: 1.41.1 + version: 1.41.1 packages: @@ -240,13 +240,13 @@ packages: '@lit-labs/ssr-dom-shim': 1.1.1 dev: false - /@playwright/experimental-ct-core@1.41.0: - resolution: {integrity: sha512-nshYXeACzQRmxHH2IfEP9tdl30tnsUXq5I5WMJtwaza2d4GOntqOUTeMHUq/HziG3XKZO4zc7Kn5tOo1L+BsLw==} + /@playwright/experimental-ct-core@1.41.1: + resolution: {integrity: sha512-d7PxESV29x6W9RYs0mhkXmxr+6FfTbg2Tm/WJZlhgbIP+OLv79uJ8hl8ERsiBBFtH88sR+WmxHBMiZRpfpa6Fw==} engines: {node: '>=16'} hasBin: true dependencies: - playwright: 1.41.0 - playwright-core: 1.41.0 + playwright: 1.41.1 + playwright-core: 1.41.1 vite: 4.5.1 transitivePeerDependencies: - '@types/node' @@ -258,12 +258,12 @@ packages: - terser dev: false - /@playwright/test@1.41.0: - resolution: {integrity: sha512-Grvzj841THwtpBOrfiHOeYTJQxDRnKofMSzCiV8XeyLWu3o89qftQ4BCKfkziJhSUQRd0utKhrddtIsiraIwmw==} + /@playwright/test@1.41.1: + resolution: {integrity: sha512-9g8EWTjiQ9yFBXc6HjCWe41msLpxEX0KhmfmPl9RPLJdfzL4F0lg2BdJ91O9azFdl11y1pmpwdjBiSxvqc+btw==} engines: {node: '>=16'} hasBin: true dependencies: - playwright: 1.41.0 + playwright: 1.41.1 dev: true /@types/trusted-types@2.0.3: @@ -336,17 +336,17 @@ packages: /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - /playwright-core@1.41.0: - resolution: {integrity: sha512-UGKASUhXmvqm2Lxa1fNr8sFwAtqjpgBRr9jQ7XBI8Rn5uFiEowGUGwrruUQsVPIom4bk7Lt+oLGpXobnXzrBIw==} + /playwright-core@1.41.1: + resolution: {integrity: sha512-/KPO5DzXSMlxSX77wy+HihKGOunh3hqndhqeo/nMxfigiKzogn8kfL0ZBDu0L1RKgan5XHCPmn6zXd2NUJgjhg==} engines: {node: '>=16'} hasBin: true - /playwright@1.41.0: - resolution: {integrity: sha512-XOsfl5ZtAik/T9oek4V0jAypNlaCNzuKOwVhqhgYT3os6kH34PzbRb74F0VWcLYa5WFdnmxl7qyAHBXvPv7lqQ==} + /playwright@1.41.1: + resolution: {integrity: sha512-gdZAWG97oUnbBdRL3GuBvX3nDDmUOuqzV/D24dytqlKt+eI5KbwusluZRGljx1YoJKZ2NRPaeWiFTeGZO7SosQ==} engines: {node: '>=16'} hasBin: true dependencies: - playwright-core: 1.41.0 + playwright-core: 1.41.1 optionalDependencies: fsevents: 2.3.2