Skip to content

Commit 1e6f460

Browse files
andrii-igithub-actions[bot]pre-commit-ci[bot]
authored
Fix CI, run lint, reduce end-to-end tests flakiness (#417)
* add macos tests * add locally-generated snapshots * check if filebrowser is already open before opening it * add actual snapshoy from CI * Update Playwright Snapshots * use notebook toolbar, mask bttns on the right * correct selector * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * run lint * Update Playwright Snapshots * timestampLocator -> timestamp * wait until fonts are ready before taking a snapshot * add maxDiffPixels * Revert "wait until fonts are ready before taking a snapshot" This reverts commit 9554559. * pin jupyterlab version for e2e tests and snapshots * remove macos tests * rename relevant job to end-to-end test * remove darwin/macos snapshots * specify jupyterlab version correctly * run lint * add jlpm install to Lint the extension step * remove ubuntu postfix from test report * Make e2e tests a separate file * add build steps * pin version of jupyterlab in e2e test file * introduce modifyListResponse, remove maxDiffPixels * modifyListResponse -> setJobList * set expected URL * always set create_time to 1 * update list view snapshot * run check option for lint * run lint locally --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 9dc2836 commit 1e6f460

File tree

8 files changed

+140
-69
lines changed

8 files changed

+140
-69
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ jobs:
2727
- name: Lint the extension
2828
run: |
2929
set -eux
30-
jlpm
30+
jlpm install
31+
jlpm run lint:check
3132
3233
- name: Test the extension
3334
run: |
@@ -87,58 +88,3 @@ jobs:
8788
jupyter labextension list
8889
jupyter labextension list 2>&1 | grep -ie "@jupyterlab/scheduler.*OK"
8990
python -m jupyterlab.browser_check
90-
91-
integration-tests:
92-
name: Integration tests
93-
needs: build
94-
runs-on: ubuntu-latest
95-
96-
env:
97-
PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/pw-browsers
98-
99-
steps:
100-
- name: Checkout
101-
uses: actions/checkout@v2
102-
103-
- name: Base Setup
104-
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
105-
106-
- name: Download extension package
107-
uses: actions/download-artifact@v2
108-
with:
109-
name: extension-artifacts
110-
111-
- name: Install the extension
112-
run: |
113-
set -eux
114-
python -m pip install "jupyterlab~=4.0" jupyter_scheduler*.whl
115-
116-
- name: Install dependencies
117-
working-directory: ui-tests
118-
env:
119-
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
120-
run: jlpm install
121-
122-
- name: Set up browser cache
123-
uses: actions/cache@v2
124-
with:
125-
path: |
126-
${{ github.workspace }}/pw-browsers
127-
key: ${{ runner.os }}-${{ hashFiles('ui-tests/yarn.lock') }}
128-
129-
- name: Install browser
130-
working-directory: ui-tests
131-
run: jlpm install-chromium
132-
133-
- name: Execute integration tests
134-
working-directory: ui-tests
135-
run: jlpm test
136-
137-
- name: Upload Playwright Test report
138-
if: always()
139-
uses: actions/upload-artifact@v2
140-
with:
141-
name: jupyter_scheduler-playwright-tests
142-
path: |
143-
ui-tests/test-results
144-
ui-tests/playwright-report

.github/workflows/e2e-tests.yml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: E2E Tests
2+
3+
# suppress warning raised by https://github.com/jupyter/jupyter_core/pull/292
4+
env:
5+
JUPYTER_PLATFORM_DIRS: '1'
6+
7+
on:
8+
push:
9+
branches: main
10+
pull_request:
11+
branches: '*'
12+
13+
jobs:
14+
e2e-tests:
15+
name: Linux
16+
runs-on: ubuntu-latest
17+
18+
env:
19+
PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/pw-browsers
20+
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@v2
24+
25+
- name: Base Setup
26+
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
27+
28+
- name: Install extension dependencies
29+
run: python -m pip install -U jupyterlab==4.0.3
30+
31+
- name: Build the extension
32+
run: |
33+
set -eux
34+
python -m pip install .
35+
36+
jupyter server extension list
37+
jupyter server extension list 2>&1 | grep -ie "jupyter_scheduler.*OK"
38+
39+
jupyter labextension list
40+
jupyter labextension list 2>&1 | grep -ie "@jupyterlab/scheduler.*OK"
41+
python -m jupyterlab.browser_check
42+
43+
- name: Install ui-tests dependencies
44+
working-directory: ui-tests
45+
env:
46+
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
47+
run: jlpm install
48+
49+
- name: Set up browser cache
50+
uses: actions/cache@v2
51+
with:
52+
path: |
53+
${{ github.workspace }}/pw-browsers
54+
key: ${{ runner.os }}-${{ hashFiles('ui-tests/yarn.lock') }}
55+
56+
- name: Install browser
57+
working-directory: ui-tests
58+
run: jlpm install-chromium
59+
60+
- name: Execute integration tests
61+
working-directory: ui-tests
62+
run: jlpm test
63+
64+
- name: Upload Playwright Test report
65+
if: always()
66+
uses: actions/upload-artifact@v2
67+
with:
68+
name: jupyter_scheduler-playwright-tests-linux
69+
path: |
70+
ui-tests/test-results
71+
ui-tests/playwright-report

.github/workflows/update-integration-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
python_version: '3.11'
3939

4040
- name: Install dependencies
41-
run: python -m pip install -U jupyterlab~=4.0
41+
run: python -m pip install -U jupyterlab==4.0.3
4242

4343
- name: Install extension
4444
run: |

ui-tests/helpers/SchedulerHelper.ts

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import { expect, IJupyterLabPageFixture } from '@jupyterlab/galata';
22
import type { Locator, TestInfo } from '@playwright/test';
33

4-
export enum SELECTORS {
4+
enum SELECTORS {
55
// tbutton = toolbar button
66
CREATE_JOB_TBUTTON = 'button.jp-ToolbarButtonComponent[data-command="scheduling:create-from-notebook"][title="Create a notebook job"]',
77
LAUNCHER_CARD = 'div.jp-LauncherCard[title="Notebook Jobs"]',
8-
LIST_VIEW_TIMES = 'td.MuiTableCell-body:has-text(" AM"), td.MuiTableCell-body:has-text(" PM")'
8+
LIST_VIEW_TIMES = 'td.MuiTableCell-body:has-text(" AM"), td.MuiTableCell-body:has-text(" PM")',
9+
NOTEBOOK_TOOLBAR = '.jp-NotebookPanel-toolbar[aria-label="notebook actions"]',
10+
ENABLE_DEBUGGER_TBUTTON = '.jp-DebuggerBugButton',
11+
KERNEL_NAME_TBUTTON = '.jp-KernelName',
12+
EXECUTION_INDICATOR_TBUTTON = '.jp-Notebook-ExecutionIndicator'
913
}
1014

1115
type SnapshotOptions = {
@@ -50,16 +54,47 @@ export class SchedulerHelper {
5054
) {}
5155

5256
/**
53-
* JupyterLab launcher "Notebook Jobs" card selector
57+
* JupyterLab launcher "Notebook Jobs" card locator
5458
*/
5559
get launcherCard() {
5660
return this.page.locator(SELECTORS.LAUNCHER_CARD);
5761
}
5862

63+
/**
64+
* Locates notebook toolbar
65+
*/
66+
get notebookToolbar() {
67+
return this.page.locator(SELECTORS.NOTEBOOK_TOOLBAR);
68+
}
69+
70+
/**
71+
* Locates "Create a notebook job" button in notebook toolbar
72+
*/
5973
get createJobTbutton() {
6074
return this.page.locator(SELECTORS.CREATE_JOB_TBUTTON);
6175
}
6276

77+
/**
78+
* Locates "Enable debugger" icon in notebook toolbar
79+
*/
80+
get enableDebuggerTbutton() {
81+
return this.page.locator(SELECTORS.ENABLE_DEBUGGER_TBUTTON);
82+
}
83+
84+
/**
85+
* Locates kernel name button in notebook toolbar
86+
*/
87+
get kernelNameTbutton() {
88+
return this.page.locator(SELECTORS.KERNEL_NAME_TBUTTON);
89+
}
90+
91+
/**
92+
* Locates execution indicator icon in notebook toolbar
93+
*/
94+
get executionIndicatorTbutton() {
95+
return this.page.locator(SELECTORS.EXECUTION_INDICATOR_TBUTTON);
96+
}
97+
6398
/**
6499
* Locates the previously created notebook's listing in the filebrowser.
65100
*/
@@ -79,7 +114,7 @@ export class SchedulerHelper {
79114
* Locates the column of timestamps in the list view. Used to mask this column
80115
* during snapshot tests.
81116
*/
82-
get timestampLocator() {
117+
get timestamp() {
83118
return this.page.locator(SELECTORS.LIST_VIEW_TIMES);
84119
}
85120

@@ -181,6 +216,21 @@ export class SchedulerHelper {
181216
expect(await target.screenshot(screenshotArgs)).toMatchSnapshot(filename);
182217
}
183218

219+
async standardizeListCreateTime() {
220+
await this.page.route('**/scheduler/*', async (route, req) => {
221+
if (req.url().includes('max_items')) {
222+
const res = await route.fetch();
223+
const json = await res.json();
224+
json.jobs[0].create_time = 1;
225+
route.fulfill({
226+
status: res.status(),
227+
headers: res.headers(),
228+
body: JSON.stringify(json)
229+
});
230+
}
231+
});
232+
}
233+
184234
protected async _waitForCreateJobLoaded() {
185235
await this.page.waitForSelector('text=Loading …', { state: 'hidden' });
186236
}

ui-tests/tests/jupyter_scheduler.spec.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { SchedulerHelper } from '../helpers/SchedulerHelper';
33

44
enum FILENAMES {
55
LAUNCHER = 'launcher.png',
6-
NOTEBOOK = 'notebook-view.png',
6+
NOTEBOOK_TOOLBAR = 'notebook-toolbar.png',
77
FILEBROWSER_MENU = 'filebrowser-menu.png',
88
// TODO: resolve this inconsistency in our frontend code. One entry point
99
// includes the file extension in the job name, the other does not.
@@ -34,7 +34,14 @@ test.describe('Jupyter Scheduler', () => {
3434
test('shows notebook toolbar button', async () => {
3535
await scheduler.createNotebook();
3636
await expect(scheduler.createJobTbutton).toBeVisible();
37-
await scheduler.assertSnapshot(FILENAMES.NOTEBOOK);
37+
await scheduler.assertSnapshot(FILENAMES.NOTEBOOK_TOOLBAR, {
38+
locator: scheduler.notebookToolbar,
39+
mask: [
40+
scheduler.enableDebuggerTbutton,
41+
scheduler.kernelNameTbutton,
42+
scheduler.executionIndicatorTbutton
43+
]
44+
});
3845
});
3946

4047
test('opens create job view from notebook toolbar', async ({ page }) => {
@@ -62,14 +69,11 @@ test.describe('Jupyter Scheduler', () => {
6269
await scheduler.assertSnapshot(FILENAMES.CREATE_VIEW_FROM_FILEBROWSER);
6370
});
6471

65-
test('shows newly created job in job list view', async () => {
72+
test('shows newly created job in job list view', async ({ page }) => {
6673
await scheduler.createNotebook();
6774
await scheduler.createJobFromFilebrowser();
68-
69-
const timeStamp = scheduler.timestampLocator;
70-
await scheduler.assertSnapshot(FILENAMES.LIST_VIEW, {
71-
mask: [timeStamp]
72-
});
75+
await scheduler.standardizeListCreateTime();
76+
await scheduler.assertSnapshot(FILENAMES.LIST_VIEW);
7377
});
7478

7579
test.afterEach(async () => {
11.2 KB
Loading
1.82 KB
Loading
Binary file not shown.

0 commit comments

Comments
 (0)