Skip to content

test(auth): add Playwright E2E coverage for invite request CTA #411

Merged
motirebuma merged 4 commits into
QuoteVote:mainfrom
Sakshamk17:feat/e2e-auth-005
Jul 7, 2026
Merged

test(auth): add Playwright E2E coverage for invite request CTA #411
motirebuma merged 4 commits into
QuoteVote:mainfrom
Sakshamk17:feat/e2e-auth-005

Conversation

@Sakshamk17

Copy link
Copy Markdown
Contributor

Summary

Fixes issue #397 .
This PR introduces Playwright end-to-end test coverage for the invite request CTA at /auths/request-access, covering both the happy path (successful submission) and the duplicate handling path. It also resolves a blocking semantic issue in PageContent.tsx where the form lacked a proper <form> element, and adds the data-testid selectors required for stable test targeting.


Changes Implemented

Fixes & Enhancements

  • Refactored the invite request submission in PageContent.tsx from an unstable div + onClick setup to a semantic <form onSubmit>, enabling native Enter key submission and proper form accessibility
  • Added data-testid attributes across PageContent.tsx and PersonalForm.tsx per the selectors specified in the issue:
    • invite-request-form
    • invite-email-input
    • invite-submit-button
    • invite-duplicate-message
    • invite-success-message

Test Implementation

  • Added two new test scenarios to e2e/auth.spec.ts under the Invite Request CTA (E2E-AUTH-005) describe block:
    • Success path — mocks checkDuplicateEmail (empty) and requestUserAccess (success), verifies the "Thank you for joining us" confirmation renders
    • Duplicate path — mocks checkDuplicateEmail (existing record), verifies "This email already exists" message appears and the success state does not render
  • Introduced mockGraphQLOperation() helper to intercept Apollo GraphQL requests by operation name, avoiding any dependency on a live backend
  • Both scenarios verified across Desktop Chrome and Mobile Chrome (Pixel 7) Playwright projects

Bug Fix — Jest/ts-jest version mismatch

  • The upstream merge introduced jest@30 while ts-jest is still on v29 — these are incompatible and caused Jest's globals (describe, jest, it) to stop being injected, breaking the entire unit test suite
  • Downgraded jest and jest-environment-jsdom from 30.x29.7.0 to restore compatibility with ts-jest@29.4.11

Verification

Check Result
Playwright — Desktop Chrome ✅ 3/3 passing
Playwright — Mobile Chrome ✅ 3/3 passing
Jest unit suite ✅ 154/155 suites passing
TypeScript ✅ No errors

The one failing Jest suite (SettingsContent › handles very long input values) is a pre-existing timing flake that reproduces consistently independent of this branch. The ProfileHeaderCover › linear-gradient failure was introduced by the upstream merge and is also unrelated to this change.


Notes for Reviewers

  • Both GraphQL operations (checkDuplicateEmail query and requestUserAccess mutation) are mocked at the network layer via page.route() since no real backend is required for this test to be meaningful. Operation names match the camelCase definitions in src/graphql/queries.ts and src/graphql/mutations.ts exactly.

  • page.keyboard.type() is used instead of Playwright's fill() for the email input. This is intentional — react-hook-form with zodResolver requires real keyboard events to trigger validation and enable the submit button. fill() bypasses React's synthetic event system and leaves the button permanently disabled.

  • The SettingsContent timeout flake and ProfileHeaderCover assertion failure are both pre-existing upstream issues introduced before this branch and are not caused by these changes.

…UTH-005)

Implements E2E-AUTH-005 (P0): validates that a logged-out visitor can
submit an invite request and receive confirmation, and that duplicate
submissions are handled gracefully with clear messaging.

Changes:
- Add data-testid attributes to PageContent.tsx (invite-request-form,
  invite-email-input, invite-submit-button, invite-duplicate-message)
  and PersonalForm.tsx (invite-success-message)
- Wrap email input and submit button in a proper <form onSubmit>
  (was a bare div with onClick, no semantic form element)
- Add mockGraphQLOperation helper to auth.spec.ts intercepting Apollo
  operations by name (checkDuplicateEmail, requestUserAccess)
- Add two test scenarios: success path and duplicate handling,
  both verified on Desktop Chrome and Mobile Chrome
- Downgrade jest/jest-environment-jsdom from 30.x to 29.7.0 to fix
  compatibility with ts-jest@29 (upstream merged jest@30 prematurely)

Playwright: 6/6 passing across Desktop Chrome and Mobile Chrome
Jest: 154/155 suites (1 pre-existing SettingsContent timeout flake,
unrelated to this change)
Copilot AI review requested due to automatic review settings July 6, 2026 14:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR adds Playwright end-to-end coverage for the invite request CTA at /auths/request-access (E2E-AUTH-005), and updates the request-access UI to be more testable and semantic. It also adjusts Jest/ts-jest-related dependencies to address a Jest major-version mismatch that was breaking unit tests.

Changes:

  • Refactors the request-access CTA interaction to use a semantic <form onSubmit> and adds stable data-testid hooks.
  • Adds Playwright E2E scenarios for invite request success and duplicate handling, with GraphQL network mocking by operation name.
  • Downgrades Jest to 29.7.x and updates lockfile entries to restore compatibility with ts-jest.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
