Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ STOREFRONT_ACCESS_TOKEN=your-public-storefront-access-token
# Optional Apple Pay merchant identifier used by accelerated checkout flows.
STOREFRONT_MERCHANT_IDENTIFIER=

# Apple team that signs the Swift samples. Set your own team id, or the Xcode build
# fails at signing. A blank value stays blank; setup applies no default team.
DEVELOPMENT_TEAM=

# Storefront API version
API_VERSION=2026-04

Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
- 'Package.swift'
- 'Package.resolved'
- '.github/workflows/swift-test-package.yml'
- '.github/workflows/swift-build-samples.yml'
- '.github/workflows/swift-build-and-test-samples.yml'
- '.github/workflows/swift-test-workflow.yml'
- '.github/workflows/swift-lint.yml'
- '.github/workflows/breaking-changes.yml'
Expand Down Expand Up @@ -129,11 +129,11 @@ jobs:
if: needs.changes.outputs.swift == 'true'
uses: ./.github/workflows/swift-test-package.yml

swift-build-samples:
swift-build-and-test-samples:
name: Swift
needs: changes
if: needs.changes.outputs.swift == 'true'
uses: ./.github/workflows/swift-build-samples.yml
uses: ./.github/workflows/swift-build-and-test-samples.yml

swift-lint:
name: Swift
Expand Down Expand Up @@ -250,7 +250,7 @@ jobs:
- changes
- android-test
- swift-test-package
- swift-build-samples
- swift-build-and-test-samples
- swift-lint
- swift-sample-package-paths
- rn-test
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/rn-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,8 @@ jobs:
coverage-summary-path: platforms/react-native/coverage/coverage-summary.json
title: 'React Native — Coverage Report'
create-new-comment: false

# Runs without --coverage so the coverage report above stays scoped to the
# published module.
- name: Run sample tests
run: pnpm test --testPathPatterns="sample/src"
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Swift — Build Sample Apps
name: Swift — Build & Test Sample Apps

on:
workflow_call:
Expand All @@ -8,9 +8,9 @@ permissions:
contents: read

