In this video· click a step to jump to it
Test recording
DevFeed — app walkthrough
160,015 ms · 818,225 pixels changed
We built this regression test for devfeed.tech — it's yours to keep, free.
Take this test with you
This is a real Playwright test, recorded against devfeed.tech. 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, 1400); await new Promise(r => setTimeout(r, 350)); await anim(max, 0, 800); })()";
await page.context().setExtraHTTPHeaders({ 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36' });
await page.route('**/cdn-cgi/scripts/**', function (r) { r.abort(); }).catch(function () {});
await page.route('**/sentry-cdn.com/**', function (r) { r.abort(); }).catch(function () {});
// ── Scenario 1: the public latest feed ────────────────────────────────────
stepLogger.log('Scenario 1: Latest feed');
await page.goto(baseUrl + '/latest', { waitUntil: 'domcontentloaded' });
await page.waitForLoadState('networkidle', { timeout: 5000 }).catch(function () {});Checks run
Notes from the demo run
AI-generatedWe signed into DevFeed with Google, picked four topics, and then drove the reader end to end: the latest feed, the personalised My feed, the tutorial and release filters, in-app search, an article page, the topics and sources directories, read-later, and both settings tabs including the topic picker filtered live. Eleven authenticated surfaces. For a reader app the thing that matters is how fast the feed becomes yours, and here that is four clicks from first login.
- Sign-in to personalised feed in one screenThe topic picker appears immediately after the Google handshake, needs three selections, and the feed rebuilds in place. No empty dashboard, no "come back tomorrow".
- Content types are first-class, not tagsArticles / News / Tutorials / Releases / Comparisons / Opinions are real routes (/tutorials, /releases) rather than query-string filters, so a reader can bookmark "just releases" and share it.
- The sources directory names its sourcesInfoQ, Phoronix, LWN, 37signals Dev, 1Password - listing the actual publications, with a Follow button each, tells a developer in five seconds whether the feed is worth their time.
- Google sign-in asks for a name it already hasAfter the Google consent screen, Zitadel's "Complete your data" step asks for first name, last name and email. Google had already supplied all three - first name and email were prefilled, only last name was blank, so the user is stopped for one field. Defaulting last name from Google's family_name (or making it optional) removes the only manual step in an otherwise one-click signup.
- The topic picker's search box is labelled twiceThe field is labelled "Find a topic" but its placeholder reads "Search topics". Harmless to a human, but it is the kind of mismatch that breaks anything driving the page by label.
3 visual changes
Share this run
Proof your app is not AI slop
This test was built for devfeed.tech — 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.








