{"id":15679507,"url":"https://github.com/tunous/xcapptest","last_synced_at":"2025-04-30T08:20:44.282Z","repository":{"id":65253154,"uuid":"533409240","full_name":"Tunous/XCAppTest","owner":"Tunous","description":"Utilities for easier interaction with XCUITest methods","archived":false,"fork":false,"pushed_at":"2025-03-02T11:17:05.000Z","size":126,"stargazers_count":23,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-24T16:06:15.150Z","etag":null,"topics":["ios","testing","xctest","xcuitest"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Tunous.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-06T16:26:20.000Z","updated_at":"2025-03-02T11:17:08.000Z","dependencies_parsed_at":"2023-11-07T17:50:23.360Z","dependency_job_id":"dc4a05a2-284a-49f7-8577-1d41c4bfc407","html_url":"https://github.com/Tunous/XCAppTest","commit_stats":{"total_commits":24,"total_committers":1,"mean_commits":24.0,"dds":0.0,"last_synced_commit":"7e1bfe537dfb3cfc7bb25159db4d7609424353eb"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tunous%2FXCAppTest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tunous%2FXCAppTest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tunous%2FXCAppTest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tunous%2FXCAppTest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Tunous","download_url":"https://codeload.github.com/Tunous/XCAppTest/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251666634,"owners_count":21624344,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ios","testing","xctest","xcuitest"],"created_at":"2024-10-03T16:32:16.806Z","updated_at":"2025-04-30T08:20:44.263Z","avatar_url":"https://github.com/Tunous.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# XCAppTest\n\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FTunous%2FXCAppTest%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/Tunous/XCAppTest) [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FTunous%2FXCAppTest%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/Tunous/XCAppTest)\n\nUtilities for easier interaction with XCUITest methods.\n\n## What's included\n\n- `XCUIElement` extensions:\n    - Checking existence of elements:\n        - `assertExists()`\n        - `assertExists(waitForAppToIdle: true)`\n        - `assertNotExists()`\n        - `assertExists(false)`\n    - Checking interactivity of elements:\n        - `assertIsHittable()`\n        - `assertIsNotHittable()`\n        - `assertIsHittable(false)`\n        - `assertIsEnabled()`\n        - `assertIsDisabled()`\n        - `assertIsEnabled(false)`\n        - `assertIsInteractive()` (exists, isHittable, isEnabled)\n    - Checking properties of elements:\n        - `assertHasLabel(\"label\")`\n        - `assertContainsText(\"label\")`\n        - `assertHasValue(\"equatable value\")`\n        - `assertIsOn()`\n        - `assertIsOff()`\n        - `assertIsOn(false)`\n        - `assertHasPlaceholder(\"placeholder\")`\n        - `assertIsEmpty()` (value == placeholderValue)\n        - `assertHasTitle(\"title\")`\n        - `assertHasNonEmptyStringValue()`\n    - Checking traits of elements:\n        - `assertIsSelected()`\n        - `assertIsNotSelected()`\n        - `assertIsSelected(false)`\n    - Performing actions:\n        - `tapWhenReady()`\n        - `waitForInteractivity()`\n        - `slowTypeText(\"text\")`\n        - `tap(withNormalizedOffset: .center)`\n        - `drag(from: .top, to: .bottom, pressDuration: 1)`\n        - `press(forDuration: 1, withNormalizedOffset: .center)`\n        - `pressWhenReady(forDuration: 2)`\n        - `tapIfExists()`\n        - `tapCenter()`\n        - `deleteText()`\n        - `deleteText(3)`\n    - Accessing properties of elements:\n        - `stringValue`\n\n- `XCUIApplication` extensions:\n    - Accessing other apps:\n        - `XCUIApplication.safari`\n        - `XCUIApplication.springboard`\n        - `XCUIApplication.messages`\n        - `XCUIApplication.settings`\n    - Checking foreground state:\n        - `assertIsInForeground()`\n        - `assertIsNotInForeground()`\n        - `assertIsInForeground(false)`\n    - Performing actions:\n        - `moveToBackground()`\n\n- `XCUIElementQuery` extensions:\n    - Checking number of elements:\n        - `assertHasCount(2)`\n        - `assertNotExists()`\n        - `assertHasCount(2...5)`, `assertHasCount(..\u003c3)`\n        - `assertExists()`\n    - Accessing elements:\n        - `lastMatch`\n        - `self[2]`\n        - `first(where: { $0.label == \"a\" })`\n        - `bannerNotifications`\n    - Asserting elements:\n        - `assertMatchedElements(perform: { element in /*...*/ })`\n\n- `CGVector` extensions:\n    - Normalized offsets:\n        - `CGVector.topLeft`, `CGVector.top`, `CGVector.topRight`\n        - `CGVector.left`, `CGVector.center`, `CGVector.right`\n        - `CGVector.bottomLeft`, `CGVector.bottom`, `CGVector.bottomRight`\n        - `offset(x: 0.2, y: 0.5)`\n        \n- `XCUIElement.ElementType` extensions:\n    - `bannerNotification`\n    \n- `XCTestCase` extensions:\n    - `run { ... }`\n    - `run(\"Activity name\") { ... }`\n\nAll of the above assertion functions have optional message as last parameter that can be used to configure what is displayed if assertion fails. For example: `element.assertExists(\"My element should be visible\")`.\nAdditionally you can configure assertion timeout globally by modifying `XCAppTestConfig.defaultTimeout` or per call via `timeout` parameter. For example: `XCAppTestConfig.defaultTimeout = 3`, `element.assertExists(timeout: 3)`.\nFor details see [documentation](https://swiftpackageindex.com/Tunous/XCAppTest/main/documentation/xcapptest).\n\n## Example\n\nHere is a short example from one of my apps that makes use of this library. In the test I am checking that it is possible to navigate to \"Premium features\" screen, verify that most important data is visible and check that it is possible to leave that screen.\n\nNote that some of the buttons are identified by enum case instead of raw string. You can see [type safe identifiers](https://swiftpackageindex.com/tunous/xcapptest/main/documentation/xcapptest/typesafeidentifiers) tip to see how this is implemented.\n\n```swift\nfunc testOpenClosePremiumScreen() throws {\n    try launch(configuration: .init(premiumUnlocked: false))\n\n    app.buttons[.toggleBottomSheetButton].tap()\n    app.buttons[\"Unlock Premium\"].tapWhenReady()\n    \n    run(\"Verify screen content\") {\n        assertPremiumScreenIsVisible()\n        app.buttons[.unlockFeaturesButton].assertIsEnabled().assertContainsText(\"Lifetime access\")\n        app.buttons[\"Restore Purchase\"].assertIsEnabled()\n    }\n\n    app.buttons[\"Dismiss\"].tap()\n    app.staticTexts[\"Pipilo Premium\"].assertNotExists()\n}\n```\n\n## Installation\n\n### Swift Package Manager\n\n1. Add the following to the dependencies array in your `Package.swift` file:\n\n```swift\n.package(url: \"https://github.com/Tunous/XCAppTest.git\", .upToNextMajor(from: \"0.14.0\")),\n```\n\n2. Add `XCAppTest` as a dependency for your **tests** target:\n\n```swift\n.target(name: \"MyAppTests\", dependencies: [\"XCAppTest\"]),\n```\n\n3. Add `import XCAppTest` in your tests source code.\n\n### Xcode\n\nAdd [https://github.com/Tunous/XCAppTest.git](https://github.com/Tunous/XCAppTest.git), to the list of Swift packages for your project in Xcode and include it as a dependency on your **tests** target.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftunous%2Fxcapptest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftunous%2Fxcapptest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftunous%2Fxcapptest/lists"}