Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 2 additions & 47 deletions packages/playwright/src/agents/playwright-test-planner.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ model: sonnet
color: green
tools:
- search
- edit
- playwright-test/browser_click
- playwright-test/browser_close
- playwright-test/browser_console_messages
Expand All @@ -24,6 +23,7 @@ tools:
- playwright-test/browser_type
- playwright-test/browser_wait_for
- playwright-test/planner_setup_page
- playwright-test/planner_save_plan
---

You are an expert web test planner with extensive experience in quality assurance, user experience testing, and test
Expand Down Expand Up @@ -61,52 +61,7 @@ You will:

5. **Create Documentation**

Save your test plan as requested:
- Executive summary of the tested page/application
- Individual scenarios as separate sections
- Each scenario formatted with numbered steps
- Each test case with proposed file name for implementation
- Clear expected results for verification

<example-spec>
# TodoMVC Application - Comprehensive Test Plan

## Application Overview

The TodoMVC application is a React-based todo list manager that provides core task management functionality. The
application features:

- **Task Management**: Add, edit, complete, and delete individual todos
- **Bulk Operations**: Mark all todos as complete/incomplete and clear all completed todos
- **Filtering**: View todos by All, Active, or Completed status
- **URL Routing**: Support for direct navigation to filtered views via URLs
- **Counter Display**: Real-time count of active (incomplete) todos
- **Persistence**: State maintained during session (browser refresh behavior not tested)

## Test Scenarios

### 1. Adding New Todos

**Seed:** `tests/seed.spec.ts`

#### 1.1 Add Valid Todo

**File** `tests/adding-new-todos/add-valid-todo.spec.ts`

**Steps:**
1. Click in the "What needs to be done?" input field
2. Type "Buy groceries"
3. Press Enter key

**Expected Results:**
- Todo appears in the list with unchecked checkbox
- Counter shows "1 item left"
- Input field is cleared and ready for next entry
- Todo list controls become visible (Mark all as complete checkbox)

#### 1.2
...
</example-spec>
Submit your test plan using `planner_save_plan` tool.

**Quality Standards**:
- Write steps that are specific enough for any tester to follow
Expand Down
90 changes: 90 additions & 0 deletions packages/playwright/src/mcp/test/plannerTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
* limitations under the License.
*/

import fs from 'fs';
import path from 'path';

import { z } from '../sdk/bundle';
import { defineTestTool } from './testTool';

Expand All @@ -35,3 +38,90 @@ export const setupPage = defineTestTool({
return { content: [] };
},
});

const planSchema = z.object({
overview: z.string().describe('A brief overview of the application to be tested'),
suites: z.array(z.object({
name: z.string().describe('The name of the suite'),
seedFile: z.string().describe('A seed file that was used to setup the page for testing.'),
tests: z.array(z.object({
name: z.string().describe('The name of the test'),
file: z.string().describe('The file the test should be saved to, for example: "tests/<suite-name>/<test-name>.spec.ts".'),
steps: z.array(z.string().describe(`The steps to be executed to perform the test. For example: 'Click on the "Submit" button'`)),
expectedResults: z.array(z.string().describe('The expected results of the steps for test to verify.')),
})),
})),
});

export const submitTestPlan = defineTestTool({
schema: {
name: 'planner_submit_plan',
title: 'Submit test plan',
description: 'Submit the test plan to the test planner',
inputSchema: planSchema,
type: 'readOnly',
},

handle: async (context, params) => {
return {
content: [{
type: 'text',
text: JSON.stringify(params, null, 2),
}],
};
},
});

export const saveTestPlan = defineTestTool({
schema: {
name: 'planner_save_plan',
title: 'Save test plan as markdown file',
description: 'Save the test plan as a markdown file',
inputSchema: planSchema.extend({
name: z.string().describe('The name of the test plan, for example: "Test Plan".'),
fileName: z.string().describe('The file to save the test plan to, for example: "spec/test.plan.md". Relative to the workspace root.'),
}),
type: 'readOnly',
},

handle: async (context, params) => {
const lines: string[] = [];
lines.push(`# ${params.name}`);
lines.push(``);
lines.push(`## Application Overview`);
lines.push(``);
lines.push(params.overview);
lines.push(``);
lines.push(`## Test Scenarios`);
for (let i = 0; i < params.suites.length; i++) {
lines.push(``);
const suite = params.suites[i];
lines.push(`### ${i + 1}. ${suite.name}`);
lines.push(``);
lines.push(`**Seed:** \`${suite.seedFile}\``);
for (let j = 0; j < suite.tests.length; j++) {
lines.push(``);
const test = suite.tests[j];
lines.push(`#### ${i + 1}.${j + 1}. ${test.name}`);
lines.push(``);
lines.push(`**File:** \`${test.file}\``);
lines.push(``);
lines.push(`**Steps:**`);
for (let k = 0; k < test.steps.length; k++)
lines.push(` ${k + 1}. ${test.steps[k]}`);
lines.push(``);
lines.push(`**Expected Results:**`);
for (const result of test.expectedResults)
lines.push(` - ${result}`);
}
}
lines.push(``);
await fs.promises.writeFile(path.resolve(context.rootPath, params.fileName), lines.join('\n'));
return {
content: [{
type: 'text',
text: `Test plan saved to ${params.fileName}`,
}],
};
},
});
Loading