Advanced (अपडेट: 3/6/2026)

Claude Code और Playwright से production-ready E2E testing

Claude Code और Playwright से E2E, mobile screenshots, auth state, Trace Viewer, selectors और CI retries सेट करें.

Claude Code और Playwright से production-ready E2E testing

Claude Code से सिर्फ “Playwright tests जोड़ दो” कहना production quality के लिए काफी नहीं है। ऐसा करने पर tests एक बार pass हो सकते हैं, पर वे CSS class पर depend करते हैं, हर test में login UI चलाते हैं, mobile screenshot नहीं रखते और CI fail होने पर Trace Viewer से कारण समझना मुश्किल हो जाता है।

इस guide में Claude Code को code generator नहीं, test-design partner की तरह इस्तेमाल किया गया है। E2E का मतलब End to End है: browser में user journey को शुरू से अंत तक चलाकर देखना। Playwright से हम revenue CTAs, authenticated pages, mobile layout, code blocks, Trace Viewer, CI retries और flaky tests को practical तरीके से संभालेंगे।

Official references के लिए Claude Code overview, Claude Code common workflows, और Playwright docs के Locators, Authentication, Screenshots, Trace Viewer, Retries, CI देखें। ClaudeCodeLab पर related reading: testing strategy, CI/CD setup, और responsive design

कौन से flows E2E में रखें

E2E tests real browser खोलते हैं, इसलिए वे unit tests से slow होते हैं। हर चीज E2E में डालने के बजाय उन flows को चुनें जहाँ browser-level proof जरूरी है।

Use caseक्या protect करता हैPlaywright proof
Article से products pageReader /products/ तक पहुँचता हैCTA link, URL, mobile tap
Signed-in dashboardAuthenticated user protected page खोलता हैstorageState, redirect, permission
Code article layoutCode blocks और tables mobile width नहीं तोड़तेMobile screenshot, no overflow, trace
flowchart LR
  A["Revenue या signup path"] --> B["Playwright E2E"]
  C["Mobile layout risk"] --> B
  D["Pure validation"] --> E["Unit tests"]
  F["API या component boundary"] --> G["Integration tests"]

Content site में भी यह practical है। अगर mobile पर CTA छिप जाए, long code line page को चौड़ा कर दे, या paid-user page CI में कभी test न हो, तो bug छोटा दिखता है लेकिन conversion और trust पर असर डालता है।

Claude Code को clear prompt दें

Claude Code codebase पढ़ सकता है, पर quality rules अपने आप तय नहीं करेगा। Prompt में routes, selector policy, command और allowed files साफ लिखें।

Existing Astro site पढ़कर Playwright E2E tests जोड़ें।

Goals:
- `/hi/blog/claude-code-playwright-testing/` से `/products/` और `/training/` reachable हैं
- 390px mobile width पर article, tables और code blocks horizontal overflow नहीं करते
- Authenticated tests में हर बार UI login न करें; `storageState` use करें
- CI में retries 2 और trace `on-first-retry` रखें

Constraints:
- `page.waitForTimeout()` use न करें
- CSS class chains के बजाय role, label, text या test id prefer करें
- केवल `playwright.config.ts` और `tests/e2e/**` बदलें
- `npx playwright test` चलाएँ और failures Trace Viewer से explain करें

Review करते समय देखें कि failure explainable है या नहीं, selector user intent से जुड़ा है या नहीं, और test data repeatable है या नहीं।

Copy-paste setup

cd site
npm i -D @playwright/test
npx playwright install
mkdir tests/e2e
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

const baseURL = process.env.BASE_URL ?? 'http://127.0.0.1:4321';
const hasAuth = Boolean(process.env.TEST_EMAIL && process.env.TEST_PASSWORD);
const authFile = 'playwright/.auth/user.json';

export default defineConfig({
  testDir: './tests/e2e',
  timeout: 30_000,
  expect: { timeout: 5_000 },
  fullyParallel: true,
  forbidOnly: Boolean(process.env.CI),
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 2 : undefined,
  reporter: process.env.CI ? [['html'], ['github']] : 'html',
  use: {
    baseURL,
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
  },
  ...(process.env.PLAYWRIGHT_WEB_SERVER === '1'
    ? {
        webServer: {
          command: 'npm run preview -- --host 127.0.0.1 --port 4321',
          url: baseURL,
          reuseExistingServer: !process.env.CI,
          timeout: 120_000,
        },
      }
    : {}),
  projects: [
    ...(hasAuth
      ? [
          {
            name: 'setup',
            testMatch: /.*\.setup\.ts/,
          },
        ]
      : []),
    {
      name: 'desktop-chrome',
      use: {
        ...devices['Desktop Chrome'],
        storageState: hasAuth ? authFile : undefined,
      },
      dependencies: hasAuth ? ['setup'] : [],
    },
    {
      name: 'mobile-safari',
      use: {
        ...devices['iPhone 13'],
        storageState: hasAuth ? authFile : undefined,
      },
      dependencies: hasAuth ? ['setup'] : [],
    },
  ],
});

Local run में retries off रखें ताकि problem जल्दी दिखे। CI में retries useful हैं, पर तभी जब trace, screenshot और HTML report save हों।

Authentication state save करें

हर test में UI login चलाना slow और fragile है। Playwright का storageState login के बाद browser state save करता है और बाकी tests उसे reuse करते हैं। playwright/.auth में sensitive cookies हो सकती हैं, इसलिए इसे git में commit न करें।

// tests/e2e/auth.setup.ts
import { test as setup, expect } from '@playwright/test';
import fs from 'node:fs';
import path from 'node:path';

const authFile = path.resolve('playwright/.auth/user.json');
const email = process.env.TEST_EMAIL;
const password = process.env.TEST_PASSWORD;

setup('save signed-in browser state', async ({ page }) => {
  setup.skip(!email || !password, 'Set TEST_EMAIL and TEST_PASSWORD to record auth state.');

  await page.goto('/login');
  await page.getByLabel(/email|メール|e-mail/i).fill(email!);
  await page.getByLabel(/password|パスワード/i).fill(password!);
  await page.getByRole('button', { name: /log in|sign in|ログイン/i }).click();

  await expect(page).toHaveURL(/dashboard|account|admin/);
  await expect(page.locator('body')).toBeVisible();

  fs.mkdirSync(path.dirname(authFile), { recursive: true });
  await page.context().storageState({ path: authFile });
});

Claude Code से कहें कि login behavior tests और authenticated feature tests अलग रखे। इससे login button बदलने पर पूरी E2E suite नहीं टूटेगी।

Mobile screenshot और code block QA

Technical articles में long code lines, tables और images mobile layout तोड़ सकते हैं। यह spec CTA, screenshot और horizontal overflow तीनों check करता है।

// tests/e2e/article-quality.spec.ts
import { test, expect } from '@playwright/test';

const articlePath = process.env.ARTICLE_PATH ?? '/hi/blog/claude-code-playwright-testing/';

test.describe('article quality checks', () => {
  test('article has monetization CTAs', async ({ page }) => {
    await page.goto(articlePath);

    await expect(page.getByRole('heading', { level: 1 })).toContainText(/Playwright|E2E|Claude Code/i);
    await expect(page.locator('a[href="/products/"], a[href="/products"]').first()).toBeVisible();
    await expect(page.locator('a[href="/training/"], a[href="/training"]').first()).toBeVisible();
  });

  test('mobile layout has no horizontal overflow', async ({ page }, testInfo) => {
    await page.setViewportSize({ width: 390, height: 844 });
    await page.goto(articlePath);
    await expect(page.locator('main, article').first()).toBeVisible();

    const overflow = await page.evaluate(() => ({
      viewport: window.innerWidth,
      documentWidth: document.documentElement.scrollWidth,
      offenders: Array.from(document.querySelectorAll('pre, table, img, iframe, .prose'))
        .filter((node) => {
          const rect = node.getBoundingClientRect();
          return rect.left < -1 || rect.right > window.innerWidth + 1;
        })
        .map((node) => {
          const rect = node.getBoundingClientRect();
          return `${node.tagName.toLowerCase()} ${Math.round(rect.left)}-${Math.round(rect.right)}`;
        }),
    }));

    expect(overflow.documentWidth, JSON.stringify(overflow)).toBeLessThanOrEqual(overflow.viewport + 2);
    expect(overflow.offenders).toEqual([]);
    await page.screenshot({ path: testInfo.outputPath('article-mobile.png'), fullPage: true });
  });

  test('code examples are present and copyable', async ({ page }) => {
    await page.goto(articlePath);

    const blocks = page.locator('pre code');
    await expect(blocks.first()).toBeVisible();
    expect(await blocks.count()).toBeGreaterThanOrEqual(3);
    await expect(blocks.nth(0)).toContainText(/playwright|defineConfig|test/i);
  });
});

