Forji/Forji/ForjiUITests/PullRequestUITests.swift
Stefan Hausotte 5adc0102eb feat: inital commit
Forji is an iOS app to interact with a Forgejo instance
2026-02-28 21:08:13 +01:00

153 lines
5.5 KiB
Swift

import XCTest
final class PullRequestUITests: ForgejoReadOnlyUITestBase {
override func tearDown() {
navigateBackToHome()
super.tearDown()
}
// MARK: - PR Tab Content (list, filter, detail, review, diff, comment)
@MainActor
func testPRTabContent() throws {
navigateToPRTab()
// PR list shows open PRs
XCTAssertTrue(app.staticTexts["Add feature file"].waitForExistence(timeout: 10))
XCTAssertTrue(app.staticTexts["Merge test PR"].waitForExistence(timeout: 5))
// Filter by Closed
let closedButton = app.buttons["Closed"]
XCTAssertTrue(closedButton.waitForExistence(timeout: 10))
closedButton.tap()
XCTAssertTrue(app.staticTexts["No Pull Requests"].waitForExistence(timeout: 10))
// Back to Open
let openButton = app.buttons["Open"]
XCTAssertTrue(openButton.waitForExistence(timeout: 5))
openButton.tap()
XCTAssertTrue(app.staticTexts["Add feature file"].waitForExistence(timeout: 10))
// PR detail title, branches
let prCell = app.staticTexts["Add feature file"].firstMatch
prCell.tap()
let titleText = app.staticTexts["pr-detail-title"]
XCTAssertTrue(titleText.waitForExistence(timeout: 10))
XCTAssertTrue(app.staticTexts["feature-branch"].waitForExistence(timeout: 5))
XCTAssertTrue(app.staticTexts["main"].waitForExistence(timeout: 5))
// Milestone and assignee (adjacent sections, both near top of list)
XCTAssertTrue(app.staticTexts["v1.0"].waitForExistence(timeout: 5), "PR milestone should be visible")
XCTAssertTrue(app.staticTexts["@testadmin"].waitForExistence(timeout: 10), "PR assignee should be visible")
// Review (may need scroll to reach review section)
app.swipeUp()
XCTAssertTrue(app.staticTexts["commented"].waitForExistence(timeout: 15))
// Diff shows feature.txt (scroll down past description and reviews)
app.swipeUp()
XCTAssertTrue(app.staticTexts["feature.txt"].waitForExistence(timeout: 10))
// Scroll down to see comment from testbot
app.swipeUp()
XCTAssertTrue(app.staticTexts["testbot"].waitForExistence(timeout: 10))
}
// MARK: - Diff View context line has no comment button
@MainActor
func testDiffViewContextLineHasNoCommentButton() throws {
navigateToPRTab()
let prCell = app.staticTexts["Add feature file"].firstMatch
XCTAssertTrue(prCell.waitForExistence(timeout: 10))
prCell.tap()
XCTAssertTrue(app.staticTexts["pr-detail-title"].waitForExistence(timeout: 10))
// Open review sheet to see the diff with inline comment support
app.swipeUp()
expandActionMenu()
let reviewButton = app.buttons["pr-submit-review"]
XCTAssertTrue(reviewButton.waitForExistence(timeout: 10))
reviewButton.tap()
XCTAssertTrue(app.staticTexts["Submit Review"].waitForExistence(timeout: 5))
// The diff should show feature.txt
XCTAssertTrue(app.staticTexts["feature.txt"].waitForExistence(timeout: 10))
// Dismiss
app.buttons["Cancel"].tap()
}
// MARK: - Pull Requests Overview (all PRs, filter, search)
@MainActor
func testPullRequestsOverview() throws {
app.tabBars.buttons["Pull Requests"].tap()
// Test PRs were created by testbot switch scope to "All" to see them
setOverviewScopeAll()
XCTAssertTrue(app.staticTexts["Add feature file"].waitForExistence(timeout: 10))
// Filter state to All via toolbar menu
let filterMenuButton = app.buttons["filter-menu-button"]
XCTAssertTrue(filterMenuButton.waitForExistence(timeout: 5))
filterMenuButton.tap()
app.buttons["All"].firstMatch.tap()
// Search
let searchField = app.searchFields.firstMatch
XCTAssertTrue(searchField.waitForExistence(timeout: 5))
searchField.tap()
searchField.typeText("feature")
XCTAssertTrue(app.staticTexts["Add feature file"].waitForExistence(timeout: 10))
}
// MARK: - Pull Requests Overview Involvement Filter
@MainActor
func testPullRequestsOverviewInvolvementFilter() throws {
app.tabBars.buttons["Pull Requests"].tap()
// Reset filters to defaults (previous test may have changed them)
resetOverviewFilters()
// Default filter summary should show "Open · Created by you"
let filterSummary = app.staticTexts["filter-summary"]
XCTAssertTrue(filterSummary.waitForExistence(timeout: 5))
XCTAssertEqual(filterSummary.label, "Open · Created by you")
let filterMenuButton = app.buttons["filter-menu-button"]
// Tap "Assigned to you" via filter menu
filterMenuButton.tap()
app.buttons["Assigned to you"].tap()
sleep(2)
XCTAssertTrue(filterSummary.label.contains("Assigned to you"))
// Tap "Mentioned" via filter menu
filterMenuButton.tap()
app.buttons["Mentioned"].tap()
sleep(2)
XCTAssertTrue(filterSummary.label.contains("Mentioned"))
// Tap back to "All" scope via filter menu
filterMenuButton.tap()
app.buttons["All"].firstMatch.tap()
sleep(2)
// "Review requested" SHOULD be present for PRs
filterMenuButton.tap()
let reviewButton = app.buttons["Review requested"]
XCTAssertTrue(reviewButton.exists, "Review filter should appear for pull requests")
// Dismiss the menu by tapping elsewhere
app.tap()
}
}