uttrflow / uttrflow/uttrflow-swift

SystemInput's accessibility writes are untested because its attribute calls have no seam

Open
#492 0 comments 0 reactions 0 assignees View on GitHub
area:dictation area:insertion enhancement P2
Dominant language
Swift
Stars
4
Forks
17
Avg merge
3h 32m
Merged PRs (30d)
277

Description

## What happens

`Sources/UttrflowInput/SystemInput.swift` is excluded from coverage because it "drives the clipboard, the keyboard and other apps' windows" (`Scripts/coverage_report.py:46`). #412 moved the range arithmetic out of it into `BackwardSelection`, which is tested, but the sequence around it is still untested:

- `replaceSelection(with:)` (lines 218-234) reads the value, writes the selected text, and treats "accepted but unchanged" as a failure;
- `replaceSelection(replacing:with:)` (lines 237-249) widens the selection backwards, writes, and puts the caret back if the write is refused;
- `selectBackwards(over:)` (lines 252-269) refuses when the text before the caret is not what would be replaced.

All of this calls `AXUIElementSetAttributeValue` and `AXUIElementCopyAttributeValue` directly on an `AXUIElement`, so a test would need a real window.

## Why it matters

This is where dictated text replaces text in another app. A mistake in the order of these steps can delete the user's words or leave a stray selection, and no test would notice.

## Acceptance criteria

- The accessibility attribute reads and writes used by these three functions go through a small internal protocol (value, selected range, set selected text, set selected range), with the `AXUIElement` implementation as the default.
- Tests with a fake field cover: a successful replace; a field that accepts and does not change (failure); a replace-over that restores the caret when the write is refused; and a refusal when the text before the caret changed.
- The real implementation remains excluded from coverage, with the seam's logic now covered.

Contributor guide

Open the contributing guide

Research direction

Start with Sources/UttrflowInput/SystemInput.swift, focusing on replaceSelection(with:), replaceSelection(replacing:with:), and selectBackwards(over:), then inspect Scripts/coverage_report.py:46. Introduce the requested internal seam and use fake fields to cover the four acceptance cases, while keeping the AXUIElement implementation excluded from coverage.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, swift
Domain
accessibility, desktop, testing-qa
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
70/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.