Skip to content

test: add emails fixture and apply to existing tests#10560

Closed
nicktrn wants to merge 8 commits intocalcom:mainfrom
nicktrn:e2e-emails
Closed

test: add emails fixture and apply to existing tests#10560
nicktrn wants to merge 8 commits intocalcom:mainfrom
nicktrn:e2e-emails

Conversation

@nicktrn
Copy link
Copy Markdown
Contributor

@nicktrn nicktrn commented Aug 3, 2023

What does this PR do?

Adds fixture for email testing. Updates some tests for demo purposes.

// this:
const { id } = await prisma.resetPasswordRequest.findFirstOrThrow({
  where: {
    email,
  },
  select: {
    id: true,
  },
  orderBy: {
    createdAt: "desc",
  },
})
await page.goto(`/auth/forgot-password/${id}`)

// becomes that:
const email = await emails.waitForOne(email)
await email.clickCta()

// while ensuring we receive the appropriate email, and that the cta works

Brief API overview:

/* Fixture */

// string: just look for recipient
// object: filter by all email props - to, from, subject, (custom) headers, content, ..
type Filter = string | Record<string, string>

// wait until we receive an email matching a single filter
emails.waitForOne(filter: Filter): Email

// wait until we receive an email for each supplied filter
emails.waitForMany(filters: Filter[]): Email[]

// returns namespaced address that will be delivered to current test only
emails.generateAddress()


/* Email */

// renders email
email.open()

// renders email and clicks cta link
// shortcut for: await email.open() && page.getByTestId("cta-link").click()
email.clickCta()

// returns href via partial string match, e.g. "forgot" => "..example.com/forgot-password/"
email.findHref(partial: string)

Fixes #10535

Architectural overview

sequenceDiagram
    participant Client
    box Server
    participant WebSocket
    participant SMTP
    end
    participant Mailer

    Client-)WebSocket: subscribe
    Note right of Client: namespaced
    Mailer-)SMTP: send mail
    SMTP->>+WebSocket: get subscribers
    WebSocket-->>-SMTP: subscribers[ ]
    loop every subscriber
    SMTP-)WebSocket: forward mail
    end
    WebSocket-)Client: forward mail
    Note right of Client: namespaced
Loading

Type of change

  • New feature (non-breaking change which adds functionality)

How should this be tested?

yarn e2e playwright/{booking-pages,auth/forgot}

Runs fine locally, but still some things to sort out for ci. and now also on ci

Mandatory Tasks

  • Make sure you have self-reviewed the code. A decent size PR without self-review might be rejected.

@vercel
Copy link
Copy Markdown

vercel bot commented Aug 3, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
ui ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 3, 2023 9:40pm

@vercel
Copy link
Copy Markdown

vercel bot commented Aug 3, 2023

@nicktrn is attempting to deploy a commit to the cal Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions bot added automated-tests area: unit tests, e2e tests, playwright Low priority Created by Linear-GitHub Sync ✨ feature New feature or request labels Aug 3, 2023
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Aug 3, 2023

Thank you for following the naming conventions! 🙏

@socket-security
Copy link
Copy Markdown

New dependencies detected. Learn more about Socket for GitHub ↗︎

Packages Version New capabilities Transitives Size Publisher
smtp-server 3.12.0 network +3 717 kB andris
@types/mailparser 3.4.0 None +0 11.9 kB types
nodemailer 6.9.3 None +0 489 kB andris
@faker-js/faker 8.0.2 None +0 9.83 MB shinigami92
mailparser 3.6.5 None +14 2.52 MB andris

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Aug 3, 2023

📦 Next.js Bundle Analysis for @calcom/web

This analysis was generated by the Next.js Bundle Analysis action. 🤖

This PR introduced no changes to the JavaScript bundle! 🙌

@nicktrn
Copy link
Copy Markdown
Contributor Author

nicktrn commented Aug 3, 2023

@shivamklr @keithwillcode @zomars as you're currently working on or reviewing mailhog integration

Would greatly value your input.

Copy link
Copy Markdown
Contributor Author

@nicktrn nicktrn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ready for review and feedback

"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next",
"dev": "next dev",
"dx": "yarn dev",
"e2e:mail-server": "ts-node --transpile-only playwright/lib/start-mail-server.ts",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for testing purposes, should be built for production

test("Can reset forgotten password", async ({ page, users }) => {
const user = await users.create();
test("Can reset forgotten password", async ({ page, users, emails }) => {
const user = await users.create({ email: emails.generateAddress() });
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be further abstracted by moving directly into users fixture, then calling users.create() as usual

await page.goto("/auth/forgot-password");

await page.fill('input[name="email"]', `${user.username}@example.com`);
await page.fill('input[name="email"]', user.email);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

email is now scoped to the test

createdAt: "desc",
},
});
const email = await emails.waitForOne(user.email);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we wait until the user receives an email, it will return immediately if one is already there

const bookingUrl = page.url();

const [free] = users.get();
await emails.waitForMany([/* testEmail, */ free.email]);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will throw if not all recipients receive an email - I disabled checking for non-namespaced, hardcoded emails for now. Ideally, test/booking user should also be randomised and email addresses scoped to test

Comment on lines +96 to +99
ws.on("message", (data) => {
const message = data.toString();
debug("received:", message);
});
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bi-directional messaging not currently used, but useful for debugging

@@ -40,8 +40,6 @@ export default class BaseEmail {
if (process.env.NEXT_PUBLIC_IS_E2E) {
global.E2E_EMAILS = global.E2E_EMAILS || [];
global.E2E_EMAILS.push(this.getNodeMailerPayload());
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leaving for now as still used by at least one test file

"ts-node": "^10.9.1",
"typescript": "^4.9.4"
"typescript": "^4.9.4",
"ws": "^8.13.0"
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"@types/react-phone-number-input": "^3.0.14",
"@types/remove-markdown": "^0.3.1",
"@types/sanitize-html": "^2.9.0",
"@types/smtp-server": "^3.5.7",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"copy-webpack-plugin": "^11.0.0",
"detect-port": "^1.3.0",
"env-cmd": "^10.1.0",
"mailparser": "^3.6.5",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicktrn nicktrn marked this pull request as ready for review August 4, 2023 08:35
@nicktrn nicktrn mentioned this pull request Aug 4, 2023
1 task
@github-actions
Copy link
Copy Markdown
Contributor

This PR is being marked as stale due to inactivity.

@github-actions github-actions bot added the Stale label Aug 19, 2023
@nicktrn nicktrn mentioned this pull request Aug 22, 2023
3 tasks
@nicktrn
Copy link
Copy Markdown
Contributor Author

nicktrn commented Aug 22, 2023

Closing as per current email testing plans #10881 (comment)

@nicktrn nicktrn closed this Aug 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automated-tests area: unit tests, e2e tests, playwright ✨ feature New feature or request Low priority Created by Linear-GitHub Sync Stale

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RFC: e2e email testing

1 participant