Front-End Quality
All examples can be found in this repo here
What are we talking about?
Here, by “quality”, I mean proper functionality and maintainability of the deliverable.
- Enforcing a specific format in your CSS.
- Refactoring CSS while being absolutely sure the interface of another page or a different state of the same page hasn’t changed.
- Ensuring a use case still works after three years of development.
- Testing the accessibility of your interfaces.
Stylelint
With Stylelint, you can enforce how your CSS should be written. For example, you can forbid the use of px or enforce the rgb notation for colors.
Linting result from the CSS in the example repo:
> npx stylelint "**/*.css"
src/style.css
6:10 ✖ Expected "rgba" to be "rgb" color-function-alias-notation
6:10 ✖ Expected modern color-function notation color-function-notation
6:30 ✖ Expected "0.87" to be "87%" alpha-value-notation
9:3 ✖ Unexpected empty line before declaration declaration-empty-line-before
10:19 ✖ Expected "optimizeLegibility" to be "optimizelegibility" value-keyword-case
20:1 ✖ Expected empty line before rule rule-empty-line-before
50:1 ✖ Expected empty line before rule rule-empty-line-before
53:1 ✖ Expected empty line before rule rule-empty-line-before
76:1 ✖ Expected empty line before rule rule-empty-line-before
79:1 ✖ Expected empty line before rule rule-empty-line-before
87:23 ✖ Expected "#ffffff" to be "#fff" color-hex-length
89:3 ✖ Expected empty line before rule rule-empty-line-before
92:3 ✖ Expected empty line before rule
Playwright
Playwright lets you write “end-to-end” tests, allowing you to test a use case by simulating user actions on your site.
Example of a test that simulates a click and checks the page content:
test('should be 1', async ({page}) => {
await page.goto('/');
await page.getByRole('button', {name: 'ADD'}).click();
await expect(page.locator('#counter')).toContainText('count is 1');
});
You can also create simple UI tests using snapshots. On the first run, Playwright will save a PNG for each defined project in the config, then use those snapshots for subsequent runs of the test.
This test ensures the UI remains unchanged:
test('style test', async ({page}) => {
await page.goto('/');
await expect(page).toHaveScreenshot({maxDiffPixels: 0});
});
You can also use the axe library to write accessibility tests.
test('should not have any automatically detectable accessibility issues', async ({ page }) => {
await page.goto('/');
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
expect(accessibilityScanResults.violations).toEqual([]);
});