Skip to content

Commit

Permalink
separate alert handling
Browse files Browse the repository at this point in the history
  • Loading branch information
shamanec committed Aug 2, 2023
1 parent 9abfadb commit ca5aeb5
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 37 deletions.
4 changes: 4 additions & 0 deletions xcuitest-sample-proj.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
FF86799B2A69699D00C4A1A7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF86799A2A69699D00C4A1A7 /* AppDelegate.swift */; };
FF86799E2A696BDC00C4A1A7 /* CarouselItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF86799D2A696BDC00C4A1A7 /* CarouselItemView.swift */; };
FFED40FE2A714284005B0940 /* Sliders in Frameworks */ = {isa = PBXBuildFile; productRef = FFED40FD2A714284005B0940 /* Sliders */; };
FFEDF6402A7A7E1A0065A5E4 /* Alerts.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFEDF63F2A7A7E1A0065A5E4 /* Alerts.swift */; };
FFF0348F2A6CFA6500A33E97 /* FirstPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFF0348E2A6CFA6500A33E97 /* FirstPage.swift */; };
FFF034912A6CFA8B00A33E97 /* BasePage.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFF034902A6CFA8B00A33E97 /* BasePage.swift */; };
FFF034932A6CFEA200A33E97 /* SecondPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFF034922A6CFEA200A33E97 /* SecondPage.swift */; };
Expand Down Expand Up @@ -64,6 +65,7 @@
FF7C553F2A6EF2DA00102A71 /* LaunchArgumentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchArgumentTests.swift; sourceTree = "<group>"; };
FF86799A2A69699D00C4A1A7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
FF86799D2A696BDC00C4A1A7 /* CarouselItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselItemView.swift; sourceTree = "<group>"; };
FFEDF63F2A7A7E1A0065A5E4 /* Alerts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alerts.swift; sourceTree = "<group>"; };
FFF0348E2A6CFA6500A33E97 /* FirstPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstPage.swift; sourceTree = "<group>"; };
FFF034902A6CFA8B00A33E97 /* BasePage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasePage.swift; sourceTree = "<group>"; };
FFF034922A6CFEA200A33E97 /* SecondPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecondPage.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -188,6 +190,7 @@
children = (
FF79C2882A66F9F500BBC60A /* Interactions.swift */,
FF4D5CAF2A68033C00B52624 /* Elements.swift */,
FFEDF63F2A7A7E1A0065A5E4 /* Alerts.swift */,
);
path = Helpers;
sourceTree = "<group>";
Expand Down Expand Up @@ -367,6 +370,7 @@
buildActionMask = 2147483647;
files = (
FF79C2832A66F54E00BBC60A /* BaseTest.swift in Sources */,
FFEDF6402A7A7E1A0065A5E4 /* Alerts.swift in Sources */,
FFF034932A6CFEA200A33E97 /* SecondPage.swift in Sources */,
FF79C2032A66F1B700BBC60A /* SampleAppUITests.swift in Sources */,
FFF034952A6D027B00A33E97 /* TabBar.swift in Sources */,
Expand Down
84 changes: 84 additions & 0 deletions xcuitest-sample-projUITests/Helpers/Alerts.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//
// Alerts.swift
// xcuitest-sample-projUITests
//
// Created by Nikola Shabanov on 2.08.23.
//

import XCTest

class Alerts {
// MARK: - App alerts handling
/// Agnostically handle application alert - wait for alert and tap the first button on it
static func handleAppAlert() {
handleAppAlert("")
}

/// Handle application alert targetting specific button
static func handleAppAlert(_ button: String) {
let alert = BaseTest().getApp().alerts.firstMatch
handleAppAlert(alert, button)
}

/// Handle application alert by text displayed in title or description and also specific button label
static func handleAppAlert(_ text: String, _ button: String) {
let alert = BaseTest().getApp().alerts.firstMatch
if alert.staticTexts.element(withLabelContaining: text).exists {
handleAppAlert(alert, button)
return
}
XCTFail("There was no alert found that contains text: \(text)")
}

/// Handle application alert by element and targetting specific button
static func handleAppAlert(_ alert: XCUIElement, _ button: String) {
XCTAssertTrue(Elements.waitForElement(alert, TestConstants.Timeout.medium), "Alert element was not found")
var alertButton: XCUIElement
if button == "" {
alertButton = alert.buttons.firstMatch
XCTAssertTrue(alertButton.exists, "No button was found in the presented alert")
} else {
alertButton = alert.buttons[button]
XCTAssertTrue(alertButton.exists, "No button with identifier: `\(button)` was found in the presented alert")
}
alertButton.tap()
Elements.waitUntilElementDisappears(alert, 2)
}

// MARK: - System alerts handling
/// Agnostically handle system alert - wait for alert and tap the first button on it
static func handleSystemAlert() {
handleSystemAlert("")
}

/// Handle system alert targetting specific button
static func handleSystemAlert(_ button: String) {
let alert = BaseTest().getSpringboardApp().alerts.firstMatch
handleSystemAlert(alert, button)
}

/// Handle system alert by text displayed in title or description and also specific button label
static func handleSystemAlert(_ text: String, _ button: String) {
let alert = BaseTest().getSpringboardApp().alerts.firstMatch
if alert.staticTexts.element(withLabelContaining: text).exists {
handleSystemAlert(alert, button)
return
}
XCTFail("There was no alert found that contains text: \(text)")
}

/// Handle system alert by element and targetting specific button
static func handleSystemAlert(_ alert: XCUIElement, _ button: String) {
XCTAssertTrue(Elements.waitForElement(alert, TestConstants.Timeout.medium), "Alert element was not found")
var alertButton: XCUIElement
if button == "" {
alertButton = alert.buttons.firstMatch
XCTAssertTrue(alertButton.exists, "No button was found in the presented alert")
} else {
alertButton = alert.buttons[button]
XCTAssertTrue(alertButton.exists, "No button with identifier: `\(button)` was found in the presented alert")
}
alertButton.tap()
Elements.waitUntilElementDisappears(alert, 2)
}
}
39 changes: 6 additions & 33 deletions xcuitest-sample-projUITests/Helpers/Elements.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,33 +47,6 @@ class Elements {
element.adjust(toPickerWheelValue: value)
}

// MARK: - App alerts handling
/// Handle application alert by element and targetting specific button
static func handleAppAlert(_ alert: XCUIElement, _ button: String) {
XCTAssertTrue(waitForElement(alert, TestConstants.Timeout.medium), "Alert element was not found")
var alertButton: XCUIElement
if button == "" {
alertButton = alert.buttons.firstMatch
XCTAssertTrue(alertButton.exists, "No button was found in the presented alert")
} else {
alertButton = alert.buttons[button]
XCTAssertTrue(alertButton.exists, "No button with identifier: `\(button)` was found in the presented alert")
}
alertButton.tap()
Elements.waitUntilElementDisappears(alertButton, 2)
}

/// Handle application alert targetting specific button
static func handleAppAlert(_ button: String) {
let alert = BaseTest().getApp().alerts.firstMatch
handleAppAlert(alert, button)
}

/// Agnostically handle application alert - just wait for alert and tap the first button on it
static func handleAppAlert() {
handleAppAlert("")
}

// MARK: - Wait functions

/// Wait for element to exist
Expand All @@ -97,7 +70,7 @@ class Elements {
}
usleep(300_000) // 300ms
}
XCTAssertFalse(elementVisible, "\(element) is still visible(exists) after \(timeoutValue) seconds")
XCTAssertFalse(elementVisible, "Element is still visible(exists) after \(timeoutValue) seconds")
}

