Skip to content

Add the E2E control link parser to all four sample apps - #554

Merged
kieran-osgood-shopify merged 1 commit into
mainfrom
kieran-osgood/e2e-control-link
Aug 12, 2026
Merged

Add the E2E control link parser to all four sample apps#554
kieran-osgood-shopify merged 1 commit into
mainfrom
kieran-osgood/e2e-control-link

Conversation

@kieran-osgood-shopify

@kieran-osgood-shopify kieran-osgood-shopify commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

What changes are you making?

One core file added for each platform E2EControlLink - parses an incoming deep link into a types argument

The extra changes in react-native are because we already started a host cart and this PR supercedes that pattern with e2e as a root host that handles multiple commands

image

Why

To keep the end to end test running quickly and without wasting time validating sample app logic as such, which we've opted for a deep link scheme that can prepare some state for us such as cart and products

maestro commands will be something like this rather than a dozen steps to get the cart prepped and move to CartView

- openLink: 'com.shopify.checkout_kit_android_demo://products/1'

How

The shape is <app-scheme>://e2e/<command>?<parameters>, where the scheme is the app id.
This PR adds one parser per platform that turns such a link into a typed command
We use a common e2e host on every command, so one intent-filter and one CFBundleURLScheme cover all of them (if you look at the AndroidManifest we use a single host, rather than having n entries per command.
A malformed control link throws, so a typo in a flow fails the test instead of passing silently.
The parsers accept identical input on all platforms.

Command Parameters Effect
reset none clear app state
cart variantId or productIndex, plus quantity and buyerIdentityMode seed the cart with one line item
signIn optional email start sign-in, pre-filled

Note: If you're familiar with maestro you might be wondering why I opted for a reset deep link here, theres a bug in the browserstack integration here, clearState is a command in maestro that achieves it by uninstalling and reinstalling the app, in browserstack it reports a success but fails to reinstall the app, which led to broken tests.

Whats Next

Wiring the parsers into each app is the next PR in the stack.

Before you merge

Important

  • I've added tests to support my implementation
  • I have read and agree with the Contribution Guidelines
  • I have read and agree with the Code of Conduct
  • I've updated the relevant platform README (platforms/swift/README.md and/or platforms/android/README.md)

Releasing a new Swift version?
  • I have bumped the version in ShopifyCheckoutKit.podspec
  • I have bumped the version in platforms/swift/Sources/ShopifyCheckoutKit/ShopifyCheckoutKit.swift
  • I have updated the SwiftPM/CocoaPods version snippets in platforms/swift/README.md (major version only)
Releasing a new Embedded Checkout Protocol version?
  • I have bumped embeddedCheckoutProtocolAndroid in platforms/android/gradle/libs.versions.toml
  • I have updated protocol/languages/kotlin/embedded-checkout-protocol/api/embedded-checkout-protocol.api if the public API changed
Releasing a new Android version?
  • I have bumped checkoutKitAndroid in platforms/android/gradle/libs.versions.toml
  • I have updated the Gradle/Maven version snippets in platforms/android/README.md

Tip

See the Contributing documentation for the full release process per platform.

@github-actions github-actions Bot added the #gsd:50662 Rebase Checkout Kit on UCP label Jul 31, 2026
@tiagocandido
tiagocandido force-pushed the e2e-sample-test-seams branch from 1abe472 to 71f2515 Compare August 3, 2026 12:12
@tiagocandido
tiagocandido force-pushed the kieran-osgood/e2e-control-link branch from fd87aa1 to 278ce30 Compare August 3, 2026 12:12
@tiagocandido
tiagocandido force-pushed the e2e-sample-test-seams branch from 71f2515 to fc857ab Compare August 3, 2026 14:42
@tiagocandido
tiagocandido force-pushed the kieran-osgood/e2e-control-link branch from 278ce30 to 66ee89d Compare August 3, 2026 14:42
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the kieran-osgood/e2e-control-link branch from 66ee89d to 7c28f96 Compare August 4, 2026 17:04
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the kieran-osgood/e2e-control-link branch from 9c0c058 to babcf9e Compare August 5, 2026 11:45
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the e2e-sample-test-seams branch 2 times, most recently from ad8bafd to 992ffc8 Compare August 5, 2026 12:33
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the kieran-osgood/e2e-control-link branch from babcf9e to 2c394fc Compare August 5, 2026 12:33
@kieran-osgood-shopify
kieran-osgood-shopify changed the base branch from e2e-sample-test-seams to graphite-base/554 August 5, 2026 14:51
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the kieran-osgood/e2e-control-link branch from 2c394fc to 1bbb44a Compare August 6, 2026 15:48
@kieran-osgood-shopify
kieran-osgood-shopify changed the base branch from graphite-base/554 to e2e-sample-test-seams August 6, 2026 15:48
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the kieran-osgood/e2e-control-link branch from 1bbb44a to 9a982e4 Compare August 6, 2026 17:06
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the kieran-osgood/e2e-control-link branch from 9a982e4 to e650dc3 Compare August 7, 2026 11:05
@kieran-osgood-shopify
kieran-osgood-shopify changed the base branch from e2e-sample-test-seams to graphite-base/554 August 7, 2026 11:20
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the kieran-osgood/e2e-control-link branch from e650dc3 to ae68cf6 Compare August 7, 2026 11:20
@graphite-app
graphite-app Bot changed the base branch from graphite-base/554 to main August 7, 2026 11:20
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the kieran-osgood/e2e-control-link branch from ae68cf6 to a3846f6 Compare August 7, 2026 11:21
@kieran-osgood-shopify
kieran-osgood-shopify marked this pull request as ready for review August 7, 2026 13:50
@kieran-osgood-shopify
kieran-osgood-shopify requested a review from a team as a code owner August 7, 2026 13:50
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

React Native — Coverage Report

Lines Statements Branches Functions
Coverage: 92%
91.64% (307/335) 88.88% (176/198) 100% (81/81)

@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the kieran-osgood/e2e-control-link branch from a3846f6 to 38169bc Compare August 7, 2026 13:51
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

Package Size

Platform Artifact Base Head Delta
React Native npm tarball 101.6 KiB 101.6 KiB 0 B
Android release AAR 273.6 KiB 273.6 KiB 0 B
React Native file breakdown
File Base Head Delta
node_modules/@shopify/checkout-kit-protocol/src/generated/Models.ts 85.4 KiB 85.4 KiB 0 B
node_modules/@shopify/checkout-kit-protocol/src/generated/Models.d.ts 53.0 KiB 53.0 KiB 0 B
ios/AcceleratedCheckoutButtons.swift 14.1 KiB 14.1 KiB 0 B
ios/ShopifyCheckoutKit.swift 13.5 KiB 13.5 KiB 0 B
src/components/AcceleratedCheckoutButtons.tsx 13.0 KiB 13.0 KiB 0 B
android/src/main/java/com/shopify/reactnative/checkoutkit/ShopifyCheckoutKitModule.java 12.8 KiB 12.8 KiB 0 B
lib/commonjs/index.js 12.3 KiB 12.3 KiB 0 B
src/index.ts 12.2 KiB 12.2 KiB 0 B
lib/commonjs/components/AcceleratedCheckoutButtons.js 11.4 KiB 11.4 KiB 0 B
lib/commonjs/components/AcceleratedCheckoutButtons.js.map 10.4 KiB 10.4 KiB 0 B
lib/module/components/AcceleratedCheckoutButtons.js 10.2 KiB 10.2 KiB 0 B
lib/module/index.js 10.2 KiB 10.2 KiB 0 B
node_modules/@shopify/checkout-kit-protocol/src/generated/ProtocolNotifications.ts 9.5 KiB 9.5 KiB 0 B
src/index.d.ts 9.1 KiB 9.1 KiB 0 B
lib/module/components/AcceleratedCheckoutButtons.js.map 9.1 KiB 9.1 KiB 0 B
src/present-dispatcher.ts 8.0 KiB 8.0 KiB 0 B
lib/module/index.js.map 7.9 KiB 7.9 KiB 0 B
lib/commonjs/index.js.map 7.7 KiB 7.7 KiB 0 B
node_modules/@shopify/checkout-kit-protocol/src/generated/ProtocolNotifications.d.ts 7.6 KiB 7.6 KiB 0 B
node_modules/@shopify/checkout-kit-protocol/src/generated/ProtocolRenameMap.ts 7.2 KiB 7.2 KiB 0 B
…and 110 smaller files
Android file breakdown
File Base Head Delta
classes.jar 289.5 KiB 289.5 KiB 0 B
res/layout/checkout_view_content.xml 2.3 KiB 2.3 KiB 0 B
res/layout/checkout_sheet_content.xml 2.0 KiB 2.0 KiB 0 B
res/values/values.xml 1.2 KiB 1.2 KiB 0 B
R.txt 1.1 KiB 1.1 KiB 0 B
proguard.txt 798 B 798 B 0 B
AndroidManifest.xml 578 B 578 B 0 B
res/drawable/close.xml 431 B 431 B 0 B
res/menu/checkout_menu.xml 354 B 354 B 0 B
META-INF/com/android/build/gradle/aar-metadata.properties 157 B 157 B 0 B

Measured from the PR base SHA and PR head SHA. The file breakdown shows uncompressed sizes within each package artifact, so individual files do not sum to the compressed artifact total. This comment reports package artifact sizes only; it is not a final app binary-size report.

@bitrise

bitrise Bot commented Aug 7, 2026

Copy link
Copy Markdown

Install this build

Open Tophat, select your target device, then click Install. Links open on the Mac running Tophat.

SDK Install
React Native Install with Tophat
Swift Install with Tophat
Kotlin Install with Tophat

Checkout Kit E2E results

Status Suite Target Platform OS version tag Device
tests/shared/launch-smoke.yaml react-native ios latest iPhone 15
iOS 27 Beta
tests/shared/launch-smoke.yaml react-native android latest Google Pixel 9
Android 17.0
tests/shared/launch-smoke.yaml kotlin android latest Google Pixel 9
Android 17.0
tests/shared/launch-smoke.yaml swift ios latest iPhone 15
iOS 27 Beta

The E2E suite drives four apps: Swift iOS, Kotlin Android, React Native iOS
and React Native Android. Only React Native could read a deep link, and only
for a cart. Widen the contract to <scheme>://e2e/<command> with the commands
reset, cart and signIn, and port the parser to Swift and Kotlin so one Maestro
flow drives every app.

Every platform rewrites the scheme to https before parsing. Neither
Foundation URLComponents nor java.net.URI accepts the underscores in the
Android application id, and the React Native URL polyfill parses a host only
for http(s). A test per platform pins that behaviour with both app schemes.

The parser stays pure and keeps three outcomes: nil when the link belongs to
another feature, a parsed command, or an error that names the bad parameter.
A parameter that is present must carry a valid value.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@kyle-schellen kyle-schellen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just left a small non-blocking question

val uri = try {
URI(PARSE_ORIGIN_SCHEME + authorityAndPath)
} catch (error: URISyntaxException) {
return null

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we reserve null for non-E2E links and throw for malformed E2E URLs instead? Might be stricter than we need today, but it would keep those cases distinct if we need clearer control-link diagnostics later.

If we do want that distinction, it’s probably worth keeping the Android, Swift, and React Native parsers aligned.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'll leave it to later if the time comes we need that

@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the kieran-osgood/e2e-control-link branch from 38169bc to e746744 Compare August 10, 2026 09:08
@kieran-osgood-shopify
kieran-osgood-shopify merged commit c66804a into main Aug 12, 2026
37 checks passed
@kieran-osgood-shopify
kieran-osgood-shopify deleted the kieran-osgood/e2e-control-link branch August 12, 2026 10:23
kieran-osgood-shopify added a commit that referenced this pull request Aug 12, 2026
### What changes are you making?
Previous PR added classes to handle parsing deep links for e2e scenarios
This one adds a controller for E2E that utilises the parser to receive the intent, and then dispatch the actions we need in the sample after 

React Native already had most of the wiring as we set them up first so this PR brings kotlin and swift up to speed on wiring in the entry points for deep links into the E2EControlLink classes from PR #554

### How to test

These things aren't wired up yet so nothing really to test, just dividing up the work 

---

### Before you merge

> [!IMPORTANT]
>
> - [ ] I've added tests to support my implementation
> - [ ] I have read and agree with the [Contribution Guidelines](./CONTRIBUTING.md)
> - [ ] I have read and agree with the [Code of Conduct](./CODE_OF_CONDUCT.md)
> - [ ] I've updated the relevant platform README (`platforms/swift/README.md` and/or `platforms/android/README.md`)

---

<details>
<summary>Releasing a new Swift version?</summary>

- [ ] I have bumped the version in `ShopifyCheckoutKit.podspec`
- [ ] I have bumped the version in `platforms/swift/Sources/ShopifyCheckoutKit/ShopifyCheckoutKit.swift`
- [ ] I have updated the SwiftPM/CocoaPods version snippets in `platforms/swift/README.md` (major version only)

</details>

<details>
<summary>Releasing a new Embedded Checkout Protocol version?</summary>

- [ ] I have bumped `embeddedCheckoutProtocolAndroid` in `platforms/android/gradle/libs.versions.toml`
- [ ] I have updated `protocol/languages/kotlin/embedded-checkout-protocol/api/embedded-checkout-protocol.api` if the public API changed

</details>

<details>
<summary>Releasing a new Android version?</summary>

- [ ] I have bumped `checkoutKitAndroid` in `platforms/android/gradle/libs.versions.toml`
- [ ] I have updated the Gradle/Maven version snippets in `platforms/android/README.md`

</details>

> [!TIP]
> See the [Contributing documentation](./CONTRIBUTING.md) for the full release process per platform.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

#gsd:50662 Rebase Checkout Kit on UCP

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants