Skip to content
Development
Skill

/e2e-tests-studio

REQUIRED when modifying any file in packages/playground-ui or packages/playground. Triggers on: React component creation/modification/refactoring, UI changes, new playground features, bug fixes affecting studio UI. Generates Playwright E2E tests that validate PRODUCT BEHAVIOR,

From plugin
mastra
27k30 skills14 commands
Install
$ npx -y skills add mastra-ai/mastra --skill e2e-tests-studio --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/e2e-tests-studio

Context preview

The summary Claude sees to decide when to auto-load this skill.

REQUIRED when modifying any file in packages/playground-ui or packages/playground. Triggers on: React component creation/modification/refactoring, UI changes, new playground features, bug fixes affecting studio UI. Generates Playwright E2E tests that validate PRODUCT BEHAVIOR,

SKILL.md

e2e-tests-studio.SKILL.md
name: e2e-tests-studio
description: >
  REQUIRED when modifying any file in packages/playground-ui or packages/playground.
  Triggers on: React component creation/modification/refactoring, UI changes,
  new playground features, bug fixes affecting studio UI. Generates Playwright E2E tests
  that validate PRODUCT BEHAVIOR, not just UI states.
model: claude-opus-4-5

E2E Behavior Validation for Frontend Modifications

Core Principle: Test Product Behavior, Not UI States

**CRITICAL**: Tests must verify that product features WORK correctly, not just that UI elements render.

What NOT to test (UI States):

  • ❌ "Dropdown opens when clicked"
  • ❌ "Modal appears after button click"
  • ❌ "Loading spinner shows during request"
  • ❌ "Form fields are visible"
  • ❌ "Sidebar collapses"

What TO test (Product Behavior):

  • ✅ "Selecting an LLM provider configures the agent to use that provider"
  • ✅ "Creating a new agent persists it and shows in the agents list"
  • ✅ "Running a tool with parameters returns the expected output"
  • ✅ "Chat messages stream correctly and maintain conversation context"
  • ✅ "Workflow execution triggers tools in the correct order"

BDD Structure (REQUIRED)

**Every E2E spec MUST follow the same BDD shape as the MSW tests.** In `packages/playground`, `e2e-bdd/test-needs-when-describe` enforces this shape.

The structure has exactly three levels:

1. **Outer `test.describe`** = the unit under test (one page or feature per file). 2. **Inner `test.describe('when …')`** = exactly ONE precondition. The title MUST start with `when`. 3. **Each `test`** = exactly ONE observable outcome.

import { test, expect } from '@playwright/test';
import { resetStorage } from '../__utils__/reset-storage';

test.describe('Tools list page', () => {
  // the unit
  test.afterEach(async () => {
    await resetStorage();
  });

  test.describe('when a registered tool is clicked', () => {
    // ONE precondition (starts with "when")
    test('navigates to that tool detail page', async ({ page }) => {
      // ONE outcome
      await page.goto('/tools');
      await page.locator('text=Get current weather for a location').click();
      await expect(page).toHaveURL(/\/tools\/weatherInfo$/);
    });

    test('shows the tool name as the page heading', async ({ page }) => {
      // ONE outcome
      await page.goto('/tools');
      await page.locator('text=Get current weather for a location').click();
      await expect(page.locator('h2')).toHaveText('weatherInfo');
    });
  });
});

Rules:

  • One outer `test.describe` per file naming the unit.
  • Every leaf `test` lives inside a `test.describe('when …')` precondition group. **No top-level flat `test()`.**
  • Split a multi-assertion `test()` only where assertions represent **distinct outcomes**; keep tightly-coupled assertions that prove a single outcome together. Never drop an assertion.
  • Place `beforeEach`/`afterEach` in the narrowest `describe` scope that needs them.

Prerequisites

Requires Playwright MCP server. If the `browser_navigate` tool is unavailable, instruct the user to add it:

claude mcp add playwright -- npx @playwright/mcp@latest

Step 1: Understand the Feature Intent

Before writing ANY test, answer these questions:

1. **What user problem does this feature solve?** 2. **What is the expected outcome when the feature works correctly?** 3. **What data flows through the system?** (user input → API → state → UI) 4. **What should persist after page reload?** 5. **What downstream effects should this action have?**

Document these answers as comments in your test file.

Step 2: Build and Start

pnpm build:cli
cd packages/playground/e2e/kitchen-sink && pnpm dev

Verify server at http://localhost:4111

Step 3: Map Feature to Behavior Tests

Feature-to-Test Mapping Guide

| Feature Category | What to Test | Example Assertion | | -------------------------- | ------------------------------------------------- | ------------------------------------------------------------ | | **Agent Configuration** | Config changes affect agent behavior | Send message → verify response uses selected model | | **LLM Provider Selection** | Selected provider is used in requests | Intercept API call → verify provider in request payload | | **Tool Execution** | Tool runs with correct params & returns result | Execute tool → verify output matches expected transformation | | **Workflow Execution** | Steps execute in order, data flows between steps | Run workflow → verify each step's output feeds next step | | **Chat/Streaming** | Messages persist, context maintained across turns | Multi-turn conversation → verify context awareness | | **MCP Server Tools** | Server tools are callable and return data | Call MCP tool → verify response structure and content | | **Memory/Persistence** | Data survives page reload | Create item → reload → verify item exists | | **Error Handling** | Errors surface correctly to user | Trigger error condition → verify error message + recovery |

Step 4: Write Behavior-Focused Tests

Test Structure Template

import { test, expect, Page } from '@playwright/test';
import { resetStorage } from '../__utils__/reset-storage';
import { selectFixture } from '../__utils__/select-fixture';
import { nanoid } from 'nanoid';

/**
 * FEATURE: [Name of feature]
 * USER STORY: As a user, I want to [action] so that [outcome]
 * BEHAVIOR UNDER TEST: [Specific behavior being validated]
 */

test.describe('[Feature Name] - Behavior Tests', () => {
  let page: Page;

  test.beforeEach(async ({ browser }) => {
    const context = await browser.newContext();
    page = await context.newPage();
  });

  test.afterEach(async () => {
    a
Read more
Ships withmastra

Mastra is a framework for building AI-powered applications and agents with a modern TypeScript stack. It includes everything you need to go from early prototypes to production-ready applications.

Get the whole plugin

Other skills on mastra.