/// Wait until an XCUIElementQuery has at least X number of elements
Expand Down Expand Up @@ -128,37 +101,37 @@ class Elements {
let isDisplayedPredicate = NSPredicate(format: predicate)
let expectation = [XCTNSPredicateExpectation(predicate: isDisplayedPredicate, object: element)]
let result = XCTWaiter().wait(for: expectation, timeout: timeoutValue)
XCTAssertEqual(result, .completed, "Element \(element) is not displayed and/or hittable")
XCTAssertEqual(result, .completed, "Element is not displayed and/or hittable after \(timeoutValue) seconds")
}

func waitForElementEnabledAttributeToBe(_ element: XCUIElement, _ timeoutValue: Double, _ enabledValue: Bool) {
let predicate = "isEnabled == \(String(enabledValue))"
let isEnabledPredicate = NSPredicate(format: predicate)
let expectation = [XCTNSPredicateExpectation(predicate: isEnabledPredicate, object: element)]
let result = XCTWaiter().wait(for: expectation, timeout: timeoutValue)
XCTAssertEqual(result, .completed, "Element \(element) is not enabled")
XCTAssertEqual(result, .completed, "Element is not enabled after \(timeoutValue) seconds")
}

func waitForElementExistenceToBe(_ element: XCUIElement, _ timeoutValue: Double, _ existence: Bool) {
let predicate = "exists == \(String(existence))"
let existsPredicate = NSPredicate(format: predicate)
let expectation = [XCTNSPredicateExpectation(predicate: existsPredicate, object: element)]
let result = XCTWaiter().wait(for: expectation, timeout: timeoutValue)
XCTAssertEqual(result, .completed, "Element \(element) does not exist")
XCTAssertEqual(result, .completed, "Element does not exist after \(timeoutValue) seconds")
}

