aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-09-12 17:06:14 -0700
committerAdam Soltys <[email protected]>2026-09-12 17:06:14 -0700
commitce61a0f20a2c535e0c69f59836a17f31a3d88468 (patch)
treebc80738e4181af5bb8b3ca0844a16d52766c415a /tools
parent8fe3d0d28d5f15643c1737809c5f1773cb8f9f94 (diff)
downloadcoinosv3-ce61a0f20a2c535e0c69f59836a17f31a3d88468.tar.gz
coinosv3-ce61a0f20a2c535e0c69f59836a17f31a3d88468.zip
End to end over the real network, and the advice now fits the app it's in.
A push sent to ntfy.sh reached a killed app on a real phone: 17:02:21.259 ntfy.sh → the phone's ntfy → broadcast to io.coinos.webview 17:02:21.308 app process started (it had been killed) 17:02:21.458 wake: job started 17:02:22.926 wake: finishing (page said so) — 1.7s, and "You were paid" One thing that took two goes: `adb shell am force-stop` marks a package STOPPED, and Android delivers no broadcasts to a stopped package unless the sender sets FLAG_INCLUDE_STOPPED_PACKAGES — which `am broadcast` does and a real distributor rightly doesn't. The first attempt looked like a failure and was a test artefact; `am kill`, which is what Android itself does to a backgrounded app, delivers fine. And the WebView build can now say something useful about push. It was inheriting the browser's line — "your browser has no push service, try Firefox" — which is nonsense inside a WebView that IS the app. It asks the host what's actually there and says: install a push app like ntfy (nothing installed), or wait a moment and reopen (a distributor that hasn't answered yet). Payments and messages still arrive whenever coinos is open, which is the part that matters most to someone reading an apology. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_019mrt228Upn9nNCwGixzSLx
Diffstat (limited to 'tools')
-rw-r--r--tools/unifiedpush-test.js26
1 files changed, 25 insertions, 1 deletions
diff --git a/tools/unifiedpush-test.js b/tools/unifiedpush-test.js
index 6cf7b6e..022ead6 100644
--- a/tools/unifiedpush-test.js
+++ b/tools/unifiedpush-test.js
@@ -14,6 +14,7 @@ import puppeteer from 'puppeteer-core';
import { generateMnemonic } from '@scure/bip39';
import { wordlist } from '@scure/bip39/wordlists/english';
import { buildHtml } from '../build.js';
+import { cacheKeyFor } from '../src/wallet.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; };
@@ -57,7 +58,8 @@ try {
await click('get started'); await sleep(500);
await click('import existing'); await sleep(400);
await page.waitForSelector('textarea');
- await page.type('textarea', generateMnemonic(wordlist));
+ const mn = generateMnemonic(wordlist);
+ await page.type('textarea', mn);
await click('open wallet');
await waitText('receive', 20000);
@@ -79,6 +81,28 @@ try {
check('the browser\'s own dead push is no longer the story', !/no push service/i.test(txt),
(txt.match(/[^\n]*push service[^\n]*/i) || [''])[0].slice(0, 50));
+ // Inside the Android build, the advice about push is about the
+ // distributor, not about browsers — it IS the browser.
+ await page.evaluateOnNewDocument(() => {
+ window.CoinosHost = { env: () => JSON.stringify({ app: 'graphene', distributors: 0, distributor: null, endpoint: false }) };
+ });
+ // a phone that has never managed a push: no endpoint, and the browser's
+ // own push already known to be dead
+ await page.evaluate((k) => {
+ localStorage.removeItem('coinos-unifiedpush');
+ const st = JSON.parse(localStorage.getItem(k) || '{}');
+ st.push = false; st.noPushService = true;
+ localStorage.setItem(k, JSON.stringify(st));
+ }, cacheKeyFor(mn + '\n') + ':messages');
+ await page.goto('http://localhost:5263/', { 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(2500);
+ const advice = await page.evaluate(() => document.body.innerText);
+ check('with no distributor installed it says to install one', /ntfy/i.test(advice),
+ (advice.match(/[^\n]*ntfy[^\n]*/i) || ['nothing about a distributor'])[0].slice(0, 60));
+ check('...and not to go and use Firefox', !/Firefox/.test(advice));
+
// The WebView build wakes the wallet off-screen with ?wake=<payload> and a
// CoinosHost bridge. The page has to notice, tidy the URL, and say when
// it's finished so the service can stop.