framewatch-mcp-server 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/README.md +895 -15
  2. package/dist/constants.d.ts +274 -0
  3. package/dist/constants.js +279 -0
  4. package/dist/constants.js.map +1 -1
  5. package/dist/engine/browser.d.ts +20 -4
  6. package/dist/engine/browser.js +26 -9
  7. package/dist/engine/browser.js.map +1 -1
  8. package/dist/engine/clicks.d.ts +221 -0
  9. package/dist/engine/clicks.js +801 -0
  10. package/dist/engine/clicks.js.map +1 -0
  11. package/dist/engine/forms.d.ts +137 -0
  12. package/dist/engine/forms.js +474 -0
  13. package/dist/engine/forms.js.map +1 -0
  14. package/dist/engine/hmr.d.ts +41 -0
  15. package/dist/engine/hmr.js +91 -0
  16. package/dist/engine/hmr.js.map +1 -0
  17. package/dist/engine/inspect.d.ts +31 -0
  18. package/dist/engine/inspect.js +383 -0
  19. package/dist/engine/inspect.js.map +1 -0
  20. package/dist/engine/interaction.d.ts +12 -7
  21. package/dist/engine/interaction.js +110 -18
  22. package/dist/engine/interaction.js.map +1 -1
  23. package/dist/engine/links.d.ts +134 -0
  24. package/dist/engine/links.js +384 -0
  25. package/dist/engine/links.js.map +1 -0
  26. package/dist/engine/mocks.d.ts +53 -0
  27. package/dist/engine/mocks.js +148 -0
  28. package/dist/engine/mocks.js.map +1 -0
  29. package/dist/engine/rtl.d.ts +129 -0
  30. package/dist/engine/rtl.js +540 -0
  31. package/dist/engine/rtl.js.map +1 -0
  32. package/dist/engine/seo.d.ts +189 -0
  33. package/dist/engine/seo.js +398 -0
  34. package/dist/engine/seo.js.map +1 -0
  35. package/dist/engine/snapshot.d.ts +29 -0
  36. package/dist/engine/snapshot.js +10 -0
  37. package/dist/engine/snapshot.js.map +1 -0
  38. package/dist/engine/vue.d.ts +54 -0
  39. package/dist/engine/vue.js +419 -0
  40. package/dist/engine/vue.js.map +1 -0
  41. package/dist/index.js +45 -1
  42. package/dist/index.js.map +1 -1
  43. package/dist/tools/accessibility.d.ts +4 -0
  44. package/dist/tools/accessibility.js +9 -2
  45. package/dist/tools/accessibility.js.map +1 -1
  46. package/dist/tools/api-mock.d.ts +405 -0
  47. package/dist/tools/api-mock.js +186 -0
  48. package/dist/tools/api-mock.js.map +1 -0
  49. package/dist/tools/capture.d.ts +90 -26
  50. package/dist/tools/capture.js +109 -58
  51. package/dist/tools/capture.js.map +1 -1
  52. package/dist/tools/compare.d.ts +4 -0
  53. package/dist/tools/compare.js +16 -5
  54. package/dist/tools/compare.js.map +1 -1
  55. package/dist/tools/dead-clicks.d.ts +128 -0
  56. package/dist/tools/dead-clicks.js +570 -0
  57. package/dist/tools/dead-clicks.js.map +1 -0
  58. package/dist/tools/form-test.d.ts +112 -0
  59. package/dist/tools/form-test.js +477 -0
  60. package/dist/tools/form-test.js.map +1 -0
  61. package/dist/tools/index.d.ts +17 -1
  62. package/dist/tools/index.js +45 -1
  63. package/dist/tools/index.js.map +1 -1
  64. package/dist/tools/inspect.d.ts +78 -0
  65. package/dist/tools/inspect.js +136 -0
  66. package/dist/tools/inspect.js.map +1 -0
  67. package/dist/tools/interact.d.ts +37 -18
  68. package/dist/tools/interact.js +113 -13
  69. package/dist/tools/interact.js.map +1 -1
  70. package/dist/tools/links.d.ts +129 -0
  71. package/dist/tools/links.js +640 -0
  72. package/dist/tools/links.js.map +1 -0
  73. package/dist/tools/responsive.d.ts +10 -6
  74. package/dist/tools/responsive.js +21 -4
  75. package/dist/tools/responsive.js.map +1 -1
  76. package/dist/tools/rtl.d.ts +241 -0
  77. package/dist/tools/rtl.js +410 -0
  78. package/dist/tools/rtl.js.map +1 -0
  79. package/dist/tools/save-auth.d.ts +263 -0
  80. package/dist/tools/save-auth.js +253 -0
  81. package/dist/tools/save-auth.js.map +1 -0
  82. package/dist/tools/screenshot.d.ts +4 -0
  83. package/dist/tools/screenshot.js +15 -4
  84. package/dist/tools/screenshot.js.map +1 -1
  85. package/dist/tools/seo.d.ts +113 -0
  86. package/dist/tools/seo.js +281 -0
  87. package/dist/tools/seo.js.map +1 -0
  88. package/dist/tools/snapshot.d.ts +122 -0
  89. package/dist/tools/snapshot.js +183 -0
  90. package/dist/tools/snapshot.js.map +1 -0
  91. package/dist/tools/wait-for.d.ts +107 -0
  92. package/dist/tools/wait-for.js +167 -0
  93. package/dist/tools/wait-for.js.map +1 -0
  94. package/dist/utils/arabic-text.d.ts +14 -0
  95. package/dist/utils/arabic-text.js +193 -0
  96. package/dist/utils/arabic-text.js.map +1 -0
  97. package/dist/utils/budget.d.ts +41 -0
  98. package/dist/utils/budget.js +182 -0
  99. package/dist/utils/budget.js.map +1 -0
  100. package/dist/utils/format.d.ts +11 -1
  101. package/dist/utils/format.js +27 -4
  102. package/dist/utils/format.js.map +1 -1
  103. package/dist/utils/highlight.d.ts +69 -0
  104. package/dist/utils/highlight.js +181 -0
  105. package/dist/utils/highlight.js.map +1 -0
  106. package/dist/utils/link-rules.d.ts +100 -0
  107. package/dist/utils/link-rules.js +284 -0
  108. package/dist/utils/link-rules.js.map +1 -0
  109. package/dist/utils/mock-rules.d.ts +144 -0
  110. package/dist/utils/mock-rules.js +224 -0
  111. package/dist/utils/mock-rules.js.map +1 -0
  112. package/dist/utils/rtl-rules.d.ts +142 -0
  113. package/dist/utils/rtl-rules.js +296 -0
  114. package/dist/utils/rtl-rules.js.map +1 -0
  115. package/dist/utils/seo-rules.d.ts +129 -0
  116. package/dist/utils/seo-rules.js +726 -0
  117. package/dist/utils/seo-rules.js.map +1 -0
  118. package/dist/utils/snapshot-rules.d.ts +33 -0
  119. package/dist/utils/snapshot-rules.js +111 -0
  120. package/dist/utils/snapshot-rules.js.map +1 -0
  121. package/dist/utils/storage-state.d.ts +76 -0
  122. package/dist/utils/storage-state.js +195 -0
  123. package/dist/utils/storage-state.js.map +1 -0
  124. package/dist/utils/style-rules.d.ts +107 -0
  125. package/dist/utils/style-rules.js +223 -0
  126. package/dist/utils/style-rules.js.map +1 -0
  127. package/dist/utils/test-data.d.ts +75 -0
  128. package/dist/utils/test-data.js +294 -0
  129. package/dist/utils/test-data.js.map +1 -0
  130. package/dist/utils/vue-rules.d.ts +72 -0
  131. package/dist/utils/vue-rules.js +108 -0
  132. package/dist/utils/vue-rules.js.map +1 -0
  133. package/package.json +6 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clicks.js","sourceRoot":"","sources":["../../src/engine/clicks.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ElementHandle, Page } from \"playwright\";\nimport {\n DEAD_CLICK_HOVER_SETTLE_MS,\n DEAD_CLICK_TIMEOUT_MS,\n MAX_DEAD_CLICK_CHANGES,\n MAX_DEAD_CLICK_CHANGE_SAMPLES,\n MAX_DEAD_CLICK_SCAN,\n MAX_DEAD_CLICK_TEXT_LENGTH,\n} from \"../constants.js\";\nimport type { ConsoleEntry, NetworkEvent } from \"../types.js\";\n\n/**\n * Click engine.\n *\n * Finds everything on a page that looks clickable, watches what a click\n * actually does, and decides whether anything happened at all. Nothing here\n * decides how to *report* it; that is `tools/dead-clicks.ts`.\n *\n * The hard part is not clicking — it is knowing that nothing happened. A\n * handler can navigate, mutate the DOM, fetch, open a dialog, toggle a\n * checkbox, scroll, move focus, write to localStorage or throw, and only some\n * of those are visible. So the answer is assembled from every channel at once:\n * the URL, an in-page MutationObserver, a signature of every field's value, of\n * storage and of scroll position, plus Playwright's own view of the console,\n * the network, dialogs, popups and downloads. \"Dead\" means every one of them\n * was silent.\n *\n * Pages are rarely silent on their own, though — a clock ticks, a carousel\n * advances, analytics beacons fire — so the same measurement is taken once\n * with nobody clicking, and whatever the page does by itself is subtracted\n * from every result (see `IdleNoise`). Without that, one `setInterval` makes\n * every element on the page look alive and the tool finds nothing.\n */\n\n/** The `window` key the in-page watcher keeps its counters under. */\nexport const CLICK_WATCH_KEY = \"__framewatch_clicks\";\n\n/** Why an element counts as clickable. */\nexport type ClickableKind = \"link\" | \"button\" | \"role\" | \"handler\" | \"pointer\";\n\n/** Everything known about one candidate before it is clicked. */\nexport interface Clickable {\n /** 1-based position in document order, and the number the report uses. */\n index: number;\n /**\n * A CSS selector for the element, recomputed rather than remembered: the\n * page is reloaded whenever a click changes it, and an ElementHandle does\n * not survive that.\n */\n selector: string;\n /** Which match of `selector` this is, for the (common) case where it is not unique. */\n match_index: number;\n /** How the element is named in the report — `button \"Save draft\"`. */\n description: string;\n kind: ClickableKind;\n tag: string;\n text: string;\n href?: string;\n role?: string;\n /** The computed `cursor`. `pointer` on a dead element is the whole finding. */\n cursor: string;\n /** The element says it is disabled without being disabled — clicking it is the test. */\n aria_disabled: boolean;\n /** Set when the element must not be clicked, and why. */\n skip?: string;\n}\n\nexport interface DiscoverClickablesOptions {\n /** Only look inside this. Defaults to the whole document. */\n selector?: string;\n /** Never click anything matching this, or inside it. */\n exclude?: string;\n /** Include elements that are only clickable-looking because of `cursor: pointer`. */\n include_pointer?: boolean;\n}\n\n/**\n * Find everything on the page a user could reasonably expect to click.\n *\n * Links, buttons, ARIA click roles and `onclick` attributes are the semantic\n * half. The other half is `cursor: pointer`, which is how a `<div>` announces\n * itself as a button — and which is where dead clicks actually live, because a\n * div has no default behaviour to fall back on when its handler never got\n * attached.\n *\n * `cursor` is an inherited property, so a pointer-styled card makes every one\n * of its descendants look clickable too. Only the outermost element of each\n * pointer subtree is kept, and a pointer element that wraps (or sits inside) a\n * real link or button is dropped entirely — that link is the thing being\n * clicked, and it is tested on its own.\n */\nexport async function discoverClickables(\n page: Page,\n options: DiscoverClickablesOptions = {},\n): Promise<Clickable[]> {\n const raw = await page.evaluate(collectClickables, {\n root: options.selector ?? \"\",\n exclude: options.exclude ?? \"\",\n include_pointer: options.include_pointer !== false,\n max_scan: MAX_DEAD_CLICK_SCAN,\n max_text: MAX_DEAD_CLICK_TEXT_LENGTH,\n });\n\n return raw.map((item, index) => ({\n index: index + 1,\n selector: item.selector,\n match_index: item.match_index,\n description: describeClickable(item),\n kind: item.kind,\n tag: item.tag,\n text: item.text,\n ...(item.href ? { href: item.href } : {}),\n ...(item.role ? { role: item.role } : {}),\n cursor: item.cursor,\n aria_disabled: item.aria_disabled,\n ...(item.skip ? { skip: item.skip } : {}),\n }));\n}\n\n/**\n * How an element is named in the report: `button \"Save draft\"`, `a \"Pricing\"`.\n *\n * An icon-only control has no text at all, and a bare selector is the least\n * recognisable thing to call it by — so a link falls back to where it points,\n * and everything else to its selector.\n */\nexport function describeClickable(item: {\n tag: string;\n text: string;\n kind: ClickableKind;\n href?: string;\n selector: string;\n}): string {\n if (item.text) return `${item.tag} \"${item.text}\"`;\n if (item.kind === \"link\" && item.href) return `${item.tag} → ${item.href}`;\n return `${item.tag} ${item.selector}`;\n}\n\n/** Re-find a candidate on the page as it is now. Null when it is no longer there. */\nexport async function resolveClickable(page: Page, clickable: Clickable): Promise<ElementHandle | null> {\n const handles = await page.$$(clickable.selector).catch(() => []);\n return handles[clickable.match_index] ?? handles[0] ?? null;\n}\n\n/* ── Watching what a click does ───────────────────────────────────────── */\n\n/** Everything about the page that a click could change, read in one go. */\nexport interface PageState {\n /** From `page.url()`, not from the page — a document mid-navigation cannot be asked. */\n url: string;\n /** Identifies this document. A reload keeps the URL and changes this. */\n doc: string;\n /** False when the MutationObserver could not be installed; `elements` is then the fallback. */\n watching: boolean;\n mutations: number;\n /** The first few mutations, described — `+ div.modal in #app`. */\n changes: string[];\n elements: number;\n /** Hash of every field's value and checked state. */\n fields: number;\n /** Hash of localStorage and sessionStorage. */\n storage: number;\n scroll_x: number;\n scroll_y: number;\n title: string;\n}\n\n/** What Playwright saw while the click was settling, which the page cannot report on itself. */\nexport interface ClickEvidence {\n console: ConsoleEntry[];\n network: NetworkEvent[];\n dialogs: string[];\n popups: string[];\n downloads: string[];\n /**\n * True when focus stayed on the clicked element (or inside it), which is\n * what clicking anything focusable does and therefore says nothing. Focus\n * landing somewhere *else* — a label handing it to its input, a skip link —\n * is a real effect.\n */\n focus_self: boolean;\n}\n\nexport const EMPTY_EVIDENCE: ClickEvidence = {\n console: [],\n network: [],\n dialogs: [],\n popups: [],\n downloads: [],\n focus_self: true,\n};\n\n/** What the page does with nobody clicking, so it can be subtracted from what it does when clicked. */\nexport interface IdleNoise {\n /** Mutations observed in one idle window. A click has to beat this to count. */\n mutations: number;\n /**\n * The mutations the page makes by itself, described. This, rather than the\n * count, is what a click is judged against: timer jitter means an idle\n * window and a click window never see the same *number* of ticks, but they\n * do see the same *kind* of change.\n */\n changes: string[];\n /** Requests the page makes by itself — polling, analytics, lazy loading. */\n network: string[];\n /** What it logs by itself. */\n console: string[];\n /** Signals that fired with nobody clicking, and are therefore worthless here. */\n unstable: EffectKind[];\n}\n\nexport const NO_NOISE: IdleNoise = { mutations: 0, changes: [], network: [], console: [], unstable: [] };\n\nexport type EffectKind =\n | \"error\"\n | \"navigated\"\n | \"reloaded\"\n | \"dialog\"\n | \"popup\"\n | \"download\"\n | \"dom\"\n | \"fields\"\n | \"storage\"\n | \"scroll\"\n | \"focus\"\n | \"title\"\n | \"network\"\n | \"console\";\n\nexport interface ClickEffect {\n kind: EffectKind;\n detail: string;\n}\n\n/** The order effects are reported in: the loudest thing the click did comes first. */\nconst EFFECT_ORDER: readonly EffectKind[] = [\n \"error\",\n \"navigated\",\n \"reloaded\",\n \"dialog\",\n \"popup\",\n \"download\",\n \"dom\",\n \"fields\",\n \"storage\",\n \"scroll\",\n \"focus\",\n \"title\",\n \"network\",\n \"console\",\n];\n\n/** Signals a noisy page can never invalidate — none of them happen by accident. */\nconst ALWAYS_TRUSTED: ReadonlySet<EffectKind> = new Set<EffectKind>([\n \"error\",\n \"navigated\",\n \"reloaded\",\n \"dialog\",\n \"popup\",\n \"download\",\n]);\n\n/**\n * Signals judged by *what* happened rather than by whether the page is restless.\n *\n * A DOM change is compared against the changes the page makes on its own, a\n * request against the URLs it fetches on its own, a log line against what it\n * logs on its own. Declaring those channels unusable the moment a page has a\n * clock in it would throw away the three most common things a working button\n * does — so they are filtered by content instead, and only the signals with\n * nothing to compare (a hash, a scroll position) are ever declared unstable.\n */\nconst CONTENT_FILTERED: ReadonlySet<EffectKind> = new Set<EffectKind>([\"dom\", \"network\", \"console\"]);\n\n/**\n * Everything the click did. An empty list is a dead click.\n *\n * Pure, so every verdict this tool reaches is unit-testable without a browser.\n *\n * When the URL changed, the two states describe two different documents and\n * comparing their innards would be meaningless — the navigation is the answer,\n * and only the out-of-page evidence is still read.\n */\nexport function diffPageState(\n before: PageState,\n after: PageState,\n evidence: ClickEvidence = EMPTY_EVIDENCE,\n idle: IdleNoise = NO_NOISE,\n): ClickEffect[] {\n const effects: ClickEffect[] = [];\n const unstable = new Set(idle.unstable);\n const add = (kind: EffectKind, detail: string): void => {\n if (!ALWAYS_TRUSTED.has(kind) && unstable.has(kind)) return;\n effects.push({ kind, detail });\n };\n\n const navigated = !sameUrl(before.url, after.url);\n if (navigated) {\n effects.push({ kind: \"navigated\", detail: `went to ${after.url}` });\n } else if (before.doc !== \"\" && after.doc !== \"\" && before.doc !== after.doc) {\n // Same address, new document: the click reloaded the page. Worth saying\n // out loud — it is what an <a href=\"\"> does, and it usually is not meant.\n effects.push({ kind: \"reloaded\", detail: \"the page reloaded itself\" });\n }\n\n for (const dialog of evidence.dialogs) {\n effects.push({ kind: \"dialog\", detail: `opened a dialog — ${dialog}` });\n }\n for (const popup of evidence.popups) {\n effects.push({ kind: \"popup\", detail: `opened a new tab — ${popup}` });\n }\n for (const download of evidence.downloads) {\n effects.push({ kind: \"download\", detail: `started a download — ${download}` });\n }\n\n if (!navigated) {\n // What the click changed, as opposed to what the page changes anyway. A\n // count alone cannot tell those apart on a page with a clock in it: two\n // windows of the same length never catch the same number of ticks.\n const fresh = after.changes.filter((change) => !idle.changes.includes(change));\n const extra = after.mutations - Math.max(0, idle.mutations);\n if (after.watching && (fresh.length > 0 || (after.changes.length === 0 && extra > 0))) {\n const many = Math.max(extra, fresh.length, 1);\n add(\"dom\", `${count(many, \"DOM change\", \"DOM changes\")}${describeChanges(fresh)}`);\n } else if (!after.watching && after.elements !== before.elements) {\n // No observer (a page that blocked it, or one replaced mid-sweep): the\n // element count is the crude fallback that is left.\n add(\"dom\", `the page has ${after.elements - before.elements > 0 ? \"gained\" : \"lost\"} ${Math.abs(after.elements - before.elements)} elements`);\n }\n if (after.fields !== before.fields) add(\"fields\", \"a form field's value or checked state changed\");\n if (after.storage !== before.storage) add(\"storage\", \"it wrote to localStorage or sessionStorage\");\n if (Math.abs(after.scroll_y - before.scroll_y) > 2 || Math.abs(after.scroll_x - before.scroll_x) > 2) {\n add(\"scroll\", `the page scrolled to ${after.scroll_x},${after.scroll_y}`);\n }\n if (!evidence.focus_self) add(\"focus\", \"it moved focus somewhere else\");\n if (after.title !== before.title) add(\"title\", `the title became \"${after.title}\"`);\n }\n\n // Network and console are filtered by *content* rather than by\n // `unstable`: a page that polls one endpoint should not lose the whole\n // channel, because a request is often the only thing a working button does,\n // and calling that one dead would be the worse mistake.\n const requests = evidence.network.filter((event) => !idle.network.includes(event.url));\n if (requests.length > 0) {\n const first = requests[0];\n const outcome = first.status > 0 ? String(first.status) : (first.error ?? \"no response\");\n effects.push({\n kind: \"network\",\n detail:\n `${count(requests.length, \"request\", \"requests\")} — ${first.method} ${first.url} → ${outcome}` +\n (requests.length > 1 ? \", and others\" : \"\"),\n });\n }\n\n const logged = evidence.console.filter((entry) => !idle.console.includes(entry.text));\n const errors = logged.filter((entry) => entry.level === \"error\");\n if (errors.length > 0) {\n effects.push({ kind: \"error\", detail: `the handler threw — ${errors[0].text}` });\n }\n const quiet = logged.filter((entry) => entry.level !== \"error\");\n if (quiet.length > 0) {\n effects.push({ kind: \"console\", detail: `wrote to the console — [${quiet[0].level}] ${quiet[0].text}` });\n }\n\n return effects.sort((a, b) => EFFECT_ORDER.indexOf(a.kind) - EFFECT_ORDER.indexOf(b.kind));\n}\n\n/**\n * What the page did to itself. Anything here fires without a click, so it\n * cannot be evidence that a click did something.\n */\nexport function measureNoise(before: PageState, after: PageState, evidence: ClickEvidence): IdleNoise {\n const effects = diffPageState(before, after, { ...evidence, focus_self: true }, NO_NOISE);\n return {\n mutations: Math.max(0, after.mutations - before.mutations),\n changes: after.changes,\n network: evidence.network.map((event) => event.url),\n console: evidence.console.map((entry) => entry.text),\n unstable: effects\n .map((effect) => effect.kind)\n .filter((kind) => !ALWAYS_TRUSTED.has(kind) && !CONTENT_FILTERED.has(kind)),\n };\n}\n\n/** One line describing what a page does on its own, or undefined when it does nothing. */\nexport function describeNoise(noise: IdleNoise): string | undefined {\n const parts: string[] = [];\n if (noise.mutations > 0) parts.push(count(noise.mutations, \"DOM change\", \"DOM changes\"));\n if (noise.network.length > 0) parts.push(count(noise.network.length, \"request\", \"requests\"));\n if (noise.console.length > 0) parts.push(count(noise.console.length, \"console entry\", \"console entries\"));\n if (noise.unstable.length > 0) parts.push(noise.unstable.join(\", \"));\n return parts.length > 0 ? parts.join(\", \") : undefined;\n}\n\n/* ── The in-page watcher ──────────────────────────────────────────────── */\n\n/**\n * Install the mutation counter, on this document and on every one after it.\n *\n * An init script alone would only reach the *next* document, and the page is\n * usually already open by the time the sweep starts; running it once by hand\n * covers the one that is there. The script refuses to install twice, so the\n * two paths cannot double-count.\n */\nexport async function installClickWatcher(page: Page): Promise<void> {\n const config = { key: CLICK_WATCH_KEY, max_changes: MAX_DEAD_CLICK_CHANGE_SAMPLES };\n await page.addInitScript(clickWatcher, config);\n await page.evaluate(clickWatcher, config).catch(() => {});\n}\n\n/** Zero the counters, so the next reading measures one click and nothing before it. */\nexport async function resetClickWatcher(page: Page): Promise<void> {\n await page\n .evaluate((key: string) => {\n const state = (globalThis as any)[key];\n if (state) {\n state.mutations = 0;\n state.changes = [];\n }\n }, CLICK_WATCH_KEY)\n .catch(() => {});\n}\n\n/**\n * Read everything the page can say about its own state.\n *\n * Returns null when the page cannot be asked at all — mid-navigation, closed,\n * crashed. A caller that gets null has still learned something (the URL, the\n * console, the network), so this is not an error.\n */\nexport async function readPageState(page: Page): Promise<PageState | null> {\n const url = safely(() => page.url()) ?? \"\";\n try {\n const state = await page.evaluate(readState, {\n key: CLICK_WATCH_KEY,\n max_changes: MAX_DEAD_CLICK_CHANGE_SAMPLES,\n max_text: MAX_DEAD_CLICK_TEXT_LENGTH,\n });\n return { url, ...state };\n } catch {\n return null;\n }\n}\n\n/* ── Hover ────────────────────────────────────────────────────────────── */\n\nexport interface HoverProbe {\n /** The computed cursor while hovered — `pointer` is the page inviting the click. */\n cursor: string;\n /** Which visual properties the page changes on hover, in words. */\n changed: string[];\n /** Why the probe could not run. */\n failed?: string;\n}\n\n/** Computed properties read before and after hovering, and what to call each one. */\nconst HOVER_PROPERTIES: ReadonlyArray<{ property: string; name: string }> = [\n { property: \"backgroundColor\", name: \"background\" },\n { property: \"backgroundImage\", name: \"background image\" },\n { property: \"color\", name: \"text colour\" },\n { property: \"borderTopColor\", name: \"border\" },\n { property: \"borderTopWidth\", name: \"border width\" },\n { property: \"boxShadow\", name: \"shadow\" },\n { property: \"opacity\", name: \"opacity\" },\n { property: \"transform\", name: \"transform\" },\n { property: \"textDecorationLine\", name: \"underline\" },\n { property: \"outlineStyle\", name: \"outline\" },\n { property: \"filter\", name: \"filter\" },\n];\n\n/**\n * Does the page react when the pointer is over this element?\n *\n * Asked only of elements that turned out dead, and for one reason: an element\n * that does nothing *and* lights up under the pointer is actively inviting the\n * click that will do nothing, which is the difference between a missing\n * feature and a broken one.\n *\n * Safe to run afterwards because a dead element, by definition, left the page\n * exactly as it was.\n */\nexport async function probeHover(\n page: Page,\n handle: ElementHandle,\n options: { timeout_ms?: number; settle_ms?: number } = {},\n): Promise<HoverProbe> {\n const timeout = options.timeout_ms ?? DEAD_CLICK_TIMEOUT_MS;\n const settle = options.settle_ms ?? DEAD_CLICK_HOVER_SETTLE_MS;\n const properties = HOVER_PROPERTIES.map((entry) => entry.property);\n\n try {\n // Start from a known state: the pointer may be sitting on this very\n // element from the click that has just happened.\n await page.mouse.move(0, 0);\n await page.waitForTimeout(settle);\n const before = await handle.evaluate(readComputed, properties);\n\n await handle.hover({ timeout });\n await page.waitForTimeout(settle);\n const after = await handle.evaluate(readComputed, properties);\n await page.mouse.move(0, 0);\n\n const changed = HOVER_PROPERTIES.filter((entry) => before[entry.property] !== after[entry.property]).map(\n (entry) => entry.name,\n );\n return { cursor: after.cursor ?? \"\", changed };\n } catch (error) {\n await page.mouse.move(0, 0).catch(() => {});\n return { cursor: \"\", changed: [], failed: firstLine(error) };\n }\n}\n\n/* ── In-page scripts ──────────────────────────────────────────────────────\n * Everything below runs inside Chromium, so it is written against\n * `globalThis` and untyped nodes: this package is compiled with the Node lib\n * only, and the page it lands in may be mid-teardown, using a framework that\n * has patched half of these properties, or both. Page scripts cannot import,\n * so the few shared helpers are inlined in each — the same trade the context\n * layers make (see engine/layers/probe.ts).\n */\n\ninterface RawClickable {\n selector: string;\n match_index: number;\n kind: ClickableKind;\n tag: string;\n text: string;\n href?: string;\n role?: string;\n cursor: string;\n aria_disabled: boolean;\n skip?: string;\n}\n\ninterface CollectOptions {\n root: string;\n exclude: string;\n include_pointer: boolean;\n max_scan: number;\n max_text: number;\n}\n\nfunction collectClickables(options: CollectOptions): RawClickable[] {\n const g = globalThis as any;\n const doc = g.document;\n if (!doc || !doc.body) return [];\n\n const SEMANTIC =\n 'a[href], button, summary, input[type=\"button\"], input[type=\"submit\"], input[type=\"reset\"], ' +\n 'input[type=\"image\"], [role=\"button\"], [role=\"link\"], [role=\"menuitem\"], [role=\"menuitemcheckbox\"], ' +\n '[role=\"menuitemradio\"], [role=\"tab\"], [role=\"switch\"], [role=\"checkbox\"], [role=\"radio\"], [role=\"option\"], [onclick]';\n const CLICK_ROLES = [\n \"button\",\n \"link\",\n \"menuitem\",\n \"menuitemcheckbox\",\n \"menuitemradio\",\n \"tab\",\n \"switch\",\n \"checkbox\",\n \"radio\",\n \"option\",\n ];\n const BUTTON_TYPES = [\"button\", \"submit\", \"reset\", \"image\"];\n // Not clickable, and nothing inside them is worth walking into.\n const SKIP_TAGS = [\"script\", \"style\", \"head\", \"meta\", \"link\", \"title\", \"template\", \"noscript\", \"svg\", \"iframe\"];\n // Schemes that hand the click to something that is not this page.\n const AWAY_SCHEMES = [\"mailto:\", \"tel:\", \"sms:\", \"callto:\", \"ftp:\"];\n\n const flatten = (text: unknown): string =>\n String(text ?? \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n\n const escape = (value: string): string => {\n try {\n if (g.CSS && typeof g.CSS.escape === \"function\") return g.CSS.escape(value);\n } catch {\n // Fall through to the conservative test below.\n }\n return /^[A-Za-z][\\w-]*$/.test(value) ? value : \"\";\n };\n\n /** A unique-enough CSS selector. Depth is capped; `match_index` settles the rest. */\n const selectorFor = (node: any): string => {\n const parts: string[] = [];\n let current = node;\n for (let depth = 0; current && current.nodeType === 1 && depth < 6; depth++) {\n const tag = String(current.tagName || \"\").toLowerCase();\n if (tag === \"body\" || tag === \"html\") {\n parts.unshift(tag);\n break;\n }\n const id = current.id ? escape(String(current.id)) : \"\";\n if (id !== \"\") {\n parts.unshift(`#${id}`);\n break;\n }\n let part = tag;\n const parent = current.parentElement;\n if (parent) {\n let position = 0;\n let total = 0;\n for (let i = 0; i < parent.children.length; i++) {\n const sibling = parent.children[i];\n if (sibling.tagName !== current.tagName) continue;\n total++;\n if (sibling === current) position = total;\n }\n if (total > 1 && position > 0) part += `:nth-of-type(${position})`;\n }\n parts.unshift(part);\n current = parent;\n }\n return parts.join(\" > \");\n };\n\n /** What the element says it is, for a report a human reads. */\n const labelFor = (node: any, tag: string): string => {\n let text = \"\";\n try {\n text = flatten(node.innerText) || flatten(node.textContent);\n } catch {\n text = \"\";\n }\n if (!text) text = flatten(node.getAttribute && node.getAttribute(\"aria-label\"));\n if (!text) text = flatten(node.getAttribute && node.getAttribute(\"title\"));\n if (!text && node.value !== undefined && tag === \"input\") text = flatten(node.value);\n if (!text) {\n try {\n const image = node.querySelector ? node.querySelector(\"img[alt], [aria-label]\") : null;\n if (image) text = flatten(image.getAttribute(\"alt\") || image.getAttribute(\"aria-label\"));\n } catch {\n // No inner label to borrow.\n }\n }\n return text.length > options.max_text ? `${text.slice(0, options.max_text)}…` : text;\n };\n\n let roots: any[] = [doc.body];\n if (options.root !== \"\") {\n try {\n roots = Array.prototype.slice.call(doc.querySelectorAll(options.root));\n } catch {\n roots = [];\n }\n }\n\n const found: Array<{ node: any; raw: RawClickable }> = [];\n const seen: any[] = [];\n let scanned = 0;\n\n const consider = (node: any, tag: string, style: any, cursor: string, parentCursor: string): void => {\n const attribute = (name: string): string => {\n try {\n const value = node.getAttribute ? node.getAttribute(name) : null;\n return value === null || value === undefined ? \"\" : String(value);\n } catch {\n return \"\";\n }\n };\n const role = attribute(\"role\").toLowerCase();\n const type = String(node.type ?? \"\").toLowerCase();\n\n let kind: ClickableKind | null = null;\n if (tag === \"a\" && node.hasAttribute && node.hasAttribute(\"href\")) kind = \"link\";\n else if (tag === \"button\" || tag === \"summary\" || (tag === \"input\" && BUTTON_TYPES.indexOf(type) !== -1)) kind = \"button\";\n else if (CLICK_ROLES.indexOf(role) !== -1) kind = \"role\";\n else if (node.hasAttribute && node.hasAttribute(\"onclick\")) kind = \"handler\";\n // `cursor` is inherited, so only the element the pointer style starts at\n // is a candidate — every descendant of a pointer-styled card would\n // otherwise be reported as its own button.\n else if (options.include_pointer && cursor === \"pointer\" && parentCursor !== \"pointer\") kind = \"pointer\";\n if (kind === null) return;\n\n if (seen.indexOf(node) !== -1) return;\n seen.push(node);\n\n if (kind === \"pointer\") {\n // A pointer wrapper around a real control is not the control; and a\n // pointer-styled span inside a button is part of the button.\n try {\n if (node.querySelector && node.querySelector(SEMANTIC)) return;\n if (node.closest && node.closest(SEMANTIC)) return;\n } catch {\n // A selector this browser will not parse; keep the candidate.\n }\n }\n\n let rect = { width: 0, height: 0 };\n try {\n rect = node.getBoundingClientRect();\n } catch {\n rect = { width: 0, height: 0 };\n }\n\n const href = tag === \"a\" ? String(node.href ?? \"\") : \"\";\n const raw: RawClickable = {\n selector: \"\",\n match_index: 0,\n kind,\n tag,\n text: labelFor(node, tag),\n ...(href ? { href } : {}),\n ...(role ? { role } : {}),\n cursor,\n aria_disabled: attribute(\"aria-disabled\").toLowerCase() === \"true\",\n };\n\n const skip = ((): string | undefined => {\n if (node.disabled === true) return \"disabled\";\n if (style && (style.visibility === \"hidden\" || style.display === \"none\")) return \"not visible\";\n if (rect.width < 1 || rect.height < 1) return \"has no size on screen\";\n if (options.exclude !== \"\") {\n try {\n if (node.closest && node.closest(options.exclude)) return \"excluded\";\n } catch {\n // An `exclude` this browser will not parse excludes nothing; the\n // tool validates it separately and says so.\n }\n }\n if (tag === \"a\") {\n if (node.hasAttribute && node.hasAttribute(\"download\")) return \"downloads a file\";\n const scheme = href.slice(0, href.indexOf(\":\") + 1).toLowerCase();\n if (AWAY_SCHEMES.indexOf(scheme) !== -1) return `hands the click to ${scheme.replace(\":\", \"\")}`;\n // A link to another site is alive by construction, and following it\n // would send a request to a third party this tool has no business\n // making on the user's behalf. Only an http(s) link can be off-site:\n // `javascript:void(0)` has no origin of its own, and it is exactly the\n // link most worth clicking here.\n try {\n const parsed = href === \"\" ? null : new g.URL(href);\n const scheme_ = parsed ? String(parsed.protocol) : \"\";\n if (parsed && (scheme_ === \"http:\" || scheme_ === \"https:\") && parsed.origin !== g.location.origin) {\n return `links to another site (${parsed.origin})`;\n }\n } catch {\n // An href that will not parse cannot be off-site.\n }\n }\n return undefined;\n })();\n if (skip !== undefined) raw.skip = skip;\n\n found.push({ node, raw });\n };\n\n const walk = (node: any, parentCursor: string): void => {\n if (scanned >= options.max_scan) return;\n scanned++;\n const tag = String(node.tagName || \"\").toLowerCase();\n if (SKIP_TAGS.indexOf(tag) !== -1) return;\n\n let style: any = null;\n try {\n style = g.getComputedStyle(node);\n } catch {\n style = null;\n }\n const cursor = style ? String(style.cursor || \"\") : parentCursor;\n\n consider(node, tag, style, cursor, parentCursor);\n\n // Nothing inside a `display: none` subtree can be seen, let alone clicked.\n if (style && style.display === \"none\") return;\n const children = node.children;\n if (!children) return;\n for (let i = 0; i < children.length; i++) walk(children[i], cursor);\n };\n\n for (const root of roots) {\n if (root) walk(root, \"\");\n }\n\n // Selectors are worked out last: they are only needed for the candidates\n // that survived, and each one costs a querySelectorAll to index.\n for (const entry of found) {\n const selector = selectorFor(entry.node);\n entry.raw.selector = selector;\n try {\n const matches = doc.querySelectorAll(selector);\n let index = -1;\n for (let i = 0; i < matches.length; i++) {\n if (matches[i] === entry.node) index = i;\n }\n if (index === -1) {\n entry.raw.match_index = 0;\n if (entry.raw.skip === undefined) entry.raw.skip = \"could not be addressed by a selector\";\n } else {\n entry.raw.match_index = index;\n }\n } catch {\n if (entry.raw.skip === undefined) entry.raw.skip = \"could not be addressed by a selector\";\n }\n }\n\n return found.map((entry) => entry.raw);\n}\n\n/**\n * The page-side watcher: a per-document id and a mutation counter.\n *\n * Head churn is skipped for the same reason the DOM layer skips it — every\n * CSS-in-JS library rewrites `<style>` elements continuously, and a click is\n * not what caused that.\n */\nconst clickWatcher = (config: { key: string; max_changes: number }): void => {\n const g = globalThis as any;\n const key = config.key;\n if (g[key] && g[key].installed) return;\n const state = {\n installed: true,\n // Identifies this document: a reload keeps the URL and replaces this.\n doc: `${Math.random()}`.slice(2) + \"-\" + Date.now(),\n watching: false,\n mutations: 0,\n changes: [] as string[],\n };\n g[key] = state;\n\n const doc = g.document;\n if (!doc || typeof g.MutationObserver !== \"function\") return;\n\n const desc = (node: any): string => {\n if (!node) return \"?\";\n if (node.nodeType === 3) return \"#text\";\n if (node.nodeType !== 1) return \"#node\";\n let out = String(node.tagName || \"?\").toLowerCase();\n if (node.id) out += \"#\" + String(node.id);\n else if (node.classList && node.classList.length) out += \".\" + String(node.classList[0]);\n return out.length > 48 ? out.slice(0, 48) + \"…\" : out;\n };\n\n const inHead = (node: any): boolean => {\n try {\n return Boolean(doc.head) && (node === doc.head || doc.head.contains(node) === true);\n } catch {\n return false;\n }\n };\n\n const note = (line: string): void => {\n if (state.changes.length < config.max_changes && state.changes.indexOf(line) === -1) state.changes.push(line);\n };\n\n try {\n new g.MutationObserver((records: any[]) => {\n for (const record of records) {\n const target = record.target;\n if (inHead(target)) continue;\n state.mutations++;\n if (record.type === \"childList\") {\n const added = record.addedNodes;\n const removed = record.removedNodes;\n if (added && added.length) note(\"+ \" + desc(added[0]) + \" in \" + desc(target));\n else if (removed && removed.length) note(\"- \" + desc(removed[0]) + \" from \" + desc(target));\n } else if (record.type === \"attributes\") {\n note(\"~ \" + desc(target) + \" [\" + String(record.attributeName || \"\") + \"]\");\n } else {\n note(\"~ text in \" + desc(target.parentNode || target));\n }\n }\n }).observe(doc, { subtree: true, childList: true, attributes: true, characterData: true });\n state.watching = true;\n } catch {\n // No observer: `elements` in the state reading is the fallback.\n }\n};\n\nfunction readState(options: { key: string; max_changes: number; max_text: number }): Omit<PageState, \"url\"> {\n const g = globalThis as any;\n const doc = g.document;\n const state = g[options.key] ?? {};\n\n // A 32-bit rolling hash. The values themselves are never wanted — only\n // whether they are the same as they were a moment ago — and a page can hold\n // megabytes of them.\n const hash = (text: string): number => {\n let value = 0;\n for (let i = 0; i < text.length; i++) value = (Math.imul(value, 31) + text.charCodeAt(i)) | 0;\n return value;\n };\n\n let fields = \"\";\n try {\n const nodes = doc.querySelectorAll(\"input, select, textarea\");\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n const type = String(node.type ?? \"\").toLowerCase();\n const value = type === \"checkbox\" || type === \"radio\" ? (node.checked ? \"1\" : \"0\") : String(node.value ?? \"\");\n fields += `${i}:${value};`;\n }\n } catch {\n fields = \"?\";\n }\n\n let storage = \"\";\n try {\n for (const store of [g.localStorage, g.sessionStorage]) {\n if (!store) continue;\n for (let i = 0; i < store.length; i++) {\n const name = store.key(i);\n storage += `${name}=${store.getItem(name)};`;\n }\n storage += \"|\";\n }\n } catch {\n // Storage can be disabled outright (a sandboxed frame, a strict setting).\n // A constant stands in: the signal is lost, not corrupted.\n storage = \"?\";\n }\n\n return {\n doc: String(state.doc ?? \"\"),\n watching: state.watching === true,\n mutations: Number(state.mutations ?? 0),\n changes: Array.isArray(state.changes) ? state.changes.slice(0, options.max_changes).map(String) : [],\n elements: doc ? doc.getElementsByTagName(\"*\").length : 0,\n fields: hash(fields),\n storage: hash(storage),\n scroll_x: Math.round(Number(g.scrollX ?? 0)),\n scroll_y: Math.round(Number(g.scrollY ?? 0)),\n title: String(doc?.title ?? \"\").slice(0, options.max_text),\n };\n}\n\nfunction readComputed(node: any, properties: string[]): Record<string, string> {\n const out: Record<string, string> = {};\n try {\n const style = (globalThis as any).getComputedStyle(node);\n for (const property of properties) out[property] = String(style[property] ?? \"\");\n out.cursor = String(style.cursor ?? \"\");\n } catch {\n // A detached node has no computed style; every property reads as empty,\n // which compares equal to itself and reports no hover feedback.\n }\n return out;\n}\n\n/* ── Helpers ──────────────────────────────────────────────────────────── */\n\n/**\n * Two URLs that differ only by an empty fragment are the same place.\n *\n * `<a href=\"#\">` is the canonical dead link, and clicking one appends a bare\n * `#` to the address bar. Counting that as a navigation would report every\n * dead link in the world as working.\n */\nexport function sameUrl(a: string, b: string): boolean {\n return stripEmptyHash(a) === stripEmptyHash(b);\n}\n\nfunction stripEmptyHash(url: string): string {\n return url.endsWith(\"#\") ? url.slice(0, -1) : url;\n}\n\nfunction describeChanges(changes: string[]): string {\n if (changes.length === 0) return \"\";\n const shown = changes.slice(0, MAX_DEAD_CLICK_CHANGES);\n const rest = changes.length - shown.length;\n return ` (${shown.join(\"; \")}${rest > 0 ? `; and ${rest} more` : \"\"})`;\n}\n\nfunction count(n: number, singular: string, plural: string): string {\n return `${n} ${n === 1 ? singular : plural}`;\n}\n\nfunction safely<T>(read: () => T): T | undefined {\n try {\n return read();\n } catch {\n return undefined;\n }\n}\n\nfunction firstLine(error: unknown): string {\n return (error instanceof Error ? error.message : String(error)).split(\"\\n\")[0];\n}\n"]}
