Skip to content

Commit 3295f5a

Browse files
author
Marcus Stöhr
committed
test(autocomplete): add browser test with dynamic forms
1 parent 90caae6 commit 3295f5a

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import { expect, type Page, test } from '@playwright/test';
2+
3+
async function typeInTomSelect(page: Page, testId: string, text: string) {
4+
const wrapper = page.locator(`[data-test-id="${testId}"]`).locator('..');
5+
const tsControl = wrapper.locator('.ts-control');
6+
await tsControl.waitFor({ state: 'visible', timeout: 10000 });
7+
await tsControl.click();
8+
await tsControl.locator('input').fill(text);
9+
}
10+
11+
async function waitForAutocomplete(page: Page, testId: string) {
12+
const element = page.locator(`[data-test-id="${testId}"]`);
13+
await element.waitFor({ state: 'attached', timeout: 10000 });
14+
const wrapper = element.locator('..');
15+
await wrapper.locator('.ts-control').waitFor({ state: 'visible', timeout: 10000 });
16+
}
17+
18+
test.describe('Autocomplete with Dynamic Forms', () => {
19+
test.beforeEach(async ({ page }) => {
20+
await page.goto('/test/autocomplete-dynamic-form');
21+
await expect(page.locator('[data-test-id="test-page"]')).toBeVisible();
22+
});
23+
24+
test('should not throw "Tom Select already initialized" error when switching between dynamic autocomplete fields', async ({
25+
page,
26+
}) => {
27+
const consoleErrors: string[] = [];
28+
page.on('console', (msg) => {
29+
if (msg.type() === 'error') {
30+
consoleErrors.push(msg.text());
31+
}
32+
});
33+
34+
await page.selectOption('[data-test-id="production-type"]', 'movie');
35+
await waitForAutocomplete(page, 'movie-autocomplete');
36+
37+
await typeInTomSelect(page, 'movie-autocomplete', 'Matrix');
38+
await page.waitForTimeout(500);
39+
40+
const optionsAfterFirstFill = page.locator('[data-test-id="autocomplete-option"]');
41+
if ((await optionsAfterFirstFill.count()) > 0) {
42+
await optionsAfterFirstFill.first().click();
43+
await page.waitForTimeout(1000);
44+
}
45+
46+
await page.selectOption('[data-test-id="production-type"]', 'videogame');
47+
await waitForAutocomplete(page, 'videogame-autocomplete');
48+
49+
await typeInTomSelect(page, 'videogame-autocomplete', 'Halo');
50+
await page.waitForTimeout(500);
51+
52+
const optionsAfterSecondFill = page.locator('[data-test-id="autocomplete-option"]');
53+
if ((await optionsAfterSecondFill.count()) > 0) {
54+
await optionsAfterSecondFill.first().click();
55+
}
56+
57+
await page.selectOption('[data-test-id="production-type"]', 'movie');
58+
await waitForAutocomplete(page, 'movie-autocomplete');
59+
60+
await typeInTomSelect(page, 'movie-autocomplete', 'Inception');
61+
await page.waitForTimeout(500);
62+
63+
const tomSelectError = consoleErrors.find((error) => error.includes('Tom Select already initialized'));
64+
65+
expect(tomSelectError).toBeUndefined();
66+
67+
await expect(page.locator('[data-test-id="autocomplete-option"]')).toHaveCount(1);
68+
});
69+
70+
test('should properly disconnect and reconnect Tom Select on rapid type changes', async ({ page }) => {
71+
const consoleErrors: string[] = [];
72+
page.on('console', (msg) => {
73+
if (msg.type() === 'error') {
74+
consoleErrors.push(msg.text());
75+
}
76+
});
77+
78+
for (let i = 0; i < 5; i++) {
79+
await page.selectOption('[data-test-id="production-type"]', 'movie');
80+
await page.waitForTimeout(100);
81+
await page.selectOption('[data-test-id="production-type"]', 'videogame');
82+
await page.waitForTimeout(100);
83+
}
84+
85+
await page.selectOption('[data-test-id="production-type"]', 'movie');
86+
await waitForAutocomplete(page, 'movie-autocomplete');
87+
88+
await typeInTomSelect(page, 'movie-autocomplete', 'Test');
89+
90+
expect(consoleErrors).toHaveLength(0);
91+
});
92+
93+
test('should handle autocomplete in morphed LiveComponent without errors', async ({ page }) => {
94+
const consoleErrors: string[] = [];
95+
page.on('console', (msg) => {
96+
if (msg.type() === 'error') {
97+
consoleErrors.push(msg.text());
98+
}
99+
});
100+
101+
await page.selectOption('[data-test-id="production-type"]', 'movie');
102+
await waitForAutocomplete(page, 'movie-autocomplete');
103+
104+
await typeInTomSelect(page, 'movie-autocomplete', 'Matrix');
105+
await page.waitForTimeout(500);
106+
107+
const dropdown = page.locator('.ts-dropdown');
108+
await dropdown.waitFor({ state: 'visible', timeout: 5000 });
109+
110+
const firstOption = dropdown.locator('.option').first();
111+
if (await firstOption.isVisible()) {
112+
await firstOption.click();
113+
}
114+
115+
await page.waitForTimeout(1000);
116+
117+
await typeInTomSelect(page, 'movie-autocomplete', 'Inception');
118+
await page.waitForTimeout(1000);
119+
120+
expect(consoleErrors).toHaveLength(0);
121+
122+
const dropdownVisible = await dropdown.isVisible();
123+
expect(dropdownVisible).toBe(true);
124+
});
125+
});

0 commit comments

Comments
 (0)