Skip to content

Commit d1799c5

Browse files
authored
[UI Tests] Re-enable Reader tests (#23748)
* Add network mocks for related posts and likes * Increase post content loading timeout * Update Reader's side menu button element * Add accessibility identifier to topics card cell * Disable testDiscover() * Update network mock * Re-enable reader tests * testSavePost() * testLikePost() * Fix test failing on iPad * testViewPost() * testViewPostInSafari() * Fix lint errors * Increase timeout for post content to load for iPad in CI * Fix test for iPad * testViewPost() * Re-enable testDiscover() * Wait for the Apple's black loading screen to disappear after launching the app. * Revert "Wait for the Apple's black loading screen to disappear after launching the app." This reverts commit 8c8e73f.
1 parent e51e847 commit d1799c5

File tree

9 files changed

+125
-36
lines changed

9 files changed

+125
-36
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"request": {
3+
"method": "GET",
4+
"urlPath": "/rest/v1.2/sites/106707880/posts/439/likes"
5+
},
6+
"response": {
7+
"status": 200,
8+
"jsonBody": {
9+
"found": 0,
10+
"i_like": false,
11+
"likes": []
12+
}
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"request": {
3+
"method": "GET",
4+
"urlPath": "/rest/v1.2/read/site/106707880/post/439/related"
5+
},
6+
"response": {
7+
"status": 200,
8+
"jsonBody": {
9+
"algorithm_local": "read:related:posts:local/7",
10+
"algorithm_global": "read:related:posts:global/1",
11+
"posts": [
12+
{
13+
"ID": 974,
14+
"site_ID": 80511,
15+
"author": {
16+
"ID": 29043,
17+
"login": "test",
18+
"email": false,
19+
"name": "Test User",
20+
"first_name": "Test",
21+
"last_name": "User",
22+
"site_ID": 80511
23+
},
24+
"date": "2024-03-07T23:00:40+00:00",
25+
"modified": "2024-03-07T23:00:40+00:00",
26+
"title": "title-a",
27+
"URL": "https://example.wordpress.com/2024/03/07/hello-974",
28+
"content": "content-a",
29+
"excerpt": "content-a",
30+
"slug": "hello-974",
31+
"status": "draft",
32+
"sticky": false,
33+
"password": "",
34+
"parent": false,
35+
"type": "post",
36+
"featured_image": "",
37+
"format": "standard"
38+
}
39+
]
40+
}
41+
}
42+
}

API-Mocks/WordPressMocks/src/main/assets/mocks/mappings/wpcom/reader/reader_tags_travel.json renamed to API-Mocks/WordPressMocks/src/main/assets/mocks/mappings/wpcom/reader/reader_tags.json

+19-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"jsonBody": {
1717
"success": true,
1818
"tags": [
19-
"travel"
19+
"{{lookup request.query 'tags[]'}}"
2020
],
2121
"sort": "date",
2222
"lang": "en",
@@ -73,7 +73,23 @@
7373
"height": 600
7474
},
7575
"format": "standard",
76-
"tags": {},
76+
"tags": {
77+
"{{capitalize (lookup request.query 'tags[]')}}": {
78+
"ID": 2290,
79+
"name": "{{lookup request.query 'tags[]'}}",
80+
"slug": "{{lookup request.query 'tags[]'}}",
81+
"description": "",
82+
"post_count": 24,
83+
"parent": 0,
84+
"meta": {
85+
"links": {
86+
"self": "https://public-api.wordpress.com/rest/v1.1/sites/181977606/categories/slug:architecture",
87+
"help": "https://public-api.wordpress.com/rest/v/sites/181977606/categories/slug:architecture/help",
88+
"site": "https://public-api.wordpress.com/rest/v1.2/sites/181977606"
89+
}
90+
}
91+
}
92+
},
7793
"categories": {
7894
"Architecture": {
7995
"ID": 2290,
@@ -322,7 +338,7 @@
322338
}
323339
}
324340
],
325-
"next_page_handle": "ZnJvbT0xMCZiZWZvcmU9MjAyMy0wOC0yMlQwOSUzQTAyJTNBMTElMkIwOCUzQTAw",
341+
"next_page_handle": null,
326342
"date_range": {
327343
"before": "2023-08-21T22:44:57-04:00",
328344
"after": "2023-08-22T09:02:11+08:00"
+9-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"request": {
33
"method": "POST",
4-
"urlPath": "/rest/v1.1/read/tags/travel/mine/new",
4+
"urlPathPattern": "/rest/v1.1/read/tags/([^/]+)/mine/new",
55
"queryParameters": {
66
"locale": {
77
"matches": "(.*)"
@@ -15,11 +15,11 @@
1515
"tags": [
1616
{
1717
"ID": "123",
18-
"slug": "travel",
19-
"title": "Travel",
20-
"display_name": "travel",
18+
"slug": "{{request.pathSegments.[4]}}",
19+
"title": "{{capitalize request.pathSegments.[4]}}",
20+
"display_name": "{{request.pathSegments.[4]}}",
2121
"description": null,
22-
"URL": "https://public-api.wordpress.com/rest/v1.1/read/tags/travel/posts"
22+
"URL": "https://public-api.wordpress.com/rest/v1.1/read/tags/{{request.pathSegments.[4]}}/posts"
2323
}
2424
],
2525
"added_tag": "123"
@@ -28,6 +28,9 @@
2828
"Content-Type": "application/json",
2929
"Connection": "keep-alive",
3030
"Cache-Control": "no-cache, must-revalidate, max-age=0"
31-
}
31+
},
32+
"transformers": [
33+
"response-template"
34+
]
3235
}
3336
}

