Writing Tests
E2E tests use Playwright Test (opens in a new tab) format with ShellApps-specific fixtures.
Basic Test
import { test, expect } from '@shellapps/e2e';
test('user can sign in', async ({ page }) => {
await page.goto('https://auth.shellapps.com/login');
await page.fill('[name="email"]', 'test@example.com');
await page.fill('[name="password"]', 'password123');
await page.click('button[type="submit"]');
await expect(page).toHaveURL(/\/dashboard/);
await expect(page.locator('h1')).toContainText('Welcome');
});ShellApps Fixtures
The @shellapps/e2e package provides custom fixtures:
authenticatedPage
A page already signed in with a test account:
import { test, expect } from '@shellapps/e2e';
test('dashboard loads widgets', async ({ authenticatedPage: page }) => {
await page.goto('https://experience.shellapps.com/dashboard');
await expect(page.locator('.widget-grid')).toBeVisible();
});testProfile
A fresh test profile for isolated testing:
test('profile switching', async ({ authenticatedPage: page, testProfile }) => {
await page.goto('https://auth.shellapps.com/profiles');
await expect(page.locator(`text=${testProfile.displayName}`)).toBeVisible();
});testGroup
A test group with configurable members:
test('group permissions', async ({ authenticatedPage: page, testGroup }) => {
await page.goto(`https://auth.shellapps.com/groups/${testGroup.id}`);
await expect(page.locator('.members-list')).toBeVisible();
});Visual Regression
Use toHaveScreenshot for visual comparisons:
test('dashboard visual', async ({ authenticatedPage: page }) => {
await page.goto('https://experience.shellapps.com/dashboard');
await page.waitForLoadState('networkidle');
await expect(page).toHaveScreenshot('dashboard.png', {
maxDiffPixelRatio: 0.01,
fullPage: true,
});
});Update baselines:
npx @shellapps/e2e-cli run --suite visual --update-snapshotsAssertions
Common assertions for ShellApps tests:
// Page loaded without errors
await expect(page.locator('.error-boundary')).not.toBeVisible();
// Design system components rendered correctly
await expect(page.locator('[data-testid="theme-provider"]')).toHaveAttribute(
'data-mode',
'dark'
);
// Auth state
await expect(page.locator('[data-testid="user-menu"]')).toContainText('Alex');
// API response
const response = await page.waitForResponse('**/api/v1/**');
expect(response.status()).toBe(200);Test Organisation
tests/
├── smoke/
│ ├── auth.spec.ts # Login, logout, registration
│ ├── navigation.spec.ts # Core navigation flows
│ └── dashboard.spec.ts # Dashboard functionality
├── regression/
│ ├── experience/
│ │ ├── pages.spec.ts
│ │ └── editor.spec.ts
│ └── auth/
│ ├── profiles.spec.ts
│ └── groups.spec.ts
├── visual/
│ ├── dashboard.spec.ts
│ └── components.spec.ts
└── fixtures/
└── index.ts # Custom fixture definitionsConfiguration
// playwright.config.ts
import { defineConfig } from '@shellapps/e2e';
export default defineConfig({
target: 'https://experience.shellapps.com',
retries: 2,
workers: 4,
browsers: ['chromium', 'firefox'],
reporter: [['html'], ['@shellapps/e2e-reporter']],
});Related
- E2E Overview — Service architecture and test suites
- API Reference — Trigger and manage test runs
- Auth — Authentication tested by E2E suites
- Design System — Components tested visually