166 lines
5.1 KiB
Swift
166 lines
5.1 KiB
Swift
//
|
|
// TripCustomItemTests.swift
|
|
// SportsTimeUITests
|
|
//
|
|
// Tests for custom itinerary item lifecycle: add, edit, delete.
|
|
// QA Sheet: F-068, F-069, F-070
|
|
//
|
|
|
|
import XCTest
|
|
|
|
final class TripCustomItemTests: BaseUITestCase {
|
|
|
|
// MARK: - Helpers
|
|
|
|
/// Plans a trip, saves it, and opens it from My Trips (enables custom items).
|
|
@MainActor
|
|
private func openSavedTripDetail() -> TripDetailScreen {
|
|
return TestFlows.planSaveAndOpenFromMyTrips(app: app)
|
|
}
|
|
|
|
/// Adds a custom item with the given title via the add sheet flow.
|
|
@MainActor
|
|
private func addCustomItem(detail: TripDetailScreen, title: String) {
|
|
detail.tapAddItem()
|
|
|
|
let addSheet = QuickAddItemSheetScreen(app: app)
|
|
addSheet.waitForLoad()
|
|
addSheet.typeTitle(title)
|
|
addSheet.tapSave()
|
|
|
|
// Wait for sheet to dismiss
|
|
addSheet.waitForDismiss()
|
|
}
|
|
|
|
// MARK: - F-068: Add custom item to day
|
|
|
|
/// F-068: Open saved trip → tap Add on day header → fill in title → save → item appears.
|
|
@MainActor
|
|
func testF068_AddCustomItemToDay() {
|
|
let detail = openSavedTripDetail()
|
|
|
|
// Tap "Add" on a day header
|
|
detail.tapAddItem()
|
|
|
|
let addSheet = QuickAddItemSheetScreen(app: app)
|
|
addSheet.waitForLoad()
|
|
|
|
// Save button should be disabled without a title
|
|
XCTAssertFalse(
|
|
addSheet.saveButton.isEnabled,
|
|
"Save button should be disabled without a title"
|
|
)
|
|
|
|
// Type a description
|
|
addSheet.typeTitle("Lunch at Pizzeria")
|
|
|
|
// Save button should now be enabled
|
|
XCTAssertTrue(
|
|
addSheet.saveButton.isEnabled,
|
|
"Save button should be enabled after entering a title"
|
|
)
|
|
|
|
addSheet.tapSave()
|
|
|
|
// Sheet should dismiss
|
|
addSheet.waitForDismiss()
|
|
|
|
// Custom item should appear in the itinerary
|
|
let customItem = detail.customItemCell
|
|
XCTAssertTrue(
|
|
customItem.waitForExistence(timeout: BaseUITestCase.defaultTimeout),
|
|
"Custom item should appear in itinerary after adding"
|
|
)
|
|
|
|
captureScreenshot(named: "F068-CustomItemAdded")
|
|
}
|
|
|
|
// MARK: - F-069: Edit custom item
|
|
|
|
/// F-069: Add a custom item → tap to edit → change title → save → updated title visible.
|
|
@MainActor
|
|
func testF069_EditCustomItem() {
|
|
let detail = openSavedTripDetail()
|
|
|
|
// Add an item first
|
|
addCustomItem(detail: detail, title: "Original Title")
|
|
|
|
// Verify item exists
|
|
XCTAssertTrue(
|
|
detail.customItemCell.waitForExistence(timeout: BaseUITestCase.defaultTimeout),
|
|
"Custom item should exist before editing"
|
|
)
|
|
|
|
// Tap the custom item to open edit sheet
|
|
detail.tapCustomItem()
|
|
|
|
let editSheet = QuickAddItemSheetScreen(app: app)
|
|
editSheet.waitForLoad()
|
|
|
|
// Clear and type new title
|
|
editSheet.clearAndTypeTitle("Updated Title")
|
|
editSheet.tapSave()
|
|
|
|
// Sheet should dismiss
|
|
editSheet.waitForDismiss()
|
|
|
|
// Verify edited item still exists in itinerary
|
|
XCTAssertTrue(
|
|
detail.customItemCell.waitForExistence(timeout: BaseUITestCase.defaultTimeout),
|
|
"Custom item should remain visible after editing"
|
|
)
|
|
|
|
// Re-open to verify updated title persisted (more reliable than global static text lookup).
|
|
detail.tapCustomItem()
|
|
let verifySheet = QuickAddItemSheetScreen(app: app)
|
|
verifySheet.waitForLoad()
|
|
|
|
let persistedTitle = (verifySheet.titleField.value as? String) ?? ""
|
|
XCTAssertTrue(
|
|
persistedTitle.localizedCaseInsensitiveContains("Updated Title"),
|
|
"Updated custom item title should persist after saving; found: '\(persistedTitle)'"
|
|
)
|
|
verifySheet.tapCancel()
|
|
verifySheet.waitForDismiss()
|
|
|
|
captureScreenshot(named: "F069-CustomItemEdited")
|
|
}
|
|
|
|
// MARK: - F-070: Delete custom item
|
|
|
|
/// F-070: Add a custom item → long-press → tap Delete in context menu → item removed.
|
|
@MainActor
|
|
func testF070_DeleteCustomItem() {
|
|
let detail = openSavedTripDetail()
|
|
|
|
// Add an item first
|
|
addCustomItem(detail: detail, title: "Item to Delete")
|
|
|
|
// Verify item exists
|
|
let customItem = detail.customItemCell
|
|
XCTAssertTrue(
|
|
customItem.waitForExistence(timeout: BaseUITestCase.defaultTimeout),
|
|
"Custom item should exist before deletion"
|
|
)
|
|
|
|
// Long-press to show context menu
|
|
detail.longPressCustomItem()
|
|
|
|
// Tap "Delete" in the context menu
|
|
let deleteButton = app.buttons["Delete"]
|
|
XCTAssertTrue(
|
|
deleteButton.waitForExistence(timeout: BaseUITestCase.shortTimeout),
|
|
"Delete button should appear in context menu"
|
|
)
|
|
deleteButton.tap()
|
|
|
|
// Custom item should disappear
|
|
customItem.waitForNonExistence(
|
|
timeout: BaseUITestCase.defaultTimeout,
|
|
"Custom item should be removed after deletion"
|
|
)
|
|
|
|
captureScreenshot(named: "F070-CustomItemDeleted")
|
|
}
|
|
}
|