Add stable extension ID for development builds
Inject manifest key via vite plugin for dev/test builds (not production). This ensures all developers get the same extension ID: pebbngnfojnignonigcnkdilknapkgid - Update vite.config.mts to inject key when !PRODUCTION - Update release script to use PRODUCTION=true - Replace old hardcoded dev extension ID in all files
This commit is contained in:
@@ -79,7 +79,7 @@ also bump package.json versions and IMPORTANT also the extension/manifest.json v
|
||||
|
||||
## debugging playwriter mcp issues
|
||||
|
||||
sometimes the user will ask you to debug an mcp issue. to do this you may want to add logs to the mcp and server. to do this you will also need to restart the server so we use the latest code. restarting the mcp yourself is not possible. instead you will need to ask the user to do it or write a test case, where the mcp can be reloaded. also making changes in the extension will not work. you will have to write a test case for that to work. you can ask the user to reconnect these too. for reloading the extension you can run the `pnpm build` script and do `osascript -e 'tell application "Google Chrome" to open location "chrome://extensions/?id=elnnakgjclnapgflmidlpobefkdmapdm"'` to make it easier for the user to reload it
|
||||
sometimes the user will ask you to debug an mcp issue. to do this you may want to add logs to the mcp and server. to do this you will also need to restart the server so we use the latest code. restarting the mcp yourself is not possible. instead you will need to ask the user to do it or write a test case, where the mcp can be reloaded. also making changes in the extension will not work. you will have to write a test case for that to work. you can ask the user to reconnect these too. for reloading the extension you can run the `pnpm build` script and do `osascript -e 'tell application "Google Chrome" to open location "chrome://extensions/?id=pebbngnfojnignonigcnkdilknapkgid"'` to make it easier for the user to reload it
|
||||
|
||||
if the problem was in the ws server you can restart that yourself killing process listening on 19988 and sending a new mcp call.
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ also bump package.json versions and IMPORTANT also the extension/manifest.json v
|
||||
|
||||
## debugging playwriter mcp issues
|
||||
|
||||
sometimes the user will ask you to debug an mcp issue. to do this you may want to add logs to the mcp and server. to do this you will also need to restart the server so we use the latest code. restarting the mcp yourself is not possible. instead you will need to ask the user to do it or write a test case, where the mcp can be reloaded. also making changes in the extension will not work. you will have to write a test case for that to work. you can ask the user to reconnect these too. for reloading the extension you can run the `pnpm build` script and do `osascript -e 'tell application "Google Chrome" to open location "chrome://extensions/?id=elnnakgjclnapgflmidlpobefkdmapdm"'` to make it easier for the user to reload it
|
||||
sometimes the user will ask you to debug an mcp issue. to do this you may want to add logs to the mcp and server. to do this you will also need to restart the server so we use the latest code. restarting the mcp yourself is not possible. instead you will need to ask the user to do it or write a test case, where the mcp can be reloaded. also making changes in the extension will not work. you will have to write a test case for that to work. you can ask the user to reconnect these too. for reloading the extension you can run the `pnpm build` script and do `osascript -e 'tell application "Google Chrome" to open location "chrome://extensions/?id=pebbngnfojnignonigcnkdilknapkgid"'` to make it easier for the user to reload it
|
||||
|
||||
if the problem was in the ws server you can restart that yourself killing process listening on 19988 and sending a new mcp call.
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"build": "tsc --project . && vite build --config vite.config.mts",
|
||||
"reload": "bun run build && osascript -e 'tell application \"Google Chrome\" to open location \"chrome://extensions/?id=elnnakgjclnapgflmidlpobefkdmapdm\"'",
|
||||
"reload": "bun run build && osascript -e 'tell application \"Google Chrome\" to open location \"chrome://extensions/?id=pebbngnfojnignonigcnkdilknapkgid\"'",
|
||||
"watch": "vite build --watch --config vite.config.mts",
|
||||
"clean": "rm -rf dist"
|
||||
},
|
||||
|
||||
@@ -961,7 +961,7 @@ async function resetDebugger(): Promise<void> {
|
||||
// Our extension IDs - allow attaching to our own extension pages for debugging
|
||||
const OUR_EXTENSION_IDS = [
|
||||
'jfeammnjpkecdekppnclgkkffahnhfhe', // Production extension (Chrome Web Store)
|
||||
'elnnakgjclnapgflmidlpobefkdmapdm', // Dev extension (loaded unpacked)
|
||||
'pebbngnfojnignonigcnkdilknapkgid', // Dev extension (stable ID from manifest key)
|
||||
]
|
||||
|
||||
// undefined URL is for about:blank pages (not restricted) and chrome:// URLs (restricted).
|
||||
|
||||
@@ -35,6 +35,12 @@ export default defineConfig({
|
||||
}
|
||||
}
|
||||
|
||||
// Inject key for stable extension ID in dev/test builds (not production)
|
||||
// This ensures all developers get the same extension ID: pebbngnfojnignonigcnkdilknapkgid
|
||||
if (!process.env.PRODUCTION) {
|
||||
manifest.key = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwCJoq5UYhOo5x8s50pVBUHjQ8idyUHnZFDj1JspWJPe6kvM7RFIaE/y5WTAH05kuK0R7v/ipcGA4ywA5wKdPKHZzkl5xstlNPj0Ivu4CqLobU7eY5G3k3Gq7wql2pbwb/A8Nat4VLbfBjQLA6TGWd3LQOHS6M0B3AvrtEw7DLDUdGKh4SCLewCbdlDIzpXQwKOzrRPyLFBwj9eEeITy5aNwJ9r9JMNBvACVZiRCHsGI6DufU+OiIO232l/8OoNNt6kdTMyNgiqOogFApXPJwREUwZHGqjXD3s6bXiBIQtwkNyZfemHKkxj6g/fhCV2EMgTY6+ikQEY1gEJMrRVmcYQIDAQAB';
|
||||
}
|
||||
|
||||
return JSON.stringify(manifest, null, 2);
|
||||
}
|
||||
},
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
"cli": "pnpm --filter playwriter cli",
|
||||
"reload": "pnpm --filter playwriter build && pnpm --filter mcp-extension reload",
|
||||
"agents.md": "agentsdotmd ./PLAYWRITER_AGENTS.md core.md typescript.md pnpm.md vitest.md changelog.md docs-writing.md github.md playwright.md zod.md gitchamber.md",
|
||||
"release": "pnpm --filter playwriter build && rm -f extension.zip && cd extension && zip -r ../extension.zip dist && cd .. && realpath extension.zip | pbcopy && open 'https://chrome.google.com/webstore/devconsole/a379d569-9533-44e4-9749-0368f6dbf878/jfeammnjpkecdekppnclgkkffahnhfhe/edit/package'"
|
||||
"release": "pnpm --filter playwriter build && cd extension && PRODUCTION=true pnpm build && cd .. && rm -f extension.zip && cd extension && zip -r ../extension.zip dist && cd .. && realpath extension.zip | pbcopy && open 'https://chrome.google.com/webstore/devconsole/a379d569-9533-44e4-9749-0368f6dbf878/jfeammnjpkecdekppnclgkkffahnhfhe/edit/package'"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@changesets/cli": "^2.29.7",
|
||||
|
||||
@@ -20,7 +20,7 @@ type ConnectedTarget = {
|
||||
// Our extension IDs - allow attaching to our own extension pages for debugging
|
||||
const OUR_EXTENSION_IDS = [
|
||||
'jfeammnjpkecdekppnclgkkffahnhfhe', // Production extension (Chrome Web Store)
|
||||
'elnnakgjclnapgflmidlpobefkdmapdm', // Dev extension (loaded unpacked)
|
||||
'pebbngnfojnignonigcnkdilknapkgid', // Dev extension (stable ID from manifest key)
|
||||
]
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# playwriter execute
|
||||
# playwriter best practices
|
||||
|
||||
Control user's Chrome browser via playwright code snippets. Prefer single-line code with semicolons between statements. If you get "extension is not connected" or "no browser tabs have Playwriter enabled" error, tell user to click the playwriter extension icon on the tab they want to control.
|
||||
|
||||
@@ -139,7 +139,7 @@ await state.myPage.goto('https://example.com');
|
||||
|
||||
**Find a page the user opened:**
|
||||
|
||||
Sometimes the user enables playwriter on a specific tab they want you to control (e.g., they're logged into an app). Find it by URL pattern:
|
||||
Sometimes the user enables playwriter extension on a specific tab they want you to control (e.g., they're logged into an app). Find it by URL pattern:
|
||||
|
||||
```js
|
||||
const pages = context.pages().filter(x => x.url().includes('myapp.com'));
|
||||
@@ -265,14 +265,14 @@ const source = await getReactSource({ locator: page.locator('aria-ref=e5') });
|
||||
// => { fileName, lineNumber, columnNumber, componentName }
|
||||
```
|
||||
|
||||
**getStylesForLocator** - inspect CSS styles applied to an element, like browser DevTools "Styles" panel. Useful for debugging styling issues, finding where a CSS property is defined (file:line), and checking inherited styles. Returns selector, source location, and declarations for each matching rule. ALWAYS read `https://playwriter.dev/resources/styles-api.md` first.
|
||||
**getStylesForLocator** - inspect CSS styles applied to an element, like browser DevTools "Styles" panel. Useful for debugging styling issues, finding where a CSS property is defined (file:line), and checking inherited styles. Returns selector, source location, and declarations for each matching rule. ALWAYS fetch `https://playwriter.dev/resources/styles-api.md` first with curl or webfetch tool.
|
||||
|
||||
```js
|
||||
const styles = await getStylesForLocator({ locator: page.locator('.btn'), cdp: await getCDPSession({ page }) });
|
||||
console.log(formatStylesAsText(styles));
|
||||
```
|
||||
|
||||
**createDebugger** - set breakpoints, step through code, inspect variables at runtime. Useful for debugging issues that only reproduce in browser, understanding code flow, and inspecting state at specific points. Can pause on exceptions, evaluate expressions in scope, and blackbox framework code. ALWAYS read `https://playwriter.dev/resources/debugger-api.md` first.
|
||||
**createDebugger** - set breakpoints, step through code, inspect variables at runtime. Useful for debugging issues that only reproduce in browser, understanding code flow, and inspecting state at specific points. Can pause on exceptions, evaluate expressions in scope, and blackbox framework code. ALWAYS fetch `https://playwriter.dev/resources/debugger-api.md` first.
|
||||
|
||||
```js
|
||||
const cdp = await getCDPSession({ page }); const dbg = createDebugger({ cdp }); await dbg.enable();
|
||||
@@ -325,6 +325,8 @@ Always use `scale: 'css'` to avoid 2-4x larger images on high-DPI displays:
|
||||
await page.screenshot({ path: 'shot.png', scale: 'css' });
|
||||
```
|
||||
|
||||
If you want to read back the image file into context make sure to resize it first, scaling down the image to make sure max size is 1500px. for example with `sips --resampleHeightWidthMax 1500 input.png --out output.png` on macOS.
|
||||
|
||||
## page.evaluate
|
||||
|
||||
Code inside `page.evaluate()` runs in the browser - use plain JavaScript only, no TypeScript syntax. Return values and log outside (console.log inside evaluate runs in browser, not visible):
|
||||
@@ -421,4 +423,13 @@ Examples of what playwriter can do:
|
||||
|
||||
## debugging playwriter issues
|
||||
|
||||
if some internal critical error happens you can read your own relay ws logs to understand the issue, it will show logs from extension, mcp and ws server together. then you can create a gh issue using `gh issue create -R remorses/playwriter --title title --body body`. ask for user confirmation before doing this.
|
||||
if some internal critical error happens you can read the relay server logs to understand the issue. the log file is located in the system temp directory:
|
||||
|
||||
```bash
|
||||
playwriter logfile # prints the log file path
|
||||
# typically: /tmp/playwriter/relay-server.log (Linux/macOS) or %TEMP%\playwriter\relay-server.log (Windows)
|
||||
```
|
||||
|
||||
the log file contains logs from the extension, MCP and WS server together with all CDP events. the file is recreated every time the server starts. for debugging internal playwriter errors, read this file with grep/rg to find relevant lines.
|
||||
|
||||
if you find a bug, you can create a gh issue using `gh issue create -R remorses/playwriter --title title --body body`. ask for user confirmation before doing this.
|
||||
|
||||
Reference in New Issue
Block a user