Skip to content

Commit 2724b86

Browse files
authored
chore: unpin playwright (#462)
* chore: unpin playwright and refactor tests to work with its changed behavior * fix: change test for server restart to avoid color codes interfering * chore: move to macos-latest again for tests * fix: use vite connected message as condition for page ready instead of networkidle
1 parent 4de8568 commit 2724b86

File tree

7 files changed

+69
-35
lines changed

7 files changed

+69
-35
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ jobs:
7474
fail-fast: false
7575
matrix:
7676
node: [16]
77-
os: [ubuntu-latest, macos-11, windows-latest]
77+
os: [ubuntu-latest, macos-latest, windows-latest]
7878
include:
7979
- node: 14
8080
os: ubuntu-latest

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"lint-staged": "^13.0.3",
4141
"node-fetch": "^3.2.10",
4242
"npm-run-all": "^4.1.5",
43-
"playwright-core": "1.25.2",
43+
"playwright-core": "^1.27.1",
4444
"prettier": "^2.7.1",
4545
"prettier-plugin-svelte": "^2.7.1",
4646
"rimraf": "^3.0.2",

packages/e2e-tests/hmr/__tests__/hmr.spec.ts

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {
22
isBuild,
3-
isWin,
43
getEl,
54
getText,
65
editFileAndWaitForHmrComplete,
@@ -12,9 +11,8 @@ import {
1211
addFile,
1312
removeFile,
1413
editViteConfig,
15-
page,
1614
browserLogs,
17-
viteTestUrl
15+
waitForServerRestartAndReloadPage
1816
} from '~utils';
1917

2018
test('should render App', async () => {
@@ -167,9 +165,7 @@ if (!isBuild) {
167165

168166
test('should work with emitCss: false in svelte config', async () => {
169167
addFile('svelte.config.cjs', `module.exports={vitePlugin:{emitCss:false}}`);
170-
await sleep(isWin ? 1000 : 500); // adding config restarts server, give it some time
171-
await page.goto(viteTestUrl, { waitUntil: 'networkidle' });
172-
await sleep(50);
168+
await waitForServerRestartAndReloadPage();
173169
expect(await getColor(`#hmr-test-1 .label`)).toBe('red');
174170
removeFile('svelte.config.cjs');
175171
});
@@ -190,9 +186,7 @@ if (!isBuild) {
190186
`module.exports = {
191187
preprocess:[{markup:${injectPreprocessor.toString()}}]};`
192188
);
193-
await sleep(isWin ? 1000 : 500); // adding config restarts server, give it some time
194-
await page.goto(viteTestUrl, { waitUntil: 'networkidle' });
195-
await sleep(50);
189+
await waitForServerRestartAndReloadPage();
196190
expect(await getText('#preprocess-inject')).toBe('Injected');
197191
expect(await getText(`#hmr-test-1 .counter`)).toBe('0');
198192
expect(await getColor(`#hmr-test-1 .label`)).toBe('red');
@@ -207,9 +201,7 @@ if (!isBuild) {
207201
.replace('preprocess-inject', 'preprocess-inject-2')
208202
.replace('Injected', 'Injected 2')
209203
);
210-
await sleep(isWin ? 1000 : 500); // editing config restarts server, give it some time
211-
await page.goto(viteTestUrl, { waitUntil: 'networkidle' });
212-
await sleep(50);
204+
await waitForServerRestartAndReloadPage();
213205
expect(await getText('#preprocess-inject-2')).toBe('Injected 2');
214206
expect(await getEl('#preprocess-inject')).toBe(null);
215207
expect(await getColor(`#hmr-test-1 .label`)).toBe('green');
@@ -221,9 +213,7 @@ if (!isBuild) {
221213
expect(await getColor(`#hmr-test-1 .label`)).toBe('red');
222214
expect(await getText(`#hmr-test-1 .counter`)).toBe('1');
223215
await removeFile('svelte.config.cjs');
224-
await sleep(isWin ? 1000 : 500); // editing config restarts server, give it some time
225-
await page.goto(viteTestUrl, { waitUntil: 'networkidle' });
226-
await sleep(50);
216+
await waitForServerRestartAndReloadPage();
227217
expect(await getEl('#preprocess-inject-2')).toBe(null);
228218
expect(await getEl('#preprocess-inject')).toBe(null);
229219
expect(await getColor(`#hmr-test-1 .label`)).toBe('red');

packages/e2e-tests/kit-node/__tests__/kit.spec.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ import {
1111
waitForNavigation,
1212
page,
1313
browserLogs,
14-
fetchPageText
14+
fetchPageText,
15+
reloadPage
1516
} from '~utils';
1617

17-
import path from 'path';
1818
import glob from 'tiny-glob';
1919

2020
describe('kit-node', () => {
@@ -172,7 +172,7 @@ describe('kit-node', () => {
172172
it('should serve changes even after page reload', async () => {
173173
expect(await getColor(`h1`)).toBe('green');
174174
expect(await getText(`#hmr-test2`)).toBe('bar');
175-
await page.reload({ waitUntil: 'networkidle' });
175+
await reloadPage();
176176
expect(await getColor(`h1`)).toBe('green');
177177
expect(await getText(`#hmr-test2`)).toBe('bar');
178178
});
@@ -189,6 +189,9 @@ describe('kit-node', () => {
189189
await updateChild((content) =>
190190
content.replace('<!-- HMR-TEMPLATE-INJECT -->', '-foo<!-- HMR-TEMPLATE-INJECT -->')
191191
);
192+
// for some reason the update takes longer to materialize, so wait for it to avoid subsequent errors
193+
await page.getByText('test-child-foo').waitFor({ state: 'attached' });
194+
192195
expect(await getText('#before-child')).toBe('before-child');
193196
expect(await getText('#test-child')).toBe('test-child-foo');
194197
expect(await getText('#after-child')).toBe('after-child');

packages/e2e-tests/testUtils.ts

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,16 @@ import colors from 'css-color-names';
77
import { ElementHandle } from 'playwright-core';
88
import fetch from 'node-fetch';
99

10-
import { isBuild, isWin, isCI, page, testDir, viteTestUrl, browserLogs } from './vitestSetup';
10+
import {
11+
isBuild,
12+
isWin,
13+
isCI,
14+
page,
15+
testDir,
16+
browserLogs,
17+
e2eServer,
18+
waitForViteConnect
19+
} from './vitestSetup';
1120

1221
export * from './vitestSetup';
1322

@@ -42,20 +51,23 @@ const timeout = (n: number) => new Promise((r) => setTimeout(r, n));
4251

4352
async function toEl(el: string | ElementHandle): Promise<ElementHandle> {
4453
if (typeof el === 'string') {
45-
return await page.$(el);
54+
return await page.$(el, { strict: true });
4655
}
4756
return el;
4857
}
4958

5059
export async function getColor(el: string | ElementHandle) {
5160
el = await toEl(el);
61+
if (el == null) {
62+
return null;
63+
}
5264
const rgb = await el.evaluate((el) => getComputedStyle(el as Element).color);
5365
return hexToNameMap[rgbToHex(rgb)] || rgb;
5466
}
5567

5668
export async function getBg(el: string | ElementHandle) {
5769
el = await toEl(el);
58-
return el.evaluate((el) => getComputedStyle(el as Element).backgroundImage);
70+
return el == null ? null : el.evaluate((el) => getComputedStyle(el as Element).backgroundImage);
5971
}
6072

6173
export function readFileContent(filename: string) {
@@ -124,7 +136,7 @@ export async function getEl(selector: string) {
124136

125137
export async function getText(el: string | ElementHandle) {
126138
el = await toEl(el);
127-
return el ? await el.evaluate((el) => el.textContent) : null;
139+
return el ? el.textContent() : null;
128140
}
129141

130142
export async function hmrUpdateComplete(file, timeout) {
@@ -204,9 +216,33 @@ export async function saveScreenshot(name: string) {
204216

205217
export async function editViteConfig(replacer: (str: string) => string) {
206218
editFile('vite.config.js', replacer);
207-
await sleep(isWin ? 1000 : 500); // editing vite config restarts server, give it some time
208-
await page.goto(viteTestUrl, { waitUntil: 'networkidle' });
209-
await sleep(50);
219+
if (!isBuild) {
220+
await waitForServerRestartAndReloadPage();
221+
}
222+
}
223+
224+
export async function waitForServerRestartAndReloadPage(timeout = 10000) {
225+
const logs = e2eServer.logs.server.out;
226+
const startIdx = logs.length;
227+
let timeleft = timeout;
228+
const pollInterval = 50;
229+
let restarted = false;
230+
while (timeleft > 0) {
231+
await sleep(pollInterval);
232+
if (logs.some((text, i) => i > startIdx && text.endsWith('server restarted.'))) {
233+
restarted = true;
234+
break;
235+
}
236+
timeleft -= pollInterval;
237+
}
238+
if (!restarted) {
239+
throw new Error(`server did not restart after ${timeout}ms`);
240+
}
241+
await reloadPage();
242+
}
243+
244+
export async function reloadPage() {
245+
await Promise.all([page.reload(), waitForViteConnect(page)]);
210246
}
211247

212248
export async function waitForNavigation(opts: Parameters<typeof page.waitForNavigation>[0]) {

packages/e2e-tests/vitestSetup.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,14 +212,20 @@ beforeAll(
212212
);
213213

214214
async function goToUrlAndWaitForViteWSConnect(page: Page, url: string) {
215+
return Promise.all([page.goto(url), waitForViteConnect(page, 15000)]);
216+
}
217+
218+
export async function waitForViteConnect(page: Page, timeoutMS = 5000) {
219+
if (isBuild) {
220+
return Promise.resolve(); // no vite websocket on build
221+
}
215222
let timerId;
216223
let pageConsoleListener;
217-
const timeoutMS = 15000;
218224
const timeoutPromise = new Promise(
219225
// eslint-disable-next-line no-unused-vars
220226
(_, reject) =>
221227
(timerId = setTimeout(() => {
222-
reject(`page under test not ready after ${timeoutMS}ms. url: ${url}`);
228+
reject(`vite client not connected after ${timeoutMS}ms. url: ${page.url()}`);
223229
}, timeoutMS))
224230
);
225231
const connectedPromise = new Promise<void>((resolve) => {
@@ -232,9 +238,8 @@ async function goToUrlAndWaitForViteWSConnect(page: Page, url: string) {
232238
page.on('console', pageConsoleListener);
233239
});
234240

235-
const connectedOrTimeout = Promise.race([connectedPromise, timeoutPromise]).finally(() => {
241+
return Promise.race([connectedPromise, timeoutPromise]).finally(() => {
236242
page.off('console', pageConsoleListener);
237243
clearTimeout(timerId);
238244
});
239-
return page.goto(url).then(() => connectedOrTimeout);
240245
}

pnpm-lock.yaml

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)