Skip to content

Feature/video recording #116

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
95 changes: 95 additions & 0 deletions docs/playwright-web/Recording-Videos.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Recording Videos

The MCP Playwright server supports recording videos of browser sessions. This feature is useful for debugging, documentation, and creating demos.

## Starting Video Recording

To start recording a video, use the `playwright_start_video` tool:

```json
{
"name": "playwright_start_video",
"parameters": {
"path": "/path/to/save/videos", // Optional - defaults to user's Videos folder
"width": 1280, // Optional - defaults to 1280
"height": 720 // Optional - defaults to 720
}
}
```

When you start video recording:

1. The current browser session is closed
2. A new browser session with video recording enabled is created
3. If you were on a specific URL, the new session will navigate back to it

## Stopping Video Recording

To stop recording and save the video file, use the `playwright_stop_video` tool:

```json
{
"name": "playwright_stop_video",
"parameters": {}
}
```

When you stop video recording:

1. The current browser context is closed, which automatically saves the video
2. A new browser context without video recording is created
3. If you were on a specific URL, the new session will navigate back to it

## Video Format and Location

- Videos are saved in the WebM format
- By default, videos are saved to the user's Videos folder
- Each page in a browser context creates its own video file
- Video files are named automatically with a timestamp
- The resolution is determined by the width and height parameters (default: 1280x720)

## Example Usage

Here's a complete example of starting a browser session, recording a video, and then stopping the recording:

```json
// First, navigate to a website
{
"name": "playwright_navigate",
"parameters": {
"url": "https://example.com"
}
}

// Start video recording
{
"name": "playwright_start_video",
"parameters": {
"path": "/my/videos/folder",
"width": 1920,
"height": 1080
}
}

// Perform some actions...
{
"name": "playwright_click",
"parameters": {
"selector": "#my-button"
}
}

// Stop recording
{
"name": "playwright_stop_video",
"parameters": {}
}
```

## Technical Notes

- Video recording uses Playwright's built-in video recording capabilities
- Starting a recording requires creating a new browser context
- Stopping a recording requires closing the browser context
- Video files are saved when the context is closed
- The feature works in headless and headful browser modes
65 changes: 65 additions & 0 deletions docs/playwright-web/Supported-Tools.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Supported Tools

The Playwright MCP server provides the following tools:

## Browser/Page Management

- `playwright_navigate` - Navigate to a URL
- `playwright_close` - Close the browser and release all resources

## Interactions

- `playwright_click` - Click an element on the page
- `playwright_iframe_click` - Click an element in an iframe on the page
- `playwright_fill` - Fill out an input field
- `playwright_select` - Select an element on the page with Select tag
- `playwright_hover` - Hover an element on the page
- `playwright_drag` - Drag an element to a target location
- `playwright_press_key` - Press a keyboard key
- `playwright_click_and_switch_tab` - Click a link and switch to the newly opened tab

## JavaScript Execution

- `playwright_evaluate` - Execute JavaScript in the browser console
- `playwright_console_logs` - Retrieve console logs from the browser with filtering options

## Response Handling

- `playwright_expect_response` - Ask Playwright to start waiting for a HTTP response
- `playwright_assert_response` - Wait for and validate a previously initiated HTTP response wait operation

## Browser Configuration

- `playwright_custom_user_agent` - Set a custom User Agent for the browser

## Page Content

- `playwright_get_visible_text` - Get the visible text content of the current page
- `playwright_get_visible_html` - Get the HTML content of the current page

## Navigation

- `playwright_go_back` - Navigate back in browser history
- `playwright_go_forward` - Navigate forward in browser history

## Media Capture

- `playwright_screenshot` - Take a screenshot of the current page or a specific element
- `playwright_save_as_pdf` - Save the current page as a PDF file
- `playwright_start_video` - Start recording video of browser session
- `playwright_stop_video` - Stop video recording and save file

## API Requests

- `playwright_get` - Perform an HTTP GET request
- `playwright_post` - Perform an HTTP POST request
- `playwright_put` - Perform an HTTP PUT request
- `playwright_patch` - Perform an HTTP PATCH request
- `playwright_delete` - Perform an HTTP DELETE request

## Code Generation

- `start_codegen_session` - Start a new code generation session to record Playwright actions
- `end_codegen_session` - End a code generation session and generate the test file
- `get_codegen_session` - Get information about a code generation session
- `clear_codegen_session` - Clear a code generation session without generating a test
43 changes: 43 additions & 0 deletions src/__tests__/tools/video.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Import the types
import { ToolContext } from '../../tools/common/types.js';

