Skip to content

test(e2e): exercise the JupyterLab integration through the labview (cell, widget, UI)#1001

Merged
krassowski merged 5 commits into
masterfrom
phase4/e2e-cell
Jul 1, 2026
Merged

test(e2e): exercise the JupyterLab integration through the labview (cell, widget, UI)#1001
krassowski merged 5 commits into
masterfrom
phase4/e2e-cell

Conversation

@notluquis

@notluquis notluquis commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Drives the labview WebContentsView to cover the pieces a JupyterLab version bump can break inside the embedded view that the existing "the labview reached the server URL" check does not catch:

  • A notebook cell runs. 1 + 1 through the labview: server boots, the kernel connects over the websocket Electron's net stack carries, output renders back. Deliberately trivial, testing numpy here would be testing Python, not Electron.
  • A bundled labextension draws. An ipywidgets IntSlider renders, riding the same kernel websocket and painting the control in the WebContentsView. jupyter labextension list only tells you the extension is compatible with the JupyterLab version; it does not tell you it renders here, which is the Electron concern.
  • The lab UI chrome renders. File browser, side bars, menu bar, status bar, the shell a bump can break without touching the notebook path.
  • Non-ASCII output renders. café, CJK and Greek through the view. This is the arm64 ICU check done by hand in past bump PRs, now automated.

Plus a plain electronAPI round-trip in the smoke suite (isDarkTheme): a renderer call over the contextBridge reaches the ipcMain handler and a value comes back, exercising that wiring end to end in the running app. The preload contract tests cover the API shape with mocks; this checks it actually wires up. It needs no Python env, so it stays in the smoke suite.

Harness changes that benefit every env-backed test:

  • The shared open-notebook-and-run flow lives in a runFirstNotebookCell helper, so the cell, widget, unicode tests each stay to one assertion. The cell handling mirrors @jupyterlab/galata (textbox role + pressSequentially, the status-bar kernel-ready poll) without pulling Galata in.
  • New sessions get defaultWorkingDirectory pointed at the per-launch temp dir, so notebooks the tests create land there and are removed with it. On macOS the spawned server's cwd follows that setting rather than $HOME (Electron resolves home via NSHomeDirectory), so without it the tests dropped Untitled.ipynb in the real home.
  • stubAllDialogs is retried once after a short settle: at launch a window can be mid-navigation, which makes its evaluate throw "execution context was destroyed" and was flaking the suite.

CI installs ipywidgets next to jupyterlab; jupyterlab already brings ipykernel.

I ran the full e2e suite locally against a clean venv twice end to end: 10 passed both times (~2 min), and the home directory stays empty before and after. The selector work was the fiddly part; the isolation and the flake fix are easy to confirm by repeating the run.

