Recording of the visual regression run on rankbuddy.io · RankBuddy — app walkthrough.

In this video· click a step to jump to it

R
Passed ✓

Test recording

RankBuddy — app walkthrough

113,045 ms · 355,107 pixels changed

We built this regression test for rankbuddy.io — it's yours to keep, free.

Take this test with you

This is a real Playwright test, recorded against rankbuddy.io. 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 UA = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36';
  const SEEDED_CHAT = '/chat/690f461c-644d-4ddd-b71e-a36271ef9545';
  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, 1200); await new Promise(r => setTimeout(r, 300)); await anim(max, 0, 700); })()";
  const SCROLL_THREAD = "(async () => { const ease = t => 1 - Math.pow(1 - t, 3); const sc = [...document.querySelectorAll('*')].filter(e => e.scrollHeight > e.clientHeight + 120 && e.clientHeight > 200).sort((a,b) => b.scrollHeight - a.scrollHeight)[0]; if (!sc) return; const max = sc.scrollHeight - sc.clientHeight; const anim = (a, b, ms) => new Promise(res => { const t0 = performance.now(); const step = now => { const p = Math.min(1, (now - t0) / ms); sc.scrollTop = a + (b - a) * ease(p); p < 1 ? requestAnimationFrame(step) : res(); }; requestAnimationFrame(step); }); await anim(0, max, 1800); await new Promise(r => setTimeout(r, 400)); })()";

  await page.context().setExtraHTTPHeaders({ 'User-Agent': UA });
  for (const pattern of ['**/cdn-cgi/scripts/**/email-decode.min.js', '**/sentry-cdn.com/**', '**/*posthog*/**', '**/datafa.st/**', '**/www.googletagmanager.com/**', '**/connect.facebook.net/**']) {
    await page.route(pattern, function (r) { r.abort(); }).catch(function () {});
  }
+91 more lines — claim the test to get the full code.

Checks run

Run
✓
Visual
100.00%
Text
—
DOM
✓
Network
+2700 −48
Console
✓
A11y
A
Perf
276 drift
URL
192 diverged
Variables
—
Full report
Log in →
355,107
Diff px
1m 53s
Duration
A
Accessible
WCAG 2.2 · 93
A
Fast
Web Vitals · 100

Notes from the demo run

AI-generated

We signed up, pointed RankBuddy at lastest.cloud, and let it work. It read 214 pages from the sitemap, rendered the homepage as Google would show it, named five real competitors unprompted (chromatic.com, applitools.com, percy.io, argos-ci.com, reflect.run), then in a later question produced a keyword-gap analysis with a stated 93.7% informational split and a four-item priority order. It also filed an unasked technical audit on its own and flagged a noindex tag on a live route. The 'employee' framing is not a skin — the agent shows the tools it ran and what each returned, which is the part that makes the answers trustable.

Highlights
  • It shows its work
    Every answer is preceded by labelled tool runs — 'Ranked keywords read: 14 keywords', 'Top pages read: 5 pages' — so you can see the evidence the conclusion rests on rather than taking prose on faith.
  • It says when it does not know
    With Search Console unconnected it said so plainly, explained exactly what that costs the analysis, then pivoted to what it could independently verify. That honesty is rarer than good output.
  • Competitor discovery with no input from us
    We gave it a bare domain and it came back with the correct five competitors in our category. That single moment does more selling than the pricing page.
  • Proactive work between sessions
    A 'FROM YOUR EMPLOYEE' item appeared in the sidebar — a technical audit we never asked for, ending with 'I check this site every day going forward'. That is the product's actual differentiator and it is buried in a sidebar list.
Friction points
  • The whole onboarding is lost if it is interrupted
    'Your progress is saved on this device — to finish later, come back with the same browser.' The analysis, the competitor set and the profile answers are device-local until the run finishes, so a user who switches machines mid-onboarding starts over.
  • The primary CTAs need a forced click to register
    'Analyze my site' and the onboarding buttons did not respond to a normal click until we forced past the actionability check — the entrance animation appears to keep them from settling. Real users on slower machines may see the same double-click behaviour on the most important button in the funnel.
Couldn't reach
  • Connect Google Search Console·Would grant a third party OAuth access to the founder's Search Console; never done on their behalf

9 visual changes

Step 432,203 px changed
Before
Before
After
After
Diff
Diff
Step 532,247 px changed
Before
Before
After
After
Diff
Diff
Step 632,184 px changed
Before
Before
After
After
Diff
Diff
Step 731,895 px changed
Before
Before
After
After
Diff
Diff
Step 836,226 px changed
Before
Before
After
After
Diff
Diff
Step 936,226 px changed
Before
Before
After
After
Diff
Diff
Step 1047,381 px changed
Before
Before
After
After
Diff
Diff
Step 1130,297 px changed
Before
Before
After
After
Diff
Diff
Step 1276,448 px changed
Before
Before
After
After
Diff
Diff

Share this run

Earned · Lastest awards

Proof your app is not AI slop

LASTEST
starter
regressions
0
Badges stay live, ratchet upward, only downgrade on confirmed regression.
57,275 test runs recorded · 1,164 products tested with Lastest

This test was built for rankbuddy.io — 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.