const path = require('path'); const fs = require('fs'); const { openStory, captureWithSensors, } = require(process.env.PROBE_KIT || process.env.HOME + '/astryx/probe-kit/lib.cjs'); const root = process.env.REVIEW_WORKTREE || process.cwd(); const sha = 'af004c602b65f7f85c3b5a17111492a50a7560a1'; const port = Number(process.env.SB_PORT || 6203); const outDir = process.env.REVIEW_OUT_DIR || path.join(process.cwd(), 'review-shots-5563'); fs.mkdirSync(outDir, {recursive: true}); const expected = { globals: {}, themeAttr: 'neutral', colorMode: 'light', direction: 'ltr', viewport: {width: 1200, height: 900, dpr: 1}, media: { forcedColors: false, reducedMotion: false, coarsePointer: false, hover: true, }, targetCount: 1, state: { headings: [ 'List', 'Markdown', 'MetadataListItem', 'NavHeadingMenu', 'Timestamp', 'Token', 'TopNavMenu styled pass-through', 'TopNavMegaMenu styled pass-through', 'TreeList', 'TypeaheadItem styled pass-through', ], hasList: true, hasTree: true, triggerNames: ['Products', 'Solutions'], typeaheadLabel: 'Typeahead result', }, runningAnimations: 0, }; async function readMatrixState(page) { return page.evaluate(() => ({ headings: [...document.querySelectorAll('.review-5563-matrix h3')].map( element => element.innerText, ), hasList: document.querySelector('[role="list"]') != null, hasTree: document.querySelector('[role="tree"]') != null, triggerNames: [ document.querySelector('[data-case="topnav"] > button')?.innerText.trim(), document.querySelector('[data-case="mega"] > button')?.innerText.trim(), ], typeaheadLabel: document.querySelector('[data-case="typeahead"]')?.innerText .split('\n') .at(-1) ?.trim(), })); } async function captureMatrix(arm) { const story = 'review-pr5563--matrix'; const ready = arm === 'after' ? () => { const element = document.querySelector('[data-case="typeahead"] > div'); return element != null && getComputedStyle(element).outlineStyle === 'solid' && getComputedStyle(element).outlineColor === 'rgb(217, 70, 239)'; } : () => { const element = document.querySelector('[data-case="typeahead"] > div'); return element != null && getComputedStyle(element).outlineStyle === 'none'; }; const {browser, page, sensorErrors} = await openStory('chromium', story, { port, viewport: {width: 1200, height: 900}, ready, waitUntil: 'domcontentloaded', gotoTimeout: 120000, }); const receipt = await captureWithSensors( page, path.join(outDir, `${arm}__matrix.png`), { label: `${arm} — ten-component forwarding matrix`, buildRoot: root, expectedSha: sha, story, target: '.review-5563-matrix', surface: 'body', expected, readState: readMatrixState, sensorErrors, screenshot: {fullPage: true}, }, ); await browser.close(); return receipt; } async function probeCancellation() { const story = 'review-pr5563--cancellation'; const {browser, page, sensorErrors} = await openStory('chromium', story, { port, viewport: {width: 900, height: 500}, ready: () => document.querySelectorAll('[role="treeitem"]').length === 2 && document.querySelectorAll('[role="menuitem"]').length === 2, waitUntil: 'domcontentloaded', gotoTimeout: 120000, }); const treeItems = page.getByRole('treeitem'); await treeItems.nth(0).focus(); await page.keyboard.press('ArrowDown'); const menuItems = page.getByRole('menuitem'); await menuItems.nth(0).focus(); await page.keyboard.press('ArrowDown'); const result = await page.evaluate(() => ({ treeConsumerSaw: document.querySelector('[data-testid="tree-seen"]')?.textContent, treeTabStops: [...document.querySelectorAll('[role="treeitem"]')].map(element => ({ text: element.textContent?.trim(), tabIndex: element.getAttribute('tabindex'), })), menuConsumerSaw: document.querySelector('[data-testid="menu-seen"]')?.textContent, activeText: document.activeElement?.textContent?.trim(), })); if (sensorErrors.length > 0) { throw new Error(`browser errors: ${JSON.stringify(sensorErrors)}`); } await browser.close(); fs.writeFileSync( path.join(outDir, 'cancellation-dom.json'), `${JSON.stringify(result, null, 2)}\n`, ); console.log(JSON.stringify(result)); } (async () => { const action = process.argv[2]; if (action === 'after' || action === 'before') { await captureMatrix(action); } else if (action === 'cancellation') { await probeCancellation(); } else { throw new Error('expected after, before, or cancellation'); } })().catch(error => { console.error(error); process.exit(1); });