Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 5 additions & 103 deletions .github/workflows/create_test_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,109 +116,11 @@ jobs:
triage:
needs: merge-reports
if: ${{ needs.merge-reports.outputs.has_failures == 'true' && needs.merge-reports.outputs.pr_number && needs.merge-reports.outputs.triage_allowed == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: read
actions: read
pull-requests: write
copilot-requests: write
outputs:
has_draft: ${{ steps.triage.outputs.has_draft }}
uses: ./.github/workflows/pr-ci-triage.yml
with:
pr_number: ${{ needs.merge-reports.outputs.pr_number }}
env:
PR_NUMBER: ${{ needs.merge-reports.outputs.pr_number }}
GH_TOKEN: ${{ github.token }}
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: "24"

- name: Install Copilot CLI
run: npm install -g @github/copilot

- name: Triage failures with Copilot CLI
id: triage
env:
COPILOT_GITHUB_TOKEN: ${{ github.token }}
run: |
mkdir -p output
PROMPT=$(cat <<EOF
Come up with a verdict on the CI test failures on pull request #$PR_NUMBER of ${{ github.repository }}: are they likely caused by this PR? Follow the pr-ci-triage guide (.github/workflows/pr-ci-triage.md) for the analysis.

Write your verdict to output/triage.md as a PR comment, in the format the guide specifies and the playwright-bot-voice register (.claude/skills/playwright-bot-voice/SKILL.md).

Do not post anything yourself — a later workflow step posts output/triage.md.
EOF
)
copilot \
--allow-all-tools \
--allow-all-paths \
--no-ask-user \
--enable-all-github-mcp-tools \
--share=output/copilot-session.md \
--model claude-opus-4.8 \
--max-ai-credits 500 \
-p "$PROMPT"

if [ -s output/triage.md ]; then
echo "has_draft=true" >> "$GITHUB_OUTPUT"
else
echo "has_draft=false" >> "$GITHUB_OUTPUT"
fi

- name: Add session transcript to job summary
if: ${{ always() }}
run: |
{
echo "## CI triage session transcript (PR #$PR_NUMBER)"
echo ''
cat "output/copilot-session.md" 2>/dev/null || echo "(no transcript)"
} >> "$GITHUB_STEP_SUMMARY"

- name: Upload output
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: ci-triage-${{ needs.merge-reports.outputs.pr_number }}
path: output/triage.md
if-no-files-found: warn

post:
needs: triage
if: needs.triage.outputs.has_draft == 'true'
runs-on: ubuntu-latest
permissions:
pull-requests: write
env:
PR_NUMBER: ${{ needs.triage.outputs.pr_number }}
GH_TOKEN: ${{ github.token }}
WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Download triage output
uses: actions/download-artifact@v4
with:
name: ci-triage-${{ needs.triage.outputs.pr_number }}
path: output

- name: Post triage comment
uses: actions/github-script@v9
with:
script: |
const fs = require('fs');
const { collapsePreviousComments } = require('./tests/config/postReportComment');
const sentinel = `<!-- playwright-ci-triage --><!-- ${context.payload.workflow_run.name} -->`;
const prNumber = +process.env.PR_NUMBER;
await collapsePreviousComments(github, context, prNumber, sentinel);

const triage = fs.readFileSync('output/triage.md', 'utf8');
const body = `${triage}\n\n<sub>Triaged by the Playwright bot - [agent run](${process.env.WORKFLOW_URL})</sub>\n${sentinel}\n`;
await github.rest.issues.createComment({
...context.repo,
issue_number: prNumber,
body,
});
134 changes: 134 additions & 0 deletions .github/workflows/pr-ci-triage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Reusable CI triage for PR test failures. Callable from other repos
# (e.g. microsoft/playwright-browsers) via workflow_call.
name: PR CI Triage

on:
workflow_call:
inputs:
pr_number:
description: 'PR number to triage'
required: true
type: string

permissions: {}

jobs:
triage:
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: read
actions: read
pull-requests: read
copilot-requests: write
outputs:
has_draft: ${{ steps.triage.outputs.has_draft }}
env:
PR_NUMBER: ${{ inputs.pr_number }}
TARGET_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
repository: microsoft/playwright
ref: main

- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: '24'

- name: Install Copilot CLI
run: npm install -g @github/copilot

- name: Triage failures with Copilot CLI
id: triage
env:
COPILOT_GITHUB_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
mkdir -p output
PROMPT=$(cat <<PROMPT_EOF
Come up with a verdict on the CI test failures on pull request #${PR_NUMBER} of ${TARGET_REPO}: are they likely caused by this PR? Follow the pr-ci-triage guide (.github/workflows/pr-ci-triage.md) for the analysis.

Write your verdict to output/triage.md as a PR comment, in the format the guide specifies and the bot voice register (.github/workflows/bot-voice.md).

Do not post anything yourself — a later workflow step posts output/triage.md.
PROMPT_EOF
)
copilot \
--allow-all-tools \
--allow-all-paths \
--no-ask-user \
--enable-all-github-mcp-tools \
--share=output/copilot-session.md \
--model claude-opus-4.8 \
--max-ai-credits 500 \
-p "$PROMPT"

if [ -s output/triage.md ]; then
echo "has_draft=true" >> "$GITHUB_OUTPUT"
else
echo "has_draft=false" >> "$GITHUB_OUTPUT"
fi

- name: Add session transcript to job summary
if: ${{ always() }}
run: |
{
echo "## CI triage session transcript (PR #$PR_NUMBER on $TARGET_REPO)"
echo ''
cat output/copilot-session.md 2>/dev/null || echo "(no transcript)"
} >> "$GITHUB_STEP_SUMMARY"

- name: Upload triage draft
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: ci-triage-${{ inputs.pr_number }}
path: output/triage.md
if-no-files-found: warn

post:
needs: triage
if: ${{ needs.triage.outputs.has_draft == 'true' }}
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
env:
PR_NUMBER: ${{ inputs.pr_number }}
GH_TOKEN: ${{ github.token }}
WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
REPORT_NAME: ${{ github.event.workflow_run.name || github.workflow }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
repository: microsoft/playwright
ref: main

- name: Download triage draft
uses: actions/download-artifact@v4
with:
name: ci-triage-${{ inputs.pr_number }}
path: output

- name: Post triage comment
uses: actions/github-script@v9
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
const { collapsePreviousComments } = require('./tests/config/postReportComment');
const sentinel = `<!-- playwright-ci-triage --><!-- ${process.env.REPORT_NAME} -->`;
const prNumber = +process.env.PR_NUMBER;
await collapsePreviousComments(github, context, prNumber, sentinel);
const triage = fs.readFileSync('output/triage.md', 'utf8');
const body = `${triage}\n\n<sub>Triaged by the Playwright bot - [agent run](${process.env.WORKFLOW_URL})</sub>\n${sentinel}\n`;
await github.rest.issues.createComment({
...context.repo,
issue_number: prNumber,
body,
});
55 changes: 55 additions & 0 deletions docs/src/api/class-locator.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,61 @@ When `true`, appends each element's bounding box as `[box=x,y,width,height]` to
relative to the viewport, in CSS pixels, as returned by [`Element.getBoundingClientRect()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect).
Defaults to `false`.

## async method: Locator.ariaSnapshotJSON
* since: v1.63
* langs: js
- returns: <[Serializable]>

Captures the aria snapshot of the given element as a free form JSON object.

**Usage**

```js
await page.getByRole('list').ariaSnapshotJSON();
```

**Details**

This method returns the same tree as [`method: Locator.ariaSnapshot`], serialized as a JSON value instead of YAML markup.
The result is a list of nodes, each node being either a plain string with static text, or an object with the following properties:
* `role` <[string]> Aria role of the element.
* `name` <[string]> Accessible name of the element, if any.
* `text` <[string]> Text content of the element, when it is the only child.
* `children` <[Array]> Child nodes and text fragments.
* Boolean and value properties for element state flags: `checked`, `disabled`, `expanded`, `active`, `invalid`, `level`, `pressed` and `selected`.
* Additional element properties, for example `url` for links and `placeholder` for text boxes.
* `ref` <[string]> Element reference for AI-optimized snapshots.
* `cursor` <[string]> Set to `"pointer"` for clickable elements in AI-optimized snapshots.
* `box` <[Object]> Bounding box of the element when [`option: Locator.ariaSnapshotJSON.boxes`] is set.

### option: Locator.ariaSnapshotJSON.mode
* since: v1.63
- `mode` <[AriaSnapshotMode]<"ai"|"default">>

When set to `"ai"`, returns a snapshot optimized for AI consumption. Defaults to `"default"`. See details in [`method: Locator.ariaSnapshot`].

### option: Locator.ariaSnapshotJSON.timeout = %%-input-timeout-%%
* since: v1.63

### option: Locator.ariaSnapshotJSON.timeout = %%-input-timeout-js-%%
* since: v1.63

### option: Locator.ariaSnapshotJSON.signal = %%-input-signal-%%

### option: Locator.ariaSnapshotJSON.depth
* since: v1.63
- `depth` <[int]>

When specified, limits the depth of the snapshot.

### option: Locator.ariaSnapshotJSON.boxes
* since: v1.63
- `boxes` <[boolean]>

When `true`, includes each element's bounding box as a `box` property with `x`, `y`, `width` and `height`. Coordinates are
relative to the viewport, in CSS pixels, as returned by [`Element.getBoundingClientRect()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect).
Defaults to `false`.

## async method: Locator.blur
* since: v1.28

Expand Down
37 changes: 37 additions & 0 deletions docs/src/api/class-page.md
Original file line number Diff line number Diff line change
Expand Up @@ -4427,6 +4427,43 @@ When `true`, appends each element's bounding box as `[box=x,y,width,height]` to
relative to the viewport, in CSS pixels, as returned by [`Element.getBoundingClientRect()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect).
Defaults to `false`.

## async method: Page.ariaSnapshotJSON
* since: v1.63
* langs: js
- returns: <[Serializable]>

Captures the aria snapshot of the page as a free form JSON object.
Returns the same tree as [`method: Page.ariaSnapshot`], serialized as a JSON value instead of YAML markup.
See [`method: Locator.ariaSnapshotJSON`] for the details of the format.

### option: Page.ariaSnapshotJSON.mode
* since: v1.63
- `mode` <[AriaSnapshotMode]<"ai"|"default">>

When set to `"ai"`, returns a snapshot optimized for AI consumption: including element references like `[ref=e2]` and snapshots of `<iframe>`s. Defaults to `"default"`.

### option: Page.ariaSnapshotJSON.timeout = %%-input-timeout-%%
* since: v1.63

### option: Page.ariaSnapshotJSON.timeout = %%-input-timeout-js-%%
* since: v1.63

### option: Page.ariaSnapshotJSON.signal = %%-input-signal-%%

### option: Page.ariaSnapshotJSON.depth
* since: v1.63
- `depth` <[int]>

When specified, limits the depth of the snapshot.

### option: Page.ariaSnapshotJSON.boxes
* since: v1.63
- `boxes` <[boolean]>

When `true`, includes each element's bounding box as a `box` property with `x`, `y`, `width` and `height`. Coordinates are
relative to the viewport, in CSS pixels, as returned by [`Element.getBoundingClientRect()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect).
Defaults to `false`.

## async method: Page.tap
* since: v1.8
* discouraged: Use locator-based [`method: Locator.tap`] instead. Read more about [locators](../locators.md).
Expand Down
6 changes: 6 additions & 0 deletions docs/src/getting-started-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ Coding agents like Claude Code and GitHub Copilot can use locally installed skil
playwright-cli install --skills
```

To share the skills across all your projects, add the `-g` flag to install them into your home directory (`~/.claude/skills` or, with `--skills=agents`, `~/.agents/skills`):

```bash
playwright-cli install --skills -g
```

### Skills-less operation

You can also point your agent at the CLI directly and let it discover commands on its own:
Expand Down
Loading
Loading