From b5e51030636e64e4446aa4768b66c05bfe27198a Mon Sep 17 00:00:00 2001 From: Tiago Marques Date: Thu, 24 Aug 2023 20:19:37 -0300 Subject: [PATCH 1/4] Move post publish notice interaction to BlockEditorScreen --- .../UITests/Tests/EditorGutenbergTests.swift | 6 +- WordPress/UITests/Tests/PostTests.swift | 3 +- .../Screens/Editor/BlockEditorScreen.swift | 65 +++++++++++-------- 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/WordPress/UITests/Tests/EditorGutenbergTests.swift b/WordPress/UITests/Tests/EditorGutenbergTests.swift index 78a9b1281f8f..1333c99256bd 100644 --- a/WordPress/UITests/Tests/EditorGutenbergTests.swift +++ b/WordPress/UITests/Tests/EditorGutenbergTests.swift @@ -29,8 +29,7 @@ class EditorGutenbergTests: XCTestCase { .enterTextInTitle(text: postTitle) .addParagraphBlock(withText: postContent) .verifyContentStructure(blocks: 1, words: postContent.components(separatedBy: " ").count, characters: postContent.count) - .publish() - .viewPublishedPost(withTitle: postTitle) + .publishAndViewEpilogue() .verifyEpilogueDisplays(postTitle: postTitle, siteAddress: WPUITestCredentials.testWPcomPaidSite) .tapDone() } @@ -48,8 +47,7 @@ class EditorGutenbergTests: XCTestCase { .selectCategory(name: category) .addTag(name: tag) .closePostSettings() - .publish() - .viewPublishedPost(withTitle: postTitle) + .publishAndViewEpilogue() .verifyEpilogueDisplays(postTitle: postTitle, siteAddress: WPUITestCredentials.testWPcomPaidSite) .tapDone() } diff --git a/WordPress/UITests/Tests/PostTests.swift b/WordPress/UITests/Tests/PostTests.swift index 8888aa522d86..e557e442c4d6 100644 --- a/WordPress/UITests/Tests/PostTests.swift +++ b/WordPress/UITests/Tests/PostTests.swift @@ -31,8 +31,7 @@ class PostTests: XCTestCase { .updatePublishDateToFutureDate() .closePublishDateSelector() .closePostSettings() - .schedulePost() - .viewPublishedPost(withTitle: postTitle) + .schedulePostAndViewEpilogue() .verifyEpilogueDisplays(postTitle: postTitle, siteAddress: WPUITestCredentials.testWPcomSiteForScheduledPost) .tapDone() } diff --git a/WordPress/UITestsFoundation/Screens/Editor/BlockEditorScreen.swift b/WordPress/UITestsFoundation/Screens/Editor/BlockEditorScreen.swift index de514f54ddb7..eef93b6b7f16 100644 --- a/WordPress/UITestsFoundation/Screens/Editor/BlockEditorScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Editor/BlockEditorScreen.swift @@ -84,6 +84,14 @@ public class BlockEditorScreen: ScreenObject { $0.staticTexts["You have unsaved changes."] } + private let noticeViewTitleGetter: (XCUIApplication) -> XCUIElement = { + $0.otherElements["notice_title_and_message"] + } + + private let noticeViewButtonGetter: (XCUIApplication) -> XCUIElement = { + $0.buttons["View"] + } + var addBlockButton: XCUIElement { addBlockButtonGetter(app) } var applyButton: XCUIElement { applyButtonGetter(app) } var chooseFromDeviceButton: XCUIElement { chooseFromDeviceButtonGetter(app) } @@ -104,6 +112,8 @@ public class BlockEditorScreen: ScreenObject { var setRemindersButton: XCUIElement { setRemindersButtonGetter(app) } var undoButton: XCUIElement { undoButtonGetter(app) } var unsavedChangesLabel: XCUIElement { unsavedChangesLabelGetter(app) } + var noticeViewButton: XCUIElement { noticeViewButtonGetter(app) } + var noticeViewTitle: XCUIElement { noticeViewTitleGetter(app) } public init(app: XCUIApplication = XCUIApplication()) throws { // The block editor has _many_ elements but most are loaded on-demand. To verify the screen @@ -234,17 +244,34 @@ public class BlockEditorScreen: ScreenObject { } } - public func publish() throws -> EditorNoticeComponent { - return try post(action: "Publish") + private enum postAction: String { + case publish = "Publish" + case schedule = "Schedule" + } + + public func publish() throws { + return try post(action: .publish) + } + + public func publishAndViewEpilogue() throws -> EditorPublishEpilogueScreen { + try publish() + waitAndTap(noticeViewButton) + return try EditorPublishEpilogueScreen() } - public func schedulePost() throws -> EditorNoticeComponent { - return try post(action: "Schedule") + public func schedulePost() throws { + try post(action: .schedule) } - private func post(action: String) throws -> EditorNoticeComponent { - let postButton = app.buttons[action] - let postNowButton = app.buttons["\(action) Now"] + public func schedulePostAndViewEpilogue() throws -> EditorPublishEpilogueScreen { + try schedulePost() + waitAndTap(noticeViewButton) + return try EditorPublishEpilogueScreen() + } + + private func post(action: postAction) throws { + let postButton = app.buttons[action.rawValue] + let postNowButton = app.buttons["\(action.rawValue) Now"] var tries = 0 // This loop to check for Publish/Schedule Now Button is an attempt to confirm that the postButton.tap() call took effect. // The tests would fail sometimes in the pipeline with no apparent reason. @@ -252,19 +279,8 @@ public class BlockEditorScreen: ScreenObject { postButton.tap() tries += 1 } while !postNowButton.waitForIsHittable(timeout: 3) && tries <= 3 - try confirmPost(button: postNowButton) - - let actionInNotice: String - - if action == "Schedule" { - actionInNotice = "scheduled" - } else if action == "Publish" { - actionInNotice = "published" - } else { - throw NSError(domain: "InvalidAction", code: 0, userInfo: [NSLocalizedDescriptionKey: "Invalid action: \(action)"]) - } - return try EditorNoticeComponent(withNotice: "Post \(actionInNotice)") + try confirmPost(button: postNowButton, action: action) } @discardableResult @@ -402,13 +418,10 @@ public class BlockEditorScreen: ScreenObject { .selectAlbum(atIndex: 0) } - private func confirmPost(button: XCUIElement) throws { - if FancyAlertComponent.isLoaded() { - try FancyAlertComponent().acceptAlert() - } else { - button.tap() - dismissBloggingRemindersAlertIfNeeded() - } + private func confirmPost(button: XCUIElement, action: postAction) throws { + button.tap() + guard action == .publish else { return } + dismissBloggingRemindersAlertIfNeeded() } public func dismissBloggingRemindersAlertIfNeeded() { From 89839932000d95d6e1e20bb88f55b0492d98d6ec Mon Sep 17 00:00:00 2001 From: jos <17252150+jostnes@users.noreply.github.com> Date: Fri, 25 Aug 2023 11:37:29 +0800 Subject: [PATCH 2/4] empty commit to trigger tests From f5e4ec47c2cac5a5e456daa3327e039de211f85f Mon Sep 17 00:00:00 2001 From: Tiago Marques Date: Fri, 25 Aug 2023 09:46:56 -0300 Subject: [PATCH 3/4] Sort variables alphabetically --- .../Screens/Editor/BlockEditorScreen.swift | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/WordPress/UITestsFoundation/Screens/Editor/BlockEditorScreen.swift b/WordPress/UITestsFoundation/Screens/Editor/BlockEditorScreen.swift index eef93b6b7f16..896e379d805f 100644 --- a/WordPress/UITestsFoundation/Screens/Editor/BlockEditorScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Editor/BlockEditorScreen.swift @@ -4,92 +4,92 @@ import XCUITestHelpers public class BlockEditorScreen: ScreenObject { - private let editorCloseButtonGetter: (XCUIApplication) -> XCUIElement = { - $0.navigationBars["Gutenberg Editor Navigation Bar"].buttons["Close"] - } - - private let undoButtonGetter: (XCUIApplication) -> XCUIElement = { - $0.navigationBars["Gutenberg Editor Navigation Bar"].buttons["Undo"] - } - - private let redoButtonGetter: (XCUIApplication) -> XCUIElement = { - $0.navigationBars["Gutenberg Editor Navigation Bar"].buttons["Redo"] - } - private let addBlockButtonGetter: (XCUIApplication) -> XCUIElement = { $0.buttons["add-block-button"] } - private let moreButtonGetter: (XCUIApplication) -> XCUIElement = { - $0.buttons["more_post_options"] + private let applyButtonGetter: (XCUIApplication) -> XCUIElement = { + $0.buttons["Apply"] } - private let insertFromUrlButtonGetter: (XCUIApplication) -> XCUIElement = { - $0.buttons["Insert from URL"] + private let chooseFromDeviceButtonGetter: (XCUIApplication) -> XCUIElement = { + $0.buttons["Choose from device"] } - private let applyButtonGetter: (XCUIApplication) -> XCUIElement = { - $0.buttons["Apply"] + private let closeButtonGetter: (XCUIApplication) -> XCUIElement = { + $0.buttons["Close"] } private let discardButtonGetter: (XCUIApplication) -> XCUIElement = { $0.buttons["Discard"] } - private let firstParagraphBlockGetter: (XCUIApplication) -> XCUIElement = { - $0.otherElements["Paragraph Block. Row 1. Empty"] + private let dismissPopoverRegionGetter: (XCUIApplication) -> XCUIElement = { + $0.otherElements["PopoverDismissRegion"] } - private let postTitleViewGetter: (XCUIApplication) -> XCUIElement = { - $0.otherElements["Post title. Empty"] + private let editorCloseButtonGetter: (XCUIApplication) -> XCUIElement = { + $0.navigationBars["Gutenberg Editor Navigation Bar"].buttons["Close"] } private let editorNavigationBarGetter: (XCUIApplication) -> XCUIElement = { $0.navigationBars["Gutenberg Editor Navigation Bar"] } - private let closeButtonGetter: (XCUIApplication) -> XCUIElement = { - $0.buttons["Close"] + private let firstParagraphBlockGetter: (XCUIApplication) -> XCUIElement = { + $0.otherElements["Paragraph Block. Row 1. Empty"] } - private let dismissPopoverRegionGetter: (XCUIApplication) -> XCUIElement = { - $0.otherElements["PopoverDismissRegion"] + private let fullScreenImageGetter: (XCUIApplication) -> XCUIElement = { + $0.images["Fullscreen view of image. Double tap to dismiss"] + } + + private let insertFromUrlButtonGetter: (XCUIApplication) -> XCUIElement = { + $0.buttons["Insert from URL"] } private let keepEditingButtonGetter: (XCUIApplication) -> XCUIElement = { $0.buttons["Keep Editing"] } + private let moreButtonGetter: (XCUIApplication) -> XCUIElement = { + $0.buttons["more_post_options"] + } + + private let noticeViewButtonGetter: (XCUIApplication) -> XCUIElement = { + $0.buttons["View"] + } + + private let noticeViewTitleGetter: (XCUIApplication) -> XCUIElement = { + $0.otherElements["notice_title_and_message"] + } + private let postSettingsButtonGetter: (XCUIApplication) -> XCUIElement = { $0.buttons["Post Settings"] } - private let switchToHTMLModeButtonGetter: (XCUIApplication) -> XCUIElement = { - $0.buttons["Switch to HTML Mode"] + private let postTitleViewGetter: (XCUIApplication) -> XCUIElement = { + $0.otherElements["Post title. Empty"] } - private let chooseFromDeviceButtonGetter: (XCUIApplication) -> XCUIElement = { - $0.buttons["Choose from device"] + private let redoButtonGetter: (XCUIApplication) -> XCUIElement = { + $0.navigationBars["Gutenberg Editor Navigation Bar"].buttons["Redo"] } private let setRemindersButtonGetter: (XCUIApplication) -> XCUIElement = { $0.buttons["Set reminders"] } - private let fullScreenImageGetter: (XCUIApplication) -> XCUIElement = { - $0.images["Fullscreen view of image. Double tap to dismiss"] - } - - private let unsavedChangesLabelGetter: (XCUIApplication) -> XCUIElement = { - $0.staticTexts["You have unsaved changes."] + private let switchToHTMLModeButtonGetter: (XCUIApplication) -> XCUIElement = { + $0.buttons["Switch to HTML Mode"] } - private let noticeViewTitleGetter: (XCUIApplication) -> XCUIElement = { - $0.otherElements["notice_title_and_message"] + private let undoButtonGetter: (XCUIApplication) -> XCUIElement = { + $0.navigationBars["Gutenberg Editor Navigation Bar"].buttons["Undo"] } - private let noticeViewButtonGetter: (XCUIApplication) -> XCUIElement = { - $0.buttons["View"] + private let unsavedChangesLabelGetter: (XCUIApplication) -> XCUIElement = { + $0.staticTexts["You have unsaved changes."] } var addBlockButton: XCUIElement { addBlockButtonGetter(app) } @@ -105,15 +105,15 @@ public class BlockEditorScreen: ScreenObject { var insertFromUrlButton: XCUIElement { insertFromUrlButtonGetter(app) } var keepEditingButton: XCUIElement { keepEditingButtonGetter(app) } var moreButton: XCUIElement { moreButtonGetter(app) } + var noticeViewButton: XCUIElement { noticeViewButtonGetter(app) } + var noticeViewTitle: XCUIElement { noticeViewTitleGetter(app) } var postSettingsButton: XCUIElement { postSettingsButtonGetter(app) } - var switchToHTMLModeButton: XCUIElement { switchToHTMLModeButtonGetter(app) } var postTitleView: XCUIElement { postTitleViewGetter(app) } var redoButton: XCUIElement { redoButtonGetter(app) } var setRemindersButton: XCUIElement { setRemindersButtonGetter(app) } + var switchToHTMLModeButton: XCUIElement { switchToHTMLModeButtonGetter(app) } var undoButton: XCUIElement { undoButtonGetter(app) } var unsavedChangesLabel: XCUIElement { unsavedChangesLabelGetter(app) } - var noticeViewButton: XCUIElement { noticeViewButtonGetter(app) } - var noticeViewTitle: XCUIElement { noticeViewTitleGetter(app) } public init(app: XCUIApplication = XCUIApplication()) throws { // The block editor has _many_ elements but most are loaded on-demand. To verify the screen From 0af55e837c5905c772c11a5c8631716a532bff5d Mon Sep 17 00:00:00 2001 From: Tiago Marques Date: Mon, 28 Aug 2023 21:30:31 -0300 Subject: [PATCH 4/4] Verify scheduled post in post list. --- .../UITests/Tests/EditorGutenbergTests.swift | 4 ++-- WordPress/UITests/Tests/PostTests.swift | 9 +++++--- .../Screens/Editor/BlockEditorScreen.swift | 22 ++++--------------- .../Screens/MySiteScreen.swift | 3 ++- .../Screens/PostsScreen.swift | 9 ++++++++ 5 files changed, 23 insertions(+), 24 deletions(-) diff --git a/WordPress/UITests/Tests/EditorGutenbergTests.swift b/WordPress/UITests/Tests/EditorGutenbergTests.swift index 1333c99256bd..a1fdf0e08ae0 100644 --- a/WordPress/UITests/Tests/EditorGutenbergTests.swift +++ b/WordPress/UITests/Tests/EditorGutenbergTests.swift @@ -29,7 +29,7 @@ class EditorGutenbergTests: XCTestCase { .enterTextInTitle(text: postTitle) .addParagraphBlock(withText: postContent) .verifyContentStructure(blocks: 1, words: postContent.components(separatedBy: " ").count, characters: postContent.count) - .publishAndViewEpilogue() + .postAndViewEpilogue(action: .publish) .verifyEpilogueDisplays(postTitle: postTitle, siteAddress: WPUITestCredentials.testWPcomPaidSite) .tapDone() } @@ -47,7 +47,7 @@ class EditorGutenbergTests: XCTestCase { .selectCategory(name: category) .addTag(name: tag) .closePostSettings() - .publishAndViewEpilogue() + .postAndViewEpilogue(action: .publish) .verifyEpilogueDisplays(postTitle: postTitle, siteAddress: WPUITestCredentials.testWPcomPaidSite) .tapDone() } diff --git a/WordPress/UITests/Tests/PostTests.swift b/WordPress/UITests/Tests/PostTests.swift index e557e442c4d6..7cf2164ebe31 100644 --- a/WordPress/UITests/Tests/PostTests.swift +++ b/WordPress/UITests/Tests/PostTests.swift @@ -31,8 +31,11 @@ class PostTests: XCTestCase { .updatePublishDateToFutureDate() .closePublishDateSelector() .closePostSettings() - .schedulePostAndViewEpilogue() - .verifyEpilogueDisplays(postTitle: postTitle, siteAddress: WPUITestCredentials.testWPcomSiteForScheduledPost) - .tapDone() + .post(action: .schedule) + + try MySiteScreen() + .goToPostsScreen() + .showOnly(.scheduled) + .verifyPostExists(withTitle: postTitle) } } diff --git a/WordPress/UITestsFoundation/Screens/Editor/BlockEditorScreen.swift b/WordPress/UITestsFoundation/Screens/Editor/BlockEditorScreen.swift index 842f29009423..e92a831cb57e 100644 --- a/WordPress/UITestsFoundation/Screens/Editor/BlockEditorScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Editor/BlockEditorScreen.swift @@ -244,32 +244,18 @@ public class BlockEditorScreen: ScreenObject { } } - private enum postAction: String { + public enum postAction: String { case publish = "Publish" case schedule = "Schedule" } - public func publish() throws { - return try post(action: .publish) - } - - public func publishAndViewEpilogue() throws -> EditorPublishEpilogueScreen { - try publish() - waitAndTap(noticeViewButton) - return try EditorPublishEpilogueScreen() - } - - public func schedulePost() throws { - try post(action: .schedule) - } - - public func schedulePostAndViewEpilogue() throws -> EditorPublishEpilogueScreen { - try schedulePost() + public func postAndViewEpilogue(action: postAction) throws -> EditorPublishEpilogueScreen { + try post(action: action) waitAndTap(noticeViewButton) return try EditorPublishEpilogueScreen() } - private func post(action: postAction) throws { + public func post(action: postAction) throws { let postButton = app.buttons[action.rawValue] let postNowButton = app.buttons["\(action.rawValue) Now"] var tries = 0 diff --git a/WordPress/UITestsFoundation/Screens/MySiteScreen.swift b/WordPress/UITestsFoundation/Screens/MySiteScreen.swift index 183ef0afb14a..cd9d01989ab6 100644 --- a/WordPress/UITestsFoundation/Screens/MySiteScreen.swift +++ b/WordPress/UITestsFoundation/Screens/MySiteScreen.swift @@ -180,6 +180,7 @@ public class MySiteScreen: ScreenObject { } public func goToPostsScreen() throws -> PostsScreen { + goToMenu() postsButton.tap() return try PostsScreen() } @@ -219,7 +220,7 @@ public class MySiteScreen: ScreenObject { @discardableResult public func goToMenu() -> Self { // On iPad, the menu items are already listed on screen, so we don't need to tap the menu button - guard XCUIDevice.isPhone else { + guard XCUIDevice.isPhone && !segmentedControlMenuButton.isSelected else { return self } diff --git a/WordPress/UITestsFoundation/Screens/PostsScreen.swift b/WordPress/UITestsFoundation/Screens/PostsScreen.swift index 4f7115049771..7be5a09d6949 100644 --- a/WordPress/UITestsFoundation/Screens/PostsScreen.swift +++ b/WordPress/UITestsFoundation/Screens/PostsScreen.swift @@ -6,6 +6,7 @@ public class PostsScreen: ScreenObject { public enum PostStatus { case published case drafts + case scheduled } private var currentlyFilteredPostStatus: PostStatus = .published @@ -56,6 +57,8 @@ public class PostsScreen: ScreenObject { publishedButton.tap() case .drafts: draftsButton.tap() + case .scheduled: + scheduledButton.tap() } currentlyFilteredPostStatus = status @@ -89,6 +92,12 @@ public class PostsScreen: ScreenObject { autosaveAlert.buttons.firstMatch.tap() } } + + public func verifyPostExists(withTitle title: String) { + let expectedPost = app.cells.containing(.staticText, identifier: title).element + + XCTAssertTrue(expectedPost.exists) + } } public struct EditorScreen {