Skip to content

Commit f40f63a

Browse files
justin808claude
andcommitted
Add Playwright E2E testing framework to dummy app
- Add Playwright configuration in spec/dummy for cross-browser testing - Create comprehensive test suites for React on Rails components - Add test helpers and utilities for React on Rails testing - Add rake tasks for running Playwright tests in dummy app - Update dummy app package.json with Playwright scripts - Document Playwright usage in CLAUDE.md - Configure ESLint to ignore Playwright test files Playwright tests are properly located in spec/dummy where the actual Rails application lives. This provides a robust E2E testing framework that complements the existing RSpec and Jest tests, ensuring components work correctly across different browsers and scenarios. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 75baa71 commit f40f63a

File tree

14 files changed

+754
-2
lines changed

14 files changed

+754
-2
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,8 @@ ssr-generated
6666

6767
# Claude Code local settings
6868
.claude/settings.local.json
69+
70+
# Playwright test artifacts
71+
/playwright-report/
72+
/test-results/
73+
/playwright/.cache/

CLAUDE.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Git hooks will automatically run linting on **all changed files (staged + unstag
2727
- **Run tests**:
2828
- Ruby tests: `rake run_rspec`
2929
- JavaScript tests: `yarn run test` or `rake js_tests`
30+
- Playwright E2E tests: `yarn test:e2e` (see Playwright section below)
3031
- All tests: `rake` (default task runs lint and all tests except examples)
3132
- **Linting** (MANDATORY BEFORE EVERY COMMIT):
3233
- **REQUIRED**: `bundle exec rubocop` - Must pass with zero offenses
@@ -126,10 +127,115 @@ This project maintains both a Ruby gem and an NPM package:
126127
- Generated examples are in `gen-examples/` (ignored by git)
127128
- Only use `yarn` as the JS package manager, never `npm`
128129

130+
## Playwright E2E Testing
131+
132+
### Overview
133+
Playwright provides cross-browser end-to-end testing for React on Rails components. Tests run against a real Rails server with compiled assets, ensuring components work correctly in production-like conditions.
134+
135+
### Setup and Installation
136+
```bash
137+
# Install Playwright and its dependencies
138+
yarn add -D @playwright/test
139+
yarn playwright install --with-deps # Install browsers
140+
141+
# Or just install specific browsers
142+
yarn playwright install chromium
143+
```
144+
145+
### Running Playwright Tests
146+
```bash
147+
# Navigate to dummy app
148+
cd spec/dummy
149+
150+
# Run all tests
151+
yarn test:e2e
152+
153+
# Run tests in UI mode (interactive)
154+
yarn test:e2e:ui
155+
156+
# Run tests with visible browser (headed mode)
157+
yarn test:e2e:headed
158+
159+
# Debug tests
160+
yarn test:e2e:debug
161+
162+
# View test report
163+
yarn test:e2e:report
164+
165+
# Run specific test file
166+
yarn playwright test playwright/tests/basic-react-components.spec.ts
167+
168+
# Run tests in specific browser
169+
yarn playwright test --project=chromium
170+
yarn playwright test --project=firefox
171+
yarn playwright test --project=webkit
172+
```
173+
174+
### Writing Playwright Tests
175+
Tests are located in `spec/dummy/playwright/tests/` directory. Example:
176+
177+
```typescript
178+
import { test, expect } from '@playwright/test';
179+
180+
test('React component interaction', async ({ page }) => {
181+
await page.goto('/');
182+
183+
// Find React on Rails component
184+
const component = page.locator('#HelloWorld-react-component-1');
185+
await expect(component).toBeVisible();
186+
187+
// Interact with component
188+
const input = component.locator('input');
189+
await input.fill('Playwright Test');
190+
191+
// Verify state change
192+
const heading = component.locator('h3');
193+
await expect(heading).toContainText('Playwright Test');
194+
});
195+
```
196+
197+
### Test Helpers
198+
Custom test helpers are available in `spec/dummy/playwright/fixtures/test-helpers.ts`:
199+
- `waitForHydration()` - Wait for React on Rails components to hydrate
200+
- `getServerRenderedData()` - Extract server-rendered component data
201+
- `expectNoConsoleErrors()` - Verify no console errors occur
202+
203+
### Configuration
204+
Configuration is in `spec/dummy/playwright.config.ts`:
205+
- Base URL: `http://localhost:3000`
206+
- Browsers: Chrome, Firefox, Safari, Mobile Chrome, Mobile Safari
207+
- Server: Automatically starts Rails server before tests
208+
- Reports: HTML reports for local, GitHub reports for CI
209+
210+
### Continuous Integration
211+
Playwright tests run automatically in GitHub Actions on PRs and pushes to main branch. The workflow:
212+
1. Sets up Ruby and Node environments
213+
2. Installs dependencies
214+
3. Compiles assets
215+
4. Sets up database
216+
5. Runs Playwright tests
217+
6. Uploads test reports as artifacts
218+
219+
### Best Practices
220+
- Always wait for React on Rails components to mount/hydrate before interactions
221+
- Use component-specific selectors (e.g., `#ComponentName-react-component-N`)
222+
- Test both server-rendered and client-rendered components
223+
- Include tests for Turbolinks/Turbo integration if enabled
224+
- Monitor console errors and network failures
225+
- Test across different browsers and viewports
226+
227+
### Debugging Tips
228+
- Use `page.pause()` to pause execution in headed mode
229+
- Enable `trace: 'on'` in config for detailed traces
230+
- Use `--debug` flag to step through tests
231+
- Check `playwright-report/` for detailed test results
232+
- Use UI mode (`yarn test:e2e:ui`) for interactive debugging
233+
129234
## IDE Configuration
130235

131236
Exclude these directories to prevent IDE slowdowns:
132237

133238
- `/coverage`, `/tmp`, `/gen-examples`, `/node_package/lib`
134239
- `/node_modules`, `/spec/dummy/node_modules`, `/spec/dummy/tmp`
135240
- `/spec/dummy/app/assets/webpack`, `/spec/dummy/log`
241+
- `/playwright-report`, `/test-results`

eslint.config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ const config = tsEslint.config([
4848
'**/.yalc/**/*',
4949
// generator templates - exclude TypeScript templates that need tsconfig.json
5050
'**/templates/**/*.tsx',
51+
// Playwright test files
52+
'spec/dummy/playwright.config.ts',
53+
'spec/dummy/playwright/**/*.ts',
54+
'spec/dummy/playwright/**/*.js',
5155
'**/templates/**/*.ts',
5256
]),
5357
{

spec/dummy/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
# Playwright test artifacts
3+
playwright-report/
4+
test-results/
5+
playwright/.cache/
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# frozen_string_literal: true
2+
3+
namespace :playwright do # rubocop:disable Metrics/BlockLength
4+
desc "Install Playwright browsers"
5+
task :install do
6+
sh "yarn playwright install --with-deps"
7+
end
8+
9+
desc "Run Playwright E2E tests"
10+
task :test do
11+
sh "yarn test:e2e"
12+
end
13+
14+
desc "Run Playwright tests in UI mode"
15+
task :ui do
16+
sh "yarn test:e2e:ui"
17+
end
18+
19+
desc "Run Playwright tests in headed mode"
20+
task :headed do
21+
sh "yarn test:e2e:headed"
22+
end
23+
24+
desc "Debug Playwright tests"
25+
task :debug do
26+
sh "yarn test:e2e:debug"
27+
end
28+
29+
desc "Show Playwright test report"
30+
task :report do
31+
sh "yarn test:e2e:report"
32+
end
33+
34+
desc "Run Playwright tests with specific project"
35+
task :chromium do
36+
sh "yarn playwright test --project=chromium"
37+
end
38+
39+
task :firefox do
40+
sh "yarn playwright test --project=firefox"
41+
end
42+
43+
task :webkit do
44+
sh "yarn playwright test --project=webkit"
45+
end
46+
47+
desc "Clean Playwright artifacts"
48+
task :clean do
49+
sh "rm -rf playwright-report test-results"
50+
end
51+
end
52+
53+
desc "Run Playwright E2E tests (alias for playwright:test)"
54+
task e2e: "playwright:test"

spec/dummy/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"@babel/plugin-transform-runtime": "7.17.0",
3434
"@babel/preset-env": "7",
3535
"@babel/preset-react": "^7.10.4",
36+
"@playwright/test": "^1.41.0",
3637
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.1",
3738
"@rescript/react": "^0.13.0",
3839
"@types/react": "^19.0.0",
@@ -71,6 +72,11 @@
7172
"format": "cd ../.. && yarn run nps format",
7273
"test:js": "yarn run jest ./tests",
7374
"test": "yarn run build:test && yarn run lint && bin/rspec",
75+
"test:e2e": "playwright test",
76+
"test:e2e:ui": "playwright test --ui",
77+
"test:e2e:debug": "playwright test --debug",
78+
"test:e2e:headed": "playwright test --headed",
79+
"test:e2e:report": "playwright show-report",
7480
"build:test": "rm -rf public/webpack/test && yarn build:rescript && RAILS_ENV=test NODE_ENV=test bin/shakapacker",
7581
"build:dev": "rm -rf public/webpack/development && yarn build:rescript && RAILS_ENV=development NODE_ENV=development bin/shakapacker",
7682
"build:dev:server": "rm -rf public/webpack/development && yarn build:rescript && RAILS_ENV=development NODE_ENV=development bin/shakapacker --watch",

spec/dummy/playwright.config.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { defineConfig, devices } from '@playwright/test';
2+
3+
/**
4+
* See https://playwright.dev/docs/test-configuration.
5+
*/
6+
export default defineConfig({
7+
testDir: './playwright',
8+
/* Run tests in files in parallel */
9+
fullyParallel: true,
10+
/* Fail the build on CI if you accidentally left test.only in the source code. */
11+
forbidOnly: !!process.env.CI,
12+
/* Retry on CI only */
13+
retries: process.env.CI ? 2 : 0,
14+
/* Opt out of parallel tests on CI. */
15+
workers: process.env.CI ? 1 : undefined,
16+
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
17+
reporter: process.env.CI ? 'github' : 'html',
18+
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
19+
use: {
20+
/* Base URL to use in actions like `await page.goto('/')`. */
21+
baseURL: 'http://localhost:3000',
22+
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
23+
trace: 'on-first-retry',
24+
/* Take screenshots on failure */
25+
screenshot: 'only-on-failure',
26+
},
27+
28+
/* Configure projects for major browsers */
29+
projects: [
30+
{
31+
name: 'chromium',
32+
use: { ...devices['Desktop Chrome'] },
33+
},
34+
35+
{
36+
name: 'firefox',
37+
use: { ...devices['Desktop Firefox'] },
38+
},
39+
40+
{
41+
name: 'webkit',
42+
use: { ...devices['Desktop Safari'] },
43+
},
44+
45+
/* Test against mobile viewports. */
46+
{
47+
name: 'Mobile Chrome',
48+
use: { ...devices['Pixel 5'] },
49+
},
50+
{
51+
name: 'Mobile Safari',
52+
use: { ...devices['iPhone 12'] },
53+
},
54+
],
55+
56+
/* Run your local dev server before starting the tests */
57+
webServer: {
58+
command: 'bundle exec rails server -p 3000',
59+
url: 'http://localhost:3000',
60+
reuseExistingServer: !process.env.CI,
61+
timeout: 120 * 1000,
62+
},
63+
});

0 commit comments

Comments
 (0)