@playwright/experimental-ct-svelte 1.55.0-alpha-1754386682000 → 1.55.0-alpha-2025-08-06

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -14,21 +14,24 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import type { SvelteComponent, ComponentProps } from 'svelte/types/runtime';
17
+ import type { ComponentProps, Component, SvelteComponent } from 'svelte';
18
18
  import type { TestType, Locator } from '@playwright/experimental-ct-core';
19
19
 
20
- type ComponentSlot = string | string[];
20
+ type ComponentSlot = Snippet | string;
21
21
  type ComponentSlots = Record<string, ComponentSlot> & { default?: ComponentSlot };
22
22
  type ComponentEvents = Record<string, Function>;
23
23
 
24
- export interface MountOptions<HooksConfig, Component extends SvelteComponent> {
24
+ // TODO: Remove after Svelte has removed S4 fallback TypeScript types for `*.svelte` files
25
+ type InteropComponent = (new (...args: unknown[]) => SvelteComponent) | Component<any, any, any>;
26
+
27
+ export interface MountOptions<HooksConfig, Component extends InteropComponent> {
25
28
  props?: ComponentProps<Component>;
26
29
  slots?: ComponentSlots;
27
30
  on?: ComponentEvents;
28
31
  hooksConfig?: HooksConfig;
29
32
  }
30
33
 
31
- export interface MountResult<Component extends SvelteComponent> extends Locator {
34
+ export interface MountResult<Component extends InteropComponent> extends Locator {
32
35
  unmount(): Promise<void>;
33
36
  update(options: {
34
37
  props?: Partial<ComponentProps<Component>>;
@@ -37,8 +40,8 @@ export interface MountResult<Component extends SvelteComponent> extends Locator
37
40
  }
38
41
 
39
42
  export const test: TestType<{
40
- mount<HooksConfig, Component extends SvelteComponent = SvelteComponent>(
41
- component: new (...args: any[]) => Component,
43
+ mount<HooksConfig, Component extends InteropComponent = InteropComponent>(
44
+ component: Component,
42
45
  options?: MountOptions<HooksConfig, Component>
43
46
  ): Promise<MountResult<Component>>;
44
47
  }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playwright/experimental-ct-svelte",
3
- "version": "1.55.0-alpha-1754386682000",
3
+ "version": "1.55.0-alpha-2025-08-06",
4
4
  "description": "Playwright Component Testing for Svelte",
5
5
  "repository": {
6
6
  "type": "git",
@@ -30,11 +30,11 @@
30
30
  "./package.json": "./package.json"
31
31
  },
32
32
  "dependencies": {
33
- "@playwright/experimental-ct-core": "1.55.0-alpha-1754386682000",
34
- "@sveltejs/vite-plugin-svelte": "^3.0.1"
33
+ "@playwright/experimental-ct-core": "1.55.0-alpha-2025-08-06",
34
+ "@sveltejs/vite-plugin-svelte": "^5.1.0"
35
35
  },
36
36
  "devDependencies": {
37
- "svelte": "^4.2.19"
37
+ "svelte": "^5.37.3"
38
38
  },
39
39
  "bin": {
40
40
  "playwright": "cli.js"
@@ -17,10 +17,10 @@
17
17
  // @ts-check
18
18
 
19
19
  // This file is injected into the registry as text, no dependencies are allowed.
20
+ import { createRawSnippet } from 'svelte';
21
+ import { asClassComponent } from 'svelte/legacy';
20
22
 
21
- import { detach as __pwDetach, insert as __pwInsert, noop as __pwNoop } from 'svelte/internal';
22
-
23
- /** @typedef {import('../playwright-ct-core/types/component').Component} Component */
23
+ /** @typedef {import('../playwright-ct-core/types/component').Component} PlaywrightComponent */
24
24
  /** @typedef {import('../playwright-ct-core/types/component').ObjectComponent} ObjectComponent */
25
25
  /** @typedef {any} FrameworkComponent */
26
26
  /** @typedef {import('svelte').SvelteComponent} SvelteComponent */
@@ -33,36 +33,23 @@ function isObjectComponent(component) {
33
33
  return typeof component === 'object' && component && component.__pw_type === 'object-component';
34
34
  }
35
35
 
36
- /**
37
- * TODO: remove this function when the following issue is fixed:
38
- * https://github.com/sveltejs/svelte/issues/2588
39
- */
40
- function __pwCreateSlots(slots) {
41
- const svelteSlots = {};
42
-
43
- for (const slotName in slots) {
44
- const template = document
45
- .createRange()
46
- .createContextualFragment(slots[slotName]);
47
- svelteSlots[slotName] = [createSlotFn(template)];
48
- }
36
+ /** @type {( component: ObjectComponent ) => Record<string, any>} */
37
+ function extractProps(component) {
38
+ let { props, slots } = component;
49
39
 
50
- function createSlotFn(element) {
51
- return function() {
52
- return {
53
- c: __pwNoop,
54
- m: function mount(target, anchor) {
55
- __pwInsert(target, element, anchor);
56
- },
57
- d: function destroy(detaching) {
58
- if (detaching)
59
- __pwDetach(element);
60
- },
61
- l: __pwNoop,
62
- };
63
- };
64
- }
65
- return svelteSlots;
40
+ // Svelte 5 dropped support for the old slot implementation in exchange for prop-based "snippets". Continue
41
+ // supporting string snippets in Playwright
42
+ slots = Object.fromEntries(
43
+ Object.entries(slots ?? {}).map(([key, snippet]) => {
44
+ if (typeof snippet === "string") {
45
+ return [key, createRawSnippet(() => ({ render: () => snippet }))];
46
+ }
47
+
48
+ return [key, snippet]
49
+ })
50
+ );
51
+
52
+ return { ...props, ...slots };
66
53
  }
67
54
 
68
55
  const __pwSvelteComponentKey = Symbol('svelteComponent');
@@ -71,23 +58,20 @@ window.playwrightMount = async (component, rootElement, hooksConfig) => {
71
58
  if (!isObjectComponent(component))
72
59
  throw new Error('JSX mount notation is not supported');
73
60
 
74
- const objectComponent = component;
75
- const componentCtor = component.type;
61
+ const componentCtor = asClassComponent(component.type);
62
+ const props = extractProps(component);
76
63
 
77
64
  class App extends componentCtor {
78
65
  constructor(options = {}) {
79
66
  super({
80
67
  target: rootElement,
81
- props: {
82
- ...objectComponent.props,
83
- $$slots: __pwCreateSlots(objectComponent.slots),
84
- $$scope: {},
85
- },
68
+ props,
86
69
  ...options
87
70
  });
88
71
  }
89
72
  }
90
73
 
74
+ /** @type {SvelteComponent | undefined} */
91
75
  let svelteComponent;
92
76
  for (const hook of window.__pw_hooks_before_mount || [])
93
77
  svelteComponent = await hook({ hooksConfig, App });
@@ -97,9 +81,6 @@ window.playwrightMount = async (component, rootElement, hooksConfig) => {
97
81
 
98
82
  rootElement[__pwSvelteComponentKey] = svelteComponent;
99
83
 
100
- for (const [key, listener] of Object.entries(objectComponent.on || {}))
101
- svelteComponent.$on(key, event => listener(event.detail));
102
-
103
84
  for (const hook of window.__pw_hooks_after_mount || [])
104
85
  await hook({ hooksConfig, svelteComponent });
105
86
  };
@@ -120,9 +101,5 @@ window.playwrightUpdate = async (rootElement, component) => {
120
101
  if (!svelteComponent)
121
102
  throw new Error('Component was not mounted');
122
103
 
123
- for (const [key, listener] of Object.entries(component.on || {}))
124
- svelteComponent.$on(key, event => listener(event.detail));
125
-
126
- if (component.props)
127
- svelteComponent.$set(component.props);
104
+ svelteComponent.$set(extractProps(component));
128
105
  };