// // EntryDetailScreen.swift // Tests iOS // // Screen object for the Entry Detail sheet (edit mood, notes, delete). // import XCTest struct EntryDetailScreen { let app: XCUIApplication // MARK: - Elements var navigationTitle: XCUIElement { app.navigationBars["Entry Details"] } var doneButton: XCUIElement { app.buttons["entry_detail_done"] } var deleteButton: XCUIElement { app.buttons["entry_detail_delete"] } var moodGrid: XCUIElement { app.otherElements["entry_detail_mood_grid"] } /// Mood buttons inside the detail sheet's mood grid. /// Match by the mood_button_ identifier prefix to avoid matching entry rows. func moodButton(for mood: MoodChoice) -> XCUIElement { app.buttons["mood_button_\(mood.rawValue)"] } // MARK: - Actions func dismiss() { let button = doneButton _ = button.waitForExistence(timeout: 5) button.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5)).tap() } func selectMood(_ mood: MoodChoice) { let button = moodButton(for: mood) _ = button.waitForExistence(timeout: 5) button.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5)).tap() } func deleteEntry() { let button = deleteButton _ = button.waitForExistence(timeout: 5) button.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5)).tap() // Confirm the delete alert let deleteAlert = app.alerts["Delete Entry"] let confirmButton = deleteAlert.buttons["Delete"] _ = confirmButton.waitForExistence(timeout: 5) confirmButton.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5)).tap() } // MARK: - Assertions func assertVisible(file: StaticString = #file, line: UInt = #line) { XCTAssertTrue( navigationTitle.waitForExistence(timeout: 5), "Entry Detail sheet should be visible", file: file, line: line ) } func assertDismissed(file: StaticString = #file, line: UInt = #line) { XCTAssertTrue( navigationTitle.waitForDisappearance(timeout: 5), "Entry Detail sheet should be dismissed", file: file, line: line ) } }