{"id":2107,"url":"https://github.com/joemasilotti/UI-Testing-Cheat-Sheet","last_synced_at":"2025-08-06T14:32:52.044Z","repository":{"id":43050615,"uuid":"42053792","full_name":"joemasilotti/UI-Testing-Cheat-Sheet","owner":"joemasilotti","description":"How do I test this with UI Testing?","archived":false,"fork":false,"pushed_at":"2020-04-29T20:42:52.000Z","size":87,"stargazers_count":2168,"open_issues_count":0,"forks_count":171,"subscribers_count":72,"default_branch":"master","last_synced_at":"2024-11-12T02:52:07.878Z","etag":null,"topics":["cheatsheet","swift","ui-testing","xctest","xcuitest"],"latest_commit_sha":null,"homepage":"http://masilotti.com/ui-testing-cheat-sheet/","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/joemasilotti.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-09-07T13:13:19.000Z","updated_at":"2024-11-06T20:44:48.000Z","dependencies_parsed_at":"2022-07-08T05:49:06.454Z","dependency_job_id":null,"html_url":"https://github.com/joemasilotti/UI-Testing-Cheat-Sheet","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joemasilotti%2FUI-Testing-Cheat-Sheet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joemasilotti%2FUI-Testing-Cheat-Sheet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joemasilotti%2FUI-Testing-Cheat-Sheet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joemasilotti%2FUI-Testing-Cheat-Sheet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joemasilotti","download_url":"https://codeload.github.com/joemasilotti/UI-Testing-Cheat-Sheet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228915452,"owners_count":17991406,"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":["cheatsheet","swift","ui-testing","xctest","xcuitest"],"created_at":"2024-01-05T20:16:03.726Z","updated_at":"2024-12-09T15:30:48.623Z","avatar_url":"https://github.com/joemasilotti.png","language":"Swift","funding_links":[],"categories":["Testing","Libs","Platforms","Swift","Testing [🔝](#readme)","Key Web Pages, Tutorials, and Tools for iOS \u0026 Beyond"],"sub_categories":["UI Testing","Testing","Other free courses"],"readme":"# UI Testing Cheat Sheet\n\nThis repository is complementary code for my post, [UI Testing Cheat Sheet and Examples](http://masilotti.com/ui-testing-cheat-sheet/). The post goes into more detail with example images for most examples.\n\nThe included project highlights working code with a simple Test Host. This was last updated for Swift 5 on Xcode 11.4.1.\n\n## Contents\n\n- [Basic Functionality](#basic-functionality)\n  - [Testing if an element exists](#testing-if-an-element-exists) \n  - [Testing if text with an ellipsis exists](#testing-if-text-with-an-ellipsis-exists)\n  - [Waiting for an element to appear](#waiting-for-an-element-to-appear) \n- [Interacting with System Controls](#interacting-with-system-controls)\n  - [Tapping buttons](#tapping-buttons) \n  - [Typing text](#typing-text) \n  - [Dismissing alerts](#dismissing-alerts) \n  - [Handling system alerts](#handling-system-alerts) \n  - [Sliding sliders](#sliding-sliders) \n  - [Interacting with pickers](#interacting-with-pickers) \n  - [Tapping links in web views](#tapping-links-in-web-views) \n- [Interactions](#interactions)\n  - [Verifying the current controller's title](#verifying-the-current-controllers-title) \n  - [Reordering table cells](#reordering-table-cells) \n  - [Pull to refresh](#pull-to-refresh) \n  - [Pushing and popping view controllers](#pushing-and-popping-view-controllers)\n\n## Basic Functionality\n\n### Testing if an element exists\n\n````swift\nXCTAssert(app.staticTexts[\"Welcome\"].exists)\n````\n\n### Testing if text with an ellipsis exists\nA full text match will find an element even if the displayed text has an ellipsis due to truncation.\n\n````swift\nlet longNameCell = app.staticTexts[\"Adolph Blaine Charles David Earl Frederick Gerald Hubert Irvin John Kenneth Lloyd Martin Nero Oliver Paul Quincy Randolph Sherman Thomas Uncas Victor William Xerxes Yancy Wolfeschlegelsteinhausenbergerdorff, Senior\"]\nXCTAssert(longNameCell.exists) // displayed text is \"Adolph Blaine Charles David Earl Freder...\"\n````\n\n### Waiting for an element to appear\n\"Waiting\" is now built into XCTest.\n\n````swift\nlet goLabel = app.staticTexts[\"Go!\"]\nXCTAssertFalse(goLabel.exists)\n\napp.buttons[\"Ready, set...\"].tap()\nXCTAssert(goLabel.waitForExistence(timeout: 5))\n````\n\n## Interacting with System Controls\n\n### Tapping buttons\nIdentify buttons by their accessibility label.\n\n````swift\napp.buttons[\"Add\"].tap()\n````\n\n### Typing text\nFirst make sure the text field has focus by tapping on it.\n\n````swift\nlet textField = app.textFields[\"Username\"]\ntextField.tap()\ntextField.typeText(\"joemasilotti\")\n````\n\n### Dismissing alerts\n````swift\napp.alerts[\"Alert Title\"].buttons[\"Button Title\"].tap()\n````\n\n### Dismissing action sheets\n````swift\napp.sheets[\"Sheet Title\"].buttons[\"Button Title\"].tap()\n````\n\n### Handling system alerts\nPresent a location services authorization dialog to the user and dismiss it with the following code.\n\nBefore presenting the alert add a UI Interruption Handler. When this fires, dismiss with the \"Allow\" button.\n\n````swift\naddUIInterruptionMonitor(withDescription: \"Location Services\") { (alert) -\u003e Bool in\n  alert.buttons[\"Allow\"].tap()\n  return true\n}\n\napp.buttons[\"Request Location\"].tap()\napp.tap() // need to interact with the app again for the handler to fire\n````\n\n### Sliding sliders\nThis will slide the value of the slider to 70%.\n\n````swift\napp.sliders.element.adjust(toNormalizedSliderPosition: 0.7)\n````\n\n### Interacting with pickers\nA picker with one wheel:\n\n````swift\napp.pickerWheels.element.adjust(toPickerWheelValue: \"Picker Wheel Item Title\")\n````\n\nA picker with multiple wheels. Make sure to set the accessibility delegate so the framework can identify the different wheels.\n\n````swift\nlet firstPredicate = NSPredicate(format: \"label BEGINSWITH 'First Picker'\")\nlet firstPicker = app.pickerWheels.element(matching: firstPredicate)\nfirstPicker.adjust(toPickerWheelValue: \"first value\")\n\nlet secondPredicate = NSPredicate(format: \"label BEGINSWITH 'Second Picker'\")\nlet secondPicker = app.pickerWheels.element(matching: secondPredicate)\nsecondPicker.adjust(toPickerWheelValue: \"second value\")\n\n````\n\n### Tapping links in web views\n````swift\napp.links[\"Tweet this\"].tap()\n````\n\n## Interactions\n\n### Verifying the current controller's title\n````swift\nXCTAssert(app.navigationBars[\"Details\"].exists)\n````\n\n### Reordering table cells\nIf you have a `UITableViewCell` with default style and set the text to \"Title\", the reorder control's accessibility label becomes \"Reorder Title\".\n\nUsing this we can drag one reorder control to another, essentially reordering the cells.\n\n````swift\nlet topButton = app.buttons[\"Reorder Top Cell\"]\nlet bottomButton = app.buttons[\"Reorder Bottom Cell\"]\nbottomButton.press(forDuration: 0.5, thenDragTo: topButton)\n\nXCTAssertLessThanOrEqual(bottomButton.frame.maxY, topButton.frame.minY)\n````\n\n### Pull to refresh\n\nCreate a `XCUICoordinate` from the first cell in your table and another one with a `dy` of six. Then drag the first coordinate to the second.\n\n````swift\nlet firstCell = app.staticTexts[\"Adrienne\"]\nlet start = firstCell.coordinate(withNormalizedOffset: (CGVectorMake(0, 0))\nlet finish = firstCell.coordinate(withNormalizedOffset: (CGVectorMake(0, 10))\nstart.press(forDuration: 0, thenDragTo: finish)\n````\n\n### Pushing and popping view controllers\n\nTest if a view controller was pushed onto the navigation stack.\n\n```swift\napp.buttons[\"More Info\"].tap()\nXCTAssert(app.navigationBars[\"Volleyball?\"].exists)\n```\n\nPop a view controller by tapping the back button in the navigation bar and assert that the title in the navigation bar has changed.\n\n```swift\napp.navigationBars.buttons.elementBoundByIndex(0).tap()\nXCTAssert(app.navigationBars[\"Volley\"].exists)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoemasilotti%2FUI-Testing-Cheat-Sheet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoemasilotti%2FUI-Testing-Cheat-Sheet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoemasilotti%2FUI-Testing-Cheat-Sheet/lists"}