QuoteWell
More workProduct
Front end
QA
A website and the lead system behind it, sold as one product to contractors who lose work in the gap between a call coming in and somebody answering it.
- Role
- Owned product. Positioning, identity, copy, interface, build and tests.
- Status
- Live at quotewell.net, 2026.
- Stack
- Next.js, TypeScript, Tailwind, Cal.com, Playwright
The homepage as shipped. Point at it or press Scroll the site.
Positioning
Most agencies fix the shopfront and leave the leak.
A website alone does nothing about the gap between a call coming in and somebody answering it. QuoteWell sells both halves as one thing: the site, and the response system wired to it.
The writing is plain on purpose. Contractors are sold to badly and constantly, so every page answers one question and ends in the same two actions: book the audit, or see the work.
Proof
No invented metrics, no borrowed testimonials.
No booked-job outcomes are claimed anywhere. The work section ships two complete reference builds instead, a roofing company and a grounds-care company, each labelled as a demonstration, not a client.
- Livequotewell.net
- Reference buildRoofing
- Reference buildGrounds care
QA
The tests break the lead form on purpose.
A lost lead is the failure that costs money, so that is what gets attacked. One test found a real bug, and the test itself had only ever passed by luck.
- Fail
The form endpoint is forced to return a 500. The test looks for the error message by role, and stops.
strict mode violation: getByRole("alert") resolved to 2 elements - Trace
Two live regions, not one: the form’s own error, and the route announcer Next.js injects into every page.
1 form error role="alert" 2 route announcer role="alert" - Fix
Scope the locator to the form, so the assertion can only see the element the form controls.
form.getByRole("alert") - Verify
Both failure-path tests pass, and fail again when the error state is broken on purpose.
✓ 500 keeps the input, offers retry ✓ network drop never loses the lead 28 cases · axe in the same run
Reconstructed from commit 0dee430 and tests/smoke.spec.ts. The guarantee under test: if the form endpoint fails, the visitor keeps what they typed and is offered a retry.
test("contact form: a server failure keeps the user's input and offers a retry", async ({ page }) => {
await page.route("**/formspree.io/**", (route) =>
route.fulfill({ status: 500, body: "boom" }),
);
await page.goto("/contact/");
await page.fill("#c-name", "Test Person");
await page.fill("#c-email", "test@example.com");
await page.fill("#c-message", "This submission is going to fail.");
await page.getByRole("button", { name: /send message/i }).click();
A second defect was in the copy: the site claimed “0.00 layout shift”. Measured on a throttled mobile profile it was 0.022, so the claim came down and a number that held on every run replaced it.
Current state
Live at quotewell.net. A static export with no client database, booking through Cal.com, essential cookies only. 43 Playwright cases run with axe.