Skip to content

Commit 81d3411

Browse files
authored
Integration test for links (#105)
* Update galata * Add helper for opening a session * Add tests on linked dataset display * Add link editor test * prettier * Move the link test which seems to be corrupted by the viewer creation one * Fix tests ? * Use simple histograms to avoid snapshot diff * update screenshot * last snapshots
1 parent ff0a3b0 commit 81d3411

8 files changed

+767
-488
lines changed

examples/session3.glu

+36-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,38 @@
11
{
2+
"34cde72b-5653-4c88-b631-06a958d51e7e": {
3+
"_type": "glue.viewers.histogram.qt.data_viewer.HistogramViewer",
4+
"pos": [
5+
0,
6+
0
7+
],
8+
"session": "Session",
9+
"size": [
10+
614,
11+
560
12+
],
13+
"state": {
14+
"values": {
15+
"layer": "w5_psc"
16+
}
17+
}
18+
},
19+
"3e7db9a2-c244-4e6e-a4fd-157329304711": {
20+
"_type": "glue.viewers.histogram.qt.data_viewer.HistogramViewer",
21+
"pos": [
22+
614,
23+
0
24+
],
25+
"session": "Session",
26+
"size": [
27+
614,
28+
560
29+
],
30+
"state": {
31+
"values": {
32+
"layer": "w6_psc"
33+
}
34+
}
35+
},
236
"CallbackList": {
337
"_type": "echo.containers.CallbackList",
438
"values": [
@@ -613,7 +647,8 @@
613647
],
614648
"viewers": [
615649
[
616-
"ImageViewer"
650+
"34cde72b-5653-4c88-b631-06a958d51e7e",
651+
"3e7db9a2-c244-4e6e-a4fd-157329304711"
617652
]
618653
]
619654
},

ui-tests/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"test:update": "npx playwright test --update-snapshots"
1010
},
1111
"devDependencies": {
12-
"@jupyterlab/galata": "^5.0.0-beta.0",
12+
"@jupyterlab/galata": "^5.0.0",
1313
"@playwright/test": "^1.32.0",
1414
"rimraf": "^3.0.2"
1515
}

ui-tests/tests/test.spec.ts

+224-26
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { IJupyterLabPageFixture, expect, test } from '@jupyterlab/galata';
2+
import { Locator } from '@playwright/test';
23

34
async function closeSideTab(page: IJupyterLabPageFixture): Promise<void> {
45
await page
@@ -7,37 +8,102 @@ async function closeSideTab(page: IJupyterLabPageFixture): Promise<void> {
78
.click();
89
}
910

11+
async function openSession(
12+
page: IJupyterLabPageFixture,
13+
session: string,
14+
waitUntilReady = true
15+
): Promise<void> {
16+
await expect(page.getByText(`${session}.glu`)).toBeVisible();
17+
await page.getByText(`${session}.glu`).dblclick();
18+
if (waitUntilReady) {
19+
// TODO Wait for spinner to not be visible once we have one
20+
await page.waitForSelector('.bqplot');
21+
}
22+
}
23+
24+
async function createLink(
25+
page: IJupyterLabPageFixture,
26+
datasets: [string, string],
27+
attributes: [string, string]
28+
): Promise<void> {
29+
// Switch to link editor
30+
await (await page.waitForSelector('text="Link Data"')).click();
31+
32+
await page.click(
33+
`.glue-LinkEditor-linkingDatasetsPanel:first-child > div:text('${datasets[0]}')`
34+
);
35+
await page.click(
36+
`.glue-LinkEditor-linkingDatasetsPanel:last-child > div:text('${datasets[1]}')`
37+
);
38+
39+
let attr = page.locator(
40+
`.firstAttributePanel > div:text('${attributes[0]}')`
41+
);
42+
if (!(await attr.getAttribute('class'))?.includes('selected')) {
43+
await page.click(`.firstAttributePanel > div:text('${attributes[0]}')`);
44+
}
45+
attr = page.locator(`.secondAttributePanel > div:text('${attributes[1]}')`);
46+
if (!(await attr.getAttribute('class'))?.includes('selected')) {
47+
await page.click(`.secondAttributePanel > div:text('${attributes[1]}')`);
48+
}
49+
50+
await page.click('.glue-LinkEditor-linkingGlueButton');
51+
}
52+
53+
async function selectPlotRange(
54+
page: IJupyterLabPageFixture,
55+
viewer: Locator
56+
): Promise<void> {
57+
await viewer.locator('button[value="bqplot:xrange"]').click();
58+
59+
await page.waitForSelector('g.selector.brushintsel');
60+
61+
const figureBox = await viewer.locator('.bqplot.figure').boundingBox();
62+
await page.mouse.move(
63+
figureBox!.x + figureBox!.width / 3,
64+
figureBox!.y + figureBox!.height / 3
65+
);
66+
await page.mouse.down();
67+
await page.mouse.move(
68+
figureBox!.x + figureBox!.width / 2,
69+
figureBox!.y + figureBox!.height / 2
70+
);
71+
await page.mouse.up();
72+
await expect(viewer.locator('.glue__subset-select')).toContainText(
73+
' Subset 1 '
74+
);
75+
}
76+
1077
/**
1178
* Don't load JupyterLab webpage before running the tests.
1279
* This is required to ensure we capture all log messages.
1380
*/
14-
test.use({ autoGoto: false });
81+
test.use({
82+
autoGoto: false,
83+
mockSettings: {
84+
'@jupyterlab/apputils-extension:notification': {
85+
fetchNews: 'false'
86+
}
87+
}
88+
});
1589

1690
test('should render session file', async ({ page }) => {
1791
await page.goto();
1892

19-
await expect(page.getByText('session.glu')).toBeVisible();
20-
await page.getByText('session.glu').dblclick();
93+
await openSession(page, 'session');
2194

2295
await closeSideTab(page);
2396

24-
// TODO Wait for spinner to not be visible once we have one
25-
await page.waitForSelector('.bqplot');
26-
2797
expect(await page.screenshot()).toMatchSnapshot('session-tab1.png');
2898
});
2999

30100
test('should switch tab', async ({ page }) => {
31101
await page.goto();
32102

33-
await expect(page.getByText('session.glu')).toBeVisible();
34-
await page.getByText('session.glu').dblclick();
103+
await openSession(page, 'session');
35104

36105
await closeSideTab(page);
37106

38-
// TODO Wait for spinner to not be visible once we have one
39-
await page.waitForSelector('.bqplot');
40-
41107
// Switch tab
42108
await page.getByRole('tab', { name: 'Tab 2' }).click();
43109

@@ -49,11 +115,7 @@ test('should switch tab', async ({ page }) => {
49115
test('should open link editor', async ({ page }) => {
50116
await page.goto();
51117

52-
await expect(page.getByText('session.glu')).toBeVisible();
53-
await page.getByText('session.glu').dblclick();
54-
55-
// TODO Wait for spinner to not be visible once we have one
56-
await page.waitForSelector('.bqplot');
118+
await openSession(page, 'session');
57119

58120
// Switch to link editor
59121
await (await page.waitForSelector('text="Link Data"')).click();
@@ -64,21 +126,17 @@ test('should open link editor', async ({ page }) => {
64126
test('should open the control panel on widget clicking', async ({ page }) => {
65127
await page.goto();
66128

67-
await expect(page.getByText('session.glu')).toBeVisible();
68-
await page.getByText('session.glu').dblclick();
69-
await page.waitForSelector('.bqplot');
129+
await openSession(page, 'session');
70130
await page.getByText('Histogram Viewer').click();
71-
await page.getByText('TAB 1 - HISTOGRAMVIEWER');
131+
page.getByText('TAB 1 - HISTOGRAMVIEWER');
72132

73133
expect(await page.screenshot()).toMatchSnapshot('control-panel.png');
74134
});
75135

76136
test('should hide the control panel on tab switching', async ({ page }) => {
77137
await page.goto();
78138

79-
await expect(page.getByText('session.glu')).toBeVisible();
80-
await page.getByText('session.glu').dblclick();
81-
await page.waitForSelector('.bqplot');
139+
await openSession(page, 'session');
82140
await page.getByText('Histogram Viewer').click();
83141
await page.getByText('TAB 1 - HISTOGRAMVIEWER');
84142

@@ -90,12 +148,44 @@ test('should hide the control panel on tab switching', async ({ page }) => {
90148
);
91149
});
92150

151+
test('should add and delete link', async ({ page }) => {
152+
await page.goto();
153+
154+
await openSession(page, 'session');
155+
156+
let linkCreated = false;
157+
await createLink(
158+
page,
159+
['w5', 'w5_psc'],
160+
['Pixel Axis 1 [x]', 'Pixel Axis 0 [x]']
161+
);
162+
163+
const summaries = page.locator('.glue-LinkEditor-summaryIdentity');
164+
const summariesCount = await summaries.count();
165+
166+
expect(summariesCount).toBe(3);
167+
168+
for (let i = 0; i < summariesCount; i++) {
169+
if (
170+
(await summaries.nth(i).innerText()) ===
171+
'Pixel Axis 1 [x]\nPixel Axis 0 [x]'
172+
) {
173+
linkCreated = true;
174+
break;
175+
}
176+
}
177+
178+
expect(linkCreated).toBeTruthy();
179+
180+
// Remove the last link
181+
await page.click('.glue-LinkEditor-deleteButton:last-child');
182+
expect(await summaries.count()).toBe(2);
183+
});
184+
93185
test('should add new dataset and create a viewer', async ({ page }) => {
94186
await page.goto();
95187

96-
await expect(page.getByText('session.glu')).toBeVisible();
97-
await page.getByText('session.glu').dblclick();
98-
await page.waitForSelector('.bqplot');
188+
await openSession(page, 'session');
99189

100190
// Open the "Add Data" dialog
101191
await page.getByText('Add Data').click();
@@ -154,3 +244,111 @@ test('should add new dataset and create a viewer', async ({ page }) => {
154244
'add-data-viewer-created.png'
155245
);
156246
});
247+
248+
test('should display linked data', async ({ page }) => {
249+
await page.goto();
250+
251+
await openSession(page, 'session3');
252+
253+
// Create a link between the ID of datasets
254+
await createLink(page, ['w5_psc', 'w6_psc'], ['ID', 'ID']);
255+
256+
await page.getByRole('tab', { name: 'Tab 1' }).click();
257+
const viewers = page.locator('.glue-item');
258+
259+
// force the size of histograms for snapshot comparison
260+
viewers
261+
.first()
262+
.locator('.bqplot.figure > svg.svg-figure > g > rect')
263+
.evaluate(element => {
264+
element.style.width = '571px';
265+
element.style.height = '410px';
266+
});
267+
268+
viewers
269+
.last()
270+
.locator('.bqplot.figure > svg.svg-figure > g > rect')
271+
.evaluate(element => {
272+
element.style.width = '571px';
273+
element.style.height = '410px';
274+
});
275+
276+
// select a range.
277+
await selectPlotRange(page, viewers.first());
278+
279+
// expect the selected area and the linked one to match.
280+
expect(
281+
await viewers
282+
.first()
283+
.locator('.bqplot.figure > svg.svg-figure > g > rect')
284+
.screenshot()
285+
).toMatchSnapshot('histogram-selection.png');
286+
287+
expect(
288+
await viewers
289+
.last()
290+
.locator('.bqplot.figure > svg.svg-figure > g > rect')
291+
.screenshot()
292+
).toMatchSnapshot('histogram-linked-selection.png');
293+
});
294+
295+
test('should delete and restore links', async ({ page }) => {
296+
await page.goto();
297+
298+
await openSession(page, 'session3');
299+
300+
// remove the existing links
301+
await (await page.waitForSelector('text="Link Data"')).click();
302+
const deleteButton = page.locator('.glue-LinkEditor-deleteButton');
303+
while (await deleteButton.count()) {
304+
await deleteButton.first().click();
305+
}
306+
307+
// select attributes in viewers
308+
await page.getByRole('tab', { name: 'Tab 1' }).click();
309+
const viewers = page.locator('.glue-item');
310+
311+
// force the size of histograms for snapshot comparison
312+
viewers
313+
.first()
314+
.locator('.bqplot.figure > svg.svg-figure > g > rect')
315+
.evaluate(element => {
316+
element.style.width = '571px';
317+
element.style.height = '410px';
318+
});
319+
320+
viewers
321+
.last()
322+
.locator('.bqplot.figure > svg.svg-figure > g > rect')
323+
.evaluate(element => {
324+
element.style.width = '571px';
325+
element.style.height = '410px';
326+
});
327+
328+
// select a range.
329+
await selectPlotRange(page, viewers.first());
330+
331+
// expect the selected area and the linked one to match
332+
expect(
333+
await viewers
334+
.first()
335+
.locator('.bqplot.figure > svg.svg-figure > g > rect')
336+
.screenshot()
337+
).toMatchSnapshot('histogram-selection.png');
338+
339+
expect(
340+
await viewers
341+
.last()
342+
.locator('.bqplot.figure > svg.svg-figure > g > rect')
343+
.screenshot()
344+
).toMatchSnapshot('histogram-no-selection.png');
345+
346+
await createLink(page, ['w5_psc', 'w6_psc'], ['ID', 'ID']);
347+
await page.getByRole('tab', { name: 'Tab 1' }).click();
348+
expect(
349+
await viewers
350+
.last()
351+
.locator('.bqplot.figure > svg.svg-figure > g > rect')
352+
.screenshot()
353+
).toMatchSnapshot('histogram-linked-selection.png');
354+
});
Loading
Loading
Loading
Loading

0 commit comments

Comments
 (0)