Skip to content

Commit 8c49845

Browse files
authored
Make ui-tests more robust (#86)
1 parent 4af812c commit 8c49845

File tree

8 files changed

+4312
-3021
lines changed

8 files changed

+4312
-3021
lines changed

ui-tests/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
"private": true,
66
"scripts": {
77
"build": "jlpm clean && python build.py",
8-
"clean": "rimraf dist",
9-
"clean:all": "jlpm clean && rimraf cockle_wasm_env .cockle_temp",
8+
"clean": "rimraf cockle_wasm_env dist .cockle_temp .jupyterlite.doit.db",
109
"start": "npx static-handler -p 8000 --cors --coop --coep --corp ./dist",
1110
"test": "jlpm playwright test",
1211
"test:ui": "jlpm playwright test --ui",

ui-tests/playwright.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ module.exports = {
1010
autoGoto: false,
1111
baseURL: 'http://localhost:8000'
1212
},
13-
retries: 2,
13+
retries: process.env.CI ? 2 : 0,
1414
workers: 1,
1515
webServer: {
1616
command: 'jlpm start',

ui-tests/tests/command.spec.ts

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import { expect, test } from '@jupyterlab/galata';
22

33
import { ContentsHelper } from './utils/contents';
4-
import { TERMINAL_SELECTOR, WAIT_MS, inputLine } from './utils/misc';
5-
6-
// Long wait such as for starting/stopping a complex WebAssembly command.
7-
export const LONG_WAIT_MS = 300;
4+
import {
5+
LONG_WAIT_MS,
6+
TERMINAL_SELECTOR,
7+
WAIT_MS,
8+
inputLine
9+
} from './utils/misc';
810

911
test.describe('individual command', () => {
1012
test.beforeEach(async ({ page }) => {
1113
await page.goto();
12-
await page.waitForTimeout(WAIT_MS);
14+
await page.waitForTimeout(LONG_WAIT_MS);
1315

1416
// Overwrite the (read-only) page.contents with our own ContentsHelper.
1517
// @ts-ignore
@@ -18,7 +20,7 @@ test.describe('individual command', () => {
1820
await page.menu.clickMenuItem('File>New>Terminal');
1921
await page.locator(TERMINAL_SELECTOR).waitFor();
2022
await page.locator('div.xterm-screen').click(); // sets focus for keyboard input
21-
await page.waitForTimeout(WAIT_MS);
23+
await page.waitForTimeout(LONG_WAIT_MS);
2224
});
2325

2426
test.describe('nano', () => {
@@ -28,18 +30,17 @@ test.describe('individual command', () => {
2830
page
2931
}) => {
3032
await inputLine(page, `cockle-config stdin ${stdinOption}`);
31-
await page.waitForTimeout(WAIT_MS);
33+
await page.waitForTimeout(LONG_WAIT_MS);
3234

3335
await inputLine(page, 'nano a.txt');
3436
await page.waitForTimeout(LONG_WAIT_MS);
3537

3638
// Insert new characters.
37-
await page.keyboard.type('mnopqrst');
39+
await inputLine(page, 'mnopqrst', false);
3840

3941
// Save and quit.
4042
await page.keyboard.press('Control+x');
41-
await page.keyboard.type('y');
42-
await page.keyboard.press('Enter');
43+
await inputLine(page, 'y');
4344
await page.waitForTimeout(LONG_WAIT_MS);
4445

4546
const outputFile = await page.contents.getContentMetadata('a.txt');
@@ -50,11 +51,11 @@ test.describe('individual command', () => {
5051
page
5152
}) => {
5253
await inputLine(page, `cockle-config stdin ${stdinOption}`);
53-
await page.waitForTimeout(WAIT_MS);
54+
await page.waitForTimeout(LONG_WAIT_MS);
5455

5556
// Prepare file to delete from.
5657
await inputLine(page, 'echo mnopqrst > b.txt');
57-
await page.waitForTimeout(WAIT_MS);
58+
await page.waitForTimeout(LONG_WAIT_MS);
5859

5960
await inputLine(page, 'nano b.txt');
6061
await page.waitForTimeout(LONG_WAIT_MS);
@@ -66,8 +67,7 @@ test.describe('individual command', () => {
6667

6768
// Save and quit.
6869
await page.keyboard.press('Control+x');
69-
await page.keyboard.type('y');
70-
await page.keyboard.press('Enter');
70+
await inputLine(page, 'y');
7171
await page.waitForTimeout(LONG_WAIT_MS);
7272

7373
const outputFile = await page.contents.getContentMetadata('b.txt');
@@ -83,13 +83,13 @@ test.describe('individual command', () => {
8383
page
8484
}) => {
8585
await inputLine(page, `cockle-config stdin ${stdinOption}`);
86-
await page.waitForTimeout(WAIT_MS);
86+
await page.waitForTimeout(LONG_WAIT_MS);
8787

8888
await inputLine(page, 'vim c.txt');
8989
await page.waitForTimeout(LONG_WAIT_MS);
9090

9191
// Insert new characters.
92-
await page.keyboard.type('iabcdefgh');
92+
await inputLine(page, 'iabcdefgh', false);
9393

9494
// Save and quit.
9595
await page.keyboard.press('Escape');
@@ -104,17 +104,17 @@ test.describe('individual command', () => {
104104
page
105105
}) => {
106106
await inputLine(page, `cockle-config stdin ${stdinOption}`);
107-
await page.waitForTimeout(WAIT_MS);
107+
await page.waitForTimeout(LONG_WAIT_MS);
108108

109109
// Prepare file to delete from.
110110
await inputLine(page, 'echo abcdefgh > d.txt');
111-
await page.waitForTimeout(WAIT_MS);
111+
await page.waitForTimeout(LONG_WAIT_MS);
112112

113113
await inputLine(page, 'vim d.txt');
114114
await page.waitForTimeout(LONG_WAIT_MS);
115115

116116
// Delete first 4 characters.
117-
await page.keyboard.type('d4l');
117+
await inputLine(page, 'd4l', false);
118118

119119
// Save and quit.
120120
await page.keyboard.press('Escape');

ui-tests/tests/extension.spec.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { expect, test } from '@jupyterlab/galata';
22

3+
import { LONG_WAIT_MS } from './utils/misc';
4+
35
test.describe('Terminal extension', () => {
46
test('should emit activation console messages', async ({ page }) => {
57
const logs: string[] = [];
@@ -8,6 +10,7 @@ test.describe('Terminal extension', () => {
810
});
911

1012
await page.goto();
13+
await page.waitForTimeout(LONG_WAIT_MS);
1114

1215
expect(
1316
logs.filter(s =>

ui-tests/tests/fs.spec.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import { expect, test } from '@jupyterlab/galata';
22

33
import { ContentsHelper } from './utils/contents';
4-
import { TERMINAL_SELECTOR, WAIT_MS, decode64, inputLine } from './utils/misc';
4+
import {
5+
LONG_WAIT_MS,
6+
TERMINAL_SELECTOR,
7+
WAIT_MS,
8+
decode64,
9+
inputLine
10+
} from './utils/misc';
511

612
const MONTHS_TXT =
713
'January\nFebruary\nMarch\nApril\nMay\nJune\nJuly\nAugust\nSeptember\nOctober\nNovember\nDecember\n';
@@ -18,7 +24,7 @@ const FACT_LUA =
1824
test.describe('Filesystem', () => {
1925
test.beforeEach(async ({ page }) => {
2026
await page.goto();
21-
await page.waitForTimeout(WAIT_MS);
27+
await page.waitForTimeout(LONG_WAIT_MS);
2228

2329
// Overwrite the (read-only) page.contents with our own ContentsHelper.
2430
// @ts-ignore
@@ -50,10 +56,11 @@ test.describe('Filesystem', () => {
5056

5157
test('should create a new file', async ({ page }) => {
5258
await page.goto();
59+
await page.waitForTimeout(LONG_WAIT_MS);
5360
await page.menu.clickMenuItem('File>New>Terminal');
5461
await page.locator(TERMINAL_SELECTOR).waitFor();
5562
await page.locator('div.xterm-screen').click(); // sets focus for keyboard input
56-
await page.waitForTimeout(WAIT_MS);
63+
await page.waitForTimeout(LONG_WAIT_MS);
5764

5865
await inputLine(page, 'echo Hello > out.txt');
5966
await page.getByTitle('Name: out.txt').waitFor();

ui-tests/tests/jupyterlite_terminal.spec.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { expect, test } from '@jupyterlab/galata';
22

3-
import { TERMINAL_SELECTOR, WAIT_MS, inputLine } from './utils/misc';
3+
import {
4+
LONG_WAIT_MS,
5+
TERMINAL_SELECTOR,
6+
WAIT_MS,
7+
inputLine
8+
} from './utils/misc';
49

510
test.describe('Terminal', () => {
611
test('should emit service worker console message', async ({ page }) => {
@@ -10,9 +15,10 @@ test.describe('Terminal', () => {
1015
});
1116

1217
await page.goto();
18+
await page.waitForTimeout(LONG_WAIT_MS);
1319
await page.menu.clickMenuItem('File>New>Terminal');
1420
await page.locator(TERMINAL_SELECTOR).waitFor();
15-
await page.waitForTimeout(WAIT_MS);
21+
await page.waitForTimeout(LONG_WAIT_MS);
1622

1723
expect(
1824
logs.filter(s => s.match(/^Service worker supports terminal stdin/))
@@ -21,10 +27,11 @@ test.describe('Terminal', () => {
2127

2228
test('should show initial prompt', async ({ page }) => {
2329
await page.goto();
30+
await page.waitForTimeout(LONG_WAIT_MS);
2431
await page.menu.clickMenuItem('File>New>Terminal');
2532
await page.locator(TERMINAL_SELECTOR).waitFor();
2633
await page.locator('div.xterm-screen').click(); // sets focus for keyboard input
27-
await page.waitForTimeout(WAIT_MS);
34+
await page.waitForTimeout(LONG_WAIT_MS);
2835

2936
// Hide modification times.
3037
const modified = page.locator('span.jp-DirListing-itemModified');
@@ -36,10 +43,11 @@ test.describe('Terminal', () => {
3643

3744
test('should run various commands', async ({ page }) => {
3845
await page.goto();
46+
await page.waitForTimeout(LONG_WAIT_MS);
3947
await page.menu.clickMenuItem('File>New>Terminal');
4048
await page.locator(TERMINAL_SELECTOR).waitFor();
4149
await page.locator('div.xterm-screen').click(); // sets focus for keyboard input
42-
await page.waitForTimeout(WAIT_MS);
50+
await page.waitForTimeout(LONG_WAIT_MS);
4351

4452
await inputLine(page, 'ls'); // avoid timestamps
4553
await page.waitForTimeout(WAIT_MS);
@@ -74,10 +82,11 @@ test.describe('Terminal', () => {
7482
page
7583
}) => {
7684
await page.goto();
85+
await page.waitForTimeout(LONG_WAIT_MS);
7786
await page.menu.clickMenuItem('File>New>Terminal');
7887
await page.locator(TERMINAL_SELECTOR).waitFor();
7988
await page.locator('div.xterm-screen').click(); // sets focus for keyboard input
80-
await page.waitForTimeout(WAIT_MS);
89+
await page.waitForTimeout(LONG_WAIT_MS);
8190

8291
await inputLine(page, 'cockle-config stdin');
8392
await page.waitForTimeout(WAIT_MS);
@@ -88,10 +97,11 @@ test.describe('Terminal', () => {
8897

8998
test('should support setting ServiceWorker for stdin', async ({ page }) => {
9099
await page.goto();
100+
await page.waitForTimeout(LONG_WAIT_MS);
91101
await page.menu.clickMenuItem('File>New>Terminal');
92102
await page.locator(TERMINAL_SELECTOR).waitFor();
93103
await page.locator('div.xterm-screen').click(); // sets focus for keyboard input
94-
await page.waitForTimeout(WAIT_MS);
104+
await page.waitForTimeout(LONG_WAIT_MS);
95105

96106
await inputLine(page, 'cockle-config stdin sw');
97107
await page.waitForTimeout(WAIT_MS);
@@ -104,10 +114,11 @@ test.describe('Terminal', () => {
104114
stdinOptions.forEach(stdinOption => {
105115
test(`should support using ${stdinOption} for stdin`, async ({ page }) => {
106116
await page.goto();
117+
await page.waitForTimeout(LONG_WAIT_MS);
107118
await page.menu.clickMenuItem('File>New>Terminal');
108119
await page.locator(TERMINAL_SELECTOR).waitFor();
109120
await page.locator('div.xterm-screen').click(); // sets focus for keyboard input
110-
await page.waitForTimeout(WAIT_MS);
121+
await page.waitForTimeout(LONG_WAIT_MS);
111122

112123
await inputLine(page, `cockle-config stdin ${stdinOption}`);
113124
await page.waitForTimeout(WAIT_MS);

ui-tests/tests/utils/misc.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,30 @@
11
import { Buffer } from 'node:buffer';
2+
import type { Page } from '@playwright/test';
23

34
export const WAIT_MS = 100;
5+
6+
// Long wait such as for starting/stopping a complex WebAssembly command.
7+
export const LONG_WAIT_MS = 300;
8+
49
export const TERMINAL_SELECTOR = '.jp-Terminal';
510

611
export function decode64(encoded: string): string {
712
return Buffer.from(encoded, 'base64').toString('binary');
813
}
914

10-
export async function inputLine(page, text: string) {
15+
export async function inputLine(
16+
page: Page,
17+
text: string,
18+
enter: boolean = true
19+
) {
20+
const ms = 20;
21+
await page.waitForTimeout(ms);
1122
for (const char of text) {
1223
await page.keyboard.type(char);
13-
await page.waitForTimeout(10);
24+
await page.waitForTimeout(ms);
25+
}
26+
if (enter) {
27+
await page.keyboard.press('Enter');
28+
await page.waitForTimeout(ms);
1429
}
15-
await page.keyboard.press('Enter');
1630
}

0 commit comments

Comments
 (0)