Skip to content

Commit c558185

Browse files
committed
feat: component update
1 parent 5e7a686 commit c558185

File tree

6 files changed

+75
-32
lines changed

6 files changed

+75
-32
lines changed

Diff for: ct-web-lit/src/components/Counter.ts

+24-23
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,31 @@
11
import { LitElement, html } from 'lit';
2-
import { customElement } from 'lit/decorators.js';
2+
import { customElement, eventOptions, property } from 'lit/decorators.js';
3+
4+
let remountCount = 0
35

46
@customElement('pw-counter')
57
export class Counter extends LitElement {
8+
@property({ type: Number })
9+
count!: number;
10+
11+
constructor() {
12+
super();
13+
remountCount++;
14+
}
15+
16+
@eventOptions({ passive: true })
17+
onClick() {
18+
this.dispatchEvent(new CustomEvent('submit', { detail: 'hello' }));
19+
}
20+
621
render() {
7-
return html``;
22+
return html`
23+
<div @click=${this.onClick}>
24+
<div id="props">${this.count}</div>
25+
<div id="remount-count">${remountCount}</div>
26+
<slot name="main" />
27+
<slot />
28+
</div>
29+
`;
830
}
931
}
10-
11-
// Example vue implementation:
12-
13-
// <template>
14-
// <div @click="$emit('submit', 'hello')">
15-
// <div id="props">{{ count }}</div>
16-
// <div id="remount-count">{{ remountCount }}</div>
17-
// <slot name="main" />
18-
// <slot />
19-
// </div>
20-
// </template>
21-
22-
// <script lang="ts">
23-
// let remountCount = 0
24-
// </script>
25-
26-
// <script lang="ts" setup>
27-
// defineProps<{ count?: number }>()
28-
29-
// remountCount++
30-
// </script>

Diff for: ct-web-lit/src/tests.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ test('render props', async ({ mount }) => {
1717
await expect(component).toContainText('Submit');
1818
});
1919

20-
test.fixme('update props without remounting', async ({ mount }) => {
20+
test('update props without remounting', async ({ mount }) => {
2121
const component = await mount(Counter, {
2222
props: { count: 9001 },
2323
});
@@ -32,7 +32,7 @@ test.fixme('update props without remounting', async ({ mount }) => {
3232
await expect(component.locator('#remount-count')).toContainText('1');
3333
});
3434

35-
test.fixme('update event listeners without remounting', async ({ mount }) => {
35+
test('update event listeners without remounting', async ({ mount }) => {
3636
const component = await mount(Counter);
3737

3838
const messages: string[] = [];

Diff for: ct-web/src/components/Counter.ts

+28
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,34 @@
1+
let remountCount = 0
2+
13
export class Counter extends HTMLElement {
4+
set count(count: string) {
5+
this.innerHTML = `
6+
<div>
7+
<div id="props">${count}</div>
8+
<div id="remount-count">${remountCount}</div>
9+
<slot name="main" />
10+
<slot />
11+
</div>
12+
`;
13+
}
14+
215
constructor() {
316
super();
17+
remountCount++;
18+
this.innerHTML = `
19+
<div>
20+
<div id="props">${this.count}</div>
21+
<div id="remount-count">${remountCount}</div>
22+
<slot name="main" />
23+
<slot />
24+
</div>
25+
`
26+
}
27+
28+
connectedCallback() {
29+
this.addEventListener('click', () => {
30+
this.dispatchEvent(new CustomEvent('submit', { detail: 'hello' }));
31+
});
432
}
533
}
634

Diff for: ct-web/src/tests.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ test('render props', async ({ mount }) => {
1717
await expect(component).toContainText('Submit');
1818
});
1919

20-
test.fixme('update props without remounting', async ({ mount }) => {
20+
test('update props without remounting', async ({ mount }) => {
2121
const component = await mount(Counter, {
2222
props: { count: 9001 },
2323
});
@@ -32,7 +32,7 @@ test.fixme('update props without remounting', async ({ mount }) => {
3232
await expect(component.locator('#remount-count')).toContainText('1');
3333
});
3434

35-
test.fixme('update event listeners without remounting', async ({ mount }) => {
35+
test('update event listeners without remounting', async ({ mount }) => {
3636
const component = await mount(Counter);
3737

3838
const messages: string[] = [];

Diff for: playwright-ct-web/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sand4rt/experimental-ct-web",
3-
"version": "0.0.7",
3+
"version": "0.0.8",
44
"description": "Playwright Component Testing for Web Components",
55
"homepage": "https://playwright.dev",
66
"engines": {

Diff for: playwright-ct-web/registerSource.mjs

+18-4
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ function createComponent(component) {
6363

6464
const webComponent = new Component();
6565

66+
for (const [key, value] of Object.entries(component.options?.props || {}))
67+
webComponent[key] = value;
68+
6669
for (const [key, listener] of Object.entries(component.options?.on || {}))
6770
webComponent.addEventListener(key, event => listener(/** @type {CustomEvent} */ (event).detail));
6871

@@ -75,14 +78,25 @@ function createComponent(component) {
7578
})
7679
}
7780

78-
for (const [key, value] of Object.entries(component.options?.props || {}))
79-
webComponent[key] = value;
80-
8181
return webComponent;
8282
}
8383

8484
window.playwrightUpdate = async (rootElement, component) => {
85-
throw new Error('component.update() is not yet supported');
85+
if (component.kind === 'jsx')
86+
throw new Error('JSX mount notation is not supported');
87+
88+
if (component.options?.slots)
89+
throw new Error('slots in component.update() is not yet supported');
90+
91+
const wrapper = rootElement.firstChild;
92+
if (!wrapper)
93+
throw new Error('Component was not mounted');
94+
95+
for (const [key, value] of Object.entries(component.options?.props || {}))
96+
wrapper[key] = value;
97+
98+
for (const [key, listener] of Object.entries(component.options?.on || {}))
99+
wrapper.addEventListener(key, event => listener(/** @type {CustomEvent} */ (event).detail));
86100
};
87101

88102
window.playwrightUnmount = async (rootElement) => {

0 commit comments

Comments
 (0)