refactor: flatten Microsoft skills from nested to flat directory structure
Rewrote sync_microsoft_skills.py (v4) to use each SKILL.md's frontmatter 'name' field as the flat directory name under skills/, replacing the nested skills/official/microsoft/<lang>/<category>/<service>/ hierarchy. This fixes CI failures caused by the indexing, validation, and catalog scripts expecting skills/<id>/SKILL.md (depth 1). Changes: - Rewrite scripts/sync_microsoft_skills.py for flat output with collision detection - Update scripts/tests/inspect_microsoft_repo.py for flat name mapping - Update scripts/tests/test_comprehensive_coverage.py for name uniqueness checks - Delete skills/official/ nested directory - Add 129 Microsoft skills as flat directories (e.g. skills/azure-mgmt-botservice-dotnet/) - Move attribution files to docs/ (LICENSE-MICROSOFT, microsoft-skills-attribution.json) - Rebuild skills_index.json, CATALOG.md, README.md (845 total skills)
This commit is contained in:
302
skills/azure-microsoft-playwright-testing-ts/SKILL.md
Normal file
302
skills/azure-microsoft-playwright-testing-ts/SKILL.md
Normal file
@@ -0,0 +1,302 @@
|
||||
---
|
||||
name: azure-microsoft-playwright-testing-ts
|
||||
description: 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.
|
||||
package: "@azure/playwright"
|
||||
---
|
||||
|
||||
# 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](https://aka.ms/mpt/migration-guidance).
|
||||
|
||||
## Installation
|
||||
|
||||
```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:**
|
||||
- Playwright version 1.47+ (basic usage)
|
||||
- Playwright version 1.57+ (Azure reporter features)
|
||||
|
||||
## Environment Variables
|
||||
|
||||
```bash
|
||||
PLAYWRIGHT_SERVICE_URL=wss://eastus.api.playwright.microsoft.com/playwrightworkspaces/{workspace-id}/browsers
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
### Microsoft Entra ID (Recommended)
|
||||
|
||||
```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 } from "@azure/identity";
|
||||
import config from "./playwright.config";
|
||||
|
||||
export default defineConfig(
|
||||
config,
|
||||
createAzurePlaywrightConfig(config, {
|
||||
os: ServiceOS.LINUX,
|
||||
credential: new DefaultAzureCredential(),
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
### Custom Credential
|
||||
|
||||
```typescript
|
||||
import { ManagedIdentityCredential } from "@azure/identity";
|
||||
import { createAzurePlaywrightConfig } from "@azure/playwright";
|
||||
|
||||
export default defineConfig(
|
||||
config,
|
||||
createAzurePlaywrightConfig(config, {
|
||||
credential: new ManagedIdentityCredential(),
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
## Core Workflow
|
||||
|
||||
### Service Configuration
|
||||
|
||||
```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(),
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
### Run Tests
|
||||
|
||||
```bash
|
||||
npx playwright test --config=playwright.service.config.ts --workers=20
|
||||
```
|
||||
|
||||
### With Azure Reporter
|
||||
|
||||
```typescript
|
||||
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
|
||||
|
||||
```typescript
|
||||
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
|
||||
|
||||
```typescript
|
||||
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
|
||||
|
||||
```typescript
|
||||
import { ServiceOS } from "@azure/playwright";
|
||||
|
||||
// Available values
|
||||
ServiceOS.LINUX // "linux" - default
|
||||
ServiceOS.WINDOWS // "windows"
|
||||
```
|
||||
|
||||
### ServiceAuth Enum
|
||||
|
||||
```typescript
|
||||
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
|
||||
|
||||
```yaml
|
||||
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
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
## Key Types
|
||||
|
||||
```typescript
|
||||
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)
|
||||
|
||||
```typescript
|
||||
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)
|
||||
|
||||
```typescript
|
||||
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
|
||||
|
||||
1. **Use Entra ID auth** — More secure than access tokens
|
||||
2. **Provide explicit credential** — Always pass `credential: new DefaultAzureCredential()`
|
||||
3. **Enable artifacts** — Set `trace: "on-first-retry"`, `video: "retain-on-failure"` in config
|
||||
4. **Scale workers** — Use `--workers=20` or higher for parallel execution
|
||||
5. **Region selection** — Choose region closest to your test targets
|
||||
6. **HTML reporter first** — When using Azure reporter, list HTML reporter before Azure reporter
|
||||
Reference in New Issue
Block a user