Skip to content

Commit 50d07d7

Browse files
Ek03anshEkanshMS03
andauthored
[@azure/playwright] Add sourceType option for browser session attribution (#38693)
### Packages impacted by this PR @azure/playwright ### Issues associated with this PR None. ### Describe the problem that is addressed by this PR Today, `@azure/playwright` always sends `sourceType=PlaywrightWorkspacesTestRun` on the remote browser WebSocket URL. The service accepts other `sourceType` values for attributing browser sessions to the tool that initiated them, but there is no way for callers to opt in. This PR adds a public `sourceType` option to `createAzurePlaywrightConfig` and `getConnectOptions`, so callers can choose how their sessions are attributed. ### What are the possible designs available to address the problem? If there are more than one possible design, why was the one in this PR chosen? **1. Strict typed union (chosen).** `sourceType?: BrowserSessionSourceTypeValue` where the union exposes only the customer-facing values (`PlaywrightWorkspacesTestRun`, `Others`). Typos are caught at compile time. Default keeps existing behaviour. **2. Widened union (`BrowserSessionSourceTypeValue | (string & {})`).** Would allow any string at compile time. Rejected because it makes the public contract dishonest: customers could type any value, get no IDE warning, and only see an HTTP 400 at runtime. **3. Expose all service-side values publicly.** Would advertise internal product names. Rejected as out of scope for a public type. ### Are there test cases added in this PR? _(If not, why?)_ Yes: - `test/utils/utils.spec.ts` -- `getServiceWSEndpoint` with and without `sourceType` arg. - `test/common/playwrightServiceConfig.spec.ts` -- default field value and `setOptions` override. - `test/core/playwrightService.spec.ts` -- end-to-end plumb-through via `createAzurePlaywrightConfig`, asserting the final `wsEndpoint` contains the chosen `sourceType` and not the default. All existing tests that assert `sourceType=PlaywrightWorkspacesTestRun` in the URL continue to pass since that remains the default. ### Provide a list of related PRs _(if any)_ None. ### Command used to generate this PR:**_(Applicable only to SDK release request PRs)_ N/A -- this is a feature PR, not a generated release PR. ### Checklists - [x] Added impacted package name to the issue description - [x] Does this PR needs any fixes in the SDK Generator? -- No, hand-authored. - [x] Added a changelog (if necessary) ### Summary of changes **Public surface (additive, non-breaking):** - `sourceType?: BrowserSessionSourceTypeValue` field on `PlaywrightServiceAdditionalOptions` - `BrowserSessionSourceTypeValue` exported type resolving to `"PlaywrightWorkspacesTestRun" | "Others"` **Behaviour:** - Default value is `PlaywrightWorkspacesTestRun` -- existing callers see no change. - Honoured by both `createAzurePlaywrightConfig` and `getConnectOptions` via the shared `PlaywrightServiceConfig` singleton. - `getServiceWSEndpoint` gains a fourth `sourceType` parameter with a default that preserves backward compatibility for in-tree callers. **Samples:** - `customising-service-parameters` (TS + JS) now lists `sourceType`. Co-authored-by: Ekansh Lavania <ekanshlnu@microsoft.com>
1 parent 472d931 commit 50d07d7

13 files changed

Lines changed: 116 additions & 5 deletions

File tree

sdk/loadtesting/playwright/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44

55
### Features Added
66

7+
- Added a `sourceType` option to `createAzurePlaywrightConfig` and `getConnectOptions`
8+
that sets the `sourceType` query parameter on the remote browser WebSocket
9+
endpoint. Supported values are `PlaywrightWorkspacesTestRun` (default) and
10+
`Others`. Defaults remain unchanged for existing callers.
11+
712
### Breaking Changes
813

914
### Bugs Fixed

sdk/loadtesting/playwright/review/playwright-node.api.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ export type BrowserConnectOptions = EndpointOptions & {
1616
options: ConnectOptions;
1717
};
1818

19+
// @public
20+
export type BrowserSessionSourceTypeValue = "PlaywrightWorkspacesTestRun" | "Others";
21+
1922
// @public
2023
export const createAzurePlaywrightConfig: (baseConfig: PlaywrightTestConfig, options?: PlaywrightServiceAdditionalOptions) => PlaywrightTestConfig;
2124

@@ -42,6 +45,7 @@ export type PlaywrightServiceAdditionalOptions = {
4245
credential?: TokenCredential;
4346
runName?: string;
4447
apiVersion?: "2025-09-01";
48+
sourceType?: BrowserSessionSourceTypeValue;
4549
};
4650

4751
// @public

sdk/loadtesting/playwright/samples/v1/javascript/customising-service-parameters/playwright.service.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const playwrightServiceAdditionalOptions = {
1616
useCloudHostedBrowsers: true, // Use cloud hosted browsers
1717
credential: azureCredential, // Custom token credential for Entra ID authentication
1818
runName: "JavaScript V1 - Sample Run", // Run name for the test run
19+
sourceType: "PlaywrightWorkspacesTestRun", // Identifies the tool that initiated the remote browser sessions
1920
};
2021

2122
export default defineConfig(

sdk/loadtesting/playwright/samples/v1/typescript/customising-service-parameters/playwright.service.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const playwrightServiceAdditionalOptions: PlaywrightServiceAdditionalOptions = {
2424
useCloudHostedBrowsers: true, // Use cloud hosted browsers
2525
credential: azureCredential, // Custom token credential for Entra ID authentication
2626
runName: "Typescript V1 - Sample Run", // Run name for the test run
27+
sourceType: "PlaywrightWorkspacesTestRun", // Identifies the tool that initiated the remote browser sessions
2728
};
2829

2930
export default defineConfig(

sdk/loadtesting/playwright/src/common/constants.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ export const UploadConstants = {
115115

116116
export const BrowserSessionSourceType = {
117117
PLAYWRIGHT_WORKSPACES_TEST_RUN: "PlaywrightWorkspacesTestRun",
118-
};
118+
OTHERS: "Others",
119+
} as const;
119120

120121
export const StorageUriValidationConstants = {
121122
AllowedProtocol: "https:",

sdk/loadtesting/playwright/src/common/playwrightServiceConfig.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@
22
// Licensed under the MIT License.
33

44
import {
5+
BrowserSessionSourceType,
56
Constants,
67
DefaultConnectOptionsConstants,
78
InternalEnvironmentVariables,
89
ServiceAuth,
910
} from "./constants.js";
10-
import type { PlaywrightServiceAdditionalOptions, OsType } from "./types.js";
11+
import type {
12+
BrowserSessionSourceTypeValue,
13+
PlaywrightServiceAdditionalOptions,
14+
OsType,
15+
} from "./types.js";
1116
import type { TokenCredential } from "@azure/identity";
1217
import { getAndSetRunId, getRunName, ValidateRunID } from "../utils/utils.js";
1318
import { CIInfoProvider } from "../utils/cIInfoProvider.js";
@@ -22,6 +27,7 @@ class PlaywrightServiceConfig {
2227
public exposeNetwork: string;
2328
public runName: string;
2429
public apiVersion: string;
30+
public sourceType: BrowserSessionSourceTypeValue;
2531
private _serviceAuthType: string = ServiceAuth.ENTRA_ID;
2632
public credential?: TokenCredential;
2733

@@ -35,6 +41,7 @@ class PlaywrightServiceConfig {
3541
this.exposeNetwork = DefaultConnectOptionsConstants.DEFAULT_EXPOSE_NETWORK;
3642
this.apiVersion =
3743
process.env[InternalEnvironmentVariables.MPT_API_VERSION] || Constants.LatestAPIVersion;
44+
this.sourceType = BrowserSessionSourceType.PLAYWRIGHT_WORKSPACES_TEST_RUN;
3845
}
3946

4047
public static get instance(): PlaywrightServiceConfig {
@@ -116,6 +123,9 @@ class PlaywrightServiceConfig {
116123
if (options?.credential) {
117124
this.credential = options.credential;
118125
}
126+
if (options?.sourceType) {
127+
this.sourceType = options.sourceType;
128+
}
119129
};
120130
}
121131

sdk/loadtesting/playwright/src/common/types.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,25 @@ export type PlaywrightServiceAdditionalOptions = {
145145
* @defaultValue `2025-09-01`
146146
*/
147147
apiVersion?: "2025-09-01";
148+
149+
/**
150+
* @public
151+
*
152+
* Identifies the tool that initiated remote browser sessions, sent to the
153+
* service as the `sourceType` query parameter on the WebSocket endpoint.
154+
*
155+
* @defaultValue `PlaywrightWorkspacesTestRun`
156+
*/
157+
sourceType?: BrowserSessionSourceTypeValue;
148158
};
149159

160+
/**
161+
* @public
162+
*
163+
* Source identifier values accepted by Azure Playwright for the `sourceType` option.
164+
*/
165+
export type BrowserSessionSourceTypeValue = "PlaywrightWorkspacesTestRun" | "Others";
166+
150167
/**
151168
* @public
152169
*

sdk/loadtesting/playwright/src/core/playwrightService.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ const createAzurePlaywrightConfig = (
174174
playwrightServiceConfig.runId,
175175
playwrightServiceConfig.serviceOs,
176176
playwrightServiceConfig.apiVersion,
177+
playwrightServiceConfig.sourceType,
177178
),
178179
headers: {
179180
Authorization: `Bearer ${getAccessToken()}`,
@@ -249,6 +250,7 @@ const getConnectOptions = async (
249250
playwrightServiceConfig.runId,
250251
playwrightServiceConfig.serviceOs,
251252
playwrightServiceConfig.apiVersion,
253+
playwrightServiceConfig.sourceType,
252254
),
253255
options: {
254256
headers: {

sdk/loadtesting/playwright/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type {
1212
OsType,
1313
AuthenticationType,
1414
BrowserConnectOptions,
15+
BrowserSessionSourceTypeValue,
1516
EndpointOptions,
1617
PlaywrightServiceAdditionalOptions,
1718
} from "./common/types.js";
@@ -26,6 +27,7 @@ export {
2627
type OsType,
2728
type AuthenticationType,
2829
type BrowserConnectOptions,
30+
type BrowserSessionSourceTypeValue,
2931
type EndpointOptions,
3032
type PlaywrightServiceAdditionalOptions,
3133
};

sdk/loadtesting/playwright/src/utils/utils.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4-
import type { AccessTokenClaims, VersionInfo, JwtPayload, RunConfig } from "../common/types.js";
4+
import type {
5+
AccessTokenClaims,
6+
BrowserSessionSourceTypeValue,
7+
VersionInfo,
8+
JwtPayload,
9+
RunConfig,
10+
} from "../common/types.js";
511
import {
612
Constants,
713
InternalEnvironmentVariables,
@@ -129,8 +135,13 @@ export const getAndSetRunId = (): string => {
129135
return runId;
130136
};
131137

132-
export const getServiceWSEndpoint = (runId: string, os: string, apiVersion: string): string => {
133-
return `${getServiceBaseURL()}?runId=${encodeURIComponent(runId)}&os=${os}&sourceType=${BrowserSessionSourceType.PLAYWRIGHT_WORKSPACES_TEST_RUN}&api-version=${apiVersion}`;
138+
export const getServiceWSEndpoint = (
139+
runId: string,
140+
os: string,
141+
apiVersion: string,
142+
sourceType: BrowserSessionSourceTypeValue = BrowserSessionSourceType.PLAYWRIGHT_WORKSPACES_TEST_RUN,
143+
): string => {
144+
return `${getServiceBaseURL()}?runId=${encodeURIComponent(runId)}&os=${os}&sourceType=${encodeURIComponent(sourceType)}&api-version=${apiVersion}`;
134145
};
135146

136147
export const validateServiceUrl = (): void => {

0 commit comments

Comments
 (0)