Skip to content

Commit 9659e48

Browse files
lemonmaderobin-drexler
authored andcommitted
e2e tests for legacy adapter
1 parent 778e18b commit 9659e48

File tree

11 files changed

+234
-92
lines changed

11 files changed

+234
-92
lines changed

e2e/basic.e2e.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ import {test, expect} from '@playwright/test';
3030
dialog.dismiss().catch(() => {});
3131
});
3232

33+
const dialogPromise = page.waitForEvent('dialog');
3334
await page.getByRole('button', {name: 'Close'}).click();
34-
await page.waitForEvent('dialog');
35+
await dialogPromise;
3536
});
3637
});

e2e/remote-ui-legacy.e2e.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import {test, expect} from '@playwright/test';
2+
const sandbox = 'iframe';
3+
const example = 'react';
4+
5+
test.use({baseURL: 'http://localhost:8081'});
6+
7+
test(`basic modal interaction remote-ui legacy rendered example`, async ({
8+
page,
9+
}) => {
10+
await page.goto(`/`);
11+
12+
await page.getByRole('button', {name: 'Open modal'}).click();
13+
await page.getByRole('button', {name: 'Click me!'}).click();
14+
await page.getByRole('button', {name: 'Click me!'}).click();
15+
16+
await expect(page.getByText('Click Count: 2')).toBeVisible();
17+
18+
page.once('dialog', (dialog) => {
19+
expect(dialog.message()).toBe('You clicked 2 times!');
20+
dialog.accept().catch(() => {});
21+
});
22+
23+
const dialogPromise = page.waitForEvent('dialog');
24+
25+
await page.getByRole('button', {name: 'Close'}).click();
26+
await dialogPromise;
27+
});

examples/remote-ui/app/host/components.tsx

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
import {type ComponentChildren} from 'preact';
22
import {forwardRef} from 'preact/compat';
3-
import {useRef, useImperativeHandle, useEffect} from 'preact/hooks';
3+
import {
4+
useRef,
5+
useImperativeHandle,
6+
useEffect,
7+
useLayoutEffect,
8+
useState,
9+
useMemo,
10+
} from 'preact/hooks';
11+
import {createContext, useContext} from 'preact/compat';
412

