Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/playwright-ct-react/hooks.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type JsonValue = JsonPrimitive | JsonObject | JsonArray;
type JsonArray = JsonValue[];
type JsonObject = { [Key in string]?: JsonValue };
export declare function beforeMount<HooksConfig extends JsonObject>(
callback: (params: { hooksConfig: HooksConfig }) => Promise<void>
callback: (params: { hooksConfig: HooksConfig; App: () => JSX.Element }) => Promise<void | JSX.Element>
): void;
export declare function afterMount<HooksConfig extends JsonObject>(
callback: (params: { hooksConfig: HooksConfig }) => Promise<void>
Expand Down
11 changes: 8 additions & 3 deletions packages/playwright-ct-react/registerSource.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export function register(components) {

/**
* @param {Component} component
* @returns {JSX.Element}
*/
function render(component) {
let componentFunc = registry.get(component.type);
Expand Down Expand Up @@ -69,10 +70,14 @@ function render(component) {
}

window.playwrightMount = async (component, rootElement, hooksConfig) => {
for (const hook of /** @type {any} */(window).__pw_hooks_before_mount || [])
await hook({ hooksConfig });
let App = () => render(component);
for (const hook of /** @type {any} */(window).__pw_hooks_before_mount || []) {
const wrapper = await hook({ App, hooksConfig });
if (wrapper)
App = () => wrapper;
}

ReactDOM.render(render(component), rootElement);
ReactDOM.render(App(), rootElement);

for (const hook of /** @type {any} */(window).__pw_hooks_after_mount || [])
await hook({ hooksConfig });
Expand Down
4 changes: 3 additions & 1 deletion packages/playwright-ct-solid/hooks.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
* limitations under the License.
*/

import { JSXElement } from "solid-js";

type JsonPrimitive = string | number | boolean | null;
type JsonValue = JsonPrimitive | JsonObject | JsonArray;
type JsonArray = JsonValue[];
type JsonObject = { [Key in string]?: JsonValue };
export declare function beforeMount<HooksConfig extends JsonObject>(
callback: (params: { hooksConfig: HooksConfig }) => Promise<void>
callback: (params: { hooksConfig: HooksConfig, App: () => JSXElement }) => Promise<void | JSXElement>
): void;
export declare function afterMount<HooksConfig extends JsonObject>(
callback: (params: { hooksConfig: HooksConfig }) => Promise<void>
Expand Down
10 changes: 7 additions & 3 deletions packages/playwright-ct-solid/registerSource.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,14 @@ function createComponent(component) {
const unmountKey = Symbol('unmountKey');

window.playwrightMount = async (component, rootElement, hooksConfig) => {
for (const hook of /** @type {any} */(window).__pw_hooks_before_mount || [])
await hook({ hooksConfig });
let App = () => createComponent(component);
for (const hook of /** @type {any} */(window).__pw_hooks_before_mount || []) {
const wrapper = await hook({ App, hooksConfig });
if (wrapper)
App = () => wrapper;
}

const unmount = solidRender(() => createComponent(component), rootElement);
const unmount = solidRender(App, rootElement);
rootElement[unmountKey] = unmount;

for (const hook of /** @type {any} */(window).__pw_hooks_after_mount || [])
Expand Down
2 changes: 1 addition & 1 deletion tests/components/ct-react-vite/playwright/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
</head>
<body>
<div id="root"></div>
<script type="module" src="./index.ts"></script>
<script type="module" src="./index.tsx"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
//@ts-check
import '../src/assets/index.css';
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;
route?: string;
routing?: boolean;
}

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

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

afterMount<HooksConfig>(async () => {
Expand Down
5 changes: 3 additions & 2 deletions tests/components/ct-react-vite/src/tests.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { test, expect } from '@playwright/experimental-ct-react';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
import Button from './components/Button';
import DefaultChildren from './components/DefaultChildren';
Expand Down Expand Up @@ -143,7 +142,9 @@ test('get textContent of the empty fragment', async ({ mount }) => {
});

test('navigate to a page by clicking a link', async ({ page, mount }) => {
const component = await mount(<BrowserRouter><App /></BrowserRouter>);
const component = await mount<HooksConfig>(<App />, {
hooksConfig: { routing: true }
});
await expect(component.getByRole('main')).toHaveText('Login');
await expect(page).toHaveURL('/');
await component.getByRole('link', { name: 'Dashboard' }).click();
Expand Down
2 changes: 1 addition & 1 deletion tests/components/ct-react/playwright/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
</head>
<body>
<div id="root"></div>
<script type="module" src="./index.ts"></script>
<script type="module" src="./index.tsx"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import '../src/assets/index.css';
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;
route?: string;
routing?: boolean;
}

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

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

afterMount<HooksConfig>(async () => {
Expand Down
5 changes: 3 additions & 2 deletions tests/components/ct-react/src/tests.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { test, expect } from '@playwright/experimental-ct-react';
const { serverFixtures } = require('../../../../tests/config/serverFixtures');
import { BrowserRouter } from 'react-router-dom';
import App from './App';
import Fetch from './components/Fetch';
import DelayedData from './components/DelayedData';
Expand Down Expand Up @@ -151,7 +150,9 @@ test('get textContent of the empty fragment', async ({ mount }) => {
});

test('navigate to a page by clicking a link', async ({ page, mount }) => {
const component = await mount(<BrowserRouter><App /></BrowserRouter>);
const component = await mount<HooksConfig>(<App />, {
hooksConfig: { routing: true }
});
await expect(component.getByRole('main')).toHaveText('Login');
await expect(page).toHaveURL('/');
await component.getByRole('link', { name: 'Dashboard' }).click();
Expand Down
7 changes: 4 additions & 3 deletions tests/components/ct-solid/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
"typecheck": "tsc --noEmit"
},
"license": "MIT",
"dependencies": {
"@solidjs/router": "^0.5.0",
"solid-js": "^1.4.7"
},
"devDependencies": {
"typescript": "^4.7.4",
"vite": "^3.2.1",
"vite-plugin-solid": "^2.3.10"
},
"dependencies": {
"solid-js": "^1.4.7"
},
"@standaloneDevDependencies": {
"@playwright/experimental-ct-solid": "^1.22.2",
"@playwright/test": "^1.22.2"
Expand Down
2 changes: 1 addition & 1 deletion tests/components/ct-solid/playwright/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
</head>
<body>
<div id="root"></div>
<script type="module" src="./index.ts"></script>
<script type="module" src="./index.tsx"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import '../src/assets/index.css';
import { beforeMount, afterMount } from '@playwright/experimental-ct-solid/hooks';
import { Router } from "@solidjs/router";
import '../src/assets/index.css';

export type HooksConfig = {
route: string;
route?: string;
routing?: boolean;
}

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

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

afterMount<HooksConfig>(async () => {
Expand Down
33 changes: 0 additions & 33 deletions tests/components/ct-solid/src/App.module.css

This file was deleted.

41 changes: 17 additions & 24 deletions tests/components/ct-solid/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
import type { Component } from 'solid-js';

import { Routes, Route, A } from "@solidjs/router"
import logo from './assets/logo.svg';
import styles from './App.module.css';
import LoginPage from './pages/LoginPage';
import DashboardPage from './pages/DashboardPage';

const App: Component = () => {
return (
<div class={styles.App}>
<header class={styles.header}>
<img src={logo} class={styles.logo} alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
class={styles.link}
href="https://github.com/solidjs/solid"
target="_blank"
rel="noopener noreferrer"
>
Learn Solid
</a>
</header>
</div>
);
export default function App() {
return <>
<header>
<img src={logo} alt="logo" width={125} height={125} />
<A href="/">Login</A>
<A href="/dashboard">Dashboard</A>
</header>
<Routes>
<Route path="/">
<Route path="/" component={LoginPage} />
<Route path="dashboard" component={DashboardPage} />
</Route>
</Routes>
</>
};

export default App;
3 changes: 2 additions & 1 deletion tests/components/ct-solid/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* @refresh reload */
import { render } from 'solid-js/web';
import { Router } from "@solidjs/router";
import App from './App';
import './assets/index.css';

render(() => <App />, document.getElementById('root') as HTMLElement);
render(() => <Router><App /></Router>, document.getElementById('root')!);
3 changes: 3 additions & 0 deletions tests/components/ct-solid/src/pages/DashboardPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function DashboardPage() {
return <main>Dashboard</main>
}
3 changes: 3 additions & 0 deletions tests/components/ct-solid/src/pages/LoginPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function LoginPage() {
return <main>Login</main>
}
46 changes: 25 additions & 21 deletions tests/components/ct-solid/src/tests.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { test, expect } from '@playwright/experimental-ct-solid';
import App from './App';
import Button from './components/Button';
import Counter from './components/Counter';
import DefaultChildren from './components/DefaultChildren';
Expand Down Expand Up @@ -81,19 +82,15 @@ test('execute callback when the button is clicked', async ({ mount }) => {
});

test('render a default child', async ({ mount }) => {
const component = await mount(
<DefaultChildren>Main Content</DefaultChildren>
);
const component = await mount(<DefaultChildren>Main Content</DefaultChildren>);
await expect(component).toContainText('Main Content');
});

test('render multiple children', async ({ mount }) => {
const component = await mount(
<DefaultChildren>
<div id="one">One</div>
<div id="two">Two</div>
</DefaultChildren>
);
const component = await mount(<DefaultChildren>
<div id="one">One</div>
<div id="two">Two</div>
</DefaultChildren>);
await expect(component.locator('#one')).toContainText('One');
await expect(component.locator('#two')).toContainText('Two');
});
Expand All @@ -107,25 +104,21 @@ test('render a component as slot', async ({ mount }) => {
});

test('render named children', async ({ mount }) => {
const component = await mount(
<MultipleChildren>
<div>Header</div>
<div>Main Content</div>
<div>Footer</div>
</MultipleChildren>
);
const component = await mount(<MultipleChildren>
<div>Header</div>
<div>Main Content</div>
<div>Footer</div>
</MultipleChildren>);
await expect(component).toContainText('Header');
await expect(component).toContainText('Main Content');
await expect(component).toContainText('Footer');
});

test('execute callback when a child node is clicked', async ({ mount }) => {
let clickFired = false;
const component = await mount(
<DefaultChildren>
<span onClick={() => (clickFired = true)}>Main Content</span>
</DefaultChildren>
);
const component = await mount(<DefaultChildren>
<span onClick={() => (clickFired = true)}>Main Content</span>
</DefaultChildren>);
await component.locator('text=Main Content').click();
expect(clickFired).toBeTruthy();
});
Expand Down Expand Up @@ -163,3 +156,14 @@ test('get textContent of the empty fragment', async ({ mount }) => {
expect(await component.textContent()).toBe('');
await expect(component).toHaveText('');
});

test('navigate to a page by clicking a link', async ({ page, mount }) => {
const component = await mount<HooksConfig>(<App />, {
hooksConfig: { routing: true }
});
await expect(component.getByRole('main')).toHaveText('Login');
await expect(page).toHaveURL('/');
await component.getByRole('link', { name: 'Dashboard' }).click();
await expect(component.getByRole('main')).toHaveText('Dashboard');
await expect(page).toHaveURL('/dashboard');
});
Loading