mirror of
https://github.com/microsoft/playwright-mcp.git
synced 2025-07-25 16:02:26 +08:00
chore: auto update tools in README (#219)
Motivation: Keeping the readme up to date is a manual effort - this keeps it automatically up to date and prevents things like https://github.com/microsoft/playwright-mcp/pull/214 and other consistency errors in the future.
This commit is contained in:
parent
7695717546
commit
0c3792d231
23
.github/workflows/ci.yml
vendored
23
.github/workflows/ci.yml
vendored
@ -7,7 +7,25 @@ on:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build-and-test:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Use Node.js 18
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
cache: 'npm'
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- run: npm run build
|
||||
- name: Run ESLint
|
||||
run: npm run lint
|
||||
- run: npm run update-readme
|
||||
- name: Ensure no changes
|
||||
run: git diff --exit-code
|
||||
|
||||
test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@ -33,9 +51,6 @@ jobs:
|
||||
if: ${{ matrix.os == 'macos-latest' }} # MS Edge is not preinstalled on macOS runners.
|
||||
run: npx playwright install msedge
|
||||
|
||||
- name: Run linting
|
||||
run: npm run lint
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
|
||||
|
129
README.md
129
README.md
@ -168,27 +168,43 @@ transport = new SSEServerTransport("/messages", res);
|
||||
server.connect(transport);
|
||||
```
|
||||
|
||||
<!--- Generated by update-readme.js -->
|
||||
|
||||
### Snapshot-based Interactions
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_snapshot**
|
||||
- Description: Capture accessibility snapshot of the current page, this is better than screenshot
|
||||
- Parameters: None
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_click**
|
||||
- Description: Perform click on a web page
|
||||
- Parameters:
|
||||
- `element` (string): Human-readable element description used to obtain permission to interact with the element
|
||||
- `ref` (string): Exact target element reference from the page snapshot
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_drag**
|
||||
- Description: Perform drag and drop between two elements
|
||||
- Parameters:
|
||||
- `startElement` (string): Human-readable source element description used to obtain the permission to interact with the element
|
||||
- `startRef` (string): Exact source element reference from the page snapshot
|
||||
- `endElement` (string): Human-readable target element description used to obtain the permission to interact with the element
|
||||
- `endRef` (string): Exact target element reference from the page snapshot
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_hover**
|
||||
- Description: Hover over element on page
|
||||
- Parameters:
|
||||
- `element` (string): Human-readable element description used to obtain permission to interact with the element
|
||||
- `ref` (string): Exact target element reference from the page snapshot
|
||||
|
||||
- **browser_drag**
|
||||
- Description: Perform drag and drop between two elements
|
||||
- Parameters:
|
||||
- `startElement` (string): Human-readable source element description used to obtain permission to interact with the element
|
||||
- `startRef` (string): Exact source element reference from the page snapshot
|
||||
- `endElement` (string): Human-readable target element description used to obtain permission to interact with the element
|
||||
- `endRef` (string): Exact target element reference from the page snapshot
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_type**
|
||||
- Description: Type text into editable element
|
||||
@ -199,6 +215,8 @@ server.connect(transport);
|
||||
- `submit` (boolean, optional): Whether to submit entered text (press Enter after)
|
||||
- `slowly` (boolean, optional): Whether to type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once.
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_select_option**
|
||||
- Description: Select an option in a dropdown
|
||||
- Parameters:
|
||||
@ -206,17 +224,25 @@ server.connect(transport);
|
||||
- `ref` (string): Exact target element reference from the page snapshot
|
||||
- `values` (array): Array of values to select in the dropdown. This can be a single value or multiple values.
|
||||
|
||||
- **browser_snapshot**
|
||||
- Description: Capture accessibility snapshot of the current page, this is better than screenshot
|
||||
- Parameters: None
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_take_screenshot**
|
||||
- Description: Take a screenshot of the current page. You can't perform actions based on the screenshot, use browser_snapshot for actions.
|
||||
- Parameters:
|
||||
- `raw` (boolean, optional): Whether to return without compression (in PNG format). Default is false, which returns a JPEG image.
|
||||
- `element` (string, optional): Human-readable element description used to obtain permission to screenshot the element. If not provided, the screenshot will be taken of viewport. If element is provided, ref must be provided too.
|
||||
- `ref` (string, optional): Exact target element reference from the page snapshot. If not provided, the screenshot will be taken of viewport. If ref is provided, element must be provided too.
|
||||
|
||||
### Vision-based Interactions
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_screen_capture**
|
||||
- Description: Take a screenshot of the current page
|
||||
- Parameters: None
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_screen_move_mouse**
|
||||
- Description: Move mouse to a given position
|
||||
- Parameters:
|
||||
@ -224,9 +250,7 @@ server.connect(transport);
|
||||
- `x` (number): X coordinate
|
||||
- `y` (number): Y coordinate
|
||||
|
||||
- **browser_screen_capture**
|
||||
- Description: Take a screenshot of the current page
|
||||
- Parameters: None
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_screen_click**
|
||||
- Description: Click left mouse button
|
||||
@ -235,6 +259,8 @@ server.connect(transport);
|
||||
- `x` (number): X coordinate
|
||||
- `y` (number): Y coordinate
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_screen_drag**
|
||||
- Description: Drag left mouse button
|
||||
- Parameters:
|
||||
@ -244,33 +270,38 @@ server.connect(transport);
|
||||
- `endX` (number): End X coordinate
|
||||
- `endY` (number): End Y coordinate
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_screen_type**
|
||||
- Description: Type text
|
||||
- Parameters:
|
||||
- `text` (string): Text to type
|
||||
- `text` (string): Text to type into the element
|
||||
- `submit` (boolean, optional): Whether to submit entered text (press Enter after)
|
||||
|
||||
- **browser_press_key**
|
||||
- Description: Press a key on the keyboard
|
||||
- Parameters:
|
||||
- `key` (string): Name of the key to press or a character to generate, such as `ArrowLeft` or `a`
|
||||
|
||||
### Tab Management
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_tab_list**
|
||||
- Description: List browser tabs
|
||||
- Parameters: None
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_tab_new**
|
||||
- Description: Open a new tab
|
||||
- Parameters:
|
||||
- `url` (string, optional): The URL to navigate to in the new tab. If not provided, the new tab will be blank.
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_tab_select**
|
||||
- Description: Select a tab by index
|
||||
- Parameters:
|
||||
- `index` (number): The index of the tab to select
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_tab_close**
|
||||
- Description: Close a tab
|
||||
- Parameters:
|
||||
@ -278,21 +309,29 @@ server.connect(transport);
|
||||
|
||||
### Navigation
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_navigate**
|
||||
- Description: Navigate to a URL
|
||||
- Parameters:
|
||||
- `url` (string): The URL to navigate to
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_navigate_back**
|
||||
- Description: Go back to the previous page
|
||||
- Parameters: None
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_navigate_forward**
|
||||
- Description: Go forward to the next page
|
||||
- Parameters: None
|
||||
|
||||
### Keyboard
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_press_key**
|
||||
- Description: Press a key on the keyboard
|
||||
- Parameters:
|
||||
@ -300,44 +339,62 @@ server.connect(transport);
|
||||
|
||||
### Console
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_console_messages**
|
||||
- Description: Returns all console messages
|
||||
- Parameters: None
|
||||
|
||||
### Files and Media
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_file_upload**
|
||||
- Description: Choose one or multiple files to upload
|
||||
- Description: Upload one or multiple files
|
||||
- Parameters:
|
||||
- `paths` (array): The absolute paths to the files to upload. Can be a single file or multiple files.
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_pdf_save**
|
||||
- Description: Save page as PDF
|
||||
- Parameters: None
|
||||
|
||||
### Utilities
|
||||
|
||||
- **browser_wait**
|
||||
- Description: Wait for a specified time in seconds
|
||||
- Parameters:
|
||||
- `time` (number): The time to wait in seconds (capped at 10 seconds)
|
||||
|
||||
- **browser_resize**
|
||||
- Description: Resize the browser window
|
||||
- Parameters:
|
||||
- `width` (number): The desired width of the browser window
|
||||
- `height` (number): The desired height of the browser window
|
||||
|
||||
- **browser_handle_dialog**
|
||||
- Description: Handle browser dialogs (alert, confirm, prompt)
|
||||
- Parameters:
|
||||
- `accept` (boolean): Whether to accept or dismiss the dialog
|
||||
- `promptText` (string, optional): Text to enter in case of prompt dialogs
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_close**
|
||||
- Description: Close the page
|
||||
- Parameters: None
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_wait**
|
||||
- Description: Wait for a specified time in seconds
|
||||
- Parameters:
|
||||
- `time` (number): The time to wait in seconds
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_resize**
|
||||
- Description: Resize the browser window
|
||||
- Parameters:
|
||||
- `width` (number): Width of the browser window
|
||||
- `height` (number): Height of the browser window
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_install**
|
||||
- Description: Install the browser specified in the config. Call this if you get an error about the browser not being installed.
|
||||
- Parameters: None
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_handle_dialog**
|
||||
- Description: Handle a dialog
|
||||
- Parameters:
|
||||
- `accept` (boolean): Whether to accept the dialog.
|
||||
- `promptText` (string, optional): The text of the prompt in case of a prompt dialog.
|
||||
|
||||
<!--- End of generated section -->
|
||||
|
@ -17,6 +17,7 @@
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"lint": "eslint .",
|
||||
"update-readme": "node utils/update-readme.js",
|
||||
"watch": "tsc --watch",
|
||||
"test": "playwright test",
|
||||
"ctest": "playwright test --project=chrome",
|
||||
|
178
utils/update-readme.js
Normal file
178
utils/update-readme.js
Normal file
@ -0,0 +1,178 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// @ts-check
|
||||
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const commonTools = require('../lib/tools/common').default;
|
||||
const consoleTools = require('../lib/tools/console').default;
|
||||
const dialogsTools = require('../lib/tools/dialogs').default;
|
||||
const filesTools = require('../lib/tools/files').default;
|
||||
const installTools = require('../lib/tools/install').default;
|
||||
const keyboardTools = require('../lib/tools/keyboard').default;
|
||||
const navigateTools = require('../lib/tools/navigate').default;
|
||||
const pdfTools = require('../lib/tools/pdf').default;
|
||||
const snapshotTools = require('../lib/tools/snapshot').default;
|
||||
const tabsTools = require('../lib/tools/tabs').default;
|
||||
const screenTools = require('../lib/tools/screen').default;
|
||||
|
||||
// Category definitions for tools
|
||||
const categories = {
|
||||
'Snapshot-based Interactions': [
|
||||
...snapshotTools,
|
||||
],
|
||||
'Vision-based Interactions': [
|
||||
...screenTools
|
||||
],
|
||||
'Tab Management': [
|
||||
...tabsTools(true),
|
||||
],
|
||||
'Navigation': [
|
||||
...navigateTools(true),
|
||||
],
|
||||
'Keyboard': [
|
||||
...keyboardTools(true)
|
||||
],
|
||||
'Console': [
|
||||
...consoleTools
|
||||
],
|
||||
'Files and Media': [
|
||||
...filesTools(true),
|
||||
...pdfTools
|
||||
],
|
||||
'Utilities': [
|
||||
...commonTools(true),
|
||||
...installTools,
|
||||
...dialogsTools(true),
|
||||
],
|
||||
};
|
||||
|
||||
const kStartMarker = `<!--- Generated by ${path.basename(__filename)} -->`;
|
||||
const kEndMarker = `<!--- End of generated section -->`;
|
||||
|
||||
/**
|
||||
* @param {ParsedToolSchema} tool
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatToolForReadme(tool) {
|
||||
const lines = /** @type {string[]} */ ([]);
|
||||
lines.push(`<!-- NOTE: This has been generated via ${path.basename(__filename)} -->\n\n`);
|
||||
lines.push(`- **${tool.name}**\n`);
|
||||
lines.push(` - Description: ${tool.description}\n`);
|
||||
|
||||
if (tool.parameters && tool.parameters.length > 0) {
|
||||
lines.push(` - Parameters:\n`);
|
||||
tool.parameters.forEach(param => {
|
||||
const meta = /** @type {string[]} */ ([]);
|
||||
if (param.type)
|
||||
meta.push(param.type);
|
||||
if (param.optional)
|
||||
meta.push('optional');
|
||||
lines.push(` - \`${param.name}\` ${meta.length ? `(${meta.join(', ')})` : ''}: ${param.description}\n`);
|
||||
});
|
||||
} else {
|
||||
lines.push(` - Parameters: None\n`);
|
||||
}
|
||||
|
||||
lines.push('\n');
|
||||
return lines.join('');
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* name: any;
|
||||
* description: any;
|
||||
* parameters: {
|
||||
* name: string;
|
||||
* description: string;
|
||||
* optional: boolean;
|
||||
* type: string;
|
||||
* }[];
|
||||
*}} ParsedToolSchema
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {import('../src/tools/tool').ToolSchema} schema
|
||||
* @returns {ParsedToolSchema}
|
||||
*/
|
||||
function processToolSchema(schema) {
|
||||
const inputSchema = /** @type {import('zod-to-json-schema').JsonSchema7ObjectType} */ (schema.inputSchema || {});
|
||||
if (inputSchema.type !== 'object')
|
||||
throw new Error(`Tool ${schema.name} input schema is not an object`);
|
||||
|
||||
// In JSON Schema, properties are considered optional unless listed in the required array
|
||||
const requiredParams = inputSchema?.required || [];
|
||||
|
||||
const parameters = Object.entries(inputSchema.properties).map(([name, prop]) => {
|
||||
return {
|
||||
name,
|
||||
description: prop.description || '',
|
||||
optional: !requiredParams.includes(name),
|
||||
type: /** @type {any} */ (prop).type,
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
name: schema.name,
|
||||
description: schema.description,
|
||||
parameters
|
||||
};
|
||||
}
|
||||
|
||||
async function updateReadme() {
|
||||
console.log('Loading tool information from compiled modules...');
|
||||
|
||||
// Count the tools processed
|
||||
const totalTools = Object.values(categories).flat().length;
|
||||
console.log(`Found ${totalTools} tools`);
|
||||
|
||||
const generatedLines = /** @type {string[]} */ ([]);
|
||||
|
||||
for (const [category, categoryTools] of Object.entries(categories)) {
|
||||
generatedLines.push(`### ${category}\n\n`);
|
||||
for (const tool of categoryTools) {
|
||||
const scheme = processToolSchema(tool.schema);
|
||||
generatedLines.push(formatToolForReadme(scheme));
|
||||
}
|
||||
}
|
||||
|
||||
const readmePath = path.join(__dirname, '..', 'README.md');
|
||||
const readmeContent = await fs.promises.readFile(readmePath, 'utf-8');
|
||||
const startMarker = readmeContent.indexOf(kStartMarker);
|
||||
const endMarker = readmeContent.indexOf(kEndMarker);
|
||||
if (startMarker === -1 || endMarker === -1)
|
||||
throw new Error('Markers for generated section not found in README');
|
||||
|
||||
const newReadmeContent = [
|
||||
readmeContent.slice(0, startMarker),
|
||||
kStartMarker + '\n\n',
|
||||
generatedLines.join(''),
|
||||
kEndMarker,
|
||||
readmeContent.slice(endMarker + kEndMarker.length),
|
||||
].join('');
|
||||
|
||||
// Write updated README
|
||||
await fs.promises.writeFile(readmePath, newReadmeContent, 'utf-8');
|
||||
console.log('README updated successfully');
|
||||
}
|
||||
|
||||
// Run the update
|
||||
updateReadme().catch(err => {
|
||||
console.error('Error updating README:', err);
|
||||
process.exit(1);
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user