UI Test Writer
Use this skill to write PR-stable UI tests for WikipediaUITests with minimal boilerplate in each test file.
Required context to load first
- Read these repository docs before writing code:
WikipediaUITests/README.md
WikipediaUITests/ROBOTS.md
- Inspect nearby examples before choosing a pattern:
- Existing test files in
WikipediaUITests/*UITests.swift
- Existing robots in
WikipediaUITests/Robots
- Configuration for UI test runs:
WikipediaUITests/Config/UITestConfiguration.swift
WikipediaUITests/Config/UITestLaunchArgument.swift
Core rules
- Write test methods using the Robots pattern documented in
WikipediaUITests/ROBOTS.md
- Keep raw
XCUIApplication selectors, waits, gestures, screenshots, scrolling, modal handling, and timing details inside robots.
- Prefer one robot per screen or cohesive flow.
- Return the next robot when an action navigates to another screen.
- Use
launchWikipediaAppRobot(...) instead of hand-rolling app launch setup.
- Centralize launch state in
UITestConfiguration and UITestLaunchArgument; do not set theme, language, onboarding, locale, HTTP profile, or simulator appearance ad hoc in individual tests.
- Default to fixture-backed coverage with
fixture-strict; use live networking when E2E is specified.
- Prefer shared accessibility identifiers from
AccessibilityIdentifiers.swift over localized visible text.
- STRONGLY prefer targeting elements based their accessibility identifier.
- Assert localized strings only when localization is the behavior under test.
- NEVER
XCTSkipUnless / XCTSkipIf unless specifically directed to do so.
- Forward
file: StaticString = #filePath and line: UInt = #line through robot assertions so failures point to the calling test.
Minimal test skeleton
When creating a new test file, start from the packaged template:
The skeleton intentionally relies on launchWikipediaAppRobot and existing robots so each new test needs only:
- A specific test class name.
- The short robot journey.
- Small helper methods only when they remove repeated journey setup.
If the journey needs new screen mechanics, add or extend a robot instead of adding selectors to the test. Use this companion template only when a new robot is needed:
Test Fixtures
Before writing a test, determine if appropriate fixture data is present. If not present, execute the following steps to build out new fixture data:
- Fixtures are captured from the live Wikipedia/MediaWiki APIs, not synthesized.
- Reproduce the request the app makes, including the app's iOS
User-Agent, Accept, and Accept-Language headers, then save the exact response body under WikipediaUnitTests/Fixtures.
- Register the route in
WikipediaUnitTests/Fixtures/TestNetworkFixtures.json with the request matcher, status, response headers, and bodyResource.
- Keep payloads byte-for-byte aligned with the API response; when
fixture-strict mode hits an unregistered request, it returns a JSON 501 with the exact method and URL to add.
Workflow
- Clarify the user-visible behavior to cover, the expected result, and whether the scenario can run with fixture-backed networking.
- Choose where the test belongs:
- Existing
*UITests.swift file for related behavior.
- New
FeatureUITests.swift file only when the coverage is a distinct feature or flow.
- Adhere to established Robot testing pattern by following examples laid out by existing tests.
- Add accessibility identifiers to target UI elements
- Add constants to
AccessibilityIdentifiers.swift.
- Add
WMFAccessibilityIdentifier Objective-C bridge values if legacy Objective-C/UIKit code needs them.
- Wire app code to set the identifier.
- Add deterministic launch configuration only through
UITestConfiguration / UITestLaunchArgument.
- Validate narrowly:
scripts/lint-ui-tests.sh
- For local validation, prefer the latest installed iOS 26 simulator destination
- Targeted UI-test run, for example:
xcodebuild test \
-scheme WikipediaUITests \
-project Wikipedia.xcodeproj \
-testPlan UITests \
-only-test-configuration "English (Light)" \
-destination "platform=iOS Simulator,name=iPhone 16" \
-only-testing:WikipediaUITests/<ClassName>/<testName>
For E2E tests:
- run with
-only-test-configuration "English (Light, E2E)"
- add the test identifier to
WikipediaUITests/E2ESmokeTests.txt to include tests in the E2E smoke lane.
1---2name: ui-test-writer3description: UI Test Writer4---56# UI Test Writer78Use this skill to write PR-stable UI tests for `WikipediaUITests` with minimal boilerplate in each test file.910## Required context to load first11121. Read these repository docs before writing code:13 - `WikipediaUITests/README.md`14 - `WikipediaUITests/ROBOTS.md`152. Inspect nearby examples before choosing a pattern:16 - Existing test files in `WikipediaUITests/*UITests.swift`17 - Existing robots in `WikipediaUITests/Robots`18 - Configuration for UI test runs:19 - `WikipediaUITests/Config/UITestConfiguration.swift`20 - `WikipediaUITests/Config/UITestLaunchArgument.swift`2122## Core rules2324- Write test methods using the Robots pattern documented in `WikipediaUITests/ROBOTS.md`25- Keep raw `XCUIApplication` selectors, waits, gestures, screenshots, scrolling, modal handling, and timing details inside robots.26- Prefer one robot per screen or cohesive flow.27- Return the next robot when an action navigates to another screen.28- Use `launchWikipediaAppRobot(...)` instead of hand-rolling app launch setup.29- Centralize launch state in `UITestConfiguration` and `UITestLaunchArgument`; do not set theme, language, onboarding, locale, HTTP profile, or simulator appearance ad hoc in individual tests.30- Default to fixture-backed coverage with `fixture-strict`; use live networking when E2E is specified.31- Prefer shared accessibility identifiers from `AccessibilityIdentifiers.swift` over localized visible text.32- STRONGLY prefer targeting elements based their accessibility identifier.33- Assert localized strings only when localization is the behavior under test.34- NEVER `XCTSkipUnless` / `XCTSkipIf` unless specifically directed to do so.35- Forward `file: StaticString = #filePath` and `line: UInt = #line` through robot assertions so failures point to the calling test.3637## Minimal test skeleton3839When creating a new test file, start from the packaged template:4041- [UITestFileSkeleton.swift](templates/UITestFileSkeleton.swift)4243The skeleton intentionally relies on `launchWikipediaAppRobot` and existing robots so each new test needs only:44451. A specific test class name.462. The short robot journey.473. Small helper methods only when they remove repeated journey setup.4849If the journey needs new screen mechanics, add or extend a robot instead of adding selectors to the test. Use this companion template only when a new robot is needed:5051- [RobotSkeleton.swift](templates/RobotSkeleton.swift)5253## Test Fixtures5455Before writing a test, determine if appropriate fixture data is present. If not present, execute the following steps to build out new fixture data:561. Fixtures are captured from the live Wikipedia/MediaWiki APIs, not synthesized.572. Reproduce the request the app makes, including the app's iOS `User-Agent`, `Accept`, and `Accept-Language` headers, then save the exact response body under `WikipediaUnitTests/Fixtures`.583. Register the route in `WikipediaUnitTests/Fixtures/TestNetworkFixtures.json` with the request matcher, status, response headers, and `bodyResource`.594. Keep payloads byte-for-byte aligned with the API response; when `fixture-strict` mode hits an unregistered request, it returns a JSON 501 with the exact method and URL to add.606162## Workflow63641. Clarify the user-visible behavior to cover, the expected result, and whether the scenario can run with fixture-backed networking.652. Choose where the test belongs:66 - Existing `*UITests.swift` file for related behavior.67 - New `FeatureUITests.swift` file only when the coverage is a distinct feature or flow.683. Adhere to established Robot testing pattern by following examples laid out by existing tests.694. Add accessibility identifiers to target UI elements70 - Add constants to `AccessibilityIdentifiers.swift`.71 - Add `WMFAccessibilityIdentifier` Objective-C bridge values if legacy Objective-C/UIKit code needs them.72 - Wire app code to set the identifier.735. Add deterministic launch configuration only through `UITestConfiguration` / `UITestLaunchArgument`.746. Validate narrowly:75 - `scripts/lint-ui-tests.sh`76 - For local validation, prefer the latest installed iOS 26 simulator destination77 - Targeted UI-test run, for example:7879```sh80xcodebuild test \81 -scheme WikipediaUITests \82 -project Wikipedia.xcodeproj \83 -testPlan UITests \84 -only-test-configuration "English (Light)" \85 -destination "platform=iOS Simulator,name=iPhone 16" \86 -only-testing:WikipediaUITests/<ClassName>/<testName>87```8889For E2E tests:90- run with `-only-test-configuration "English (Light, E2E)"`91- add the test identifier to `WikipediaUITests/E2ESmokeTests.txt` to include tests in the E2E smoke lane.