Skip to content

Commit 80085bf

Browse files
committed
Add change email test
1 parent bf955c7 commit 80085bf

File tree

4 files changed

+145
-2
lines changed

4 files changed

+145
-2
lines changed

playwright.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export default defineConfig({
3333
// baseURL: "http://localhost:3000",
3434

3535
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
36-
trace: "on-first-retry",
36+
trace: "on",
3737
},
3838

3939
/* Configure projects for major browsers */

tests/change-email.spec.ts

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import { expect, test } from "@playwright/test";
2+
3+
// Use a clean user for this test, to not interfere with other tests
4+
test.use({ storageState: { cookies: [], origins: [] } });
5+
6+
test.describe("User Email Change Flow", () => {
7+
test("should sign up new user, change email, sign out, and sign in with new email", async ({
8+
page,
9+
}) => {
10+
// Generate random emails for the test
11+
const initialEmail = `${Math.random().toString(36).substring(2, 15)}@example.com`;
12+
const newEmail = `${Math.random().toString(36).substring(2, 15)}@example.com`;
13+
const testPassword = "testpassword123";
14+
15+
await test.step("Navigate to homepage and ensure clean state", async () => {
16+
await page.goto("/");
17+
await expect(page).toHaveTitle("Playwright Tutorial");
18+
19+
// Verify we're not logged in by checking for Sign Up link
20+
await expect(page.getByRole("link", { name: "Sign Up" })).toBeVisible();
21+
});
22+
23+
await test.step("Navigate to sign up page", async () => {
24+
await page.getByRole("link", { name: "Sign Up" }).click();
25+
await expect(page).toHaveURL("/sign-up");
26+
await expect(
27+
page.getByRole("heading", { name: "Create your account" }),
28+
).toBeVisible();
29+
});
30+
31+
await test.step("Fill signup form and submit", async () => {
32+
await page.getByRole("textbox", { name: "Email" }).fill(initialEmail);
33+
await page.getByRole("textbox", { name: "Password" }).fill(testPassword);
34+
await page.getByRole("button", { name: "Sign up" }).click();
35+
});
36+
37+
await test.step("Verify successful signup redirects to dashboard", async () => {
38+
await expect(page).toHaveURL("/dashboard");
39+
await expect(
40+
page.getByRole("heading", { name: "Team Settings" }),
41+
).toBeVisible();
42+
// Verify initial email appears in team members list
43+
await expect(page.getByText(initialEmail)).toBeVisible();
44+
});
45+
46+
await test.step("Navigate to general settings page", async () => {
47+
await page.getByRole("link", { name: "General" }).click();
48+
await expect(page).toHaveURL("/dashboard/general");
49+
await expect(
50+
page.getByRole("heading", { name: "General Settings" }),
51+
).toBeVisible();
52+
});
53+
54+
await test.step("Change email to new randomly generated email", async () => {
55+
const nameInput = page.getByRole("textbox", { name: "Name" });
56+
await expect(nameInput).toBeVisible();
57+
await nameInput.fill("John Doe");
58+
59+
const emailInput = page.getByRole("textbox", { name: "Email" });
60+
await expect(emailInput).toBeVisible();
61+
await expect(emailInput).toHaveValue(initialEmail);
62+
63+
await emailInput.clear();
64+
await emailInput.fill(newEmail);
65+
await page.getByRole("button", { name: "Save Changes" }).click();
66+
67+
// Wait for success message
68+
await expect(
69+
page.getByText("Account updated successfully."),
70+
).toBeVisible();
71+
});
72+
73+
await test.step("Sign out", async () => {
74+
// Click on user menu button
75+
await page.getByTestId("user-menu-trigger").click();
76+
await page.getByRole("button", { name: "Sign out" }).click();
77+
78+
// Verify we're signed out by checking for Sign Up link
79+
await expect(page.getByRole("link", { name: "Sign Up" })).toBeVisible();
80+
});
81+
82+
await test.step("Sign in with new email and test password", async () => {
83+
// If not already on sign-in page, navigate there
84+
const currentUrl = page.url();
85+
if (!currentUrl.includes("/sign-in")) {
86+
await page.goto("/sign-in");
87+
}
88+
89+
await expect(
90+
page.getByRole("heading", { name: "Sign in to your account" }),
91+
).toBeVisible();
92+
93+
await page.getByRole("textbox", { name: "Email" }).fill(newEmail);
94+
await page.getByRole("textbox", { name: "Password" }).fill(testPassword);
95+
await page.getByRole("button", { name: "Sign in" }).click();
96+
});
97+
98+
await test.step("Verify successful sign in and redirect to team settings page", async () => {
99+
await expect(page).toHaveURL("/dashboard");
100+
await expect(
101+
page.getByRole("heading", { name: "Team Settings" }),
102+
).toBeVisible();
103+
});
104+
105+
await test.step("Verify new email is displayed in general settings page", async () => {
106+
await page.getByRole("link", { name: "General" }).click();
107+
await expect(page).toHaveURL("/dashboard/general");
108+
await expect(
109+
page.getByRole("heading", { name: "General Settings" }),
110+
).toBeVisible();
111+
112+
// Verify the new email is displayed in the email field
113+
const emailInput = page.getByRole("textbox", { name: "Email" });
114+
await expect(emailInput).toBeVisible();
115+
await expect(emailInput).toHaveValue(newEmail);
116+
});
117+
});
118+
});

tutorial.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export const tutorialConfig: TutorialConfig = {
3636
"tests/change-password.spec.ts",
3737
"tests/change-name.spec.ts",
3838
"tests/plan-upgrade.spec.ts",
39+
"tests/change-email.spec.ts",
3940
],
4041
},
4142
{

tutorial/stage-2-generated-tests/generate-tests-playwright-mcp.mdx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,20 @@ Here are a few more prompts you can try out to generate more tests (don't forget
375375
- Verify that the users new name is displayed in the team members list.
376376
```
377377

378+
#### Change the email
379+
```
380+
# Test scenario
381+
- Navigate to /.
382+
- (sign out of the current user, this is not part of the test for later, but we need to have a clean new user here to not interfere with other tests)
383+
- sign up as a new user with a randomly generated email and password "testpassword123".
384+
- Navigate to the general section.
385+
- Change the email to a new randomly generated email.
386+
- Sign out.
387+
- Sign in with the password "testpassword123" and the new email.
388+
- Verify that we are logged in and on the team settings page.
389+
- verify that the new email is displayed on the general page in the email field.
390+
```
391+
378392

379393

380394
## List of bugs we found and fixed in the course of generating these tests
@@ -388,10 +402,20 @@ Instead, here's a list of bugs we fixed to give you an idea of the kinds of prob
388402
- Users couldn't not be deleted when activities existed, foreign key constraint
389403
- The user menu wouldn't collapse on click
390404
- Updating the user name wouldn't update the user menu name icon
405+
- Not possible to update the email without updating the name
391406

392407
Other classic problems with the tests that the AI generated:
393408

394409
- Strict mode violations / more than one element on the page that matches a locator
395410
- Adding manual timeouts to tests instead of crafting good assertions
396411
- Hardcoding urls instead of using relative paths
397-
- Not using Playwright `test.step` to label steps in the test & excessive comments
412+
- Not using Playwright `test.step` to label steps in the test & excessive comments
413+
414+
## Glaring holes in our test setup at the moment
415+
416+
It's been fantastic to generate a few tests using this method. When creating this tutorial, I was able to go from one test to ten tests in the space of just an hour or two, but that also should give us a little space to reflect over what we've done.
417+
418+
At the moment:
419+
420+
- Have lots of duplicated selectors in tests where better practice would be to have [page object models](https://playwright.dev/docs/pom) so that we can reduce the amount of places we need to update selectors when changes are needed.
421+
- Our change email test manually runs through the signup process again, instead of using the available API endpoint to generate a new user.

0 commit comments

Comments
 (0)