Skip to content

Vpat fixes - #15

Closed
luckylionheart wants to merge 10 commits into
mpds-io:refactor-vanilla-es-modulesfrom
tilde-lab:vpat_fixes
Closed

luckylionheart wants to merge 10 commits into
mpds-io:refactor-vanilla-es-modulesfrom
tilde-lab:vpat_fixes

Conversation

@luckylionheart

Copy link
Copy Markdown
Contributor

No description provided.

claude and others added 10 commits October 25, 2026 15:42
…ne panel only

- search.js open_sim_col(): the port scoped the property-name selectors to
  #sim_col ('#sim_col tr.busy_entry > td.c2'), but the selected busy_entry
  row/thumbnail is in the results, never in #sim_col. null.textContent
  threw inside the async function (an unhandled rejection), after the
  preloader was hidden and before anything was rendered: "See also" stayed
  empty for every property (P) entry, in the table and thumbnail views.
  Master's global selectors are restored, null-safe like jQuery's .text().
- events.js ESC: master's $('div.cross:visible').trigger('click') clicks
  EVERY visible cross; the port clicked only the first, so e.g. with an
  entry selected, the advanced search and the numeric box open, ESC left
  three panels open. All visible crosses are clicked again.
- New scenarios (tags context, sim, keyboard): sim_col_property_entry,
  sim_col_property_entry_thumbs, esc_closes_entry_columns,
  esc_closes_all_visible_panels, with absolute expectations. Against the
  unfixed code the first three fail (empty column + the unhandled
  rejection) and the last leaves 3 crosses visible.
- AGENTS.md: two migration traps (jQuery null-safety vs DOM throws in async
  code; jQuery set operations vs picking the first element).
…i fallback

- deploy/dev_api_proxy.py: redirects are no longer followed. An anonymous
  /download/p?...&fmt=pdf is a 302 to https://mpds.io/#junction; followed
  by urllib, the proxy served the mpds.io page (fragment lost) as the API
  response, its relative assets resolving to localhost:7070: broken HTML.
  Now the 3xx goes to the browser with its Location (rewritten to the proxy
  when it points back into the API), and the cache keeps the Location of a
  redirect (an extra header line for 3xx records only; older cache files
  read unchanged). fetch_remote() / local_location() are shared with the
  parity runner, whose request interception had the same problem.
- parity/run_parity.py: the playwright driver is the default and never
  falls back to chrome-cli by itself (that produced "FileNotFoundError:
  'google-chrome'" when pip had installed playwright for another
  interpreter). A missing playwright or a missing Playwright Chromium stops
  the run with the exact install commands for sys.executable;
  --driver chrome-cli finds Chrome/Chromium in PATH or /Applications.
  The storage-preset init script runs only in the GUI's own documents (it
  threw "localStorage ... Access is denied" pageerrors in opaque frames).
- README.md, parity/README.md: install with the same python3 that runs the
  suite, playwright pinned to 1.50.0.

Full run: 244 scenarios, PASS 240, XFAIL 4 (the approved numeric changes).
…rtial reports)

- Every Playwright side runs in a worker process with its own process group,
  streaming progress (launch, load, each step, each live API request,
  capture). No progress for --stall-timeout s (default 90, env
  PARITY_STALL_TIMEOUT) or more than --side-timeout s (default 600) kills
  the group (SIGTERM first, so Playwright's node driver also kills the
  browser, which lives in a group of its own; SIGKILL after 5 s). The
  scenario becomes ERROR "SideFrozen: <SIDE> side froze ..., last activity:
  <what>", the next one gets a fresh worker; 3 frozen scenarios in a row
  stop the run (a broken environment). --stall-timeout 0 runs in-process.
- Heartbeat lines every 15 s name the scenario, side and current activity,
  so a slow API is told apart from a freeze; stdout is line-buffered even
  when piped.
- Bounded inner waits: pending requests are awaited at most 60 s per side
  in total (it was up to 30 s at EVERY 50 ms virtual-time chunk), default
  Playwright timeouts are set, the browser is closed after the result is
  sent (a browser that does not close costs a worker, not the result), and
  the build has a 300 s timeout.
