Skip to content

chore: prep devtools app#39231

Merged
pavelfeldman merged 1 commit intomicrosoft:mainfrom
pavelfeldman:one_frontend
Feb 12, 2026
Merged

chore: prep devtools app#39231
pavelfeldman merged 1 commit intomicrosoft:mainfrom
pavelfeldman:one_frontend

Conversation

@pavelfeldman
Copy link
Member

No description provided.


const show = declareCommand({
const devtoolsShow = declareCommand({
name: 'show',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop this command?

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Prepares groundwork for a standalone DevTools “app” flow by introducing a new internal protocol method for setting the dock tile icon, refactoring DevTools start/stop tooling, and removing the old tray daemon implementation/dependency.

Changes:

  • Add internal Page.setDockTile protocol method and wire it through client/server/dispatcher layers (Chromium implementation; other engines stubbed).
  • Introduce a new devtoolsApp launcher (replacing the removed tray daemon) and update CLI command routing.
  • Refactor DevTools MCP tools and update DevTools frontend connection logic to expect a ?ws= URL parameter.

Reviewed changes

Copilot reviewed 22 out of 25 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/protocol/src/protocol.yml Adds internal Page.setDockTile protocol command definition.
packages/protocol/src/channels.d.ts Adds typed channel method + params for setDockTile.
packages/playwright/src/mcp/terminal/trayDaemon.ts Removes tray daemon implementation.
packages/playwright/src/mcp/terminal/program.ts Re-routes show command to launch devtoolsApp.js.
packages/playwright/src/mcp/terminal/devtoolsApp.ts Adds new DevTools “app” launcher and singleton socket handling.
packages/playwright/src/mcp/terminal/commands.ts Splits DevTools commands into show, devtools-start, devtools-stop.
packages/playwright/src/mcp/terminal/appIcon.png Adds app icon used by devtoolsApp.
packages/playwright/src/mcp/browser/tools/devtools.ts Renames tool(s) and adds devtools start/stop MCP tools.
packages/playwright/src/mcp/browser/tools.ts Switches tool registration from removed show tool to new devtools tools.
packages/playwright-core/src/utils/isomorphic/protocolMetainfo.ts Marks Page.setDockTile as internal in protocol metainfo.
packages/playwright-core/src/server/webkit/wkPage.ts Adds required setDockTile stub to WebKit delegate.
packages/playwright-core/src/server/trace/viewer/traceViewer.ts Removes openUrlInApp helper.
packages/playwright-core/src/server/page.ts Extends PageDelegate and Page with setDockTile.
packages/playwright-core/src/server/index.ts Stops exporting openUrlInApp and ProgressController from server index.
packages/playwright-core/src/server/firefox/ffPage.ts Adds required setDockTile stub to Firefox delegate.
packages/playwright-core/src/server/dispatchers/pageDispatcher.ts Exposes Page.setDockTile over the wire.
packages/playwright-core/src/server/devtoolsController.ts Changes DevTools endpoint to return a ws URL and removes static-file routing.
packages/playwright-core/src/server/chromium/crPage.ts Implements setDockTile via CDP Browser.setDockTile.
packages/playwright-core/src/server/browserContext.ts Minor refactor of devtoolsStart return.
packages/playwright-core/src/server/bidi/bidiPage.ts Adds required setDockTile stub to BiDi delegate.
packages/playwright-core/src/protocol/validator.ts Adds validation schema for PageSetDockTile.
packages/playwright-core/src/client/page.ts Adds internal client helper _setDockTile.
packages/devtools/src/devtools.tsx Changes transport initialization to read a full ws URL from ?ws=.
package.json Removes @trayjs/trayjs dependency.
package-lock.json Removes @trayjs/* packages from lockfile.
Comments suppressed due to low confidence (1)

packages/playwright/src/mcp/browser/tools/devtools.ts:33

  • The tool schema exposes an optional guid parameter, but the underlying protocol/server BrowserContext.devtoolsStart does not accept/consume it (it will be silently dropped by protocol validation). Either remove guid from the tool schema, or plumb it through to DevToolsController.start() so callers can request a deterministic endpoint path.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

reject(new Error('already running'));
});
client.on('error', () => {
fs.unlinkSync(socketPath);
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fs.unlinkSync(socketPath) in the client.on('error') path can throw (e.g. on Windows named pipes, or if the socket path doesn't exist / is already removed). This would prevent recovery from a stale socket. Guard this unlink (platform check + exists + try/catch) before re-listening.

Suggested change
fs.unlinkSync(socketPath);
// Attempt to clean up a stale Unix domain socket; on Windows the path is a named pipe.
if (process.platform !== 'win32') {
try {
if (fs.existsSync(socketPath))
fs.unlinkSync(socketPath);
} catch {
// Ignore cleanup errors and still attempt to re-listen.
}
}

Copilot uses AI. Check for mistakes.
const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
const guid = new URLSearchParams(location.search).get('ws');
const transport = new DevToolsTransport(wsProtocol + '//' + location.host + '/' + guid);
const wsUrl = new URLSearchParams(location.search).get('ws')!;
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code assumes the ws query parameter is always present (get('ws')!). devtoolsApp currently navigates to the UI without that param, and users can also open the page directly, so this will throw at runtime. Handle a missing/invalid ws parameter by showing a clear disconnected/error state instead of crashing (and consider validating that it’s a ws/wss URL).

Suggested change
const wsUrl = new URLSearchParams(location.search).get('ws')!;
const searchParams = new URLSearchParams(location.search);
const wsUrl = searchParams.get('ws');
const isValidWsUrl = typeof wsUrl === 'string' && /^wss?:\/\//.test(wsUrl);
if (!isValidWsUrl) {
setStatus({ text: 'Disconnected: missing or invalid "ws" query parameter', cls: 'error' });
return;
}

Copilot uses AI. Check for mistakes.
Comment on lines +42 to +46
const url = httpServer.urlPrefix('human-readable');

const { page } = await launchApp('devtools');
await page.goto(url);
return page;
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

openDevToolsApp() navigates to the DevTools UI without providing the required ws query parameter, but packages/devtools/src/devtools.tsx now assumes ?ws=<wsUrl> is always present. As a result, the app will fail to connect (or crash) when launched this way. Consider passing the WebSocket endpoint into devtoolsApp (e.g. via argv/env or by discovering/running browser_devtools_start) and navigating to index.html?ws=${encodeURIComponent(wsUrl)}.

Copilot uses AI. Check for mistakes.
Comment on lines +118 to +124
async function acquireSingleton(): Promise<net.Server> {
const socketPath = devtoolsSocketPath();

return await new Promise((resolve, reject) => {
const server = net.createServer();
server.listen(socketPath, () => resolve(server));
server.on('error', (err: NodeJS.ErrnoException) => {
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Unix, net.Server.listen(socketPath) will fail if the parent directory of the socket file does not exist. devtoolsSocketPath() uses a temp subdirectory but acquireSingleton() does not ensure it exists. Create the sockets directory (e.g. fs.mkdirSync(socketsDirectory(), { recursive: true })) before calling listen() on non-Windows platforms.

Copilot uses AI. Check for mistakes.
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@pavelfeldman pavelfeldman force-pushed the one_frontend branch 2 times, most recently from ad7d672 to a35421b Compare February 12, 2026 01:15
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions
Copy link
Contributor

Test results for "MCP"

1 failed
❌ [chrome] › mcp/cli-webstorage.spec.ts:20 › localstorage-list shows no items when empty @mcp-macos-15

4791 passed, 135 skipped


Merge workflow run.

@github-actions
Copy link
Contributor

Test results for "tests 1"

5 failed
❌ [playwright-test] › expect.spec.ts:582 › should log scale the time @macos-latest-node20
❌ [playwright-test] › global-setup.spec.ts:313 › globalSetup should work for auth @macos-latest-node20
❌ [playwright-test] › playwright.artifacts.spec.ts:127 › should work with screenshot: on @macos-latest-node20
❌ [playwright-test] › reporter.spec.ts:251 › merged › should not have internal error when steps are finished after timeout @macos-latest-node20
❌ [playwright-test] › ui-mode-test-network-tab.spec.ts:301 › should copy network request @macos-latest-node20

2 flaky ⚠️ [playwright-test] › ui-mode-trace.spec.ts:700 › should indicate current test status `@macos-latest-node20`
⚠️ [playwright-test] › ui-mode-trace.spec.ts:700 › should indicate current test status `@windows-latest-node20`

38518 passed, 843 skipped


Merge workflow run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants