got it to work

This commit is contained in:
Tommy D. Rossi
2025-11-13 21:12:31 +01:00
parent ddde04fe63
commit 8e98c68de4
18 changed files with 328 additions and 516 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 776 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

+13 -7
View File
@@ -1,8 +1,8 @@
{ {
"manifest_version": 3, "manifest_version": 3,
"name": "Playwright MCP Bridge", "name": "Playwriter",
"version": "0.0.47", "version": "0.0.47",
"description": "Click to attach debugger to current tab", "description": "Playwriter MCP",
"permissions": [ "permissions": [
"debugger", "debugger",
"activeTab", "activeTab",
@@ -16,12 +16,18 @@
"type": "module" "type": "module"
}, },
"action": { "action": {
"default_title": "Click to attach debugger" "default_title": "Click to attach debugger",
"default_icon": {
"16": "icons/icon-gray-16.png",
"32": "icons/icon-gray-32.png",
"48": "icons/icon-gray-48.png",
"128": "icons/icon-gray-128.png"
}
}, },
"icons": { "icons": {
"16": "icons/icon-16.png", "16": "icons/icon-gray-16.png",
"32": "icons/icon-32.png", "32": "icons/icon-gray-32.png",
"48": "icons/icon-48.png", "48": "icons/icon-gray-48.png",
"128": "icons/icon-128.png" "128": "icons/icon-gray-128.png"
} }
} }
+29 -28
View File
@@ -1,30 +1,31 @@
{ {
"name": "@playwright/mcp-extension", "name": "@playwright/mcp-extension",
"version": "0.0.46", "version": "0.0.46",
"description": "Playwright MCP Browser Extension", "description": "Playwright MCP Browser Extension",
"private": true, "private": true,
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/microsoft/playwright-mcp.git" "url": "git+https://github.com/microsoft/playwright-mcp.git"
}, },
"homepage": "https://playwright.dev", "homepage": "https://playwright.dev",
"engines": { "engines": {
"node": ">=18" "node": ">=18"
}, },
"author": { "author": {
"name": "Microsoft Corporation" "name": "Microsoft Corporation"
}, },
"license": "Apache-2.0", "license": "Apache-2.0",
"scripts": { "scripts": {
"build": "tsc --project . && vite build --config vite.sw.config.mts", "build": "tsc --project . && vite build --config vite.sw.config.mts",
"watch": "tsc --watch --project . & vite build --watch --config vite.sw.config.mts", "watch": "concurrently \"tsc --watch --project .\" \"vite build --watch --config vite.sw.config.mts\"",
"test": "playwright test", "test": "playwright test",
"clean": "rm -rf dist" "clean": "rm -rf dist"
}, },
"devDependencies": { "devDependencies": {
"@types/chrome": "^0.0.315", "@types/chrome": "^0.0.315",
"typescript": "^5.8.2", "typescript": "^5.8.2",
"vite": "^5.4.21", "concurrently": "^8.2.2",
"vite-plugin-static-copy": "^3.1.1" "vite": "^5.4.21",
} "vite-plugin-static-copy": "^3.1.1"
}
} }
+29 -3
View File
@@ -17,7 +17,7 @@
import { RelayConnection, debugLog } from './relayConnection'; import { RelayConnection, debugLog } from './relayConnection';
// Relay URL - fixed port for MCP bridge // Relay URL - fixed port for MCP bridge
const RELAY_URL = 'ws://localhost:9988'; const RELAY_URL = 'ws://localhost:9988/extension/550e8400-e29b-41d4-a716-446655440000';
class SimplifiedExtension { class SimplifiedExtension {
private _connection: RelayConnection | undefined; private _connection: RelayConnection | undefined;
@@ -133,12 +133,29 @@ class SimplifiedExtension {
try { try {
switch (state) { switch (state) {
case 'connected': case 'connected':
await chrome.action.setBadgeText({ tabId, text: '✓' }); await chrome.action.setIcon({
await chrome.action.setBadgeBackgroundColor({ tabId, color: '#4CAF50' }); tabId,
path: {
'16': '/icons/icon-green-16.png',
'32': '/icons/icon-green-32.png',
'48': '/icons/icon-green-48.png',
'128': '/icons/icon-green-128.png'
}
});
await chrome.action.setBadgeText({ tabId, text: '' });
await chrome.action.setTitle({ tabId, title: 'Connected - Click to disconnect' }); await chrome.action.setTitle({ tabId, title: 'Connected - Click to disconnect' });
break; break;
case 'connecting': case 'connecting':
await chrome.action.setIcon({
tabId,
path: {
'16': '/icons/icon-gray-16.png',
'32': '/icons/icon-gray-32.png',
'48': '/icons/icon-gray-48.png',
'128': '/icons/icon-gray-128.png'
}
});
await chrome.action.setBadgeText({ tabId, text: '...' }); await chrome.action.setBadgeText({ tabId, text: '...' });
await chrome.action.setBadgeBackgroundColor({ tabId, color: '#FF9800' }); await chrome.action.setBadgeBackgroundColor({ tabId, color: '#FF9800' });
await chrome.action.setTitle({ tabId, title: 'Connecting...' }); await chrome.action.setTitle({ tabId, title: 'Connecting...' });
@@ -146,6 +163,15 @@ class SimplifiedExtension {
case 'disconnected': case 'disconnected':
default: default:
await chrome.action.setIcon({
tabId,
path: {
'16': '/icons/icon-gray-16.png',
'32': '/icons/icon-gray-32.png',
'48': '/icons/icon-gray-48.png',
'128': '/icons/icon-gray-128.png'
}
});
await chrome.action.setBadgeText({ tabId, text: '' }); await chrome.action.setBadgeText({ tabId, text: '' });
await chrome.action.setTitle({ tabId, title: 'Click to attach debugger' }); await chrome.action.setTitle({ tabId, title: 'Click to attach debugger' });
break; break;
+6 -17
View File
@@ -14,28 +14,17 @@
* limitations under the License. * limitations under the License.
*/ */
import { resolve } from 'path'; import { fileURLToPath } from 'url';
import { dirname, resolve } from 'path';
import { defineConfig } from 'vite'; import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react'; import react from '@vitejs/plugin-react';
import { viteStaticCopy } from 'vite-plugin-static-copy';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [react()],
react(),
viteStaticCopy({
targets: [
{
src: '../../icons/*',
dest: 'icons'
},
{
src: '../../manifest.json',
dest: '.'
}
]
})
],
root: resolve(__dirname, 'src/ui'), root: resolve(__dirname, 'src/ui'),
build: { build: {
outDir: resolve(__dirname, 'dist/'), outDir: resolve(__dirname, 'dist/'),
+20 -1
View File
@@ -14,10 +14,29 @@
* limitations under the License. * limitations under the License.
*/ */
import { resolve } from 'path'; import { fileURLToPath } from 'url';
import { dirname, resolve } from 'path';
import { defineConfig } from 'vite'; import { defineConfig } from 'vite';
import { viteStaticCopy } from 'vite-plugin-static-copy';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
export default defineConfig({ export default defineConfig({
plugins: [
viteStaticCopy({
targets: [
{
src: resolve(__dirname, 'icons/*'),
dest: 'icons'
},
{
src: resolve(__dirname, 'manifest.json'),
dest: '.'
}
]
})
],
build: { build: {
lib: { lib: {
entry: resolve(__dirname, 'src/background.ts'), entry: resolve(__dirname, 'src/background.ts'),
+31
View File
@@ -0,0 +1,31 @@
import playwright from 'playwright-core';
async function main() {
const uuid = process.env.CDP_UUID || '550e8400-e29b-41d4-a716-446655440000';
const cdpEndpoint = `ws://localhost:9988/cdp/${uuid}`
const browser = await playwright.chromium.connectOverCDP(cdpEndpoint);
const contexts = browser.contexts();
console.log(`Found ${contexts.length} browser context(s)`);
for (const context of contexts) {
const pages = context.pages();
console.log(`Context has ${pages.length} page(s):`);
for (const page of pages) {
const url = page.url();
console.log(`\nPage URL: ${url}`);
const html = await page.content();
const lines = html.split('\n').slice(0, 3);
console.log('First 3 lines of HTML:');
lines.forEach((line, i) => {
console.log(` ${i + 1}: ${line}`);
});
}
}
await browser.close();
}
main()
+2 -2
View File
@@ -5,6 +5,6 @@ async function main() {
const { browserContext, close } = await createExtensionContext( const { browserContext, close } = await createExtensionContext(
controller.signal, controller.signal,
) )
} }
main()
+4 -2
View File
@@ -75,7 +75,7 @@ export class CDPRelayServer {
this._wsHost = httpAddressToString(server.address()).replace(/^http/, 'ws'); this._wsHost = httpAddressToString(server.address()).replace(/^http/, 'ws');
const uuid = crypto.randomUUID(); const uuid = process.env.CDP_UUID || crypto.randomUUID();
this._cdpPath = `/cdp/${uuid}`; this._cdpPath = `/cdp/${uuid}`;
this._extensionPath = `/extension/${uuid}`; this._extensionPath = `/extension/${uuid}`;
@@ -227,7 +227,9 @@ export class CDPRelayServer {
if (sessionId) if (sessionId)
break; break;
// Simulate auto-attach behavior with real target info // Simulate auto-attach behavior with real target info
const { targetInfo } = await this._extensionConnection!.send('attachToTab', { }); if (!this._extensionConnection)
throw new Error('Extension not connected. Please ensure the Chrome extension is installed and connected to the extension endpoint before connecting Playwright.');
const { targetInfo } = await this._extensionConnection.send('attachToTab', { });
this._connectedTabInfo = { this._connectedTabInfo = {
targetInfo, targetInfo,
sessionId: `pw-tab-${this._nextSessionId++}`, sessionId: `pw-tab-${this._nextSessionId++}`,
@@ -40,6 +40,8 @@ export async function createExtensionContext(abortSignal: AbortSignal, ): Promis
// TODO simply call fetch. it was creatign a full fledged browser just to fetch an url previously. CRAZY // TODO simply call fetch. it was creatign a full fledged browser just to fetch an url previously. CRAZY
// await cdpRelayServer.ensureExtensionConnectionForMCPContext(clientInfo, abortSignal, toolName); // await cdpRelayServer.ensureExtensionConnectionForMCPContext(clientInfo, abortSignal, toolName);
// await waitForExtension()
return {}
const browser = await playwright.chromium.connectOverCDP(cdpRelayServer.cdpEndpoint()); const browser = await playwright.chromium.connectOverCDP(cdpRelayServer.cdpEndpoint());
return { return {
+183 -447
View File
File diff suppressed because it is too large Load Diff