aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/feed-live-test.js39
1 files changed, 37 insertions, 2 deletions
diff --git a/tools/feed-live-test.js b/tools/feed-live-test.js
index fd50191..afbbf10 100644
--- a/tools/feed-live-test.js
+++ b/tools/feed-live-test.js
@@ -30,7 +30,15 @@ const signed = (content, ago) => finalizeEvent(
const seeded = Array.from({ length: 25 }, (_, i) => signed('post number ' + (i + 1), 600 + i * 60));
const html = await buildHtml({ minify: true, pwa: false });
-const server = Bun.serve({ port: 5296, fetch: () => new Response(html, { headers: { 'content-type': 'text/html' } }) });
+// a picture that takes its time, so a post showing it must have waited
+const PNG = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==', 'base64');
+const server = Bun.serve({ port: 5296, fetch: async (req) => {
+ if (new URL(req.url).pathname === '/slow.png') {
+ await sleep(700);
+ return new Response(PNG, { headers: { 'content-type': 'image/png', 'cache-control': 'no-store' } });
+ }
+ return new Response(html, { headers: { 'content-type': 'text/html' } });
+} });
const browser = await puppeteer.launch({ executablePath: '/usr/bin/google-chrome', headless: 'new', args: ['--no-sandbox'] });
const page = await browser.newPage();
await page.evaluateOnNewDocument(() => {
@@ -111,7 +119,10 @@ try {
const fresh = signed('BRAND NEW POST', 0);
const delivered = await page.evaluate((ev) => window.__inject(ev), fresh);
check('...a post really arrives on a live subscription', delivered > 0, delivered + ' socket(s)');
- await sleep(900);
+ // A post waits at the door for its author's face and its pictures (or the
+ // two-second deadline, for a face nobody has) before it is even counted —
+ // so give it that long, and no longer.
+ await sleep(2600);
const after = await page.evaluate(() => ({
y: Math.round(window.scrollY),
pill: (document.querySelector('.feed-new-pill') || {}).textContent || '',
@@ -145,6 +156,30 @@ try {
await page.evaluate(() => /ANOTHER ONE/.test(document.querySelector('.notes-feed')?.innerText || '')
&& !document.querySelector('.feed-new-pill')));
+ console.log('\n[a post arrives whole]');
+ // A row used to paint first and fill in its picture after. Watch the feed
+ // from the instant the post is injected: the first time the row exists,
+ // its image must already be decoded.
+ await page.evaluate(() => {
+ window.__firstSight = null;
+ const feed = document.querySelector('.notes-feed');
+ const look = () => {
+ if (window.__firstSight) return;
+ const row = [...feed.querySelectorAll('.row')].find((n) => /PICTURE POST/.test(n.innerText || ''));
+ if (!row) return;
+ const img = row.querySelector('img.note-img');
+ window.__firstSight = { img: !!img, ready: !!(img && img.complete && img.naturalWidth > 0), at: performance.now() };
+ };
+ new MutationObserver(look).observe(feed, { childList: true, subtree: true });
+ });
+ const t0 = await page.evaluate(() => performance.now());
+ await page.evaluate((ev) => window.__inject(ev), signed('PICTURE POST http://localhost:5296/slow.png?' + Date.now(), 0));
+ await sleep(3000);
+ const sight = await page.evaluate(() => window.__firstSight);
+ check('the post is in the feed', !!sight && sight.img, JSON.stringify(sight));
+ check('...and its picture was already decoded the first time the row existed', !!sight && sight.ready);
+ check('...having waited for the slow host', !!sight && sight.at - t0 >= 700, sight ? Math.round(sight.at - t0) + 'ms' : '');
+
console.log('\n[coming back after being away]');
// the throttle would otherwise swallow a refresh this soon after the last
// the app was hidden for a while, then focused again