Modules/Sources/UITestsFoundation/Screens/CommentsScreen.swift

+29-15
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,46 @@ import XCTest
33

44
public class CommentsScreen: ScreenObject {
55

6+
private let addCommentButtonGetter: (XCUIApplication) -> XCUIElement = {
7+
$0.otherElements["button_add_comment_large"]
8+
}
9+
10+
private let backButtonGetter: (XCUIApplication) -> XCUIElement = {
11+
$0.navigationBars.buttons["Reader"]
12+
}
13+
14+
private let emptyImageGetter: (XCUIApplication) -> XCUIElement = {
15+
$0.images["wp-illustration-reader-empty"]
16+
}
17+
618
private let navigationBarTitleGetter: (XCUIApplication) -> XCUIElement = {
719
$0.navigationBars["Comments"]
820
}
921

1022
private let replyFieldGetter: (XCUIApplication) -> XCUIElement = {
11-
$0.otherElements["reply-to-post-text-field"]
23+
$0.textViews["edit_comment_text_view"]
1224
}
1325

1426
private let replyMessageNoticeGetter: (XCUIApplication) -> XCUIElement = {
1527
$0.otherElements["notice_title_and_message"]
1628
}
1729

18-
private let backButtonGetter: (XCUIApplication) -> XCUIElement = {
19-
$0.navigationBars.buttons["Reader"]
20-
}
21-
22-
private let replyButtonGetter: (XCUIApplication) -> XCUIElement = {
23-
$0.buttons["Reply"]
30+
private let sendButtonGetter: (XCUIApplication) -> XCUIElement = {
31+
$0.buttons["button_send_comment"]
2432
}
2533

34+
var addCommentButton: XCUIElement { addCommentButtonGetter(app) }
2635
var backButton: XCUIElement { backButtonGetter(app) }
27-
var replyButton: XCUIElement { replyButtonGetter(app) }
36+
var emptyImage: XCUIElement { emptyImageGetter(app) }
2837
var replyField: XCUIElement { replyFieldGetter(app) }
2938
var replyMessageNotice: XCUIElement { replyMessageNoticeGetter(app) }
39+
var sendButton: XCUIElement { sendButtonGetter(app) }
3040

3141
init(app: XCUIApplication = XCUIApplication()) throws {
3242
try super.init(
3343
expectedElementGetters: [
3444
navigationBarTitleGetter,
35-
replyFieldGetter
45+
addCommentButtonGetter
3646
],
3747
app: app
3848
)
@@ -49,21 +59,25 @@ public class CommentsScreen: ScreenObject {
4959

5060
@discardableResult
5161
public func replyToPost(_ comment: String) -> CommentsScreen {
52-
replyField.tap()
62+
addCommentButton.tap()
5363
replyField.typeText(comment)
54-
replyButton.tap()
64+
sendButton.tap()
5565
return self
5666
}
5767

5868
public func verifyCommentsListEmpty() -> CommentsScreen {
59-
XCTAssertTrue(app.tables.firstMatch.label == "Empty list")
69+
XCTAssertTrue(emptyImage.waitForExistence(timeout: 3))
6070
XCTAssertTrue(app.staticTexts["Be the first to leave a comment."].isHittable)
61-
XCTAssertTrue(app.cells.count == 0)
71+
XCTAssertTrue(app.cells.containing(.button, identifier: "reply-comment-button").count == 0)
6272
return self
6373
}
6474

6575
public func verifyCommentSent(_ content: String) {
66-
XCTAssertTrue(replyMessageNotice.waitForIsHittable(), "'Reply Sent' message was not displayed.")
67-
XCTAssertTrue(app.cells.containing(.textView, identifier: content).count == 1, "Comment was not visible")
76+
let comment = app.cells.containing(.staticText, identifier: content)
77+
let commentExists = comment.firstMatch.waitForExistence(timeout: 3)
78+
let commentIsUnique = comment.count == 1
79+
80+
XCTAssertTrue(commentExists, "Comment not found.")
81+
XCTAssertTrue(commentIsUnique, "Multiple comments found.")
6882
}
6983
}

Modules/Sources/UITestsFoundation/Screens/ReaderMenuScreen.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ public final class ReaderMenuScreen: ScreenObject {
1313
case discover
1414
case saved
1515
case likes
16+
case search
1617

1718
func menuButton(_ app: XCUIApplication) -> XCUIElement {
18-
app.staticTexts["reader_sidebar_\(rawValue)"].firstMatch
19+
app.otherElements["reader_sidebar_\(rawValue)"].firstMatch
1920
}
2021
}
2122

Modules/Sources/UITestsFoundation/Screens/ReaderScreen.swift

+3-5
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ public class ReaderScreen: ScreenObject {
99
var followingButton: XCUIElement { app.buttons["Following"] }
1010
var subscriptionsMenuButton: XCUIElement { app.buttons["Subscriptions"] }
1111
var likesTabButton: XCUIElement { app.buttons["Likes"] }
12-
var noResultsView: XCUIElement { app.staticTexts["no-results-label-stack-view"].firstMatch }
1312
var readerButton: XCUIElement { app.buttons["Reader"] }
1413
var readerTable: XCUIElement { app.tables["reader_table_view"] }
1514
var savedButton: XCUIElement { app.buttons["Saved"] }
16-
var tagCellButton: XCUIElement { app.cells["topics-card-cell-button"] }
15+
var tagCellButton: XCUIElement { app.cells["topics-card-cell"].firstMatch.buttons.firstMatch }
1716
var visitButton: XCUIElement { app.buttons["Visit"] }
1817
var ghostLoading: XCUIElement { app.tables["Reader Ghost Loading"] }
1918

@@ -45,7 +44,7 @@ public class ReaderScreen: ScreenObject {
4544

4645
@discardableResult
4746
public func getLastPost() throws -> XCUIElement {
48-
guard let post = app.cells.lastMatch else {
47+
guard let post = readerTable.cells.lastMatch else {
4948
throw UIElementNotFoundError(message: "ReaderScreen: No posts loaded")
5049
}
5150
scrollDownUntilElementIsFullyVisible(element: post)
@@ -64,7 +63,7 @@ public class ReaderScreen: ScreenObject {
6463

6564
private func postContentEquals(_ expected: String) -> Bool {
6665
let equalsPostContent = NSPredicate(format: "label == %@", expected)
67-
let isPostContentEqual = app.staticTexts.element(matching: equalsPostContent).waitForIsHittable(timeout: 3)
66+
let isPostContentEqual = app.staticTexts.element(matching: equalsPostContent).waitForIsHittable(timeout: 60)
6867

6968
return isPostContentEqual
7069
}
@@ -213,7 +212,6 @@ public class ReaderScreen: ScreenObject {
213212
}
214213

215214
private func verifyEmptyPostList(file: StaticString = #file, line: UInt = #line) {
216-
XCTAssertTrue(noResultsView.waitForExistence(timeout: 5), file: file, line: line)
217215
XCTAssertTrue(readerTable.label == .emptyListLabel, file: file, line: line)
218216
}
219217
}

WordPress/Classes/ViewRelated/Reader/Controllers/ReaderDiscoverViewController.swift

+1
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ private class ReaderDiscoverStreamViewController: ReaderStreamViewController {
283283
private func makeRecommendedTagsCell(for interests: [ReaderTagTopic]) -> UITableViewCell {
284284
let cell = tableView.dequeueReusableCell(withIdentifier: readerCardTopicsIdentifier) as! ReaderRecommendedTagsCell
285285
cell.configure(with: interests, delegate: self)
286+
cell.accessibilityIdentifier = "topics-card-cell"
286287
hideSeparator(for: cell)
287288
return cell
288289
}

WordPress/UITests/Tests/ReaderTests.swift

+6-6
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,19 @@ class ReaderTests: XCTestCase {
2525
}
2626

2727
class ReaderTests_01: ReaderTests {
28-
func _testViewPost() throws {
28+
func testViewPost() throws {
2929
try openStream(.recent)
3030
.openLastPost()
3131
.verifyPostContentEquals(.expectedPostContent)
3232
}
3333

34-
func _testViewPostInSafari() throws {
34+
func testViewPostInSafari() throws {
3535
try openStream(.recent)
3636
.openLastPostInSafari()
3737
.verifyPostContentEquals(.expectedPostContent)
3838
}
3939

40-
func _testDiscover() throws {
40+
func testDiscover() throws {
4141
try openStream(.discover)
4242
.selectTag()
4343
.verifyTagLoaded()
@@ -47,15 +47,15 @@ class ReaderTests_01: ReaderTests {
4747
}
4848

4949
class ReaderTests_02: ReaderTests {
50-
func _testAddCommentToPost() throws {
50+
func testAddCommentToPost() throws {
5151
try openStream(.recent)
5252
.openLastPostComments()
5353
.verifyCommentsListEmpty()
5454
.replyToPost(.commentContent)
5555
.verifyCommentSent(.commentContent)
5656
}
5757

58-
func _testSavePost() throws {
58+
func testSavePost() throws {
5959
// Get saved post label
6060
let (updatedReaderScreen, savedPostLabel) = try openStream(.saved)
6161
.verifySavedPosts(state: .withoutPosts)
@@ -68,7 +68,7 @@ class ReaderTests_02: ReaderTests {
6868
.verifySavedPosts(state: .withPosts, postLabel: savedPostLabel)
6969
}
7070

71-
func _testLikePost() throws {
71+
func testLikePost() throws {
7272
try openStream(.likes)
7373
.verifyLikedPosts(state: .withoutPosts)
7474
.switchToStream(.recent)

0 commit comments

Comments
 (0)