From ca5aeb5ddeab78912f5f83ab0a6480291cbbdcaa Mon Sep 17 00:00:00 2001 From: shamanec Date: Wed, 2 Aug 2023 15:46:56 +0300 Subject: [PATCH] separate alert handling --- .../project.pbxproj | 4 + .../Helpers/Alerts.swift | 84 +++++++++++++++++++ .../Helpers/Elements.swift | 39 ++------- .../SampleAppUITests.swift | 8 +- 4 files changed, 98 insertions(+), 37 deletions(-) create mode 100644 xcuitest-sample-projUITests/Helpers/Alerts.swift diff --git a/xcuitest-sample-proj.xcodeproj/project.pbxproj b/xcuitest-sample-proj.xcodeproj/project.pbxproj index e72d55a..00ae59e 100644 --- a/xcuitest-sample-proj.xcodeproj/project.pbxproj +++ b/xcuitest-sample-proj.xcodeproj/project.pbxproj @@ -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 */; }; @@ -64,6 +65,7 @@ FF7C553F2A6EF2DA00102A71 /* LaunchArgumentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchArgumentTests.swift; sourceTree = ""; }; FF86799A2A69699D00C4A1A7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; FF86799D2A696BDC00C4A1A7 /* CarouselItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselItemView.swift; sourceTree = ""; }; + FFEDF63F2A7A7E1A0065A5E4 /* Alerts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alerts.swift; sourceTree = ""; }; FFF0348E2A6CFA6500A33E97 /* FirstPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstPage.swift; sourceTree = ""; }; FFF034902A6CFA8B00A33E97 /* BasePage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasePage.swift; sourceTree = ""; }; FFF034922A6CFEA200A33E97 /* SecondPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecondPage.swift; sourceTree = ""; }; @@ -188,6 +190,7 @@ children = ( FF79C2882A66F9F500BBC60A /* Interactions.swift */, FF4D5CAF2A68033C00B52624 /* Elements.swift */, + FFEDF63F2A7A7E1A0065A5E4 /* Alerts.swift */, ); path = Helpers; sourceTree = ""; @@ -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 */, diff --git a/xcuitest-sample-projUITests/Helpers/Alerts.swift b/xcuitest-sample-projUITests/Helpers/Alerts.swift new file mode 100644 index 0000000..df0fcff --- /dev/null +++ b/xcuitest-sample-projUITests/Helpers/Alerts.swift @@ -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) + } +} diff --git a/xcuitest-sample-projUITests/Helpers/Elements.swift b/xcuitest-sample-projUITests/Helpers/Elements.swift index f48b186..1a268eb 100644 --- a/xcuitest-sample-projUITests/Helpers/Elements.swift +++ b/xcuitest-sample-projUITests/Helpers/Elements.swift @@ -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 @@ -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 @@ -128,7 +101,7 @@ 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) { @@ -136,7 +109,7 @@ class Elements { 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) { @@ -144,7 +117,7 @@ class Elements { 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) { @@ -152,13 +125,13 @@ class Elements { 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") } } diff --git a/xcuitest-sample-projUITests/SampleAppUITests.swift b/xcuitest-sample-projUITests/SampleAppUITests.swift index acfb5b1..b9c3ae7 100644 --- a/xcuitest-sample-projUITests/SampleAppUITests.swift +++ b/xcuitest-sample-projUITests/SampleAppUITests.swift @@ -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() {