@@ -0,0 +1,137 @@
1
+ import type { ElementHandle, Page } from "playwright";
2
+ import { type FieldShape, type FormStrategy, type OptionInfo } from "../utils/test-data.js";
3
+ /** How a field is filled. */
4
+ export type FieldKind = "text" | "choice" | "toggle";
5
+ export interface FieldInfo extends FieldShape {
6
+ tag: string;
7
+ kind: FieldKind;
8
+ required: boolean;
9
+ options?: OptionInfo[];
10
+ /** How the field is named in the report — `#email`, `[name="plan"]`, `input[type=text]`. */
11
+ description: string;
12
+ }
13
+ export interface DiscoveredField {
14
+ info: FieldInfo;
15
+ handle: ElementHandle;
16
+ }
17
+ /** A field that was not filled, and why. */
18
+ export interface FieldProblem {
19
+ description: string;
20
+ reason: string;
21
+ }
22
+ export interface DiscoveredForm {
23
+ /** 1-based position among the forms found on the page. */
24
+ index: number;
25
+ description: string;
26
+ /** False when this is not a real `<form>` — see `discoverForms`. */
27
+ is_form: boolean;
28
+ /** Fillable fields found, before `max_fields` trimmed the list. */
29
+ total_fields: number;
30
+ fields: DiscoveredField[];
31
+ /** Fields that exist but cannot be filled (hidden, disabled, read-only, file). */
32
+ skipped: FieldProblem[];
33
+ root: ElementHandle;
34
+ page: Page;
35
+ }
36
+ export interface DiscoverOptions {
37
+ /** CSS selector for one form, or for a container to treat as one. Defaults to every `<form>` on the page. */
38
+ selector?: string;
39
+ max_fields?: number;
40
+ }
41
+ /**
42
+ * Find the forms on a page.
43
+ *
44
+ * With a `selector`, whatever it matches is the form — a `<form>` element or
45
+ * any container, since the fields are looked for underneath it either way.
46
+ * Without one, every `<form>` on the page is returned in document order.
47
+ *
48
+ * A page with no `<form>` element at all is not a page without a form: React,
49
+ * Vue and Svelte apps routinely put inputs and a button in a `<div>` and wire
50
+ * the submit up in JavaScript. So when there is no form, the page itself is
51
+ * treated as one (`is_form: false`), and everything works as it does for a
52
+ * real form except that Enter cannot be used to submit it.
53
+ */
54
+ export declare function discoverForms(page: Page, options?: DiscoverOptions): Promise<DiscoveredForm[]>;
55
+ /**
56
+ * Fill every field of `form` according to `strategy`.
57
+ *
58
+ * A field that will not take its value is recorded and the rest are still
59
+ * filled: a form where one field is locked is a finding about that field, and
60
+ * abandoning the other twenty would throw away the run that found it.
61
+ */
62
+ export declare function fillForm(form: DiscoveredForm, strategy: FormStrategy, options?: {
63
+ timeout_ms?: number;
64
+ }): Promise<FillResult>;
65
+ export interface FilledField {
66
+ description: string;
67
+ kind: FieldKind;
68
+ /** What the strategy asked for, elided for the report. */
69
+ requested: string;
70
+ requested_length: number;
71
+ /** What the field actually holds now, elided for the report. */
72
+ landed: string;
73
+ landed_length: number;
74
+ /** True when the page kept less than it was given — a limit nothing declared. */
75
+ truncated: boolean;
76
+ /** For checkboxes and radios. */
77
+ checked?: boolean;
78
+ }
79
+ export interface FillResult {
80
+ filled: FilledField[];
81
+ failed: FieldProblem[];
82
+ /** Fields this strategy deliberately left alone, with the reason. */
83
+ skipped: FieldProblem[];
84
+ }
85
+ export interface SubmitResult {
86
+ ok: boolean;
87
+ /** What was done — `clicked "#submit"`, `pressed Enter in "#q"`. */
88
+ how: string;
89
+ /** Why nothing was done, when `ok` is false. */
90
+ reason?: string;
91
+ }
92
+ /**
93
+ * Send the form the way a person would.
94
+ *
95
+ * A real submit control comes first, then a button whose text says what it
96
+ * does, then Enter in a text field — which is how a search box with no button
97
+ * is submitted, and the only route left when the markup names nothing. A form
98
+ * that offers none of those is reported rather than forced: calling
99
+ * `form.submit()` from script would skip the page's own submit handler and
100
+ * validation, which is the thing under test.
101
+ */
102
+ export declare function submitForm(form: DiscoveredForm, options?: {
103
+ timeout_ms?: number;
104
+ }): Promise<SubmitResult>;
105
+ export interface ValidationSnapshot {
106
+ /** The browser's own constraint validation, per field that fails it. */
107
+ browser: Array<{
108
+ field: string;
109
+ message: string;
110
+ }>;
111
+ /** Messages visible on the page — the app's own validation, plus any alert or toast. */
112
+ messages: string[];
113
+ /** Fields the page marked `aria-invalid`. */
114
+ invalid: string[];
115
+ }
116
+ /**
117
+ * What the page says about the state it is in.
118
+ *
119
+ * Two independent sources, because apps use one, the other or both: the
120
+ * browser's constraint validation (`required`, `type=email`, `min`), which is
121
+ * true whether or not the app ever shows it, and the text actually visible on
122
+ * screen, which is what a user would see. Neither is meaningful alone —
123
+ * constraint validation on a form with `novalidate` never reaches the user,
124
+ * and visible text tells you nothing about which field it belongs to.
125
+ */
126
+ export declare function readValidation(page: Page, form: DiscoveredForm): Promise<ValidationSnapshot>;
127
+ /** Messages that were not on the page before — the ones this strategy caused. */
128
+ export declare function newMessages(before: ValidationSnapshot, after: ValidationSnapshot): string[];
129
+ /**
130
+ * Whether an XSS payload has executed on this page (see `XSS_MARKER`).
131
+ *
132
+ * Reading a marker the payload itself sets is the only honest answer to "did
133
+ * my input run as code". Looking for the payload in the DOM afterwards is not:
134
+ * an input's `value` serialises with its angle brackets intact, so a page that
135
+ * escaped everything perfectly would still look like a hit.
136
+ */
137
+ export declare function readXssMarker(page: Page): Promise<boolean>;