jobs:
build-samples:
build-and-test-samples:
uses: ./.github/workflows/swift-test-workflow.yml
with:
test-path: ./Scripts/build_samples
job-name: Build Sample Apps
test-path: ./Scripts/build_and_test_samples
job-name: Build & Test Sample Apps
setup-storefront-env: true
2 changes: 1 addition & 1 deletion .github/workflows/swift-update-linters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ jobs:
BODY+="1. **Close and reopen this PR** — this fires a new \`pull_request\` event from your user, which triggers all checks.\n"
BODY+="2. **Trigger workflows via CLI:**\n"
BODY+="\`\`\`bash\n"
BODY+="gh workflow run swift-build-samples.yml --ref auto/update-linters\n"
BODY+="gh workflow run swift-build-and-test-samples.yml --ref auto/update-linters\n"
BODY+="gh workflow run swift-lint.yml --ref auto/update-linters\n"
BODY+="gh workflow run swift-test-package.yml --ref auto/update-linters\n"
BODY+="\`\`\`\n"
Expand Down
20 changes: 17 additions & 3 deletions dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -384,10 +384,24 @@ commands:
../Scripts/xcode_run build CheckoutKitSwiftDemo
test:
desc: |
`dev swift test` - Run all tests for the ShopifyCheckoutKit-Package.
`dev swift test <test_class_name>` - Run only the specified test class.
`dev swift test` - Run all tests for the ShopifyCheckoutKit-Package and the sample apps.
`dev swift test <test_class_name>` - Run only the specified package test class.
`dev swift test sample [test_class_name]` - Run only the sample app test targets.
syntax: "[test_class_name]"
run: cd platforms/swift && ./Scripts/xcode_run test ShopifyCheckoutKit-Package "$1"
run: |
set -e
cd platforms/swift
if [ -n "${1:-}" ]; then
./Scripts/xcode_run test ShopifyCheckoutKit-Package "$1"
else
./Scripts/xcode_run test ShopifyCheckoutKit-Package
./Scripts/test_samples
fi
subcommands:
sample:
desc: Run the sample app test targets
syntax: "[test_class_name]"
run: cd platforms/swift && ./Scripts/test_samples "${1:-}"
api:
desc: Validate or update the public Swift API baseline (platforms/swift/api/*.json)
run: |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.shopify.checkoutkit.androiddemo.e2e

import org.assertj.core.api.Assertions.assertThat
import org.junit.Test

class E2ETestIdsTest {
@Test
fun `app ready marker matches the maestro flows`() {
assertThat(E2ETestIds.APP_READY).isEqualTo("checkout-kit-sample-ready")
}
}
2 changes: 1 addition & 1 deletion platforms/react-native/sample/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ import ErrorBoundary from './ErrorBoundary';
import env from 'react-native-config';
import {createDebugLogger} from './utils';
import {useShopifyEventHandlers} from './hooks/useCheckoutEventHandlers';
import {useE2ECartBootstrap} from './hooks/useE2ECartBootstrap';
import {useE2ECartBootstrap} from './e2e/useE2ECartBootstrap';
import {E2ETestIds} from './e2e/testIds';

const log = createDebugLogger('ENV');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import {useCallback} from 'react';
import {Alert} from 'react-native';
import {useCart} from '../context/Cart';
import {
parseCartBootstrapLink,
type CartBootstrapLink,
} from '../linking/cartBootstrap';
import useShopify from './useShopify';
import useShopify from '../hooks/useShopify';
import {parseCartBootstrapLink, type CartBootstrapLink} from './cartBootstrap';

type UseE2ECartBootstrapOptions = {
onCartReady: () => void;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@testable import CheckoutKitSwiftDemo
import XCTest

class E2ETestIdsTests: XCTestCase {
func testAppReadyMarkerMatchesTheMaestroFlows() {
XCTAssertEqual(E2ETestIds.appReady, "checkout-kit-sample-ready")
}
}
32 changes: 31 additions & 1 deletion platforms/swift/Samples/CheckoutKitSwiftDemo/project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ schemes:
build:
targets:
CheckoutKitSwiftDemo: all
CheckoutKitSwiftDemoTests: [test]
run:
config: Debug
test:
config: Debug
targets:
- CheckoutKitSwiftDemoTests
profile:
config: Release
analyze:
Expand All @@ -47,7 +50,7 @@ targets:
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.shopify.checkoutkit.swiftdemo
DEVELOPMENT_TEAM: A7XGC83MZE
DEVELOPMENT_TEAM: $(DEVELOPMENT_TEAM)
SWIFT_VERSION: "6.0"
SWIFT_STRICT_CONCURRENCY: complete
SWIFT_TREAT_WARNINGS_AS_ERRORS: YES
Expand Down Expand Up @@ -128,3 +131,30 @@ targets:
com.apple.developer.associated-domains:
- webcredentials:$(STOREFRONT_DOMAIN)?mode=developer
- applinks:$(STOREFRONT_DOMAIN)?mode=developer

CheckoutKitSwiftDemoTests:
type: bundle.unit-test
platform: iOS
sources:
- path: CheckoutKitSwiftDemoTests
dependencies:
- target: CheckoutKitSwiftDemo
configFiles:
Debug: Storefront.xcconfig
Release: Storefront.xcconfig
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.shopify.checkoutkit.swiftdemo.tests
DEVELOPMENT_TEAM: $(DEVELOPMENT_TEAM)
SWIFT_VERSION: "6.0"
SWIFT_STRICT_CONCURRENCY: complete
SWIFT_TREAT_WARNINGS_AS_ERRORS: YES
TEST_HOST: $(BUILT_PRODUCTS_DIR)/CheckoutKitSwiftDemo.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/CheckoutKitSwiftDemo
BUNDLE_LOADER: $(TEST_HOST)
LD_RUNPATH_SEARCH_PATHS:
- $(inherited)
- "@executable_path/Frameworks"
- "@loader_path/Frameworks"
info:
path: CheckoutKitSwiftDemoTests/Info.plist
properties: {}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ targets:
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.shopify.example.ShopifyAcceleratedCheckoutsApp
DEVELOPMENT_TEAM: A7XGC83MZE
DEVELOPMENT_TEAM: $(DEVELOPMENT_TEAM)
SWIFT_VERSION: "6.0"
TARGETED_DEVICE_FAMILY: "1,2"
MARKETING_VERSION: "1.0.1"
Expand Down
31 changes: 31 additions & 0 deletions platforms/swift/Scripts/build_and_test_samples
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
SAMPLES_DIR="$SCRIPT_DIR/../Samples"

if ! "$REPO_ROOT/scripts/setup_storefront_env" --check; then
echo "Run dev up from the repo root to sync sample app storefront configuration."
exit 1
fi

"$SCRIPT_DIR/generate_xcode_projects"

cd "$SAMPLES_DIR"

run_app() {
local app="$1"
local action="$2"

if [[ ! -f "$app/Storefront.xcconfig" ]]; then
echo "Missing Storefront.xcconfig for $app. Run dev up from the repo root."
exit 1
fi

"$SCRIPT_DIR/xcode_run" "$action" "$app"
}

run_app CheckoutKitSwiftDemo "clean build test"
run_app ShopifyAcceleratedCheckoutsApp "clean build"
28 changes: 28 additions & 0 deletions platforms/swift/Scripts/test_samples
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
SAMPLES_DIR="$SCRIPT_DIR/../Samples"
TEST_FILTER="${1:-}"

if ! "$REPO_ROOT/scripts/setup_storefront_env" --check; then
echo "Run dev up from the repo root to sync sample app storefront configuration."
exit 1
fi

"$SCRIPT_DIR/generate_xcode_projects"

if [[ ! -f "$SAMPLES_DIR/CheckoutKitSwiftDemo/Storefront.xcconfig" ]]; then
echo "Missing Storefront.xcconfig for CheckoutKitSwiftDemo. Run dev up from the repo root."
exit 1
fi

if [[ -n "$TEST_FILTER" && "$TEST_FILTER" != */* ]]; then
TEST_FILTER="CheckoutKitSwiftDemoTests/$TEST_FILTER"
fi

