import { chromium } from 'playwright'; import { createInterface } from 'node:readline'; const lines = createInterface({ input: process.stdin }); const input = lines[Symbol.asyncIterator](); const config = JSON.parse((await input.next()).value); const browser = await chromium.launch({headless:true}); try { // A fresh default-browser profile; no cookie is copied out to the app. // JavaScript is disabled to verify the entire sign-in/consent flow is HTML. const context = await browser.newContext({javaScriptEnabled:false}); const page = await context.newPage(); await page.goto(config.url); process.stdout.write("stage:signin\n"); // A member's target lands on the sign-in page. An invitation now lands on // the guest screen instead (guest.html, added with guest joining): join in // the app, a name form to continue in the browser, and the bar's Sign in. // Only the sign-in page carries the address field, so follow the link when // that is what this target produced. const address = page.locator('input[name="address"]'); if ((await address.count()) === 0) { await Promise.all([ page.waitForURL('**/signin*'), // Since the shared chrome (f86d4da) the link is the bar's "Sign in". page.getByRole('link', { name: 'Sign in', exact: true }).first().click(), ]); } await address.fill(config.address); await Promise.all([ page.waitForURL('**/signin?sent=1'), page.locator('form[action="/signin"] button[type="submit"]').click(), ]); process.stdout.write('mail\n'); const link = JSON.parse((await input.next()).value).link; // Email opens a NEW browser tab, exactly as the reported failure did. const email = await context.newPage(); await email.goto(link); process.stdout.write("stage:email-opened\n"); // The link opens the confirm door, which spends nothing; its one Sign // in button POSTs the link back, and that is what signs in. await email.locator('form[action="/auth/verify"] button[type="submit"]').click(); await email.waitForURL('**/native/authorize?*'); if (!(await email.locator("body").innerText()).includes(config.code)) throw Error("confirmation code differs from app"); await email.getByRole('button', {name:'Sign in to Calls app', exact:true}).click(); await email.waitForURL('**/native/complete'); if (!(await email.locator('body').innerText()).includes('Return to the Calls app')) throw Error('missing completion'); process.stdout.write('approved\n'); } finally { await browser.close(); lines.close(); process.stdin.destroy(); }