import { test, expect, PASSWORD, uniqueEmail } from './fixtures'; test.describe('Customer accounts', () => { // Both names are required from anyone new so every email has a first name to // greet with (#106). The server refuses without them; this is the form // refusing first, so nobody gets a round trip to find out. test('will not submit a registration without both names', async ({ authModal, header }) => { await authModal.gotoRegister(); await authModal.fillRegistration({ email: uniqueEmail(), password: PASSWORD }); await authModal.submitRegistration(); await expect(authModal.registerDialog.getByText('First name is required')).toBeVisible(); await expect(authModal.registerDialog.getByText('Last name is required')).toBeVisible(); // Still on the form rather than signed in. await expect(header.myAccountButton).toHaveCount(0); }); test('marketing consent checkbox is unchecked by default', async ({ authModal }) => { await authModal.gotoRegister(); await expect(authModal.marketingConsent).not.toBeChecked(); }); test('the consent label is the exact wording the server records', async ({ authModal }) => { await authModal.gotoRegister(); // The stored consent text is kept verbatim so the record says what the // customer actually saw. Three different wordings were in circulation // before the sign-in form was shared between the routes and the cart // prompt, and none of them matched what was stored. // Widened in #56 to cover the Brevo tracker as well as email. The literal is // repeated here rather than imported on purpose: importing it from the app // would make this assert that a constant equals itself, and the drift it // guards against is exactly the rendered label parting from the stored // string. const consent = 'I want to receive occasional emails about new one-of-a-kind items from Redefined Designs, and I agree that what I browse and buy here may be shared with our email provider to help choose what they contain. I can unsubscribe at any time.'; await expect(authModal.registerDialog).toContainText(consent); }); // Drives the form rather than taking the `customer` fixture: this test is // about registering, so the thing under test has to be the thing exercised. test('registering signs the customer in and returns them where they were', async ({ page, authModal, header, accountModal }) => { const email = uniqueEmail(); await authModal.gotoRegister(); await authModal.fillRegistration({ email, password: PASSWORD, firstName: 'Test', lastName: 'Customer' }); await authModal.submitRegistration(); await header.waitForSignedIn(); // Back on the storefront, signed in — not moved to the account page. await expect(page).toHaveURL(/\/$/); await accountModal.open(); await expect(accountModal.emailText(email)).toBeVisible(); }); test('rejects login with the wrong password', async ({ page, customer, accountModal, authModal, header }) => { await accountModal.openAndLogOut(); await expect(header.logInButton).toBeVisible(); await authModal.gotoLogIn(); await authModal.logIn(customer.email, 'wrong-password'); await expect(page.getByText('invalid email or password')).toBeVisible(); }); test('logging out returns to the home page and resets the header', async ({ page, customer, accountModal, header }) => { await accountModal.openAndLogOut(); // A server round-trip followed by re-rendering the storefront behind the // modal, so the 5s default is too tight when workers run concurrently. await expect(page).toHaveURL(/\/$/, { timeout: 20000 }); await expect(header.logInButton).toBeVisible(); await expect(header.signUpButton).toBeVisible(); await expect(header.myAccountButton).toBeHidden(); }); test('the logged-out header survives a reload', async ({ page, customer, accountModal, header }) => { await accountModal.openAndLogOut(); await expect(header.logInButton).toBeVisible(); // Proves the server session was actually destroyed, rather than the header // merely being repainted from stale client state. await page.reload(); await expect(header.logInButton).toBeVisible(); await expect(header.myAccountButton).toBeHidden(); }); test('logging out does not leave the account page on the back stack', async ({ page, customer, accountModal }) => { await accountModal.openAndLogOut(); await expect(page).toHaveURL(/\/$/, { timeout: 20000 }); await page.goBack(); await expect(page).not.toHaveURL(/\/account/); }); test('a failed logout says so instead of appearing to succeed', async ({ page, customer, accountModal }) => { await accountModal.open(); await page.route('**/api/customers/logout', (route) => route.fulfill({ status: 500, contentType: 'application/json', body: '{"error":"internal error"}' }) ); await accountModal.logOut(); // The session cookie is still valid, so pretending to be logged out would // silently log the customer back in on their next reload. await expect(page.getByText(/couldn't log out/i)).toBeVisible(); await expect(page).toHaveURL(/\/account/); }); }); test.describe('Auth routes are not dead ends', () => { test('opening Log in from the header closes back to where browsing left off', async ({ page, header, authModal }) => { await page.goto('/?max_price=50000'); await header.logInButton.click(); await expect(authModal.logInDialog).toBeVisible(); await expect(page).toHaveURL(/\/login/); await authModal.closeButton.click(); await expect(authModal.logInDialog).toBeHidden(); await expect(page).toHaveURL(/max_price=50000/); }); test('a direct visit opens over the storefront rather than a blank page', async ({ authModal, header }) => { await authModal.gotoLogIn(); await expect(authModal.logInDialog).toBeVisible(); await expect(header.siteTitle).toBeVisible(); }); test('switching between sign in and sign up keeps one history entry', async ({ page, header, authModal }) => { await page.goto('/?max_price=50000'); await header.logInButton.click(); await authModal.createAccountTab.click(); await expect(page).toHaveURL(/\/register/); await authModal.logInTab.click(); await expect(page).toHaveURL(/\/login/); // Back returns to browsing rather than walking through each tab visited. await page.goBack(); await expect(page).toHaveURL(/max_price=50000/); await expect(authModal.logInDialog).toBeHidden(); }); test('signing in from the header returns to the page behind, signed in', async ({ page, customer, accountModal, header, authModal }) => { await accountModal.openAndLogOut(); await expect(header.logInButton).toBeVisible(); await page.goto('/?max_price=50000'); await header.logInButton.click(); await authModal.logIn(customer.email, customer.password); await header.waitForSignedIn(); await expect(page).toHaveURL(/max_price=50000/); }); test('reaching password recovery from the login form keeps a way back', async ({ page, authModal, passwordReset }) => { await authModal.gotoLogIn(); await authModal.forgotPasswordButton.click(); await expect(passwordReset.requestDialog).toBeVisible(); await expect(page).toHaveURL(/\/forgot-password/); await passwordReset.signInButton.click(); await expect(authModal.logInDialog).toBeVisible(); }); });