oficina / sheets Public

Drive scripts: wait for the redirect, not networkidle, after a submit

The busy rule holds a submit for 650ms, so networkidle resolved before
the POST left: chrome, clipboard, menus and tableformat read the log
before the magic link was in it and died with "no magic link". They
wait for /signin?sent=1 now, as drive.mjs and drop.mjs already did.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Paul Campbell pushed by paul@keymail.dev 6fc76ab02da1c45d827543250d4f219317b5e746 parent 48c1052
4 files changed, +5 −5
  • tools/drive/chrome.mjs +2 −2
  • tools/drive/clipboard.mjs +1 −1
  • tools/drive/menus.mjs +1 −1
  • tools/drive/tableformat.mjs +1 −1

CI passed — run details

CI log
amadan: .amadan/timeout: this job's budget is 15m0s (this runner allows up to 30m0s)
=== vet ===
CGO_ENABLED=0 go vet ./...
CGO_ENABLED=0 go vet -tags browser ./internal/sheets/
=== fmt ===
=== build ===
CGO_ENABLED=0 go build ./...
=== migrations ===
go tool rastrillo migration check
go: downloading github.com/BurntSushi/toml v1.6.0
rastrillo migration check: models and migrations agree
=== go-test ===
CGO_ENABLED=0 go test -count=1 ./...
?   	amadan.net/oficina/sheets/cmd/sheets	[no test files]
ok  	amadan.net/oficina/sheets/internal/guardstest	0.083s
ok  	amadan.net/oficina/sheets/internal/sheets	11.335s
ok  	amadan.net/oficina/sheets/internal/sheets/calc	0.011s
ok  	amadan.net/oficina/sheets/internal/sheets/format	0.006s
ok  	amadan.net/oficina/sheets/internal/sheets/live	0.054s
ok  	amadan.net/oficina/sheets/internal/sheets/seal	0.006s
ok  	amadan.net/oficina/sheets/internal/sheets/sealtest	0.004s
ok  	amadan.net/oficina/sheets/internal/sheets/store	2.869s
ok  	amadan.net/oficina/sheets/internal/sheets/xlsx	0.288s
?   	amadan.net/oficina/sheets/tools/gencorpus	[no test files]
=== race ===
go test -race -count=1 ./internal/sheets/store/... ./internal/sheets/live/...
ok  	amadan.net/oficina/sheets/internal/sheets/store	46.315s
ok  	amadan.net/oficina/sheets/internal/sheets/live	1.060s
diff --git a/tools/drive/chrome.mjs b/tools/drive/chrome.mjs
index 62ccdf9..7e0db03 100644
--- a/tools/drive/chrome.mjs
+++ b/tools/drive/chrome.mjs
@@ -56,7 +56,7 @@ page.on('pageerror', (e) => errors.push(String(e)));
* "\n\nIt..." and the link comes back expired. */
await page.goto(`${base}/signin`);
await page.fill('input[type=email]', 'paul@example.com');
-await Promise.all([page.waitForLoadState('networkidle'), page.click('button[type=submit]')]);
+await Promise.all([page.waitForURL(/signin\?sent=1/), page.click('form[action="/signin"] button[type=submit]')]);
const log = fs.readFileSync(LOG, 'utf8');
const m = [...log.matchAll(/http:\/\/127\.0\.0\.1:8799\/auth\/verify\?[^\s\\"]+/g)].pop();
if (!m) { console.error('no magic link in the log'); process.exit(1); }
@@ -283,7 +283,7 @@ const vErrors = [];
vp.on('pageerror', (e) => vErrors.push(String(e)));
await vp.goto(`${base}/signin`);
await vp.fill('input[type=email]', 'ada@elsewhere.example');
-await Promise.all([vp.waitForLoadState('networkidle'), vp.click('button[type=submit]')]);
+await Promise.all([vp.waitForURL(/signin\?sent=1/), vp.click('form[action="/signin"] button[type=submit]')]);
const vm = [...fs.readFileSync(LOG, 'utf8').matchAll(/http:\/\/127\.0\.0\.1:8799\/auth\/verify\?[^\s\\"]+/g)].pop();
await vp.goto(vm[0]);
await vp.goto(url);
diff --git a/tools/drive/clipboard.mjs b/tools/drive/clipboard.mjs
index a240fdd..66f3af5 100644
--- a/tools/drive/clipboard.mjs
+++ b/tools/drive/clipboard.mjs
@@ -31,7 +31,7 @@ const errors=[]; page.on('pageerror',e=>errors.push(String(e))); page.on('consol
const fails=[]; const ok=n=>console.log(' ok '+n);
const check=(n,c,d)=>c?ok(n):(fails.push(n),console.log(' FAIL '+n+' — '+d));
await page.goto(`${base}/signin`); await page.fill('input[type=email]','paul@example.com');
-await Promise.all([page.waitForLoadState('networkidle'),page.click('button[type=submit]')]);
+await Promise.all([page.waitForURL(/signin\?sent=1/), page.click('form[action="/signin"] button[type=submit]')]);
const mm=[...fs.readFileSync(process.env.SHEETS_LOG,'utf8').matchAll(/http:\/\/127\.0\.0\.1:8799\/auth\/verify\?[^\s\\"]+/g)].pop();
await page.goto(mm[0]); await page.waitForURL(/\/sheets/);
// Create from the top bar, then name it by renaming: the list's #title
diff --git a/tools/drive/menus.mjs b/tools/drive/menus.mjs
index 2d077f3..8ecc9ae 100644
--- a/tools/drive/menus.mjs
+++ b/tools/drive/menus.mjs
@@ -45,7 +45,7 @@ const errors=[]; page.on('pageerror',e=>errors.push(String(e))); page.on('consol
const reqs=[]; page.on('request',r=>{if(r.method()!=='GET')reqs.push(r.method()+' '+new URL(r.url()).pathname);});
await page.goto(`${base}/signin`); await page.fill('input[type=email]','paul@example.com');
-await Promise.all([page.waitForLoadState('networkidle'),page.click('button[type=submit]')]);
+await Promise.all([page.waitForURL(/signin\?sent=1/), page.click('form[action="/signin"] button[type=submit]')]);
const mm=[...fs.readFileSync(LOG,'utf8').matchAll(/http:\/\/127\.0\.0\.1:8799\/auth\/verify\?[^\s\\"]+/g)].pop();
await page.goto(mm[0]); await page.waitForURL(/\/sheets/);
// No sheets yet: Create from the top bar, then name it by renaming.
diff --git a/tools/drive/tableformat.mjs b/tools/drive/tableformat.mjs
index 535bf8e..74d2ae4 100644
--- a/tools/drive/tableformat.mjs
+++ b/tools/drive/tableformat.mjs
@@ -23,7 +23,7 @@ const browser=await chromium.launch();
const page=await (await browser.newContext({viewport:{width:1280,height:900},deviceScaleFactor:2})).newPage();
const errs=[]; page.on('pageerror',e=>errs.push(String(e)));
await page.goto(`${base}/signin`); await page.fill('input[type=email]','paul@example.com');
-await Promise.all([page.waitForLoadState('networkidle'),page.click('button[type=submit]')]);
+await Promise.all([page.waitForURL(/signin\?sent=1/), page.click('form[action="/signin"] button[type=submit]')]);
const mm=[...fs.readFileSync(process.env.SHEETS_LOG,'utf8').matchAll(/http:\/\/127\.0\.0\.1:8799\/auth\/verify\?[^\s\\"]+/g)].pop();
await page.goto(mm[0]); await page.waitForURL(/\/sheets/);
// Create from the top bar, then name it by renaming: the list's #title