Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ct): resolve hooksConfig import refs #30455

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/playwright-ct-core/src/mount.ts
Expand Up @@ -102,6 +102,7 @@ async function innerMount(page: Page, componentRef: JsxComponent | ImportRef, op

const selector = await page.evaluate(async ({ component, hooksConfig }) => {
component = await window.__pwUnwrapObject(component);
hooksConfig = await window.__pwUnwrapObject(hooksConfig);
let rootElement = document.getElementById('root');
if (!rootElement) {
rootElement = document.createElement('div');
Expand Down
15 changes: 5 additions & 10 deletions packages/playwright-ct-core/types/component.d.ts
Expand Up @@ -14,11 +14,6 @@
* limitations under the License.
*/

type JsonPrimitive = string | number | boolean | null;
type JsonValue = JsonPrimitive | JsonObject | JsonArray;
type JsonArray = JsonValue[];
export type JsonObject = { [Key in string]?: JsonValue };
sand4rt marked this conversation as resolved.
Show resolved Hide resolved

export type JsxComponent = {
__pw_type: 'jsx',
type: any,
Expand Down Expand Up @@ -47,15 +42,15 @@ declare global {
playwrightMount(component: Component, rootElement: Element, hooksConfig?: any): Promise<void>;
playwrightUnmount(rootElement: Element): Promise<void>;
playwrightUpdate(rootElement: Element, component: Component): Promise<void>;
__pw_hooks_before_mount?: (<HooksConfig extends JsonObject = JsonObject>(
__pw_hooks_before_mount?: (<HooksConfig>(
params: { hooksConfig?: HooksConfig; [key: string]: any }
) => Promise<any>)[];
__pw_hooks_after_mount?: (<HooksConfig extends JsonObject = JsonObject>(
__pw_hooks_after_mount?: (<HooksConfig>(
params: { hooksConfig?: HooksConfig; [key: string]: any }
) => Promise<void>)[];
// Can't start with __pw due to core reuse bindings logic for __pw*.
__ctDispatchFunction: (ordinal: number, args: any[]) => void;
__pwUnwrapObject: (value: any) => Promise<any>;
__pwTransformObject: (value: any, mapping: (v: any) => { result: any } | undefined) => any;
__ctDispatchFunction(ordinal: number, args: any[]): void;
__pwUnwrapObject(value: any): Promise<any>;
__pwTransformObject(value: any, mapping: (v: any) => { result: any } | undefined): any;
}
}
6 changes: 3 additions & 3 deletions packages/playwright-ct-react/hooks.d.ts
Expand Up @@ -14,11 +14,11 @@
* limitations under the License.
*/

import type { JsonObject } from '@playwright/experimental-ct-core/types/component';
export interface RegisterHooksConfig {}
sand4rt marked this conversation as resolved.
Show resolved Hide resolved

export declare function beforeMount<HooksConfig extends JsonObject>(
export declare function beforeMount<HooksConfig = RegisterHooksConfig>(
callback: (params: { hooksConfig?: HooksConfig; App: () => JSX.Element }) => Promise<void | JSX.Element>
): void;
export declare function afterMount<HooksConfig extends JsonObject>(
export declare function afterMount<HooksConfig = RegisterHooksConfig>(
callback: (params: { hooksConfig?: HooksConfig }) => Promise<void>
): void;
6 changes: 3 additions & 3 deletions packages/playwright-ct-react/index.d.ts
Expand Up @@ -15,10 +15,10 @@
*/

import type { Locator } from 'playwright/test';
import type { JsonObject } from '@playwright/experimental-ct-core/types/component';
import type { TestType } from '@playwright/experimental-ct-core';
import type { RegisterHooksConfig } from './hooks';

export interface MountOptions<HooksConfig extends JsonObject> {
export interface MountOptions<HooksConfig extends RegisterHooksConfig> {
hooksConfig?: HooksConfig;
}

Expand All @@ -28,7 +28,7 @@ export interface MountResult extends Locator {
}

export const test: TestType<{
mount<HooksConfig extends JsonObject>(
mount<HooksConfig extends RegisterHooksConfig>(
component: JSX.Element,
options?: MountOptions<HooksConfig>
): Promise<MountResult>;
Expand Down
6 changes: 3 additions & 3 deletions packages/playwright-ct-react17/hooks.d.ts
Expand Up @@ -14,11 +14,11 @@
* limitations under the License.
*/

import type { JsonObject } from '@playwright/experimental-ct-core/types/component';
export interface RegisterHooksConfig {}

export declare function beforeMount<HooksConfig extends JsonObject>(
export declare function beforeMount<HooksConfig = RegisterHooksConfig>(
callback: (params: { hooksConfig?: HooksConfig; App: () => JSX.Element }) => Promise<void | JSX.Element>
): void;
export declare function afterMount<HooksConfig extends JsonObject>(
export declare function afterMount<HooksConfig = RegisterHooksConfig>(
callback: (params: { hooksConfig?: HooksConfig }) => Promise<void>
): void;
6 changes: 3 additions & 3 deletions packages/playwright-ct-react17/index.d.ts
Expand Up @@ -15,10 +15,10 @@
*/

import type { Locator } from 'playwright/test';
import type { JsonObject } from '@playwright/experimental-ct-core/types/component';
import type { TestType } from '@playwright/experimental-ct-core';
import type { RegisterHooksConfig } from './hooks';

export interface MountOptions<HooksConfig extends JsonObject> {
export interface MountOptions<HooksConfig extends RegisterHooksConfig> {
hooksConfig?: HooksConfig;
}

Expand All @@ -28,7 +28,7 @@ export interface MountResult extends Locator {
}

export const test: TestType<{
mount<HooksConfig extends JsonObject>(
mount<HooksConfig extends RegisterHooksConfig>(
component: JSX.Element,
options?: MountOptions<HooksConfig>
): Promise<MountResult>;
Expand Down
9 changes: 5 additions & 4 deletions packages/playwright-ct-solid/hooks.d.ts
Expand Up @@ -14,12 +14,13 @@
* limitations under the License.
*/

import { JSXElement } from "solid-js";
import type { JsonObject } from '@playwright/experimental-ct-core/types/component';
import type { JSXElement } from 'solid-js';

export declare function beforeMount<HooksConfig extends JsonObject>(
export interface RegisterHooksConfig {}

export declare function beforeMount<HooksConfig extends RegisterHooksConfig>(
callback: (params: { hooksConfig?: HooksConfig, App: () => JSXElement }) => Promise<void | JSXElement>
): void;
export declare function afterMount<HooksConfig extends JsonObject>(
export declare function afterMount<HooksConfig extends RegisterHooksConfig>(
callback: (params: { hooksConfig?: HooksConfig }) => Promise<void>
): void;
6 changes: 3 additions & 3 deletions packages/playwright-ct-solid/index.d.ts
Expand Up @@ -15,10 +15,10 @@
*/

import type { Locator } from 'playwright/test';
import type { JsonObject } from '@playwright/experimental-ct-core/types/component';
import type { TestType } from '@playwright/experimental-ct-core';
import type { RegisterHooksConfig } from './hooks';

export interface MountOptions<HooksConfig extends JsonObject> {
export interface MountOptions<HooksConfig extends RegisterHooksConfig> {
hooksConfig?: HooksConfig;
}

Expand All @@ -28,7 +28,7 @@ export interface MountResult extends Locator {
}

export const test: TestType<{
mount<HooksConfig extends JsonObject>(
mount<HooksConfig extends RegisterHooksConfig>(
component: JSX.Element,
options?: MountOptions<HooksConfig>
): Promise<MountResult>;
Expand Down
7 changes: 4 additions & 3 deletions packages/playwright-ct-svelte/hooks.d.ts
Expand Up @@ -15,15 +15,16 @@
*/

import type { ComponentConstructorOptions, SvelteComponent } from 'svelte';
import type { JsonObject } from '@playwright/experimental-ct-core/types/component';

export declare function beforeMount<HooksConfig extends JsonObject>(
export interface RegisterHooksConfig {}

export declare function beforeMount<HooksConfig extends RegisterHooksConfig>(
callback: (params: {
hooksConfig?: HooksConfig,
App: new (options: Partial<ComponentConstructorOptions>) => SvelteComponent
}) => Promise<SvelteComponent | void>
): void;
export declare function afterMount<HooksConfig extends JsonObject>(
export declare function afterMount<HooksConfig extends RegisterHooksConfig>(
callback: (params: {
hooksConfig?: HooksConfig;
svelteComponent: SvelteComponent;
Expand Down
6 changes: 3 additions & 3 deletions packages/playwright-ct-svelte/index.d.ts
Expand Up @@ -15,15 +15,15 @@
*/

import type { Locator } from 'playwright/test';
import type { JsonObject } from '@playwright/experimental-ct-core/types/component';
import type { SvelteComponent, ComponentProps } from 'svelte/types/runtime';
import type { TestType } from '@playwright/experimental-ct-core';
import type { RegisterHooksConfig } from './hooks';

type ComponentSlot = string | string[];
type ComponentSlots = Record<string, ComponentSlot> & { default?: ComponentSlot };
type ComponentEvents = Record<string, Function>;

export interface MountOptions<HooksConfig extends JsonObject, Component extends SvelteComponent> {
export interface MountOptions<HooksConfig extends RegisterHooksConfig, Component extends SvelteComponent> {
props?: ComponentProps<Component>;
slots?: ComponentSlots;
on?: ComponentEvents;
Expand All @@ -39,7 +39,7 @@ export interface MountResult<Component extends SvelteComponent> extends Locator
}

export const test: TestType<{
mount<HooksConfig extends JsonObject, Component extends SvelteComponent = SvelteComponent>(
mount<HooksConfig extends RegisterHooksConfig, Component extends SvelteComponent = SvelteComponent>(
component: new (...args: any[]) => Component,
options?: MountOptions<HooksConfig, Component>
): Promise<MountResult<Component>>;
Expand Down
7 changes: 4 additions & 3 deletions packages/playwright-ct-vue/hooks.d.ts
Expand Up @@ -15,12 +15,13 @@
*/

import type { App, ComponentPublicInstance } from 'vue';
import type { JsonObject } from '@playwright/experimental-ct-core/types/component';

export declare function beforeMount<HooksConfig extends JsonObject>(
export interface RegisterHooksConfig {}

export declare function beforeMount<HooksConfig = RegisterHooksConfig>(
callback: (params: { app: App; hooksConfig?: HooksConfig }) => Promise<void>
): void;
export declare function afterMount<HooksConfig extends JsonObject>(
export declare function afterMount<HooksConfig = RegisterHooksConfig>(
callback: (params: {
app: App;
hooksConfig?: HooksConfig;
Expand Down
10 changes: 5 additions & 5 deletions packages/playwright-ct-vue/index.d.ts
Expand Up @@ -15,7 +15,7 @@
*/

import type { Locator } from 'playwright/test';
import type { JsonObject } from '@playwright/experimental-ct-core/types/component';
import type { RegisterHooksConfig } from './hooks';
import type { TestType } from '@playwright/experimental-ct-core';

type ComponentSlot = string | string[];
Expand All @@ -29,14 +29,14 @@ type ComponentProps<T> =
T extends (props: infer P, ...args: any) => any ? P :
{};

export interface MountOptions<HooksConfig extends JsonObject, Component> {
export interface MountOptions<HooksConfig extends RegisterHooksConfig, Component> {
props?: ComponentProps<Component>;
slots?: ComponentSlots;
on?: ComponentEvents;
hooksConfig?: HooksConfig;
}

export interface MountOptionsJsx<HooksConfig extends JsonObject> {
export interface MountOptionsJsx<HooksConfig extends RegisterHooksConfig> {
hooksConfig?: HooksConfig;
}

Expand All @@ -55,11 +55,11 @@ export interface MountResultJsx extends Locator {
}

export const test: TestType<{
mount<HooksConfig extends JsonObject>(
mount<HooksConfig extends RegisterHooksConfig>(
component: JSX.Element,
options: MountOptionsJsx<HooksConfig>
): Promise<MountResultJsx>;
mount<HooksConfig extends JsonObject, Component = unknown>(
mount<HooksConfig extends RegisterHooksConfig, Component = unknown>(
component: Component,
options?: MountOptions<HooksConfig, Component>
): Promise<MountResult<Component>>;
Expand Down
17 changes: 9 additions & 8 deletions packages/playwright-ct-vue2/hooks.d.ts
Expand Up @@ -14,17 +14,18 @@
* limitations under the License.
*/

import { ComponentOptions } from 'vue';
import { CombinedVueInstance, Vue, VueConstructor } from 'vue/types/vue';
import type { JsonObject } from '@playwright/experimental-ct-core/types/component';
import type { ComponentOptions } from 'vue';
import type { CombinedVueInstance, Vue, VueConstructor } from 'vue/types/vue';

export declare function beforeMount<HooksConfig extends JsonObject>(
callback: (params: {
hooksConfig?: HooksConfig,
Vue: VueConstructor<Vue>,
export interface RegisterHooksConfig {}

export declare function beforeMount<HooksConfig extends RegisterHooksConfig>(
callback: (params: {
hooksConfig?: HooksConfig,
Vue: VueConstructor<Vue>,
}) => Promise<void | ComponentOptions<Vue> & Record<string, unknown>>
): void;
export declare function afterMount<HooksConfig extends JsonObject>(
export declare function afterMount<HooksConfig extends RegisterHooksConfig>(
callback: (params: {
hooksConfig?: HooksConfig;
instance: CombinedVueInstance<
Expand Down
10 changes: 5 additions & 5 deletions packages/playwright-ct-vue2/index.d.ts
Expand Up @@ -15,8 +15,8 @@
*/

import type { Locator } from 'playwright/test';
import type { JsonObject } from '@playwright/experimental-ct-core/types/component';
import type { TestType } from '@playwright/experimental-ct-core';
import type { RegisterHooksConfig } from './hooks';

type Slot = string | string[];
type ComponentSlots = Record<string, Slot> & { default?: Slot };
Expand All @@ -29,14 +29,14 @@ type ComponentProps<T> =
T extends (props: infer P, ...args: any) => any ? P :
{};

export interface MountOptions<HooksConfig extends JsonObject, Component> {
export interface MountOptions<HooksConfig extends RegisterHooksConfig, Component> {
props?: ComponentProps<Component>;
slots?: ComponentSlots;
on?: ComponentEvents;
hooksConfig?: HooksConfig;
}

export interface MountOptionsJsx<HooksConfig extends JsonObject> {
export interface MountOptionsJsx<HooksConfig extends RegisterHooksConfig> {
hooksConfig?: HooksConfig;
}

Expand All @@ -55,11 +55,11 @@ export interface MountResultJsx extends Locator {
}

export const test: TestType<{
mount<HooksConfig extends JsonObject>(
mount<HooksConfig extends RegisterHooksConfig>(
component: JSX.Element,
options?: MountOptionsJsx<HooksConfig>
): Promise<MountResultJsx>;
mount<HooksConfig extends JsonObject, Component = unknown>(
mount<HooksConfig extends RegisterHooksConfig, Component = unknown>(
component: Component,
options?: MountOptions<HooksConfig, Component>
): Promise<MountResult<Component>>;
Expand Down
11 changes: 6 additions & 5 deletions tests/components/ct-react-vite/playwright/index.tsx
Expand Up @@ -2,18 +2,19 @@ import { beforeMount, afterMount } from '@playwright/experimental-ct-react/hooks
import { BrowserRouter } from 'react-router-dom';
import '../src/assets/index.css';

export type HooksConfig = {
route?: string;
routing?: boolean;
declare module '@playwright/experimental-ct-react/hooks' {
interface RegisterHooksConfig {
routing?: boolean;
}
}

beforeMount<HooksConfig>(async ({ hooksConfig, App }) => {
beforeMount(async ({ hooksConfig, App }) => {
console.log(`Before mount: ${JSON.stringify(hooksConfig)}`);

if (hooksConfig?.routing)
return <BrowserRouter><App /></BrowserRouter>;
});

afterMount<HooksConfig>(async () => {
afterMount(async () => {
console.log(`After mount`);
});
7 changes: 3 additions & 4 deletions tests/components/ct-react-vite/tests/react-router.spec.tsx
@@ -1,9 +1,8 @@
import { test, expect } from '@playwright/experimental-ct-react';
import App from '@/App';
import type { HooksConfig } from '../playwright';

test('navigate to a page by clicking a link', async ({ page, mount }) => {
const component = await mount<HooksConfig>(<App />, {
const component = await mount(<App />, {
hooksConfig: { routing: true },
});
await expect(component.getByRole('main')).toHaveText('Login');
Expand All @@ -13,8 +12,8 @@ test('navigate to a page by clicking a link', async ({ page, mount }) => {
await expect(page).toHaveURL('/dashboard');
});

test('update should not reset mount hooks', async ({ page, mount }) => {
const component = await mount<HooksConfig>(<App title='before'/>, {
test('update should not reset mount hooks', async ({ mount }) => {
const component = await mount(<App title="before"/>, {
hooksConfig: { routing: true },
});
await expect(component.getByRole('heading')).toHaveText('before');
Expand Down
1 change: 0 additions & 1 deletion tests/components/ct-react-vite/tsconfig.json
Expand Up @@ -21,6 +21,5 @@
"*": ["_"],
}
},
"include": ["src", "tests"],
"references": [{ "path": "./tsconfig.node.json" }]
}