home / skills / toilahuongg / shopify-agents-kit / shopify-testing
This skill guides you through unit, integration, and E2E testing for Shopify apps using Remix, Vitest, and Playwright.
npx playbooks add skill toilahuongg/shopify-agents-kit --skill shopify-testingReview the files below or copy the command above to add this skill to your agents.
---
name: shopify-testing
description: Guide for testing Shopify Apps, including Unit Testing with Remix, Mocking Shopify Context, and E2E Testing.
---
# Shopify App Testing
Reliable testing is crucial for ensuring your app handles Shopify's authentication and API quirks correctly.
## 1. Unit & Integration Testing (Vitest + Remix)
Use **Vitest** for running unit and integration tests in the Remix environment.
### Setup
Install dependencies:
```bash
npm install -D vitest @testing-library/react @testing-library/jest-dom jsdom
```
### Mocking `shopify.server.ts`
Creating a mock for the `authenticate` object is critical for testing loaders and actions without hitting real Shopify APIs.
```typescript
// test/mocks/shopify.ts
import { vi } from 'vitest';
export const mockShopify = {
authenticate: {
admin: vi.fn(),
public: vi.fn(),
webhook: vi.fn(),
},
};
// Usage in test file:
vi.mock('../app/shopify.server', () => mockShopify);
test('loader returns data for authenticated shop', async () => {
mockShopify.authenticate.admin.mockResolvedValue({
currentShop: 'test-shop.myshopify.com',
session: { shop: 'test-shop.myshopify.com', accessToken: 'fake_token' },
admin: {
graphql: vi.fn().mockResolvedValue({ /* mock response */ })
}
});
const response = await loader({ request: new Request('http://localhost/') });
// Assertions...
});
```
## 2. Testing Loaders & Actions
Using Remix's `createRemixStub` or calling loaders/actions directly is the best way to test backend logic.
### Direct Function Call (Preferred for logic)
You can import the `loader` or `action` and call it directly with a mock Request.
```typescript
import { loader } from '../app/routes/app.dashboard';
test('dashboard loader returns stats', async () => {
// Setup mocks...
const response = await loader({
request: new Request('http://localhost/app/dashboard'),
params: {}
});
const data = await response.json();
expect(data.stats).toBeDefined();
});
```
## 3. End-to-End (E2E) Testing (Playwright)
For E2E tests, you need to handle the OAuth flow or bypass it using session tokens.
### Bypassing Auth (Session Token)
The most stable way to E2E test embedded apps is to generate a valid session token (or mock the validation) so you don't have to automate the Login screen interaction which often triggers captchas.
### Basic Playwright Test
```typescript
import { test, expect } from '@playwright/test';
test('load dashboard', async ({ page }) => {
await page.goto('http://localhost:3000/app');
// Expect to see the Polaris Page title
await expect(page.locator('.Polaris-Page-Header__Title')).toHaveText('Dashboard');
});
```
## 4. Testing Webhooks
To test webhooks locally:
1. **Trigger via Shopify CLI**: `shopify app webhook trigger --topic ORDERS_CREATE`
2. **Unit Test**: Import the webhook action and pass a mock Request with the correct HMAC header.
```typescript
import { action } from '../app/routes/webhooks';
import crypto from 'crypto';
test('webhook verifies hmac', async () => {
const payload = JSON.stringify({ id: 123 });
const hmac = crypto.createHmac('sha256', 'FULL_SECRET').update(payload).digest('base64');
const request = new Request('http://localhost/webhooks', {
method: 'POST',
body: payload,
headers: { 'X-Shopify-Hmac-Sha256': hmac }
});
// Mock authenticate.webhook to succeed
// ...
const response = await action({ request });
expect(response.status).toBe(200);
});
```
This skill is a practical guide for testing Shopify Apps with focus on unit, integration, and end-to-end testing. It covers mocking Shopify context in Remix, running tests with Vitest, E2E flows with Playwright, and webhook verification strategies.
It shows how to replace Shopify server helpers with lightweight mocks so loaders and actions can be called directly in tests. It explains setting up Vitest and testing UI and backend logic, how to bypass or simulate OAuth/session tokens for Playwright E2E tests, and how to create and verify webhook requests locally.
Do I need to run Shopify APIs for tests?
No — mock the authenticate object and GraphQL responses to keep tests fast and reliable.
How do I avoid OAuth in E2E tests?
Generate or mock a valid session token and inject it into the app context or bypass validation in test mode.