From cc721609274d38d9a578575710edcb00d8064548 Mon Sep 17 00:00:00 2001 From: Oliver Stenbom Date: Wed, 11 Nov 2026 20:38:12 +0100 Subject: [PATCH 1/2] Log team invitations before responding, not after the email The invite activity was written in after(), behind the invitation email. When the email provider was slow (6-9s), the activity log didn't show the invite until well after the inviter saw "Invitation sent", which also made the team-invite-activity test flaky. Write the activity with the invitation and only defer the email. Co-Authored-By: Claude Opus 5.5 --- app/(login)/actions.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/app/(login)/actions.ts b/app/(login)/actions.ts index cd45efc..38677bf 100644 --- a/app/(login)/actions.ts +++ b/app/(login)/actions.ts @@ -339,13 +339,17 @@ export const inviteTeamMember = validatedActionWithUser( }) .returning(); - // 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); - }); + // The activity log is the team's record of what happened, so it is written + // with the invitation and is there as soon as the inviter looks for it. + await logActivity( + userWithTeam.teamId, + user.id, + ActivityType.INVITE_TEAM_MEMBER, + ); + + // The email provider has a slow tail, so send once the response has gone + // out and inviting still feels instant. + after(() => sendInvitationEmail(email, role)); return { success: "Invitation sent successfully", id: invitation[0].id }; }, From 6b7dddfb35ad2b00e02dd86a73ad7f6bc14e1e82 Mon Sep 17 00:00:00 2001 From: Oliver Stenbom Date: Wed, 11 Nov 2026 20:45:09 +0100 Subject: [PATCH 2/2] Throwaway: repeat the invite activity test 20 times (after the fix) --- .github/workflows/e2e-endform.yml | 2 +- .github/workflows/e2e-intent.yml | 47 ------------------ .github/workflows/e2e-playwright.yml | 55 --------------------- .github/workflows/endform-tests-on-main.yml | 45 ----------------- .github/workflows/endform-tests-on-prs.yml | 45 ----------------- 5 files changed, 1 insertion(+), 193 deletions(-) delete mode 100644 .github/workflows/e2e-intent.yml delete mode 100644 .github/workflows/e2e-playwright.yml delete mode 100644 .github/workflows/endform-tests-on-main.yml delete mode 100644 .github/workflows/endform-tests-on-prs.yml diff --git a/.github/workflows/e2e-endform.yml b/.github/workflows/e2e-endform.yml index a202245..ff491a4 100644 --- a/.github/workflows/e2e-endform.yml +++ b/.github/workflows/e2e-endform.yml @@ -42,4 +42,4 @@ jobs: set-vercel-bypass-env-var: VERCEL_BYPASS_TOKEN - name: Run end to end tests with Endform - run: npx endform@latest test + run: npx endform@latest test --repeat-each 20 --max-failures 0 -g "team invitation in the activity log" diff --git a/.github/workflows/e2e-intent.yml b/.github/workflows/e2e-intent.yml deleted file mode 100644 index badcdbb..0000000 --- a/.github/workflows/e2e-intent.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Playwright Intent - -on: - pull_request: - branches: - - webinar/main - -permissions: - contents: write # the agent commits changed steps to the pull request - id-token: write # used by the Vercel deployment action - -jobs: - e2e: - if: github.repository == 'endformdev/playwright-tutorial' - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up pnpm - uses: pnpm/action-setup@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 24 - cache: "pnpm" - - - name: Install dependencies - run: pnpm install - - - name: Install Playwright browsers - run: pnpm exec playwright install --with-deps chromium - - - name: Wait for Vercel deployment - uses: endformdev/actions/run-with-vercel-deployment@main - with: - project-name: endform-playwright-tutorial - set-url-env-var: BASE_URL - set-vercel-bypass-env-var: VERCEL_BYPASS_TOKEN - - - name: Run intent tests - run: pnpm exec playwright test -c playwright.intent.config.ts - env: - AI_GATEWAY_API_KEY: ${{ secrets.AI_GATEWAY_API_KEY }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/e2e-playwright.yml b/.github/workflows/e2e-playwright.yml deleted file mode 100644 index f7c37ee..0000000 --- a/.github/workflows/e2e-playwright.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: Playwright - -on: - pull_request: - branches: - - webinar/main - push: - branches: - - webinar/main - -permissions: - contents: read - id-token: write # used by the Vercel deployment action - -jobs: - e2e: - if: github.repository == 'endformdev/playwright-tutorial' - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up pnpm - uses: pnpm/action-setup@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: lts/* - cache: "pnpm" - - - name: Install dependencies - run: pnpm install - - - name: Install Playwright browsers - run: pnpm exec playwright install --with-deps chromium - - - name: Wait for Vercel deployment - uses: endformdev/actions/run-with-vercel-deployment@main - with: - project-name: endform-playwright-tutorial - set-url-env-var: BASE_URL - set-vercel-bypass-env-var: VERCEL_BYPASS_TOKEN - - - name: Run Playwright tests - run: pnpm exec playwright test - - - name: Upload Playwright report - if: ${{ !cancelled() }} - uses: actions/upload-artifact@v4 - with: - name: playwright-report - path: playwright-report/ - retention-days: 30 diff --git a/.github/workflows/endform-tests-on-main.yml b/.github/workflows/endform-tests-on-main.yml deleted file mode 100644 index 9880892..0000000 --- a/.github/workflows/endform-tests-on-main.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Run end to end tests with endform on main - -on: - push: - branches: - - main - -permissions: - contents: read - id-token: write # required for authentication with Endform - -jobs: - e2e: - # Only run in this repository: copies made by the Deploy to Vercel/Netlify - # buttons don't have its Vercel project, so the job would always fail there. - if: github.repository == 'endformdev/playwright-tutorial' - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up pnpm - uses: pnpm/action-setup@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: lts/* - cache: "pnpm" - - - name: Install dependencies - run: pnpm install - - - name: Wait for Vercel deployment - uses: endformdev/actions/run-with-vercel-deployment@main - with: - project-name: endform-playwright-tutorial - set-url-env-var: BASE_URL # Sets the Vercel preview URL as the BASE_URL environment variable - set-vercel-bypass-env-var: VERCEL_BYPASS_TOKEN # Exports a deployment protection bypass token as this env var - - - name: Run end to end tests with endform - run: | - npx endform@latest test diff --git a/.github/workflows/endform-tests-on-prs.yml b/.github/workflows/endform-tests-on-prs.yml deleted file mode 100644 index f4a30bc..0000000 --- a/.github/workflows/endform-tests-on-prs.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Run end to end tests with endform - -on: - pull_request: - branches: - - main - -permissions: - contents: read - id-token: write # required for authentication with Endform - -jobs: - e2e: - # Only run in this repository: copies made by the Deploy to Vercel/Netlify - # buttons don't have its Vercel project, so the job would always fail there. - if: github.repository == 'endformdev/playwright-tutorial' - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up pnpm - uses: pnpm/action-setup@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: lts/* - cache: "pnpm" - - - name: Install dependencies - run: pnpm install - - - name: Wait for Vercel deployment - uses: endformdev/actions/run-with-vercel-deployment@main - with: - project-name: endform-playwright-tutorial - set-url-env-var: BASE_URL # Sets the Vercel preview URL as the BASE_URL environment variable - set-vercel-bypass-env-var: VERCEL_BYPASS_TOKEN # Exports a deployment protection bypass token as this env var - - - name: Run end to end tests with endform - run: | - npx endform@latest test