Skip to content

Commit 5f9aba4

Browse files
gbirch-stripecodex
andcommitted
[PaymentSheet] Expand Checkout Session synchronization UI coverage
Committed-By-Agent: codex Co-authored-by: codex <noreply@openai.com>
1 parent 38b1db2 commit 5f9aba4

4 files changed

Lines changed: 61 additions & 12 deletions

File tree

Example/PaymentSheet Example/PaymentSheet Example/Checkout Playground/CheckoutCartContentView.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ struct CheckoutCartContentView: View {
9494
Text("\((item.unitAmountDecimal ?? item.unitAmount).amount) × \(item.quantity)")
9595
.font(.subheadline)
9696
.foregroundColor(.secondary)
97+
.accessibilityIdentifier("checkout_line_item_amount")
9798
}
9899
Spacer()
99100
}
@@ -246,6 +247,7 @@ struct CheckoutCartContentView: View {
246247
Spacer()
247248
Text(totals.subtotal.amount)
248249
.foregroundColor(.primary)
250+
.accessibilityIdentifier("checkout_subtotal_amount")
249251
}
250252
if totals.discount.minorUnitsAmount > 0 {
251253
HStack {
@@ -254,6 +256,7 @@ struct CheckoutCartContentView: View {
254256
Spacer()
255257
Text("-" + totals.discount.amount)
256258
.foregroundColor(.green)
259+
.accessibilityIdentifier("checkout_discount_amount")
257260
}
258261
}
259262

@@ -267,6 +270,7 @@ struct CheckoutCartContentView: View {
267270
}
268271
.frame(maxWidth: .infinity, alignment: .leading)
269272
.accessibilityElement(children: .combine)
273+
.accessibilityIdentifier("checkout_tax_prompt")
270274
} else if totals.taxExclusive.minorUnitsAmount > 0 {
271275
HStack {
272276
HStack(spacing: 4) {
@@ -279,6 +283,7 @@ struct CheckoutCartContentView: View {
279283
Spacer()
280284
Text(totals.taxExclusive.amount)
281285
.foregroundColor(.primary)
286+
.accessibilityIdentifier("checkout_tax_amount")
282287
}
283288
}
284289

@@ -291,6 +296,7 @@ struct CheckoutCartContentView: View {
291296
Spacer()
292297
Text(totals.total.amount)
293298
.font(.title3).bold()
299+
.accessibilityIdentifier("checkout_total_amount")
294300
}
295301

296302
if taxAddressPrompt == nil && totals.taxInclusive.minorUnitsAmount > 0 {

Example/PaymentSheet Example/PaymentSheet Example/Checkout Playground/CheckoutCartPaymentButton.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ struct CheckoutCartBuyButton: View {
119119
}
120120
.padding(.horizontal)
121121
.disabled(checkout.isUpdating)
122+
.accessibilityIdentifier("checkout_buy_button")
122123
}
123124
}
124125

Example/PaymentSheet Example/PaymentSheet Example/Checkout Playground/CheckoutCartViewController.swift

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ final class CheckoutCartViewController: UIViewController {
368368
unitAmountLabel.text = "\((item.unitAmountDecimal ?? item.unitAmount).amount) × \(item.quantity)"
369369
unitAmountLabel.font = .preferredFont(forTextStyle: .subheadline)
370370
unitAmountLabel.textColor = .secondaryLabel
371+
unitAmountLabel.accessibilityIdentifier = "checkout_line_item_amount"
371372

372373
let detailsStackView = UIStackView(arrangedSubviews: [nameLabel, unitAmountLabel])
373374
detailsStackView.axis = .vertical
@@ -456,7 +457,8 @@ final class CheckoutCartViewController: UIViewController {
456457
summaryStackView.addArrangedSubview(
457458
makeSummaryRow(
458459
title: "Subtotal",
459-
amount: totals.subtotal.amount
460+
amount: totals.subtotal.amount,
461+
amountAccessibilityIdentifier: "checkout_subtotal_amount"
460462
)
461463
)
462464

@@ -465,7 +467,8 @@ final class CheckoutCartViewController: UIViewController {
465467
makeSummaryRow(
466468
title: "Discount",
467469
amount: "-" + totals.discount.amount,
468-
color: .systemGreen
470+
color: .systemGreen,
471+
amountAccessibilityIdentifier: "checkout_discount_amount"
469472
)
470473
)
471474
}
@@ -477,7 +480,8 @@ final class CheckoutCartViewController: UIViewController {
477480
makeSummaryRow(
478481
title: "Tax",
479482
amount: totals.taxExclusive.amount,
480-
showsTaxDetailsButton: hasTaxDetails
483+
showsTaxDetailsButton: hasTaxDetails,
484+
amountAccessibilityIdentifier: "checkout_tax_amount"
481485
)
482486
)
483487
}
@@ -487,7 +491,8 @@ final class CheckoutCartViewController: UIViewController {
487491
makeSummaryRow(
488492
title: "Total",
489493
amount: totals.total.amount,
490-
emphasizesText: true
494+
emphasizesText: true,
495+
amountAccessibilityIdentifier: "checkout_total_amount"
491496
)
492497
)
493498

@@ -524,6 +529,7 @@ final class CheckoutCartViewController: UIViewController {
524529
stackView.spacing = 2
525530
stackView.isAccessibilityElement = true
526531
stackView.accessibilityLabel = "Tax. \(message)"
532+
stackView.accessibilityIdentifier = "checkout_tax_prompt"
527533
return stackView
528534
}
529535

@@ -543,7 +549,8 @@ final class CheckoutCartViewController: UIViewController {
543549
amount: String,
544550
color: UIColor = .secondaryLabel,
545551
emphasizesText: Bool = false,
546-
showsTaxDetailsButton: Bool = false
552+
showsTaxDetailsButton: Bool = false,
553+
amountAccessibilityIdentifier: String? = nil
547554
) -> UIView {
548555
let titleLabel = UILabel()
549556
titleLabel.text = title
@@ -555,6 +562,7 @@ final class CheckoutCartViewController: UIViewController {
555562
amountLabel.textColor = emphasizesText ? .label : (color == .systemGreen ? color : .label)
556563
amountLabel.font = .preferredFont(forTextStyle: emphasizesText ? .headline : .body)
557564
amountLabel.setContentHuggingPriority(.required, for: .horizontal)
565+
amountLabel.accessibilityIdentifier = amountAccessibilityIdentifier
558566

559567
let titleStackView = UIStackView(arrangedSubviews: [titleLabel])
560568
titleStackView.alignment = .center
@@ -642,6 +650,7 @@ final class CheckoutCartViewController: UIViewController {
642650

643651
let formattedAmount = session.totals.total.amount
644652
button.accessibilityLabel = "Buy, \(formattedAmount)"
653+
button.accessibilityIdentifier = "checkout_buy_button"
645654

646655
let stackView = UIStackView(arrangedSubviews: [titleLabel])
647656
stackView.isUserInteractionEnabled = false

Example/PaymentSheet Example/PaymentSheetUITest/CheckoutElementsUITests.swift

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,38 @@ final class CheckoutElementsUITests: PaymentSheetUITestCase {
1717
app.buttons["Create Checkout Session"].waitForExistenceAndTap()
1818

1919
XCTAssertTrue(app.navigationBars["Your Cart"].waitForExistence(timeout: 15))
20-
XCTAssertTrue(app.staticTexts["Enter shipping address to calculate"].waitForExistence(timeout: 10))
20+
let lineItemAmount = app.staticTexts["checkout_line_item_amount"].firstMatch
21+
let subtotalAmount = app.staticTexts["checkout_subtotal_amount"]
22+
let totalAmount = app.staticTexts["checkout_total_amount"]
23+
let buyButton = app.buttons["checkout_buy_button"]
24+
let taxPrompt = app.descendants(matching: .any)["checkout_tax_prompt"]
25+
XCTAssertTrue(lineItemAmount.waitForExistence(timeout: 10))
26+
XCTAssertTrue(subtotalAmount.exists)
27+
XCTAssertTrue(totalAmount.exists)
28+
XCTAssertTrue(buyButton.exists)
29+
XCTAssertTrue(taxPrompt.exists)
30+
31+
// Then the merchant surface and Payment Element reflect the localized Session
32+
XCTAssertTrue(lineItemAmount.label.contains(""))
33+
XCTAssertTrue(subtotalAmount.label.contains(""))
34+
XCTAssertEqual(totalAmount.label, subtotalAmount.label)
35+
XCTAssertTrue(buyButton.label.contains(totalAmount.label))
36+
XCTAssertTrue(app.buttons["Select payment method"].exists)
2137

2238
// When the customer selects the integration currency in Currency Selector Element
2339
let usdCurrencyOption = app.buttons["currency_option_usd"]
2440
usdCurrencyOption.waitForExistenceAndTap()
2541

26-
// Then the merchant surface reflects the new Session
27-
XCTAssertTrue(app.staticTexts["$120.00"].waitForExistence(timeout: 10))
42+
// Then every merchant-owned amount reflects the new Session
43+
expectation(
44+
for: NSPredicate(format: "label == %@", "$120.00"),
45+
evaluatedWith: totalAmount,
46+
handler: nil
47+
)
48+
waitForExpectations(timeout: 10)
49+
XCTAssertTrue(lineItemAmount.label.contains("$"))
50+
XCTAssertEqual(subtotalAmount.label, "$120.00")
51+
XCTAssertTrue(buyButton.label.contains("$120.00"))
2852
expectation(
2953
for: NSPredicate(format: "hittable == true"),
3054
evaluatedWith: usdCurrencyOption,
@@ -46,7 +70,19 @@ final class CheckoutElementsUITests: PaymentSheetUITestCase {
4670
// Then the merchant surface reflects the new Session
4771
XCTAssertTrue(app.staticTexts["Jane Doe"].waitForExistence(timeout: 10))
4872
XCTAssertTrue(app.staticTexts["510 Townsend St"].exists)
49-
XCTAssertFalse(app.staticTexts["Enter shipping address to calculate"].exists)
73+
expectation(
74+
for: NSPredicate(format: "exists == false"),
75+
evaluatedWith: taxPrompt,
76+
handler: nil
77+
)
78+
waitForExpectations(timeout: 10)
79+
let taxAmount = app.staticTexts["checkout_tax_amount"]
80+
XCTAssertTrue(taxAmount.waitForExistence(timeout: 10))
81+
XCTAssertTrue(taxAmount.label.contains("$"))
82+
XCTAssertNotEqual(taxAmount.label, "$0.00")
83+
XCTAssertEqual(subtotalAmount.label, "$120.00")
84+
XCTAssertNotEqual(totalAmount.label, subtotalAmount.label)
85+
XCTAssertTrue(buyButton.label.contains(totalAmount.label))
5086

5187
// When the customer selects a card in Payment Element
5288
app.buttons["Select payment method"].scrollToAndTap(in: app)
@@ -62,9 +98,6 @@ final class CheckoutElementsUITests: PaymentSheetUITestCase {
6298

6399
// Then the merchant surface reflects the selected payment method after Checkout updates.
64100
XCTAssertTrue(app.staticTexts["•••• 4242"].waitForExistence(timeout: 10))
65-
let buyButton = app.buttons.matching(
66-
NSPredicate(format: "label BEGINSWITH %@", "Buy")
67-
).firstMatch
68101
buyButton.scrollToAndTap(in: app)
69102

70103
XCTAssertTrue(app.alerts["Success"].waitForExistence(timeout: 20))

0 commit comments

Comments
 (0)