From 9a49107afe8cf7104ea7da1638e680518fa55bb8 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Wed, 7 Oct 2026 08:10:17 -0700 Subject: Profile tests: reach the feed and chats through the bottom nav, start on Following, follow today's onboarding - avatar-profile, profile-open: a new wallet opens the feed on Popular, so seed this wallet's last feed as Following; profile-open opens Feed from the nav - profile-feed: a mainnet import offers a username first (Not now), Messages is a bottom-nav button - profile-draft, profile-recovery: the import button reads 'Have an existing seed or entropy to import?'; profile batches stream through queryStreamOn, so the recovery test answers that too Co-Authored-By: Claude Opus 5.5 --- tools/avatar-profile-test.js | 1 + tools/profile-draft-test.js | 2 +- tools/profile-feed-test.js | 8 ++++---- tools/profile-open-test.js | 6 +++--- tools/profile-recovery-test.js | 4 +++- 5 files changed, 12 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/avatar-profile-test.js b/tools/avatar-profile-test.js index 293d7c1..4ed1b25 100644 --- a/tools/avatar-profile-test.js +++ b/tools/avatar-profile-test.js @@ -39,6 +39,7 @@ try { })); localStorage.setItem(k + ':follows', JSON.stringify({ tags: [['p', a], ['p', b]], c: '', at: now })); localStorage.setItem(k + ':feedNotes', JSON.stringify(ns)); + localStorage.setItem('btc-wallet-feed:' + k, 'following'); // this wallet's last feed (new ones open on Popular) localStorage.setItem(k + ':profiles', JSON.stringify({ [a]: { name: 'Alice Poster', t: Date.now() }, [b]: { name: 'Bob Poster', about: 'bob bio here', t: Date.now() } })); }, [base, A, B]); await page.reload({ waitUntil: 'domcontentloaded' }); diff --git a/tools/profile-draft-test.js b/tools/profile-draft-test.js index 9062726..437dd61 100644 --- a/tools/profile-draft-test.js +++ b/tools/profile-draft-test.js @@ -42,7 +42,7 @@ try { await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest')); await page.reload({ waitUntil: 'domcontentloaded' }); await click('Create a new wallet'); - await click('Have an existing seed'); + await click('Have an existing seed or entropy to import?'); await page.waitForSelector('textarea'); const mnemonic = generateMnemonic(wordlist); await page.type('textarea', mnemonic); diff --git a/tools/profile-feed-test.js b/tools/profile-feed-test.js index 9c743ae..266e3f8 100644 --- a/tools/profile-feed-test.js +++ b/tools/profile-feed-test.js @@ -32,12 +32,12 @@ try { await page.waitForSelector('textarea'); await page.type('textarea', generateMnemonic(wordlist)); await click('button', 'Open wallet'); + // a mainnet wallet offers a username first (the spending-account step) + if (await waitText('claim a username', 8000)) await click('button', 'Not now'); check('wallet opens', await waitText('receive', 20000)); - // .header-msgs is the shared header-button class — settings, lock and - // search wear it too, and the first one is no longer this. Ask for the - // messages button by name. - await page.evaluate(() => [...document.querySelectorAll('button')] + // Messages is a button in the bottom nav; ask for it by name. + await page.evaluate(() => [...document.querySelectorAll('.app-nav-button')] .find((b) => /message/i.test(b.getAttribute('aria-label') || ''))?.click()); await sleep(800); check('chat home opens', await waitText('coinos', 10000)); diff --git a/tools/profile-open-test.js b/tools/profile-open-test.js index e2fcb3a..aa0c943 100644 --- a/tools/profile-open-test.js +++ b/tools/profile-open-test.js @@ -73,12 +73,12 @@ try { await page.evaluate(([k, pks, ns]) => { localStorage.setItem(k + ':follows', JSON.stringify({ tags: pks.map((p) => ['p', p]), c: '', at: Math.floor(Date.now() / 1000) })); localStorage.setItem(k + ':feedNotes', JSON.stringify(ns)); + localStorage.setItem('btc-wallet-feed:' + k, 'following'); // this wallet's last feed (new ones open on Popular) }, [base, authors, notes.map((e) => ({ id: e.id, pubkey: e.pubkey, kind: 1, created_at: e.created_at, content: e.content.slice(0, 200), tags: [] }))]); 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 button in the bottom nav + await page.evaluate(() => { const b = [...document.querySelectorAll('.app-nav-button')].find((e) => /^feed$/i.test(e.getAttribute('aria-label') || '')); if (b) b.click(); }); // let the feed settle completely — this test is about what happens AFTER await sleep(12000); diff --git a/tools/profile-recovery-test.js b/tools/profile-recovery-test.js index b2c871a..2f6ae90 100644 --- a/tools/profile-recovery-test.js +++ b/tools/profile-recovery-test.js @@ -46,7 +46,9 @@ const bundle = await Bun.build({ entrypoints: ['profile-test-entry'], target: 'b build.onLoad({ filter: /src\/features\/messages\.js$/ }, async ({ path }) => ({ contents: (await Bun.file(path).text()) .replace("id: 'messages',", "id: 'messages', testFetch: fetchFullProfile, testView: profileScreen, testApply: applyProfile, testLight: (pk) => profiles.get(pk), testFull: (pk) => fullProfiles.get(pk),"), loader: 'js' })); build.onLoad({ filter: /src\/nostr\.js$/ }, async ({ path }) => ({ contents: (await Bun.file(path).text()) - .replace('export async function queryOn(relays, filter, maxWait = 1500) {', 'export async function queryOn(relays, filter, maxWait = 1500) { if (globalThis.__profileQuery) return globalThis.__profileQuery(relays, filter);'), loader: 'js' })); + .replace('export async function queryOn(relays, filter, maxWait = 1500) {', 'export async function queryOn(relays, filter, maxWait = 1500) { if (globalThis.__profileQuery) return globalThis.__profileQuery(relays, filter);') + // profile batches stream each answer as it lands (our relays and the indexes at once) + .replace('export async function queryStreamOn(relays, filter, onEvent, maxWait = 1500) {', 'export async function queryStreamOn(relays, filter, onEvent, maxWait = 1500) { if (globalThis.__profileQuery) { const evs = await globalThis.__profileQuery(relays, filter); for (const ev of evs || []) onEvent(ev); return; }'), loader: 'js' })); } }] }); assert(bundle.success, bundle.logs.join('\n')); const css = await Bun.file('src/style.css').text(); -- cgit v1.2.3