diff options
| author | Adam Soltys <[email protected]> | 2026-10-07 08:34:45 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-07 08:34:45 -0700 |
| commit | 8dfc629d129c6c1a8a3ed38a935e659eee9f67c7 (patch) | |
| tree | e85c955e7014e1cf4b22166077d41e3d5c2bc4bd /tools/feed-live-test.js | |
| parent | 1d6786265f4d86b2260b30060df473a51774fb72 (diff) | |
| download | coinosv3-8dfc629d129c6c1a8a3ed38a935e659eee9f67c7.tar.gz coinosv3-8dfc629d129c6c1a8a3ed38a935e659eee9f67c7.zip | |
Feed tests: open the Feed from the bottom nav, on Following
The feed left the chat home for a bottom-nav tab, and a wallet with no
feed remembered opens on Popular, so these tests click the Feed tab and
seed Following as the wallet's last feed. Also brought up to date:
- feed-live: the pill lands on the oldest new post; arrivals at the top go
in above the first post (held still), not behind the pill; scroll up a
screen at a time (one jump lands before the windowed rows are back)
- feed-custom: only the feeds' chips are counted (not All/Images/…); the
follows box is not the first checkbox any more; the last feed is
remembered across a reload; the pack shows in the feed's editor (the chat
home no longer lists the feed)
- feed-follow: Feed tab + Following chip instead of the messages-home row;
the feed opens at ten posts (tall ones, so a page doesn't fill the screen)
- moderation: nos.lol is a local stand-in (a relay that won't connect held
the mute list back past the checks)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'tools/feed-live-test.js')
| -rw-r--r-- | tools/feed-live-test.js | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/tools/feed-live-test.js b/tools/feed-live-test.js index 9f98fde..8f80d46 100644 --- a/tools/feed-live-test.js +++ b/tools/feed-live-test.js @@ -105,12 +105,12 @@ try { localStorage.setItem(k + ':follows', JSON.stringify({ tags: [['p', pk]], c: '', at: Math.floor(Date.now() / 1000) })); localStorage.setItem(k + ':feedNotes', JSON.stringify(ns)); localStorage.setItem(k + ':profiles', JSON.stringify({ [pk]: { name: 'Test Author', t: Date.now() } })); + localStorage.setItem('btc-wallet-feed:' + k, 'following'); // a new wallet would open on Popular }, [base, AUTHOR, seeded]); await page.reload({ waitUntil: 'domcontentloaded' }); await waitText('receive', 20000); - await page.evaluate(() => { const b = [...document.querySelectorAll('button')].find((e) => /message/i.test(e.getAttribute('aria-label') || '')); if (b) b.click(); }); - await sleep(1000); - await page.evaluate(() => { const e = [...document.querySelectorAll('.item')].find((n) => /feed/i.test(n.textContent)); if (e) e.click(); }); + // the Feed is a tab in the bottom nav (it was a row on the chat home) + await page.evaluate(() => [...document.querySelectorAll('.app-nav-button')].find((b) => b.getAttribute('aria-label') === 'Feed')?.click()); await sleep(4000); check('the feed has posts in it', (await page.evaluate(() => document.querySelectorAll('.notes-feed > .row').length)) > 0); @@ -144,8 +144,12 @@ try { await page.evaluate(() => document.querySelector('.feed-new-pill').click()); await sleep(600); - const opened = await page.evaluate(() => ({ y: Math.round(window.scrollY), pill: !!document.querySelector('.feed-new-pill') })); - check('tapping it takes you up to the post', opened.y < 120, 'scrollY ' + opened.y); + // the pill lands on the (oldest) new post, at the top of the screen + const opened = await page.evaluate(() => { + const r = [...document.querySelectorAll('.notes-feed > .row')].find((n) => /BRAND NEW POST/.test(n.innerText)); + return { top: r ? Math.round(r.getBoundingClientRect().top) : null, pill: !!document.querySelector('.feed-new-pill') }; + }); + check('tapping it takes you up to the post', opened.top !== null && opened.top >= 0 && opened.top < 120, 'post top ' + opened.top); check('...and the pill is done', !opened.pill); console.log('\n[scrolling back up on your own]'); @@ -238,6 +242,12 @@ try { const r = [...document.querySelectorAll('.notes-feed > .row')].find((n) => eval(label)(n) === text); return r ? { text, top: Math.round(r.getBoundingClientRect().top), y: Math.round(window.scrollY) } : null; }, label.toString(), text); + // up to the top the way a reader goes, a screen at a time (one jump from + // far down lands before the rows up there are mounted again) + const scrollUp = async () => { + while (await page.evaluate(() => { scrollBy(0, -Math.min(scrollY, innerHeight)); return scrollY > 0; })) await sleep(80); + await sleep(600); + }; const topRow = () => page.evaluate(() => (document.querySelector('.notes-feed > .row') || {}).innerText || ''); console.log('\n[coming back after being away, a few new posts]'); @@ -260,23 +270,20 @@ try { await page.evaluate(() => window.scrollTo(0, document.documentElement.scrollHeight)); await sleep(600); check('...older posts that merely missed the cache went in quietly too', /not in the cache/.test(await feedText())); - await page.evaluate(() => window.scrollTo(0, 0)); - await sleep(600); + await scrollUp(); check('...scrolling up reaches the newest post, and clears the pill', /CATCH-UP 1/.test(await topRow()) && !(await page.$('.feed-new-pill')), (await topRow()).slice(0, 40)); console.log('\n[coming back while sitting at the top]'); const wasTop = await anchor(); await away(() => [signed('AT-THE-TOP A', 0), signed('AT-THE-TOP B', 1)]); const a2 = await rowAt(wasTop.text); - check('the header and first post stay in place', !!wasTop && !!a2 && a2.text === wasTop.text && Math.abs(a2.top - wasTop.top) <= 2 && a2.y === wasTop.y, + // new posts go in above the first post, which is held where it was (the + // page grows upward, scrolled by what went in above it) + check('the first post stays in place', !!wasTop && !!a2 && a2.text === wasTop.text && Math.abs(a2.top - wasTop.top) <= 2, JSON.stringify({ was: wasTop, now: a2 })); - check('...new posts wait while the header is visible', !/AT-THE-TOP A/.test(await topRow())); - await page.evaluate(() => { - const first = document.querySelector('.notes-feed > .row'); - scrollBy(0, Math.ceil(first.getBoundingClientRect().top)); - }); - await sleep(600); - check('...then arrive offscreen above it, with a notice', /AT-THE-TOP A/.test(await topRow()) && /2 new posts/i.test(await page.evaluate(() => document.querySelector('.feed-new-pill')?.textContent || ''))); + const atTop = await rowAt('AT-THE-TOP A'); + check('...the new posts went in above it', /AT-THE-TOP A/.test(await topRow()) && !!atTop && !!a2 && atTop.top < a2.top, JSON.stringify(atTop)); + check('...with a notice', /2 new posts/i.test(await page.evaluate(() => document.querySelector('.feed-new-pill')?.textContent || ''))); console.log('\n[coming back after a long time away]'); await page.evaluate(() => window.scrollTo(0, 900)); |