Adds an env-backed e2e that drives the labview WebContentsView: open a
notebook, run 1 + 1, assert the output renders. The point is the Electron
glue, not JupyterLab, so it stays at 1 + 1 (a kernel running over the
websocket Electron's net stack carries) rather than testing Python
packages. The cell handling mirrors what Galata does (textbox role +
pressSequentially, the status-bar kernel-ready check) instead of guessing
selectors, and the kernel picker is accepted only if it appears.

Also closes a gap the env-backed tests already meant to cover: new
sessions now get defaultWorkingDirectory set to the per-launch temp dir,
so notebooks the test creates land there and are cleaned up with it
rather than in the real home (on macOS HOME alone doesn't move the
session cwd).

I validated this locally against a clean jupyterlab venv: the cell test
passes repeatedly (~22s) and the home directory stays empty before and
after. jupyterlab already pulls ipykernel, so the venv has a python3
kernel without installing one separately, which I confirmed with a
jupyterlab-only venv (kernelspec lists python3).
Three env-backed e2e drive the labview WebContentsView, each covering a
piece a JupyterLab version bump can break in the embedded view that the
"reached the server URL" check does not:

- a notebook cell runs (1 + 1): server boots, the kernel connects over
  the websocket Electron carries, output renders back in the view
- a bundled labextension draws: an ipywidgets IntSlider renders, which
  rides the same widget-comm websocket and paints in the WebContentsView.
  This is the Electron-relevant check; jupyter labextension list only
  tells you the extension is compatible, not that it renders here
- the lab UI chrome renders: file browser, side bars, menu bar, status bar

The shared open-notebook-and-run flow moves into a runFirstNotebookCell
helper so the cell and widget tests stay to their one assertion. The cell
work mirrors Galata (textbox role + pressSequentially, the status-bar
kernel-ready poll) rather than hand-rolled selectors.

New sessions also get defaultWorkingDirectory set to the per-launch temp
dir, so notebooks the tests create land there and are cleaned up with it
rather than in the real home (on macOS the session cwd follows that
setting, not $HOME). CI installs ipywidgets next to jupyterlab for the
widget test; jupyterlab already brings ipykernel for the kernel.

I ran the four env-backed tests locally against a clean venv: all pass,
the widget and UI assertions repeat green, and the home directory stays
empty. The selector work was the fiddly part; the isolation is easy to
confirm by checking nothing is left behind.
@notluquis notluquis changed the title test(e2e): run a notebook cell through the labview, isolate the work dir test(e2e): exercise the JupyterLab integration through the labview (cell, widget, UI) Jun 29, 2026
Drive the labview WebContentsView to check the pieces a JupyterLab bump
can break in the embedded view that "reached the server URL" does not:

- a notebook cell runs (1 + 1): server boots, the kernel connects over
  the websocket Electron carries, output renders back in the view
- a bundled labextension draws: an ipywidgets IntSlider renders, riding
  the same widget-comm websocket and painting in the view. This is the
  Electron-relevant check; jupyter labextension list only says an
  extension is compatible, not that it renders here
- the lab UI chrome renders: file browser, side bars, menu bar, status bar
- non-ASCII output renders (cafe / CJK / Greek), the arm64 ICU check from
  past bump PRs, now automated

Also adds a plain electronAPI round-trip in the smoke suite (isDarkTheme),
which exercises the contextBridge to ipcMain wiring end to end in the
running app, where the preload contract tests use mocks.

Harness: the shared open-notebook-and-run flow moves into a
runFirstNotebookCell helper; new sessions get defaultWorkingDirectory set
to the per-launch temp dir so created notebooks land there and are cleaned
up with it (on macOS the session cwd follows that, not $HOME); and
stubAllDialogs is retried once after a settle, since at launch a window can
be mid-navigation and make its evaluate throw, which was flaking the suite.

I ran the full e2e suite locally against a clean venv twice end to end:
10 passed both times, and the home directory stays empty. CI installs
ipywidgets next to jupyterlab; jupyterlab already brings ipykernel.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands the Playwright e2e suite to exercise the embedded JupyterLab “labview” more deeply, aiming to catch Electron-integration regressions that a JupyterLab bump can introduce (cell execution, widget rendering, UI chrome, Unicode output), and adds a cheap smoke-level preload round-trip check.

Changes:

  • Add new env-backed e2e assertions for cell execution, ipywidgets rendering, UI chrome visibility, and non-ASCII output rendering.
  • Introduce a shared runFirstNotebookCell helper and improve launch stability/isolation (working directory + dialog stubbing retry).
  • Update CI e2e workflow to install ipywidgets alongside the pinned jupyterlab.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
test/e2e/smoke.test.ts Adds a smoke test that round-trips an electronAPI call to validate preload → IPC wiring.
test/e2e/python-env.test.ts Adds env-backed labview integration checks (cell, widget, UI chrome, Unicode).
test/e2e/helpers.ts Adds runFirstNotebookCell helper and improves env isolation + dialog-stub launch robustness.
.github/workflows/e2e.yml Installs ipywidgets in the CI venv to support the new widget-render e2e test.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/e2e/helpers.ts
Comment thread test/e2e/helpers.ts
Comment thread test/e2e/smoke.test.ts
Comment thread .github/workflows/e2e.yml
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@krassowski krassowski enabled auto-merge (squash) July 1, 2026 18:30
@krassowski krassowski merged commit 4cb3370 into master Jul 1, 2026
12 checks passed
@krassowski krassowski deleted the phase4/e2e-cell branch July 1, 2026 18:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants