From power-pages
Tests deployed Power Pages sites at runtime: navigates browser, crawls up to 25 links, verifies page loads and /_api/ requests, captures network/screenshots via Playwright.
npx claudepluginhub microsoft/power-platform-skills --plugin power-pagesThis skill is limited to using the following tools:
Test a deployed, activated Power Pages site at runtime. Navigate the site in a browser, crawl all discoverable links, verify pages load correctly, capture network traffic to test API requests, and generate a comprehensive test report.
Systematically tests all pages for errors, functionality, rendering using Playwright MCP. Reads page list from tests/e2e-test-plan.md; verifies assets, build, and base URL first.
Guides deployment of existing Power Pages code sites to environments using PAC CLI. Verifies tooling, authenticates, confirms targets, builds, and uploads.
Validates web pages by detecting JavaScript errors, capturing console logs and screenshots, testing mobile/desktop viewports with 14 presets, and supporting authentication for protected apps.
Share bugs, ideas, or general feedback.
Test a deployed, activated Power Pages site at runtime. Navigate the site in a browser, crawl all discoverable links, verify pages load correctly, capture network traffic to test API requests, and generate a comprehensive test report.
Prerequisite: This skill expects a deployed and activated Power Pages site. Run
/deploy-siteand/activate-sitefirst if the site is not yet live.
/_api/ (Web API / OData) requests return successful responses.Initial request: $ARGUMENTS
Goal: Determine the live URL of the Power Pages site to test.
Create the full task list with all 6 phases before starting any work (see Progress Tracking table).
If the user provided a URL in $ARGUMENTS:
https://.SITE_URL and skip to Phase 2.If no URL was provided, attempt auto-detection:
Locate the project root by searching for powerpages.config.json:
**/powerpages.config.json
Run the activation status check script:
node "${CLAUDE_PLUGIN_ROOT}/scripts/check-activation-status.js" --projectRoot "<PROJECT_ROOT>"
Evaluate the JSON result:
activated is true and websiteUrl is present: Use websiteUrl as SITE_URL. Inform the user: "Detected your site URL: "activated is false: Inform the user: "Your site is not yet activated. Please run /activate-site first, then re-run this skill." Stop the skill.error is present: Fall through to step 1.4.If auto-detection failed or was inconclusive, use AskUserQuestion:
| Question | Header | Options |
|---|---|---|
| What is the URL of the deployed Power Pages site you want to test? (e.g., https://contoso.powerappsportals.com) | Site URL | I'll paste the URL (description: Select "Other" below and paste your site URL), I don't know my URL (description: Run /activate-site to get your site URL, or check the Power Platform admin center) |
Store the user-provided URL as SITE_URL.
SITE_URL resolved and ready for testingGoal: Open the site in a browser, verify the homepage loads, and capture baseline errors.
Set the browser to a standard desktop viewport:
browser_resize with width: 1280, height: 720.browser_navigate to open SITE_URL.browser_wait_for with time: 5 seconds to allow the page to fully render (SPAs may need time for client-side routing and API calls).browser_snapshot to take an accessibility snapshot.browser_console_messages with level: "error" to check for JavaScript errors on initial load.browser_network_requests with includeStatic: false to capture the initial page load API calls./_api/ or OData requests and their status codes for Phase 5 analysis.Goal: Detect if the site requires authentication and handle login if needed. Power Pages sites can have two layers of authentication:
login.microsoftonline.com, *.b2clogin.com).Review the browser snapshot from Phase 2.4 and the current browser URL for signs of a private site redirect:
SITE_URL (e.g., login.microsoftonline.com, *.b2clogin.com, or a custom identity provider domain)If a private site gate is detected, use AskUserQuestion:
| Question | Header | Options |
|---|---|---|
| This site is private — it redirected to an identity provider login page before any content could load. A browser window should be open showing the login page. Please log in there using credentials that have access to this site. Once you have successfully logged in and can see the site homepage, select "I have logged in" below. | Private Site Login | I have logged in (Recommended) — I've completed the login and can see the site, Cancel testing — Stop the test |
If "I have logged in":
browser_snapshot to verify the user is now on the actual site (site content visible, navigation present, URL is back on the SITE_URL domain).AskUserQuestion again: "It looks like the login hasn't completed yet. The browser should still be open — please complete the login and try again."If "Cancel testing":
After the homepage is loaded (either directly for public sites, or after passing the private site gate), review the snapshot for signs of site-level authentication:
If neither a private site gate nor site-level authentication indicators are found:
If site-level authentication indicators are detected (login links in navigation, etc.), use AskUserQuestion:
| Question | Header | Options |
|---|---|---|
| The site has a Sign in option, which means some pages or API calls may require authentication. A browser window should be open — you can click "Sign in" and log in with a user account that has the appropriate web role. Once you have successfully logged in, select "I have logged in" below. | Site Authentication | I have logged in (Recommended) — I've signed in through the site's login flow, Skip authenticated pages — Only test publicly accessible pages and APIs, Cancel testing — Stop the test |
If "I have logged in":
Use browser_snapshot to verify the user is now logged in (login link replaced with user name/profile, or authenticated content is visible).
If the login form is still showing:
AskUserQuestion again: "It looks like the login hasn't completed yet. The browser should still be open — please complete the login and try again."Create an additional task for testing authenticated scenarios using TaskCreate:
| Task subject | activeForm | Description |
|---|---|---|
| Test authenticated pages and APIs | Testing authenticated scenarios | Re-crawl site as logged-in user, verify auth-gated pages load and authenticated API calls succeed |
If "Skip authenticated pages":
If "Cancel testing":
Goal: Discover all navigable links on the site and verify each page loads correctly.
Use browser_evaluate to extract all internal links:
() => {
const links = Array.from(document.querySelectorAll('a[href]'));
return links
.map(a => a.href)
.filter(href => href.startsWith(window.location.origin))
.filter(href => !href.includes('#') || href.split('#')[0] !== window.location.href.split('#')[0])
.map(href => href.split('#')[0])
.filter((href, i, arr) => arr.indexOf(href) === i);
}
Present the discovered links to the user:
"Found X internal links on the homepage. Testing each page..."
For each discovered URL, in sequence:
browser_navigate to go to the URL.browser_wait_for with time: 3 seconds for the page to render.browser_snapshot to verify the page rendered content.browser_console_messages with level: "error" to check for JavaScript errors.browser_evaluate (same script as 4.1) to find any new internal links not already in the queue.Build a results list tracking:
Goal: Capture and analyze all API requests made by the site to verify they are working.
Navigate back to pages that are likely to make API calls — pages with dynamic content such as data tables, lists, forms, or dashboards. Prioritize pages where /_api/ requests were observed in Phase 2.6 or Phase 4.
For each data-driven page:
browser_navigate to go to the page.browser_wait_for with time: 5 seconds to allow API calls to complete.browser_network_requests with includeStatic: false to get all network requests./_api/ — Power Pages Web API / OData endpoints/api/ — Custom API endpointsodata or $filter, $select, $expand query parametersFor each captured API request, evaluate:
| Status Code | Category | Action |
|---|---|---|
| 200, 201, 204 | Pass | Valid successful response |
| 304 | Warning | Cached response — acceptable but note it |
| 401 | Fail | Unauthorized — missing or expired auth token |
| 403 | Fail | Forbidden — table permissions or site settings issue |
| 404 | Fail | Not found — incorrect entity set name or endpoint |
| 500 | Fail | Server error — internal Dataverse or plugin error |
| Other 4xx/5xx | Fail | Unexpected error |
For each failed API request, provide specific remediation:
/_api/ calls: "Check the following:\n 1. Table permissions — Ensure a table permission exists for this table with the correct scope and privileges (Read, Write, etc.) assigned to the appropriate web role.\n 2. Site settings — Verify Webapi/<tablename>/enabled is set to true and Webapi/<tablename>/fields lists the required columns (exact Dataverse LogicalNames, all lowercase, comma-separated). If the failing request uses aggregate OData ($apply, aggregate, grouped totals), set Webapi/<tablename>/fields to *.\n 3. Web role assignment — Confirm the authenticated user has the correct web role assigned."Webapi/error/innererror site setting (set to true) to get detailed error messages. Redeploy and retest to see the inner error details."If forms are detected on any page (via browser_snapshot showing form elements), ask the user before interacting:
| Question | Header | Options |
|---|---|---|
| I found forms on the site that may trigger API calls when submitted. Should I attempt to interact with these forms to test the POST/PATCH API endpoints? Note: this may create or modify data in your Dataverse environment. | Form Testing | Yes, test form submissions — I understand this may create test data, Skip form testing (Recommended) — Only test read-only API calls |
If "Yes":
browser_click to interact with form submit buttons.browser_wait_for to wait for the form response.browser_network_requests to capture the resulting POST/PATCH requests.If "Skip": Continue to Phase 5.6 (or Phase 6 if no authenticated testing task was created).
Skip this step entirely if the user chose "Skip authenticated pages" in Phase 3.5, or if no site-level authentication was detected in Phase 3.3.
Goal: Re-crawl the site as an authenticated user to discover and test pages and API calls that are only available after login.
Mark the "Test authenticated pages and APIs" task as in_progress.
After login, the site navigation may show additional links that were hidden or restricted for anonymous users (e.g., profile pages, dashboards, admin panels, account management).
SITE_URL (homepage).browser_snapshot to capture the authenticated navigation.browser_evaluate (same link extraction script as Phase 4.1) to discover internal links.If new links are found, inform the user:
"Found X additional pages visible after login that were not accessible anonymously. Testing each page..."
For each newly discovered link, follow the same test procedure as Phase 4.2:
For each authenticated page that makes /_api/ requests:
browser_network_requests with includeStatic: false to capture API calls.Record authenticated test results separately so Phase 6 can report them in a distinct section:
Mark the "Test authenticated pages and APIs" task as completed.
Goal: Present a comprehensive summary of all test results and suggest next steps.
Reference:
${CLAUDE_PLUGIN_ROOT}/references/skill-tracking-reference.md
Follow the skill tracking instructions in the reference to record this skill's usage. Use --skillName "TestSite".
Present results in a clear table:
## Page Test Results
| # | URL | Status | Console Errors | Notes |
|---|-----|--------|----------------|-------|
| 1 | / | Pass | 0 | Homepage loaded successfully |
| 2 | /about | Pass | 0 | |
| 3 | /products | Pass | 2 | Minor JS warnings |
| 4 | /admin | Fail | 1 | 403 Forbidden |
Pages tested: 4/4 | Passed: 3 | Failed: 1
## API Test Results
| # | Endpoint | Method | Status | Notes |
|---|----------|--------|--------|-------|
| 1 | /_api/cr4fc_products | GET | 200 OK | 12 records returned |
| 2 | /_api/cr4fc_categories | GET | 200 OK | 3 records returned |
| 3 | /_api/cr4fc_orders | GET | 403 Forbidden | Missing table permissions |
API endpoints tested: 3 | Passed: 2 | Failed: 1
If no API requests were captured, note: "No API requests (/_api/ or OData) were detected during testing. This site may not use the Web API, or API calls may require specific user interactions to trigger."
If Phase 5.6 was executed, present results in separate tables:
## Authenticated Page Test Results
| # | URL | Status | Console Errors | Notes |
|---|-----|--------|----------------|-------|
| 1 | /profile | Pass | 0 | User profile loaded |
| 2 | /dashboard | Pass | 1 | Minor JS warning |
| 3 | /admin/settings | Fail | 0 | 403 Forbidden — insufficient web role |
Authenticated pages tested: 3 | Passed: 2 | Failed: 1
## Authenticated API Test Results
| # | Endpoint | Method | Status | Notes |
|---|----------|--------|--------|-------|
| 1 | /_api/cr4fc_orders | GET | 200 OK | Previously 403 — now accessible after login |
| 2 | /_api/cr4fc_userprofiles | GET | 200 OK | Only visible after auth |
Authenticated API endpoints tested: 2 | Passed: 2 | Failed: 0
If no additional pages or APIs were discovered after login, note: "No additional pages or API endpoints were found after authentication. The authenticated user sees the same content as an anonymous visitor."
## Overall Test Summary
| Category | Tested | Passed | Failed | Warnings |
|--------------------------|--------|--------|--------|----------|
| Pages (public) | 4 | 3 | 1 | 0 |
| Pages (authenticated) | 3 | 2 | 1 | 0 |
| API Endpoints (public) | 3 | 2 | 1 | 0 |
| API Endpoints (auth) | 2 | 2 | 0 | 0 |
| Console Errors | — | — | — | 2 |
Overall: X/Y checks passed
If authenticated testing was skipped, omit the authenticated rows from the table.
For each failure, reiterate the specific remediation guidance from Phase 5.4. Group recommendations by category:
/create-webroles or manually configure table permissionsWebapi/<table>/enabled and Webapi/<table>/fields settings/setup-auth/setup-datamodelWebapi/error/innererror site setting for diagnosticsbrowser_close to clean up the browser session.Based on the test results, suggest relevant skills:
/integrate-webapi — Fix Web API site settings and table permissions/setup-auth — Configure authentication providers/deploy-site/add-seo for search engine optimization/activate-siteBefore starting Phase 1, create a task list with all phases using TaskCreate:
| Task subject | activeForm | Description |
|---|---|---|
| Resolve site URL | Resolving site URL | Get URL from user input, activation status check, or context |
| Launch browser and verify initial load | Loading site in browser | Navigate to site, verify homepage loads, capture baseline errors |
| Check authentication requirements | Checking authentication | Detect if site requires auth, handle login if needed |
| Crawl and test all pages | Crawling site pages | Discover links, navigate each page, verify loads, check console errors |
| Test API requests | Testing API endpoints | Capture network requests, verify API responses, analyze errors |
| Generate test report | Generating test report | Present summary of all pages and APIs tested, suggest next steps |
Mark each task in_progress when starting it and completed when done via TaskUpdate.
Begin with Phase 1: Resolve Site URL