Skip to content

Commit c1764b8

Browse files
authored
fix(cli): fix list command not showing sessions when workspaceDir is undefined (#40039)
1 parent ff6d41b commit c1764b8

3 files changed

Lines changed: 33 additions & 13 deletions

File tree

packages/playwright-core/src/tools/cli-client/program.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { execSync, spawn } from 'child_process';
2222
import crypto from 'crypto';
2323
import os from 'os';
2424
import path from 'path';
25-
import { createClientInfo, explicitSessionName, Registry, resolveSessionName } from './registry';
25+
import { clientKey, createClientInfo, explicitSessionName, Registry, resolveSessionName } from './registry';
2626
import { Session, renderResolvedConfig } from './session';
2727
import { serverRegistry } from '../../serverRegistry';
2828
import { minimist } from './minimist';
@@ -295,30 +295,31 @@ async function listSessions(registry: Registry, clientInfo: ClientInfo, all: boo
295295
let count = 0;
296296
const runningSessions = new Set<string>();
297297
const entries = registry.entryMap();
298-
for (const [workspace, list] of entries) {
299-
if (!all && workspace !== clientInfo.workspaceDir)
298+
const key = clientKey(clientInfo);
299+
for (const [workspaceKey, list] of entries) {
300+
if (!all && workspaceKey !== key)
300301
continue;
301-
count += await gcAndPrintSessions(clientInfo, list.map(entry => new Session(entry)), all ? `${path.relative(process.cwd(), workspace) || '/'}:` : undefined, runningSessions);
302+
count += await gcAndPrintSessions(clientInfo, list.map(entry => new Session(entry)), all ? `${path.relative(process.cwd(), workspaceKey) || '/'}:` : undefined, runningSessions);
302303
}
303304

304305
// Filter out server entries that already have an attached session.
305306
const serverEntries = await serverRegistry.list();
306307
const filteredServerEntries = new Map<string, BrowserStatus[]>();
307-
for (const [workspace, list] of serverEntries) {
308-
if (!all && workspace !== clientInfo.workspaceDir)
308+
for (const [workspaceKey, list] of serverEntries) {
309+
if (!all && workspaceKey !== key)
309310
continue;
310311
const unattached = list.filter(d => !runningSessions.has(d.title));
311312
if (unattached.length)
312-
filteredServerEntries.set(workspace, unattached);
313+
filteredServerEntries.set(workspaceKey, unattached);
313314
}
314315

315316
if (filteredServerEntries.size) {
316317
if (count)
317318
console.log('');
318319
console.log('### Browser servers available for attach');
319320
}
320-
for (const [workspace, list] of filteredServerEntries)
321-
count += await gcAndPrintBrowserSessions(workspace, list);
321+
for (const [workspaceKey, list] of filteredServerEntries)
322+
count += await gcAndPrintBrowserSessions(workspaceKey, list);
322323

323324
if (!count)
324325
console.log(' (no browsers)');

packages/playwright-core/src/tools/cli-client/registry.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ export type ClientInfo = {
2828
workspaceDir: string | undefined;
2929
};
3030

31+
export function clientKey(clientInfo: ClientInfo): string {
32+
return clientInfo.workspaceDir || clientInfo.workspaceDirHash;
33+
}
34+
3135
export type SessionConfig = {
3236
name: string;
3337
version: string;
@@ -58,14 +62,13 @@ export class Registry {
5862
}
5963

6064
entry(clientInfo: ClientInfo, sessionName: string): SessionFile | undefined {
61-
const key = clientInfo.workspaceDir || clientInfo.workspaceDirHash;
65+
const key = clientKey(clientInfo);
6266
const entries = this._files.get(key) || [];
6367
return entries.find(entry => entry.config.name === sessionName);
6468
}
6569

6670
entries(clientInfo: ClientInfo): SessionFile[] {
67-
const key = clientInfo.workspaceDir || clientInfo.workspaceDirHash;
68-
return this._files.get(key) || [];
71+
return this._files.get(clientKey(clientInfo)) || [];
6972
}
7073

7174
entryMap(): Map<string, SessionFile[]> {
@@ -77,7 +80,7 @@ export class Registry {
7780
if (!entry)
7881
throw new Error(`Could not start the session "${sessionName}"`);
7982

80-
const key = clientInfo.workspaceDir || clientInfo.workspaceDirHash;
83+
const key = clientKey(clientInfo);
8184
let list = this._files.get(key);
8285
if (!list) {
8386
list = [];

tests/mcp/cli-session.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
import fs from 'fs';
18+
import os from 'os';
1819
import path from 'path';
1920
import { test, expect, daemonFolder } from './cli-fixtures';
2021
import { killProcessGroup } from '../config/commonFixtures';
@@ -32,6 +33,21 @@ test('list', async ({ cli, server }) => {
3233
expect(listOutput).toContain('- default:');
3334
});
3435

36+
test('list shows sessions when cwd has no .playwright directory', async ({ cli, server }) => {
37+
// Temp dir must have no .playwright ancestor so findWorkspaceDir returns undefined
38+
// and the registry key falls back to workspaceDirHash.
39+
const tmpDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'pw-no-workspace-'));
40+
try {
41+
await cli('open', server.HELLO_WORLD, { cwd: tmpDir });
42+
43+
const { output } = await cli('list', { cwd: tmpDir });
44+
expect(output).toContain('### Browsers');
45+
expect(output).toContain('- default:');
46+
} finally {
47+
await fs.promises.rm(tmpDir, { recursive: true, force: true }).catch(() => {});
48+
}
49+
});
50+
3551
test('close', async ({ cli, server }) => {
3652
await cli('open', server.HELLO_WORLD);
3753

0 commit comments

Comments
 (0)