diff --git a/cli.js b/cli.js index bbda09e..95d4dbd 100755 --- a/cli.js +++ b/cli.js @@ -15,4 +15,4 @@ * limitations under the License. */ -import './lib/program.js'; +require('./lib/program'); diff --git a/eslint.config.mjs b/eslint.config.js similarity index 88% rename from eslint.config.mjs rename to eslint.config.js index 3ff35a9..c4b8a02 100644 --- a/eslint.config.mjs +++ b/eslint.config.js @@ -14,16 +14,12 @@ * limitations under the License. */ -import typescriptEslint from "@typescript-eslint/eslint-plugin"; -import tsParser from "@typescript-eslint/parser"; -import notice from "eslint-plugin-notice"; -import path from "path"; -import { fileURLToPath } from "url"; -import stylistic from "@stylistic/eslint-plugin"; -import importRules from "eslint-plugin-import"; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); +const typescriptEslint = require("@typescript-eslint/eslint-plugin"); +const tsParser = require("@typescript-eslint/parser"); +const notice = require("eslint-plugin-notice"); +const path = require("path"); +const stylistic = require("@stylistic/eslint-plugin"); +const importRules = require("eslint-plugin-import"); const plugins = { "@stylistic": stylistic, @@ -32,8 +28,7 @@ const plugins = { import: importRules, }; -export const baseRules = { - "import/extensions": ["error", "ignorePackages", {ts: "always"}], +const baseRules = { "@typescript-eslint/no-floating-promises": "error", "@typescript-eslint/no-unused-vars": [ 2, @@ -188,7 +183,7 @@ const languageOptions = { ecmaVersion: 9, sourceType: "module", parserOptions: { - project: path.join(fileURLToPath(import.meta.url), "..", "tsconfig.all.json"), + project: path.join(__filename, "..", "tsconfig.all.json"), } }; @@ -217,7 +212,7 @@ const noBooleanCompareRules = { "@typescript-eslint/no-unnecessary-boolean-literal-compare": 2, }; -export default [ +module.exports = [ { ignores: ["**/*.js"], }, diff --git a/extension/manifest.json b/extension/manifest.json index b9365bc..ffc9e9d 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -14,7 +14,7 @@ "" ], "background": { - "service_worker": "lib/background.js", + "service_worker": "lib/background.mjs", "type": "module" }, "action": { diff --git a/extension/package.json b/extension/package.json index 2d0e12c..89b75eb 100644 --- a/extension/package.json +++ b/extension/package.json @@ -2,7 +2,6 @@ "name": "@playwright/mcp-extension", "version": "0.0.36", "description": "Playwright MCP Browser Extension", - "type": "module", "private": true, "repository": { "type": "git", @@ -17,8 +16,8 @@ }, "license": "Apache-2.0", "scripts": { - "build": "tsc --project . && tsc --project tsconfig.ui.json && vite build", - "watch": "tsc --watch --project . & tsc --watch --project tsconfig.ui.json & vite build --watch", + "build": "tsc --project . && tsc --project tsconfig.ui.json && vite build && vite build --config vite.sw.config.mts", + "watch": "tsc --watch --project . & tsc --watch --project tsconfig.ui.json & vite build --watch & vite build --watch --config vite.sw.config.mts", "test": "playwright test", "clean": "rm -rf dist" }, diff --git a/extension/src/background.ts b/extension/src/background.ts index e71e0df..e74ebb8 100644 --- a/extension/src/background.ts +++ b/extension/src/background.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { RelayConnection, debugLog } from './relayConnection.js'; +import { RelayConnection, debugLog } from './relayConnection'; type PageMessage = { type: 'connectToMCPRelay'; diff --git a/extension/tests/extension.spec.ts b/extension/tests/extension.spec.ts index 60cc4fb..0c69927 100644 --- a/extension/tests/extension.spec.ts +++ b/extension/tests/extension.spec.ts @@ -16,7 +16,6 @@ import fs from 'fs'; import path from 'path'; -import { fileURLToPath } from 'url'; import { chromium } from 'playwright'; import { test as base, expect } from '../../tests/fixtures.js'; @@ -38,7 +37,7 @@ type TestFixtures = { const test = base.extend({ pathToExtension: async ({}, use) => { - await use(fileURLToPath(new URL('../dist', import.meta.url))); + await use(path.resolve(__dirname, '../dist')); }, browserWithExtension: async ({ mcpBrowser, pathToExtension }, use, testInfo) => { @@ -126,7 +125,7 @@ async function startWithExtensionFlag(browserWithExtension: BrowserWithExtension const testWithOldExtensionVersion = test.extend({ pathToExtension: async ({}, use, testInfo) => { const extensionDir = testInfo.outputPath('extension'); - const oldPath = fileURLToPath(new URL('../dist', import.meta.url)); + const oldPath = path.resolve(__dirname, '../dist'); await fs.promises.cp(oldPath, extensionDir, { recursive: true }); const manifestPath = path.join(extensionDir, 'manifest.json'); diff --git a/extension/tsconfig.json b/extension/tsconfig.json index 70fb340..9c22b0b 100644 --- a/extension/tsconfig.json +++ b/extension/tsconfig.json @@ -10,7 +10,8 @@ "resolveJsonModule": true, "types": ["chrome"], "jsx": "react-jsx", - "jsxImportSource": "react" + "jsxImportSource": "react", + "noEmit": true }, "include": [ "src", diff --git a/extension/vite.config.ts b/extension/vite.config.mts similarity index 100% rename from extension/vite.config.ts rename to extension/vite.config.mts diff --git a/extension/vite.sw.config.mts b/extension/vite.sw.config.mts new file mode 100644 index 0000000..a383e4b --- /dev/null +++ b/extension/vite.sw.config.mts @@ -0,0 +1,31 @@ +/** + * 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. + */ + +import { resolve } from 'path'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + build: { + lib: { + entry: resolve(__dirname, 'src/background.ts'), + fileName: 'lib/background', + formats: ['es'] + }, + outDir: 'dist', + emptyOutDir: false, + minify: false + } +}); diff --git a/index.d.ts b/index.d.ts index f7a1dde..4a2b679 100644 --- a/index.d.ts +++ b/index.d.ts @@ -16,7 +16,7 @@ */ import type { Server } from '@modelcontextprotocol/sdk/server/index.js'; -import type { Config } from './config.js'; +import type { Config } from './config'; import type { BrowserContext } from 'playwright'; export declare function createConnection(config?: Config, contextGetter?: () => Promise): Promise; diff --git a/index.js b/index.js index 69f7ae2..b153a9f 100755 --- a/index.js +++ b/index.js @@ -15,5 +15,5 @@ * limitations under the License. */ -import { createConnection } from './lib/index.js'; -export { createConnection }; +const { createConnection } = require('./lib/index.js'); +module.exports = { createConnection }; diff --git a/package.json b/package.json index b3f739d..2ff240d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,6 @@ "name": "@playwright/mcp", "version": "0.0.36", "description": "Playwright Tools for MCP", - "type": "module", "repository": { "type": "git", "url": "git+https://github.com/microsoft/playwright-mcp.git" diff --git a/playwright.config.ts b/playwright.config.ts index 8486de1..c69e8f0 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -16,7 +16,7 @@ import { defineConfig } from '@playwright/test'; -import type { TestOptions } from './tests/fixtures.js'; +import type { TestOptions } from './tests/fixtures'; export default defineConfig({ testDir: './tests', diff --git a/src/browserContextFactory.ts b/src/browserContextFactory.ts index 81072e1..a0f8e92 100644 --- a/src/browserContextFactory.ts +++ b/src/browserContextFactory.ts @@ -23,11 +23,11 @@ import * as playwright from 'playwright'; import { registryDirectory } from 'playwright-core/lib/server/registry/index'; // @ts-ignore import { startTraceViewerServer } from 'playwright-core/lib/server'; -import { logUnhandledError, testDebug } from './utils/log.js'; -import { createHash } from './utils/guid.js'; -import { outputFile } from './config.js'; +import { logUnhandledError, testDebug } from './utils/log'; +import { createHash } from './utils/guid'; +import { outputFile } from './config'; -import type { FullConfig } from './config.js'; +import type { FullConfig } from './config'; export function contextFactory(config: FullConfig): BrowserContextFactory { if (config.browser.remoteEndpoint) diff --git a/src/browserServerBackend.ts b/src/browserServerBackend.ts index 10f5ff4..137fcb8 100644 --- a/src/browserServerBackend.ts +++ b/src/browserServerBackend.ts @@ -15,18 +15,18 @@ */ import { fileURLToPath } from 'url'; -import { FullConfig } from './config.js'; -import { Context } from './context.js'; -import { logUnhandledError } from './utils/log.js'; -import { Response } from './response.js'; -import { SessionLog } from './sessionLog.js'; -import { filteredTools } from './tools.js'; -import { toMcpTool } from './mcp/tool.js'; +import { FullConfig } from './config'; +import { Context } from './context'; +import { logUnhandledError } from './utils/log'; +import { Response } from './response'; +import { SessionLog } from './sessionLog'; +import { filteredTools } from './tools'; +import { toMcpTool } from './mcp/tool'; -import type { Tool } from './tools/tool.js'; -import type { BrowserContextFactory } from './browserContextFactory.js'; -import type * as mcpServer from './mcp/server.js'; -import type { ServerBackend } from './mcp/server.js'; +import type { Tool } from './tools/tool'; +import type { BrowserContextFactory } from './browserContextFactory'; +import type * as mcpServer from './mcp/server'; +import type { ServerBackend } from './mcp/server'; export class BrowserServerBackend implements ServerBackend { private _tools: Tool[]; diff --git a/src/config.ts b/src/config.ts index e579002..f6b410b 100644 --- a/src/config.ts +++ b/src/config.ts @@ -18,7 +18,7 @@ import fs from 'fs'; import os from 'os'; import path from 'path'; import { devices } from 'playwright'; -import { sanitizeForFilePath } from './utils/fileUtils.js'; +import { sanitizeForFilePath } from './utils/fileUtils'; import type { Config, ToolCapability } from '../config.js'; import type { BrowserContextOptions, LaunchOptions } from 'playwright'; diff --git a/src/context.ts b/src/context.ts index 1890b3d..0a65212 100644 --- a/src/context.ts +++ b/src/context.ts @@ -17,15 +17,15 @@ import debug from 'debug'; import * as playwright from 'playwright'; -import { logUnhandledError } from './utils/log.js'; -import { Tab } from './tab.js'; -import { outputFile } from './config.js'; +import { logUnhandledError } from './utils/log'; +import { Tab } from './tab'; +import { outputFile } from './config'; -import type { FullConfig } from './config.js'; -import type { Tool } from './tools/tool.js'; -import type { BrowserContextFactory, ClientInfo } from './browserContextFactory.js'; -import type * as actions from './actions.js'; -import type { SessionLog } from './sessionLog.js'; +import type { FullConfig } from './config'; +import type { Tool } from './tools/tool'; +import type { BrowserContextFactory, ClientInfo } from './browserContextFactory'; +import type * as actions from './actions'; +import type { SessionLog } from './sessionLog'; const testDebug = debug('pw:mcp:test'); diff --git a/src/extension/cdpRelay.ts b/src/extension/cdpRelay.ts index 79e8290..5602db6 100644 --- a/src/extension/cdpRelay.ts +++ b/src/extension/cdpRelay.ts @@ -26,17 +26,19 @@ import { spawn } from 'child_process'; import http from 'http'; import debug from 'debug'; import { WebSocket, WebSocketServer } from 'ws'; + +// @ts-ignore +import { registry } from 'playwright-core/lib/server/registry/index'; + import { httpAddressToString } from '../mcp/http.js'; import { logUnhandledError } from '../utils/log.js'; import { ManualPromise } from '../mcp/manualPromise.js'; -import * as protocol from './protocol.js'; +import * as protocol from './protocol'; import type websocket from 'ws'; import type { ClientInfo } from '../browserContextFactory.js'; -import type { ExtensionCommand, ExtensionEvents } from './protocol.js'; +import type { ExtensionCommand, ExtensionEvents } from './protocol'; -// @ts-ignore -const { registry } = await import('playwright-core/lib/server/registry/index'); const debugLogger = debug('pw:mcp:relay'); diff --git a/src/extension/extensionContextFactory.ts b/src/extension/extensionContextFactory.ts index bff7726..965e27d 100644 --- a/src/extension/extensionContextFactory.ts +++ b/src/extension/extensionContextFactory.ts @@ -17,7 +17,7 @@ import debug from 'debug'; import * as playwright from 'playwright'; import { startHttpServer } from '../mcp/http.js'; -import { CDPRelayServer } from './cdpRelay.js'; +import { CDPRelayServer } from './cdpRelay'; import type { BrowserContextFactory, ClientInfo } from '../browserContextFactory.js'; diff --git a/src/index.ts b/src/index.ts index 6809cd9..73eeb30 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,15 +14,15 @@ * limitations under the License. */ -import { BrowserServerBackend } from './browserServerBackend.js'; -import { resolveConfig } from './config.js'; -import { contextFactory } from './browserContextFactory.js'; -import * as mcpServer from './mcp/server.js'; -import { packageJSON } from './utils/package.js'; +import { BrowserServerBackend } from './browserServerBackend'; +import { resolveConfig } from './config'; +import { contextFactory } from './browserContextFactory'; +import * as mcpServer from './mcp/server'; +import { packageJSON } from './utils/package'; import type { Config } from '../config.js'; import type { BrowserContext } from 'playwright'; -import type { BrowserContextFactory } from './browserContextFactory.js'; +import type { BrowserContextFactory } from './browserContextFactory'; import type { Server } from '@modelcontextprotocol/sdk/server/index.js'; export async function createConnection(userConfig: Config = {}, contextGetter?: () => Promise): Promise { diff --git a/src/loop/loopClaude.ts b/src/loop/loopClaude.ts index 92dc1d5..b2f915b 100644 --- a/src/loop/loopClaude.ts +++ b/src/loop/loopClaude.ts @@ -15,7 +15,7 @@ */ import type Anthropic from '@anthropic-ai/sdk'; -import type { LLMDelegate, LLMConversation, LLMToolCall, LLMTool } from './loop.js'; +import type { LLMDelegate, LLMConversation, LLMToolCall, LLMTool } from './loop'; import type { Tool } from '@modelcontextprotocol/sdk/types.js'; const model = 'claude-sonnet-4-20250514'; @@ -26,7 +26,7 @@ export class ClaudeDelegate implements LLMDelegate { async anthropic(): Promise { if (!this._anthropic) { const anthropic = await import('@anthropic-ai/sdk'); - this._anthropic = new anthropic.Anthropic(); + this._anthropic = new anthropic.Anthropic() as unknown as Anthropic; } return this._anthropic; } diff --git a/src/loop/loopOpenAI.ts b/src/loop/loopOpenAI.ts index 81e2ef2..24ac46d 100644 --- a/src/loop/loopOpenAI.ts +++ b/src/loop/loopOpenAI.ts @@ -15,7 +15,7 @@ */ import type OpenAI from 'openai'; -import type { LLMDelegate, LLMConversation, LLMToolCall, LLMTool } from './loop.js'; +import type { LLMDelegate, LLMConversation, LLMToolCall, LLMTool } from './loop'; import type { Tool } from '@modelcontextprotocol/sdk/types.js'; const model = 'gpt-4.1'; @@ -26,7 +26,7 @@ export class OpenAIDelegate implements LLMDelegate { async openai(): Promise { if (!this._openai) { const oai = await import('openai'); - this._openai = new oai.OpenAI(); + this._openai = new oai.OpenAI() as unknown as OpenAI; } return this._openai; } diff --git a/src/loop/main.ts b/src/loop/main.ts index d1d7c3e..b43310b 100644 --- a/src/loop/main.ts +++ b/src/loop/main.ts @@ -17,28 +17,25 @@ /* eslint-disable no-console */ import path from 'path'; -import url from 'url'; import dotenv from 'dotenv'; import { program } from 'commander'; import * as mcpBundle from '../mcp/bundle.js'; -import { OpenAIDelegate } from './loopOpenAI.js'; -import { ClaudeDelegate } from './loopClaude.js'; -import { runTask } from './loop.js'; +import { OpenAIDelegate } from './loopOpenAI'; +import { ClaudeDelegate } from './loopClaude'; +import { runTask } from './loop'; -import type { LLMDelegate } from './loop.js'; +import type { LLMDelegate } from './loop'; dotenv.config(); -const __filename = url.fileURLToPath(import.meta.url); - async function run(delegate: LLMDelegate) { const transport = new mcpBundle.StdioClientTransport({ command: 'node', args: [ - path.resolve(__filename, '../../../cli.js'), + path.resolve(__dirname, '../../cli.js'), '--save-session', - '--output-dir', path.resolve(__filename, '../../../sessions') + '--output-dir', path.resolve(__dirname, '../../sessions') ], stderr: 'inherit', env: process.env as Record, diff --git a/src/loopTools/main.ts b/src/loopTools/main.ts index 2d017ba..aaaf611 100644 --- a/src/loopTools/main.ts +++ b/src/loopTools/main.ts @@ -18,14 +18,14 @@ import dotenv from 'dotenv'; import * as mcpServer from '../mcp/server.js'; import { packageJSON } from '../utils/package.js'; -import { Context } from './context.js'; -import { perform } from './perform.js'; -import { snapshot } from './snapshot.js'; +import { Context } from './context'; +import { perform } from './perform'; +import { snapshot } from './snapshot'; import { toMcpTool } from '../mcp/tool.js'; import type { FullConfig } from '../config.js'; import type { ServerBackend } from '../mcp/server.js'; -import type { Tool } from './tool.js'; +import type { Tool } from './tool'; export async function runLoopTools(config: FullConfig) { dotenv.config(); diff --git a/src/loopTools/tool.ts b/src/loopTools/tool.ts index 8ea56aa..9c185cd 100644 --- a/src/loopTools/tool.ts +++ b/src/loopTools/tool.ts @@ -16,7 +16,7 @@ import type { z } from 'zod'; import type * as mcpServer from '../mcp/server.js'; -import type { Context } from './context.js'; +import type { Context } from './context'; import type { ToolSchema } from '../mcp/tool.js'; diff --git a/src/mcp/http.ts b/src/mcp/http.ts index e8ca580..51101a7 100644 --- a/src/mcp/http.ts +++ b/src/mcp/http.ts @@ -21,10 +21,10 @@ import crypto from 'crypto'; import debug from 'debug'; -import * as mcpBundle from './bundle.js'; -import * as mcpServer from './server.js'; +import * as mcpBundle from './bundle'; +import * as mcpServer from './server'; -import type { ServerBackendFactory } from './server.js'; +import type { ServerBackendFactory } from './server'; import type { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js'; import type { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; diff --git a/src/mcp/mdb.ts b/src/mcp/mdb.ts index 2db2699..bdeca18 100644 --- a/src/mcp/mdb.ts +++ b/src/mcp/mdb.ts @@ -16,12 +16,12 @@ import debug from 'debug'; -import { defineToolSchema } from './tool.js'; -import * as mcpBundle from './bundle.js'; -import * as mcpServer from './server.js'; -import * as mcpHttp from './http.js'; -import { wrapInProcess } from './server.js'; -import { ManualPromise } from './manualPromise.js'; +import { defineToolSchema } from './tool'; +import * as mcpBundle from './bundle'; +import * as mcpServer from './server'; +import * as mcpHttp from './http'; +import { wrapInProcess } from './server'; +import { ManualPromise } from './manualPromise'; import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'; import type { Client } from '@modelcontextprotocol/sdk/client/index.js'; diff --git a/src/mcp/proxyBackend.ts b/src/mcp/proxyBackend.ts index b151ad6..96b8c7f 100644 --- a/src/mcp/proxyBackend.ts +++ b/src/mcp/proxyBackend.ts @@ -16,9 +16,9 @@ import debug from 'debug'; -import * as mcpBundle from './bundle.js'; +import * as mcpBundle from './bundle'; -import type { ServerBackend, ClientVersion, Root, Server } from './server.js'; +import type { ServerBackend, ClientVersion, Root, Server } from './server'; import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'; import type { Tool, CallToolResult, CallToolRequest } from '@modelcontextprotocol/sdk/types.js'; import type { Client } from '@modelcontextprotocol/sdk/client/index.js'; diff --git a/src/mcp/server.ts b/src/mcp/server.ts index 082c9fc..4519092 100644 --- a/src/mcp/server.ts +++ b/src/mcp/server.ts @@ -16,9 +16,9 @@ import debug from 'debug'; -import * as mcpBundle from './bundle.js'; -import { httpAddressToString, installHttpTransport, startHttpServer } from './http.js'; -import { InProcessTransport } from './inProcessTransport.js'; +import * as mcpBundle from './bundle'; +import { httpAddressToString, installHttpTransport, startHttpServer } from './http'; +import { InProcessTransport } from './inProcessTransport'; import type { Tool, CallToolResult, CallToolRequest, Root } from '@modelcontextprotocol/sdk/types.js'; import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'; diff --git a/src/mcp/tool.ts b/src/mcp/tool.ts index 97fb334..af2594c 100644 --- a/src/mcp/tool.ts +++ b/src/mcp/tool.ts @@ -17,7 +17,7 @@ import { zodToJsonSchema } from '../mcp/bundle.js'; import type { z } from 'zod'; -import type * as mcpServer from './server.js'; +import type * as mcpServer from './server'; export type ToolSchema = { name: string; diff --git a/src/program.ts b/src/program.ts index dde0cca..819295f 100644 --- a/src/program.ts +++ b/src/program.ts @@ -15,18 +15,18 @@ */ import { program, Option } from 'commander'; -import * as mcpServer from './mcp/server.js'; -import { commaSeparatedList, resolveCLIConfig, semicolonSeparatedList } from './config.js'; -import { packageJSON } from './utils/package.js'; -import { Context } from './context.js'; -import { contextFactory } from './browserContextFactory.js'; -import { runLoopTools } from './loopTools/main.js'; -import { ProxyBackend } from './mcp/proxyBackend.js'; -import { BrowserServerBackend } from './browserServerBackend.js'; -import { ExtensionContextFactory } from './extension/extensionContextFactory.js'; +import * as mcpServer from './mcp/server'; +import { commaSeparatedList, resolveCLIConfig, semicolonSeparatedList } from './config'; +import { packageJSON } from './utils/package'; +import { Context } from './context'; +import { contextFactory } from './browserContextFactory'; +import { runLoopTools } from './loopTools/main'; +import { ProxyBackend } from './mcp/proxyBackend'; +import { BrowserServerBackend } from './browserServerBackend'; +import { ExtensionContextFactory } from './extension/extensionContextFactory'; -import { runVSCodeTools } from './vscode/host.js'; -import type { MCPProvider } from './mcp/proxyBackend.js'; +import { runVSCodeTools } from './vscode/host'; +import type { MCPProvider } from './mcp/proxyBackend'; program .version('Version ' + packageJSON.version) diff --git a/src/response.ts b/src/response.ts index 6c66d3d..3dc95ab 100644 --- a/src/response.ts +++ b/src/response.ts @@ -14,11 +14,11 @@ * limitations under the License. */ -import { renderModalStates } from './tab.js'; +import { renderModalStates } from './tab'; -import type { Tab, TabSnapshot } from './tab.js'; +import type { Tab, TabSnapshot } from './tab'; import type { ImageContent, TextContent } from '@modelcontextprotocol/sdk/types.js'; -import type { Context } from './context.js'; +import type { Context } from './context'; export class Response { private _result: string[] = []; diff --git a/src/sessionLog.ts b/src/sessionLog.ts index dfda6a0..c8922f7 100644 --- a/src/sessionLog.ts +++ b/src/sessionLog.ts @@ -17,13 +17,13 @@ import fs from 'fs'; import path from 'path'; -import { Response } from './response.js'; -import { logUnhandledError } from './utils/log.js'; -import { outputFile } from './config.js'; +import { Response } from './response'; +import { logUnhandledError } from './utils/log'; +import { outputFile } from './config'; -import type { FullConfig } from './config.js'; -import type * as actions from './actions.js'; -import type { Tab, TabSnapshot } from './tab.js'; +import type { FullConfig } from './config'; +import type * as actions from './actions'; +import type { Tab, TabSnapshot } from './tab'; type LogEntry = { timestamp: number; diff --git a/src/tab.ts b/src/tab.ts index 5ef34af..c57b9d7 100644 --- a/src/tab.ts +++ b/src/tab.ts @@ -16,12 +16,12 @@ import { EventEmitter } from 'events'; import * as playwright from 'playwright'; -import { callOnPageNoTrace, waitForCompletion } from './tools/utils.js'; -import { logUnhandledError } from './utils/log.js'; -import { ManualPromise } from './mcp/manualPromise.js'; -import { ModalState } from './tools/tool.js'; +import { callOnPageNoTrace, waitForCompletion } from './tools/utils'; +import { logUnhandledError } from './utils/log'; +import { ManualPromise } from './mcp/manualPromise'; +import { ModalState } from './tools/tool'; -import type { Context } from './context.js'; +import type { Context } from './context'; type PageEx = playwright.Page & { _snapshotForAI: () => Promise; diff --git a/src/tools.ts b/src/tools.ts index 0eedf85..b1e8059 100644 --- a/src/tools.ts +++ b/src/tools.ts @@ -14,26 +14,26 @@ * limitations under the License. */ -import common from './tools/common.js'; -import console from './tools/console.js'; -import dialogs from './tools/dialogs.js'; -import evaluate from './tools/evaluate.js'; -import files from './tools/files.js'; -import form from './tools/form.js'; -import install from './tools/install.js'; -import keyboard from './tools/keyboard.js'; -import mouse from './tools/mouse.js'; -import navigate from './tools/navigate.js'; -import network from './tools/network.js'; -import pdf from './tools/pdf.js'; -import snapshot from './tools/snapshot.js'; -import tabs from './tools/tabs.js'; -import screenshot from './tools/screenshot.js'; -import wait from './tools/wait.js'; -import verify from './tools/verify.js'; +import common from './tools/common'; +import console from './tools/console'; +import dialogs from './tools/dialogs'; +import evaluate from './tools/evaluate'; +import files from './tools/files'; +import form from './tools/form'; +import install from './tools/install'; +import keyboard from './tools/keyboard'; +import mouse from './tools/mouse'; +import navigate from './tools/navigate'; +import network from './tools/network'; +import pdf from './tools/pdf'; +import snapshot from './tools/snapshot'; +import tabs from './tools/tabs'; +import screenshot from './tools/screenshot'; +import wait from './tools/wait'; +import verify from './tools/verify'; -import type { Tool } from './tools/tool.js'; -import type { FullConfig } from './config.js'; +import type { Tool } from './tools/tool'; +import type { FullConfig } from './config'; export const allTools: Tool[] = [ ...common, diff --git a/src/tools/common.ts b/src/tools/common.ts index a652bc4..8f8aca7 100644 --- a/src/tools/common.ts +++ b/src/tools/common.ts @@ -15,7 +15,7 @@ */ import { z } from '../mcp/bundle.js'; -import { defineTabTool, defineTool } from './tool.js'; +import { defineTabTool, defineTool } from './tool'; const close = defineTool({ capability: 'core', diff --git a/src/tools/console.ts b/src/tools/console.ts index 53cecde..a2fb6b7 100644 --- a/src/tools/console.ts +++ b/src/tools/console.ts @@ -15,7 +15,7 @@ */ import { z } from '../mcp/bundle.js'; -import { defineTabTool } from './tool.js'; +import { defineTabTool } from './tool'; const console = defineTabTool({ capability: 'core', diff --git a/src/tools/dialogs.ts b/src/tools/dialogs.ts index 70b1d98..637e4a7 100644 --- a/src/tools/dialogs.ts +++ b/src/tools/dialogs.ts @@ -15,7 +15,7 @@ */ import { z } from '../mcp/bundle.js'; -import { defineTabTool } from './tool.js'; +import { defineTabTool } from './tool'; const handleDialog = defineTabTool({ capability: 'core', diff --git a/src/tools/evaluate.ts b/src/tools/evaluate.ts index e214f12..e1f188c 100644 --- a/src/tools/evaluate.ts +++ b/src/tools/evaluate.ts @@ -15,9 +15,9 @@ */ import { z } from '../mcp/bundle.js'; -import { defineTabTool } from './tool.js'; +import { defineTabTool } from './tool'; import * as javascript from '../utils/codegen.js'; -import { generateLocator } from './utils.js'; +import { generateLocator } from './utils'; import type * as playwright from 'playwright'; diff --git a/src/tools/files.ts b/src/tools/files.ts index 1e2d687..a3b2e5a 100644 --- a/src/tools/files.ts +++ b/src/tools/files.ts @@ -15,7 +15,7 @@ */ import { z } from '../mcp/bundle.js'; -import { defineTabTool } from './tool.js'; +import { defineTabTool } from './tool'; const uploadFile = defineTabTool({ capability: 'core', diff --git a/src/tools/form.ts b/src/tools/form.ts index f59266c..501f067 100644 --- a/src/tools/form.ts +++ b/src/tools/form.ts @@ -15,8 +15,8 @@ */ import { z } from '../mcp/bundle.js'; -import { defineTabTool } from './tool.js'; -import { generateLocator } from './utils.js'; +import { defineTabTool } from './tool'; +import { generateLocator } from './utils'; import * as javascript from '../utils/codegen.js'; const fillForm = defineTabTool({ diff --git a/src/tools/install.ts b/src/tools/install.ts index 6ab263a..4152ec7 100644 --- a/src/tools/install.ts +++ b/src/tools/install.ts @@ -16,10 +16,9 @@ import { fork } from 'child_process'; import path from 'path'; -import url from 'url'; import { z } from '../mcp/bundle.js'; -import { defineTool } from './tool.js'; +import { defineTool } from './tool'; const install = defineTool({ capability: 'core-install', @@ -33,8 +32,7 @@ const install = defineTool({ handle: async (context, params, response) => { const channel = context.config.browser?.launchOptions?.channel ?? context.config.browser?.browserName ?? 'chrome'; - const cliUrl = import.meta.resolve('playwright/package.json'); - const cliPath = path.join(url.fileURLToPath(cliUrl), '..', 'cli.js'); + const cliPath = path.join(require.resolve('playwright/package.json'), '../cli.js'); const child = fork(cliPath, ['install', channel], { stdio: 'pipe', }); diff --git a/src/tools/keyboard.ts b/src/tools/keyboard.ts index 8857d92..70ed94e 100644 --- a/src/tools/keyboard.ts +++ b/src/tools/keyboard.ts @@ -15,9 +15,9 @@ */ import { z } from '../mcp/bundle.js'; -import { defineTabTool } from './tool.js'; -import { elementSchema } from './snapshot.js'; -import { generateLocator } from './utils.js'; +import { defineTabTool } from './tool'; +import { elementSchema } from './snapshot'; +import { generateLocator } from './utils'; import * as javascript from '../utils/codegen.js'; const pressKey = defineTabTool({ diff --git a/src/tools/mouse.ts b/src/tools/mouse.ts index 1e2e027..4063f05 100644 --- a/src/tools/mouse.ts +++ b/src/tools/mouse.ts @@ -15,7 +15,7 @@ */ import { z } from '../mcp/bundle.js'; -import { defineTabTool } from './tool.js'; +import { defineTabTool } from './tool'; const elementSchema = z.object({ element: z.string().describe('Human-readable element description used to obtain permission to interact with the element'), diff --git a/src/tools/navigate.ts b/src/tools/navigate.ts index 2558d45..ca68a5a 100644 --- a/src/tools/navigate.ts +++ b/src/tools/navigate.ts @@ -15,7 +15,7 @@ */ import { z } from '../mcp/bundle.js'; -import { defineTool, defineTabTool } from './tool.js'; +import { defineTool, defineTabTool } from './tool'; const navigate = defineTool({ capability: 'core', diff --git a/src/tools/network.ts b/src/tools/network.ts index c2b4284..6b1b3b7 100644 --- a/src/tools/network.ts +++ b/src/tools/network.ts @@ -15,7 +15,7 @@ */ import { z } from '../mcp/bundle.js'; -import { defineTabTool } from './tool.js'; +import { defineTabTool } from './tool'; import type * as playwright from 'playwright'; diff --git a/src/tools/pdf.ts b/src/tools/pdf.ts index 72bee47..d7defb5 100644 --- a/src/tools/pdf.ts +++ b/src/tools/pdf.ts @@ -15,7 +15,7 @@ */ import { z } from '../mcp/bundle.js'; -import { defineTabTool } from './tool.js'; +import { defineTabTool } from './tool'; import * as javascript from '../utils/codegen.js'; const pdfSchema = z.object({ diff --git a/src/tools/screenshot.ts b/src/tools/screenshot.ts index 08d7cf1..256e710 100644 --- a/src/tools/screenshot.ts +++ b/src/tools/screenshot.ts @@ -15,9 +15,9 @@ */ import { z } from '../mcp/bundle.js'; -import { defineTabTool } from './tool.js'; +import { defineTabTool } from './tool'; import * as javascript from '../utils/codegen.js'; -import { generateLocator } from './utils.js'; +import { generateLocator } from './utils'; import type * as playwright from 'playwright'; diff --git a/src/tools/snapshot.ts b/src/tools/snapshot.ts index 523d69e..a68cf20 100644 --- a/src/tools/snapshot.ts +++ b/src/tools/snapshot.ts @@ -15,9 +15,9 @@ */ import { z } from '../mcp/bundle.js'; -import { defineTabTool, defineTool } from './tool.js'; +import { defineTabTool, defineTool } from './tool'; import * as javascript from '../utils/codegen.js'; -import { generateLocator } from './utils.js'; +import { generateLocator } from './utils'; const snapshot = defineTool({ capability: 'core', diff --git a/src/tools/tabs.ts b/src/tools/tabs.ts index 4cfe7d5..6ee44fe 100644 --- a/src/tools/tabs.ts +++ b/src/tools/tabs.ts @@ -15,7 +15,7 @@ */ import { z } from '../mcp/bundle.js'; -import { defineTool } from './tool.js'; +import { defineTool } from './tool'; const browserTabs = defineTool({ capability: 'core-tabs', diff --git a/src/tools/verify.ts b/src/tools/verify.ts index 3414f97..b28da52 100644 --- a/src/tools/verify.ts +++ b/src/tools/verify.ts @@ -15,9 +15,9 @@ */ import { z } from '../mcp/bundle.js'; -import { defineTabTool } from './tool.js'; +import { defineTabTool } from './tool'; import * as javascript from '../utils/codegen.js'; -import { generateLocator } from './utils.js'; +import { generateLocator } from './utils'; const verifyElement = defineTabTool({ capability: 'verify', diff --git a/src/tools/wait.ts b/src/tools/wait.ts index 95c5ab6..9338047 100644 --- a/src/tools/wait.ts +++ b/src/tools/wait.ts @@ -15,7 +15,7 @@ */ import { z } from '../mcp/bundle.js'; -import { defineTool } from './tool.js'; +import { defineTool } from './tool'; const wait = defineTool({ capability: 'core', diff --git a/src/utils/package.ts b/src/utils/package.ts index e3c4bba..0c415d6 100644 --- a/src/utils/package.ts +++ b/src/utils/package.ts @@ -16,7 +16,5 @@ import fs from 'fs'; import path from 'path'; -import url from 'url'; -const __filename = url.fileURLToPath(import.meta.url); -export const packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(__filename), '..', '..', 'package.json'), 'utf8')); +export const packageJSON = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '..', 'package.json'), 'utf8')); diff --git a/src/vscode/host.ts b/src/vscode/host.ts index f6d3077..e4e729d 100644 --- a/src/vscode/host.ts +++ b/src/vscode/host.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import url from 'url'; import path from 'path'; import * as mcpBundle from '../mcp/bundle.js'; @@ -137,7 +136,7 @@ class VSCodeProxyBackend implements ServerBackend { command: process.execPath, cwd: process.cwd(), args: [ - path.join(url.fileURLToPath(import.meta.url), '..', 'main.js'), + path.join(__dirname, 'main.js'), JSON.stringify(this._config), params.connectionString, params.lib, diff --git a/src/vscode/main.ts b/src/vscode/main.ts index e0e73e2..e1905f6 100644 --- a/src/vscode/main.ts +++ b/src/vscode/main.ts @@ -69,8 +69,10 @@ async function main(config: FullConfig, connectionString: string, lib: string) { ); } -await main( - JSON.parse(process.argv[2]), - process.argv[3], - process.argv[4] -); +void (async () => { + await main( + JSON.parse(process.argv[2]), + process.argv[3], + process.argv[4] + ); +})(); diff --git a/tests/capabilities.spec.ts b/tests/capabilities.spec.ts index fe928de..7ec699a 100644 --- a/tests/capabilities.spec.ts +++ b/tests/capabilities.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('test snapshot tool list', async ({ client }) => { const { tools } = await client.listTools(); diff --git a/tests/cdp.spec.ts b/tests/cdp.spec.ts index 4ab9571..77702c4 100644 --- a/tests/cdp.spec.ts +++ b/tests/cdp.spec.ts @@ -14,10 +14,9 @@ * limitations under the License. */ -import url from 'node:url'; import path from 'node:path'; import { spawnSync } from 'node:child_process'; -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('cdp server', async ({ cdpServer, startClient, server }) => { await cdpServer.start(); @@ -84,9 +83,6 @@ test('should throw connection error and allow re-connecting', async ({ cdpServer }); }); -// NOTE: Can be removed when we drop Node.js 18 support and changed to import.meta.filename. -const __filename = url.fileURLToPath(import.meta.url); - test('does not support --device', async () => { const result = spawnSync('node', [ path.join(__filename, '../../cli.js'), '--device=Pixel 5', '--cdp-endpoint=http://localhost:1234', diff --git a/tests/click.spec.ts b/tests/click.spec.ts index d6b425e..53db231 100644 --- a/tests/click.spec.ts +++ b/tests/click.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('browser_click', async ({ client, server, mcpBrowser }) => { server.setContent('/', ` diff --git a/tests/config.spec.ts b/tests/config.spec.ts index 8dc5083..246d754 100644 --- a/tests/config.spec.ts +++ b/tests/config.spec.ts @@ -17,7 +17,7 @@ import fs from 'node:fs'; import { Config } from '../config.js'; -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('config user data dir', async ({ startClient, server, mcpMode }, testInfo) => { server.setContent('/', ` diff --git a/tests/console.spec.ts b/tests/console.spec.ts index 572623b..835b453 100644 --- a/tests/console.spec.ts +++ b/tests/console.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('browser_console_messages', async ({ client, server }) => { server.setContent('/', ` diff --git a/tests/core.spec.ts b/tests/core.spec.ts index cdf1f03..f5bd171 100644 --- a/tests/core.spec.ts +++ b/tests/core.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('browser_navigate', async ({ client, server }) => { expect(await client.callTool({ diff --git a/tests/device.spec.ts b/tests/device.spec.ts index 51f75c1..986d321 100644 --- a/tests/device.spec.ts +++ b/tests/device.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('--device should work', async ({ startClient, server, mcpMode }) => { const { client } = await startClient({ diff --git a/tests/dialogs.spec.ts b/tests/dialogs.spec.ts index 6739825..0b57714 100644 --- a/tests/dialogs.spec.ts +++ b/tests/dialogs.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('alert dialog', async ({ client, server }) => { server.setContent('/', ``, 'text/html'); diff --git a/tests/evaluate.spec.ts b/tests/evaluate.spec.ts index 8457fca..68c8a39 100644 --- a/tests/evaluate.spec.ts +++ b/tests/evaluate.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('browser_evaluate', async ({ client, server }) => { expect(await client.callTool({ diff --git a/tests/files.spec.ts b/tests/files.spec.ts index 160686a..b3ac198 100644 --- a/tests/files.spec.ts +++ b/tests/files.spec.ts @@ -15,7 +15,7 @@ */ import fs from 'fs/promises'; -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('browser_file_upload', async ({ client, server }, testInfo) => { server.setContent('/', ` diff --git a/tests/fixtures.ts b/tests/fixtures.ts index d6368e8..80d03b9 100644 --- a/tests/fixtures.ts +++ b/tests/fixtures.ts @@ -15,7 +15,6 @@ */ import fs from 'fs'; -import url from 'url'; import path from 'path'; import { chromium } from 'playwright'; @@ -23,7 +22,7 @@ import { test as baseTest, expect as baseExpect } from '@playwright/test'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { ListRootsRequestSchema } from '@modelcontextprotocol/sdk/types.js'; -import { TestServer } from './testserver/index.ts'; +import { TestServer } from './testserver/index'; import type { Config } from '../config'; import type { BrowserContext } from 'playwright'; @@ -186,8 +185,6 @@ async function createTransport(args: string[], mcpMode: TestOptions['mcpMode'], transport: Transport, stderr: Stream | null, }> { - // NOTE: Can be removed when we drop Node.js 18 support and changed to import.meta.filename. - const __filename = url.fileURLToPath(import.meta.url); if (mcpMode === 'docker') { const dockerArgs = ['run', '--rm', '-i', '--network=host', '-v', `${test.info().project.outputDir}:/app/test-results`]; const transport = new StdioClientTransport({ @@ -202,7 +199,7 @@ async function createTransport(args: string[], mcpMode: TestOptions['mcpMode'], const transport = new StdioClientTransport({ command: 'node', - args: [path.join(path.dirname(__filename), '../cli.js'), ...args], + args: [path.join(__dirname, '../cli.js'), ...args], cwd: path.dirname(test.info().config.configFile!), stderr: 'pipe', env: { diff --git a/tests/form.spec.ts b/tests/form.spec.ts index 458cc4c..339d79d 100644 --- a/tests/form.spec.ts +++ b/tests/form.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('browser_fill_form (textbox)', async ({ client, server }) => { server.setContent('/', ` diff --git a/tests/headed.spec.ts b/tests/headed.spec.ts index 7274657..af3be37 100644 --- a/tests/headed.spec.ts +++ b/tests/headed.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; for (const mcpHeadless of [false, true]) { test.describe(`mcpHeadless: ${mcpHeadless}`, () => { diff --git a/tests/http.spec.ts b/tests/http.spec.ts index 4ff9ac9..6558451 100644 --- a/tests/http.spec.ts +++ b/tests/http.spec.ts @@ -14,20 +14,16 @@ * limitations under the License. */ -import fs from 'node:fs'; -import url from 'node:url'; +import fs from 'fs'; -import { ChildProcess, spawn } from 'node:child_process'; -import path from 'node:path'; +import { ChildProcess, spawn } from 'child_process'; +import path from 'path'; import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'; import { Client } from '@modelcontextprotocol/sdk/client/index.js'; -import { test as baseTest, expect } from './fixtures.js'; +import { test as baseTest, expect } from './fixtures'; import type { Config } from '../config.d.ts'; -// NOTE: Can be removed when we drop Node.js 18 support and changed to import.meta.filename. -const __filename = url.fileURLToPath(import.meta.url); - const test = baseTest.extend<{ serverEndpoint: (options?: { args?: string[], noPort?: boolean }) => Promise<{ url: URL, stderr: () => string }> }>({ serverEndpoint: async ({ mcpHeadless }, use, testInfo) => { let cp: ChildProcess | undefined; diff --git a/tests/iframes.spec.ts b/tests/iframes.spec.ts index 69d9863..3c53de1 100644 --- a/tests/iframes.spec.ts +++ b/tests/iframes.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('stitched aria frames', async ({ client }) => { expect(await client.callTool({ diff --git a/tests/install.spec.ts b/tests/install.spec.ts index e8c1b42..70fde07 100644 --- a/tests/install.spec.ts +++ b/tests/install.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('browser_install', async ({ client, mcpBrowser }) => { test.skip(mcpBrowser !== 'chromium', 'Test only chromium'); diff --git a/tests/launch.spec.ts b/tests/launch.spec.ts index 37fa264..f7f0171 100644 --- a/tests/launch.spec.ts +++ b/tests/launch.spec.ts @@ -16,7 +16,7 @@ import fs from 'fs'; -import { test, expect, formatOutput } from './fixtures.js'; +import { test, expect, formatOutput } from './fixtures'; test('test reopen browser', async ({ startClient, server, mcpMode }) => { const { client, stderr } = await startClient(); diff --git a/tests/library.spec.ts b/tests/library.spec.ts index 2029b3d..754df89 100644 --- a/tests/library.spec.ts +++ b/tests/library.spec.ts @@ -15,7 +15,7 @@ */ import child_process from 'child_process'; import fs from 'fs/promises'; -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('library can be used from CommonJS', { annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright-mcp/issues/456' } }, async ({}, testInfo) => { const file = testInfo.outputPath('main.cjs'); diff --git a/tests/mdb.spec.ts b/tests/mdb.spec.ts index d694b58..8b98414 100644 --- a/tests/mdb.spec.ts +++ b/tests/mdb.spec.ts @@ -21,7 +21,7 @@ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/ import { runMainBackend, runOnPauseBackendLoop } from '../src/mcp/mdb.js'; -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; import type * as mcpServer from '../src/mcp/server.js'; import type { ServerBackendOnPause } from '../src/mcp/mdb.js'; diff --git a/tests/network.spec.ts b/tests/network.spec.ts index 96ee98c..40b3852 100644 --- a/tests/network.spec.ts +++ b/tests/network.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('browser_network_requests', async ({ client, server }) => { server.setContent('/', ` diff --git a/tests/pdf.spec.ts b/tests/pdf.spec.ts index 3d72e75..937eb16 100644 --- a/tests/pdf.spec.ts +++ b/tests/pdf.spec.ts @@ -16,7 +16,7 @@ import fs from 'fs'; -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('save as pdf unavailable', async ({ startClient, server }) => { const { client } = await startClient(); diff --git a/tests/roots.spec.ts b/tests/roots.spec.ts index ad5170b..94c1e9e 100644 --- a/tests/roots.spec.ts +++ b/tests/roots.spec.ts @@ -18,7 +18,7 @@ import fs from 'fs'; import path from 'path'; import { pathToFileURL } from 'url'; -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; import { createHash } from '../src/utils/guid.js'; const p = process.platform === 'win32' ? 'c:\\non\\existent\\folder' : '/non/existent/folder'; diff --git a/tests/screenshot.spec.ts b/tests/screenshot.spec.ts index 294a43f..50b2eae 100644 --- a/tests/screenshot.spec.ts +++ b/tests/screenshot.spec.ts @@ -16,7 +16,7 @@ import fs from 'fs'; -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('browser_take_screenshot (viewport)', async ({ startClient, server }, testInfo) => { const { client } = await startClient({ diff --git a/tests/session-log.spec.ts b/tests/session-log.spec.ts index 2654c2d..364723d 100644 --- a/tests/session-log.spec.ts +++ b/tests/session-log.spec.ts @@ -17,7 +17,7 @@ import fs from 'fs'; import path from 'path'; -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('session log should record tool calls', async ({ startClient, server }, testInfo) => { const { client, stderr } = await startClient({ diff --git a/tests/sse.spec.ts b/tests/sse.spec.ts index 60cc740..62183d9 100644 --- a/tests/sse.spec.ts +++ b/tests/sse.spec.ts @@ -14,20 +14,16 @@ * limitations under the License. */ -import fs from 'node:fs'; -import url from 'node:url'; +import fs from 'fs'; -import { ChildProcess, spawn } from 'node:child_process'; -import path from 'node:path'; +import { ChildProcess, spawn } from 'child_process'; +import path from 'path'; import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'; import { Client } from '@modelcontextprotocol/sdk/client/index.js'; -import { test as baseTest, expect } from './fixtures.js'; +import { test as baseTest, expect } from './fixtures'; import type { Config } from '../config.d.ts'; -// NOTE: Can be removed when we drop Node.js 18 support and changed to import.meta.filename. -const __filename = url.fileURLToPath(import.meta.url); - const test = baseTest.extend<{ serverEndpoint: (options?: { args?: string[], noPort?: boolean }) => Promise<{ url: URL, stderr: () => string }> }>({ serverEndpoint: async ({ mcpHeadless }, use, testInfo) => { let cp: ChildProcess | undefined; diff --git a/tests/tabs.spec.ts b/tests/tabs.spec.ts index ddd873d..a0b40d8 100644 --- a/tests/tabs.spec.ts +++ b/tests/tabs.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; import type { Client } from '@modelcontextprotocol/sdk/client/index.js'; diff --git a/tests/testserver/index.ts b/tests/testserver/index.ts index b40f7f4..da77cb5 100644 --- a/tests/testserver/index.ts +++ b/tests/testserver/index.ts @@ -16,7 +16,6 @@ */ import fs from 'fs'; -import url from 'node:url'; import http from 'http'; import https from 'https'; import path from 'path'; @@ -25,9 +24,6 @@ import debug from 'debug'; const fulfillSymbol = Symbol('fulfil callback'); const rejectSymbol = Symbol('reject callback'); -// NOTE: Can be removed when we drop Node.js 18 support and changed to import.meta.filename. -const __filename = url.fileURLToPath(import.meta.url); - export class TestServer { private _server: http.Server; readonly debugServer: any; diff --git a/tests/trace.spec.ts b/tests/trace.spec.ts index 6cfe12e..927f23a 100644 --- a/tests/trace.spec.ts +++ b/tests/trace.spec.ts @@ -16,7 +16,7 @@ import fs from 'fs'; -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('check that trace is saved', async ({ startClient, server, mcpMode }, testInfo) => { const outputDir = testInfo.outputPath('output'); diff --git a/tests/type.spec.ts b/tests/type.spec.ts index ffcc6c6..7ac2314 100644 --- a/tests/type.spec.ts +++ b/tests/type.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('browser_type', async ({ client, server }) => { server.setContent('/', ` diff --git a/tests/verify.spec.ts b/tests/verify.spec.ts index 91366e1..58c9b36 100644 --- a/tests/verify.spec.ts +++ b/tests/verify.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test.use({ mcpArgs: ['--caps=verify'] }); diff --git a/tests/vscode.spec.ts b/tests/vscode.spec.ts index 3582ca3..7f1c3d2 100644 --- a/tests/vscode.spec.ts +++ b/tests/vscode.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('browser_connect(vscode) works', async ({ startClient, playwright, browserName }) => { const { client } = await startClient({ @@ -27,7 +27,7 @@ test('browser_connect(vscode) works', async ({ startClient, playwright, browserN name: 'browser_connect', arguments: { connectionString: server.wsEndpoint(), - lib: import.meta.resolve('playwright'), + lib: require.resolve('playwright'), } })).toHaveResponse({ result: 'Successfully connected.' diff --git a/tests/wait.spec.ts b/tests/wait.spec.ts index a75c955..0388faf 100644 --- a/tests/wait.spec.ts +++ b/tests/wait.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('browser_wait_for(text)', async ({ client, server }) => { server.setContent('/', ` diff --git a/tests/webdriver.spec.ts b/tests/webdriver.spec.ts index bd96925..ef742d7 100644 --- a/tests/webdriver.spec.ts +++ b/tests/webdriver.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { test, expect } from './fixtures.js'; +import { test, expect } from './fixtures'; test('do not falsely advertise user agent as a test driver', async ({ client, server, mcpBrowser }) => { test.skip(mcpBrowser === 'firefox'); diff --git a/tsconfig.json b/tsconfig.json index 114ce8b..c9424f8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,9 @@ { "compilerOptions": { - "target": "ESNext", + "target": "ES2019", "esModuleInterop": true, - "moduleResolution": "nodenext", "strict": true, - "module": "NodeNext", + "module": "commonjs", "rootDir": "src", "outDir": "./lib", "resolveJsonModule": true diff --git a/utils/check-deps.js b/utils/check-deps.js index 60d545c..adbdde8 100644 --- a/utils/check-deps.js +++ b/utils/check-deps.js @@ -18,13 +18,10 @@ // @ts-check -import fs from 'fs'; -import ts from 'typescript'; -import path from 'path'; -import Module from 'module'; - -const __dirname = path.dirname(new URL(import.meta.url).pathname); -const require = Module.createRequire(import.meta.url); +const fs = require('fs'); +const ts = require('typescript'); +const path = require('path'); +const Module = require('module'); const builtins = new Set(Module.builtinModules); diff --git a/utils/set-version.js b/utils/set-version.js index b0d7b34..ec0e2da 100644 --- a/utils/set-version.js +++ b/utils/set-version.js @@ -22,8 +22,6 @@ import path from 'path'; import child_process from 'child_process'; import { argv } from 'process'; -const __dirname = path.dirname(new URL(import.meta.url).pathname); - const readJSON = async (filePath) => JSON.parse(await fs.promises.readFile(filePath, 'utf8')); const writeJSON = async (filePath, json) => { await fs.promises.writeFile(filePath, JSON.stringify(json, null, 2) + '\n'); diff --git a/utils/update-readme.js b/utils/update-readme.js index 4e0648b..f5855bb 100644 --- a/utils/update-readme.js +++ b/utils/update-readme.js @@ -16,13 +16,12 @@ */ // @ts-check -import fs from 'node:fs' -import path from 'node:path' -import url from 'node:url' -import zodToJsonSchema from 'zod-to-json-schema' -import { execSync } from 'node:child_process'; +const fs = require('fs') +const path = require('path') +const { zodToJsonSchema } = require('zod-to-json-schema') +const { execSync } = require('child_process'); -import { allTools } from '../lib/tools.js'; +const { allTools } = require('../lib/tools.js'); const capabilities = { 'core': 'Core automation', @@ -35,11 +34,8 @@ const capabilities = { const toolsByCapability = Object.fromEntries(Object.entries(capabilities).map(([capability, title]) => [title, allTools.filter(tool => tool.capability === capability).sort((a, b) => a.schema.name.localeCompare(b.schema.name))])); -// NOTE: Can be removed when we drop Node.js 18 support and changed to import.meta.filename. -const __filename = url.fileURLToPath(import.meta.url); - /** - * @param {import('../src/tools/tool.js').ToolSchema} tool + * @param {import('../src/mcp/tool.js').ToolSchema} tool * @returns {string[]} */ function formatToolForReadme(tool) {