RSS Amplifier

Blog by Steve Frenzel · Apr 30, 2026

Quality assurance, accessibility and Astro: Part 1

0
Sign in to vote or save

Steve Frenzel · Steve Frenzel

Table of contents

Here’s the second part and the third part of this series. You can find the branch for this blog post on Codeberg.

Why I’m doing this

Let me take you on a journey! The topic of quality assurance in web development has become much more interesting to me lately, as I feel that the appreciation for the craft of a frontend developer has suffered greatly since the “AI” hype. Maaike Brinkhof has articulated this feeling (which I’ve had for quite some time) very well in her article Ignore the humanities at your own peril.

I wrote unit tests for a while, with a strong focus on accessibility, and got a glimpse of a QA engineer’s work on the side, but those were my only points of contact with the subject. Since then, though, I’ve found it fascinating and a lot of fun because it’s so close to my “normal” work, yet looks at it from a different angle.

Nevertheless, in all my jobs, I had the impression that the focus was almost always exclusively on automated tests, their integration into the pipeline, and test coverage. Some colleagues did manual testing themselves by clicking through Google Chrome, and that was it. Even without in-depth knowledge of QA, this approach seemed very superficial and full of holes to me, like Swiss cheese. It raised so many questions for me:

  • Why aren’t all four popular browsers (Chrome, Firefox, Safari and Edge) used for testing?
  • Why don’t they use various accessibility extensions or bookmarklets to find bugs?
  • Why doesn’t anyone use a screen reader to find bugs?
  • Why do they rely primarily on how a machine tests, rather than how a human uses the product?
  • Where does this fixation on a specific number for test coverage come from, instead of focusing on whether it actually works for as many people as possible?

Here, too, Maaike found the right words in her article What developers get wrong about testing:

The core of testing (and development!) is that it’s centred around humans, not the tools. The roots of what we do are centred in psychology, sociology, emotion. Software is made for humans, so why would it make sense to have as few humans as possible testing the application during development? That’s highly irresponsible!

Especially at a time when the tech industry is hyper-obsessed with “AI,” the human factor is increasingly taking a back seat. In her series 10 Years in Testing, Maaike demonstrated in Lesson 9 using a video just how important and unpredictable the human factor is (in this example, the focus is on processes).

I took this as an opportunity to learn more about the topic through a showcase project and to learn in public. My goal was to use a fake e-commerce store with existing end-to-end tests to demonstrate how I would approach the task from a QA perspective. For this, I’m going to use Playwright for end-to-end tests and Vitest for unit tests, as these seem to be the most popular choices and have great documentation.

The test subject

Screenshot of the homepage, showing the fake e-commerce store named TechMart. It shows a navigation with search bar on top, a hero section welcoming the user, a section with various filter, as well as some product cards arranged in a grid view.

During my research, I came across this tutorial from freeCodeCamp: Software Testing Course – Playwright, E2E, and AI Agents. It met all the requirements I was looking for:

  • The fake store can be run locally and is complex enough to help me learn the subject
  • There are already quite a few tests in place that cover important user flows (though I would implement some of them differently)
  • There are also some design choices in the code that I would handle differently, especially regarding accessibility

The project itself was created specifically for this video, so its architecture doesn’t reflect what you’d find in the real world. Feel free to check out the GitHub repository software-testing-course for yourself.

That’s why I decided to convert it into an Astro project, so I can structure the project using components and take advantage of various features from my favourite static site generator!

You can find my repository quality-assurance-showcase on Codeberg. I want to try to keep the number of commits to a minimum so that they correspond to the specific steps I took to ensure the project meets my quality standards. Let’s move on to the first step:

Turning it into an Astro project

Screenshot of the login screen, showing a centered card containing inputs for email and password, as well as a login button and the credentials.

What a massive task! I spent an entire day getting it to run smoothly locally so I could successfully test all the user flows. In this case, that means:

  • The search function displays the correct results
  • The filters for categories, maximum price, and sorting work as intended
  • Items can be added to the shopping cart and remain there until deleted
    • Additional items can be added or removed from the shopping cart, and an order summary is displayed
  • You can navigate to the login, registration, and checkout pages and perform the corresponding actions
    • If something goes wrong, a corresponding error message is displayed
  • You receive a message upon successful order placement

Making things work

Screenshot of the shopping card, containing three items and an order summary.

Most of the work involved successfully interacting with the various APIs, converting them to TypeScript, and ensuring that the information in the shopping cart and from user login is persistent. The following functions can now be found under /src/pages/api/:

  • health.ts (checks whether the API endpoints are “healthy” and can be accessed)
  • login.ts
  • logout.ts
  • products.ts
  • register.ts

The heart of this website is now located under /src/utils/app.ts, which contains the global state as well as fundamental functionality. To ensure everything works as expected here, I used export const prerender = false; to take advantage of Astro’s on-demand rendering. When starting the dev server, all of this must be available; otherwise, it would be unusable and untestable.

I’ve also placed the type definitions in /src/types/global.d.ts so they’re available everywhere. The product data is now located in /src/data/products.json to ensure a clear separation here as well, making it easier to maintain and debug.

Making things look right

Screenshot of the checkout screen showing a section for shipping information, payment information and order summary.

To reduce HTML boilerplate code, the individual pages are now wrapped in a layout that uses two CSS files: reset.css and global.css. The latter contains a lot of code, which I plan to break down into individual components in the next step.

Testing the tests

Screenshot of VS Code, showing an anxiety inducing amount of failed tests.

In this first step, I’m not focusing on automated testing yet. However, I want to make sure that Playwright is working; I’ll add Vitest later. I use VS Code and the official Playwright extension so I can test directly without much typing and get visual feedback.

The two biggest roadblocks were, first, that I had to point the Playwright configuration to the correct location of the tests, which is ./src/tests/, and second, that the local server on Astro isn’t port 3000, but 4321.

Out of the 76 tests, only 7 run successfully. That’s okay, because at this point I just want to know if Playwright itself works. Moving on!

Some nice-to-have’s

I started with a fresh, pre-configured Astro project, but I could just as easily have used my own Astro template, since there are certain things I simply must have when working with Astro:

  • A pre-commit hook that performs type checking, diagnostics, and a build before committing
  • Andy Bell’s more modern CSS reset: Can’t live without it!
  • Prettier configuration for code formatting
  • Absolute imports

Coming up

Phew, that was a lot of work! 🥵 Next, I’ll tidy things up and see which sections I can break down into separate components and how I can hopefully reduce the over 600 lines of code in global.css. Here’s the second part of this series.

Read the original on stevefrenzel.dev

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.