Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix CI, run lint, reduce end-to-end tests flakiness #417

Merged
merged 32 commits into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
3c9fb1e
add macos tests
andrii-i Jul 20, 2023
f8d6561
add locally-generated snapshots
andrii-i Jul 20, 2023
abfb947
check if filebrowser is already open before opening it
andrii-i Jul 20, 2023
8b56d6e
add actual snapshoy from CI
andrii-i Jul 21, 2023
951bed2
Update Playwright Snapshots
github-actions[bot] Jul 31, 2023
a9f318b
use notebook toolbar, mask bttns on the right
andrii-i Aug 1, 2023
8851647
correct selector
andrii-i Aug 1, 2023
a4bb17f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 1, 2023
f2c6ea0
run lint
andrii-i Aug 1, 2023
535207e
Update Playwright Snapshots
github-actions[bot] Aug 1, 2023
2a2b76f
timestampLocator -> timestamp
andrii-i Aug 1, 2023
9554559
wait until fonts are ready before taking a snapshot
andrii-i Aug 1, 2023
2388612
add maxDiffPixels
andrii-i Aug 8, 2023
cbf476f
Revert "wait until fonts are ready before taking a snapshot"
andrii-i Aug 8, 2023
d1d71fd
pin jupyterlab version for e2e tests and snapshots
andrii-i Aug 9, 2023
63b9bda
remove macos tests
andrii-i Aug 9, 2023
025c55e
rename relevant job to end-to-end test
andrii-i Aug 9, 2023
69a5ae3
remove darwin/macos snapshots
andrii-i Aug 9, 2023
e627ef0
specify jupyterlab version correctly
andrii-i Aug 9, 2023
36599e4
run lint
andrii-i Aug 9, 2023
f00caca
add jlpm install to Lint the extension step
andrii-i Aug 9, 2023
4fc86bf
remove ubuntu postfix from test report
andrii-i Aug 9, 2023
42b944d
Make e2e tests a separate file
andrii-i Aug 10, 2023
cf0c63c
add build steps
andrii-i Aug 10, 2023
d742a06
pin version of jupyterlab in e2e test file
andrii-i Aug 10, 2023
0ab5c8e
introduce modifyListResponse, remove maxDiffPixels
andrii-i Aug 10, 2023
cb68b99
modifyListResponse -> setJobList
andrii-i Aug 10, 2023
582d590
set expected URL
andrii-i Aug 10, 2023
2decf9a
always set create_time to 1
andrii-i Aug 11, 2023
0800ef0
update list view snapshot
andrii-i Aug 11, 2023
c1c2dea
run check option for lint
andrii-i Aug 11, 2023
549c16d
run lint locally
andrii-i Aug 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 2 additions & 56 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ jobs:
- name: Lint the extension
run: |
set -eux
jlpm
jlpm install
jlpm run lint:check

- name: Test the extension
run: |
Expand Down Expand Up @@ -87,58 +88,3 @@ jobs:
jupyter labextension list
jupyter labextension list 2>&1 | grep -ie "@jupyterlab/scheduler.*OK"
python -m jupyterlab.browser_check

integration-tests:
name: Integration tests
needs: build
runs-on: ubuntu-latest

env:
PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/pw-browsers

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Base Setup
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1

- name: Download extension package
uses: actions/download-artifact@v2
with:
name: extension-artifacts

- name: Install the extension
run: |
set -eux
python -m pip install "jupyterlab~=4.0" jupyter_scheduler*.whl

- name: Install dependencies
working-directory: ui-tests
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
run: jlpm install

- name: Set up browser cache
uses: actions/cache@v2
with:
path: |
${{ github.workspace }}/pw-browsers
key: ${{ runner.os }}-${{ hashFiles('ui-tests/yarn.lock') }}

- name: Install browser
working-directory: ui-tests
run: jlpm install-chromium

- name: Execute integration tests
working-directory: ui-tests
run: jlpm test

- name: Upload Playwright Test report
if: always()
uses: actions/upload-artifact@v2
with:
name: jupyter_scheduler-playwright-tests
path: |
ui-tests/test-results
ui-tests/playwright-report
71 changes: 71 additions & 0 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: E2E Tests

# suppress warning raised by https://github.com/jupyter/jupyter_core/pull/292
env:
JUPYTER_PLATFORM_DIRS: '1'

on:
push:
branches: main
pull_request:
branches: '*'

jobs:
e2e-tests:
name: Linux
runs-on: ubuntu-latest

env:
PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/pw-browsers

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Base Setup
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1

- name: Install extension dependencies
run: python -m pip install -U jupyterlab==4.0.3

- name: Build the extension
run: |
set -eux
python -m pip install .

jupyter server extension list
jupyter server extension list 2>&1 | grep -ie "jupyter_scheduler.*OK"

jupyter labextension list
jupyter labextension list 2>&1 | grep -ie "@jupyterlab/scheduler.*OK"
python -m jupyterlab.browser_check

