Skip to content

feat(browserstack-service): stamp hook_run_uuid on App A11y scans fired inside hooks [APPA11Y-5542]#48

Open
AakashHotchandani wants to merge 3 commits into
mainfrom
APPA11Y-5542-hook-scans-main
Open

feat(browserstack-service): stamp hook_run_uuid on App A11y scans fired inside hooks [APPA11Y-5542]#48
AakashHotchandani wants to merge 3 commits into
mainfrom
APPA11Y-5542-hook-scans-main

Conversation

@AakashHotchandani

Copy link
Copy Markdown
Collaborator

What

App A11y scans fired inside test hooks (before/after, beforeEach/afterEach) are dropped or misattributed today. This makes the SDK stamp the hook's run UUID (thHookRunUuid) on scans fired inside a supported hook.

How

  • util.ts_getParamsForAppAccessibility(commandName, testName, hookRunUuid?) adds thHookRunUuid (dropped by JSON.stringify when undefined, so in-test scans are byte-for-byte unchanged); performA11yScan(…, hookRunUuid?) threads it.
  • insights-handler.ts — expose getCurrentHook() so a11y reuses the same UUID reported to TestHub as HookRunStarted (= the hook's BTCER uuid).
  • accessibility-handler.tsbeforeHook/afterHook set _currentHookRunUuid for the hook window and, for mocha, enable the scan gate during hooks (per-test hooks honour include/exclude scope; suite hooks use autoScanning); commandWrapper passes the hook uuid into performA11yScan.
  • service.ts — wire accessibilityHandler.beforeHook/afterHook, passing the shared hook uuid.

Backend contract

SeleniumHub appAllyHandler (PR #14162, APPA11Y-5542-hook-run-uuid) destructures thHookRunUuid and relays it as hook_run_uuid; app-accessibility reconciles the scan onto the wrapping test via the BTCER self-join. Additive at every hop — no field ⇒ unchanged in-test behaviour.

Scope

Gated on frameworkSupportsHook (mocha before/after/beforeEach/afterEach; cucumber uuid-stamped, its scan gate stays owned by beforeScenario).

Tests

Added hook-scan unit tests (stamp/clear + unsupported-framework no-op). Note: local tsc couldn't fully run against a v8 node_modules on the v9 main base — CI validates on v9 deps.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

🤖 Generated with Claude Code

…ed inside hooks [APPA11Y-5542]

App A11y scans fired inside test hooks (before/after, beforeEach/afterEach) were
dropped or misattributed. The SDK now stamps the hook's run UUID (thHookRunUuid)
on scans fired inside a supported hook, so SeleniumHub (appAllyHandler, PR #14162)
relays it as hook_run_uuid and app-accessibility reconciles the scan onto the
wrapping test case. Additive: in-test scans are unchanged (field dropped when absent).

- util: _getParamsForAppAccessibility / performA11yScan thread optional hookRunUuid (thHookRunUuid)
- insights-handler: expose getCurrentHook() so a11y reuses the HookRunStarted uuid (= hook BTCER uuid)
- accessibility-handler: beforeHook/afterHook set _currentHookRunUuid + enable the scan gate during
  mocha hook windows (per-test hooks honour include/exclude scope; suite hooks use autoScanning)
- service: wire accessibilityHandler.beforeHook/afterHook, passing the shared hook uuid
- tests: cover hook-uuid stamp/clear + unsupported-framework no-op

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
AakashHotchandani and others added 2 commits July 16, 2026 10:32
… change [APPA11Y-5542]

- afterHook: drop unused params (no-unused-vars) — it only resets the hook-uuid stamp
- beforeHook: add `@ts-expect-error fix type` on the shouldScanTestForAccessibility call,
  matching the existing beforeTest call (v9 types the 3rd arg as { [key: string]: string })

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…the v9 CLI runtime path [APPA11Y-5542]

The earlier commits fixed accessibility-handler.ts (the classic/non-CLI
path), but v9 App Automate runs through the CLI observer runtime
(cli/modules/accessibilityModule.ts), where the hook-scan change was
inert. This ports the same contract into the active v9 path.

- Register hook-lifecycle observers (BEFORE_ALL / BEFORE_EACH /
  AFTER_EACH / AFTER_ALL, PRE + POST). PRE (onHookStart) captures the
  hook's run uuid from KEY_HOOK_ID — the same uuid reported to TestHub
  as the hook run — and opens the scan gate for the hook window so
  DOM-changing commands inside hooks trigger scans. POST (onHookEnd)
  clears the uuid so subsequent test-body scans are not mis-stamped.
- Thread currentHookRunUuid through every scan entry point: the web
  per-command commandWrapper and both manual performScan() patches, into
  performScanCli(..., hookRunUuid) -> _getParamsForAppAccessibility,
  which emits thHookRunUuid (dropped when undefined, so in-test and
  lifecycle scans are unchanged). Matches SeleniumHub #14162 appAllyScan
  -> hook_run_uuid.
- Add 6 unit tests for the hook-scan logic in the CLI module.

Verified end-to-end on real BrowserStack sessions (web + Android App
Automate): scans fired inside before/beforeEach/afterEach carry the
correct per-hook uuid; test-body and end-of-test lifecycle scans carry
none.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@AakashHotchandani

Copy link
Copy Markdown
Collaborator Author

Follow-up: ported the change into the active v9 CLI runtime path

The initial commits changed accessibility-handler.ts (the classic/non-CLI path). While validating against a real v9 App Automate session I found that path is inert in the v9 CLI runtime — v9 routes accessibility through the CLI observer modules (cli/modules/accessibilityModule.ts), so the hook-scan behaviour never actually engaged there. This latest commit (62c6f6e) ports the identical contract into the CLI module. (The handler changes are retained; they cover the non-CLI path and are additive.)

What the CLI-path change does

  • Registers hook-lifecycle observers (BEFORE_ALL/BEFORE_EACH/AFTER_EACH/AFTER_ALL, PRE+POST). PRE captures the hook's run uuid from KEY_HOOK_ID (the same uuid reported to TestHub as the hook run) and opens the scan gate for the hook window; POST clears it so test-body scans stay unstamped.
  • Threads currentHookRunUuid through the web per-command commandWrapper and both manual performScan() patches → performScanCli(…, hookRunUuid)_getParamsForAppAccessibilitythHookRunUuid (dropped when undefined, so in-test / end-of-test scans are unchanged). Matches SeleniumHub #14162 appAllyScanhook_run_uuid.
  • Adds 6 unit tests for the CLI-module hook logic.

Verified end-to-end on real BrowserStack sessions (file-write probe, since removed):

  • Web (Chrome): 5 hook windows detected; each url scan fired inside before/beforeEach/afterEach carried that hook's uuid; test-body click/url scans carried null.
  • Android App Automate (Appium): a performScan() called inside each hook fired performScanCli (app branch) with the matching hook uuid → thHookRunUuid in the payload; test-body and end-of-test lifecycle scans carried none.

Scope note for reviewers (App Automate per-command): the v9 CLI deliberately does not install per-command overwriteCommand wrapping for app sessions (appium drivers don't register those commands; it would throw and abort onBeforeExecute) — app scans run via the lifecycle/performScan path. So on the CLI path a hook-time app scan is stamped when it comes from a performScan() (or the lifecycle scan while a hook window is open), not from automatic per-command wrapping. The v8/handler path (which wraps every command) covers automatic per-command app hook scans. If we want automatic per-command app scanning on the CLI path too, that's a separate, larger change (re-enabling app command wrapping with per-command try/catch) and I'd raise it separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant