Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/playwright-core/src/serverRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ class ServerRegistry extends EventEmitter {
}

private _browsersDir() {
return process.env.PLAYWRIGHT_SERVER_REGISTRY || registryDirectory;
return process.env.PWTEST_SERVER_REGISTRY || registryDirectory;
}

private _startWatcher() {
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/tools/cli-client/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ export class Registry {
}

export const baseDaemonDir = (() => {
if (process.env.PLAYWRIGHT_DAEMON_SESSION_DIR)
return process.env.PLAYWRIGHT_DAEMON_SESSION_DIR;
if (process.env.PWTEST_DAEMON_SESSION_DIR)
return process.env.PWTEST_DAEMON_SESSION_DIR;

let localCacheDir: string | undefined;
if (process.platform === 'linux')
Expand Down
10 changes: 0 additions & 10 deletions packages/playwright/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,16 +186,6 @@ export function expectTypes(receiver: any, types: ('APIResponse' | 'Page' | 'Loc

export const windowsFilesystemFriendlyLength = 60;

export function trimLongString(s: string, length = 100) {
if (s.length <= length)
return s;
const hash = calculateSha1(s);
const middle = `-${hash.substring(0, 5)}-`;
const start = Math.floor((length - middle.length) / 2);
const end = length - middle.length - start;
return s.substring(0, start) + middle + s.slice(-end);
}

export function addSuffixToFilePath(filePath: string, suffix: string): string {
const ext = path.extname(filePath);
const base = filePath.substring(0, filePath.length - ext.length);
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright/src/worker/testInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ import { captureRawStack, stringifyStackFrames } from '@isomorphic/stackTrace';
import { escapeWithQuotes } from '@isomorphic/stringUtils';
import { monotonicTime } from '@isomorphic/time';
import { createGuid } from '@utils/crypto';
import { sanitizeForFilePath } from '@utils/fileUtils';
import { sanitizeForFilePath, trimLongString } from '@utils/fileUtils';
import { currentZone } from '@utils/zones';

import { TimeoutManager, TimeoutManagerError } from './timeoutManager';
import { addSuffixToFilePath, filteredStackTrace, getContainedPath, normalizeAndSaveAttachment, sanitizeFilePathBeforeExtension, trimLongString, windowsFilesystemFriendlyLength } from '../util';
import { addSuffixToFilePath, filteredStackTrace, getContainedPath, normalizeAndSaveAttachment, sanitizeFilePathBeforeExtension, windowsFilesystemFriendlyLength } from '../util';
import { TestTracing } from './testTracing';
import { testInfoError } from './util';
import { ipc, transform } from '../common';
Expand Down
24 changes: 21 additions & 3 deletions packages/utils/fileUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ export function sanitizeForFilePath(s: string) {
return s.replace(/[\x00-\x2C\x2E-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]+/g, '-');
}

export function trimLongString(s: string, length = 100) {
if (s.length <= length)
return s;
const hash = calculateSha1(s);
const middle = `-${hash.substring(0, 5)}-`;
const start = Math.floor((length - middle.length) / 2);
const end = length - middle.length - start;
return s.substring(0, start) + middle + s.slice(-end);
}

export function isPathInside(root: string, candidate: string): boolean {
const resolvedRoot = path.resolve(root);
const resolvedCandidate = path.resolve(candidate);
Expand All @@ -104,16 +114,24 @@ export function toPosixPath(aPath: string): string {
return aPath.split(path.sep).join(path.posix.sep);
}

// macOS sun_path is 104 bytes (Linux is 108) including the NUL terminator. Use the lower bound.
const UNIX_SOCKET_PATH_MAX = 103;

export function makeSocketPath(domain: string, name: string): string {
const userNameHash = calculateSha1(process.env.USERNAME || process.env.USER || 'default').slice(0, 8);
if (process.platform === 'win32') {
const socketsDir = process.env.PLAYWRIGHT_SOCKETS_DIR;
const socketsDir = process.env.PWTEST_SOCKETS_DIR;
const suffix = socketsDir ? `-${calculateSha1(socketsDir).slice(0, 8)}` : '';
return `\\\\.\\pipe\\pw-${userNameHash}-${domain}-${name}${suffix}`;
}
const baseDir = process.env.PLAYWRIGHT_SOCKETS_DIR || path.join(os.tmpdir(), `pw-${userNameHash}`);
const baseDir = process.env.PWTEST_SOCKETS_DIR || path.join(os.tmpdir(), `pw-${userNameHash}`);
const dir = path.join(baseDir, domain);
const result = path.join(dir, `${name}.sock`);
const suffix = '.sock';
const maxNameLength = UNIX_SOCKET_PATH_MAX - dir.length - path.sep.length - suffix.length;
if (maxNameLength < 1)
throw new Error(`Socket directory path is too long (${dir.length} chars); set PWTEST_SOCKETS_DIR to a shorter location.`);
const fsFriendlyName = trimLongString(sanitizeForFilePath(name), maxNameLength);
const result = path.join(dir, `${fsFriendlyName}${suffix}`);
fs.mkdirSync(dir, { recursive: true });
return result;
}
6 changes: 3 additions & 3 deletions tests/extension/extension-fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,11 @@ export const testWithOldExtensionVersion = test.extend({

function cliEnv() {
return {
PLAYWRIGHT_SERVER_REGISTRY: test.info().outputPath('registry'),
PLAYWRIGHT_DAEMON_SESSION_DIR: test.info().outputPath('daemon'),
PWTEST_SERVER_REGISTRY: test.info().outputPath('registry'),
PWTEST_DAEMON_SESSION_DIR: test.info().outputPath('daemon'),
// Short path because macOS caps unix socket paths at 104 chars; the
// long `project.outputDir` path overflows and causes EADDRINUSE.
PLAYWRIGHT_SOCKETS_DIR: path.join(os.tmpdir(), 'pwmcp-sock', String(test.info().parallelIndex)),
PWTEST_SOCKETS_DIR: path.join(os.tmpdir(), 'pwmcp-sock', String(test.info().parallelIndex)),
};
}

Expand Down
4 changes: 2 additions & 2 deletions tests/library/browser-server.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ import { browserTest as it, expect } from '../config/browserTest';
it.skip(({ mode }) => mode !== 'default');

it.beforeEach(({}, testInfo) => {
process.env.PLAYWRIGHT_SERVER_REGISTRY = testInfo.outputPath('registry');
process.env.PWTEST_SERVER_REGISTRY = testInfo.outputPath('registry');
});

it('should start and stop pipe server', async ({ browserType, browser }) => {
const serverInfo = await browser.bind('default', {});
expect(serverInfo).toEqual(expect.objectContaining({
endpoint: expect.stringMatching(/browser@/),
endpoint: expect.stringMatching(/browser-/),
}));

const browser2 = await browserType.connect(serverInfo.endpoint);
Expand Down
6 changes: 3 additions & 3 deletions tests/mcp/cli-fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,10 @@ export const test = baseTest.extend<{

function cliEnv() {
return {
PLAYWRIGHT_SERVER_REGISTRY: test.info().outputPath('registry'),
PWTEST_SERVER_REGISTRY: test.info().outputPath('registry'),
PWTEST_DASHBOARD_SETTINGS_FILE: test.info().outputPath('dashboard.settings.json'),
PLAYWRIGHT_DAEMON_SESSION_DIR: test.info().outputPath('daemon'),
PLAYWRIGHT_SOCKETS_DIR: path.join(os.tmpdir(), 'ds-' + crypto.createHash('sha1').update(test.info().outputDir).digest('hex').slice(0, 16)),
PWTEST_DAEMON_SESSION_DIR: test.info().outputPath('daemon'),
PWTEST_SOCKETS_DIR: path.join(os.tmpdir(), 'ds-' + crypto.createHash('sha1').update(test.info().outputDir).digest('hex').slice(0, 16)),
PWTEST_CLI_CHANNEL_SCAN_DISABLED_FOR_TEST: '1',
};
}
Expand Down
9 changes: 9 additions & 0 deletions tests/mcp/cli-misc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,12 @@ test('install handles browser detection', async ({ cli }) => {
if (foundMatch?.[1] !== 'chrome')
expect(output).toContain(`Created default config for ${foundMatch?.[1] ?? 'chromium'}.`);
});

test('open with very long session name (issue 40878)', async ({ cli, server }) => {
// Long session names push the unix socket path past sun_path's 104-byte limit on macOS.
const longSessionName = 'awesome-coding-agent-orchestrators-with-an-overlong-suffix-for-testing';
const result = await cli(`-s=${longSessionName}`, 'open', server.PREFIX);
expect(result.error).toBe('');
expect(result.exitCode).toBe(0);
expect(result.output).toContain('Page URL');
});
2 changes: 1 addition & 1 deletion tests/mcp/cli-session.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ test('older client with newer daemon - list shows incompatible warning', async (
test.describe('browser server', () => {
test.beforeEach(async ({ mcpBrowser }, testInfo) => {
test.skip(!['chrome', 'chromium', 'webkit', 'firefox'].includes(mcpBrowser));
process.env.PLAYWRIGHT_SERVER_REGISTRY = testInfo.outputPath('registry');
process.env.PWTEST_SERVER_REGISTRY = testInfo.outputPath('registry');
});

test('list browser servers', async ({ cli, mcpBrowser }) => {
Expand Down
2 changes: 1 addition & 1 deletion tests/mcp/dashboard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function displayPath(p: string): string {
}

test.beforeEach(({}, testInfo) => {
process.env.PLAYWRIGHT_SERVER_REGISTRY = testInfo.outputPath('registry');
process.env.PWTEST_SERVER_REGISTRY = testInfo.outputPath('registry');
});

test('should show browser session chip', async ({ cli, server, startDashboardServer }) => {
Expand Down
Loading