Skip to content

BUG: Saved-run technique and objective dialogs do not restore opener focus #3915

Open

Description

@romanlutz

Describe the bug

Closing saved-run Techniques and Objectives detail dialogs does not return keyboard focus to the button that opened them. Both Close and Escape leave BODY focused, interrupting sequential keyboard inspection.

Related hierarchy PR #3611 is merged (2026-11-01). Its focus work concerns saved-result Details; this report concerns the separate read-only Techniques and Objectives dialogs. Filed separately as requested because that PR is no longer open. No competing hierarchy implementation is proposed.

Historical source: frontend/src/components/Scenarios/ScenarioRunPage.tsx:658-665,708-724,812-813 and ScenarioRunDialogs.tsx:22-34,79-91 at the tested revision.

Steps/Code to Reproduce

  1. Open a saved Scanner run containing multiple technique and objective detail buttons.
  2. Focus and open a Techniques detail button, then activate Close.
  3. Inspect document.activeElement and press Tab.
  4. Repeat with another technique, dismissing with Escape.
  5. Repeat Close/Escape for Objectives detail buttons.

The original fixture used a real local backend/private SQLite run plan, actual React UI and two fresh Chrome contexts. The saved plan was synthetic and had no executions. An assertion that the technique opener regained focus failed.

Expected Results

Restore focus to each still-mounted opening button after Close/Escape. Use a correctly associated Fluent DialogTrigger or per-dialog opening-element reference. Do not focus detached elements after navigation.

Cover both dialogs, multiple openers, keyboard activation, Close/Escape, reopening, and navigation/unmount safety. Preserve the existing read-only metadata behavior.

Actual Results

All four measured closures left BODY focused with triggerFocused=false. The next Tab focused the fixture's last objective instead of preserving the opener's inspection position.

No stored result changes, scan execution, or objective-text loss. Progress API content remained unchanged, and browser API traffic was GET-only.

Screenshots

Historical screenshots and exact active-element/network captures retained locally; no hosted attachment in this report.

Versions

Linux; headless installed Google Chrome, Playwright 1.64.1; PyRIT 1.2.0.dev0 at 01ce6ca66a315770b36c7dca1f320668c0d92d7c. Historical real browser/local backend reproduction, not a fresh latest-main retest. No screen reader, platform matrix, Azure, provider inference, or real attack execution. Full package-version output was not collected.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions