aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/avatar-thumb-test.js2
-rw-r--r--tools/boot-balance-test.js2
-rw-r--r--tools/boot-signin-flash-test.js6
-rw-r--r--tools/chat-layout-test.js2
-rw-r--r--tools/feed-follow-test.js2
-rw-r--r--tools/lock-wallet-test.js8
-rw-r--r--tools/minimal-smoke.js2
-rw-r--r--tools/onboard-backup-test.js121
-rw-r--r--tools/padlock-ask-test.js2
-rw-r--r--tools/padlock-flow-test.js4
-rw-r--r--tools/post-actions-test.js2
-rw-r--r--tools/profile-batch-test.js2
-rw-r--r--tools/profile-draft-test.js2
-rw-r--r--tools/profile-feed-test.js2
-rw-r--r--tools/profile-open-test.js2
-rw-r--r--tools/push-unavailable-test.js2
-rw-r--r--tools/quote-card-test.js2
-rw-r--r--tools/ui-morph-test.js4
-rw-r--r--tools/unifiedpush-test.js2
-rw-r--r--tools/youtube-embed-test.js2
-rw-r--r--tools/zap-tally-cache-test.js2
21 files changed, 148 insertions, 27 deletions
diff --git a/tools/avatar-thumb-test.js b/tools/avatar-thumb-test.js
index 727c49a..c776179 100644
--- a/tools/avatar-thumb-test.js
+++ b/tools/avatar-thumb-test.js
@@ -73,7 +73,7 @@ try {
await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
- await click('get started'); await sleep(500);
+ await click('create a new wallet'); await sleep(500);
await click('import existing'); await sleep(400);
await page.waitForSelector('textarea');
const mnemonic = generateMnemonic(wordlist);
diff --git a/tools/boot-balance-test.js b/tools/boot-balance-test.js
index 96f47a9..c34712b 100644
--- a/tools/boot-balance-test.js
+++ b/tools/boot-balance-test.js
@@ -28,7 +28,7 @@ try {
await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
- await click('get started'); await sleep(500);
+ await click('create a new wallet'); await sleep(500);
await click('import existing'); await sleep(400);
await page.waitForSelector('textarea');
await page.type('textarea', generateMnemonic(wordlist));
diff --git a/tools/boot-signin-flash-test.js b/tools/boot-signin-flash-test.js
index e46ee72..b29bc63 100644
--- a/tools/boot-signin-flash-test.js
+++ b/tools/boot-signin-flash-test.js
@@ -1,7 +1,7 @@
// A signed-in wallet must never flash the signed-out welcome screen. Anything
// that renders before boot has restored the session (a deferred feature chunk
// landing, an emitter tick) is rendering without knowing whether anyone is
-// signed in, and "Get started" over a wallet that's about to open is the one
+// signed in, and the start page over a wallet that's about to open is the one
// wrong guess that's unmistakable.
//
// The race is widened here (the locale fetch is delayed, so the deferred
@@ -27,7 +27,7 @@ try {
await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
- await click('get started'); await sleep(500);
+ await click('create a new wallet'); await sleep(500);
await click('import existing'); await sleep(400);
await page.waitForSelector('textarea');
await page.type('textarea', generateMnemonic(wordlist));
@@ -48,7 +48,7 @@ try {
window.__sawSignin = null;
const tick = () => {
const txt = (document.body && document.body.innerText) || '';
- if (!window.__sawSignin && /get started|sign in with/i.test(txt)) window.__sawSignin = Math.round(performance.now());
+ if (!window.__sawSignin && /create a new wallet|sign in with/i.test(txt)) window.__sawSignin = Math.round(performance.now());
if (!window.__walletAt && document.querySelector('.balance')) window.__walletAt = Math.round(performance.now());
if (!window.__walletAt) requestAnimationFrame(tick);
};
diff --git a/tools/chat-layout-test.js b/tools/chat-layout-test.js
index 853aafa..772e38f 100644
--- a/tools/chat-layout-test.js
+++ b/tools/chat-layout-test.js
@@ -43,7 +43,7 @@ try {
await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
- await click('button', 'Get started');
+ await click('button', 'Create a new wallet');
await sleep(300);
await click('button', 'Import existing');
await sleep(300);
diff --git a/tools/feed-follow-test.js b/tools/feed-follow-test.js
index 4c1fed3..ae486a6 100644
--- a/tools/feed-follow-test.js
+++ b/tools/feed-follow-test.js
@@ -31,7 +31,7 @@ try {
await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
- await click('get started'); await sleep(500);
+ await click('create a new wallet'); await sleep(500);
await click('import existing'); await sleep(400);
await page.waitForSelector('textarea');
const mnemonic = generateMnemonic(wordlist);
diff --git a/tools/lock-wallet-test.js b/tools/lock-wallet-test.js
index 8db392a..494195e 100644
--- a/tools/lock-wallet-test.js
+++ b/tools/lock-wallet-test.js
@@ -44,7 +44,7 @@ try {
await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
- await click('button', 'Get started');
+ await click('button', 'Create a new wallet');
await sleep(500);
await click('button', 'Import existing');
await sleep(400);
@@ -76,7 +76,7 @@ try {
await logout();
txt = await body();
check('it does not ask a second time', !/protect this device/i.test(txt), txt.slice(0, 120).replace(/\n+/g, ' | '));
- check('logout means the front door', /create new|get started|sign in/i.test(txt), txt.slice(0, 120).replace(/\n+/g, ' | '));
+ check('logout means the front door', /create a new wallet|sign in/i.test(txt), txt.slice(0, 120).replace(/\n+/g, ' | '));
await page.reload({ waitUntil: 'domcontentloaded' });
check('and a saved passwordless wallet is one reload away', await waitText('receive'));
await sleep(1000);
@@ -109,7 +109,7 @@ try {
check('back in the wallet', await waitText('receive'));
await logout();
txt = await body();
- check('logout is still the front door', /create new|get started|sign in/i.test(txt), txt.slice(0, 120).replace(/\n+/g, ' | '));
+ check('logout is still the front door', /create a new wallet|sign in/i.test(txt), txt.slice(0, 120).replace(/\n+/g, ' | '));
check('the wallet is still saved', (await vaultSize()) > 0);
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(800);
@@ -148,7 +148,7 @@ try {
await sleep(1200);
txt = await body();
check('everything is gone', (await vaultSize()) === 0);
- check('back at the start page', /get started/i.test(txt), txt.slice(0, 120).replace(/\n+/g, ' | '));
+ check('back at the start page', /create a new wallet/i.test(txt), txt.slice(0, 120).replace(/\n+/g, ' | '));
} catch (e) {
check('run completed', false, e.message);
} finally {
diff --git a/tools/minimal-smoke.js b/tools/minimal-smoke.js
index f3f896c..2bdc4a6 100644
--- a/tools/minimal-smoke.js
+++ b/tools/minimal-smoke.js
@@ -65,7 +65,7 @@ try {
await sleep(400);
console.log('\n[1] import + core wallet');
- await clickText('button', 'Get started'); // the front door gained a step
+ await clickText('button', 'Create a new wallet'); // the front door gained a step
await sleep(300);
await clickText('button', 'Import existing');
await sleep(200);
diff --git a/tools/onboard-backup-test.js b/tools/onboard-backup-test.js
new file mode 100644
index 0000000..3b242dd
--- /dev/null
+++ b/tools/onboard-backup-test.js
@@ -0,0 +1,121 @@
+// Two things about the front door.
+//
+// One: making your own keys has to look like the way in. Four equally
+// weighted buttons, where only the sign-in ones said what they did, sent
+// people straight past the seed phrase — which IS the wallet — into a login
+// that is only a convenience wrapped around one.
+//
+// Two: a wallet that arrived by SIGN-IN has a recovery phrase its owner has
+// never seen, and nobody can reissue it. So it gets shown once, during
+// setup, and if they put it off the wallet keeps one quiet line about it.
+//
+// Run: bun tools/onboard-backup-test.js
+import puppeteer from 'puppeteer-core';
+import { bech32 } from '@scure/base';
+import { generateSecretKey } from 'nostr-tools/pure';
+import { seedFromNostrKey } from '../src/nostr-login.js';
+import { buildHtml } from '../build.js';
+const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
+let ok = true;
+const check = (n, c, d = '') => { console.log(` ${c ? '✓' : '✗'} ${n}${d ? ' — ' + d : ''}`); if (!c) ok = false; };
+
+const html = await buildHtml({ minify: true, pwa: false });
+const server = Bun.serve({ port: 5291, fetch: () => new Response(html, { headers: { 'content-type': 'text/html' } }) });
+const browser = await puppeteer.launch({ executablePath: '/usr/bin/google-chrome', headless: 'new', args: ['--no-sandbox'] });
+
+const click = (page, t, sel = 'button') => page.evaluate((s, x) => {
+ const e = [...document.querySelectorAll(s)].find((n) => n.textContent.trim().toLowerCase().includes(x));
+ if (e) { e.click(); return true; } return false;
+}, sel, t.toLowerCase());
+const text = (page) => page.evaluate(() => document.body.innerText);
+const waitText = async (page, x, ms = 30000) => {
+ for (let i = 0; i < ms / 250; i++) { if ((await text(page)).toLowerCase().includes(x.toLowerCase())) return true; await sleep(250); }
+ return false;
+};
+
+// Sign in with a pasted nsec and stop at whatever the wizard shows next.
+// Its own browser context, so each run meets a genuinely fresh front door
+// rather than the wallet the previous one left in localStorage.
+async function signIn() {
+ const ctx = await browser.createBrowserContext();
+ const page = await ctx.newPage();
+ await page.setViewport({ width: 390, height: 844 });
+ await page.goto('http://localhost:5291/', { waitUntil: 'domcontentloaded' });
+ await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
+ await page.reload({ waitUntil: 'domcontentloaded' });
+ // wait for the front door to actually be painted before poking it
+ await waitText(page, 'sign in with nostr');
+ const sk = generateSecretKey();
+ const nsec = bech32.encode('nsec', bech32.toWords(sk), 1000);
+ await click(page, 'sign in with nostr');
+ await waitText(page, 'log in with nostr');
+ await page.waitForSelector('input[placeholder*="nsec" i], textarea[placeholder*="nsec" i]', { timeout: 15000 });
+ await page.type('input[placeholder*="nsec" i], textarea[placeholder*="nsec" i]', nsec);
+ await click(page, 'log in');
+ return { page, ctx, seed: seedFromNostrKey(sk) };
+}
+
+try {
+ console.log('[the start page]');
+ {
+ const page = await browser.newPage();
+ await page.setViewport({ width: 390, height: 844 });
+ await page.goto('http://localhost:5291/', { waitUntil: 'domcontentloaded' });
+ await sleep(1500);
+ const front = await page.evaluate(() => {
+ const btns = [...document.querySelectorAll('button')].filter((b) => b.offsetParent);
+ const primary = document.getElementById('onb-create');
+ const idx = btns.indexOf(primary);
+ const signins = btns.filter((b) => /sign in with/i.test(b.textContent));
+ return {
+ label: primary ? primary.textContent.trim() : null,
+ first: idx === 0 || (idx >= 0 && idx < btns.findIndex((b) => /sign in with/i.test(b.textContent))),
+ primaryTop: primary ? primary.getBoundingClientRect().top : -1,
+ signinTop: signins.length ? signins[0].getBoundingClientRect().top : -1,
+ divider: !!document.querySelector('.onb-or'),
+ body: (document.querySelector('.onb p') || {}).textContent || '',
+ };
+ });
+ check('the way in says what it makes', /wallet/i.test(front.label || ''), front.label || 'missing');
+ check('...and comes before the sign-in buttons', front.first && front.primaryTop < front.signinTop,
+ `create at ${Math.round(front.primaryTop)}, first sign-in at ${Math.round(front.signinTop)}`);
+ check('...with a line between them, so they read as the alternative', front.divider);
+ check('the page says what the wallet actually is', /twelve words|seed|phrase/i.test(front.body),
+ front.body.slice(0, 60) + '…');
+ await page.close();
+ }
+
+ console.log('\n[signing in, then writing it down]');
+ {
+ const { page, ctx, seed } = await signIn();
+ check('a sign-in is asked to write the phrase down', await waitText(page, 'write down your recovery phrase'));
+ const shown = await page.evaluate(() => [...document.querySelectorAll('.words .w .t')].map((e) => e.textContent.trim()));
+ check('...and the real twelve words are on screen', shown.length === 12 && shown.join(' ') === seed,
+ shown.length + ' words' + (shown.join(' ') === seed ? ', matching the derived seed' : ', WRONG'));
+ await click(page, "i've written it down");
+ check('confirming lands in the wallet', await waitText(page, 'receive'));
+ const nag = await text(page);
+ check('...and there is no reminder afterwards', !/still unwritten/i.test(nag));
+ await page.reload({ waitUntil: 'domcontentloaded' });
+ check('...not after a reload either', await waitText(page, 'receive') && !/still unwritten/i.test(await text(page)));
+ await ctx.close();
+ }
+
+ console.log('\n[signing in, then putting it off]');
+ {
+ const { page, ctx } = await signIn();
+ check('the ask appears', await waitText(page, 'write down your recovery phrase'));
+ await click(page, 'later');
+ check('later lands in the wallet too', await waitText(page, 'receive'));
+ check('...but the wallet keeps a quiet reminder', /still unwritten/i.test(await text(page)));
+ await page.reload({ waitUntil: 'domcontentloaded' });
+ await waitText(page, 'receive');
+ check('...which survives a reload', /still unwritten/i.test(await text(page)));
+ // and it is a way IN, not just a scold
+ await click(page, 'write it down');
+ check('tapping it opens the recovery phrase', await waitText(page, 'recovery phrase'));
+ await ctx.close();
+ }
+} finally { await browser.close(); server.stop(true); }
+console.log(ok ? '\n✅ the front door points at your own keys' : '\n❌ failed');
+process.exit(ok ? 0 : 1);
diff --git a/tools/padlock-ask-test.js b/tools/padlock-ask-test.js
index 8007aad..eb35047 100644
--- a/tools/padlock-ask-test.js
+++ b/tools/padlock-ask-test.js
@@ -26,7 +26,7 @@ try {
await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
- await click('button', 'get started');
+ await click('button', 'create a new wallet');
await sleep(500);
await click('button', 'Import existing');
await sleep(400);
diff --git a/tools/padlock-flow-test.js b/tools/padlock-flow-test.js
index 4b659aa..be4f5ec 100644
--- a/tools/padlock-flow-test.js
+++ b/tools/padlock-flow-test.js
@@ -29,7 +29,7 @@ try {
await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
- await click('button', 'Get started');
+ await click('button', 'Create a new wallet');
await sleep(500);
await click('button', 'Import existing');
await sleep(400);
@@ -117,7 +117,7 @@ try {
await p2.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await p2.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
- await click2('Get started');
+ await click2('Create a new wallet');
await sleep(500);
check('wallet A open', await importWallet());
await sleep(2000);
diff --git a/tools/post-actions-test.js b/tools/post-actions-test.js
index 8cc525c..06d4739 100644
--- a/tools/post-actions-test.js
+++ b/tools/post-actions-test.js
@@ -38,7 +38,7 @@ try {
await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
- await click('get started'); await sleep(500);
+ await click('create a new wallet'); await sleep(500);
await click('import existing'); await sleep(400);
await page.waitForSelector('textarea');
const mn = generateMnemonic(wordlist);
diff --git a/tools/profile-batch-test.js b/tools/profile-batch-test.js
index 335bfbc..bf8dcf4 100644
--- a/tools/profile-batch-test.js
+++ b/tools/profile-batch-test.js
@@ -68,7 +68,7 @@ try {
await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
- await click('get started'); await sleep(500);
+ await click('create a new wallet'); await sleep(500);
await click('import existing'); await sleep(400);
await page.waitForSelector('textarea');
const mn = generateMnemonic(wordlist);
diff --git a/tools/profile-draft-test.js b/tools/profile-draft-test.js
index 243f8ec..cb016da 100644
--- a/tools/profile-draft-test.js
+++ b/tools/profile-draft-test.js
@@ -41,7 +41,7 @@ try {
await page.goto(origin);
await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await page.reload({ waitUntil: 'domcontentloaded' });
- await click('Get started');
+ await click('Create a new wallet');
await click('Import existing');
await page.waitForSelector('textarea');
const mnemonic = generateMnemonic(wordlist);
diff --git a/tools/profile-feed-test.js b/tools/profile-feed-test.js
index 1e7283b..d285c44 100644
--- a/tools/profile-feed-test.js
+++ b/tools/profile-feed-test.js
@@ -25,7 +25,7 @@ const waitText = async (x, ms = 20000) => { for (let i = 0; i < ms / 250; i++) {
try {
await page.goto('http://localhost:5234/', { waitUntil: 'domcontentloaded' });
await sleep(400);
- await click('button', 'Get started');
+ await click('button', 'Create a new wallet');
await sleep(300);
await click('button', 'Import existing');
await sleep(300);
diff --git a/tools/profile-open-test.js b/tools/profile-open-test.js
index 7c88dee..da90af5 100644
--- a/tools/profile-open-test.js
+++ b/tools/profile-open-test.js
@@ -62,7 +62,7 @@ try {
await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
- await click('get started'); await sleep(500);
+ await click('create a new wallet'); await sleep(500);
await click('import existing'); await sleep(400);
await page.waitForSelector('textarea');
const mn = generateMnemonic(wordlist);
diff --git a/tools/push-unavailable-test.js b/tools/push-unavailable-test.js
index b285aee..4808501 100644
--- a/tools/push-unavailable-test.js
+++ b/tools/push-unavailable-test.js
@@ -38,7 +38,7 @@ try {
await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
- await click('get started'); await sleep(500);
+ await click('create a new wallet'); await sleep(500);
await click('import existing'); await sleep(400);
await page.waitForSelector('textarea');
const mn = generateMnemonic(wordlist);
diff --git a/tools/quote-card-test.js b/tools/quote-card-test.js
index 5225f4a..695ee93 100644
--- a/tools/quote-card-test.js
+++ b/tools/quote-card-test.js
@@ -38,7 +38,7 @@ try {
await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
- await click('get started'); await sleep(500);
+ await click('create a new wallet'); await sleep(500);
await click('import existing'); await sleep(400);
await page.waitForSelector('textarea');
const mn = generateMnemonic(wordlist);
diff --git a/tools/ui-morph-test.js b/tools/ui-morph-test.js
index 858a5a7..343ccd2 100644
--- a/tools/ui-morph-test.js
+++ b/tools/ui-morph-test.js
@@ -29,12 +29,12 @@ check('app booted to a screen with buttons', hasButton);
// walk into a wallet if the entry button exists
const clicked = await page.evaluate(() => {
- const btn = [...document.querySelectorAll('button')].find((b) => /get started/i.test(b.textContent));
+ const btn = [...document.querySelectorAll('button')].find((b) => /create a new wallet/i.test(b.textContent));
if (btn) { btn.click(); return true; }
return false;
});
await sleep(4000);
-check('entered next screen', await page.evaluate(() => document.body.textContent.length > 100), clicked ? '' : '(no Get started button — already in wallet)');
+check('entered next screen', await page.evaluate(() => document.body.textContent.length > 100), clicked ? '' : '(no start button — already in wallet)');
// node identity across background renders: tag a button, force renders, compare
const identity = await page.evaluate(async () => {
diff --git a/tools/unifiedpush-test.js b/tools/unifiedpush-test.js
index 022ead6..6a3819c 100644
--- a/tools/unifiedpush-test.js
+++ b/tools/unifiedpush-test.js
@@ -55,7 +55,7 @@ try {
await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
- await click('get started'); await sleep(500);
+ await click('create a new wallet'); await sleep(500);
await click('import existing'); await sleep(400);
await page.waitForSelector('textarea');
const mn = generateMnemonic(wordlist);
diff --git a/tools/youtube-embed-test.js b/tools/youtube-embed-test.js
index f9bbf0d..a70272c 100644
--- a/tools/youtube-embed-test.js
+++ b/tools/youtube-embed-test.js
@@ -22,7 +22,7 @@ await page.goto('http://localhost:5267/', { waitUntil: 'domcontentloaded' });
await page.evaluate(() => { localStorage.setItem('btc-wallet-network', 'regtest'); localStorage.setItem('btc-wallet-theme', 'dark'); });
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
-await click('get started'); await sleep(500);
+await click('create a new wallet'); await sleep(500);
await click('import existing'); await sleep(400);
await page.waitForSelector('textarea');
const mn = generateMnemonic(wordlist);
diff --git a/tools/zap-tally-cache-test.js b/tools/zap-tally-cache-test.js
index 98cfe7e..4e91260 100644
--- a/tools/zap-tally-cache-test.js
+++ b/tools/zap-tally-cache-test.js
@@ -24,7 +24,7 @@ try {
await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(400);
- await click('get started'); await sleep(500);
+ await click('create a new wallet'); await sleep(500);
await click('import existing'); await sleep(400);
await page.waitForSelector('textarea');
const mnemonic = generateMnemonic(wordlist);