Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions DEMO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
Prompt 1:

You're testing a web app by hand, using your browser tool. Don't write any code.

App: https://deploy-preview-10--endform-playwright-tutorial.netlify.app

1. Go to `/sign-up` and create an account with a made-up email like `demo-<random>@example.com` and the password `testpassword123`.
2. On the Team Settings page (`/dashboard`), invite a teammate using another made-up email, with the Member role, and wait for "Invitation sent successfully".
3. Open the Activity page from the sidebar.
4. Check that the newest (top) entry says "You invited a team member".

Report PASS or FAIL. Describe exactly what you saw at each step, including the full list of entries on the Activity page.

Prompt 2:

In this repo (branch `demo/invite-activity-after-response`), write a new Playwright test at `tests/team-invite-activity.live.spec.ts`. Explore the app first, using existing tests and functionality through an endform live test.

- Start a session inside an existing test that already has a logged-in new user: `tests/duplicate-invite.spec.ts` or similar using endform live test.
- Step through the scenario one action at a time. To expore and figure out which playwright code makes sense for the test.
- invite a teammate from the Team Settings page (`/dashboard`);
- wait for "Invitation sent successfully";
- open the Activity page from the sidebar;
- check that the newest entry is "You invited a team member".
- Once every step has worked live, stop the session and create a nice new playwright test for this flow.
- Follow the suite's conventions: the `testWithNewUser` fixture from `tests/test-with-new-user.ts`, `test.step` blocks, role-based locators, and a unique invite email per run.
- Finish by running it once with `npx endform test team-invite-activity.live`.

Next commands:

p playwright test team-invite-activity --debug --no-deps

p endform test team-invite-activity --repeat-each=100 --no-deps

Then ask:

look at `team-invite-activity` playwright/endform runs from the last hour. What's the pass rate, and what's the most common failure? Is it a bug in the app or noise in the test?
17 changes: 9 additions & 8 deletions app/(login)/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { and, eq } from "drizzle-orm";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import { after } from "next/server";
import { z } from "zod";
import { logActivity } from "@/lib/auth/activity";
import { signup } from "@/lib/auth/login";
Expand All @@ -22,6 +23,7 @@ import {
type User,
users,
} from "@/lib/db/schema";
import { sendInvitationEmail } from "@/lib/email";
import { isFaultActive } from "@/lib/faults";

const signInSchema = z.object({
Expand Down Expand Up @@ -365,14 +367,13 @@ export const inviteTeamMember = validatedActionWithUser(
})
.returning();

await logActivity(
userWithTeam.teamId,
user.id,
ActivityType.INVITE_TEAM_MEMBER,
);

// TODO: Send invitation email and include ?inviteId={id} to sign-up URL
// await sendInvitationEmail(email, userWithTeam.team.name, role)
// Email the invitee and log the invite once the response has been sent,
// so inviting feels instant.
const teamId = userWithTeam.teamId;
after(async () => {
await sendInvitationEmail(email, role);
await logActivity(teamId, user.id, ActivityType.INVITE_TEAM_MEMBER);
});

return { success: "Invitation sent successfully", id: invitation[0].id };
},
Expand Down
5 changes: 5 additions & 0 deletions endform.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { defineEndformConfig } from "endform";

export default defineEndformConfig({
organizationId: "68prmZ74",
});
14 changes: 14 additions & 0 deletions lib/email.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import "server-only";

// Stand-in for a transactional email provider. Most sends are quick but, like
// most third-party APIs, it has a slow tail.
export async function sendInvitationEmail(email: string, role: string) {
const latencyMs =
Math.random() < 0.15
? 6000 + Math.random() * 3000
: 50 + Math.random() * 100;
await new Promise((resolve) => setTimeout(resolve, latencyMs));
console.log(
`[email] sent ${role} invitation to ${email} in ${Math.round(latencyMs)}ms`,
);
}
7 changes: 5 additions & 2 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import type { PlaywrightOpentelemetryUseOptions } from "playwright-opentelemetry
// dotenv.config({ path: path.resolve(__dirname, '.env') });

export const baseURL =
process.env.BASE_URL || "https://endform-playwright-tutorial.vercel.app";
process.env.BASE_URL ||
"https://deploy-preview-10--endform-playwright-tutorial.netlify.app";

const playwrightOtelEnabled = Boolean(
process.env.PLAYWRIGHT_TRACE_API_ENDPOINT ||
Expand Down Expand Up @@ -47,7 +48,9 @@ export default defineConfig<PlaywrightOpentelemetryUseOptions>({
// baseURL: "http://localhost:3000",

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: playwrightOtelEnabled ? "on" : "retain-on-failure",
// trace: playwrightOtelEnabled ? "on" : "retain-on-failure",
trace: "on",
// trace: "retain-on-failure",
playwrightOpentelemetry: playwrightOtelEnabled
? {
trace: "on",
Expand Down
Loading