feat(ct): svelte vite context (#26554)

This commit is contained in:
Sander 2023-08-20 01:26:06 +02:00 committed by GitHub
parent 192b697488
commit e2a11bed19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 55 additions and 20 deletions

View File

@ -14,11 +14,14 @@
* limitations under the License.
*/
import type { SvelteComponent } from 'svelte';
import type { ComponentConstructorOptions, SvelteComponent } from 'svelte';
import type { JsonObject } from '@playwright/experimental-ct-core/types/component';
export declare function beforeMount<HooksConfig extends JsonObject>(
callback: (params: { hooksConfig?: HooksConfig }) => Promise<void>
callback: (params: {
hooksConfig?: HooksConfig,
App: new (options: Partial<ComponentConstructorOptions>) => SvelteComponent
}) => Promise<SvelteComponent | void>
): void;
export declare function afterMount<HooksConfig extends JsonObject>(
callback: (params: {

View File

@ -52,7 +52,7 @@ function isComponent(component) {
*/
async function __pwResolveComponent(component) {
if (!isComponent(component))
return
return;
let componentFactory = __pwLoaderRegistry.get(component.type);
if (!componentFactory) {
@ -68,7 +68,7 @@ async function __pwResolveComponent(component) {
if (!componentFactory)
throw new Error(`Unregistered component: ${component.type}. Following components are registered: ${[...__pwRegistry.keys()]}`);
if(componentFactory)
if (componentFactory)
__pwRegistry.set(component.type, await componentFactory())
if ('children' in component)
@ -84,8 +84,8 @@ function __pwCreateSlots(slots) {
for (const slotName in slots) {
const template = document
.createRange()
.createContextualFragment(slots[slotName]);
.createRange()
.createContextualFragment(slots[slotName]);
svelteSlots[slotName] = [createSlotFn(template)];
}
@ -111,22 +111,31 @@ const __pwSvelteComponentKey = Symbol('svelteComponent');
window.playwrightMount = async (component, rootElement, hooksConfig) => {
await __pwResolveComponent(component);
const componentCtor = __pwRegistry.get(component.type);
if (component.kind !== 'object')
throw new Error('JSX mount notation is not supported');
for (const hook of window.__pw_hooks_before_mount || [])
await hook({ hooksConfig });
const svelteComponent = /** @type {SvelteComponent} */ (new componentCtor({
target: rootElement,
props: {
...component.options?.props,
$$slots: __pwCreateSlots(component.options?.slots),
$$scope: {},
class App extends componentCtor {
constructor(options = {}) {
super({
target: rootElement,
props: {
...component.options?.props,
$$slots: __pwCreateSlots(component.options?.slots),
$$scope: {},
},
...options
});
}
}));
}
let svelteComponent;
for (const hook of window.__pw_hooks_before_mount || [])
svelteComponent = await hook({ hooksConfig, App });
if (!svelteComponent)
svelteComponent = new App();
rootElement[__pwSvelteComponentKey] = svelteComponent;
for (const [key, listener] of Object.entries(component.options?.on || {}))

View File

@ -2,11 +2,17 @@ import '../src/assets/index.css';
import { beforeMount, afterMount } from '@playwright/experimental-ct-svelte/hooks';
export type HooksConfig = {
route: string;
context?: string;
route?: string;
}
beforeMount<HooksConfig>(async ({ hooksConfig }) => {
beforeMount<HooksConfig>(async ({ hooksConfig, App }) => {
console.log(`Before mount: ${JSON.stringify(hooksConfig)}`);
return new App({
context: new Map([
['context-key', hooksConfig?.context]
]),
});
});
afterMount<HooksConfig>(async () => {

View File

@ -0,0 +1,6 @@
<script lang="ts">
import { getContext } from 'svelte';
const contextValue = getContext('context-key');
</script>
<div>{contextValue}</div>

View File

@ -1,6 +1,8 @@
import { test, expect } from '@playwright/experimental-ct-svelte';
import type { HooksConfig } from 'playwright';
import Button from '@/components/Button.svelte';
import Empty from '@/components/Empty.svelte';
import Context from '@/components/Context.svelte';
test('render props', async ({ mount }) => {
const component = await mount(Button, {
@ -17,3 +19,12 @@ test('get textContent of the empty component', async ({ mount }) => {
expect(await component.textContent()).toBe('');
await expect(component).toHaveText('');
});
test('render context', async ({ mount }) => {
const component = await mount<HooksConfig>(Context, {
hooksConfig: {
context: 'context-value',
}
});
await expect(component).toContainText('context-value');
});