diff --git a/PediFoodsUITests/CartCheckoutFlowTests.swift b/PediFoodsUITests/CartCheckoutFlowTests.swift index f3d4ec4..170d579 100644 --- a/PediFoodsUITests/CartCheckoutFlowTests.swift +++ b/PediFoodsUITests/CartCheckoutFlowTests.swift @@ -77,6 +77,43 @@ final class CartCheckoutFlowTests: XCTestCase { // Deliberately not tapping "Confirmar e Pagar" - see doc comment. } + /// With "Cartão de Crédito" selected, "Confirmar e Pagar" does NOT + /// submit an order immediately - `CheckoutView+Logic.handleConfirmPaymentTap()` + /// returns early and opens `CardSelectionSheet` instead (real order + /// creation only happens if a saved card is then picked and confirmed + /// inside that sheet, which this test does not do). Confirmed by + /// reading the source before relying on it - this is a real, + /// deliberate app behavior, not an assumption. + func testConfirmarEPagarWithCreditCardOpensCardSelectionWithoutSubmitting() throws { + let app = XCUIApplication() + app.launch() + try reachCheckoutWithOneItem(app) + + let creditCardRow = app.buttons.matching(NSPredicate(format: "label CONTAINS[c] %@", "Cartão de Crédito")).firstMatch + XCTAssertTrue(creditCardRow.waitForExistence(timeout: 5), "This store is expected to offer Cartão de Crédito") + creditCardRow.tap() + + app.buttons["Confirmar e Pagar"].tap() + XCTAssertTrue(app.staticTexts["Selecionar Cartão"].waitForExistence(timeout: 10), "Never reached the card selection sheet") + + // Dismiss via the sheet's own "x" close button - never selects a + // card, never submits anything. + let closeButton = app.buttons.matching(identifier: "xmark").firstMatch + var dismissed = false + for _ in 0..<10 { + if closeButton.exists, closeButton.isHittable { + closeButton.tap() + dismissed = true + break + } + usleep(200_000) + } + if dismissed == false { + app.swipeDown() + } + XCTAssertTrue(app.staticTexts["Finalizar Pedido"].waitForExistence(timeout: 10), "Never returned to Checkout") + } + private func reachCheckoutWithOneItem(_ app: XCUIApplication) throws { XCTAssertTrue(app.ensureLoggedIn(), "Login never completed") @@ -97,11 +134,25 @@ final class CartCheckoutFlowTests: XCTestCase { XCTAssertTrue(storeCard.exists, "Expected store card never appeared on Home") storeCard.tap() - // A plain (non-addon, non-pizza) product row's "+" button adds - // directly with no sheet - identified by its SF Symbol name like - // the rest of this app's icon-only controls (person.fill, etc). - let addButton = app.buttons.matching(identifier: "plus").firstMatch - XCTAssertTrue(addButton.waitForExistence(timeout: 15), "Store Detail's product list never loaded") + // A plain (non-addon, non-pizza) product row's "+" control adds + // directly with no sheet. Once a product's quantity is > 0, its + // outer Button's identifier moves off itself - the same badge- + // merging bug already fixed for the tab bar's cart icon - because + // the row's own quantity Text becomes the Button's accessible + // label/identity instead. The QA account's cart has genuinely + // accumulated real quantities across many runs today, so + // app.buttons.matching(identifier: "plus") stopped matching once + // the first several products all had quantity > 0 (confirmed via + // screenshot: the "+" controls were clearly visible on screen + // while the buttons-only query found nothing). The nested Image + // keeps identifier "plus" regardless of quantity, so target that + // directly instead - same fix pattern as the cart-tab icon. + let addButton = app.images.matching(identifier: "plus").firstMatch + if addButton.waitForExistence(timeout: 25) == 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)/store_detail_timeout40.png")) + } + XCTAssertTrue(addButton.exists, "Store Detail's product list never loaded") addButton.tap() // Once the cart has items, the tab bar button's accessible label diff --git a/PediFoodsUITests/UITestSupport.swift b/PediFoodsUITests/UITestSupport.swift index c07ba28..52ff997 100644 --- a/PediFoodsUITests/UITestSupport.swift +++ b/PediFoodsUITests/UITestSupport.swift @@ -162,7 +162,10 @@ extension XCUIApplication { buttons["Receber Código"].tap() - guard staticTexts["Verificação"].waitForExistence(timeout: 15) else { return false } + // The real "request OTP" backend call has been observed taking + // longer than 15s under load - confirmed via trace (waited the + // full 15s, "Verificação" never appeared, not a broken selector). + guard staticTexts["Verificação"].waitForExistence(timeout: 25) else { return false } textFields.firstMatch.tap() guard keys["6"].waitForExistence(timeout: 5) else { return false } for digit in otp {