# Playwright ARIA Snapshot & Accessibility Tree Change Monitor (`produkdigitalali/playwright-aria-snapshot-change-monitor`) Actor

Detect accessibility-tree changes on public pages with Playwright, persistent baselines, desktop/mobile checks, and privacy-safe hashed change evidence.

- **URL**: https://apify.com/produkdigitalali/playwright-aria-snapshot-change-monitor.md
- **Developed by:** [ProdukDigitalAli](https://apify.com/produkdigitalali) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$12.00 / 1,000 aria page snapshot checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Playwright ARIA Snapshot & Accessibility Tree Change Monitor

Detect changes in the rendered accessibility tree of public web pages. Capture privacy-safe Playwright ARIA snapshots, keep a persistent baseline, and compare subsequent runs on desktop or mobile.

### What you can monitor

- Accessibility-tree regressions after website deployments.
- Changes to navigation, forms, component roles, accessible labels, and states.
- Separate desktop and mobile page structures in release QA.
- Recurring checks from an Apify schedule or API workflow.

This Actor detects changes, not whether they violate WCAG. An unchanged snapshot does not certify accessibility. Names and state/text payloads are hashed, so change examples show privacy-safe tokens rather than human-readable page content. Ordering changes can set CHANGED even when added/removed counts are zero.

### Quick start

```json
{
  "urls": ["https://example.com/"],
  "monitorKey": "homepage-daily",
  "viewport": "desktop",
  "settleMs": 1000,
  "navigationTimeoutSeconds": 30,
  "maxChanges": 50,
  "resetBaseline": false
}
```

The first successful run creates a baseline. Subsequent runs with the same monitorKey, exact URL, and viewport compare against the last successful snapshot and replace it. Use resetBaseline true when intentionally accepting a new baseline. Query strings participate in the identity hash but are removed from displayed URLs.

### Input

| Field | Default | Behavior |
| --- | --- | --- |
| urls | https://example.com/ | 1-10 public HTTP(S) URLs; duplicates removed |
| monitorKey | homepage-daily | Stable 3-64 character label; letters, numbers, hyphens, underscores |
| viewport | desktop | desktop 1365x768 or mobile 390x844 |
| waitUntil | domcontentloaded | domcontentloaded, load, or networkidle |
| settleMs | 1000 | Additional 0-10,000 ms wait before capture |
| navigationTimeoutSeconds | 30 | 5-60 seconds per page |
| maxChanges | 50 | 1-200 change examples |
| resetBaseline | false | Replace current baseline without comparison |
| proxyConfiguration | unset | Optional Apify proxy; proxy services may cost extra |

### Results

The dataset contains one row per checked page:

- BASELINE_CREATED: first successful capture or intentional reset.
- UNCHANGED: snapshot matches the previous capture.
- CHANGED: snapshot differs; added/removed line counts and capped examples are returned.
- ERROR: capture or persistence failed; no event charge for that failed check.

Rows include safe page URLs, viewport, HTTP status, current/previous snapshot hashes, node counts, changes, duration, transfer statistics, and error code. The OUTPUT record summarizes requested, succeeded, failed, changed, and charged counts. The Output tab links to the dataset and summary.

Baselines are stored in the account's named key-value store playwright-aria-snapshot-baselines. Keys are hashes of monitorKey, URL, and viewport. Preserve the store for scheduled comparisons; deleting the corresponding baseline record causes the next run to initialize it again. Avoid concurrent runs for the same monitorKey and URL because the baseline uses last-write semantics.

### Suggested tasks

1. Daily homepage check: desktop, stable monitorKey, resetBaseline false.
2. Mobile release regression: mobile, a separate monitorKey, same URL list.
3. Approve a new baseline: run once with resetBaseline true, then turn it off.

### Pricing

Pay per event: USD 0.012 per aria-snapshot-checked event. One successful check is charged after its dataset result and persistent baseline are saved. First-time baseline creation is also one useful check. Failed checks do not receive this event charge. Set the run's maximum charge high enough for the URL count (one page needs USD 0.012). Platform compute/storage and optional proxy charges depend on the user's plan and account.

### Security and limits

Public pages only. Credentials, cookies, custom headers, and arbitrary scripts are not supported. Private, loopback, metadata, reserved, and mixed public/private DNS targets are blocked. Browser traffic uses a DNS-pinned egress guard. Downloads and service workers are disabled. Each page is limited to 48 MiB transfer, 250 proxy connections, and 2,000 snapshot lines. Baselines hash all non-role payloads, including names, text, resource URLs, and states. URL queries and fragments are stripped from dataset URLs.

Only rendered body content is captured. This does not interact with menus, scroll lazy-loaded sections, authenticate, or guarantee coverage of embedded documents. Dynamic content can create noise; keep URL, viewport, readiness, and settle settings consistent. A fully failed run exits as FAILED.

### Validation

Cloud baseline and comparison smoke tests passed. All four Apify schemas validated. Sixteen local tests cover input limits, redaction, diffs, public DNS enforcement, and proxy behavior. Actual PPE run recorded one successful event after persistence.

# Changelog

This Actor's version history is a separate document: https://apify.com/produkdigitalali/playwright-aria-snapshot-change-monitor/changelog.md

# Actor input Schema

## `urls` (type: `array`):

One to ten public HTTP(S) pages.

## `monitorKey` (type: `string`):

Stable label used to reuse baselines across scheduled runs.

## `viewport` (type: `string`):

Browser viewport used for this baseline.

## `waitUntil` (type: `string`):

Playwright navigation readiness event.

## `settleMs` (type: `integer`):

Extra wait after navigation before capture.

## `navigationTimeoutSeconds` (type: `integer`):

Maximum navigation time per page.

## `maxChanges` (type: `integer`):

Maximum added or removed line examples in output.

## `resetBaseline` (type: `boolean`):

Replace any existing baseline during this run.

## `proxyConfiguration` (type: `object`):

Optional Apify proxy configuration.

## Actor input object example

```json
{
  "urls": [
    "https://example.com/"
  ],
  "monitorKey": "homepage-daily",
  "viewport": "desktop",
  "waitUntil": "domcontentloaded",
  "settleMs": 1000,
  "navigationTimeoutSeconds": 30,
  "maxChanges": 50,
  "resetBaseline": false
}
```

# Actor output Schema

## `summary` (type: `string`):

No description

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("produkdigitalali/playwright-aria-snapshot-change-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("produkdigitalali/playwright-aria-snapshot-change-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call produkdigitalali/playwright-aria-snapshot-change-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,produkdigitalali/playwright-aria-snapshot-change-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/3ucBAoH1Wb6JBGGKy/builds/N6vsSiJMHZb9jzour/openapi.json
