Skip to content

Commit 43fd8c1

Browse files
committed
feat: enhance HttpServer and utilities; introduce EXTENSION_INSTALLED_FILENAME constant and improve browser name validation
1 parent f1af26e commit 43fd8c1

6 files changed

Lines changed: 31 additions & 13 deletions

File tree

apps/playwright-browser-tunnel/src/HttpServer.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import http from 'node:http';
66
import { WebSocketServer, type WebSocket, type AddressInfo } from 'ws';
77

88
import type { ITerminal } from '@rushstack/terminal';
9+
10+
const LOCALHOST_IP: string = '127.0.0.1';
11+
912
/**
1013
* This HttpServer is used for the localProxyWs WebSocketServer.
1114
* The purpose is to parse the query params and path for the websocket url to get the
@@ -34,10 +37,12 @@ export class HttpServer {
3437

3538
public listen(): Promise<void> {
3639
return new Promise((resolve) => {
37-
this._server.listen(0, '127.0.0.1', () => {
40+
this._server.listen(0, LOCALHOST_IP, () => {
3841
this._listeningPort = (this._server.address() as AddressInfo).port;
3942
// This MUST be printed to terminal so VS Code can auto-port forward
40-
this._logger.writeLine(`Local proxy HttpServer listening at ws://127.0.0.1:${this._listeningPort}`);
43+
this._logger.writeLine(
44+
`Local proxy HttpServer listening at ws://${LOCALHOST_IP}:${this._listeningPort}`
45+
);
4146
resolve();
4247
});
4348
});
@@ -47,7 +52,7 @@ export class HttpServer {
4752
if (this._listeningPort === undefined) {
4853
throw new Error('HttpServer not listening yet');
4954
}
50-
return `ws://127.0.0.1:${this._listeningPort}`;
55+
return `ws://${LOCALHOST_IP}:${this._listeningPort}`;
5156
}
5257

5358
public get wsServer(): WebSocketServer {

apps/playwright-browser-tunnel/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ export type {
2424
IDisposableTunneledBrowserConnection,
2525
IDisposableTunneledBrowser
2626
} from './tunneledBrowserConnection';
27-
export { isExtensionInstalledAsync } from './utilities';
27+
export { isExtensionInstalledAsync, EXTENSION_INSTALLED_FILENAME } from './utilities';

apps/playwright-browser-tunnel/src/tunneledBrowserConnection.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import { HttpServer } from './HttpServer';
1313

1414
const { version: playwrightVersion } = playwrightPackageJson;
1515

16+
const SUPPORTED_BROWSER_NAMES: Set<string> = new Set(['chromium', 'firefox', 'webkit']);
17+
1618
interface IHandshake {
1719
action: 'handshake';
1820
browserName: BrowserName;
@@ -156,7 +158,7 @@ export async function tunneledBrowserConnection(
156158
const parsed: URL = new URL(urlString, 'http://localhost');
157159
logger.writeLine(`Local client connected with query params: ${parsed.searchParams.toString()}`);
158160
const bName: string | null = parsed.searchParams.get('browser');
159-
if (bName && ['chromium', 'firefox', 'webkit'].includes(bName)) {
161+
if (bName && SUPPORTED_BROWSER_NAMES.has(bName)) {
160162
browserName = bName as BrowserName;
161163
}
162164
const launchOptionsParam: string | null = parsed.searchParams.get('launchOptions');
@@ -173,7 +175,8 @@ export async function tunneledBrowserConnection(
173175
}
174176

175177
if (!browserName) {
176-
console.error('browser query param required (chromium|firefox|webkit)');
178+
const supportedBrowsersString: string = Array.from(SUPPORTED_BROWSER_NAMES).join('|');
179+
console.error(`browser query param required (${supportedBrowsersString})`);
177180
localWs.close();
178181
return;
179182
}

apps/playwright-browser-tunnel/src/utilities.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ import { tmpdir } from 'node:os';
55

66
import { FileSystem } from '@rushstack/node-core-library';
77

8+
/**
9+
* The filename used to indicate that the Playwright on Codespaces extension is installed.
10+
* @beta
11+
*/
12+
export const EXTENSION_INSTALLED_FILENAME: string = '.playwright-codespaces-extension-installed.txt';
13+
814
/**
915
* Helper to determine if the Playwright on Codespaces extension is installed. This check's for the
1016
* existence of a well-known file in the OS temp directory.
@@ -14,7 +20,7 @@ export async function isExtensionInstalledAsync(): Promise<boolean> {
1420
// Read file from os.tempdir() + '/.playwright-codespaces-extension-installed'
1521
const tempDir: string = tmpdir();
1622

17-
const extensionInstalledFilePath: string = `${tempDir}/.playwright-codespaces-extension-installed.txt`;
23+
const extensionInstalledFilePath: string = `${tempDir}/${EXTENSION_INSTALLED_FILENAME}`;
1824
const doesExist: boolean = FileSystem.exists(extensionInstalledFilePath);
1925

2026
// check if file exists

common/reviews/api/playwright-browser-tunnel.api.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import type { LaunchOptions } from 'playwright-core';
1111
// @beta
1212
export type BrowserName = 'chromium' | 'firefox' | 'webkit';
1313

14+
// @beta
15+
export const EXTENSION_INSTALLED_FILENAME: string;
16+
1417
// @beta
1518
export interface IDisposableTunneledBrowser {
1619
[Symbol.asyncDispose]: () => Promise<void>;

vscode-extensions/playwright-on-codespaces-vscode-extension/src/extension.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
import * as os from 'node:os';
55
import * as path from 'node:path';
66
import * as vscode from 'vscode';
7-
import { PlaywrightTunnel, type TunnelStatus } from '@rushstack/playwright-browser-tunnel';
7+
import {
8+
PlaywrightTunnel,
9+
type TunnelStatus,
10+
EXTENSION_INSTALLED_FILENAME
11+
} from '@rushstack/playwright-browser-tunnel';
812
import { Terminal, type ITerminal, type ITerminalProvider } from '@rushstack/terminal';
913

1014
import { runWorkspaceCommandAsync } from '@rushstack/vscode-shared/lib/runWorkspaceCommandAsync';
@@ -43,15 +47,12 @@ async function writeExtensionInstalledFile(terminal: ITerminal): Promise<void> {
4347
fileUri = vscode.Uri.from({
4448
scheme: workspaceFolder.uri.scheme,
4549
authority: workspaceFolder.uri.authority,
46-
path: `${tempDir}/playwright-codespaces-extension-installed.txt`
50+
path: `${tempDir}/${EXTENSION_INSTALLED_FILENAME}`
4751
});
4852
} else {
4953
// Fallback if no workspace folder
5054
fileUri = vscode.Uri.parse(
51-
`vscode-remote://${vscode.env.remoteName}${path.posix.join(
52-
tempDir,
53-
'.playwright-codespaces-extension-installed.txt'
54-
)}`
55+
`vscode-remote://${vscode.env.remoteName}${path.posix.join(tempDir, EXTENSION_INSTALLED_FILENAME)}`
5556
);
5657
}
5758

0 commit comments

Comments
 (0)