Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions FlipcashUITests/Regression/CashLinkRegressionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import XCTest

/// Regression test for the cash link lifecycle: create a cash link, confirm it was "sent",
/// then navigate to transaction history and cancel it.
/// then navigate to transaction history and cancel it from the row's details.
///
/// **Prerequisites:**
/// - A valid `FLIPCASH_UI_TEST_ACCESS_KEY` set in `secrets.local.xcconfig`
Expand All @@ -22,6 +22,7 @@ final class CashLinkRegressionTests: BaseUITestCase {

func testCashLink_createAndCancel() {
let currencyInfo = CurrencyInfoUIScreen(app: app)
let details = TransactionDetailsUIScreen(app: app)

assertMainScreenReached()

Expand Down Expand Up @@ -60,22 +61,19 @@ final class CashLinkRegressionTests: BaseUITestCase {
// per-token history.
currencyInfo.tapRecentActivityHeader(from: self)

// Step 3: Tap the first "Sending" row to trigger the cancel dialog.
// Rows are List cells containing "Sending" as a static text label.
// There may be multiple pending cash links — tap the most recent (first) one.
// Step 3: Open the first "Sending" row. Rows are List cells containing
// "Sending" as a static text label. There may be multiple pending cash
// links — open the most recent (first) one. Tapping a row pushes the
// transaction's Details screen; it no longer prompts to cancel directly.
let sendingLabel = app.staticTexts.matching(identifier: "Sending").firstMatch
XCTAssertTrue(
sendingLabel.waitForExistence(timeout: 10),
"Expected a 'Sending' transaction in history"
)
sendingLabel.tap()
details.assertReached()

// Step 4: Confirm cancellation.
let cancelTransfer = app.buttons["Cancel Transfer"]
XCTAssertTrue(
cancelTransfer.waitForExistence(timeout: 5),
"Expected 'Cancel Transfer' confirmation dialog"
)
cancelTransfer.tap()
// Step 4: Cancel from the Details screen's trailing action and confirm.
details.cancelTransfer(from: self)
}
}
60 changes: 60 additions & 0 deletions FlipcashUITests/Support/Screens/TransactionDetailsUIScreen.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//
// TransactionDetailsUIScreen.swift
// FlipcashUITests
//

import XCTest

/// Page object for `TransactionDetailsScreen` — the screen a tapped activity
/// row pushes from the per-token history.
///
/// Cancelling a pending cash link is the bar's trailing "Cancel" action, which
/// confirms through a "Cancel … Transfer?" dialog rather than acting directly.
@MainActor
struct TransactionDetailsUIScreen {

private let app: XCUIApplication

init(app: XCUIApplication) {
self.app = app
}

// MARK: - Elements

/// The screen's inline navigation title.
var navigationBar: XCUIElement { app.navigationBars["Details"] }

/// The bar's trailing Cancel action, present only while the activity can
/// still be cancelled.
var cancelButton: XCUIElement { navigationBar.buttons["Cancel"] }

/// The destructive confirmation in the "Cancel … Transfer?" dialog.
var cancelTransferButton: XCUIElement { app.buttons["Cancel Transfer"] }

// MARK: - Actions

/// Cancels the shown transfer: taps the bar's Cancel action, then confirms
/// the dialog.
func cancelTransfer(from testCase: BaseUITestCase) {
testCase.waitAndTap(
cancelButton,
timeout: 10,
"Expected the Details screen's Cancel action for a pending cash link"
)
testCase.waitAndTap(
cancelTransferButton,
timeout: 5,
"Expected 'Cancel Transfer' confirmation dialog"
)
}

// MARK: - Assertions

/// Asserts the details screen was pushed.
func assertReached(timeout: TimeInterval = 10) {
XCTAssertTrue(
navigationBar.waitForExistence(timeout: timeout),
"Expected the transaction Details screen (navigation title 'Details')"
)
}
}
Loading