Recording of the visual regression run on www.cardvender.com · Cardvender — vending machine finder walkthrough.

In this video· click a step to jump to it

W
Passed

Test recording

Cardvender — vending machine finder walkthrough

139,394 ms · 178,954 pixels changed

We built this regression test for www.cardvender.com — it's yours to keep, free.

Take this test with you

This is a real Playwright test, recorded against www.cardvender.com. Claim it into your own workspace and re-run it on every deploy — free.

export async function test(page, baseUrl, screenshotPath, stepLogger) {
  const shot = (n, slug) => screenshotPath.replace('.png', `-${n}-${slug}.png`);
  const SCROLL_THROUGH = "(async () => { const ease = t => 1 - Math.pow(1 - t, 3); const max = Math.max(0, document.body.scrollHeight - window.innerHeight); if (max < 40) return; const anim = (a, b, ms) => new Promise(res => { const t0 = performance.now(); const step = now => { const p = Math.min(1, (now - t0) / ms); window.scrollTo(0, a + (b - a) * ease(p)); p < 1 ? requestAnimationFrame(step) : res(); }; requestAnimationFrame(step); }); await anim(0, max, 1100); await new Promise(r => setTimeout(r, 250)); await anim(max, 0, 650); })()";

  await page.route(/googletagmanager|google-analytics|posthog|hotjar|clarity\.ms|segment\.io/, function (r) { r.abort().catch(function () {}); });

  stepLogger.log('Scenario 1: Cardvender home, signed in');
  await page.goto(baseUrl + '/', { waitUntil: 'domcontentloaded' });
  await page.waitForTimeout(3500);
  await page.evaluate(SCROLL_THROUGH).catch(function () {});
  await page.waitForTimeout(500);
  await page.screenshot({ path: shot(1, 'home-signed-in'), fullPage: true });
+77 more lines claim the test to get the full code.

Checks run

Run
Visual
9.98%
Text
DOM
Network
+72 −72
Console
A11y
A
Perf
648 over
URL
144 diverged
Variables
Full report
Log in →
178,954
Diff px
2m 19s
Duration
A
Accessible
WCAG 2.2 · 97
Review
Fast
Web Vitals

Notes from the demo run

AI-generated

We signed into Cardvender with your email magic link and drove eleven authenticated surfaces: ZIP search across two metros, two machine detail pages, a community sighting, the spotted-report form filled with a real location, list-a-machine, the route course and the blog. The search is the product and it delivers: ZIP 45211 returned five listed partners on a live map with distances, addresses, stocked brands and price bands, plus community sightings underneath.

Highlights
  • Search answers the actual question
    One ZIP gives a map, five partners sorted by distance (0.8 mi, 1.6 mi, 3.6 mi), the exact address, what each machine stocks (Pokemon, One Piece, Baseball, Hockey) and a $5 to $400 price band. That is everything someone needs to decide whether to drive there.
  • Listed partners and community sightings stay visually separate
    Gold pins for verified partners, gray for sightings, with LISTED PARTNER and COMMUNITY SIGHTING, NOT A VERIFIED PARTNER labels carried onto the detail pages. Trust boundaries are drawn clearly instead of blending user submissions into your own data.
  • Search is free, the account is genuinely optional
    Your sign-in page says it plainly: search stays free, an account is only for favorites, drop alerts, listings or the course. Then the product honours it. The favorite stars only appear once signed in, which is a clean reason to sign up rather than a wall.
  • Sighting reports do not require ownership
    The spotted form asks for a photo, venue, ZIP and notes from anyone who walked past a machine. That is how the map gets dense in cities where you have no operator relationships yet.
Friction points
  • Google sign-in fails with OAuthCreateAccount
    Continue with Google bounced us back to /auth/signin?error=OAuthCreateAccount on a first-time account. The magic link then worked with the same address, so the account creation path itself is fine and it looks like the NextAuth adapter is rejecting the OAuth account link. Google is the first and most prominent button on the page, so anyone who tries it first sees a raw error code and no explanation.
  • Turnstile sits on the sighting form
    The spotted form carries a Cloudflare Turnstile widget. Understandable for a public submission form, but combined with a photo upload it is a lot of friction for a drive-by contribution, and it is the one contribution flow you most want to be frictionless.

3 visual changes

Step 152,622 px changed
Before
Before
After
After
Diff
Diff
Step 94,736 px changed
Before
Before
After
After
Diff
Diff
Step 11121,596 px changed
Before
Before
After
After
Diff
Diff

Share this run

Earned · Lastest awards

Proof your app is not AI slop

LASTEST
starter
tests
all passing
regressions
0
Badges stay live, ratchet upward, only downgrade on confirmed regression.
56,846 test runs recorded · 1,040 products tested with Lastest

This test was built for www.cardvender.com — claim it free

One click copies the test and baseline screenshots into your own Lastest workspace. Re-run on every deploy and catch regressions before your users do — free, no card required.