Using Playwright to Test Shopify App Admin Interfaces

Hi everyone,

I’m looking to implement automated testing for my Shopify app’s admin interface and would appreciate guidance from anyone who has experience with this.

My app contains several admin pages with forms, settings, validations, and dynamic UI components. I’d like to use Playwright to perform end-to-end testing, including:

  • Filling out admin forms and saving data

  • Verifying required field validations and error messages

  • Testing dropdowns, checkboxes, and other form controls

  • Confirming success/error notifications after actions

  • Testing different user workflows and edge cases

  • Running tests as part of a CI/CD pipeline

Since the app is embedded within Shopify Admin, I’m particularly interested in understanding:

  1. What is the recommended approach for authenticating Playwright tests with Shopify?

  2. Are there any best practices for testing embedded Shopify apps?

  3. How do you handle Shopify App Bridge and iframe-related challenges during testing?

  4. Do you use development stores or mock environments for automated tests?

  5. Are there any examples, guides, or open-source repositories that demonstrate Playwright testing for Shopify embedded apps?

Any recommendations, lessons learned, or sample implementations would be greatly appreciated.

Thanks in advance!

Great question. I’m curious have you considered using a dedicated development store with pre-seeded test data and saving authenticated browser sessions to avoid repeated Shopify logins during Playwright runs?

Also, for those already running Playwright on embedded apps, have you found App Bridge or iframe handling to be the biggest challenge, or is maintaining stable selectors across UI updates the real pain point?

Would love to hear what approach has worked best in production environments.

Yes, we did consider using a dedicated development store with seeded test data and also tried persisting authenticated sessions to avoid repeated Shopify logins in Playwright runs.

We did face a few challenges around session handling and embedded app context. Maintaining a stable authenticated state helped to some extent, but session expiry and re-auth flows still added inconsistency in CI runs.

We also ran into iframe/App Bridge related issues since the app is embedded inside Shopify Admin. Handling context switching between Shopify Admin and the embedded app iframe was definitely one of the trickier parts.

That said, the main goal on our side is fairly straightforward—we want Playwright to behave like a real user inside the admin:

  • Fill forms for creating pricing rules / configurations

  • Submit and validate different rule setups

  • Verify form-level validations and error messages

  • Check success/error toasts after saving

  • Cover edge cases where incorrect inputs should be blocked

So overall, iframe/App Bridge + session handling were initial blockers, but the bigger focus now is ensuring stable end-to-end flows for rule creation and validation testing, similar to how a real merchant would configure the app in production.

Thanks for the detailed explanation. It sounds like you’ve already worked through many of the common obstacles and are now focused on making the tests truly reflect real merchant behavior.

I’m curious have you found that most test failures come from the Shopify embedding layer itself, or from the dynamic UI and validation logic within your app? Also, are you planning to run these tests against a fully deployed staging environment, or are you considering mocking certain Shopify interactions to improve CI stability?

I’d be interested to hear what strategy ends up giving you the best balance between reliability and real-world coverage, especially for those pricing rule workflows.

At this stage, most of the challenges are coming from the Shopify embedding layer (authentication, session persistence, embedded app context, etc.) rather than the validation logic within our app.

Our forms and pricing rule workflows are relatively straightforward to test once Playwright is operating reliably within the embedded app. The main goal is to validate the same merchant journeys that happen in production—creating rules, updating configurations, verifying validation messages, and ensuring the correct success/error responses are displayed.

Ideally, we’d like to run these tests against a staging environment with a dedicated development store rather than heavily mocking Shopify interactions. Since our objective is end-to-end coverage, we want Playwright to interact with the application as a merchant would, including navigating through the Shopify Admin, configuring rules, and verifying the resulting behavior.

That said, we’re still evaluating the best approach for handling authentication and embedded app stability in CI. If anyone has experience running Playwright reliably against Shopify embedded apps at scale, we’d be very interested in learning about the setup, particularly around session management and App Bridge integration.

