Azure Playwright Workspaces SDK for TypeScript
Run Playwright tests at scale with cloud-hosted browsers and integrated Azure portal reporting.
Migration Notice: @azure/microsoft-playwright-testing is retired on March 8, 2026. Use @azure/playwright instead. See migration guide.
Installation
Recommended: Auto-generates config
npm init @azure/playwright@latest
Manual installation
npm install @azure/playwright --save-dev npm install @playwright/test@^1.47 --save-dev npm install @azure/identity --save-dev
Requirements:
-
Playwright version 1.47+ (basic usage)
-
Playwright version 1.57+ (Azure reporter features)
Environment Variables
PLAYWRIGHT_SERVICE_URL=wss://eastus.api.playwright.microsoft.com/playwrightworkspaces/{workspace-id}/browsers
Authentication
Microsoft Entra ID (Recommended)
Sign in with Azure CLI
az login
// playwright.service.config.ts import { defineConfig } from "@playwright/test"; import { createAzurePlaywrightConfig, ServiceOS } from "@azure/playwright"; import { DefaultAzureCredential } from "@azure/identity"; import config from "./playwright.config";
export default defineConfig( config, createAzurePlaywrightConfig(config, { os: ServiceOS.LINUX, credential: new DefaultAzureCredential(), }) );
Custom Credential
import { ManagedIdentityCredential } from "@azure/identity"; import { createAzurePlaywrightConfig } from "@azure/playwright";
export default defineConfig( config, createAzurePlaywrightConfig(config, { credential: new ManagedIdentityCredential(), }) );
Core Workflow
Service Configuration
// playwright.service.config.ts import { defineConfig } from "@playwright/test"; import { createAzurePlaywrightConfig, ServiceOS } from "@azure/playwright"; import { DefaultAzureCredential } from "@azure/identity"; import config from "./playwright.config";
export default defineConfig( config, createAzurePlaywrightConfig(config, { os: ServiceOS.LINUX, connectTimeout: 30000, exposeNetwork: "<loopback>", credential: new DefaultAzureCredential(), }) );
Run Tests
npx playwright test --config=playwright.service.config.ts --workers=20
With Azure Reporter
import { defineConfig } from "@playwright/test"; import { createAzurePlaywrightConfig, ServiceOS } from "@azure/playwright"; import { DefaultAzureCredential } from "@azure/identity"; import config from "./playwright.config";
export default defineConfig( config, createAzurePlaywrightConfig(config, { os: ServiceOS.LINUX, credential: new DefaultAzureCredential(), }), { reporter: [ ["html", { open: "never" }], ["@azure/playwright/reporter"], ], } );
Manual Browser Connection
import playwright, { test, expect, BrowserType } from "@playwright/test"; import { getConnectOptions } from "@azure/playwright";
test("manual connection", async ({ browserName }) => { const { wsEndpoint, options } = await getConnectOptions(); const browser = await (playwright[browserName] as BrowserType).connect(wsEndpoint, options); const context = await browser.newContext(); const page = await context.newPage();
await page.goto("https://example.com"); await expect(page).toHaveTitle(/Example/);
await browser.close(); });
Configuration Options
type PlaywrightServiceAdditionalOptions = { serviceAuthType?: "ENTRA_ID" | "ACCESS_TOKEN"; // Default: ENTRA_ID os?: "linux" | "windows"; // Default: linux runName?: string; // Custom run name for portal connectTimeout?: number; // Default: 30000ms exposeNetwork?: string; // Default: <loopback> credential?: TokenCredential; // REQUIRED for Entra ID };
ServiceOS Enum
import { ServiceOS } from "@azure/playwright";
// Available values ServiceOS.LINUX // "linux" - default ServiceOS.WINDOWS // "windows"
ServiceAuth Enum
import { ServiceAuth } from "@azure/playwright";
// Available values ServiceAuth.ENTRA_ID // Recommended - uses credential ServiceAuth.ACCESS_TOKEN // Use PLAYWRIGHT_SERVICE_ACCESS_TOKEN env var
CI/CD Integration
GitHub Actions
name: playwright-ts on: [push, pull_request]
permissions: id-token: write contents: read
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Azure Login
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- run: npm ci
- name: Run Tests
env:
PLAYWRIGHT_SERVICE_URL: ${{ secrets.PLAYWRIGHT_SERVICE_URL }}
run: npx playwright test -c playwright.service.config.ts --workers=20
Azure Pipelines
- task: AzureCLI@2 displayName: Run Playwright Tests env: PLAYWRIGHT_SERVICE_URL: $(PLAYWRIGHT_SERVICE_URL) inputs: azureSubscription: My_Service_Connection scriptType: pscore inlineScript: | npx playwright test -c playwright.service.config.ts --workers=20 addSpnToEnvironment: true
Key Types
import { createAzurePlaywrightConfig, getConnectOptions, ServiceOS, ServiceAuth, ServiceEnvironmentVariable, } from "@azure/playwright";
import type { OsType, AuthenticationType, BrowserConnectOptions, PlaywrightServiceAdditionalOptions, } from "@azure/playwright";
Migration from Old Package
Old (@azure/microsoft-playwright-testing ) New (@azure/playwright )
getServiceConfig()
createAzurePlaywrightConfig()
timeout option connectTimeout option
runId option runName option
useCloudHostedBrowsers option Removed (always enabled)
@azure/microsoft-playwright-testing/reporter
@azure/playwright/reporter
Implicit credential Explicit credential parameter
Before (Old)
import { getServiceConfig, ServiceOS } from "@azure/microsoft-playwright-testing";
export default defineConfig( config, getServiceConfig(config, { os: ServiceOS.LINUX, timeout: 30000, useCloudHostedBrowsers: true, }), { reporter: [["@azure/microsoft-playwright-testing/reporter"]], } );
After (New)
import { createAzurePlaywrightConfig, ServiceOS } from "@azure/playwright"; import { DefaultAzureCredential } from "@azure/identity";
export default defineConfig( config, createAzurePlaywrightConfig(config, { os: ServiceOS.LINUX, connectTimeout: 30000, credential: new DefaultAzureCredential(), }), { reporter: [ ["html", { open: "never" }], ["@azure/playwright/reporter"], ], } );
Best Practices
-
Use Entra ID auth — More secure than access tokens
-
Provide explicit credential — Always pass credential: new DefaultAzureCredential()
-
Enable artifacts — Set trace: "on-first-retry" , video: "retain-on-failure" in config
-
Scale workers — Use --workers=20 or higher for parallel execution
-
Region selection — Choose region closest to your test targets
-
HTML reporter first — When using Azure reporter, list HTML reporter before Azure reporter