From 311086d0e743e9b1ce9419dacd18230b96295778 Mon Sep 17 00:00:00 2001 From: giancarlo Date: Thu, 11 Apr 2024 18:15:16 +0800 Subject: [PATCH] Update retries in playwright config and refactor account settings This update changes the number of retries in the Playwright configuration. Additionally, solid improvements have been made in the account settings, including better data semantics for testing, changes to email confirmation, and adding a new E2E test suite for accounts. The sign-up flow was updated and problems with multi-language support logic were fixed. --- apps/e2e/playwright.config.ts | 3 +- apps/e2e/tests/account/account.po.ts | 35 +++++++++++++++++ apps/e2e/tests/account/account.spec.ts | 38 +++++++++++++++++++ apps/e2e/tests/authentication/auth.po.ts | 18 ++++++++- apps/e2e/tests/utils/mailbox.ts | 6 +++ .../components/personal-account-dropdown.tsx | 12 +++++- .../account-settings-container.tsx | 6 ++- .../email/update-email-form.tsx | 9 +++-- .../update-account-details-form.tsx | 6 +-- .../components/password-sign-up-container.tsx | 4 +- .../components/sign-up-methods-container.tsx | 7 ++++ 11 files changed, 130 insertions(+), 14 deletions(-) create mode 100644 apps/e2e/tests/account/account.po.ts create mode 100644 apps/e2e/tests/account/account.spec.ts diff --git a/apps/e2e/playwright.config.ts b/apps/e2e/playwright.config.ts index 504e978ce..1c8cdd282 100644 --- a/apps/e2e/playwright.config.ts +++ b/apps/e2e/playwright.config.ts @@ -15,8 +15,7 @@ export default defineConfig({ fullyParallel: true, /* Fail the build on CI if you accidentally left test.only in the source code. */ forbidOnly: !!process.env.CI, - /* Retry on CI only */ - retries: process.env.CI ? 2 : 0, + retries: process.env.CI ? 3 : 1, /* Opt out of parallel tests on CI. */ workers: process.env.CI ? 1 : undefined, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ diff --git a/apps/e2e/tests/account/account.po.ts b/apps/e2e/tests/account/account.po.ts new file mode 100644 index 000000000..faa8589a5 --- /dev/null +++ b/apps/e2e/tests/account/account.po.ts @@ -0,0 +1,35 @@ +import { Page } from '@playwright/test'; +import { AuthPageObject } from '../authentication/auth.po'; + +export class AccountPageObject { + private readonly page: Page; + public auth: AuthPageObject; + + constructor(page: Page) { + this.page = page; + this.auth = new AuthPageObject(page); + } + + async setup() { + return this.auth.signUpFlow('/home/settings'); + } + + async updateProfileName(name: string) { + await this.page.locator('[data-test="update-account-name-form"] input').fill(name); + await this.page.locator('[data-test="update-account-name-form"] button').click(); + } + + async updateProfileEmail(email: string) { + await this.page.locator('[data-test="account-email-form-email-input"]').fill(email); + await this.page.locator('[data-test="account-email-form-repeat-email-input"]').fill(email); + await this.page.locator('[data-test="account-email-form"] button').click(); + } + + getProfileName() { + return this.page.locator('[data-test="account-dropdown-display-name"]'); + } + + getProfileEmail() { + return this.page.locator('[data-test="account-dropdown-email"]'); + } +} \ No newline at end of file diff --git a/apps/e2e/tests/account/account.spec.ts b/apps/e2e/tests/account/account.spec.ts new file mode 100644 index 000000000..1c06dc000 --- /dev/null +++ b/apps/e2e/tests/account/account.spec.ts @@ -0,0 +1,38 @@ +import { expect, Page, test } from '@playwright/test'; +import { AccountPageObject } from './account.po'; + +test.describe('Account Settings', () => { + let page: Page; + let account: AccountPageObject; + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + account = new AccountPageObject(page); + + await account.setup(); + }) + + test('user can update their profile name', async () => { + const name = 'John Doe'; + + await account.updateProfileName(name); + + await page.waitForResponse((resp) => { + return resp.url().includes('accounts'); + }); + + await expect(account.getProfileName()).toHaveText(name); + }); + + test('user can update their email', async () => { + const email = account.auth.createRandomEmail(); + + await account.updateProfileEmail(email); + + const req = await page.waitForResponse((resp) => { + return resp.url().includes('auth/v1/user'); + }); + + expect(req.status()).toBe(200); + }); +}); \ No newline at end of file diff --git a/apps/e2e/tests/authentication/auth.po.ts b/apps/e2e/tests/authentication/auth.po.ts index 024fabb8a..da283969e 100644 --- a/apps/e2e/tests/authentication/auth.po.ts +++ b/apps/e2e/tests/authentication/auth.po.ts @@ -43,7 +43,7 @@ export class AuthPageObject { async visitConfirmEmailLink(email: string) { await this.page.waitForTimeout(300); - return this.mailbox.visitMailbox(email); + await this.mailbox.visitMailbox(email); } createRandomEmail() { @@ -51,4 +51,20 @@ export class AuthPageObject { return `${value.toFixed(0)}@makerkit.dev`; } + + async signUpFlow(path: string) { + const email = this.createRandomEmail(); + + await this.page.goto(`/auth/sign-up?next=${path}`, { + waitUntil: 'networkidle', + }); + + await this.signUp({ + email, + password: 'password', + repeatPassword: 'password', + }); + + await this.visitConfirmEmailLink(email); + } } \ No newline at end of file diff --git a/apps/e2e/tests/utils/mailbox.ts b/apps/e2e/tests/utils/mailbox.ts index 594fd02b9..32db5b687 100644 --- a/apps/e2e/tests/utils/mailbox.ts +++ b/apps/e2e/tests/utils/mailbox.ts @@ -18,6 +18,12 @@ export class Mailbox { const json = await this.getInviteEmail(mailbox); + if (!json.body) { + console.log(json); + + throw new Error('Email body was not found'); + } + const html = (json.body as { html: string }).html; const el = parse(html); diff --git a/packages/features/accounts/src/components/personal-account-dropdown.tsx b/packages/features/accounts/src/components/personal-account-dropdown.tsx index cab659cee..ec59020b4 100644 --- a/packages/features/accounts/src/components/personal-account-dropdown.tsx +++ b/packages/features/accounts/src/components/personal-account-dropdown.tsx @@ -88,9 +88,17 @@ export function PersonalAccountDropdown({ 'fade-in animate-in flex w-full flex-col truncate text-left' } > - {displayName} + + {displayName} + - + {signedInAsLabel} diff --git a/packages/features/accounts/src/components/personal-account-settings/account-settings-container.tsx b/packages/features/accounts/src/components/personal-account-settings/account-settings-container.tsx index 63658a7f0..d0faabc3d 100644 --- a/packages/features/accounts/src/components/personal-account-settings/account-settings-container.tsx +++ b/packages/features/accounts/src/components/personal-account-settings/account-settings-container.tsx @@ -156,5 +156,9 @@ export function PersonalAccountSettingsContainer( function useSupportMultiLanguage() { const { i18n } = useTranslation(); - return i18n.options.supportedLngs && i18n.options.supportedLngs.length > 1; + const langs = (i18n.options.supportedLngs as string[]) ?? []; + + const supportedLangs = langs.filter((lang) => lang !== 'cimode'); + + return supportedLangs.length > 1; } diff --git a/packages/features/accounts/src/components/personal-account-settings/email/update-email-form.tsx b/packages/features/accounts/src/components/personal-account-settings/email/update-email-form.tsx index ceddac848..f4b7f11d1 100644 --- a/packages/features/accounts/src/components/personal-account-settings/email/update-email-form.tsx +++ b/packages/features/accounts/src/components/personal-account-settings/email/update-email-form.tsx @@ -3,6 +3,7 @@ import type { User } from '@supabase/supabase-js'; import { zodResolver } from '@hookform/resolvers/zod'; +import { CheckIcon } from '@radix-ui/react-icons'; import { useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { toast } from 'sonner'; @@ -74,11 +75,13 @@ export function UpdateEmailForm({
+ + @@ -99,7 +102,7 @@ export function UpdateEmailForm({ diff --git a/packages/features/accounts/src/components/personal-account-settings/update-account-details-form.tsx b/packages/features/accounts/src/components/personal-account-settings/update-account-details-form.tsx index bbe50dbf2..921f766a9 100644 --- a/packages/features/accounts/src/components/personal-account-settings/update-account-details-form.tsx +++ b/packages/features/accounts/src/components/personal-account-settings/update-account-details-form.tsx @@ -50,7 +50,7 @@ export function UpdateAccountDetailsForm({ return toast.promise(() => promise, { success: t(`updateProfileSuccess`), error: t(`updateProfileError`), - loading: t(`:pdateProfileLoading`), + loading: t(`updateProfileLoading`), }); }; @@ -58,7 +58,7 @@ export function UpdateAccountDetailsForm({
@@ -72,7 +72,7 @@ export function UpdateAccountDetailsForm({ - + diff --git a/packages/features/auth/src/components/sign-up-methods-container.tsx b/packages/features/auth/src/components/sign-up-methods-container.tsx index 55ed0c3fe..0b024efe8 100644 --- a/packages/features/auth/src/components/sign-up-methods-container.tsx +++ b/packages/features/auth/src/components/sign-up-methods-container.tsx @@ -87,6 +87,13 @@ function getCallbackUrl(props: { url.searchParams.set('invite_token', props.inviteToken); } + const searchParams = new URLSearchParams(window.location.search); + const next = searchParams.get('next'); + + if (next) { + url.searchParams.set('next', next); + } + return url.href; }