From 3cfb26e8c395f3fea06ad53ccb1d82231b69d578 Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Thu, 25 Jun 2026 18:35:55 -0300 Subject: [PATCH] test: use gotoChannel when possible --- apps/meteor/tests/e2e/README.md | 24 +++++++++++++++++-- apps/meteor/tests/e2e/embedded-layout.spec.ts | 15 ++++-------- apps/meteor/tests/e2e/file-upload.spec.ts | 8 +++---- apps/meteor/tests/e2e/image-upload.spec.ts | 3 +-- .../meteor/tests/e2e/quote-attachment.spec.ts | 3 +-- apps/meteor/tests/e2e/quote-messages.spec.ts | 3 +-- 6 files changed, 33 insertions(+), 23 deletions(-) diff --git a/apps/meteor/tests/e2e/README.md b/apps/meteor/tests/e2e/README.md index 90b96c356b736..6358a7c6babda 100644 --- a/apps/meteor/tests/e2e/README.md +++ b/apps/meteor/tests/e2e/README.md @@ -243,6 +243,26 @@ Do **not** apply when: - Suite covers auth, 2FA, or session lifecycle — the browser state is the subject. - Suite has more than ~15 tests: the debug cost of shared state outgrows the speed win (see "Big test files should not be `.serial`" above). +### Pattern 3 — navigate to a known room by URL, not by search + +When a test already knows the room it needs (a channel created via API, `general`, etc.), open it directly with `poHomeChannel.gotoChannel(name)` instead of `page.goto('/home')` + `navbar.openChat(name)`. + +```ts +// ❌ fragile — three independent things must align before the combobox `fill` resolves +await page.goto('/home'); +await poHomeChannel.navbar.openChat(targetChannel); + +// ✅ deterministic — navigate straight to the room, then wait for it to be ready +await poHomeChannel.gotoChannel(targetChannel); +``` + +Why: searching the navbar couples the navigation to (1) the app shell hydrating, (2) the **search index** having picked up the room — a real lag for a channel created moments earlier via API — and (3) the listbox rendering and the option becoming clickable. Any one stalling makes `searchInput.fill` hang until the test timeout, surfacing as the misleading `Target page, context or browser has been closed`. `gotoChannel` loads `/channel/` and then `waitForChannel()` (main region, heading, message list, `aria-busy` cleared), so it has a proper readiness wait without the search dependency. + +Do **not** apply when: +- The navbar search is the actual subject of the test. +- Navigating to a **DM** (`/direct/`) or a **discussion** — `gotoChannel` builds a `/channel/` URL only. +- Reaching a channel the user is **not a member of** — the direct URL hits a different preview/join flow; verify the behavior before switching. + ## API helpers for state seeding Prefer these helpers in `beforeAll` / `beforeEach` and in setup `test.step`s. All live under `apps/meteor/tests/e2e/utils/`. @@ -296,8 +316,7 @@ test.describe.serial('Feature X', () => { page = await context.newPage(); poHomeChannel = new HomeChannel(page); - await page.goto('/home'); - await poHomeChannel.navbar.openChat(targetChannel); + await poHomeChannel.gotoChannel(targetChannel); }); test.afterAll(async ({ api }) => { @@ -332,6 +351,7 @@ Recipe for a single spec. Keep PRs to at most 5 files so reviews stay tractable. - `poHomeChannel.content.sendMessage(...)` used inside `beforeEach` or `beforeAll` — that is setup, should be `sendMessage(api, ...)`. - Opening meatball menus or modals purely to create a discussion, thread, or DM as a setup step. - `test.describe.serial` combined with `beforeEach(async ({ page }) => { await page.goto(...) })` — the context should be shared in `beforeAll`. +- `page.goto('/home')` + `navbar.openChat(name)` to reach a room the test already knows — use `poHomeChannel.gotoChannel(name)` (see Pattern 3). Searching a just-created channel races the search index and hangs until timeout. - New non-serial suites whose tests still each carry >3s of UI setup. - Inline `api.post('/im.create', …)` / `api.post('/chat.sendMessage', …)` in a spec instead of extending the helpers in `utils/`. diff --git a/apps/meteor/tests/e2e/embedded-layout.spec.ts b/apps/meteor/tests/e2e/embedded-layout.spec.ts index c834d96c17da8..b4901cd04feb5 100644 --- a/apps/meteor/tests/e2e/embedded-layout.spec.ts +++ b/apps/meteor/tests/e2e/embedded-layout.spec.ts @@ -31,8 +31,7 @@ test.describe('embedded-layout', () => { test.describe('Layout elements visibility', () => { test('should hide primary navigation elements in embedded layout', async ({ page }) => { - await page.goto('/home'); - await poHomeChannel.navbar.openChat(targetChannelId); + await poHomeChannel.gotoChannel(targetChannelId); await expect(poHomeChannel.roomHeaderToolbar).toBeVisible(); await page.goto(embeddedLayoutURL(page.url())); @@ -50,8 +49,7 @@ test.describe('embedded-layout', () => { }); test('should show room header toolbar as top navbar when setting enabled', async ({ page }) => { - await page.goto('/home'); - await poHomeChannel.navbar.openChat(targetChannelId); + await poHomeChannel.gotoChannel(targetChannelId); await page.goto(embeddedLayoutURL(page.url())); await expect(poHomeChannel.roomHeaderToolbar).toBeVisible(); @@ -61,8 +59,7 @@ test.describe('embedded-layout', () => { test.describe('Channel member functionality', () => { test('should hide join button and enable messaging for members', async ({ page }) => { - await page.goto('/home'); - await poHomeChannel.navbar.openChat(targetChannelId); + await poHomeChannel.gotoChannel(targetChannelId); await page.goto(embeddedLayoutURL(page.url())); await expect(poHomeChannel.composer.inputMessage).toBeVisible(); @@ -71,8 +68,7 @@ test.describe('embedded-layout', () => { }); test('should allow sending and receiving messages', async ({ page }) => { - await page.goto('/home'); - await poHomeChannel.navbar.openChat(targetChannelId); + await poHomeChannel.gotoChannel(targetChannelId); await page.goto(embeddedLayoutURL(page.url())); const testMessage = `Embedded test message ${Date.now()}`; @@ -81,8 +77,7 @@ test.describe('embedded-layout', () => { }); test('should preserve message composer functionality', async ({ page }) => { - await page.goto('/home'); - await poHomeChannel.navbar.openChat(targetChannelId); + await poHomeChannel.gotoChannel(targetChannelId); await page.goto(embeddedLayoutURL(page.url())); await expect(poHomeChannel.composer.inputMessage).toBeVisible(); diff --git a/apps/meteor/tests/e2e/file-upload.spec.ts b/apps/meteor/tests/e2e/file-upload.spec.ts index 0b371494e5478..7e70791c368b6 100644 --- a/apps/meteor/tests/e2e/file-upload.spec.ts +++ b/apps/meteor/tests/e2e/file-upload.spec.ts @@ -24,8 +24,7 @@ test.describe.serial('file-upload', () => { test.beforeEach(async ({ page }) => { poHomeChannel = new HomeChannel(page); - await page.goto('/home'); - await poHomeChannel.navbar.openChat(targetChannel); + await poHomeChannel.gotoChannel(targetChannel); }); test.afterAll(async ({ api }) => { @@ -132,7 +131,7 @@ test.describe.serial('file-upload', () => { test('should upload file in composer after recording video message', async ({ context }) => { await context.grantPermissions(['camera', 'microphone']); - await poHomeChannel.navbar.openChat(targetChannel); + await poHomeChannel.gotoChannel(targetChannel); await test.step('should be able to record a video with text content in composer ', async () => { await poHomeChannel.composer.inputMessage.fill('this is a message with video message'); @@ -235,8 +234,7 @@ test.describe('file-upload-not-member', () => { test.beforeEach(async ({ page }) => { poHomeChannel = new HomeChannel(page); - await page.goto('/home'); - await poHomeChannel.navbar.openChat(targetChannel); + await poHomeChannel.gotoChannel(targetChannel); }); test.afterAll(async ({ api }) => { diff --git a/apps/meteor/tests/e2e/image-upload.spec.ts b/apps/meteor/tests/e2e/image-upload.spec.ts index 3e19f8ae945db..dc7de61e51751 100644 --- a/apps/meteor/tests/e2e/image-upload.spec.ts +++ b/apps/meteor/tests/e2e/image-upload.spec.ts @@ -19,8 +19,7 @@ test.describe('image-upload', () => { test.beforeEach(async ({ page }) => { poHomeChannel = new HomeChannel(page); - await page.goto('/home'); - await poHomeChannel.navbar.openChat(targetChannel); + await poHomeChannel.gotoChannel(targetChannel); }); test.afterAll(async ({ api }) => { diff --git a/apps/meteor/tests/e2e/quote-attachment.spec.ts b/apps/meteor/tests/e2e/quote-attachment.spec.ts index 2630e2bcbe3d5..9c3bbf17ac4b8 100644 --- a/apps/meteor/tests/e2e/quote-attachment.spec.ts +++ b/apps/meteor/tests/e2e/quote-attachment.spec.ts @@ -18,8 +18,7 @@ test.describe.parallel('Quote Attachment', () => { test.beforeEach(async ({ page }) => { poHomeChannel = new HomeChannel(page); - await page.goto('/home'); - await poHomeChannel.navbar.openChat(targetChannel); + await poHomeChannel.gotoChannel(targetChannel); }); test.afterAll(async ({ api }) => { diff --git a/apps/meteor/tests/e2e/quote-messages.spec.ts b/apps/meteor/tests/e2e/quote-messages.spec.ts index 334dbfcd20da7..1c98af01c898f 100644 --- a/apps/meteor/tests/e2e/quote-messages.spec.ts +++ b/apps/meteor/tests/e2e/quote-messages.spec.ts @@ -32,8 +32,7 @@ test.describe.serial('Quote Messages', () => { page = await context.newPage(); poHomeChannel = new HomeChannel(page); - await page.goto('/home'); - await poHomeChannel.navbar.openChat(targetChannel); + await poHomeChannel.gotoChannel(targetChannel); }); test.afterAll(async ({ api }) => {