← All posts

How we work

What we check before a website goes live

Every build runs the same checks before it ships. Here is the actual list, why each one exists, and the bugs each has caught on real projects.

Most website bugs are not found by looking. They are found by measuring, because the ones that matter are invisible until somebody complains.

This is the list every build of ours goes through before it ships. Nothing here is theoretical: each check is on the list because it caught something real.

Every page, at every width, with the console open

The check runs each page at five viewport widths and records three things: any JavaScript error, any horizontal overflow, and any link that points at nothing.

Sixty combinations for a twelve-page site. It sounds excessive until you remember that most people will only ever see your site at one width, on one device, and if it is broken at that width they simply leave.

Horizontal overflow is the one worth explaining. If a single element is a few pixels too wide, the whole page scrolls sideways on a phone. Everyone has used a site like that. Almost nobody who owns one knows.

Contrast, measured rather than eyeballed

Text against its background, as a ratio. The accessibility standard asks for 4.5:1 for body text.

The trap is that this has to be measured as rendered, not from the design file. Semi-transparent overlays, one colour sitting on another, a theme switching underneath — all of these change the real ratio. We have written checks that got this wrong and reported perfectly legible text as a failure, because they ignored alpha.

Measure the composite. Both themes. Every time.

The thing the page says it does

Passing a build does not mean the feature works, and this is where most checklists stop being useful.

An example from our own client portal. It sent an invoice by email and showed "Sent". The test asserted the word "Sent" appeared. Both were green. Nothing had been delivered, because the code called PHP's mail() and threw the answer away.

The check we should have written, and now do, is: did the thing the user was promised actually happen? Not "did the page say it happened".

So the invoice test now sends to a real mail server we run for the test, and checks the message arrived — with the right recipient, the right subject, and the attached PDF decoding byte-for-byte back to the file we generated.

That distinction is most of the value in testing. A test that checks the interface agrees with itself will pass forever while the product is broken.

Permissions, from the outside

Every private page is requested while signed out, and while signed in as somebody else, and has to refuse both.

This caught a genuine embarrassment during development. A test appeared to show a signed-out visitor could download another client's invoice. It turned out the test was wrong — pages in one browser session share cookies, so the "signed out" check was still carrying a staff session.

There was no hole. But it took a day to prove that, and the lesson stuck: when a security test fails, suspect the test first, then the code, and do not relax until you know which.

Performance, as numbers

Page weight, largest element load time, layout shift.

Layout shift is the underrated one. If your page moves after it loads — an image without dimensions pushing text down, a font swapping in — people misclick and Google marks you down. It costs one attribute per image to prevent and is invisible on a fast connection, which is why it survives so long.

What this actually buys you

Not perfection. Things still get through.

What it buys is that the same thing does not get through twice. Every bug found after launch becomes a check, so it cannot come back quietly. Our own portal is at 337 checks now, and every one of them exists because something went wrong once.

That is the honest version of quality assurance. Not "we are careful" — anyone can say that — but a list that gets longer every time we are wrong, and runs before anything reaches you.