- report.json is rewritten after every scenario ("complete": false until
  the end); Ctrl-C kills the browsers at once, prints the partial summary
  and exits with 130.

Verified: an endless JS loop and a never-settling page call each end as
ERROR after the stall timeout with the run continuing; 3 in a row abort;
Ctrl-C exits at once with a partial report; no orphaned browsers. Full run:
244 scenarios, PASS 240, XFAIL 4, 556 s.
- parity/scenarios.json: the 244 scenarios as a bare list of objects;
  parity/config.json: {"defaults": {...}, "fixtures": [...]}. Converted
  mechanically from scenarios.toml (removed); the old TOML loader and the
  new JSON loader yield identical expanded scenarios and fixtures.
- JSON has no comments: an optional "comment" (string or list of strings)
  is allowed on any object and ignored; the TOML comments are kept that way,
  section banners as "comment": "section: ...".
- run_parity.py: no tomllib dependency any more (any Python 3); --config for
  an alternative config.json; the linter reports JSON syntax errors with
  line and column, duplicate keys (json would silently keep the last one,
  where TOML rejected them) and non-object entries.
- Docs (parity/README.md, README.md, AGENTS.md, harness.js) and the CI
  cache key follow; every JSON example in the README parses and lints.

Full run: 244 scenarios, PASS 240, XFAIL 4.
The fork's Actions default to a read-only GITHUB_TOKEN, so the
JamesIves deploy step failed with 'Permission denied to
github-actions[bot]' (403).
…e changes, a11y audit

- The OLD side now loads the stylesheet of the pinned gh-pages commit
  (OLD_CSS_URL / OLD_CSS_SHA1, --reference-css-url / --reference-css-sha1),
  url()s rewritten to webassets/. Before, both sides used the working
  tree's CSS, so a CSS change could never show up as a diff.
- ignore_attributes (default: role, tabindex, aria-*, inert, data-a11y-*)
  strips the accessibility markup from the DOM and probe values before the
  OLD-vs-NEW comparison; expect / expect_new still see the raw values.
- "approved": "<reason>" + expect_new: an approved change confined to the
  pinned probes (e.g. focus); those are not compared, every other layer
  is, and the scenario passes or fails normally. A whole-scenario xfail
  tolerates every layer and would hide unrelated regressions.
- harness.js: window.__a11y(), an audit of mouse-only controls, the Tab
  order, Tab stops outside an open dialog and controls a zoomed viewport
  cuts off.
…4.4)

WCAG 2.1.1 Keyboard:
- core/a11y.js: a declarative registry (A11Y_CONTROLS) gives the clickable
  div/span/li controls a role, label, state (aria-pressed/-selected/
  -checked/-expanded/-sort from the existing classes) and a Tab stop; a
  MutationObserver re-applies it to rendered content. Enter/Space call the
  element's click(), so the existing handlers serve the keyboard.
- Arrow keys in the periodic table (grid), the results, the galleries, the
  tab lists and the VIEW switches (roving tabindex).
- Dialogs: the page behind is inert (except the overlay, notifications,
  the sliders box, #userbox above the overlay, the body-level autocomplete
  suggestions, tooltips, the preloader); the dialog takes the focus and
  returns it to the opener on close; the sliders box returns it to its
  numeric control. wmgui.open_dialog() / wmgui.release_dialog() expose it.
- Entry columns: Enter on a row moves the focus into them, closing returns
  it to the row. A "Skip to content" button (hash routing: not a link),
  landmarks, labels on dialogs, buttons and slider handles; focus rings
  with :focus-visible only.

WCAG 1.4.4 Resize Text (150% and 200% of 1280x800):
- The periodic table and the hierarchy dialog are clamped to the window
  instead of a negative margin-left; the fixed side columns and the fixed
  dialogs scroll instead of cutting content off; at narrow widths the
  search area, grid columns, column titles and See also links make room;
  the hierarchy's vh line heights get an em floor.

Parity: 27 a11y scenarios (audits, zoom audits, keyboard contracts; xfail
against the deployed GUI, pinned by expect_new), a mouse-click autocomplete
scenario, and 48 scenarios whose only difference is the now focusable
clicked control, marked "approved" with the expected focus.
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.

3 participants