func waitForElementLabelAttributeToBe(_ element: XCUIElement, _ timeoutValue: Double, _ labelValue: String) {
let predicate = "label == '\(String(labelValue))'"
let labelEqualsPredicate = NSPredicate(format: predicate)
let expectation = [XCTNSPredicateExpectation(predicate: labelEqualsPredicate, object: element)]
let result = XCTWaiter().wait(for: expectation, timeout: timeoutValue)
XCTAssertEqual(result, .completed, "Element \(element) label value should be '\(labelValue)'")
XCTAssertEqual(result, .completed, "Element label value is not '\(labelValue)' after \(timeoutValue) seconds")
}

func waitForElementValueAttributeContains(_ element: XCUIElement, _ timeoutValue: Double, _ value: String) {
let valueContainsPredicate = NSPredicate(format: "value CONTAINS[c] %@", value)
let expectation = [XCTNSPredicateExpectation(predicate: valueContainsPredicate, object: element)]
let result = XCTWaiter().wait(for: expectation, timeout: timeoutValue)
XCTAssertEqual(result, .completed, "Element \(element) label value does not contain '\(value)'")
XCTAssertEqual(result, .completed, "Element label value does not contain '\(value)' after \(timeoutValue) seconds")
}
}
8 changes: 4 additions & 4 deletions xcuitest-sample-projUITests/SampleAppUITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,21 +112,21 @@ final class SampleAppUITests: BaseTest {
func testCloseAppAlertWithAlertAndButtonName() {
let firstPage = FirstPage(app: getApp())
firstPage.triggerAlertButton.tap()
Elements.handleAppAlert(getApp().alerts.firstMatch, "Close")
Alerts.handleAppAlert(getApp().alerts.firstMatch, "Close")
}

func testCloseAppAlertWithButtonName() {
let firstPage = FirstPage(app: getApp())
firstPage.triggerAlertButton.tap()
Elements.handleAppAlert("Close")
Alerts.handleAppAlert("Close")
firstPage.triggerAlertButton.tap()
Elements.handleAppAlert("Accept")
Alerts.handleAppAlert("Accept")
}

func testCloseAppAlertAgnostic() {
let firstPage = FirstPage(app: getApp())
firstPage.triggerAlertButton.tap()
Elements.handleAppAlert("")
Alerts.handleAppAlert("")
}

func testElementFullyVisible() {
Expand Down

0 comments on commit ca5aeb5

Please sign in to comment.