Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

website: Add some new detail to the docs on e2e testing #271

Merged
merged 1 commit into from
Jan 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
49 changes: 44 additions & 5 deletions website/cypress/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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");
});
});
Expand All @@ -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
<Input data-cy="email-address" placeholder="Email Address" />
```

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.
6 changes: 2 additions & 4 deletions website/cypress/e2e/auth/signin.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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", () => {
Expand Down
12 changes: 9 additions & 3 deletions website/src/pages/auth/signin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,16 @@ export default function Signin({ csrfToken, providers }) {
</form>
)}
{email && (
<form data-cy="signin-email" onSubmit={signinWithEmail}>
<form onSubmit={signinWithEmail}>
<Stack>
<Input variant="outline" size="lg" placeholder="Email Address" ref={emailEl} />
<Button size={"lg"} leftIcon={<FaEnvelope />} colorScheme="gray" type="submit">
<Input data-cy="email-address" variant="outline" size="lg" placeholder="Email Address" ref={emailEl} />
<Button
data-cy="signin-email-button"
size={"lg"}
leftIcon={<FaEnvelope />}
colorScheme="gray"
type="submit"
>
Continue with Email
</Button>
</Stack>
Expand Down