ScreenshotNeo

BlogHow-to

How to Test Shopify Themes with Cypress

Use Shopify CLI to preview a theme safely, then test storefront flows with Cypress. Learn setup, coverage, network checks, and preview limitations.

By the ScreenshotNeo team4 October 20268 min read

To test a Shopify theme with Cypress, start a Shopify development preview with shopify theme dev, then point Cypress at the storefront URL and exercise the rendered pages. Shopify and Cypress document the pieces separately; the sources do not describe a dedicated Shopify-Cypress integration. Treat this as a browser end-to-end test of the preview, and keep checkout customizations outside the coverage claimed for the local preview.

1. Create a Shopify theme preview

Use a development store and a theme directory with Shopify’s expected structure. A theme commonly contains directories such as assets, config, layout, locales, sections, snippets, and templates. If your build process generates the theme files, run the Shopify CLI command from that generated theme directory.

  1. Install and authenticate Shopify CLI using the official theme CLI guide.
  2. From the theme directory, run shopify theme dev --store my-store, replacing my-store with your development store.
  3. Use the local preview URL printed by the command, typically http://127.0.0.1:9292, as Cypress’s base URL.

The command uploads the local theme as a development theme and provides local, admin editor, and shareable preview destinations. CSS and section changes can hot reload, and other changes can refresh the page. Development themes are temporary: Shopify says they are deleted after seven days of inactivity and when you run shopify auth logout. For a preview that remains available after logout, push the development theme to an unpublished theme. See Shopify’s theme dev reference.

For teams switching between stores or environments, Shopify CLI environments can keep command configuration in shopify.theme.toml. Follow your team’s secret-handling practices; do not casually commit plaintext credentials. See Shopify CLI environments.

2. Configure Cypress to visit the preview

Set Cypress’s base URL to the preview address for the environment where the command is running. The exact configuration file and syntax depend on the Cypress version and project setup, so keep this value in the project’s existing Cypress configuration rather than assuming Shopify provides a prescribed combined configuration.

// cypress.config.js — example configuration
const { defineConfig } = require('cypress');

module.exports = defineConfig({
  e2e: {
    baseUrl: 'http://127.0.0.1:9292',
    specPattern: 'cypress/e2e/**/*.cy.js'
  }
});

Keep the preview running while Cypress executes. A basic smoke test can assert that the storefront responds and that a recognizable page element renders:

// cypress/e2e/storefront.cy.js
describe('Shopify theme preview', () => {
  it('renders the storefront home page', () => {
    cy.visit('/');
    cy.get('main').should('be.visible');
  });
});

Replace broad selectors such as main with stable selectors that match your theme. Cypress waits for the page load event after cy.visit(); assertions should then verify the particular behavior the test is meant to protect. Cypress discusses its browser and request behavior in its FAQ.

3. Cover storefront behavior that matters

Choose scenarios based on the theme’s actual templates and store data. These are useful coverage ideas, not guarantees about what every theme or store supports:

  • Navigation: open key menus and follow links to collections and products.
  • Collection pages: check that products render and any sorting or filtering controls behave as intended.
  • Product pages: select available options, verify the displayed selection or price behavior, and submit the product form.
  • Cart feedback: add an item and verify that the theme communicates the resulting cart state.
  • Responsive layout: repeat important checks at desktop and mobile viewport sizes.
describe('product page', () => {
  it('shows the product and supports an option selection', () => {
    cy.visit('/products/example-product');
    cy.get('h1').should('be.visible');
    cy.viewport(390, 844);
    cy.get('select').first().select(1);
    // Add theme-specific assertions for the selected variant and cart feedback.
  });
});

The example product path and selector are placeholders: use a real product handle and the actual controls in your preview. Prefer selectors tied to accessible labels or stable test attributes over styling classes that change during redesigns. Cypress supports viewport adjustment for responsive checks; select dimensions that represent the layouts your project supports.

4. Use representative development-store data

Development stores start empty by default, but Shopify provides generated test data with common commerce primitives and configurations for testing themes and storefronts. Populate or select data that exercises the states your tests need: products with options, collections with multiple items, and any store configuration relevant to the theme. Record fixture assumptions so a missing product does not look like a rendering regression. Shopify’s development store documentation describes generated data; it does not prescribe a Cypress fixture workflow.

5. Test browser requests and direct API calls correctly

Use cy.intercept() to observe, wait for, or stub requests made by the storefront browser. Use cy.request() when Cypress’s Node process should call an endpoint directly and inspect its response. These commands have different network paths: Cypress documents that cy.request() does not pass through the interception proxy, so a cy.intercept() spy will not capture it.

