Conventions
General Guidelines
-
Use existing components from the Design System and refrain from writing any hardcoded styling, like colors/font size/etc.
-
Refrain from “bypassing” typescript by typing anything as
any. It might take a little more time but there’s usually a correct way to do what you want to do. Same goes for eslint rules - there’s a reason they exist.- If you have any ideas or modifications for prettier/eslint config, bring them up!
-
New features should be added with tests - that means unit tests for more complex logic, or integration tests for user flows.
- If there’s no time to do because of tight deadlines/other reasons, a linear ticket should be opened to write these tests with the labels “Frontend”, “Debt” and “Testing”.
-
If you made changes to existing components or added new ones, make sure to create stories for them in the storybook (or modify existing ones).
-
When adding new pages to the application, ensure they are correctly protected by our authentication module.
-
Each route’s
loaderandactionendpoints should be auth protected. That is done by doing the following:const headers = await requireValidSession(request); // ...logic return data({}, { headers }); -
If the route should be publicly available (such as the login route), do this instead:
await requireAnonymous(request); // ...logic -
For more information about the authentication module, see this document.
-
E2E Testing Guidelines
- E2E tests should be written in
.spec.tsfiles underservices/remix/tests/e2e. - Each feature (whether its a more abstract concept like “authentication” or a specific page like “dashboard”) should have its own
.spec.tsfile. - E2E tests should follow the “Page Model Design” pattern.
- Read this article to understand the upsides to this approach.
- Basic rule of thumb - each page in the application should have corresponding page model files to represent the page’s UI.
- If pages share common UI components/logic (like a data table), create a separate file for that component/logic and ensure the page model files extend it or create an instance of it.
- Create more classes as needed - for example, if this page contains a UI component that is relatively complex (like a table that has custom row actions, etc).
- Follow playwright’s best practices when writing tests. Some highlights:
- keeping tests isolated and independent
- using “strong”, user-facing attributes or the “data-testid” attribute to locate elements (instead of “weak” selectors like css classes)
- avoid tests that are too long or complex - this could complicate debugging and investigating bugs, and cause the tests to be flaky or run slowly.
- The tests you write should not only work in the CI environment, but also when running locally. If, for some reason, the test won’t work out of the box locally, make sure to add a comment to the test file explaining why and what’s needed to change when running it locally.
- After you write your tests and ensure they pass in your local environment, make sure to run them against a remote server (such as our ArgoCD dev environment) to reduce the chance of your deploy failing.
- In the future, we should have a triggerable pipeline that creates a new tenant under the dev environment and runs the tests itself, so we don’t have to do all this setup manually.