Skip to content

fix(runner): resolve FrameSurface by type so axe-core runs - #15

Merged
tom-sapletta-com merged 2 commits into
mainfrom
fix/axe-frame-detection
Oct 18, 2026
Merged

tom-sapletta-com merged 2 commits into
mainfrom
fix/axe-frame-detection

Conversation

@tom-sapletta-com

Copy link
Copy Markdown
Contributor

Problem: testwins/runner.py used hasattr(page, 'frame') to tell a FrameSurface (testwins/frames.py) apart from an ordinary page. Playwright's Page also has frame() (a method), so the condition was always true:

  • axe: await page.frame.evaluate(axe_code) failed on a method. Every observation ended with required_detector_failed ("axe-core did not complete"), and every audit with axe enabled was incomplete (exit code 2). This is likely why projects disable axe (for example axe: {enabled: false} in www-heyasa-com).
  • url assertions: on an ordinary page they took the FrameSurface branch (page.frame.wait_for_url).

Fix: a _surface(page) helper plus isinstance(page, FrameSurface) in both places.

Tests:

  • tests/test_runner_surface.py (written first): a plain page vs a FrameSurface.
  • Full suite: 442 passed.
  • End to end, an audit of paxlet-com/www-heyasa-com (6 routes × 3 devices, 2 journeys):
Before After
axe 0/60 observations 60/60
Scope gaps 60× required_detector_failed none
Gate incomplete passed (exit 0)
  • With axe working, real scrollable-region-focusable findings appeared on the site and were fixed there.

Process: the implementation is a willman → koru.develop_ticket patch (PLF-TW-axe, zai/glm-5.3), verified in staging. The repo has no project/new-ticket.sh, so this is an ordinary branch and PR.

🤖 Generated with Claude Code

tom-sapletta-com and others added 2 commits October 18, 2026 16:08
Regression test: Playwright's Page has a frame() method, so the runner's
hasattr(page, 'frame') check mistook every ordinary page for a
FrameSurface. Fails until runner.py resolves surfaces by type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Playwright's Page has a frame() method, so hasattr(page, 'frame') was
always true: the runner called page.frame.evaluate(axe_code) on a bound
method and every observation reported "axe-core did not complete"; url
assertions on ordinary pages took the FrameSurface branch too. _surface()
and isinstance(page, FrameSurface) replace both checks.

Patch produced by willman -> koru.develop_ticket (PLF-TW-axe,
zai/glm-5.3) and verified in staging. Suite: 442 passed. End to end on a
www-heyasa-com audit: axe ran in 60/60 observations, cells complete,
gate passed (previously incomplete: required_detector_failed x60).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tom-sapletta-com

Copy link
Copy Markdown
Contributor Author

The red unit job fails in tools/verify_testql.py (task shell-smoke: 1 of 3 steps fails with the testql backend). The same job also fails on main (a20967f and 3c06c7e), because CI installs testql from the moving TESTQL_REF=main. It isn't caused by this PR. The pytest suite (-m 'not browser') passes locally: 442 passed.

@tom-sapletta-com
tom-sapletta-com merged commit ccd4673 into main Oct 18, 2026
4 of 6 checks passed
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