- name: Install ui-tests dependencies
working-directory: ui-tests
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
run: jlpm install

- name: Set up browser cache
uses: actions/cache@v2
with:
path: |
${{ github.workspace }}/pw-browsers
key: ${{ runner.os }}-${{ hashFiles('ui-tests/yarn.lock') }}

- name: Install browser
working-directory: ui-tests
run: jlpm install-chromium

- name: Execute integration tests
working-directory: ui-tests
run: jlpm test

- name: Upload Playwright Test report
if: always()
uses: actions/upload-artifact@v2
with:
name: jupyter_scheduler-playwright-tests-linux
path: |
ui-tests/test-results
ui-tests/playwright-report
2 changes: 1 addition & 1 deletion .github/workflows/update-integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
python_version: '3.11'

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

- name: Install extension
run: |
Expand Down
58 changes: 54 additions & 4 deletions ui-tests/helpers/SchedulerHelper.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { expect, IJupyterLabPageFixture } from '@jupyterlab/galata';
import type { Locator, TestInfo } from '@playwright/test';

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

type SnapshotOptions = {
Expand Down Expand Up @@ -50,16 +54,47 @@ export class SchedulerHelper {
) {}

/**
* JupyterLab launcher "Notebook Jobs" card selector
* JupyterLab launcher "Notebook Jobs" card locator
*/
get launcherCard() {
return this.page.locator(SELECTORS.LAUNCHER_CARD);
}

/**
* Locates notebook toolbar
*/
get notebookToolbar() {
return this.page.locator(SELECTORS.NOTEBOOK_TOOLBAR);
}

/**
* Locates "Create a notebook job" button in notebook toolbar
*/
get createJobTbutton() {
return this.page.locator(SELECTORS.CREATE_JOB_TBUTTON);
}

/**
* Locates "Enable debugger" icon in notebook toolbar
*/
get enableDebuggerTbutton() {
return this.page.locator(SELECTORS.ENABLE_DEBUGGER_TBUTTON);
}

/**
* Locates kernel name button in notebook toolbar
*/
get kernelNameTbutton() {
return this.page.locator(SELECTORS.KERNEL_NAME_TBUTTON);
}

/**
* Locates execution indicator icon in notebook toolbar
*/
get executionIndicatorTbutton() {
return this.page.locator(SELECTORS.EXECUTION_INDICATOR_TBUTTON);
}

/**
* Locates the previously created notebook's listing in the filebrowser.
*/
Expand All @@ -79,7 +114,7 @@ export class SchedulerHelper {
* Locates the column of timestamps in the list view. Used to mask this column
* during snapshot tests.
*/
get timestampLocator() {
get timestamp() {
return this.page.locator(SELECTORS.LIST_VIEW_TIMES);
}

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

async standardizeListCreateTime() {
await this.page.route('**/scheduler/*', async (route, req) => {
if (req.url().includes('max_items')) {
const res = await route.fetch();
const json = await res.json();
json.jobs[0].create_time = 1;
route.fulfill({
status: res.status(),
headers: res.headers(),
body: JSON.stringify(json)
});
}
});
}

protected async _waitForCreateJobLoaded() {
await this.page.waitForSelector('text=Loading …', { state: 'hidden' });
}
Expand Down
20 changes: 12 additions & 8 deletions ui-tests/tests/jupyter_scheduler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { SchedulerHelper } from '../helpers/SchedulerHelper';

enum FILENAMES {
LAUNCHER = 'launcher.png',
NOTEBOOK = 'notebook-view.png',
NOTEBOOK_TOOLBAR = 'notebook-toolbar.png',
FILEBROWSER_MENU = 'filebrowser-menu.png',
// TODO: resolve this inconsistency in our frontend code. One entry point
// includes the file extension in the job name, the other does not.
Expand Down Expand Up @@ -34,7 +34,14 @@ test.describe('Jupyter Scheduler', () => {
test('shows notebook toolbar button', async () => {
await scheduler.createNotebook();
await expect(scheduler.createJobTbutton).toBeVisible();
await scheduler.assertSnapshot(FILENAMES.NOTEBOOK);
await scheduler.assertSnapshot(FILENAMES.NOTEBOOK_TOOLBAR, {
locator: scheduler.notebookToolbar,
mask: [
scheduler.enableDebuggerTbutton,
scheduler.kernelNameTbutton,
scheduler.executionIndicatorTbutton
]
});
});

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

test('shows newly created job in job list view', async () => {
test('shows newly created job in job list view', async ({ page }) => {
await scheduler.createNotebook();
await scheduler.createJobFromFilebrowser();

const timeStamp = scheduler.timestampLocator;
await scheduler.assertSnapshot(FILENAMES.LIST_VIEW, {
mask: [timeStamp]
});
await scheduler.standardizeListCreateTime();
await scheduler.assertSnapshot(FILENAMES.LIST_VIEW);
});

test.afterEach(async () => {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading