import { test, expect, Page } from '@playwright/test'; const PASSWORD = 'supersecret123'; const uniqueEmail = () => `account-${Date.now().toString(36)}${Math.random().toString(36).slice(2, 7)}@example.com`; // Registering lands on /account, which is now the modal over the storefront. // Returns the address so a test can assert the right account is shown. async function registerAndCloseAccount(page: Page): Promise { const email = uniqueEmail(); await page.goto('/register'); await page.getByRole('textbox', { name: 'Email' }).fill(email); await page.getByLabel('Password').fill(PASSWORD); await page.getByRole('button', { name: 'Create account' }).click(); await expect(page).toHaveURL(/\/account/); await closeAccount(page); return email; } const accountModal = (page: Page) => page.getByRole('dialog', { name: 'My Account' }); async function closeAccount(page: Page) { await accountModal(page).getByRole('button', { name: 'Close' }).click(); await expect(accountModal(page)).toBeHidden(); } test.describe('My Account opens as a modal', () => { test('opens over the storefront and closes back to it, filters and all', async ({ page }) => { await registerAndCloseAccount(page); // A filtered view, to prove closing restores where the customer actually // was rather than a bare storefront. await page.goto('/?max_price=50000'); await expect(page.getByRole('button', { name: 'My Account' })).toBeVisible(); await page.getByRole('button', { name: 'My Account' }).click(); await expect(accountModal(page)).toBeVisible(); // Still a real, linkable URL rather than hidden view state. await expect(page).toHaveURL(/\/account/); await closeAccount(page); await expect(page).toHaveURL(/max_price=50000/); }); test('the browser back button closes it, the same as the close control', async ({ page }) => { await registerAndCloseAccount(page); await page.goto('/?max_price=50000'); await page.getByRole('button', { name: 'My Account' }).click(); await expect(accountModal(page)).toBeVisible(); await page.goBack(); await expect(accountModal(page)).toBeHidden(); await expect(page).toHaveURL(/max_price=50000/); }); test('a direct visit renders the storefront behind it, so closing lands somewhere real', async ({ page }) => { await registerAndCloseAccount(page); // A bookmark, or the link in a verification email. There is no page behind // in this case, which is what used to make /account a dead end. await page.goto('/account'); await expect(accountModal(page)).toBeVisible(); await expect(page.getByRole('heading', { name: 'Redefined Designs' })).toBeVisible(); await closeAccount(page); await expect(page).toHaveURL(/\/$/); await expect(page.getByRole('button', { name: 'My Account' })).toBeVisible(); }); test('survives a reload, since it is a route rather than view state', async ({ page }) => { const email = await registerAndCloseAccount(page); await page.goto('/?max_price=50000'); await page.getByRole('button', { name: 'My Account' }).click(); await expect(accountModal(page)).toBeVisible(); await page.reload(); await expect(accountModal(page)).toBeVisible(); await expect(accountModal(page)).toContainText(email); }); test('shows the signed-in account and its settings', async ({ page }) => { const email = await registerAndCloseAccount(page); await page.goto('/account'); const modal = accountModal(page); await expect(modal).toContainText(email); await expect(modal).toContainText('Order History'); // Scoped to the modal: the storefront behind it has a theme switch of its // own, so an unscoped switch locator would be ambiguous. await expect(modal.getByRole('switch')).toHaveCount(2); }); });