the thing that helped me most was realizing you don’t have to test through the Admin iframe for most of it. the embedded context switching is exactly where the flakiness lives, so i keep a couple of real end-to-end tests that go through Admin (those stay a bit flaky, just accept it) and run everything else by hitting the app’s own route directly with auth injected. you skip App Bridge entirely for the bulk of your form and validation coverage.

on the session expiry pain, that usually means you’re persisting the wrong layer. the App Bridge session token is a short-lived JWT, so saving that in storageState rots fast. persist the Shopify admin login cookie instead and let App Bridge mint a fresh token each run. for CI i give the backend a test-mode bypass that accepts a known token, so the tests exercise my UI and not Shopify’s auth handshake.

if you do need to assert inside the embedded app, use frameLocator on the iframe rather than page-level selectors, otherwise you’re racing the iframe load and the failures look random.

what’s your CI runner, and are you on the new CDN App Bridge or still the React version? the re-auth behavior is different between them.

Thanks for the input so far. Sharing where I’ve landed on testing the embedded admin UI specifically, plus a few sharper follow-ups.

The biggest realization: most of my list — filling forms, required-field validation, error messages, dropdowns/checkboxes, success/error notifications — is actually covered far more reliably by component/integration tests than by full Playwright browser tests. The embedded app is just a React (Polaris) app, so I render the page/form components with Testing Library, drive them, and assert inline Polaris errors, control state, and the action results directly. These are fast, deterministic, and run on every PR.

To make that work outside the Admin shell, I mock the App Bridge shopify global (toast, save bar, modal, idToken) once in a shared setup file — those surfaces don’t exist outside the iframe, so mocking them lets the components run headless.

Where I do use Playwright (a thin layer): a real end-to-end smoke of a representative workflow against a dev store — load the embedded page, fill the form, save, then assert the result via the Admin GraphQL API rather than scraping the embedded DOM. Verifying persisted data through the API is much less flaky than asserting on App Bridge toasts or Polaris-rendered markup.

On the iframe/App Bridge specifics:

  • Everything renders in a cross-origin iframe, so in-browser tests have to scope to the app frame, and App Bridge drives navigation/save-bar behavior that races assertions.
  • For auth, I avoid driving the full Admin login each run — establish an authenticated session once and reuse it, rather than going through admin.shopify.com every time.
  • App Bridge toasts are imperative/ephemeral, so I assert the underlying state change instead of trying to catch the toast.

Fixtures: seeded and reset through the Admin API, resetting only what each test dirtied (resetting everything per test rate-limited the store quickly).

Remaining questions I’d love input on:

  1. Auth — what’s your cleanest way to get an authenticated Playwright session against the embedded app without re-driving the Admin login + iframe each run? Reusing storageState, or stubbing the session-token exchange?
  2. Contextual save bar — how are you reliably triggering and asserting an App Bridge save (save bar → action → confirmation) in a real browser test?
  3. Polaris controlsSelect, Combobox, Checkbox etc. render custom markup; are you targeting them by role, or adding data-testids?
  4. Notifications — do you assert App Bridge toasts in-browser at all, or always fall back to asserting state?
  5. Where’s your line between component/integration coverage and full embedded browser E2E?

Thanks again — happy to compare notes on any of these.

Hey @SatishMantri .
Hope you are having a nice day .

For the embedded app, the easiest approach is to skip OAuth and test entirely, sign up against a dev store, grab a long-lived session API key manually, and inject it so Playwright bypasses the shopify login flow.

That’s a very thoughtful approach. I completely agree that testing against a staging environment with a dedicated development store provides much more confidence than heavily mocked scenarios, especially when you’re trying to replicate actual merchant behavior.

One thing I’m curious about: have you explored using pre-authenticated browser states combined with periodic session refreshes to reduce CI instability, or does App Bridge still introduce unpredictable behavior even with that setup?

I’d genuinely love to follow your progress on this because reliable Playwright testing for embedded Shopify apps is a challenge many developers face. If you’re open to exchanging ideas and experiences, feel free to reach out to me on WhatsApp at +1 (951) 469-5617. It would be great to connect and discuss possible solutions in more detail.