From eceb77a6c4ff40bcc6d2d42fedb8a33faeb9af29 Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 11 May 2026 12:59:01 +0200 Subject: [PATCH] fix(tests): smoke specs use page.request for auth-cookie carryover MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bare `request` fixture is an isolated API context that does not share the browser session cookie established by login(). Result: every API call hit withAuth and 401'd, and the tests silently skipped themselves through the existing graceful-skip guards — the assertions never ran. Switching to page.request shares the browser context cookie jar, so the API calls now reach the handler and the assertions execute. Also adds a conditional "view signing details" trigger assertion behind a feature-flag-style check so future signed-file seed fixtures exercise the SigningDetailsDialog path automatically. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../smoke/04-documents-hub-aggregated.spec.ts | 29 ++++++++------ ...4-documents-hub-upload-into-entity.spec.ts | 39 +++++++------------ 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/tests/e2e/smoke/04-documents-hub-aggregated.spec.ts b/tests/e2e/smoke/04-documents-hub-aggregated.spec.ts index caf73c64..0eb20a2c 100644 --- a/tests/e2e/smoke/04-documents-hub-aggregated.spec.ts +++ b/tests/e2e/smoke/04-documents-hub-aggregated.spec.ts @@ -81,11 +81,13 @@ test.describe('Documents hub — aggregated view', () => { test('entity sub-folder view renders Signing-in-progress and Files sections', async ({ page, - request, }) => { // Create a fresh client via the API so we have a guaranteed entity with a // folder. ensureEntityFolder is called by the createClient service hook. - const res = await request.post('/api/v1/clients', { + // page.request shares the browser context cookie jar (session cookie from + // login()) — the bare `request` fixture is an isolated API context that + // does not carry the session cookie and would 401. + const res = await page.request.post('/api/v1/clients', { data: { firstName: 'HubAgg', lastName: `Smoke${Date.now()}`, @@ -101,7 +103,9 @@ test.describe('Documents hub — aggregated view', () => { ); return; } - const { data: client } = (await res.json()) as { data: { id: string; firstName: string; lastName: string } }; + const { data: client } = (await res.json()) as { + data: { id: string; firstName: string; lastName: string }; + }; // Navigate to the documents hub. await navigateTo(page, '/documents'); @@ -110,10 +114,7 @@ test.describe('Documents hub — aggregated view', () => { // Expand the Clients system root by clicking its chevron (Expand button). // The Expand chevron is the first button sibling inside the FolderRow div. // It is aria-labeled "Expand" when collapsed. - const expandBtn = page - .locator('aside') - .getByRole('button', { name: 'Expand' }) - .first(); + const expandBtn = page.locator('aside').getByRole('button', { name: 'Expand' }).first(); await expect(expandBtn).toBeVisible({ timeout: 10_000 }); await expandBtn.click(); @@ -129,10 +130,7 @@ test.describe('Documents hub — aggregated view', () => { await navigateTo(page, '/documents'); await page.waitForLoadState('networkidle'); // Re-expand. - const expandBtn2 = page - .locator('aside') - .getByRole('button', { name: 'Expand' }) - .first(); + const expandBtn2 = page.locator('aside').getByRole('button', { name: 'Expand' }).first(); await expandBtn2.click(); } @@ -142,5 +140,14 @@ test.describe('Documents hub — aggregated view', () => { // EntityFolderView renders two AggregatedSection blocks with these headings. await expect(page.getByText('Signing in progress')).toBeVisible({ timeout: 10_000 }); await expect(page.getByText('Files')).toBeVisible({ timeout: 5_000 }); + + // TODO(Task 19 verification): assert SigningDetailsDialog trigger once + // a signed-file fixture exists in the smoke seed. The button is only + // rendered when files[].signedFromDocumentId is non-null (Task 15 fix-up). + const detailsButton = page.getByRole('button', { name: /view signing details/i }); + if ((await detailsButton.count()) > 0) { + await detailsButton.first().click(); + await expect(page.getByRole('dialog', { name: /Signing details/i })).toBeVisible(); + } }); }); diff --git a/tests/e2e/smoke/04-documents-hub-upload-into-entity.spec.ts b/tests/e2e/smoke/04-documents-hub-upload-into-entity.spec.ts index 5f7f287b..49ca0517 100644 --- a/tests/e2e/smoke/04-documents-hub-upload-into-entity.spec.ts +++ b/tests/e2e/smoke/04-documents-hub-upload-into-entity.spec.ts @@ -24,12 +24,14 @@ test.describe('Documents hub — upload into entity folder', () => { test('file uploaded with clientId appears in the client entity folder view', async ({ page, - request, }) => { const headers = await apiHeaders(page); // 1. Create a client. - const clientRes = await request.post('/api/v1/clients', { + // page.request shares the browser context cookie jar (session cookie from + // login()) — the bare `request` fixture is an isolated API context that + // does not carry the session cookie and would 401. + const clientRes = await page.request.post('/api/v1/clients', { headers, data: { firstName: 'UploadSmoke', @@ -38,10 +40,7 @@ test.describe('Documents hub — upload into entity folder', () => { }, }); if (!clientRes.ok()) { - test.skip( - true, - `Client create returned ${clientRes.status()} — upload test skipped`, - ); + test.skip(true, `Client create returned ${clientRes.status()} — upload test skipped`); return; } const { data: client } = (await clientRes.json()) as { @@ -66,7 +65,6 @@ test.describe('Documents hub — upload into entity folder', () => { const uploadRes = await page.request.fetch('/api/v1/files/upload', { method: 'POST', headers: { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion 'X-Port-Id': headers['X-Port-Id']!, }, multipart: { @@ -92,10 +90,7 @@ test.describe('Documents hub — upload into entity folder', () => { await page.waitForLoadState('networkidle'); // 4. Expand the Clients system root. - const expandBtn = page - .locator('aside') - .getByRole('button', { name: 'Expand' }) - .first(); + const expandBtn = page.locator('aside').getByRole('button', { name: 'Expand' }).first(); await expect(expandBtn).toBeVisible({ timeout: 10_000 }); await expandBtn.click(); @@ -116,15 +111,15 @@ test.describe('Documents hub — upload into entity folder', () => { await expect(page.getByText('test-document.txt')).toBeVisible({ timeout: 10_000 }); }); - test('file uploaded with folderId (entity folder) auto-sets client_id', async ({ - page, - request, - }) => { + test('file uploaded with folderId (entity folder) auto-sets client_id', async ({ page }) => { const headers = await apiHeaders(page); // 1. Create a client — ensureEntityFolder is triggered server-side when // the first file is uploaded with clientId or directly by the create hook. - const clientRes = await request.post('/api/v1/clients', { + // page.request shares the browser context cookie jar (session cookie from + // login()) — the bare `request` fixture is an isolated API context that + // does not carry the session cookie and would 401. + const clientRes = await page.request.post('/api/v1/clients', { headers, data: { firstName: 'FolderIdSmoke', @@ -162,10 +157,9 @@ test.describe('Documents hub — upload into entity folder', () => { } // 3. List files for this client to discover the folder id. - const listRes = await request.get( - `/api/v1/files?entityType=client&entityId=${client.id}`, - { headers }, - ); + const listRes = await page.request.get(`/api/v1/files?entityType=client&entityId=${client.id}`, { + headers, + }); if (!listRes.ok()) { test.skip(true, `File list returned ${listRes.status()} — folderId test skipped`); return; @@ -176,10 +170,7 @@ test.describe('Documents hub — upload into entity folder', () => { await page.waitForLoadState('networkidle'); // Expand Clients and click entity folder. - const expandBtn = page - .locator('aside') - .getByRole('button', { name: 'Expand' }) - .first(); + const expandBtn = page.locator('aside').getByRole('button', { name: 'Expand' }).first(); await expect(expandBtn).toBeVisible({ timeout: 10_000 }); await expandBtn.click();