# ADR-0004: Accessibility Node Backend DOM ID Field

## Status

Accepted (v0.2.6 bug fix)

## Context

Accessibility tree nodes contain references to DOM nodes. The CDP specification defines this field as `backendDOMNodeId`:

```json
{
  "nodeId": 42,
  "ignored": false,
  "role": {"type": "button"},
  "name": {"type": "value", "value": "Submit"},
  "backendDOMNodeId": 123  // Note the full name
}
```

Several naming conventions exist:
- `backendNodeId` — Shortened version (incorrect)
- `backend_node_id` — Python convention (incorrect)
- `backendDOMNodeId` — CDP specification (correct)

## Decision

Always use `backendDOMNodeId` exactly as defined in CDP:

```python
# CORRECT: Full field name from CDP
async def _resolve_node(self, node: dict) -> Optional[str]:
    backend_node_id = node.get("backendDOMNodeId")  # Correct
    if backend_node_id is None:
        return None
    
    result = await self._send_cdp("DOM.resolveNode", {
        "backendNodeId": backend_node_id,  # DOM.resolveNode uses 'backendNodeId'
    })
    return result["objectId"]
```

**Note:** `DOM.resolveNode` uses `backendNodeId`, but the accessibility node uses `backendDOMNodeId`.

## Consequences

### Positive

- **Correct field access** — Matches CDP specification
- **Consistent with docs** — CDP docs use full name

### Negative

- **Inconsistent naming** — Different CDP methods use different names:
  - Accessibility node: `backendDOMNodeId`
  - DOM.resolveNode: `backendNodeId`
- **Easy to typo** — Similar names cause confusion

## Examples

### Before (v0.2.5 — Wrong)

```python
# WRONG: Field does not exist
backend_node_id = node.get("backend_node_id")  # None
backend_node_id = node.get("backendNodeId")    # None

# Result: objectId always None, click/type fail
```

### After (v0.2.6 — Correct)

```python
# CORRECT: Full field name
backend_node_id = node.get("backendDOMNodeId")  # 123

# DOM.resolveNode uses 'backendNodeId' (different!)
result = await self._send_cdp("DOM.resolveNode", {
    "backendNodeId": backend_node_id,
})
```

### CDP Naming Inconsistencies

| Method/Field | Correct Name |
|--------------|--------------|
| Accessibility node | `backendDOMNodeId` |
| DOM.resolveNode param | `backendNodeId` |
| DOM.describeNode result | `backendNodeId` |
| DOM.pushNodesByBackendIdsToFrontend | `backendNodeIds` |

This naming is inconsistent in CDP itself. Always check the specification.

## Affected Locations (v0.2.5 → v0.2.6)

| File | Line | Fix |
|------|------|-----|
| `browser.py` | `_resolve_node()` | `backendNodeId` → `backendDOMNodeId` |
| `browser.py` | `_find_nodes()` | `backendNodeId` → `backendDOMNodeId` |
| `browser.py` | `click()` | Same fix |
| `browser.py` | `type_text()` | Same fix |

## References

- [CDP Accessibility.Node](https://chromedevtools.github.io/devtools-protocol/tot/Accessibility/#type-Node)
- [CDP DOM.resolveNode](https://chromedevtools.github.io/devtools-protocol/tot/DOM/#method-resolveNode)
- [Changelog — v0.2.6](../changelog.md)