Skip to content

Commit

Permalink
Backport PR jupyterlab#15524: Fix visual tests
Browse files Browse the repository at this point in the history
* Try to make the test terminal snapshot more robust

by mock `tree . -L 2` command

* Workaround `test-` dirs issue by capturing `/data` instead of `/`

* Update Playwright Snapshots

* Run customization docs snapshots in serial

* Ignore all test files in galata tests

* Update Playwright Snapshots

* Disable concurrency in `build:examples` to fix flaky test

This was already use in `build:src`

* Ensure no flaky focus indicator on snapshot

(cherry picked from commit c26a0e7)
  • Loading branch information
krassowski committed Dec 29, 2023
1 parent 3ce0331 commit bf2e51f
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 104 deletions.
1 change: 1 addition & 0 deletions .licenserc.yaml
Expand Up @@ -32,6 +32,7 @@ header:
- 'dev_mode/style.js'
- 'examples/federated/example.cert'
- 'galata/test/jupyterlab/notebooks/'
- 'galata/test/*/*/*.txt'
- 'jupyterlab.desktop'
- 'jupyterlab/staging'
- 'packages/codemirror/test/foo.grammar'
Expand Down
Expand Up @@ -1915,9 +1915,7 @@
"id": "notebook:toggle-all-cell-line-numbers",
"label": "Show Line Numbers",
"caption": "",
"shortcuts": [
"Shift L"
]
"shortcuts": []
},
{
"id": "notebook:toggle-autoclosing-brackets",
Expand Down
3 changes: 3 additions & 0 deletions galata/test/documentation/customization.test.ts
Expand Up @@ -10,6 +10,9 @@ test.use({
viewport: { height: 720, width: 1280 }
});

// Use serial mode to avoid flaky screenshots
test.describe.configure({ mode: 'serial' });

test.describe('Default', () => {
test('should use default layout', async ({ page }) => {
await galata.Mock.freezeContentLastModified(page);
Expand Down
37 changes: 37 additions & 0 deletions galata/test/documentation/data/tree_fixture.txt
@@ -0,0 +1,37 @@
$ tree . -L 2
.
├── LICENSE
├── README.md
├── data
│   ├── 1024px-Hubble_Interacting_Galaxy_AM_0500-620_(2008-04-24).jpg
│   ├── Dockerfile
│   ├── Museums_in_DC.geojson
│   ├── README.md
│   ├── bar.vl.json
│   ├── iris.csv
│   ├── japan_meterological_agency_201707211555.json
│   └── zika_assembled_genomes.fasta
├── jupyter_notebook_config.py
├── narrative
│   ├── QConAI.md
│   ├── jupyterlab.md
│   ├── markdown_python.md
│   └── scipy2017.md
├── notebooks
│   ├── Cpp.ipynb
│   ├── Data.ipynb
│   ├── Fasta.ipynb
│   ├── Julia.ipynb
│   ├── Lorenz.ipynb
│   ├── R.ipynb
│   ├── audio
│   ├── images
│   └── lorenz.py
├── slides
│   ├── jupyterlab-slides.key
│   ├── jupyterlab-slides.pdf
│   └── jupyterlab-slides_scipy19.pdf
├── talks.yml
└── tasks.py

6 directories, 27 files
110 changes: 11 additions & 99 deletions galata/test/documentation/general.test.ts
Expand Up @@ -2,6 +2,7 @@
// Distributed under the terms of the Modified BSD License.

import { expect, galata, test } from '@jupyterlab/galata';
import path from 'path';
import {
generateArrow,
positionMouse,
Expand Down Expand Up @@ -79,13 +80,6 @@ test.describe('General', () => {
expect(await page.screenshot()).toMatchSnapshot('jupyterlab.png');
});

test('Overview', async ({ page }) => {
await galata.Mock.freezeContentLastModified(page);
await openOverview(page);

expect(await page.screenshot()).toMatchSnapshot('interface_jupyterlab.png');
});

test('Left Sidebar', async ({ page }) => {
await galata.Mock.freezeContentLastModified(page);
await page.goto();
Expand All @@ -98,6 +92,8 @@ test.describe('General', () => {
await setSidebarWidth(page);

await page.dblclick('[aria-label="File Browser Section"] >> text=data');
// Wait for the `data` folder to load to have something to blur
await page.waitForSelector('text=1024px');

await page.evaluate(() => {
(document.activeElement as HTMLElement).blur();
Expand Down Expand Up @@ -228,32 +224,6 @@ test.describe('General', () => {
);
});

test('Open tabs', async ({ page }) => {
await openOverview(page);

await page.click('[title="Running Terminals and Kernels"]');

await page
.locator(
'.jp-RunningSessions-item.jp-mod-kernel >> text="Python 3 (ipykernel)"'
)
.waitFor();
expect(
await page.screenshot({ clip: { y: 27, x: 0, width: 283, height: 400 } })
).toMatchSnapshot('interface_tabs.png');
});

test('Tabs menu', async ({ page }) => {
await galata.Mock.freezeContentLastModified(page);
await openOverview(page);

await page.click('text="Tabs"');

expect(
await page.screenshot({ clip: { y: 0, x: 210, width: 700, height: 350 } })
).toMatchSnapshot('interface_tabs_menu.png');
});

test('File menu', async ({ page }) => {
await page.goto();
await page.addStyleTag({
Expand Down Expand Up @@ -532,8 +502,13 @@ test.describe('General', () => {
);
});

test('Terminals', async ({ page }) => {
test('Terminal layout', async ({ page, tmpPath }) => {
await galata.Mock.freezeContentLastModified(page);
const fileName = 'tree_fixture.txt';
await page.contents.uploadFile(
path.resolve(__dirname, `./data/${fileName}`),
`${tmpPath}/${fileName}`
);
await page.goto();
await page.addStyleTag({
content: `.jp-LabShell.jp-mod-devMode {
Expand All @@ -559,7 +534,7 @@ test.describe('General', () => {

await page.keyboard.type('cd $JUPYTERLAB_GALATA_ROOT_DIR');
await page.keyboard.press('Enter');
await page.keyboard.type('tree . -L 2');
await page.keyboard.type(`clear && cat ${tmpPath}/${fileName}`);
await page.keyboard.press('Enter');

// Wait for command answer
Expand Down Expand Up @@ -634,6 +609,7 @@ test.describe('General', () => {

await setSidebarWidth(page);

await page.dblclick('[aria-label="File Browser Section"] >> text=data');
await page.click('text=README.md', {
button: 'right'
});
Expand Down Expand Up @@ -710,67 +686,3 @@ test.describe('General', () => {
});
});
});

async function openOverview(page) {
await page.goto();
await page.addStyleTag({
content: `.jp-LabShell.jp-mod-devMode {
border-top: none;
}`
});

await setSidebarWidth(page);

// Open Data.ipynb
await page.dblclick('[aria-label="File Browser Section"] >> text=notebooks');
await page.dblclick('text=Data.ipynb');

// Back home
await page.click('.jp-BreadCrumbs-home svg');

// Open jupyterlab.md
await page.dblclick('[aria-label="File Browser Section"] >> text=narrative');
await page.click('text=jupyterlab.md', {
button: 'right'
});
await page.click('text=Open With');
await page.click('text=Markdown Preview');

// Back home
await page.click('.jp-BreadCrumbs-home svg');

// Open bar.vl.json
await page.dblclick('[aria-label="File Browser Section"] >> text=data');
await page.dblclick('text=bar.vl.json');
await page.dblclick(
'text=1024px-Hubble_Interacting_Galaxy_AM_0500-620_(2008-04-24).jpg'
);

// Move notebook panel
const notebookHandle = await page.$('div[role="main"] >> text=Data.ipynb');
await notebookHandle.click();
const notebookBBox = await notebookHandle.boundingBox();

await page.mouse.move(
notebookBBox.x + 0.5 * notebookBBox.width,
notebookBBox.y + 0.5 * notebookBBox.height
);
await page.mouse.down();
await page.mouse.move(notebookBBox.x + 0.5 * notebookBBox.width, 350);
await page.mouse.up();

// Move md panel
const mdHandle = await page.$('div[role="main"] >> text=jupyterlab.md');
await mdHandle.click();
const mdBBox = await mdHandle.boundingBox();
const panelHandle = await page.activity.getPanel();
const panelBBox = await panelHandle.boundingBox();

await page.mouse.move(
mdBBox.x + 0.5 * mdBBox.width,
mdBBox.y + 0.5 * mdBBox.height
);
await page.mouse.down();
await page.mouse.move(panelBBox.x + 0.5 * panelBBox.width, 200);
await page.mouse.up();
}
2 changes: 2 additions & 0 deletions galata/test/documentation/internationalization.test.ts
Expand Up @@ -44,6 +44,8 @@ test.describe('Internationalization', () => {
await galata.Mock.freezeContentLastModified(page);
await page.goto();

await page.dblclick('[aria-label="File Browser Section"] >> text=data');

await page.click('text=Settings');
await page.click('.lm-Menu ul[role="menu"] >> text=Language');
await page.click('#jp-mainmenu-settings-language >> text=Chinese');
Expand Down
113 changes: 113 additions & 0 deletions galata/test/documentation/overview.test.ts
@@ -0,0 +1,113 @@
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.

import { expect, galata, test } from '@jupyterlab/galata';
import { setSidebarWidth } from './utils';

test.use({
autoGoto: false,
mockState: galata.DEFAULT_DOCUMENTATION_STATE,
viewport: { height: 720, width: 1280 }
});

// Use serial mode to avoid flaky screenshots
test.describe.configure({ mode: 'serial' });

test.describe('Overview', () => {
test('Overview', async ({ page }) => {
await galata.Mock.freezeContentLastModified(page);
await openOverview(page);

expect(await page.screenshot()).toMatchSnapshot('interface_jupyterlab.png');
});

test('Open tabs', async ({ page }) => {
await openOverview(page);

await page.click('[title="Running Terminals and Kernels"]');

await page
.locator(
'.jp-RunningSessions-item.jp-mod-kernel >> text="Python 3 (ipykernel)"'
)
.waitFor();
expect(
await page.screenshot({ clip: { y: 27, x: 0, width: 283, height: 400 } })
).toMatchSnapshot('interface_tabs.png');
});

test('Tabs menu', async ({ page }) => {
await galata.Mock.freezeContentLastModified(page);
await openOverview(page);

await page.click('text="Tabs"');

expect(
await page.screenshot({ clip: { y: 0, x: 210, width: 700, height: 350 } })
).toMatchSnapshot('interface_tabs_menu.png');
});
});

async function openOverview(page) {
await page.goto();
await page.addStyleTag({
content: `.jp-LabShell.jp-mod-devMode {
border-top: none;
}`
});

await setSidebarWidth(page);

// Open Data.ipynb
await page.dblclick('[aria-label="File Browser Section"] >> text=notebooks');
await page.dblclick('text=Data.ipynb');

// Back home
await page.click('.jp-BreadCrumbs-home svg');

// Open jupyterlab.md
await page.dblclick('[aria-label="File Browser Section"] >> text=narrative');
await page.click('text=jupyterlab.md', {
button: 'right'
});
await page.click('text=Open With');
await page.click('text=Markdown Preview');

// Back home
await page.click('.jp-BreadCrumbs-home svg');

// Open bar.vl.json
await page.dblclick('[aria-label="File Browser Section"] >> text=data');
await page.dblclick('text=bar.vl.json');
await page.dblclick(
'text=1024px-Hubble_Interacting_Galaxy_AM_0500-620_(2008-04-24).jpg'
);

// Move notebook panel
const notebookHandle = await page.$('div[role="main"] >> text=Data.ipynb');
await notebookHandle.click();
const notebookBBox = await notebookHandle.boundingBox();

await page.mouse.move(
notebookBBox.x + 0.5 * notebookBBox.width,
notebookBBox.y + 0.5 * notebookBBox.height
);
await page.mouse.down();
await page.mouse.move(notebookBBox.x + 0.5 * notebookBBox.width, 350);
await page.mouse.up();

// Move md panel
const mdHandle = await page.$('div[role="main"] >> text=jupyterlab.md');
await mdHandle.click();
const mdBBox = await mdHandle.boundingBox();
const panelHandle = await page.activity.getPanel();
const panelBBox = await panelHandle.boundingBox();

await page.mouse.move(
mdBBox.x + 0.5 * mdBBox.width,
mdBBox.y + 0.5 * mdBBox.height
);
await page.mouse.down();
await page.mouse.move(panelBBox.x + 0.5 * panelBBox.width, 200);
await page.mouse.up();
}
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -41,7 +41,7 @@
"build:dev:prod:minimize": "npm run integrity && npm run build:all && cd dev_mode && npm run build:prod:minimize",
"build:dev:prod:minimize:report": "npm run integrity && npm run build:all && cd dev_mode && npm run build:prod:minimize:report",
"build:dev:prod:release": "npm run integrity && npm run build:all && cd dev_mode && npm run build:prod:release",
"build:examples": "lerna run build --scope \"@jupyterlab/example-*\"",
"build:examples": "lerna run build --scope \"@jupyterlab/example-*\" --concurrency 1",
"build:galata": "cd galata && npm run build",
"build:nbconvert:css": "cd packages/nbconvert-css && npm run build",
"build:packages": "cd packages/metapackage && npm run build",
Expand Down
2 changes: 1 addition & 1 deletion packages/terminal/src/tokens.ts
Expand Up @@ -104,7 +104,7 @@ export namespace ITerminal {
closeOnExit: boolean;

/**
* Whether to blink the cursor. Can only be set at startup.
* Whether to blink the cursor. Can only be set at startup.
*/
cursorBlink: boolean;

Expand Down

0 comments on commit bf2e51f

Please sign in to comment.