Ga naar hoofdinhoud

End to End testing guide

We use Playwright for end-to-end testing. It is installed in the playwright directory.

Getting started

Running Playwright can be done in two ways:

  • Locally: By starting the backend and client as how we always do it and running yarn install; yarn playwright test in playwright directory.
  • Docker: docker compose -f docker-compose-buildkite.yml run --rm playwright bin/playwright

FactoryBot

Is a Ruby gem which we use to easily generate data in the database for our backend specs. We added logic to make it possible to use that same logic for end-to-end testing with a create function. The result of this function are the attributes that we expose from the factory's model. It is possible expose more than only those attributes. The factories are defined at backend/spec/factories/.

Note: The sequence count in the backend is reset after any change in the backend. Down the backend and database container with its volumes to resolve weird "factory has not been created" issues, after you've changed something in the backend and already ran the end-to-end tests once.

Take for example the department factory:

FactoryBot.define do
factory :department do
company
sequence(:name) { |n| "Department-#{n}" }
end
end

In order to create a department with a new company we can run the following:

await create('department');
// { "name": "Department-0" }

In order to create a department with a custom name we can run the following:

await create('department', { attributes: { name: "Foo" } });
// { "name": "Foo" }

In order to create a department for an existing company, we can run the following:

const company = await create('company', { as_json: { methods: ['to_global_id'] } });
// { "id": "gid://ozone/Company/1", ... }

await create('department', { attributes: { company_id: company.to_global_id } });
// { "name": "Department-0" }

In order to create a department with a new company and return the id of the company, we can run the following:

await create('department', { as_json: { include: { company: {} } } });
// { "name": "Department-0", "company": { "name": "Company-0", ... } }

In order to create an expired participation (expired is a trait, which we defined at its factory) run:

await create('participation', { traits: ['expired'] });

Helpful links

To learn more about Playwright and the concepts that we use, please read the following links:

  • List of most common command line commands,
  • After reading the command line commands, you can get started by setting up VS Code for a better developer experience,
  • We use fixtures to establish environment for each test. These are defined and configured in playwright/test.ts.
    • Take a look at the built-in fixtures.
    • By default, Playwright runs in parallel with "workers". Without any configuration, a fixture is executed for every spec where it is defined. To prevent repetitive compute cost we can configure that some fixtures are executed once and per worker and reused for that worker. For this we use worker-scoped fixtures.
  • We use Page Object Models to structure our test suite. A POM represents one page with potentially some sub pages/overlays. These are defined in playwright/pages,
  • Try to use data-testid='foo.bar' as much as possible,
  • Follow the test generator guide to get more familiar with creating end-to-end specs.

Visit https://playwright.dev/docs/intro for more information. ✨

Happy hacking! 🎭