Always use TAB key for keyboard navigation instead of javascript focus()
This commit is contained in:
@@ -1,21 +1,25 @@
|
||||
# Real Keyboard Simulation for Focus Indicator Testing
|
||||
|
||||
**Date:** 2025-11-20
|
||||
**Status:** ✅ **IMPLEMENTED**
|
||||
**Date:** 2025-11-20
|
||||
**Updated:** 2025-12-09
|
||||
**Status:** ✅ **IMPLEMENTED** (Now the only method - legacy programmatic method removed)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
We've implemented real Tab key simulation for keyboard navigation testing to solve the `:focus-within` detection issue identified in `docs/FOCUS_INDICATORS_VALIDATION_SUCCESS.md`.
|
||||
Cremote **always uses real Tab key simulation** for keyboard navigation testing. The legacy programmatic `.focus()` method has been removed because it produces false negatives.
|
||||
|
||||
### The Problem
|
||||
|
||||
**Programmatic `.focus()` cannot trigger `:focus-within` on parent elements**, causing false negatives for dropdown menus and other elements that rely on CSS `:focus-within` pseudo-class to become visible.
|
||||
**Programmatic `.focus()` cannot trigger `:focus-within` or `:focus-visible` on elements**, causing false negatives for:
|
||||
- Dropdown menus that rely on CSS `:focus-within` pseudo-class
|
||||
- Modern focus indicators using `:focus-visible` pseudo-class
|
||||
- Accessibility plugins that inject universal focus styles
|
||||
|
||||
### The Solution
|
||||
|
||||
**Use real Tab key presses via Chrome DevTools Protocol** to simulate actual user keyboard navigation, which properly triggers all CSS pseudo-classes including `:focus-within`.
|
||||
**Always use real Tab key presses via Chrome DevTools Protocol** to simulate actual user keyboard navigation, which properly triggers all CSS pseudo-classes including `:focus-within` and `:focus-visible`.
|
||||
|
||||
---
|
||||
|
||||
@@ -47,35 +51,29 @@ Located in `daemon/daemon.go` (lines 10849-11148), this function:
|
||||
|
||||
### Client Function: `TestKeyboardNavigation()`
|
||||
|
||||
**Old signature:**
|
||||
```go
|
||||
func (c *Client) TestKeyboardNavigation(tabID string, timeout int) (*KeyboardTestResult, error)
|
||||
```
|
||||
|
||||
**New signature:**
|
||||
**Current signature:**
|
||||
```go
|
||||
func (c *Client) TestKeyboardNavigation(tabID string, useRealKeys bool, timeout int) (*KeyboardTestResult, error)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `tabID` - Tab ID (empty string uses current tab)
|
||||
- `useRealKeys` - `true` for real Tab simulation (recommended), `false` for legacy programmatic focus
|
||||
- `useRealKeys` - **Ignored** (always uses real Tab simulation for accuracy)
|
||||
- `timeout` - Timeout in seconds
|
||||
|
||||
**Note:** The `useRealKeys` parameter is maintained for backward compatibility but is ignored. All keyboard testing now uses real Tab key simulation.
|
||||
|
||||
### Client Function: `GetKeyboardAudit()`
|
||||
|
||||
**Old signature:**
|
||||
```go
|
||||
func (c *Client) GetKeyboardAudit(tabID string, checkFocusIndicators, checkTabOrder, checkKeyboardTraps bool, timeout int) (*KeyboardAuditResult, error)
|
||||
```
|
||||
|
||||
**New signature:**
|
||||
**Current signature:**
|
||||
```go
|
||||
func (c *Client) GetKeyboardAudit(tabID string, checkFocusIndicators, checkTabOrder, checkKeyboardTraps, useRealKeys bool, timeout int) (*KeyboardAuditResult, error)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `useRealKeys` - `true` for real Tab simulation (default), `false` for legacy method
|
||||
- `useRealKeys` - **Ignored** (always uses real Tab simulation for accuracy)
|
||||
|
||||
**Note:** The `useRealKeys` parameter is maintained for backward compatibility but is ignored.
|
||||
|
||||
---
|
||||
|
||||
@@ -83,15 +81,17 @@ func (c *Client) GetKeyboardAudit(tabID string, checkFocusIndicators, checkTabOr
|
||||
|
||||
### `web_keyboard_test_cremotemcp`
|
||||
|
||||
**New parameter:**
|
||||
- `use_real_keys` (boolean, default: `true`) - Use real Tab key simulation
|
||||
**Parameters:**
|
||||
- `tab` (string, optional) - Tab ID
|
||||
- `timeout` (integer, default: 15) - Timeout in seconds
|
||||
|
||||
**Note:** The `use_real_keys` parameter has been removed. Real Tab key simulation is always used.
|
||||
|
||||
**Example:**
|
||||
```json
|
||||
{
|
||||
"tool": "web_keyboard_test_cremotemcp",
|
||||
"arguments": {
|
||||
"use_real_keys": true,
|
||||
"timeout": 15
|
||||
}
|
||||
}
|
||||
@@ -99,8 +99,14 @@ func (c *Client) GetKeyboardAudit(tabID string, checkFocusIndicators, checkTabOr
|
||||
|
||||
### `web_keyboard_audit_cremotemcp`
|
||||
|
||||
**New parameter:**
|
||||
- `use_real_keys` (boolean, default: `true`) - Use real Tab key simulation
|
||||
**Parameters:**
|
||||
- `tab` (string, optional) - Tab ID
|
||||
- `check_focus_indicators` (boolean, default: true)
|
||||
- `check_tab_order` (boolean, default: true)
|
||||
- `check_keyboard_traps` (boolean, default: true)
|
||||
- `timeout` (integer, default: 15) - Timeout in seconds
|
||||
|
||||
**Note:** The `use_real_keys` parameter has been removed. Real Tab key simulation is always used.
|
||||
|
||||
**Example:**
|
||||
```json
|
||||
@@ -108,7 +114,6 @@ func (c *Client) GetKeyboardAudit(tabID string, checkFocusIndicators, checkTabOr
|
||||
"tool": "web_keyboard_audit_cremotemcp",
|
||||
"arguments": {
|
||||
"check_focus_indicators": true,
|
||||
"use_real_keys": true,
|
||||
"timeout": 15
|
||||
}
|
||||
}
|
||||
@@ -118,10 +123,13 @@ func (c *Client) GetKeyboardAudit(tabID string, checkFocusIndicators, checkTabOr
|
||||
|
||||
## Backward Compatibility
|
||||
|
||||
✅ **Fully backward compatible** with optional parameter:
|
||||
- Default behavior: Uses real Tab key simulation (`use_real_keys: true`)
|
||||
- Legacy behavior: Set `use_real_keys: false` to use programmatic `.focus()`
|
||||
- Existing code without the parameter will use the new, more accurate method
|
||||
⚠️ **Breaking Change (Simplified):**
|
||||
- The `use_real_keys` parameter has been removed from MCP tools
|
||||
- Client functions still accept the parameter for backward compatibility but ignore it
|
||||
- **All keyboard testing now uses real Tab key simulation** for accurate results
|
||||
- Legacy programmatic `.focus()` method has been removed
|
||||
|
||||
**Rationale:** The programmatic method produced false negatives for `:focus-visible` and `:focus-within`, making it unreliable for accessibility testing.
|
||||
|
||||
---
|
||||
|
||||
@@ -132,7 +140,6 @@ func (c *Client) GetKeyboardAudit(tabID string, checkFocusIndicators, checkTabOr
|
||||
{
|
||||
"tool": "web_keyboard_audit_cremotemcp",
|
||||
"arguments": {
|
||||
"use_real_keys": true,
|
||||
"check_focus_indicators": true
|
||||
}
|
||||
}
|
||||
@@ -143,7 +150,7 @@ func (c *Client) GetKeyboardAudit(tabID string, checkFocusIndicators, checkTabOr
|
||||
{
|
||||
"tool": "web_keyboard_test_cremotemcp",
|
||||
"arguments": {
|
||||
"use_real_keys": true
|
||||
"timeout": 15
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user