Skip to content

Commit 816c0d0

Browse files
Update the way we run UI-tests (#1054)
* Update the way we run UI-tests This uses a logic closer to other projects (ipympl, bqplot, ipydatagrid). And run ui-tests with the dark theme. * Install browser * Increase timeout * Update Playwright Snapshots Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 6db416c commit 816c0d0

File tree

51 files changed

+869
-1844
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+869
-1844
lines changed

.github/workflows/update_galata_references.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ jobs:
4747
- name: Install JS deps
4848
run: |
4949
jlpm
50+
jlpm playwright install chromium
5051
jlpm build
5152
working-directory: js
5253

ui-tests/jupyter_server_config.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,3 @@
55
c.ServerApp.open_browser = False
66
c.LabApp.open_browser = False
77
c.LabApp.expose_app_in_browser = True
8-
c.ServerApp.notebook_dir = './notebooks'

ui-tests/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"license": "MIT",
1616
"dependencies": {
1717
"@jupyterlab/galata": "^4.3.5",
18+
"klaw-sync": "^6.0.0",
1819
"rimraf": "^3.0.2"
1920
}
2021
}

ui-tests/playwright.config.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module.exports = {
55
expect: {
66
toMatchSnapshot: { threshold: 0.33 },
77
},
8-
preserveOutput: 'failures-only',
9-
retries: 0
10-
};
8+
preserveOutput: 'failures-only',
9+
retries: 0,
10+
timeout: 600000,
11+
};

ui-tests/tests/ipyleaflet.test.ts

Lines changed: 80 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,85 @@
1-
import { galata, IJupyterLabPageFixture, test } from "@jupyterlab/galata";
2-
import { expect } from "@playwright/test";
3-
4-
async function renderMap(fileName: string, page: IJupyterLabPageFixture) {
5-
const fullName = `./${fileName}.ipynb`;
6-
await page.notebook.openByPath(fullName);
7-
await page.notebook.activate(fullName);
8-
await page.notebook.run();
9-
await page.notebook.waitForRun();
10-
const maps = await page.$("div.leaflet-container");
11-
await new Promise((_) => setTimeout(_, 1000));
12-
13-
// Move the mouse to the center of the map
14-
const bb = await maps?.boundingBox();
15-
await page.mouse.move(bb!.x + bb!.width / 2, bb!.y + bb!.height / 2);
16-
17-
expect(await maps!.screenshot()).toMatchSnapshot({
18-
name: `${fileName}.png`,
19-
});
1+
import { IJupyterLabPageFixture, test } from '@jupyterlab/galata';
2+
import { expect } from '@playwright/test';
3+
import * as path from 'path';
4+
const klaw = require('klaw-sync');
5+
6+
7+
const filterUpdateNotebooks = item => {
8+
const basename = path.basename(item.path);
9+
return basename.includes('_update');
2010
}
2111

22-
const notebookList = [
23-
"DivIcon",
24-
"DrawControl",
25-
"FullScreenControl",
26-
"Icon",
27-
"LayersControl",
28-
"LegendControl",
29-
"MagnifyingGlass",
30-
"Marker",
31-
"Polyline",
32-
"Popup",
33-
"ScaleControl",
34-
"SplitMapControl",
35-
"TileLayer",
36-
"WidgetControl",
37-
"ZoomControl",
38-
];
39-
40-
test.describe("ipyleaflet Visual Regression", () => {
41-
test.beforeEach(async ({ page }) => {
42-
page.setViewportSize({ width: 1920, height: 1080 });
43-
});
44-
for (const name of notebookList) {
45-
test(`Render ${name}`, async ({ page }) => {
46-
await renderMap(name, page);
12+
const testCellOutputs = async (page: IJupyterLabPageFixture, tmpPath: string, theme: 'JupyterLab Light' | 'JupyterLab Dark') => {
13+
const paths = klaw(path.resolve(__dirname, '../notebooks'), {filter: item => !filterUpdateNotebooks(item), nodir: true});
14+
const notebooks = paths.map(item => path.basename(item.path));
15+
16+
const contextPrefix = theme == 'JupyterLab Light' ? 'light_' : 'dark_';
17+
page.theme.setTheme(theme);
18+
19+
for (const notebook of notebooks) {
20+
let results = [];
21+
22+
await page.notebook.openByPath(`${tmpPath}/${notebook}`);
23+
await page.notebook.activate(notebook);
24+
25+
let numCellImages = 0;
26+
27+
const getCaptureImageName = (contextPrefix: string, notebook: string, id: number): string => {
28+
return `${contextPrefix}-${notebook}-cell-${id}.png`;
29+
};
30+
31+
await page.notebook.runCellByCell({
32+
onAfterCellRun: async (cellIndex: number) => {
33+
const cell = await page.notebook.getCellOutput(cellIndex);
34+
if (cell) {
35+
const map = await cell.$("div.leaflet-container");
36+
37+
if (map) {
38+
await new Promise((_) => setTimeout(_, 1000));
39+
40+
// Move the mouse to the center of the map
41+
const bb = await map.boundingBox();
42+
if (bb) {
43+
await page.mouse.move(bb.x + bb.width / 2, bb.y + bb.height / 2);
44+
}
45+
}
46+
47+
results.push(await cell.screenshot());
48+
numCellImages++;
49+
}
50+
}
4751
});
52+
53+
await page.notebook.save();
54+
55+
for (let c = 0; c < numCellImages; ++c) {
56+
expect(results[c]).toMatchSnapshot(getCaptureImageName(contextPrefix, notebook, c));
57+
}
58+
59+
await page.notebook.close(true);
4860
}
61+
}
62+
63+
test.describe('ipyleaflet Visual Regression', () => {
64+
test.beforeEach(async ({ page, tmpPath }) => {
65+
await page.contents.uploadDirectory(
66+
path.resolve(__dirname, '../notebooks'),
67+
tmpPath
68+
);
69+
await page.filebrowser.openDirectory(tmpPath);
70+
});
71+
72+
test('Light theme: Check ipyleaflet renders', async ({
73+
page,
74+
tmpPath,
75+
}) => {
76+
await testCellOutputs(page, tmpPath, 'JupyterLab Light');
77+
});
78+
79+
test('Dark theme: Check ipyleaflet renders', async ({
80+
page,
81+
tmpPath,
82+
}) => {
83+
await testCellOutputs(page, tmpPath, 'JupyterLab Dark');
84+
});
4985
});
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)