Skip to content

Commit 5a897a4

Browse files
committed
test(e2e): fix flaky "creating a new notebook adds a tab" spec
1 parent 8044ff2 commit 5a897a4

2 files changed

Lines changed: 28 additions & 2 deletions

File tree

‎tests/e2e/fixtures-warm.ts‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,29 @@ export async function resetWarmNotebookPanel(page: Page): Promise<void> {
143143
}
144144
});
145145
// 3. Spawn a fresh Empty notebook and ensure it is the active tab.
146+
//
147+
// ``persistAndOpen`` (in ``NotebookPanel``) awaits a Pyodide round-trip
148+
// before it appends the new tab to the React state. Previous tests in
149+
// the warm worker may have left several stale ``Untitled`` tabs around,
150+
// and the *previously* active tab may also be titled ``Untitled``.
151+
// Asserting only that "the active tab is named Untitled" is therefore
152+
// racy: the assertion can match the prior active tab and return BEFORE
153+
// the new tab has been appended, leaving a deferred React state update
154+
// that pollutes the next test.
155+
//
156+
// To get a deterministic reset, snapshot the tab count first and wait
157+
// for it to grow by exactly one before continuing.
158+
const tabCountBefore = await page.locator(".nb-tab").count();
146159
await page.locator(".nb-tab-new").click();
147160
await page.getByRole("menuitem", { name: /Empty notebook/ }).click();
161+
await expect(page.locator(".nb-tab")).toHaveCount(tabCountBefore + 1, {
162+
timeout: 10_000,
163+
});
164+
// The newly-appended tab is always the last one (``openOrFocusNotebook``
165+
// appends), and the panel activates it synchronously after the append.
166+
await expect(page.locator(".nb-tab").last()).toHaveClass(/active/, {
167+
timeout: 10_000,
168+
});
148169
await expect(page.locator(".nb-tab.active .nb-tab-title")).toHaveText(
149170
"Untitled",
150171
{ timeout: 10_000 },

‎tests/e2e/notebooks.spec.ts‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,15 @@ test.describe("Notebook UI", () => {
150150
const before = await page.locator(".nb-tab").count();
151151
await page.locator(".nb-tab-new").click();
152152
await page.getByRole("menuitem", { name: /Empty notebook/ }).click();
153-
// One more tab and the latest one is active.
153+
// One more tab and the latest one is active. ``persistAndOpen``
154+
// appends the new tab to the React state and immediately activates
155+
// it, so the newly-created notebook is always the *last* tab — use
156+
// ``.last()`` rather than ``.nth(before)`` to keep the assertion
157+
// robust if a stale, deferred state update from a previous test
158+
// happens to land between the count snapshot and the assertions.
154159
await expect(page.locator(".nb-tab")).toHaveCount(before + 1);
155160
await expect(page.locator(".nb-tab.active")).toHaveCount(1);
156-
await expect(page.locator(".nb-tab").nth(before)).toHaveClass(/active/);
161+
await expect(page.locator(".nb-tab").last()).toHaveClass(/active/);
157162
});
158163

159164
test("Export… triggers a .ipynb download with valid nbformat content", async ({

0 commit comments

Comments
 (0)