Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Run Playwright tests at scale using Azure Playwright Workspaces (formerly Microsoft Playwright Testing). Use when scaling browser tests across cloud-hosted browsers, integrating with CI/CD pipelines, or publishing test results to the Azure portal.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-14 | ✗→✓ | ▲ Improved | 26% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 68% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 91% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 76% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 186% | 0% |
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.
bash# 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:
bashPLAYWRIGHT_SERVICE_URL=wss://eastus.api.playwright.microsoft.com/playwrightworkspaces/{workspace-id}/browsers AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production
bash# Sign in with Azure CLI az login
typescript// playwright.service.config.ts import { defineConfig } from "@playwright/test"; import { createAzurePlaywrightConfig, ServiceOS } from "@azure/playwright"; import { DefaultAzureCredential, ManagedIdentityCredential } from "@azure/identity"; import config from "./playwright.config"; // Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential> const credential = new DefaultAzureCredential({requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"]}); // Or use a specific credential directly in production: // See https://learn.microsoft.com/javascript/api/overview/azure/identity-readme?view=azure-node-latest#credential-classes // const credential = new ManagedIdentityCredential(); export default defineConfig( config, createAzurePlaywrightConfig(config, { os: ServiceOS.LINUX, credential, }) );
typescriptimport { ManagedIdentityCredential } from "@azure/identity"; import { createAzurePlaywrightConfig } from "@azure/playwright"; export default defineConfig( config, createAzurePlaywrightConfig(config, { credential: new ManagedIdentityCredential(), }) );
typescript// 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({requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"]}), }) );
bashnpx playwright test --config=playwright.service.config.ts --workers=20
typescriptimport { 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({requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"]}), }), { reporter: [ ["html", { open: "never" }], ["@azure/playwright/reporter"], ], } );
typescriptimport 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(); });
typescripttype 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 };
typescriptimport { ServiceOS } from "@azure/playwright"; // Available values ServiceOS.LINUX // "linux" - default ServiceOS.WINDOWS // "windows"
typescriptimport { ServiceAuth } from "@azure/playwright"; // Available values ServiceAuth.ENTRA_ID // Recommended - uses credential ServiceAuth.ACCESS_TOKEN // Use PLAYWRIGHT_SERVICE_ACCESS_TOKEN env var
yamlname: 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
yaml- 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
typescriptimport { createAzurePlaywrightConfig, getConnectOptions, ServiceOS, ServiceAuth, ServiceEnvironmentVariable, } from "@azure/playwright"; import type { OsType, AuthenticationType, BrowserConnectOptions, PlaywrightServiceAdditionalOptions, } from "@azure/playwright";
| 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 |
typescriptimport { 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"]], } );
typescriptimport { createAzurePlaywrightConfig, ServiceOS } from "@azure/playwright"; import { DefaultAzureCredential } from "@azure/identity"; export default defineConfig( config, createAzurePlaywrightConfig(config, { os: ServiceOS.LINUX, connectTimeout: 30000, credential: new DefaultAzureCredential({requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"]}), }), { reporter: [ ["html", { open: "never" }], ["@azure/playwright/reporter"], ], } );
DefaultAzureCredential for local development; use ManagedIdentityCredential or WorkloadIdentityCredential for productiontrace: "on-first-retry", video: "retain-on-failure" in config--workers=20 or higher for parallel executionOther measured skills in the registry, with their headline benchmark lift.