diff --git a/PediFoodsUITests/CartCheckoutFlowTests.swift b/PediFoodsUITests/CartCheckoutFlowTests.swift index 7ce87f2..f3d4ec4 100644 --- a/PediFoodsUITests/CartCheckoutFlowTests.swift +++ b/PediFoodsUITests/CartCheckoutFlowTests.swift @@ -17,6 +17,67 @@ final class CartCheckoutFlowTests: XCTestCase { func testAddProductToCartAndReachCheckout() throws { let app = XCUIApplication() app.launch() + try reachCheckoutWithOneItem(app) + } + + /// Exercises CheckoutView's payment-method selection and the address + /// picker's "Alterar" entry point without ever tapping "Confirmar e + /// Pagar" - deliberately not submitting a real order (per explicit + /// user direction: cover the screen, don't create real order data). + func testCheckoutPaymentMethodSelectionAndAddressAlterar() throws { + let app = XCUIApplication() + app.launch() + try reachCheckoutWithOneItem(app) + + XCTAssertTrue(app.staticTexts["MÉTODO DE PAGAMENTO"].waitForExistence(timeout: 5)) + + // PIX is the default selection; only tap an alternative if this + // store's real catalog actually offers one - don't assume Cartão + // de Crédito exists (in-app payment methods depend on real store + // config, already found to vary - see the standing-account state + // notes in decisions/2026-08-06-ui-test-account-and-app-attest-bypass.md). + let creditCardRow = app.buttons.matching(NSPredicate(format: "label CONTAINS[c] %@", "Cartão de Crédito")).firstMatch + if creditCardRow.exists { + creditCardRow.tap() + } + + XCTAssertTrue(app.staticTexts["TIPO DE ENTREGA"].waitForExistence(timeout: 5)) + + app.buttons["Alterar"].tap() + XCTAssertTrue( + app.staticTexts["Meus Endereços"].waitForExistence(timeout: 10), + "Alterar never opened the address picker" + ) + + // Dismiss without changing anything, back to Checkout. .isHittable, + // not just .exists: a Back button that exists but is mid-transition + // throws a fatal, uncatchable "not hittable" failure on tap - same + // issue already fixed in UITestSupport.reachProfileTabRegardlessOfAuthState. + // Poll briefly since the push-in animation can still be settling + // right after "Meus Endereços" first becomes visible. + let backButton = app.buttons.matching(NSPredicate(format: "label == %@", "Back")).firstMatch + var dismissed = false + for _ in 0..<10 { + if backButton.exists, backButton.isHittable { + backButton.tap() + dismissed = true + break + } + usleep(200_000) + } + if dismissed == false { + app.swipeDown() + } + if app.staticTexts["Finalizar Pedido"].waitForExistence(timeout: 10) == false { + let dir = "/private/tmp/claude-501/-Users-loverde-co-Documents-Loverde-JOBs-Producao-Loverde-Co-LC-RAG-Struct-projects-PediFoods-ios/4a9ec4f7-c3ad-4cf5-8dad-073446f6fd81/scratchpad" + try? app.screenshot().pngRepresentation.write(to: URL(fileURLWithPath: "\(dir)/after_alterar_dismiss.png")) + } + XCTAssertTrue(app.staticTexts["Finalizar Pedido"].exists, "Never returned to Checkout") + + // Deliberately not tapping "Confirmar e Pagar" - see doc comment. + } + + private func reachCheckoutWithOneItem(_ app: XCUIApplication) throws { XCTAssertTrue(app.ensureLoggedIn(), "Login never completed") // ensureLoggedIn can land on whichever tab it detected the