diff --git a/website/cypress/README.md b/website/cypress/README.md index 7f2c5d53..4750cbf6 100644 --- a/website/cypress/README.md +++ b/website/cypress/README.md @@ -58,13 +58,13 @@ under test. When running `npm run cypress` and selecting e2e testing, we assume you have the NextJS site running at `localhost:3000`. -An example test from this time of writing, could look as follows: +An example test could look as follows: ```typescript describe("signin flow", () => { it("redirects to a confirmation page on submit of valid email address", () => { cy.visit("/auth/signin"); - cy.get(".chakra-input").type(`test@example.com{enter}`); + cy.get('[data-cy="email-address"]').type(`test@example.com{enter}`); cy.url().should("contain", "/auth/verify"); }); }); @@ -82,10 +82,49 @@ Cypress will [automatically await](https://docs.cypress.io/guides/core-concepts/introduction-to-cypress#Timeouts) almost anything you do, but fail if the default timeout is reached. -Then we get the email input field and type our email address. Notice the -`{enter}` keyword, this will cause Cypress to hit the return key which we expect -to submit the form. +Then we get the email input field and type our email address. We find the input +field using the data-cy attribute that we added in the source code of the +element on the page. + +```jsx + +``` + +Using `data-cy` is how we ensure that selecting the element is robust to changes +in page design or function and is one of the +[best practices recommended by Cypress](https://docs.cypress.io/guides/references/best-practices#Selecting-Elements). + +Next we call `type()` to use the keyboard, cypress will automatically focus the +element and send the keypress events. Notice the `{enter}` keyword, this will +cause Cypress to hit the return key which we expect to submit the form. We then assert that the URL should contain `/auth/verify`. Again the timeout will make sure we are not waiting forever, and the test will fail if we do not manage to get there in a reasonable time. + +## Authenticating in e2e tests + +For end-to-end tests almost every test will need to first sign in to the +website. To make this easier we have a custom command for Cypress that makes +logging in with an email address a single command, `cy.signInWithEmail()`. + +```typescript +describe("replying as the assistant", () => { + it("completes the current task on submit", () => { + cy.signInWithEmail("cypress@example.com"); + + cy.visit("/create/assistant_reply"); + + cy.get('[data-cy="reply"').type( + "You need to run pre-commit to make the reviewer happy." + ); + cy.get('[data-cy="submit"]').click(); + }); +}); +``` + +In this example we sign in as `cypress@example.com` before visiting the +`/create/assistant_reply` page that is only available when authenticated. We can +then continue on with our test as normal. Note: using `cy.signInWithEmail()` +requires that the maildev is running, which should have been started as part of +the `docker compose up` command that is required to do any end-to-end testing. diff --git a/website/cypress/e2e/auth/signin.cy.ts b/website/cypress/e2e/auth/signin.cy.ts index e87d4b88..6d57d1f9 100644 --- a/website/cypress/e2e/auth/signin.cy.ts +++ b/website/cypress/e2e/auth/signin.cy.ts @@ -3,10 +3,8 @@ import { faker } from "@faker-js/faker"; describe("signin flow", () => { it("redirects to a confirmation page on submit of valid email address", () => { cy.visit("/auth/signin"); - cy.get('form[data-cy="signin-email"').within(() => { - cy.get(".chakra-input").type(`test@example.com`); - cy.get(".chakra-stack > .chakra-button").click(); - }); + cy.get('[data-cy="email-address"]').type(`test@example.com`); + cy.get('[data-cy="signin-email-button"]').click(); cy.url().should("contain", "/auth/verify"); }); it("emails a login link to the user when signing in with email", () => { diff --git a/website/src/pages/auth/signin.tsx b/website/src/pages/auth/signin.tsx index a1af2326..5bfeeb3b 100644 --- a/website/src/pages/auth/signin.tsx +++ b/website/src/pages/auth/signin.tsx @@ -41,10 +41,16 @@ export default function Signin({ csrfToken, providers }) { )} {email && ( -
+ - -