513
import type {
614
ButtonProperties,
@@ -31,15 +39,14 @@ export function Button({
3139
children?: ComponentChildren;
3240
modal?: ComponentChildren;
3341
} & ButtonProperties) {
34-
console.log('#modal', modal);
3542
return (
3643
<>
3744
<button
3845
class="Button"
3946
type="button"
40-
onClick={() =>
41-
onPress?.() ?? document.querySelector('dialog')?.showModal()
42-
}
47+
onClick={() => {
48+
onPress?.();
49+
}}
4350
>
4451
{children}
4552
</button>
@@ -67,30 +74,11 @@ export const Modal = forwardRef<
6774
children?: ComponentChildren;
6875
primaryAction?: ComponentChildren;
6976
} & ModalProperties
70-
>(function Modal({children, primaryAction, onClose}, ref) {
71-
const dialogRef = useRef<HTMLDialogElement>(null);
72-
73-
useImperativeHandle(ref, () => ({
74-
open() {
75-
dialogRef.current?.showModal();
76-
},
77-
close() {
78-
dialogRef.current?.close();
79-
},
80-
}));
81-
82-
useEffect(() => {
83-
dialogRef.current?.showModal();
84-
85-
return () => {
86-
dialogRef.current?.close();
87-
};
88-
}, [dialogRef.current]);
89-
77+
>(function Modal({children, primaryAction}) {
9078
return (
91-
<dialog ref={dialogRef} class="Modal" onClose={() => onClose?.()}>
79+
<div class="Modal">
9280
<div class="Modal-Content">{children}</div>
9381
{primaryAction && <div class="Modal-Actions">{primaryAction}</div>}
94-
</dialog>
82+
</div>
9583
);
9684
});
Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,60 @@
11
/** @jsxRuntime automatic */
22
/** @jsxImportSource react */
33

4-
import {useEffect, useState} from 'react';
4+
import {useState} from 'react';
55
import {Button, Modal, Stack, Text} from './components';
66

7-
export function App() {
8-
const [counter, setCounter] = useState(0);
7+
export function App({api}: {api: any}) {
8+
const [showModal, setShowModal] = useState(false);
9+
const [count, setCount] = useState(0);
910

10-
useEffect(() => {
11-
const timer = setTimeout(() => {
12-
setCounter(counter + 1);
13-
}, 1000);
14-
15-
return () => clearTimeout(timer);
16-
}, [counter]);
11+
function removeModal() {
12+
setShowModal(false);
13+
}
1714

1815
return (
19-
<Stack>
20-
<Button
21-
onPress={() => setCounter(counter + 1)}
22-
modal={counter === 0 ? <Modal>Hello</Modal> : undefined}
23-
>
24-
Update counter
25-
</Button>
26-
<Text>Counter: {counter}</Text>
16+
<Stack spacing>
17+
<>
18+
<Text>
19+
Rendering example: <Text emphasis>remote-ui legacy</Text>
20+
</Text>
21+
<Button
22+
onPress={() => setShowModal(true)}
23+
modal={
24+
showModal ? (
25+
<Modal
26+
primaryAction={
27+
<Button
28+
onPress={() => {
29+
removeModal();
30+
if (count > 0) {
31+
alert(`You clicked ${count} times!`);
32+
}
33+
}}
34+
>
35+
Close
36+
</Button>
37+
}
38+
>
39+
<Stack spacing>
40+
<Text>
41+
Click count: <Text emphasis>{count}</Text>
42+
</Text>
43+
<Button
44+
onPress={() => {
45+
setCount((count) => count + 1);
46+
}}
47+
>
48+
Click me!
49+
</Button>
50+
</Stack>
51+
</Modal>
52+
) : undefined
53+
}
54+
>
55+
Open modal
56+
</Button>
57+
</>
2758
</Stack>
2859
);
2960
}

examples/remote-ui/app/remote/components.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ export const Stack = createRemoteReactComponent<'Stack', StackProperties>(
1616
);
1717
export const Modal = createRemoteReactComponent<'Modal', ModalProperties>(
1818
'Modal',
19+
{fragmentProps: ['primaryAction']},
1920
);

examples/remote-ui/app/remote/remote.tsx

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,7 @@ endpoint.expose({
1515
components: Object.keys(components),
1616
});
1717

18-
const modal = remoteRoot.createFragment();
19-
modal.appendChild(remoteRoot.createComponent('Modal', {}, ['Hello']));
20-
const button = remoteRoot.createComponent('Button', {modal}, ['click me']);
21-
22-
remoteRoot.appendChild(button);
23-
24-
setTimeout(() => {
25-
const mewModal = remoteRoot.createFragment();
26-
mewModal.appendChild(
27-
remoteRoot.createComponent('Modal', {}, ['Hello from the new side']),
28-
);
29-
30-
button.updateProps({modal: mewModal});
31-
}, 1000);
32-
33-
// createRoot(remoteRoot).render(<App />);
18+
createRoot(remoteRoot).render(<App />);
3419
remoteRoot.mount();
3520
},
3621
});

examples/remote-ui/app/style.css

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,6 @@ li {
164164
background: rgba(9, 9, 11, 0.65);
165165
}
166166

167-
.Modal[open] {
168-
animation: OpenModal 0.2s ease normal;
169-
}
170-
171-
.Modal:not([open]) {
172-
display: none;
173-
}
174-
175167
@keyframes OpenModal {
176168
from {
177169
opacity: 0;

examples/remote-ui/app/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ export interface ModalProperties {
3737
* Remote DOM, this property can be set using `addEventListener('press')`.
3838
*/
3939
onClose?(): void;
40+
41+
primaryAction?: RemoteFragment;
4042
}
4143

4244
export interface ModalMethods {

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@
2222
"example:kitchen-sink": "pnpm run --filter example-kitchen-sink start"
2323
},
2424
"devDependencies": {
25+
"wait-on": "^8.0.1",
2526
"@changesets/changelog-github": "^0.5.0",
2627
"@changesets/cli": "^2.27.0",
27-
"@playwright/test": "^1.48.2",
28+
"@playwright/test": "^1.49.0",
2829
"@quilted/rollup": "^0.2.45",
2930
"@quilted/typescript": "^0.4.2",
3031
"@quilted/vite": "^0.1.27",
3132
"@types/node": "~20.11.0",
3233
"jsdom": "^25.0.0",
33-
"playwright": "^1.48.2",
34+
"playwright": "^1.49.0",
3435
"prettier": "^3.3.3",
3536
"rollup": "^4.21.0",
3637
"tsx": "^4.19.0",

playwright.config.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,16 @@ export default defineConfig({
3232
],
3333

3434
// Run your local dev server before starting the tests
35-
webServer: {
36-
command: 'pnpm run example:kitchen-sink --port 8080',
37-
url: 'http://localhost:8080',
38-
reuseExistingServer: !process.env.CI,
39-
},
35+
webServer: [
36+
{
37+
command: 'pnpm run example:kitchen-sink --port 8080',
38+
url: 'http://localhost:8080',
39+
reuseExistingServer: !process.env.CI,
40+
},
41+
{
42+
command: 'pnpm run example:remote-ui --port 8081',
43+
url: 'http://localhost:8081',
44+
reuseExistingServer: !process.env.CI,
45+
},
46+
],
4047
});

0 commit comments

Comments
 (0)