test(e2e): exercise the JupyterLab integration through the labview (cell, widget, UI)#1001
Merged
Conversation
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).
36f324b to
507efb4
Compare
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.
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.
Contributor
There was a problem hiding this comment.
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
runFirstNotebookCellhelper and improve launch stability/isolation (working directory + dialog stubbing retry). - Update CI e2e workflow to install
ipywidgetsalongside the pinnedjupyterlab.
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.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
krassowski
approved these changes
Jul 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
1 + 1through 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.ipywidgetsIntSliderrenders, riding the same kernel websocket and painting the control in the WebContentsView.jupyter labextension listonly tells you the extension is compatible with the JupyterLab version; it does not tell you it renders here, which is the Electron concern.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
electronAPIround-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:
runFirstNotebookCellhelper, 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.defaultWorkingDirectorypointed 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 droppedUntitled.ipynbin the real home.stubAllDialogsis retried once after a short settle: at launch a window can be mid-navigation, which makes itsevaluatethrow "execution context was destroyed" and was flaking the suite.CI installs
ipywidgetsnext tojupyterlab;jupyterlabalready bringsipykernel.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.