cd "$SAMPLES_DIR"

"$SCRIPT_DIR/xcode_run" test CheckoutKitSwiftDemo "$TEST_FILTER"
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ class CheckoutWebViewTests: XCTestCase {

pollForInvalidation()

wait(for: [invalidated], timeout: 2)
wait(for: [invalidated], timeout: 3)
}

func testInvalidateDetachesCachedPreloadedWebView() {
Expand Down Expand Up @@ -864,7 +864,7 @@ class CheckoutWebViewTests: XCTestCase {

view.userContentController(WKUserContentController(), didReceive: message)

await fulfillment(of: [responseSent], timeout: 1.0)
await fulfillment(of: [responseSent], timeout: 5.0)
let response = try XCTUnwrap(MockCheckoutBridge.lastResponseBody)
let parsed = try XCTUnwrap(try JSONSerialization.jsonObject(with: Data(response.utf8)) as? [String: Any])
XCTAssertEqual(parsed["id"] as? String, "r")
Expand Down
14 changes: 14 additions & 0 deletions scripts/setup_storefront_env
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ root_has_canonical_keys() {
STOREFRONT_DOMAIN \
STOREFRONT_ACCESS_TOKEN \
STOREFRONT_MERCHANT_IDENTIFIER \
DEVELOPMENT_TEAM \
API_VERSION \
CUSTOMER_ACCOUNT_API_CLIENT_ID \
CUSTOMER_ACCOUNT_API_SHOP_ID \
Expand Down Expand Up @@ -454,6 +455,11 @@ load_values() {
PROVINCE_VALUE="$(root_or_source_value PROVINCE "$(env_fallback PROVINCE)" "$(read_env_value PROVINCE "$REACT_NATIVE_ENV")" "$(read_env_value PROVINCE "$SWIFT_DEMO_XCCONFIG")" "ON")"
ZIP_VALUE="$(root_or_source_value ZIP "$(env_fallback ZIP)" "$(read_env_value ZIP "$REACT_NATIVE_ENV")" "$(read_env_value ZIP "$SWIFT_DEMO_XCCONFIG")" "M5V 1M7")"
PHONE_VALUE="$(root_or_source_value PHONE "$(env_fallback PHONE)" "$(read_env_value PHONE "$ANDROID_ENV")" "$(read_env_value PREFILL_PHONE "$ANDROID_ENV")" "$(read_env_value PHONE "$REACT_NATIVE_ENV")" "$(read_env_value PHONE "$SWIFT_DEMO_XCCONFIG")" "+14165550100")"

# No default and no generated-file fallback: a cleared DEVELOPMENT_TEAM stays cleared, and
# the Xcode build fails at signing until the developer supplies their own team.
DEVELOPMENT_TEAM_VALUE="$(root_or_source_nonempty_value DEVELOPMENT_TEAM \
Comment thread
kieran-osgood-shopify marked this conversation as resolved.
"$(env_fallback DEVELOPMENT_TEAM)")"
}

collect_missing_values() {
Expand Down Expand Up @@ -507,6 +513,12 @@ EOF
write_env_assignment STOREFRONT_MERCHANT_IDENTIFIER "$STOREFRONT_MERCHANT_IDENTIFIER_VALUE"
cat <<EOF

# Apple team that signs the Swift samples. Set your own team id, or the Xcode build
# fails at signing. A blank value stays blank; setup applies no default team.
EOF
write_env_assignment DEVELOPMENT_TEAM "$DEVELOPMENT_TEAM_VALUE"
cat <<EOF

# Storefront API version
EOF
write_env_assignment API_VERSION "$API_VERSION_VALUE"
Expand Down Expand Up @@ -611,6 +623,7 @@ EOF

generate_swift_demo_xcconfig() {
generate_xcconfig_header
write_xcconfig_assignment DEVELOPMENT_TEAM "$DEVELOPMENT_TEAM_VALUE"
write_xcconfig_assignment STOREFRONT_DOMAIN "$STOREFRONT_DOMAIN_VALUE"
write_xcconfig_assignment STOREFRONT_ACCESS_TOKEN "$STOREFRONT_ACCESS_TOKEN_VALUE"
write_xcconfig_assignment STOREFRONT_MERCHANT_IDENTIFIER "$STOREFRONT_MERCHANT_IDENTIFIER_VALUE"
Expand Down Expand Up @@ -642,6 +655,7 @@ EOF

generate_swift_accelerated_xcconfig() {
generate_xcconfig_header
write_xcconfig_assignment DEVELOPMENT_TEAM "$DEVELOPMENT_TEAM_VALUE"
write_xcconfig_assignment STOREFRONT_DOMAIN "$STOREFRONT_DOMAIN_VALUE"
write_xcconfig_assignment STOREFRONT_ACCESS_TOKEN "$STOREFRONT_ACCESS_TOKEN_VALUE"
write_xcconfig_assignment API_VERSION "$API_VERSION_VALUE"
Expand Down
Loading
Loading