// Observe a browser-originated request during a UI action
cy.intercept('POST', '**/cart/add.js').as('addToCart');
cy.visit('/products/example-product');
// Perform the theme's add-to-cart interaction here.
cy.wait('@addToCart').its('response.statusCode').should('be.oneOf', [200, 201]);

// Direct request from Cypress's Node process; not seen by cy.intercept()
cy.request('/').its('status').should('eq', 200);

Adapt endpoint paths and expected statuses to the storefront behavior being tested. In tests intended to build confidence in an integrated preview, avoid stubbing every dependency: stubs verify how the UI responds to supplied fixtures, while real browser requests exercise the connected path. UI interactions followed by API assertions can check persistence when the test environment and endpoint access allow it.

6. Know the preview boundary

Shopify explicitly states that checkout customizations cannot be previewed using http://127.0.0.1:9292. Do not present tests against that local URL as checkout-customization coverage. The reviewed documentation does not establish a Cypress-supported procedure for hosted checkout, so verify Shopify’s currently supported checkout test environment separately before defining checkout steps. The theme dev documentation explains this limitation.

Other useful quality checks complement browser E2E tests. Shopify’s theme-testing guidance discusses Theme Check, checking navigation and product forms with JavaScript disabled, and running Lighthouse against preview links. These are separate checks, not Cypress features; consult the Shopify theme-testing article and verify current submission requirements where relevant.

7. Troubleshooting

Symptom Likely cause What to do
theme dev rejects the current directory The command is not running from a valid theme structure, or the build output lives elsewhere. Run it from the theme root or the generated theme directory and confirm the expected theme folders are present.
Cypress cannot connect or cy.visit() times out The preview server is stopped, the configured base URL is wrong, or the preview has not finished starting. Keep shopify theme dev running, copy the local URL it prints, and visit that URL directly before running Cypress.
A product or collection test finds no content The development store is empty or does not have the fixture state the test expects. Add representative data or use Shopify’s generated test data; make the required handles and options explicit in test setup.
An intercept never matches a request The request URL or method pattern is wrong, the UI action did not trigger it, or the call was made by cy.request(). Check the browser’s actual request method and URL, trigger the UI action, and remember that runner-originated cy.request() calls bypass cy.intercept().
Tests pass with stubs but fail in the preview The stubbed response does not match the real storefront path or state. Keep focused stub tests for UI states, and add an integration test that makes the relevant browser request against the development preview.
Checkout changes are absent from the local test The local 127.0.0.1:9292 preview cannot preview checkout customizations. Limit local preview claims to storefront theme behavior and consult current Shopify guidance for an appropriate checkout test environment.
A shareable development preview disappears Development themes are temporary and can be deleted after inactivity or CLI logout. Use an unpublished theme when you need a preview to persist beyond the development-theme lifecycle.

8. Performance, reliability, and cost

Keep the suite focused on user-visible paths and run independent scenarios against known data. A remote storefront preview adds network and page-loading variability; when a test is flaky, distinguish a slow or unavailable preview from a failed assertion instead of hiding failures with broad retries. Ensure the preview is available before Cypress starts, and use Cypress’s request waiting and assertions around the actual behavior under test.

Development previews are useful for iterative theme work, but they are temporary. Plan how the team will recreate the preview and its data, or use an unpublished theme for a longer-lived shareable preview. The research sources do not specify Cypress execution pricing or Shopify testing costs, so those depend on the accounts, hosting, and CI setup your team chooses.

Or skip the browser setup

For a screenshot of the rendered storefront, ScreenshotNeo provides a website screenshot API and MCP server. A screenshot is useful for visual review, but it does not replace Cypress assertions or prove that a product form or cart flow works. This request captures a page as WebP; see the ScreenshotNeo API documentation for options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://your-storefront-preview.example -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://your-storefront-preview.example"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://your-storefront-preview.example'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await require('node:fs/promises').writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for 1,000 free screenshots a month, with no card.

FAQ

Is there an official Shopify-Cypress integration?

The reviewed Shopify and Cypress documentation does not describe a dedicated integration. The workflow here connects Shopify CLI’s preview with Cypress’s browser testing capabilities.

Can I test a preview without a populated store?

You can visit an empty development store, but tests for product and collection states need matching data. Shopify’s generated development-store data can provide useful test scenarios.

Does a screenshot prove the theme works?

No. A screenshot records a rendered page. Use Cypress for interactive behavior and assertions, and use screenshots as a visual review aid.

What should I run alongside Cypress?

Consider Theme Check and performance review with Lighthouse, plus checks of navigation and product forms with JavaScript disabled where relevant. These complement browser E2E coverage.

Sources