| @@ -310,7 +310,7 @@ final class LiveSmokeUITests: XCTestCase { |
| 310 | openRepo(Self.fixtureRepo) |
310 | openRepo(Self.fixtureRepo) |
| 311 | |
311 | |
| 312 | // --- the fixture issue: milestone picker assigns the fixture --- |
312 | // --- the fixture issue: milestone picker assigns the fixture --- |
| 313 | app.staticTexts["Issues"].firstMatch.tap() |
313 | repoLink("issues").tap() |
| 314 | let issueRow = app.staticTexts |
314 | let issueRow = app.staticTexts |
| 315 | .containing(NSPredicate(format: "label CONTAINS 'ui-smoke fixture'")).firstMatch |
315 | .containing(NSPredicate(format: "label CONTAINS 'ui-smoke fixture'")).firstMatch |
| 316 | XCTAssertTrue(issueRow.waitForExistence(timeout: 10), |
316 | XCTAssertTrue(issueRow.waitForExistence(timeout: 10), |
| @@ -367,7 +367,7 @@ final class LiveSmokeUITests: XCTestCase { |
| 367 | back() // to repo screen |
367 | back() // to repo screen |
| 368 | |
368 | |
| 369 | // --- MR: create from ui-smoke, then close it --- |
369 | // --- MR: create from ui-smoke, then close it --- |
| 370 | app.staticTexts["Merge Requests"].firstMatch.tap() |
370 | repoLink("merge-requests").tap() |
| 371 | app.descendants(matching: .any).matching(identifier: "mr-create-button") |
371 | app.descendants(matching: .any).matching(identifier: "mr-create-button") |
| 372 | .firstMatch.tap() |
372 | .firstMatch.tap() |
| 373 | |
373 | |
| @@ -434,7 +434,7 @@ final class LiveSmokeUITests: XCTestCase { |
| 434 | XCTAssertTrue(row.waitForExistence(timeout: 15), "\(path) not in the repo list") |
434 | XCTAssertTrue(row.waitForExistence(timeout: 15), "\(path) not in the repo list") |
| 435 | row.tap() |
435 | row.tap() |
| 436 | // Repo screen is loaded once its links render. |
436 | // Repo screen is loaded once its links render. |
| 437 | XCTAssertTrue(app.staticTexts["Files"].firstMatch.waitForExistence(timeout: 10), |
437 | XCTAssertTrue(repoLink("files").waitForExistence(timeout: 10), |
| 438 | "repo screen did not open") |
438 | "repo screen did not open") |
| 439 | } |
439 | } |
| 440 | |
440 | |
| @@ -442,6 +442,34 @@ final class LiveSmokeUITests: XCTestCase { |
| 442 | app.navigationBars.buttons.firstMatch.tap() |
442 | app.navigationBars.buttons.firstMatch.tap() |
| 443 | } |
443 | } |
| 444 | |
444 | |
| |
445 | /// One of the four links in the grid at the top of the repo screen. |
| |
446 | private func repoLink(_ id: String) -> XCUIElement { |
| |
447 | app.descendants(matching: .any).matching(identifier: "repo-link-\(id)").firstMatch |
| |
448 | } |
| |
449 | |
| |
450 | /// A link in the repo screen's More section, below the README. |
| |
451 | /// Expands the section when it is still collapsed. |
| |
452 | private func moreLink(_ title: String) -> XCUIElement { |
| |
453 | let link = app.staticTexts[title].firstMatch |
| |
454 | if link.exists { return link } |
| |
455 | let more = app.descendants(matching: .any).matching(identifier: "repo-more").firstMatch |
| |
456 | XCTAssertTrue(scrollTo(more, swipes: 20), "More section not reachable") |
| |
457 | more.tap() |
| |
458 | XCTAssertTrue(scrollTo(link), "\(title) not under More") |
| |
459 | return link |
| |
460 | } |
| |
461 | |
| |
462 | /// Settings is in the repo screen's actions menu. |
| |
463 | private func openRepoSettings() { |
| |
464 | let menu = app.descendants(matching: .any) |
| |
465 | .matching(identifier: "repo-actions-menu").firstMatch |
| |
466 | XCTAssertTrue(menu.waitForExistence(timeout: 10), "repo actions menu missing") |
| |
467 | menu.tap() |
| |
468 | let settings = app.buttons["Settings"].firstMatch |
| |
469 | XCTAssertTrue(settings.waitForExistence(timeout: 5), "Settings missing from the actions menu") |
| |
470 | settings.tap() |
| |
471 | } |
| |
472 | |
| 445 | /// Keys, PGP and email live behind the account menu, which is on the |
473 | /// Keys, PGP and email live behind the account menu, which is on the |
| 446 | /// My Profile tab and nowhere else. |
474 | /// My Profile tab and nowhere else. |
| 447 | func openAccountScreen(file: StaticString = #filePath, line: UInt = #line) { |
475 | func openAccountScreen(file: StaticString = #filePath, line: UInt = #line) { |
| @@ -589,8 +617,8 @@ extension LiveSmokeUITests { |
| 589 | |
617 | |
| 590 | // --- access: grant a user on the scratch repo, then revoke --- |
618 | // --- access: grant a user on the scratch repo, then revoke --- |
| 591 | app.staticTexts[Self.scratchRepo].firstMatch.tap() |
619 | app.staticTexts[Self.scratchRepo].firstMatch.tap() |
| 592 | XCTAssertTrue(app.staticTexts["Files"].firstMatch.waitForExistence(timeout: 10)) |
620 | XCTAssertTrue(repoLink("files").waitForExistence(timeout: 10)) |
| 593 | app.staticTexts["Settings"].firstMatch.tap() |
621 | openRepoSettings() |
| 594 | let grantUser = app.descendants(matching: .any) |
622 | let grantUser = app.descendants(matching: .any) |
| 595 | .matching(identifier: "settings-grant-user").firstMatch |
623 | .matching(identifier: "settings-grant-user").firstMatch |
| 596 | XCTAssertTrue(scrollTo(grantUser, swipes: 8), "access section not reachable") |
624 | XCTAssertTrue(scrollTo(grantUser, swipes: 8), "access section not reachable") |
| @@ -639,12 +667,7 @@ extension LiveSmokeUITests { |
| 639 | if firstRename { |
667 | if firstRename { |
| 640 | firstRename = false // already on the settings screen |
668 | firstRename = false // already on the settings screen |
| 641 | } else { |
669 | } else { |
| 642 | // Fresh repo screen: scroll to the top so no row hides |
670 | self.openRepoSettings() |
| 643 | // under the navigation bar, then reach Settings. |
| |
| 644 | self.app.swipeDown() |
| |
| 645 | let settingsLink = self.app.descendants(matching: .any).matching(identifier: "repo-settings-link").firstMatch |
| |
| 646 | XCTAssertTrue(self.scrollTo(settingsLink), "settings link not reachable") |
| |
| 647 | settingsLink.tap() |
| |
| 648 | } |
671 | } |
| 649 | let renameButton = self.app.descendants(matching: .any) |
672 | let renameButton = self.app.descendants(matching: .any) |
| 650 | .matching(identifier: "settings-rename-button").firstMatch |
673 | .matching(identifier: "settings-rename-button").firstMatch |
| @@ -664,8 +687,10 @@ extension LiveSmokeUITests { |
| 664 | for _ in 0..<6 where !renamedLink.exists { self.app.swipeDown() } |
687 | for _ in 0..<6 where !renamedLink.exists { self.app.swipeDown() } |
| 665 | XCTAssertTrue(renamedLink.waitForExistence(timeout: 10), "rename did not land") |
688 | XCTAssertTrue(renamedLink.waitForExistence(timeout: 10), "rename did not land") |
| 666 | renamedLink.tap() |
689 | renamedLink.tap() |
| 667 | XCTAssertTrue(self.app.staticTexts[expectedPath].firstMatch.waitForExistence(timeout: 15), |
690 | // The repo screen's title is the name alone; the header |
| 668 | "renamed repo did not open as \(expectedPath)") |
691 | // splits the path into the owner link and the rest. |
| |
692 | XCTAssertTrue(self.app.navigationBars.staticTexts[newName].firstMatch |
| |
693 | .waitForExistence(timeout: 15), "renamed repo did not open as \(expectedPath)") |
| 669 | } |
694 | } |
| 670 | rename("ui-smoke-2", Self.scratchRepo + "-2") |
695 | rename("ui-smoke-2", Self.scratchRepo + "-2") |
| 671 | rename("ui-smoke", Self.scratchRepo) |
696 | rename("ui-smoke", Self.scratchRepo) |
| @@ -681,7 +706,7 @@ extension LiveSmokeUITests { |
| 681 | let repoRow = app.staticTexts["krz/gitbay-ios"].firstMatch |
706 | let repoRow = app.staticTexts["krz/gitbay-ios"].firstMatch |
| 682 | XCTAssertTrue(repoRow.waitForExistence(timeout: 15)) |
707 | XCTAssertTrue(repoRow.waitForExistence(timeout: 15)) |
| 683 | repoRow.tap() |
708 | repoRow.tap() |
| 684 | XCTAssertTrue(app.staticTexts["Files"].firstMatch.waitForExistence(timeout: 10)) |
709 | XCTAssertTrue(repoLink("files").waitForExistence(timeout: 10)) |
| 685 | let menu = app.descendants(matching: .any) |
710 | let menu = app.descendants(matching: .any) |
| 686 | .matching(identifier: "repo-actions-menu").firstMatch |
711 | .matching(identifier: "repo-actions-menu").firstMatch |
| 687 | XCTAssertTrue(menu.waitForExistence(timeout: 10)) |
712 | XCTAssertTrue(menu.waitForExistence(timeout: 10)) |
| @@ -729,12 +754,7 @@ extension LiveSmokeUITests { |
| 729 | unbookmark.tap() |
754 | unbookmark.tap() |
| 730 | |
755 | |
| 731 | // --- settings: topic and merge-rule round-trips --- |
756 | // --- settings: topic and merge-rule round-trips --- |
| 732 | // The links section can sit below the README fold, and the row's |
757 | openRepoSettings() |
| 733 | // label is not always exposed as a static text. |
| |
| 734 | let settingsLink = app.descendants(matching: .any) |
| |
| 735 | .matching(identifier: "repo-settings-link").firstMatch |
| |
| 736 | XCTAssertTrue(scrollTo(settingsLink), "settings link not reachable") |
| |
| 737 | settingsLink.tap() |
| |
| 738 | let addTopic = app.descendants(matching: .any) |
758 | let addTopic = app.descendants(matching: .any) |
| 739 | .matching(identifier: "settings-add-topic").firstMatch |
759 | .matching(identifier: "settings-add-topic").firstMatch |
| 740 | XCTAssertTrue(addTopic.waitForExistence(timeout: 10), "settings did not load") |
760 | XCTAssertTrue(addTopic.waitForExistence(timeout: 10), "settings did not load") |
| @@ -822,14 +842,11 @@ extension LiveSmokeUITests { |
| 822 | |
842 | |
| 823 | |
843 | |
| 824 | back() // settings -> repo |
844 | back() // settings -> repo |
| 825 | // The repo screen keeps the scroll that reached Settings, which |
| |
| 826 | // can leave Builds under the navigation bar. |
| |
| 827 | app.swipeDown() |
| |
| 828 | |
845 | |
| 829 | // --- nothing to trigger without a job file --- |
846 | // --- nothing to trigger without a job file --- |
| 830 | // This repo has no .gitbay/ci.yml, so `build jobs` returns none |
847 | // This repo has no .gitbay/ci.yml, so `build jobs` returns none |
| 831 | // and the control is gated rather than failing after a guess. |
848 | // and the control is gated rather than failing after a guess. |
| 832 | app.staticTexts["Builds"].firstMatch.tap() |
849 | repoLink("builds").tap() |
| 833 | let trigger = app.descendants(matching: .any) |
850 | let trigger = app.descendants(matching: .any) |
| 834 | .matching(identifier: "build-trigger-button").firstMatch |
851 | .matching(identifier: "build-trigger-button").firstMatch |
| 835 | XCTAssertTrue(trigger.waitForExistence(timeout: 15), "trigger control missing") |
852 | XCTAssertTrue(trigger.waitForExistence(timeout: 15), "trigger control missing") |
| @@ -877,13 +894,12 @@ extension LiveSmokeUITests { |
| 877 | XCTAssertTrue(hit.waitForExistence(timeout: 15), |
894 | XCTAssertTrue(hit.waitForExistence(timeout: 15), |
| 878 | "server-side topic search found nothing") |
895 | "server-side topic search found nothing") |
| 879 | hit.tap() |
896 | hit.tap() |
| 880 | XCTAssertTrue(app.staticTexts["Files"].firstMatch.waitForExistence(timeout: 10)) |
897 | XCTAssertTrue(repoLink("files").waitForExistence(timeout: 10)) |
| 881 | |
898 | |
| 882 | // --- owner profile from the repo screen --- |
899 | // --- owner profile from the repo screen --- |
| 883 | // The row's label merges; match it at any element type. It is |
900 | let ownerLink = app.descendants(matching: .any) |
| 884 | // the last row of the links section, below the fold. |
901 | .matching(identifier: "repo-owner-link").firstMatch |
| 885 | let ownerLink = app.descendants(matching: .any)["krz"].firstMatch |
902 | XCTAssertTrue(ownerLink.waitForExistence(timeout: 10), "owner link missing") |
| 886 | XCTAssertTrue(scrollTo(ownerLink), "owner link not reachable") |
| |
| 887 | ownerLink.tap() |
903 | ownerLink.tap() |
| 888 | XCTAssertTrue(app.staticTexts["warez for the public"].firstMatch |
904 | XCTAssertTrue(app.staticTexts["warez for the public"].firstMatch |
| 889 | .waitForExistence(timeout: 15), "profile did not load") |
905 | .waitForExistence(timeout: 15), "profile did not load") |
| @@ -893,7 +909,7 @@ extension LiveSmokeUITests { |
| 893 | back() |
909 | back() |
| 894 | |
910 | |
| 895 | // --- grep inside the repo, last: its search UI owns the screen --- |
911 | // --- grep inside the repo, last: its search UI owns the screen --- |
| 896 | app.staticTexts["Search in Files"].firstMatch.tap() |
912 | moreLink("Search in Files").tap() |
| 897 | let grepField = app.searchFields.firstMatch |
913 | let grepField = app.searchFields.firstMatch |
| 898 | XCTAssertTrue(grepField.waitForExistence(timeout: 10)) |
914 | XCTAssertTrue(grepField.waitForExistence(timeout: 10)) |
| 899 | focusAndType(grepField, "space") |
915 | focusAndType(grepField, "space") |
| @@ -910,7 +926,7 @@ extension LiveSmokeUITests { |
| 910 | /// missing-tag refusal on create. Nothing changes state. |
926 | /// missing-tag refusal on create. Nothing changes state. |
| 911 | func testReleaseFlows() throws { |
927 | func testReleaseFlows() throws { |
| 912 | openRepo("krz/gitbay") |
928 | openRepo("krz/gitbay") |
| 913 | app.staticTexts["Releases"].firstMatch.tap() |
929 | moreLink("Releases").tap() |
| 914 | |
930 | |
| 915 | // Newest first, and the list has grown past the fold, so the |
931 | // Newest first, and the list has grown past the fold, so the |
| 916 | // first row is whichever release is current. |
932 | // first row is whichever release is current. |
| @@ -1119,7 +1135,7 @@ extension LiveSmokeUITests { |
| 1119 | openRepo("krz/gitbay") |
1135 | openRepo("krz/gitbay") |
| 1120 | snap("repo") |
1136 | snap("repo") |
| 1121 | |
1137 | |
| 1122 | app.staticTexts["Merge Requests"].firstMatch.tap() |
1138 | repoLink("merge-requests").tap() |
| 1123 | let all = app.segmentedControls.buttons["All"].firstMatch |
1139 | let all = app.segmentedControls.buttons["All"].firstMatch |
| 1124 | XCTAssertTrue(all.waitForExistence(timeout: 10), "state picker missing") |
1140 | XCTAssertTrue(all.waitForExistence(timeout: 10), "state picker missing") |
| 1125 | all.tap() |
1141 | all.tap() |
| @@ -1208,7 +1224,7 @@ extension LiveSmokeUITests { |
| 1208 | func testBlameAndEditFlows() throws { |
1224 | func testBlameAndEditFlows() throws { |
| 1209 | // --- blame on a real file --- |
1225 | // --- blame on a real file --- |
| 1210 | openRepo("krz/gitbay") |
1226 | openRepo("krz/gitbay") |
| 1211 | app.staticTexts["Files"].firstMatch.tap() |
1227 | repoLink("files").tap() |
| 1212 | let goMod = app.staticTexts["go.mod"].firstMatch |
1228 | let goMod = app.staticTexts["go.mod"].firstMatch |
| 1213 | XCTAssertTrue(goMod.waitForExistence(timeout: 15), "go.mod not in the tree") |
1229 | XCTAssertTrue(goMod.waitForExistence(timeout: 15), "go.mod not in the tree") |
| 1214 | goMod.tap() |
1230 | goMod.tap() |
| @@ -1228,7 +1244,7 @@ extension LiveSmokeUITests { |
| 1228 | app.terminate() |
1244 | app.terminate() |
| 1229 | app.launch() |
1245 | app.launch() |
| 1230 | openRepo(Self.fixtureRepo) |
1246 | openRepo(Self.fixtureRepo) |
| 1231 | app.staticTexts["Files"].firstMatch.tap() |
1247 | repoLink("files").tap() |
| 1232 | let notes = app.staticTexts["notes.txt"].firstMatch |
1248 | let notes = app.staticTexts["notes.txt"].firstMatch |
| 1233 | XCTAssertTrue(notes.waitForExistence(timeout: 15), "notes.txt not in the tree") |
1249 | XCTAssertTrue(notes.waitForExistence(timeout: 15), "notes.txt not in the tree") |
| 1234 | notes.tap() |
1250 | notes.tap() |
| @@ -1344,7 +1360,7 @@ extension LiveSmokeUITests { |
| 1344 | app.terminate() |
1360 | app.terminate() |
| 1345 | app.launch() |
1361 | app.launch() |
| 1346 | openRepo("krz/gitbay") |
1362 | openRepo("krz/gitbay") |
| 1347 | app.staticTexts["History"].firstMatch.tap() |
1363 | moreLink("History").tap() |
| 1348 | let firstCommit = app.cells.firstMatch |
1364 | let firstCommit = app.cells.firstMatch |
| 1349 | XCTAssertTrue(firstCommit.waitForExistence(timeout: 20), "history is empty") |
1365 | XCTAssertTrue(firstCommit.waitForExistence(timeout: 20), "history is empty") |
| 1350 | firstCommit.tap() |
1366 | firstCommit.tap() |
| @@ -1368,7 +1384,7 @@ extension LiveSmokeUITests { |
| 1368 | openRepo("krz/gitbay") |
1384 | openRepo("krz/gitbay") |
| 1369 | |
1385 | |
| 1370 | // --- branches and tags, and browsing at a ref --- |
1386 | // --- branches and tags, and browsing at a ref --- |
| 1371 | app.staticTexts["Branches & Tags"].firstMatch.tap() |
1387 | moreLink("Branches & Tags").tap() |
| 1372 | let main = app.staticTexts["main"].firstMatch |
1388 | let main = app.staticTexts["main"].firstMatch |
| 1373 | XCTAssertTrue(main.waitForExistence(timeout: 20), "refs did not load") |
1389 | XCTAssertTrue(main.waitForExistence(timeout: 20), "refs did not load") |
| 1374 | XCTAssertTrue(app.staticTexts["default"].firstMatch.exists, |
1390 | XCTAssertTrue(app.staticTexts["default"].firstMatch.exists, |
| @@ -1382,7 +1398,7 @@ extension LiveSmokeUITests { |
| 1382 | back() |
1398 | back() |
| 1383 | |
1399 | |
| 1384 | // --- milestones with progress --- |
1400 | // --- milestones with progress --- |
| 1385 | app.staticTexts["Milestones"].firstMatch.tap() |
1401 | moreLink("Milestones").tap() |
| 1386 | XCTAssertTrue(app.segmentedControls.firstMatch.waitForExistence(timeout: 15), |
1402 | XCTAssertTrue(app.segmentedControls.firstMatch.waitForExistence(timeout: 15), |
| 1387 | "milestones did not load") |
1403 | "milestones did not load") |
| 1388 | app.segmentedControls.buttons["All"].firstMatch.tap() |
1404 | app.segmentedControls.buttons["All"].firstMatch.tap() |
| @@ -1392,7 +1408,7 @@ extension LiveSmokeUITests { |
| 1392 | back() |
1408 | back() |
| 1393 | |
1409 | |
| 1394 | // --- an MR's milestone reads back, and can be cleared --- |
1410 | // --- an MR's milestone reads back, and can be cleared --- |
| 1395 | app.staticTexts["Merge Requests"].firstMatch.tap() |
1411 | repoLink("merge-requests").tap() |
| 1396 | app.segmentedControls.buttons["All"].firstMatch.tap() |
1412 | app.segmentedControls.buttons["All"].firstMatch.tap() |
| 1397 | let mrNumber = app.staticTexts |
1413 | let mrNumber = app.staticTexts |
| 1398 | .containing(NSPredicate(format: "label BEGINSWITH '!'")).firstMatch |
1414 | .containing(NSPredicate(format: "label BEGINSWITH '!'")).firstMatch |
| @@ -1427,7 +1443,7 @@ extension LiveSmokeUITests { |
| 1427 | .containing(NSPredicate(format: "label CONTAINS 'audit-labs/'")).firstMatch |
1443 | .containing(NSPredicate(format: "label CONTAINS 'audit-labs/'")).firstMatch |
| 1428 | .waitForExistence(timeout: 10), "explore is not the public listing") |
1444 | .waitForExistence(timeout: 10), "explore is not the public listing") |
| 1429 | firstRepo.tap() |
1445 | firstRepo.tap() |
| 1430 | XCTAssertTrue(app.staticTexts["Files"].firstMatch.waitForExistence(timeout: 20), |
1446 | XCTAssertTrue(repoLink("files").waitForExistence(timeout: 20), |
| 1431 | "explore row did not open its repo") |
1447 | "explore row did not open its repo") |
| 1432 | |
1448 | |
| 1433 | // --- history at a ref --- |
1449 | // --- history at a ref --- |
| @@ -1436,7 +1452,7 @@ extension LiveSmokeUITests { |
| 1436 | openRepo("krz/gitbay") |
1452 | openRepo("krz/gitbay") |
| 1437 | // Browse a ref, then ask for its history — the move the tree page |
1453 | // Browse a ref, then ask for its history — the move the tree page |
| 1438 | // offers on the web. |
1454 | // offers on the web. |
| 1439 | app.staticTexts["Branches & Tags"].firstMatch.tap() |
1455 | moreLink("Branches & Tags").tap() |
| 1440 | let main = app.staticTexts["main"].firstMatch |
1456 | let main = app.staticTexts["main"].firstMatch |
| 1441 | XCTAssertTrue(main.waitForExistence(timeout: 20), "refs did not load") |
1457 | XCTAssertTrue(main.waitForExistence(timeout: 20), "refs did not load") |
| 1442 | main.tap() |
1458 | main.tap() |
| @@ -1458,7 +1474,7 @@ extension LiveSmokeUITests { |
| 1458 | /// krz/gitbay#48. Read-only; editing is a push, on every surface. |
1474 | /// krz/gitbay#48. Read-only; editing is a push, on every surface. |
| 1459 | func testWikiFlows() throws { |
1475 | func testWikiFlows() throws { |
| 1460 | openRepo("krz/gitbay") |
1476 | openRepo("krz/gitbay") |
| 1461 | app.staticTexts["Wiki"].firstMatch.tap() |
1477 | moreLink("Wiki").tap() |
| 1462 | |
1478 | |
| 1463 | // The landing page leads and is marked. |
1479 | // The landing page leads and is marked. |
| 1464 | let home = app.staticTexts["Home"].firstMatch |
1480 | let home = app.staticTexts["Home"].firstMatch |
| @@ -1488,7 +1504,7 @@ extension LiveSmokeUITests { |
| 1488 | /// server names, and the detail screen says more than the log. |
1504 | /// server names, and the detail screen says more than the log. |
| 1489 | func testBuildJobsAndDetail() throws { |
1505 | func testBuildJobsAndDetail() throws { |
| 1490 | openRepo("krz/gitbay") |
1506 | openRepo("krz/gitbay") |
| 1491 | app.staticTexts["Builds"].firstMatch.tap() |
1507 | repoLink("builds").tap() |
| 1492 | |
1508 | |
| 1493 | // The picker lists jobs from `build jobs` — no name to type. |
1509 | // The picker lists jobs from `build jobs` — no name to type. |
| 1494 | let trigger = app.descendants(matching: .any) |
1510 | let trigger = app.descendants(matching: .any) |
| @@ -1535,7 +1551,7 @@ extension LiveSmokeUITests { |
| 1535 | let firstRepo = app.cells.firstMatch |
1551 | let firstRepo = app.cells.firstMatch |
| 1536 | XCTAssertTrue(firstRepo.waitForExistence(timeout: 20), "explore listed nothing") |
1552 | XCTAssertTrue(firstRepo.waitForExistence(timeout: 20), "explore listed nothing") |
| 1537 | firstRepo.tap() |
1553 | firstRepo.tap() |
| 1538 | XCTAssertTrue(app.staticTexts["Files"].firstMatch.waitForExistence(timeout: 20), |
1554 | XCTAssertTrue(repoLink("files").waitForExistence(timeout: 20), |
| 1539 | "repo screen did not open") |
1555 | "repo screen did not open") |
| 1540 | snap("repo") |
1556 | snap("repo") |
| 1541 | |
1557 | |
| @@ -1782,7 +1798,7 @@ extension LiveSmokeUITests { |
| 1782 | /// filtered empty state. Clearing brings the list back. |
1798 | /// filtered empty state. Clearing brings the list back. |
| 1783 | func testBuildFilterFlow() throws { |
1799 | func testBuildFilterFlow() throws { |
| 1784 | openRepo("krz/gitbay") |
1800 | openRepo("krz/gitbay") |
| 1785 | app.staticTexts["Builds"].firstMatch.tap() |
1801 | repoLink("builds").tap() |
| 1786 | XCTAssertTrue(app.cells.firstMatch.waitForExistence(timeout: 20), "no builds listed") |
1802 | XCTAssertTrue(app.cells.firstMatch.waitForExistence(timeout: 20), "no builds listed") |
| 1787 | |
1803 | |
| 1788 | let filter = app.descendants(matching: .any) |
1804 | let filter = app.descendants(matching: .any) |
| @@ -1837,7 +1853,7 @@ extension LiveSmokeUITests { |
| 1837 | else { throw XCTSkip("could not read krz/gitbay's builds over the API") } |
1853 | else { throw XCTSkip("could not read krz/gitbay's builds over the API") } |
| 1838 | |
1854 | |
| 1839 | openRepo("krz/gitbay") |
1855 | openRepo("krz/gitbay") |
| 1840 | app.staticTexts["Builds"].firstMatch.tap() |
1856 | repoLink("builds").tap() |
| 1841 | XCTAssertTrue(app.cells.firstMatch.waitForExistence(timeout: 20), "no builds listed") |
1857 | XCTAssertTrue(app.cells.firstMatch.waitForExistence(timeout: 20), "no builds listed") |
| 1842 | let thirtyFirst = app.staticTexts |
1858 | let thirtyFirst = app.staticTexts |
| 1843 | .containing(NSPredicate(format: "label BEGINSWITH %@", "#\(number) ")).firstMatch |
1859 | .containing(NSPredicate(format: "label BEGINSWITH %@", "#\(number) ")).firstMatch |
| @@ -1850,7 +1866,7 @@ extension LiveSmokeUITests { |
| 1850 | /// links to it. |
1866 | /// links to it. |
| 1851 | func testCloseInFavourFlow() throws { |
1867 | func testCloseInFavourFlow() throws { |
| 1852 | openRepo(Self.fixtureRepo) |
1868 | openRepo(Self.fixtureRepo) |
| 1853 | app.staticTexts["Merge Requests"].firstMatch.tap() |
1869 | repoLink("merge-requests").tap() |
| 1854 | let superseded = app.staticTexts[Self.supersededTitle].firstMatch |
1870 | let superseded = app.staticTexts[Self.supersededTitle].firstMatch |
| 1855 | XCTAssertTrue(superseded.waitForExistence(timeout: 15), "fixture MR not listed") |
1871 | XCTAssertTrue(superseded.waitForExistence(timeout: 15), "fixture MR not listed") |
| 1856 | superseded.tap() |
1872 | superseded.tap() |
| @@ -1885,7 +1901,7 @@ extension LiveSmokeUITests { |
| 1885 | /// list filters to it, and removing it clears the chip. |
1901 | /// list filters to it, and removing it clears the chip. |
| 1886 | func testMRLabelFlow() throws { |
1902 | func testMRLabelFlow() throws { |
| 1887 | openRepo(Self.fixtureRepo) |
1903 | openRepo(Self.fixtureRepo) |
| 1888 | app.staticTexts["Merge Requests"].firstMatch.tap() |
1904 | repoLink("merge-requests").tap() |
| 1889 | let row = app.staticTexts[Self.labelledTitle].firstMatch |
1905 | let row = app.staticTexts[Self.labelledTitle].firstMatch |
| 1890 | XCTAssertTrue(row.waitForExistence(timeout: 15), "fixture MR not listed") |
1906 | XCTAssertTrue(row.waitForExistence(timeout: 15), "fixture MR not listed") |
| 1891 | row.tap() |
1907 | row.tap() |
| @@ -1923,7 +1939,7 @@ extension LiveSmokeUITests { |
| 1923 | /// the bold markers are gone and the word remains. Nothing is posted. |
1939 | /// the bold markers are gone and the word remains. Nothing is posted. |
| 1924 | func testMarkupPreviewFlow() throws { |
1940 | func testMarkupPreviewFlow() throws { |
| 1925 | openRepo(Self.fixtureRepo) |
1941 | openRepo(Self.fixtureRepo) |
| 1926 | app.staticTexts["Issues"].firstMatch.tap() |
1942 | repoLink("issues").tap() |
| 1927 | let issue = app.staticTexts[Self.fixtureIssueTitle].firstMatch |
1943 | let issue = app.staticTexts[Self.fixtureIssueTitle].firstMatch |
| 1928 | XCTAssertTrue(issue.waitForExistence(timeout: 15), "fixture issue not listed") |
1944 | XCTAssertTrue(issue.waitForExistence(timeout: 15), "fixture issue not listed") |
| 1929 | issue.tap() |
1945 | issue.tap() |