quotevote-frontend/src/components/RequestAccess/PersonalForm/PersonalForm.tsx Adds test targeting for the invite success confirmation UI.
quotevote-frontend/src/app/auths/request-access/PageContent.tsx Converts CTA UI to a form-based submission flow and adds data-testid attributes.
quotevote-frontend/e2e/auth.spec.ts Adds E2E-AUTH-005 coverage and introduces a GraphQL operation-mocking helper.
quotevote-frontend/package.json Adjusts Jest/ts-jest versions to address major-version incompatibility.
quotevote-frontend/pnpm-lock.yaml Lockfile updates reflecting Jest/ts-jest dependency changes.
Files not reviewed (1)
  • quotevote-frontend/pnpm-lock.yaml: Generated file
Comments suppressed due to low confidence (1)

quotevote-frontend/src/components/RequestAccess/PersonalForm/PersonalForm.tsx:77

  • data-testid="invite-success-message" is currently applied to the

    in both success and non-success states. That makes the selector misleading and allows tests to pass/fail incorrectly (e.g., the element remains visible even when the invite request is not successful).

        <h1 data-testid="invite-success-message" className="text-center text-2xl md:text-4xl font-bold mb-4 md:mb-8">
          {requestInviteSuccessful ? (
            <>
              Thank you for{' '}
              <span className="text-[#52b274]">joining us</span>

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 213 to 216
<button
data-testid="invite-submit-button"
onClick={onSubmit}
disabled={loading}
Comment on lines +168 to +171
// 2. Email input accepts a registered email address
await emailInput.fill(registeredUser.email);
await emailInput.dispatchEvent("input");

* password setup, admin invite management, email delivery.
*/

const GRAPHQL_URL = "http://localhost:4000/graphql";
Comment on lines +201 to +202
await emailInput.fill(visitorEmail);
await submitButton.click();
Comment on lines +210 to +211
const successMessage = page.getByTestId("invite-success-message");
await expect(successMessage).not.toBeVisible();
Comment on lines 183 to +185
ts-jest:
specifier: ^29.4.5
version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@30.2.0(@types/node@20.19.25))(typescript@5.9.3)
specifier: ^29.4.11
version: 29.4.11(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@20.19.25))(typescript@5.9.3)
Comment on lines +80 to +85
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"next-test-api-route-handler": "^5.0.3",
"prettier": "^3.7.1",
"tailwindcss": "^4",
"ts-jest": "^29.4.5",
"ts-jest": "^29.4.11",
Comment on lines 193 to 197
<input
data-testid="invite-email-input"
type="email"
placeholder="Enter Email"
value={userDetails}
@motirebuma motirebuma self-requested a review July 6, 2026 20:40

@motirebuma motirebuma left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nice work @Sakshamk17. Clean and well-scoped -- the E2E spec covers both the happy path and the duplicate handling path, the mockGraphQLOperation helper is reusable, and the <form onSubmit> refactor in PageContent.tsx is a good accessibility improvement. The note about page.keyboard.type() vs fill() for react-hook-form compatibility is a helpful detail for future contributors.

Two things to fix:

  1. The <button onClick={onSubmit}> in PageContent.tsx still has the old onClick handler alongside the new <form onSubmit>. Since the form's onSubmit already calls onSubmit(), the button's onClick is redundant and will fire the submission twice if someone clicks (once from onClick, once from the form submit event). Remove the onClick from the button and just keep type="submit".

  2. The frontend CI is currently failing. Please make sure pnpm run test, pnpm run lint, and pnpm run type-check all pass before this can be merged.

Verdict: Will be approved and merged after fixing the double-submit bug and getting CI green.

Thank you!!

@flyblackbox @Sakshamk17

@vercel

vercel Bot commented Jul 7, 2026

Copy link
Copy Markdown

@Sakshamk17 is attempting to deploy a commit to the Louis Girifalco's projects Team on Vercel.

A member of the Team first needs to authorize it.

@Sakshamk17

Copy link
Copy Markdown
Contributor Author

Hi @motirebuma and @flyblackbox , I have successfully resolved all merge conflicts and synchronized the branch with the upstream main. The codebase is fully normalized and ready for your review.

@motirebuma motirebuma self-requested a review July 7, 2026 19:57

@motirebuma motirebuma left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nice work @Sakshamk17. You addressed the previous feedback:

  • Double-submit bug -- fixed. The redundant onClick={onSubmit} is removed from the button and replaced with type="submit", so the form's onSubmit handles submission cleanly without firing twice.

The E2E spec covers both the happy path and the duplicate handling path, the mockGraphQLOperation helper is reusable, and the <form onSubmit> refactor is a good accessibility improvement.

CI is all green (Backend, Frontend, E2E all passing).

Verdict: approved, ready to merge.

Thank you!!!!

@flyblackbox @Sakshamk17

@motirebuma motirebuma merged commit 5dd433c into QuoteVote:main Jul 7, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants