Files
claude-skills-reference/engineering-team/playwright-pro/templates/onboarding/registration.md
Alireza Rezvani d33d03da50 feat: add playwright-pro plugin — production-grade Playwright testing toolkit (#254)
Complete Claude Code plugin with:
- 9 skills (/pw:init, generate, review, fix, migrate, coverage, testrail, browserstack, report)
- 3 specialized agents (test-architect, test-debugger, migration-planner)
- 55 test case templates across 11 categories (auth, CRUD, checkout, search, forms, dashboard, settings, onboarding, notifications, API, accessibility)
- TestRail MCP server (TypeScript) — 8 tools for bidirectional sync
- BrowserStack MCP server (TypeScript) — 7 tools for cross-browser testing
- Smart hooks (auto-validate tests, auto-detect Playwright projects)
- 6 curated reference docs (golden rules, locators, assertions, fixtures, pitfalls, flaky tests)
- Leverages Claude Code built-ins (/batch, /debug, Explore subagent)
- Zero-config for core features; TestRail/BrowserStack via env vars
- Both TypeScript and JavaScript support throughout

Co-authored-by: Leo <leo@openclaw.ai>
2026-03-05 13:50:05 +01:00

5.7 KiB

Registration Template

Tests signup form submission, validation, and post-registration flow.

Prerequisites

  • Unique test email for each run: {{newUserEmail}}
  • App running at {{baseUrl}}

TypeScript

import { test, expect } from '@playwright/test';

const uniqueEmail = `test+${Date.now()}@example.com`;

test.describe('Registration', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('{{baseUrl}}/register');
  });

  // Happy path: successful registration
  test('registers new user with valid data', async ({ page }) => {
    await page.getByRole('textbox', { name: /first name/i }).fill('{{firstName}}');
    await page.getByRole('textbox', { name: /last name/i }).fill('{{lastName}}');
    await page.getByRole('textbox', { name: /email/i }).fill(uniqueEmail);
    await page.getByRole('textbox', { name: /^password$/i }).fill('{{newPassword}}');
    await page.getByRole('textbox', { name: /confirm.*password/i }).fill('{{newPassword}}');
    await page.getByRole('checkbox', { name: /terms/i }).check();
    await page.getByRole('button', { name: /sign up|register|create account/i }).click();
    await expect(page).toHaveURL(/\/verify-email|\/dashboard|\/onboarding/);
  });

  // Happy path: success message or redirect
  test('shows confirmation after registration', async ({ page }) => {
    await page.getByRole('textbox', { name: /email/i }).fill(uniqueEmail);
    await page.getByRole('textbox', { name: /^password$/i }).fill('{{newPassword}}');
    await page.getByRole('checkbox', { name: /terms/i }).check();
    await page.getByRole('button', { name: /sign up|register/i }).click();
    await expect(page.getByText(/check your email|account created|welcome/i)).toBeVisible();
  });

  // Error case: email already registered
  test('shows error for already registered email', async ({ page }) => {
    await page.getByRole('textbox', { name: /email/i }).fill('{{existingUserEmail}}');
    await page.getByRole('textbox', { name: /^password$/i }).fill('{{newPassword}}');
    await page.getByRole('checkbox', { name: /terms/i }).check();
    await page.getByRole('button', { name: /sign up|register/i }).click();
    await expect(page.getByRole('alert')).toContainText(/already.*registered|email.*taken/i);
  });

  // Error case: terms not accepted
  test('blocks registration if terms not accepted', async ({ page }) => {
    await page.getByRole('textbox', { name: /email/i }).fill(uniqueEmail);
    await page.getByRole('textbox', { name: /^password$/i }).fill('{{newPassword}}');
    await page.getByRole('button', { name: /sign up|register/i }).click();
    await expect(page.getByText(/accept.*terms|terms.*required/i)).toBeVisible();
  });

  // Error case: weak password
  test('shows error for weak password', async ({ page }) => {
    await page.getByRole('textbox', { name: /^password$/i }).fill('123');
    await page.getByRole('textbox', { name: /^password$/i }).blur();
    await expect(page.getByText(/at least \d+ characters|too weak/i)).toBeVisible();
  });

  // Error case: passwords mismatch
  test('shows error when passwords do not match', async ({ page }) => {
    await page.getByRole('textbox', { name: /^password$/i }).fill('{{newPassword}}');
    await page.getByRole('textbox', { name: /confirm.*password/i }).fill('different');
    await page.getByRole('textbox', { name: /confirm.*password/i }).blur();
    await expect(page.getByText(/do not match/i)).toBeVisible();
  });

  // Edge case: already logged-in user redirected
  test('redirects to dashboard when already authenticated', async ({ page, context }) => {
    await context.addCookies([{ name: '{{sessionCookieName}}', value: '{{validSession}}', domain: '{{cookieDomain}}', path: '/' }]);
    await page.goto('{{baseUrl}}/register');
    await expect(page).toHaveURL('{{baseUrl}}/dashboard');
  });
});

JavaScript

const { test, expect } = require('@playwright/test');

test.describe('Registration', () => {
  test('registers with valid data', async ({ page }) => {
    const email = `test+${Date.now()}@example.com`;
    await page.goto('{{baseUrl}}/register');
    await page.getByRole('textbox', { name: /email/i }).fill(email);
    await page.getByRole('textbox', { name: /^password$/i }).fill('{{newPassword}}');
    await page.getByRole('checkbox', { name: /terms/i }).check();
    await page.getByRole('button', { name: /sign up|register/i }).click();
    await expect(page).toHaveURL(/\/verify-email|\/dashboard|\/onboarding/);
  });

  test('shows error for existing email', async ({ page }) => {
    await page.goto('{{baseUrl}}/register');
    await page.getByRole('textbox', { name: /email/i }).fill('{{existingUserEmail}}');
    await page.getByRole('textbox', { name: /^password$/i }).fill('{{newPassword}}');
    await page.getByRole('checkbox', { name: /terms/i }).check();
    await page.getByRole('button', { name: /sign up|register/i }).click();
    await expect(page.getByRole('alert')).toContainText(/already.*registered/i);
  });

  test('requires terms acceptance', async ({ page }) => {
    await page.goto('{{baseUrl}}/register');
    await page.getByRole('textbox', { name: /email/i }).fill(`t${Date.now()}@example.com`);
    await page.getByRole('textbox', { name: /^password$/i }).fill('{{newPassword}}');
    await page.getByRole('button', { name: /sign up|register/i }).click();
    await expect(page.getByText(/accept.*terms/i)).toBeVisible();
  });
});

Variants

Variant Description
Valid registration All fields → redirect or success message
Confirmation Email check or welcome shown
Existing email Error alert
Terms not accepted Validation error
Weak password Strength error on blur
Password mismatch Confirm error
Already authed Redirected to dashboard