// Mocking the filesystem operations to avoid permission issues
jest.mock('fs', () => ({
existsSync: jest.fn().mockReturnValue(true),
mkdirSync: jest.fn()
}));

// Skip importing the actual tools until after mocks
let StartVideoRecordingTool;
let StopVideoRecordingTool;

describe('Video Recording Tools', () => {
beforeAll(() => {
// Import tools after mocks are set up
const videoModule = require('../../tools/browser/video.js');
StartVideoRecordingTool = videoModule.StartVideoRecordingTool;
StopVideoRecordingTool = videoModule.StopVideoRecordingTool;
});

test('StartVideoRecordingTool exists', () => {
expect(typeof StartVideoRecordingTool).toBe('function');
});

test('StopVideoRecordingTool exists', () => {
expect(typeof StopVideoRecordingTool).toBe('function');
});

test('StartVideoRecordingTool returns error if browser not initialized', async () => {
// Setup
const mockContextNoBrowser = { server: {} } as ToolContext;
const tool = new StartVideoRecordingTool({});
const args = {};

// Execute
const result = await tool.execute(args, mockContextNoBrowser);

// Assert
expect(result.isError).toBe(true);
expect(result.content[0].text).toContain('Browser not initialized');
});
});
14 changes: 13 additions & 1 deletion src/toolHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import {
ConsoleLogsTool,
ExpectResponseTool,
AssertResponseTool,
CustomUserAgentTool
CustomUserAgentTool,
StartVideoRecordingTool,
StopVideoRecordingTool
} from './tools/browser/index.js';
import {
ClickTool,
Expand Down Expand Up @@ -96,6 +98,8 @@ let dragTool: DragTool;
let pressKeyTool: PressKeyTool;
let saveAsPdfTool: SaveAsPdfTool;
let clickAndSwitchTabTool: ClickAndSwitchTabTool;
let startVideoRecordingTool: StartVideoRecordingTool;
let stopVideoRecordingTool: StopVideoRecordingTool;


interface BrowserSettings {
Expand Down Expand Up @@ -306,6 +310,8 @@ function initializeTools(server: any) {
if (!pressKeyTool) pressKeyTool = new PressKeyTool(server);
if (!saveAsPdfTool) saveAsPdfTool = new SaveAsPdfTool(server);
if (!clickAndSwitchTabTool) clickAndSwitchTabTool = new ClickAndSwitchTabTool(server);
if (!startVideoRecordingTool) startVideoRecordingTool = new StartVideoRecordingTool(server);
if (!stopVideoRecordingTool) stopVideoRecordingTool = new StopVideoRecordingTool(server);
}

/**
Expand Down Expand Up @@ -504,6 +510,12 @@ export async function handleToolCall(
case "playwright_click_and_switch_tab":
return await clickAndSwitchTabTool.execute(args, context);

case "playwright_start_video":
return await startVideoRecordingTool.execute(args, context);

case "playwright_stop_video":
return await stopVideoRecordingTool.execute(args, context);

default:
return {
content: [{
Expand Down
27 changes: 26 additions & 1 deletion src/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,29 @@ import { codegenTools } from './tools/codegen';

export function createToolDefinitions() {
return [
// Video Recording tools
{
name: "playwright_start_video",
description: "Start recording video of browser session",
inputSchema: {
type: "object",
properties: {
path: { type: "string", description: "Directory path to save video file (default: user's Videos folder)" },
width: { type: "number", description: "Video width in pixels (default: 1280)" },
height: { type: "number", description: "Video height in pixels (default: 720)" }
},
required: []
}
},
{
name: "playwright_stop_video",
description: "Stop video recording and save file",
inputSchema: {
type: "object",
properties: {},
required: []
}
},
// Codegen tools
{
name: "start_codegen_session",
Expand Down Expand Up @@ -433,7 +456,9 @@ export const BROWSER_TOOLS = [
"playwright_drag",
"playwright_press_key",
"playwright_save_as_pdf",
"playwright_click_and_switch_tab"
"playwright_click_and_switch_tab",
"playwright_start_video",
"playwright_stop_video"
];

// API Request tools for conditional launch
Expand Down
1 change: 1 addition & 0 deletions src/tools/browser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from './console.js';
export * from './interaction.js';
export * from './response.js';
export * from './useragent.js';
export * from './video.js';

// TODO: Add exports for other browser tools as they are implemented
// export * from './interaction.js';
Loading