From 686b6e6168ece87599ce031645d2e9719826e709 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Mon, 25 Oct 2021 15:55:38 +1100 Subject: [PATCH 1/8] Convert `AztecEditorScreen` to be a `ScreenObject` subclass --- .../Screens/Editor/AztecEditorScreen.swift | 138 ++++++++---------- .../Screens/PostsScreen.swift | 8 +- .../Screens/TabNavComponent.swift | 4 +- .../Tests/EditorAztecTests.swift | 2 +- 4 files changed, 68 insertions(+), 84 deletions(-) diff --git a/WordPress/UITestsFoundation/Screens/Editor/AztecEditorScreen.swift b/WordPress/UITestsFoundation/Screens/Editor/AztecEditorScreen.swift index c3bc0f888dd9..9d9f467fb947 100644 --- a/WordPress/UITestsFoundation/Screens/Editor/AztecEditorScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Editor/AztecEditorScreen.swift @@ -1,6 +1,8 @@ +import ScreenObject import XCTest -public class AztecEditorScreen: BaseScreen { +public class AztecEditorScreen: ScreenObject { + enum Mode { case rich case html @@ -11,46 +13,31 @@ public class AztecEditorScreen: BaseScreen { } let mode: Mode - var textView: XCUIElement - - private var richTextField = "aztec-rich-text-view" - private var htmlTextField = "aztec-html-text-view" - - let editorCloseButton = XCUIApplication().navigationBars["Azctec Editor Navigation Bar"].buttons["Close"] - let publishButton = XCUIApplication().buttons["Publish"] - let publishNowButton = XCUIApplication().buttons["Publish Now"] - let moreButton = XCUIApplication().buttons["more_post_options"] - let uploadProgressBar = XCUIApplication().progressIndicators["Progress"] - - let titleView = XCUIApplication().textViews["Title"] - let contentPlaceholder = XCUIApplication().staticTexts["aztec-content-placeholder"] - - let mediaButton = XCUIApplication().buttons["format_toolbar_insert_media"] - let insertMediaButton = XCUIApplication().buttons["insert_media_button"] - let headerButton = XCUIApplication().buttons["format_toolbar_select_paragraph_style"] - let boldButton = XCUIApplication().buttons["format_toolbar_toggle_bold"] - let italicButton = XCUIApplication().buttons["format_toolbar_toggle_italic"] - let underlineButton = XCUIApplication().buttons["format_toolbar_toggle_underline"] - let strikethroughButton = XCUIApplication().buttons["format_toolbar_toggle_strikethrough"] - let blockquoteButton = XCUIApplication().buttons["format_toolbar_toggle_blockquote"] - let listButton = XCUIApplication().buttons["format_toolbar_toggle_list_unordered"] - let linkButton = XCUIApplication().buttons["format_toolbar_insert_link"] - let horizontalrulerButton = XCUIApplication().buttons["format_toolbar_insert_horizontal_ruler"] - let sourcecodeButton = XCUIApplication().buttons["format_toolbar_toggle_html_view"] - let moreToolbarButton = XCUIApplication().buttons["format_toolbar_insert_more"] - - let unorderedListOption = XCUIApplication().buttons["Unordered List"] - let orderedListOption = XCUIApplication().buttons["Ordered List"] - - // Action sheets - let actionSheet = XCUIApplication().sheets.element(boundBy: 0) - let postSettingsButton = XCUIApplication().sheets.buttons["Post Settings"] - let keepEditingButton = XCUIApplication().sheets.buttons["Keep Editing"] - let postHasChangesSheet = XCUIApplication().sheets["post-has-changes-alert"] - - init(mode: Mode) { - var textField = "" + private(set) var textView: XCUIElement + + private let richTextField = "aztec-rich-text-view" + private let htmlTextField = "aztec-html-text-view" + + var mediaButton: XCUIElement { app.buttons["format_toolbar_insert_media"] } + var sourcecodeButton: XCUIElement { app.buttons["format_toolbar_toggle_html_view"] } + + private let textViewGetter: (String) -> (XCUIApplication) -> XCUIElement = { identifier in + return { app in + var textView = app.textViews[identifier] + + if textView.exists == false { + if app.otherElements[identifier].exists { + textView = app.otherElements[identifier] + } + } + + return textView + } + } + + init(mode: Mode, app: XCUIApplication = XCUIApplication()) throws { self.mode = mode + let textField: String switch mode { case .rich: textField = richTextField @@ -58,16 +45,12 @@ public class AztecEditorScreen: BaseScreen { textField = htmlTextField } - let app = XCUIApplication() textView = app.textViews[textField] - if !textView.exists { - if app.otherElements[textField].exists { - textView = app.otherElements[textField] - } - } - - super.init(element: textView) + try super.init( + expectedElementGetters: [ textViewGetter(textField) ], + app: app + ) showOptionsStrip() } @@ -87,11 +70,12 @@ public class AztecEditorScreen: BaseScreen { @discardableResult func addList(type: String) -> AztecEditorScreen { + let listButton = app.buttons["format_toolbar_toggle_list_unordered"] tapToolbarButton(button: listButton) if type == "ul" { - unorderedListOption.tap() + app.buttons["Unordered List"].tap() } else if type == "ol" { - orderedListOption.tap() + app.buttons["Ordered List"].tap() } return self @@ -114,6 +98,7 @@ public class AztecEditorScreen: BaseScreen { */ @discardableResult func tapToolbarButton(button: XCUIElement) -> AztecEditorScreen { + let linkButton = app.buttons["format_toolbar_insert_link"] let swipeElement = mediaButton.isHittable ? mediaButton : linkButton if !button.exists || !button.isHittable { @@ -147,22 +132,12 @@ public class AztecEditorScreen: BaseScreen { return self } - /** - Switches between Rich and HTML view. - */ - func switchContentView() -> AztecEditorScreen { - tapToolbarButton(button: sourcecodeButton) - - - return AztecEditorScreen(mode: mode.toggle()) - } - /** Common method to type in different text fields */ @discardableResult - func enterText(text: String) -> AztecEditorScreen { - contentPlaceholder.tap() + public func enterText(text: String) -> AztecEditorScreen { + app.staticTexts["aztec-content-placeholder"].tap() textView.typeText(text) return self } @@ -171,7 +146,8 @@ public class AztecEditorScreen: BaseScreen { Enters text into title field. - Parameter text: the test to enter into the title */ - func enterTextInTitle(text: String) -> AztecEditorScreen { + public func enterTextInTitle(text: String) -> AztecEditorScreen { + let titleView = app.textViews["Title"] titleView.tap() titleView.typeText(text) @@ -222,10 +198,14 @@ public class AztecEditorScreen: BaseScreen { // Inject the first picture try MediaPickerAlbumScreen().selectImage(atIndex: 0) - insertMediaButton.tap() + app.buttons["insert_media_button"].tap() // Wait for upload to finish - waitFor(element: uploadProgressBar, predicate: "exists == false", timeout: 10) + let uploadProgressBar = app.progressIndicators["Progress"] + XCTAssertEqual( + uploadProgressBar.waitFor(predicateString: "exists == false", timeout: 10), + .completed + ) return self } @@ -234,19 +214,23 @@ public class AztecEditorScreen: BaseScreen { public func closeEditor() { XCTContext.runActivity(named: "Close the Aztec editor") { (activity) in XCTContext.runActivity(named: "Close the More menu if needed") { (activity) in + let actionSheet = app.sheets.element(boundBy: 0) if actionSheet.exists { if XCUIDevice.isPad { app.otherElements["PopoverDismissRegion"].tap() } else { - keepEditingButton.tap() + app.sheets.buttons["Keep Editing"].tap() } } } + let editorCloseButton = app.navigationBars["Azctec Editor Navigation Bar"].buttons["Close"] + editorCloseButton.tap() XCTContext.runActivity(named: "Discard any local changes") { (activity) in + let postHasChangesSheet = app.sheets["post-has-changes-alert"] let discardButton = XCUIDevice.isPad ? postHasChangesSheet.buttons.lastMatch : postHasChangesSheet.buttons.element(boundBy: 1) if postHasChangesSheet.exists && (discardButton?.exists ?? false) { @@ -255,13 +239,16 @@ public class AztecEditorScreen: BaseScreen { } } - let editorClosed = waitFor(element: editorCloseButton, predicate: "isEnabled == false") - XCTAssert(editorClosed, "Aztec editor should be closed but is still loaded.") + XCTAssertEqual( + editorCloseButton.waitFor(predicateString: "isEnabled == false"), + .completed, + "Aztec editor should be closed but is still loaded." + ) } } - func publish() throws -> EditorNoticeComponent { - publishButton.tap() + public func publish() throws -> EditorNoticeComponent { + app.buttons["Publish"].tap() try confirmPublish() @@ -272,13 +259,14 @@ public class AztecEditorScreen: BaseScreen { if FancyAlertComponent.isLoaded() { try FancyAlertComponent().acceptAlert() } else { - publishNowButton.tap() + app.buttons["Publish Now"].tap() } } public func openPostSettings() throws -> EditorPostSettings { - moreButton.tap() - postSettingsButton.tap() + app.buttons["more_post_options"].tap() + + app.sheets.buttons["Post Settings"].tap() return try EditorPostSettings() } @@ -298,7 +286,7 @@ public class AztecEditorScreen: BaseScreen { return textView.value as! String } - static func isLoaded() -> Bool { - return XCUIApplication().navigationBars["Azctec Editor Navigation Bar"].buttons["Close"].exists + static func isLoaded(mode: Mode = .rich) -> Bool { + (try? AztecEditorScreen(mode: mode).isLoaded) ?? false } } diff --git a/WordPress/UITestsFoundation/Screens/PostsScreen.swift b/WordPress/UITestsFoundation/Screens/PostsScreen.swift index 57464e467c54..4923e540f603 100644 --- a/WordPress/UITestsFoundation/Screens/PostsScreen.swift +++ b/WordPress/UITestsFoundation/Screens/PostsScreen.swift @@ -65,10 +65,6 @@ public struct EditorScreen { return XCUIApplication().navigationBars[aztecEditorElement].exists } - private var aztecEditor: AztecEditorScreen { - return AztecEditorScreen(mode: .rich) - } - func dismissDialogsIfNeeded() throws { guard let blockEditor = try? BlockEditorScreen() else { return } @@ -80,8 +76,8 @@ public struct EditorScreen { blockEditor.closeEditor() } - if isAztecEditor { - self.aztecEditor.closeEditor() + if let aztecEditor = try? AztecEditorScreen(mode: .rich) { + aztecEditor.closeEditor() } } } diff --git a/WordPress/UITestsFoundation/Screens/TabNavComponent.swift b/WordPress/UITestsFoundation/Screens/TabNavComponent.swift index bbd490405db6..8891550381d8 100644 --- a/WordPress/UITestsFoundation/Screens/TabNavComponent.swift +++ b/WordPress/UITestsFoundation/Screens/TabNavComponent.swift @@ -48,12 +48,12 @@ public class TabNavComponent: ScreenObject { return try MySiteScreen() } - public func gotoAztecEditorScreen() throws -> AztecEditorScreen { + public func goToAztecEditorScreen() throws -> AztecEditorScreen { let mySiteScreen = try goToMySiteScreen() let actionSheet = try mySiteScreen.gotoCreateSheet() actionSheet.goToBlogPost() - return AztecEditorScreen(mode: .rich) + return try AztecEditorScreen(mode: .rich) } public func gotoBlockEditorScreen() throws -> BlockEditorScreen { diff --git a/WordPress/WordPressUITests/Tests/EditorAztecTests.swift b/WordPress/WordPressUITests/Tests/EditorAztecTests.swift index 8cdbf7e205fb..6b666dfa0891 100644 --- a/WordPress/WordPressUITests/Tests/EditorAztecTests.swift +++ b/WordPress/WordPressUITests/Tests/EditorAztecTests.swift @@ -11,7 +11,7 @@ class EditorAztecTests: XCTestCase { editorScreen = try EditorFlow .toggleBlockEditor(to: .off) .goBackToMySite() - .tabBar.gotoAztecEditorScreen() + .tabBar.goToAztecEditorScreen() .dismissNotificationAlertIfNeeded(.accept) } From cd2654a4b73d7694346acb489a7212c5fc510445 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Mon, 25 Oct 2021 16:07:02 +1100 Subject: [PATCH 2/8] Convert `PasswordScreen` to be a `ScreenObject` subclass --- .../Login/Unified/GetStartedScreen.swift | 4 +-- .../Login/Unified/PasswordScreen.swift | 31 ++++++++----------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/WordPress/UITestsFoundation/Screens/Login/Unified/GetStartedScreen.swift b/WordPress/UITestsFoundation/Screens/Login/Unified/GetStartedScreen.swift index 0504b1c6de45..0e6a02dbf560 100644 --- a/WordPress/UITestsFoundation/Screens/Login/Unified/GetStartedScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Login/Unified/GetStartedScreen.swift @@ -42,12 +42,12 @@ public class GetStartedScreen: ScreenObject { ) } - public func proceedWith(email: String) -> PasswordScreen { + public func proceedWith(email: String) throws -> PasswordScreen { emailTextField.tap() emailTextField.typeText(email) continueButton.tap() - return PasswordScreen() + return try PasswordScreen() } public func goBackToPrologue() { diff --git a/WordPress/UITestsFoundation/Screens/Login/Unified/PasswordScreen.swift b/WordPress/UITestsFoundation/Screens/Login/Unified/PasswordScreen.swift index 6f9c368a3516..0afdc10d0d96 100644 --- a/WordPress/UITestsFoundation/Screens/Login/Unified/PasswordScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Login/Unified/PasswordScreen.swift @@ -1,21 +1,14 @@ +import ScreenObject import XCTest -private struct ElementStringIDs { - static let passwordTextField = "Password" - static let continueButton = "Continue Button" - static let errorLabel = "Password Error" -} - -public class PasswordScreen: BaseScreen { - let passwordTextField: XCUIElement - let continueButton: XCUIElement - - public init() { - let app = XCUIApplication() - passwordTextField = app.secureTextFields[ElementStringIDs.passwordTextField] - continueButton = app.buttons[ElementStringIDs.continueButton] +public class PasswordScreen: ScreenObject { - super.init(element: passwordTextField) + public init(app: XCUIApplication = XCUIApplication()) throws { + try super.init( + // // swiftlint:disable:next opening_brace + expectedElementGetters: [ { $0.secureTextFields["Password"] } ], + app: app + ) } public func proceedWith(password: String) -> LoginEpilogueScreen { @@ -37,18 +30,20 @@ public class PasswordScreen: BaseScreen { // // Calling passwordTextField.doubleTap() prevents tests from failing by ensuring that the text field's // secureTextEntry property remains 'true'. + let passwordTextField = expectedElement passwordTextField.doubleTap() passwordTextField.typeText(password) + let continueButton = app.buttons["Continue Button"] continueButton.tap() if continueButton.exists && !continueButton.isHittable { - waitFor(element: continueButton, predicate: "isEnabled == true") + XCTAssertEqual(continueButton.waitFor(predicateString: "isEnabled == true"), .completed) } return self } public func verifyLoginError() -> PasswordScreen { - let errorLabel = app.cells[ElementStringIDs.errorLabel] + let errorLabel = app.cells["Password Error"] _ = errorLabel.waitForExistence(timeout: 2) XCTAssertTrue(errorLabel.exists) @@ -56,6 +51,6 @@ public class PasswordScreen: BaseScreen { } public static func isLoaded() -> Bool { - return XCUIApplication().buttons[ElementStringIDs.continueButton].exists + (try? PasswordScreen().isLoaded) ?? false } } From 01ec1061924679471203214d80ddc780e1d08010 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Mon, 25 Oct 2021 16:16:11 +1100 Subject: [PATCH 3/8] Convert `WelcomeScreen` to be a `ScreenObject` subclass --- .../Screens/Login/WelcomeScreen.swift | 4 +-- .../Login/WelcomeScreenLoginComponent.swift | 29 ++++++++++--------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/WordPress/UITestsFoundation/Screens/Login/WelcomeScreen.swift b/WordPress/UITestsFoundation/Screens/Login/WelcomeScreen.swift index 68c99a48d7f6..afc41edff7d0 100644 --- a/WordPress/UITestsFoundation/Screens/Login/WelcomeScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Login/WelcomeScreen.swift @@ -26,10 +26,10 @@ public class WelcomeScreen: ScreenObject { return try WelcomeScreenSignupComponent() } - public func selectLogin() -> WelcomeScreenLoginComponent { + public func selectLogin() throws -> WelcomeScreenLoginComponent { logInButton.tap() - return WelcomeScreenLoginComponent() + return try WelcomeScreenLoginComponent() } static func isLoaded() -> Bool { diff --git a/WordPress/UITestsFoundation/Screens/Login/WelcomeScreenLoginComponent.swift b/WordPress/UITestsFoundation/Screens/Login/WelcomeScreenLoginComponent.swift index edec43edaa09..2107cddc8a41 100644 --- a/WordPress/UITestsFoundation/Screens/Login/WelcomeScreenLoginComponent.swift +++ b/WordPress/UITestsFoundation/Screens/Login/WelcomeScreenLoginComponent.swift @@ -1,31 +1,32 @@ +import ScreenObject import XCTest // TODO: remove when unifiedAuth is permanent. -private struct ElementStringIDs { - static let emailLoginButton = "Log in with Email Button" - static let siteAddressButton = "Self Hosted Login Button" -} - -public class WelcomeScreenLoginComponent: BaseScreen { - let emailLoginButton: XCUIElement - let siteAddressButton: XCUIElement +public class WelcomeScreenLoginComponent: ScreenObject { - init() { - emailLoginButton = XCUIApplication().buttons[ElementStringIDs.emailLoginButton] - siteAddressButton = XCUIApplication().buttons[ElementStringIDs.siteAddressButton] + let emailLoginButtonGetter: (XCUIApplication) -> XCUIElement = { + $0.buttons["Log in with Email Button"] + } + let siteAddressButtonGetter: (XCUIApplication) -> XCUIElement = { + $0.buttons["Self Hosted Login Button"] + } - super.init(element: emailLoginButton) + init(app: XCUIApplication = XCUIApplication()) throws { + try super.init( + expectedElementGetters: [emailLoginButtonGetter, siteAddressButtonGetter], + app: app + ) } public func selectEmailLogin() throws -> LoginEmailScreen { - emailLoginButton.tap() + emailLoginButtonGetter(app).tap() return try LoginEmailScreen() } func goToSiteAddressLogin() -> LoginSiteAddressScreen { - siteAddressButton.tap() + siteAddressButtonGetter(app).tap() return LoginSiteAddressScreen() } From c0ec00648773278735350b3c8bc1c08b9d4ab12d Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Mon, 25 Oct 2021 16:26:41 +1100 Subject: [PATCH 4/8] Convert `LoginPasswordScreen` to be a `ScreenObject` subclass --- .../Screens/Login/LinkOrPasswordScreen.swift | 4 +-- .../Login/LoginCheckMagicLinkScreen.swift | 4 +-- .../Screens/Login/LoginPasswordScreen.swift | 27 +++++++++---------- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/WordPress/UITestsFoundation/Screens/Login/LinkOrPasswordScreen.swift b/WordPress/UITestsFoundation/Screens/Login/LinkOrPasswordScreen.swift index 9f2ed29902cb..1a7c60621019 100644 --- a/WordPress/UITestsFoundation/Screens/Login/LinkOrPasswordScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Login/LinkOrPasswordScreen.swift @@ -18,10 +18,10 @@ public class LinkOrPasswordScreen: BaseScreen { super.init(element: passwordOption) } - func proceedWithPassword() -> LoginPasswordScreen { + func proceedWithPassword() throws -> LoginPasswordScreen { passwordOption.tap() - return LoginPasswordScreen() + return try LoginPasswordScreen() } public func proceedWithLink() -> LoginCheckMagicLinkScreen { diff --git a/WordPress/UITestsFoundation/Screens/Login/LoginCheckMagicLinkScreen.swift b/WordPress/UITestsFoundation/Screens/Login/LoginCheckMagicLinkScreen.swift index a6bab6db1e76..100d875ee401 100644 --- a/WordPress/UITestsFoundation/Screens/Login/LoginCheckMagicLinkScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Login/LoginCheckMagicLinkScreen.swift @@ -17,10 +17,10 @@ public class LoginCheckMagicLinkScreen: BaseScreen { super.init(element: mailButton) } - func proceedWithPassword() -> LoginPasswordScreen { + func proceedWithPassword() throws -> LoginPasswordScreen { passwordOption.tap() - return LoginPasswordScreen() + return try LoginPasswordScreen() } public func openMagicLoginLink() -> LoginEpilogueScreen { diff --git a/WordPress/UITestsFoundation/Screens/Login/LoginPasswordScreen.swift b/WordPress/UITestsFoundation/Screens/Login/LoginPasswordScreen.swift index 0ad6f87606fe..c444bedd99af 100644 --- a/WordPress/UITestsFoundation/Screens/Login/LoginPasswordScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Login/LoginPasswordScreen.swift @@ -1,21 +1,16 @@ +import ScreenObject import XCTest // TODO: remove when unifiedAuth is permanent. -private struct ElementStringIDs { - static let passwordTextField = "Password" - static let loginButton = "Password Next Button" - static let errorLabel = "pswdErrorLabel" -} +class LoginPasswordScreen: ScreenObject { -class LoginPasswordScreen: BaseScreen { - let passwordTextField: XCUIElement - let loginButton: XCUIElement + let passwordTextFieldGetter: (XCUIApplication) -> XCUIElement = { + $0.secureTextFields["Password"] + } - init() { - passwordTextField = XCUIApplication().secureTextFields[ElementStringIDs.passwordTextField] - loginButton = XCUIApplication().buttons[ElementStringIDs.loginButton] - super.init(element: passwordTextField) + init(app: XCUIApplication = XCUIApplication()) throws { + try super.init(expectedElementGetters: [passwordTextFieldGetter], app: app) } func proceedWith(password: String) -> LoginEpilogueScreen { @@ -25,17 +20,19 @@ class LoginPasswordScreen: BaseScreen { } func tryProceed(password: String) -> LoginPasswordScreen { + let passwordTextField = passwordTextFieldGetter(app) passwordTextField.tap() passwordTextField.typeText(password) + let loginButton = app.buttons["Password next Button"] loginButton.tap() if loginButton.exists && !loginButton.isHittable { - waitFor(element: loginButton, predicate: "isEnabled == true") + XCTAssertEqual(loginButton.waitFor(predicateString: "isEnabled == true"), .completed) } return self } func verifyLoginError() -> LoginPasswordScreen { - let errorLabel = app.staticTexts[ElementStringIDs.errorLabel] + let errorLabel = app.staticTexts["pswdErrorLabel"] _ = errorLabel.waitForExistence(timeout: 2) XCTAssertTrue(errorLabel.exists) @@ -43,6 +40,6 @@ class LoginPasswordScreen: BaseScreen { } static func isLoaded() -> Bool { - return XCUIApplication().buttons[ElementStringIDs.loginButton].exists + (try? LoginPasswordScreen().isLoaded) ?? false } } From 820693855c870c028faee8ef1e5fd84988e8edbe Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Mon, 25 Oct 2021 16:36:39 +1100 Subject: [PATCH 5/8] Convert `LinkOrPasswordScreen` to be a `ScreenObject` subclass --- .../Screens/Login/LinkOrPasswordScreen.swift | 28 +++++++++---------- .../Screens/Login/LoginEmailScreen.swift | 4 +-- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/WordPress/UITestsFoundation/Screens/Login/LinkOrPasswordScreen.swift b/WordPress/UITestsFoundation/Screens/Login/LinkOrPasswordScreen.swift index 1a7c60621019..e8d13b3fd744 100644 --- a/WordPress/UITestsFoundation/Screens/Login/LinkOrPasswordScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Login/LinkOrPasswordScreen.swift @@ -1,36 +1,34 @@ +import ScreenObject import XCTest // TODO: remove when unifiedAuth is permanent. -private struct ElementStringIDs { - static let passwordOption = "Use Password" - static let linkButton = "Send Link Button" -} - -public class LinkOrPasswordScreen: BaseScreen { - let passwordOption: XCUIElement - let linkButton: XCUIElement +public class LinkOrPasswordScreen: ScreenObject { - init() { - passwordOption = XCUIApplication().buttons[ElementStringIDs.passwordOption] - linkButton = XCUIApplication().buttons[ElementStringIDs.linkButton] + let passwordOptionGetter: (XCUIApplication) -> XCUIElement = { + $0.buttons["Use Password"] + } + let linkButtonGetter: (XCUIApplication) -> XCUIElement = { + $0.buttons["Send Link Button"] + } - super.init(element: passwordOption) + init(app: XCUIApplication = XCUIApplication()) throws { + try super.init(expectedElementGetters: [passwordOptionGetter, linkButtonGetter], app: app) } func proceedWithPassword() throws -> LoginPasswordScreen { - passwordOption.tap() + passwordOptionGetter(app).tap() return try LoginPasswordScreen() } public func proceedWithLink() -> LoginCheckMagicLinkScreen { - linkButton.tap() + linkButtonGetter(app).tap() return LoginCheckMagicLinkScreen() } public static func isLoaded() -> Bool { - return XCUIApplication().buttons[ElementStringIDs.passwordOption].exists + (try? LinkOrPasswordScreen().isLoaded) ?? false } } diff --git a/WordPress/UITestsFoundation/Screens/Login/LoginEmailScreen.swift b/WordPress/UITestsFoundation/Screens/Login/LoginEmailScreen.swift index 824784a5c021..d5ec051792d2 100644 --- a/WordPress/UITestsFoundation/Screens/Login/LoginEmailScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Login/LoginEmailScreen.swift @@ -23,12 +23,12 @@ public class LoginEmailScreen: ScreenObject { ) } - public func proceedWith(email: String) -> LinkOrPasswordScreen { + public func proceedWith(email: String) throws -> LinkOrPasswordScreen { emailTextField.tap() emailTextField.typeText(email) nextButton.tap() - return LinkOrPasswordScreen() + return try LinkOrPasswordScreen() } func goToSiteAddressLogin() -> LoginSiteAddressScreen { From b0724fcc1efb977aa959466352d342dd3f0531ac Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Mon, 25 Oct 2021 16:46:44 +1100 Subject: [PATCH 6/8] Convert `LoginCheckMagicLinkScreen` to be a `ScreenObject` subclass --- .../Screens/Login/LinkOrPasswordScreen.swift | 4 +-- .../Login/LoginCheckMagicLinkScreen.swift | 31 ++++++++++--------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/WordPress/UITestsFoundation/Screens/Login/LinkOrPasswordScreen.swift b/WordPress/UITestsFoundation/Screens/Login/LinkOrPasswordScreen.swift index e8d13b3fd744..4f3ab9d7e3c7 100644 --- a/WordPress/UITestsFoundation/Screens/Login/LinkOrPasswordScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Login/LinkOrPasswordScreen.swift @@ -22,10 +22,10 @@ public class LinkOrPasswordScreen: ScreenObject { return try LoginPasswordScreen() } - public func proceedWithLink() -> LoginCheckMagicLinkScreen { + public func proceedWithLink() throws -> LoginCheckMagicLinkScreen { linkButtonGetter(app).tap() - return LoginCheckMagicLinkScreen() + return try LoginCheckMagicLinkScreen() } public static func isLoaded() -> Bool { diff --git a/WordPress/UITestsFoundation/Screens/Login/LoginCheckMagicLinkScreen.swift b/WordPress/UITestsFoundation/Screens/Login/LoginCheckMagicLinkScreen.swift index 100d875ee401..8f7e5348ba57 100644 --- a/WordPress/UITestsFoundation/Screens/Login/LoginCheckMagicLinkScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Login/LoginCheckMagicLinkScreen.swift @@ -1,24 +1,25 @@ +import ScreenObject import XCTest -private struct ElementStringIDs { - static let passwordOption = "Use Password" - static let mailButton = "Open Mail Button" -} - -public class LoginCheckMagicLinkScreen: BaseScreen { - let passwordOption: XCUIElement - let mailButton: XCUIElement +public class LoginCheckMagicLinkScreen: ScreenObject { - init() { - let app = XCUIApplication() - passwordOption = app.buttons[ElementStringIDs.passwordOption] - mailButton = app.buttons[ElementStringIDs.mailButton] + let passwordOptionGetter: (XCUIApplication) -> XCUIElement = { + $0.buttons["Use Password"] + } - super.init(element: mailButton) + init(app: XCUIApplication = XCUIApplication()) throws { + try super.init( + expectedElementGetters: [ + passwordOptionGetter, + // swiftlint:disable:next opening_brace + { $0.buttons["Open Mail Button"] } + ], + app: app + ) } func proceedWithPassword() throws -> LoginPasswordScreen { - passwordOption.tap() + passwordOptionGetter(app).tap() return try LoginPasswordScreen() } @@ -30,6 +31,6 @@ public class LoginCheckMagicLinkScreen: BaseScreen { } public static func isLoaded() -> Bool { - return XCUIApplication().buttons[ElementStringIDs.mailButton].exists + (try? LoginCheckMagicLinkScreen().isLoaded) ?? false } } From 8a7f206d60d1ebe6b9796d90937d23e43697b4b6 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Mon, 25 Oct 2021 16:53:12 +1100 Subject: [PATCH 7/8] Convert `LoginSiteAddressScreen` to be a `ScreenObject` subclass --- .../Screens/Login/LoginEmailScreen.swift | 4 ++-- .../Login/LoginSiteAddressScreen.swift | 20 ++++++++++--------- .../Login/Unified/PrologueScreen.swift | 4 ++-- .../Login/WelcomeScreenLoginComponent.swift | 4 ++-- .../Screens/MySitesScreen.swift | 4 ++-- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/WordPress/UITestsFoundation/Screens/Login/LoginEmailScreen.swift b/WordPress/UITestsFoundation/Screens/Login/LoginEmailScreen.swift index d5ec051792d2..0891e67a5501 100644 --- a/WordPress/UITestsFoundation/Screens/Login/LoginEmailScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Login/LoginEmailScreen.swift @@ -31,10 +31,10 @@ public class LoginEmailScreen: ScreenObject { return try LinkOrPasswordScreen() } - func goToSiteAddressLogin() -> LoginSiteAddressScreen { + func goToSiteAddressLogin() throws -> LoginSiteAddressScreen { app.buttons["Self Hosted Login Button"].tap() - return LoginSiteAddressScreen() + return try LoginSiteAddressScreen() } static func isLoaded() -> Bool { diff --git a/WordPress/UITestsFoundation/Screens/Login/LoginSiteAddressScreen.swift b/WordPress/UITestsFoundation/Screens/Login/LoginSiteAddressScreen.swift index 9a6823b345c7..eee1952af0e6 100644 --- a/WordPress/UITestsFoundation/Screens/Login/LoginSiteAddressScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Login/LoginSiteAddressScreen.swift @@ -1,3 +1,4 @@ +import ScreenObject import XCTest private struct ElementStringIDs { @@ -13,16 +14,17 @@ private struct ElementStringIDs { static let siteAddressTextField = "Site address" } -public class LoginSiteAddressScreen: BaseScreen { - let siteAddressTextField: XCUIElement - let nextButton: XCUIElement +public class LoginSiteAddressScreen: ScreenObject { - init() { - let app = XCUIApplication() - siteAddressTextField = app.textFields[ElementStringIDs.siteAddressTextField] - nextButton = app.buttons[ElementStringIDs.nextButton] + let siteAddressTextFieldGetter: (XCUIApplication) -> XCUIElement = { + $0.textFields["Site address"] + } + + var siteAddressTextField: XCUIElement { siteAddressTextFieldGetter(app) } + var nextButton: XCUIElement { app.buttons[ElementStringIDs.nextButton] } - super.init(element: siteAddressTextField) + init(app: XCUIApplication = XCUIApplication()) throws { + try super.init(expectedElementGetters: [siteAddressTextFieldGetter], app: app) } public func proceedWith(siteUrl: String) throws -> LoginUsernamePasswordScreen { @@ -42,6 +44,6 @@ public class LoginSiteAddressScreen: BaseScreen { } public static func isLoaded() -> Bool { - return XCUIApplication().buttons[ElementStringIDs.nextButton].exists + (try? LoginSiteAddressScreen().isLoaded) ?? false } } diff --git a/WordPress/UITestsFoundation/Screens/Login/Unified/PrologueScreen.swift b/WordPress/UITestsFoundation/Screens/Login/Unified/PrologueScreen.swift index 70ecb8970f36..81bfe6f284f4 100644 --- a/WordPress/UITestsFoundation/Screens/Login/Unified/PrologueScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Login/Unified/PrologueScreen.swift @@ -28,10 +28,10 @@ public class PrologueScreen: ScreenObject { return try GetStartedScreen() } - public func selectSiteAddress() -> LoginSiteAddressScreen { + public func selectSiteAddress() throws -> LoginSiteAddressScreen { siteAddressButton.tap() - return LoginSiteAddressScreen() + return try LoginSiteAddressScreen() } public static func isLoaded(app: XCUIApplication = XCUIApplication()) -> Bool { diff --git a/WordPress/UITestsFoundation/Screens/Login/WelcomeScreenLoginComponent.swift b/WordPress/UITestsFoundation/Screens/Login/WelcomeScreenLoginComponent.swift index 2107cddc8a41..fb4b2b8510cf 100644 --- a/WordPress/UITestsFoundation/Screens/Login/WelcomeScreenLoginComponent.swift +++ b/WordPress/UITestsFoundation/Screens/Login/WelcomeScreenLoginComponent.swift @@ -25,9 +25,9 @@ public class WelcomeScreenLoginComponent: ScreenObject { return try LoginEmailScreen() } - func goToSiteAddressLogin() -> LoginSiteAddressScreen { + func goToSiteAddressLogin() throws -> LoginSiteAddressScreen { siteAddressButtonGetter(app).tap() - return LoginSiteAddressScreen() + return try LoginSiteAddressScreen() } } diff --git a/WordPress/UITestsFoundation/Screens/MySitesScreen.swift b/WordPress/UITestsFoundation/Screens/MySitesScreen.swift index 821237b83f05..24e551fa7f96 100644 --- a/WordPress/UITestsFoundation/Screens/MySitesScreen.swift +++ b/WordPress/UITestsFoundation/Screens/MySitesScreen.swift @@ -24,10 +24,10 @@ public class MySitesScreen: ScreenObject { ) } - public func addSelfHostedSite() -> LoginSiteAddressScreen { + public func addSelfHostedSite() throws -> LoginSiteAddressScreen { plusButtonGetter(app).tap() app.buttons["Add self-hosted site"].tap() - return LoginSiteAddressScreen() + return try LoginSiteAddressScreen() } public func closeModal() throws -> MySiteScreen { From e284434fa0baa61e19a58a82cc05a56f81508a41 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Wed, 8 Dec 2021 02:28:22 +1100 Subject: [PATCH 8/8] Remove a double comment start syntax Co-authored-by: pachlava <73365754+pachlava@users.noreply.github.com> --- .../Screens/Login/Unified/PasswordScreen.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/UITestsFoundation/Screens/Login/Unified/PasswordScreen.swift b/WordPress/UITestsFoundation/Screens/Login/Unified/PasswordScreen.swift index 0afdc10d0d96..88c1497a01eb 100644 --- a/WordPress/UITestsFoundation/Screens/Login/Unified/PasswordScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Login/Unified/PasswordScreen.swift @@ -5,7 +5,7 @@ public class PasswordScreen: ScreenObject { public init(app: XCUIApplication = XCUIApplication()) throws { try super.init( - // // swiftlint:disable:next opening_brace + // swiftlint:disable:next opening_brace expectedElementGetters: [ { $0.secureTextFields["Password"] } ], app: app )