Skip to content

Commit c178bf2

Browse files
authored
♻️ Migrate Storybook & Static-Site SDKs from Puppeteer to Playwright (#193)
## Summary This PR fixes critical screenshot timeout issues in CI and dramatically improves performance by migrating both the Storybook and Static-Site SDKs from Puppeteer to Playwright. **Root cause:** Puppeteer's new headless mode has known issues with parallel screenshot capture causing timeouts. Playwright's BrowserContext provides proper isolation for parallel workers. **Results:** - Screenshots now complete in <1 second instead of timing out after 60+ seconds - Client-side navigation for Storybook provides ~47x speedup (94s → 2s for 10 screenshots) ## Changes ### Puppeteer → Playwright Migration - Replace `puppeteer` with `playwright-core` in both SDKs - Migrate from tab-based pooling to BrowserContext-based pooling for proper isolation - Update API calls: `setViewport()` → `setViewportSize()`, `networkidle2` → `networkidle` - Fix `page.evaluate()` syntax: Playwright uses object destructuring `({ args }) => {}, { args }` ### Chrome Browser Flags Audit - Remove deprecated flags causing hangs (`--disable-gpu` + `--disable-software-rasterizer`) - Remove flags deprecated since 2017-2019 (`--disable-translate`, `--safebrowsing-disable-auto-update`) - Use modern `--disable-features=Translate,OptimizationHints,MediaRouter` approach - Add screenshot consistency flags (`--force-color-profile=srgb`, `--hide-scrollbars`) - Document flags in `docs/browser-flags.md` with source of truth references ### Storybook Client-Side Navigation - Use `__STORYBOOK_PREVIEW__.channel.emit('setCurrentStory')` instead of full page reloads - First story per tab: Full page load to initialize Storybook - Subsequent stories: Client-side navigation + wait for `storyRendered` event - Sort tasks by viewport to minimize resize operations ### Plugin System Enhancement - Support `vizzlyPlugin` field in package.json for plugin registration ### CI Improvements - Update E2E workflow for Playwright browser installation - Restructure SDK E2E tests to match real user workflow - Add proper build steps before E2E tests ## Test plan - [x] All unit tests pass - [x] Storybook E2E: 5 screenshots in 0s (TDD mode) - [x] Storybook E2E: 5 screenshots in 0s (Cloud mode) - previously ALL timed out - [x] Static-Site E2E: 5 screenshots in 1s (TDD mode) - [x] Static-Site E2E: Works (Cloud mode) - previously slow/timing out - [x] CI passes for all SDK E2E jobs
1 parent daa9fa1 commit c178bf2

35 files changed

Lines changed: 1377 additions & 2010 deletions

.github/workflows/sdk-e2e.yml

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,34 +145,44 @@ jobs:
145145
working-directory: ./clients/storybook
146146
run: npm install
147147

148+
- name: Build Storybook client
149+
working-directory: ./clients/storybook
150+
run: npm run build
151+
148152
- name: Get Playwright version
149153
working-directory: ./clients/storybook
150154
id: playwright-version
151-
run: echo "version=$(npx playwright --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')" >> $GITHUB_OUTPUT
155+
run: echo "version=$(node -p "require('playwright-core/package.json').version")" >> $GITHUB_OUTPUT
152156

153157
- name: Cache Playwright browsers
154158
uses: actions/cache@v4
155159
id: playwright-cache
156160
with:
157161
path: ~/.cache/ms-playwright
158-
key: playwright-${{ steps.playwright-version.outputs.version }}-chromium
162+
key: playwright-${{ steps.playwright-version.outputs.version }}-storybook-chromium
159163

160164
- name: Install Playwright browsers
161165
if: steps.playwright-cache.outputs.cache-hit != 'true'
162166
working-directory: ./clients/storybook
163-
run: npx playwright install chromium --with-deps
167+
run: npx playwright-core install chromium --with-deps
168+
169+
- name: Build example-storybook
170+
working-directory: ./clients/storybook/example-storybook
171+
run: npm install && npm run build-storybook
164172

165173
- name: Run E2E tests (TDD mode)
166174
working-directory: ./clients/storybook
167175
run: ../../bin/vizzly.js tdd run "npm run test:e2e"
168176
env:
169177
CI: true
178+
VIZZLY_LOG_LEVEL: debug
170179

171180
- name: Run E2E tests (Cloud mode)
172181
working-directory: ./clients/storybook
173182
run: ../../bin/vizzly.js run "npm run test:e2e"
174183
env:
175184
CI: true
185+
VIZZLY_LOG_LEVEL: debug
176186
VIZZLY_TOKEN: ${{ secrets.VIZZLY_STORYBOOK_CLIENT_TOKEN }}
177187
VIZZLY_COMMIT_MESSAGE: ${{ github.event.pull_request.head.commit.message || github.event.head_commit.message }}
178188
VIZZLY_COMMIT_SHA: ${{ github.event.pull_request.head.sha || github.event.head_commit.id }}
@@ -202,22 +212,26 @@ jobs:
202212
working-directory: ./clients/static-site
203213
run: npm install
204214

215+
- name: Build Static-Site client
216+
working-directory: ./clients/static-site
217+
run: npm run build
218+
205219
- name: Get Playwright version
206220
working-directory: ./clients/static-site
207221
id: playwright-version
208-
run: echo "version=$(npx playwright --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')" >> $GITHUB_OUTPUT
222+
run: echo "version=$(node -p "require('playwright-core/package.json').version")" >> $GITHUB_OUTPUT
209223

210224
- name: Cache Playwright browsers
211225
uses: actions/cache@v4
212226
id: playwright-cache
213227
with:
214228
path: ~/.cache/ms-playwright
215-
key: playwright-${{ steps.playwright-version.outputs.version }}-chromium
229+
key: playwright-${{ steps.playwright-version.outputs.version }}-static-site-chromium
216230

217231
- name: Install Playwright browsers
218232
if: steps.playwright-cache.outputs.cache-hit != 'true'
219233
working-directory: ./clients/static-site
220-
run: npx playwright install chromium --with-deps
234+
run: npx playwright-core install chromium --with-deps
221235

222236
- name: Run E2E tests (TDD mode)
223237
working-directory: ./clients/static-site

clients/static-site/.vizzlyrc.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Vizzly config for Static-Site SDK development
3+
*
4+
* This config explicitly loads the local plugin since it's not installed
5+
* in node_modules during development.
6+
*/
7+
export default {
8+
// Load the local plugin directly
9+
plugins: ['./dist/plugin.js'],
10+
11+
// Default static-site config for E2E tests
12+
staticSite: {
13+
viewports: [{ name: 'default', width: 1280, height: 720 }],
14+
concurrency: 3,
15+
browser: {
16+
headless: true,
17+
},
18+
},
19+
};

0 commit comments

Comments
 (0)