From 53d6d5785422415c522c2a67b334896070667c7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Wi=C5=9Bniowski?= Date: Sat, 15 Feb 2025 14:38:24 +0100 Subject: [PATCH] refactor: make all components svelte5 compliant and update tests --- packages/playwright-ct-svelte/index.d.ts | 3 +- .../playwright-ct-svelte/registerSource.mjs | 53 ++++++++++++++----- .../ct-svelte/src/components/Button.svelte | 8 ++- .../ct-svelte/src/components/Counter.svelte | 10 ++-- .../src/components/DefaultSlot.svelte | 6 ++- .../src/components/NamedSlots.svelte | 12 +++-- .../components/ct-svelte/tests/slots.spec.ts | 2 +- 7 files changed, 63 insertions(+), 31 deletions(-) diff --git a/packages/playwright-ct-svelte/index.d.ts b/packages/playwright-ct-svelte/index.d.ts index 9280a3779d..3cb31954d5 100644 --- a/packages/playwright-ct-svelte/index.d.ts +++ b/packages/playwright-ct-svelte/index.d.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import type { Snippet } from "svelte" import type { SvelteComponent as V4Component, Component as V5Component, @@ -21,7 +22,7 @@ import type { } from 'svelte/types/runtime'; import type { TestType, Locator } from '@playwright/experimental-ct-core'; -type ComponentSlot = string | string[]; +type ComponentSlot = Snippet | string; type ComponentSlots = Record & { default?: ComponentSlot }; type ComponentEvents = Record; diff --git a/packages/playwright-ct-svelte/registerSource.mjs b/packages/playwright-ct-svelte/registerSource.mjs index e7daf809b5..1503e03913 100644 --- a/packages/playwright-ct-svelte/registerSource.mjs +++ b/packages/playwright-ct-svelte/registerSource.mjs @@ -19,10 +19,10 @@ // This file is injected into the registry as text, no dependencies are allowed. import { asClassComponent } from 'svelte/legacy'; +import { createRawSnippet } from "svelte"; /** @typedef {import('../playwright-ct-core/types/component').Component} Component */ /** @typedef {import('../playwright-ct-core/types/component').ObjectComponent} ObjectComponent */ -/** @typedef {any} FrameworkComponent */ /** @typedef {import('svelte').SvelteComponent} SvelteComponent */ /** @typedef {import('svelte').ComponentType} ComponentType */ @@ -38,6 +38,30 @@ function isObjectComponent(component) { ); } +/** @type {( component: ObjectComponent ) => Record} */ +function extractParams(component) { + let {props, slots, on} = component; + + slots = Object.fromEntries( + Object.entries(slots ?? {}).map(([key, snippet]) => { + if(typeof snippet === "string") { + console.log("ugraded", key); + return [key, createRawSnippet(() => ({render: () => snippet}))]; + } + + return [key, snippet] + }) + ); + + on = Object.fromEntries( + Object.entries(on ?? {}).map(([key, fn]) => { + return [`on${key}`, fn] + }) + ); + + return {props, slots, on}; +} + const __pwSvelteComponentKey = Symbol('svelteComponent'); window.playwrightMount = async (component, rootElement, hooksConfig) => { @@ -45,17 +69,20 @@ window.playwrightMount = async (component, rootElement, hooksConfig) => { throw new Error('JSX mount notation is not supported'); const objectComponent = component; - component.type = component.type; - - /** @type {ComponentType} */ const componentCtor = asClassComponent(component.type); class App extends componentCtor { constructor(options = {}) { + if (!isObjectComponent(component)) + throw new Error('JSX mount notation is not supported'); + + let {props, slots, on} = extractParams(component); + super({ target: rootElement, props: { - ...objectComponent.props, - $$scope: {} + ...props, + ...slots, + ...on, }, ...options }); @@ -63,9 +90,7 @@ window.playwrightMount = async (component, rootElement, hooksConfig) => { } /** @type {SvelteComponent | undefined} */ - let svelteComponent; - for (const hook of window.__pw_hooks_before_mount || []) { svelteComponent = await hook({ hooksConfig, App }); } @@ -76,9 +101,6 @@ window.playwrightMount = async (component, rootElement, hooksConfig) => { rootElement[__pwSvelteComponentKey] = svelteComponent; - for (const [key, listener] of Object.entries(objectComponent.on || {})) - svelteComponent.$on(key, event => listener(event.detail)); - for (const hook of window.__pw_hooks_after_mount || []) await hook({ hooksConfig, svelteComponent }); }; @@ -101,8 +123,11 @@ window.playwrightUpdate = async (rootElement, component) => { ); if (!svelteComponent) throw new Error('Component was not mounted'); - for (const [key, listener] of Object.entries(component.on || {})) - svelteComponent.$on(key, event => listener(event.detail)); + let {props, slots, on} = extractParams(component); - if (component.props) svelteComponent.$set(component.props); + svelteComponent.$set({ + ...props, + ...slots, + ...on, + }); }; diff --git a/tests/components/ct-svelte/src/components/Button.svelte b/tests/components/ct-svelte/src/components/Button.svelte index 8c46efd1f2..9e8d2ac890 100644 --- a/tests/components/ct-svelte/src/components/Button.svelte +++ b/tests/components/ct-svelte/src/components/Button.svelte @@ -1,7 +1,5 @@ - - + + diff --git a/tests/components/ct-svelte/src/components/Counter.svelte b/tests/components/ct-svelte/src/components/Counter.svelte index 38674bb6c3..76cace9a5b 100644 --- a/tests/components/ct-svelte/src/components/Counter.svelte +++ b/tests/components/ct-svelte/src/components/Counter.svelte @@ -1,14 +1,12 @@ - diff --git a/tests/components/ct-svelte/src/components/DefaultSlot.svelte b/tests/components/ct-svelte/src/components/DefaultSlot.svelte index 201dda6ce3..be05b7924f 100644 --- a/tests/components/ct-svelte/src/components/DefaultSlot.svelte +++ b/tests/components/ct-svelte/src/components/DefaultSlot.svelte @@ -1,7 +1,11 @@ + +

Welcome!

- + {@render children?.()}