Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This article covers the full local development loop: writing tests in your editor, running them against a live Power Platform environment, and debugging failures by using Playwright's built-in tools. You get AI assistance from Claude Code and GitHub Copilot.
Prerequisites
Before you begin, make sure you have the following tools and access.
- Node.js 18 or later
- VS Code (recommended) or any TypeScript-capable editor
- A Power Platform environment with your app deployed
- Authentication configured - see Authentication guide
Set up your workspace
Follow these steps to clone the repository, install dependencies, and open the project in VS Code.
Clone the repository:
git clone https://github.com/microsoft/power-platform-playwright-samples.git cd power-platform-playwright-samplesInstall dependencies:
node common/scripts/install-run-rush.js installInstall the recommended VS Code extensions:
- Playwright Test for VS Code (
ms-playwright.playwright) - run and debug tests from the sidebar - GitHub Copilot (
GitHub.copilot) - AI test authoring in-editor - ESLint (
dbaeumer.vscode-eslint) - inline linting
- Playwright Test for VS Code (
Open the workspace:
code power-platform-playwright-samples.code-workspace
Write tests
This section covers where to put test files, how to structure them, and how to find the control names you need for selectors.
File naming and location
Place test files in packages/e2e-tests/tests/. Use the naming pattern <feature>.test.ts.
packages/e2e-tests/
└── tests/
└── northwind/
├── canvas/
│ └── canvas-app-crud.test.ts
└── mda/
├── model-driven-crud.test.ts
└── custom-page-crud.test.ts
Basic test structure
Every test file follows the same pattern: import the toolkit, launch the app in beforeEach, and write individual test() blocks with assertions.
import { test, expect } from '@playwright/test';
import {
AppProvider,
AppType,
AppLaunchMode,
buildCanvasAppUrlFromEnv,
} from 'power-platform-playwright-toolkit';
test.describe('Feature name', () => {
test.beforeEach(async ({ page, context }) => {
const app = new AppProvider(page, context);
await app.launch({
app: 'My App',
type: AppType.Canvas,
mode: AppLaunchMode.Play,
skipMakerPortal: true,
directUrl: buildCanvasAppUrlFromEnv(),
});
});
test('should do something', async ({ page }) => {
const canvasFrame = page.frameLocator('iframe[name="fullscreen-app-host"]');
await canvasFrame
.locator('[data-control-part="gallery-item"]')
.first()
.waitFor({ state: 'visible', timeout: 60000 });
// your assertions here
});
});
Find control names in your Power Apps canvas app
To write selectors for canvas controls, you need data-control-name values:
- Open your app in play mode in a browser.
- Press F12 to open DevTools.
- Click the Inspector (Elements) tab.
- Hover over a control - the attribute
data-control-name="Button1"appears.
Alternatively, ask Claude Code or GitHub Copilot to inspect the DOM for you by using the Playwright MCP server.
Run tests
You can run tests from the command line using the Playwright CLI. The following subsections show common options.
Run all tests
To run every test in the project, use the following commands.
cd packages/e2e-tests
npx playwright test
Run a specific file
Pass the file path to run only the tests in that file.
npx playwright test tests/northwind/canvas/canvas-app-crud.test.ts
Run a specific test by name
Use --grep to run only tests whose name matches a pattern.
npx playwright test --grep "should create an account"
Run a specific project (canvas or MDA)
Use --project to target a specific app type defined in your Playwright config.
npx playwright test --project=canvas
npx playwright test --project=mda
Run with the Playwright UI (recommended for local development)
The Playwright UI provides a visual test runner with time-travel debugging:
npx playwright test --ui
Use the UI to:
- See each test listed with pass or fail status
- Click a test to replay it step by step
- View screenshots, traces, and network requests at each step
- Re-run a single test with one click
Run in headed mode
Headed mode opens a visible browser window so you can watch the test interact with the app.
npx playwright test --headed
Headed mode lets you watch the browser as tests execute. It's useful for understanding what the app looks like at each step.
Run with slow motion
Slow motion adds a delay between each Playwright action so you can follow along visually.
npx playwright test --headed --slow-mo=500
Each action is delayed by 500 ms, so you can easily follow the test execution visually.
Debug tests
When a test fails, use these tools to step through the execution, inspect the DOM, and review traces.
Debug with the Playwright Inspector
The Inspector pauses execution and lets you step through actions:
npx playwright test --debug
Or add await page.pause() inside your test at the point where you want to break:
test('should do something', async ({ page }) => {
const canvasFrame = page.frameLocator('iframe[name="fullscreen-app-host"]');
await canvasFrame.locator('[data-control-part="gallery-item"]').first()
.waitFor({ state: 'visible', timeout: 60000 });
await page.pause(); // <-- execution pauses here; Inspector opens
await canvasFrame.locator('[data-control-name="MyButton"]').click();
});
When paused, the Inspector shows:
- The current locator highlighted in the browser
- A locator picker tool to click any element and get its selector
- Step forward and step back controls
Debug in VS Code
The Playwright Test for VS Code extension adds a Testing sidebar (beaker icon). From there you can:
- Click the play button next to any test to run it.
- Click the bug icon to run it in debug mode - VS Code breakpoints work.
- Set a breakpoint on any line of your test, select Debug Test, and VS Code pauses there.
To configure the VS Code debugger manually, add to .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Playwright Test",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/node_modules/.bin/playwright",
"args": ["test", "--project=canvas", "--headed", "--debug"],
"cwd": "${workspaceFolder}/packages/e2e-tests",
"console": "integratedTerminal",
"env": {
"PWDEBUG": "1"
}
}
]
}
Read the HTML report
After a test run, open the HTML report:
npx playwright show-report
The report shows:
- Pass or fail status for each test
- Screenshots captured on failure
- Full trace for each test (if
trace: 'on-first-retry'is set)
Read the trace viewer
Traces are recorded ZIP files that you can use to replay a test execution step by step.
npx playwright show-trace test-results/<test-folder>/trace.zip
Or drag the ZIP file onto trace.playwright.dev.
The trace viewer shows:
- Every Playwright action with timing
- DOM snapshots before and after each action
- Network requests
- Console logs and errors
Tip
Set trace: 'on' in playwright.config.ts during debugging to capture traces for all runs, not just retries.
Write and debug with Claude Code
Claude Code is an AI coding assistant that runs in your terminal with full access to your project files, shell, and browser (via the Playwright MCP server).
Set up Claude Code for this project
Complete these steps to install Claude Code and connect it to the Playwright MCP server.
Install Claude Code:
npm install -g @anthropic-ai/claude-codeCreate
packages/e2e-tests/CLAUDE.mdwith your project conventions. See Custom instructions for AI agents.Add the Playwright MCP server to
~/.claude/settings.json:{ "mcpServers": { "playwright": { "command": "npx", "args": ["@playwright/mcp"] } } }Start Claude Code from the repo root:
claude
Write a new test with Claude Code
In the Claude Code session, describe the test you want:
"Write a Playwright test for the Accounts canvas app. It should open the gallery, click Add, fill in the account name with a unique value, save, then verify the new item appears in the gallery. Put it in
packages/e2e-tests/tests/accounts/accounts.test.ts."
Claude Code reads your CLAUDE.md conventions, writes the test file, and confirms. Review the file before running.
Ask Claude Code to inspect your app
With the Playwright MCP server connected:
"Navigate to
<your-canvas-app-url>. Inspect the DOM insideiframe[name='fullscreen-app-host']and find thedata-control-namevalues for the gallery, the Add button, and the account name input. Then write selectors for each."
Claude Code opens a browser, navigates, inspects the DOM, and returns precise selectors.
Fix a failing test with Claude Code
Paste the test output into Claude Code:
"This test is failing with the following error: [paste error]. Here is the test file: [paste or reference the file]. Diagnose the issue and fix it."
Claude Code reads the file, understands the error, and suggests a fix - often catching problems like wrong selectors, missing waitFor, or data conflicts.
Run tests from Claude Code
Claude Code can run tests directly:
"Run
npx playwright test tests/accounts/accounts.test.ts --headedand tell me if it passes."
Claude Code executes the command, reads the output, and reports results. If the test fails, it can immediately propose a fix.
Write and debug with GitHub Copilot
GitHub Copilot integrates directly into VS Code and JetBrains IDEs, providing inline completions and a chat panel.
Enable Copilot for this project
Complete these steps to activate Copilot and configure project-specific instructions.
- Install the GitHub Copilot extension in VS Code.
- Create
.github/copilot-instructions.mdwith your project conventions - see Custom instructions for AI agents. - Open a test file - Copilot reads existing tests and learns the pattern.
Use inline completions
As you type, Copilot completes test code based on context. Start typing a test() block and press Tab to accept:
test('should filter orders by keyword', async ({ page }) => {
// Copilot suggests: await mda.grid.filterByKeyword('ORD-001');
The more existing tests it can see, the better the suggestions.
Use Copilot Chat to generate tests
Open Copilot Chat (Ctrl+Shift+I) and ask:
"@workspace Write a test that navigates to the Orders model-driven app, filters the grid by 'ORD-001', opens the first record, updates the notes field, saves, and verifies the form is no longer dirty."
Copilot reads your codebase via @workspace and generates a test that matches your existing style.
Fix a failing test with Copilot
Use Copilot Chat to diagnose and fix a test that isn't passing.
Open the failing test file.
Select the failing test function.
Open Copilot Chat and ask:
"Fix this test. It's failing because the gallery selector times out. The gallery takes up to 60 seconds to load Dataverse data."
Copilot updates the waitFor timeout and might suggest other improvements.
Use Copilot to explain an error
Paste the error message into Copilot Chat:
"Explain this Playwright error and how to fix it in the context of a Power Platform canvas app test:
TimeoutError: locator.waitFor: Timeout 30000ms exceeded"
Copilot explains the error and gives specific advice about canvas iframe scoping and timeout settings.
Generate selectors with Copilot
With DevTools open in your browser showing the canvas DOM, copy the relevant HTML and ask Copilot:
"Given this HTML from a Power Apps canvas app, write the Playwright locator to click the Save button scoped to
iframe[name='fullscreen-app-host']."
Recommended local development workflow for Playwright tests
This end-to-end workflow covers the typical steps from initial setup through committing your tests.
- Set up once: Configure
.env, runauth:headful, verify the sample tests pass. - Inspect first: Open your app, use DevTools or the Playwright MCP server to find control names.
- Write with AI: Use Claude Code or Copilot Chat to scaffold the test from a description.
- Run with UI:
npx playwright test --uigives immediate visual feedback. - Debug with Inspector:
await page.pause()at the failure point to inspect state live. - Read the trace: If a test is flaky in CI, open the trace zip to see exactly what happened.
- Commit selectively: Stage only the test files - never commit
.envor.playwright-ms-auth/.
Troubleshoot common local issues
Use this table to diagnose and resolve the most frequent problems when running tests locally.
| Symptom | Likely cause | Fix |
|---|---|---|
Storage state file does not exist |
Auth never run | npm run auth:headful |
Authentication tokens have expired |
Session expired (>1 hour) | Re-run npm run auth:headful |
TimeoutError on gallery |
Dataverse load time | Increase timeout to 60000 |
Strict mode violation — N elements |
Selector too broad | Add .filter() or .first() |
| Test passes locally, fails in CI | Timing or environment diff | Add await page.waitForLoadState(), check retries |
ERR_ABORTED during model-driven app auth |
Previous browser process alive | Wait a few seconds and retry npm run auth:mda:headful |
| VS Code Playwright extension not finding tests | Wrong testDir |
Check playwright.config.ts → testDir: './tests' |