Screenshot human review के लिए है; overflow assertion CI gate के लिए है।

Revenue और training CTAs protect करें

// tests/e2e/revenue-flows.spec.ts
import { test, expect } from '@playwright/test';

const articlePath = process.env.ARTICLE_PATH ?? '/hi/blog/claude-code-playwright-testing/';

test.describe('revenue and learning flows', () => {
  test('reader can move from article to products', async ({ page }) => {
    await page.goto(articlePath);

    await page.locator('a[href="/products/"], a[href="/products"]').first().click();
    await expect(page).toHaveURL(/\/products\/?$/);
    await expect(page.locator('main').first()).toBeVisible();
  });

  test('training CTA is reachable on mobile', async ({ page }) => {
    await page.setViewportSize({ width: 390, height: 844 });
    await page.goto(articlePath);

    await page.locator('a[href="/training/"], a[href="/training"]').first().click();
    await expect(page).toHaveURL(/\/training\/?$/);
    await expect(page.locator('main').first()).toBeVisible();
  });

  test('main navigation can open the blog index', async ({ page }) => {
    await page.goto('/');

    await expect(page.getByRole('navigation').first()).toBeVisible();
    await page.getByRole('link', { name: /blog|記事|articles/i }).first().click();
    await expect(page).toHaveURL(/blog/);
  });
});

Multilingual site में CTA text बदल सकता है। Critical actions के लिए stable href या data-testid अच्छा contract देता है।

Flaky tests कम करने वाले selectors

PrioritySelectorExampleWhy
HighRole + namepage.getByRole('button', { name: /save/i })User और accessibility view के करीब
HighLabelpage.getByLabel(/email/i)Form semantics भी check होते हैं
MediumTextpage.getByText(/Start trial/)साफ है, पर copy changes से टूट सकता है
MediumTest idpage.getByTestId('checkout-submit')Stable business action के लिए अच्छा
LowCSS structure.card:nth-child(3)Layout बदलते ही टूटता है

page.waitForTimeout() avoid करें। toBeVisible(), toHaveURL() और toContainText() जैसी web-first assertions real condition का इंतजार करती हैं।

Trace Viewer से failure समझें

npx playwright test --trace on
npx playwright show-report
npx playwright show-trace test-results/path-to-trace/trace.zip

Failure Claude Code को भेजते समय test name, trace में दिखी screen state और expected user behavior दें। इससे वह blind timeout नहीं बढ़ाएगा, बल्कि selector, data setup या UI issue पर काम करेगा।

CI example

# .github/workflows/playwright.yml
name: Playwright E2E

on:
  pull_request:
  push:
    branches: [main]

jobs:
  e2e:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    defaults:
      run:
        working-directory: site
    env:
      BASE_URL: http://127.0.0.1:4321
      PLAYWRIGHT_WEB_SERVER: "1"
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
          cache-dependency-path: site/package-lock.json
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npm run build
      - run: npx playwright test
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: site/playwright-report
          retention-days: 7

Retry flaky test को ठीक नहीं करता; वह बस classify करके evidence छोड़ता है। HTML report और trace zip जरूर देखें।

Common pitfalls

पहली गलती है हर चीज E2E में डालना। Calculations, validation और permission edge cases को unit या integration tests में रखें।

दूसरी गलती auth state commit करना है। Limited test user use करें और playwright/.auth को git से बाहर रखें।

तीसरी गलती retry से instability छिपाना है। अगर test retry पर ही pass होता है, तो वह अभी भी risk है।

चौथी गलती Claude Code को बहुत बड़ा scope देना है। पहले failing test जोड़ें, trace देखें, फिर smallest product fix करें।

Self-serve implementation के लिए ClaudeCodeLab products templates से शुरू करें। Team rollout के लिए training review rules, CI policy और onboarding align करने में मदद करता है।

मैंने इस workflow को local ClaudeCodeLab-style article page पर आजमाया: 390px screenshot, code block overflow, /products/ और /training/ CTA navigation, और CI retry config। पहले useful failures Playwright में नहीं थे; वे long code lines और ambiguous link names थे। इन्हें ठीक करने के बाद Trace Viewer अगली Claude Code prompt के लिए solid evidence बन गया।

#Claude Code #Playwright #E2E testing #test automation #quality assurance
मुफ़्त

मुफ़्त PDF: Claude Code cheatsheet

Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.

हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.

Masa

लेखक के बारे में

Masa

Claude Code workflow और team adoption पर काम करने वाला engineer.