import { expect, request as apiRequest, test } from '@playwright/test'; import { FRONTEND_URL, WORKER_URL, createTestAddress, deleteAddress, seedTestMail, } from '../../fixtures/test-helpers'; test.describe('Mail state browser flow', () => { test('opens, toggles, filters and marks the current page read', async ({ page }) => { const request = await apiRequest.newContext(); let jwt: string | undefined; try { const mailbox = await createTestAddress(request, 'mail-flags-browser'); jwt = mailbox.jwt; const subjects = [`Unread A ${Date.now()}`, `Unread B ${Date.now()}`]; for (const subject of subjects) { await seedTestMail(request, mailbox.address, { subject }); } await page.goto(`${FRONTEND_URL}/en/`); await page.evaluate(() => localStorage.setItem('mailListView', 'true')); await page.goto(`${FRONTEND_URL}/en/?jwt=${jwt}`); for (const subject of subjects) { await expect(page.getByText(subject, { exact: true })).toBeVisible({ timeout: 10_000 }); } await expect(page.getByText('Unread', { exact: true })).toHaveCount(2); const openStateResponse = page.waitForResponse((response) => { return new URL(response.url()).pathname === '/api/mails/state' && response.request().method() === 'PATCH'; }); await page.getByText(subjects[0], { exact: true }).click(); expect((await openStateResponse).ok()).toBe(true); await expect(page.getByRole('button', { name: 'Mark as Unread' })).toBeVisible(); const unreadAfterOpen = await request.get( `${WORKER_URL}/api/mails?limit=10&offset=0&mail_state=unread`, { headers: { Authorization: `Bearer ${jwt}` } }, ); expect((await unreadAfterOpen.json()).results).toHaveLength(1); const toggleResponse = page.waitForResponse((response) => { return new URL(response.url()).pathname === '/api/mails/state' && response.request().method() === 'PATCH'; }); await page.getByRole('button', { name: 'Mark as Unread' }).click(); expect((await toggleResponse).ok()).toBe(true); await expect(page.getByRole('button', { name: 'Mark as Read' })).toBeVisible(); await page.getByRole('button', { name: 'Back to List' }).click(); const pageReadResponse = page.waitForResponse((response) => { if (new URL(response.url()).pathname !== '/api/mails/state') return false; if (response.request().method() !== 'PATCH') return false; const body = response.request().postDataJSON(); return body.state === 'read' && body.ids.length === 2; }); await page.getByRole('button', { name: 'Mark This Page as Read' }).click(); expect((await pageReadResponse).ok()).toBe(true); await expect(page.getByRole('button', { name: 'Mark This Page as Read' })).toBeHidden(); const unreadAfterPage = await request.get( `${WORKER_URL}/api/mails?limit=10&offset=0&mail_state=unread`, { headers: { Authorization: `Bearer ${jwt}` } }, ); expect((await unreadAfterPage.json()).results).toHaveLength(0); const unreadFilterResponse = page.waitForResponse((response) => { const url = new URL(response.url()); return url.pathname === '/api/mails' && url.searchParams.get('mail_state') === 'unread'; }); const stateSelect = page.locator('.n-select').filter({ hasText: 'All Mail' }).first(); await stateSelect.click(); await page.locator('.n-base-select-option').filter({ hasText: /^Unread$/ }).click(); expect((await unreadFilterResponse).ok()).toBe(true); for (const subject of subjects) { await expect(page.getByText(subject, { exact: true })).toHaveCount(0); } } finally { try { if (jwt) await deleteAddress(request, jwt); } finally { await request.dispose(); } } }); });