{"id":10921,"date":"2026-05-22T20:29:47","date_gmt":"2026-05-22T12:29:47","guid":{"rendered":"https:\/\/aeosub.com\/qaproof\/"},"modified":"2026-05-22T20:29:47","modified_gmt":"2026-05-22T12:29:47","slug":"qaproof","status":"publish","type":"post","link":"https:\/\/aeosub.com\/zh\/qaproof\/","title":{"rendered":"QAProof"},"content":{"rendered":"<div class=\"post-img\" style=\"margin-bottom: 25px\"><img decoding=\"async\" src=\"https:\/\/ps.w.org\/qaproof\/assets\/banner-1544x500.png?rev=3543678\" alt=\"QAProof\" style=\"width: 100%;height: auto;border-radius: 12px\"><\/div>\n<div class=\"plugin-info-card\" style=\"border: 1px solid #e2e8f0;border-radius: 10px;overflow: hidden;margin-bottom: 30px;font-family: -apple-system, system-ui, sans-serif;background: #fff\">\n<table style=\"width: 100%;border-collapse: collapse;font-size: 14px\">\n<tr style=\"border-bottom: 1px solid #edf2f7\">\n<th style=\"padding: 15px 20px;text-align: left;width: 35%;color: #4a5568;background: #fcfcfc\"><img decoding=\"async\" src=\"https:\/\/ps.w.org\/qaproof\/assets\/icon-256x256.png?rev=3543678\" style=\"width: 40px;height: 40px;border-radius: 6px;margin-right: 12px;vertical-align: middle\"> Developer<\/th>\n<td style=\"padding: 15px 20px;font-weight: 500\"><a href=\"https:\/\/profiles.wordpress.org\/qaproof\/\" target=\"_blank\" rel=\"noopener\">QaProof<\/a><\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #edf2f7\">\n<th style=\"padding: 12px 20px;text-align: left;color: #4a5568;background: #fcfcfc\">Version<\/th>\n<td style=\"padding: 12px 20px\">v1.0.1<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #edf2f7\">\n<th style=\"padding: 12px 20px;text-align: left;color: #4a5568;background: #fcfcfc\">Active Installs<\/th>\n<td style=\"padding: 12px 20px\">0 +<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #edf2f7\">\n<th style=\"padding: 12px 20px;text-align: left;color: #4a5568;background: #fcfcfc\">Requires \/ Tested<\/th>\n<td style=\"padding: 12px 20px\">6.0 \/ 7.0<\/td>\n<\/tr>\n<tr style=\"border-bottom: 1px solid #edf2f7\">\n<th style=\"padding: 12px 20px;text-align: left;color: #4a5568;background: #fcfcfc\">Last Updated<\/th>\n<td style=\"padding: 12px 20px\">2026-05-22 11:44am GMT<\/td>\n<\/tr>\n<tr>\n<th style=\"padding: 12px 20px;text-align: left;color: #4a5568;background: #fcfcfc\">Official Link<\/th>\n<td style=\"padding: 12px 20px\"><a href=\"https:\/\/wordpress.org\/plugins\/qaproof\/\" target=\"_blank\" style=\"text-decoration: none;color: #4a3bca;font-weight: bold\" rel=\"noopener\">View Details \u2192<\/a><\/td>\n<\/tr>\n<\/table><\/div>\n<div class=\"plugin-short-desc\" style=\"margin: 20px 0;padding: 12px 15px;background: #f9fafb;border-left: 4px solid #4a3bca;border-radius: 6px;font-style: italic;color: #4a5568\">Compare live pages against Figma, audit accessibility (WCAG 2.1), detect visual regressions, and analyze responsive behavior \u2014 powered by AI vision.<\/div>\n<p>QAProof helps WordPress site owners and developers catch visual bugs before users do. It pairs Playwright-rendered screenshots of your live pages with AI vision analysis to find design drift, accessibility issues, and responsive breakage automatically.<\/p>\n<p>Five test types, one workflow:<\/p>\n<ul>\n<li><strong>Design Fidelity<\/strong> \u2014 Compares your live page against a Figma design (or any image you upload) and reports layout drift, color mismatches, typography differences, spacing issues, and component variations with severity ratings and pixel-coordinate markers.<\/li>\n<li><strong>Responsive Testing<\/strong> \u2014 Renders the page at desktop, tablet, and mobile viewports and analyzes how the layout adapts. Flags overflow, broken stacks, illegible text, missing media-query rules.<\/li>\n<li><strong>Accessibility Audit<\/strong> \u2014 WCAG 2.1 Level A \/ AA \/ AAA compliance check. Covers color contrast, focus indicators, heading hierarchy, form labels, ARIA misuse, touch-target sizes, and more, with the WCAG criterion referenced for each violation.<\/li>\n<li><strong>Visual Regression Monitoring<\/strong> \u2014 Scheduled screenshot diffing. Captures a baseline of a page, then re-shoots on a daily \/ weekly \/ monthly schedule and alerts you if anything changed (broken CSS deploy, missing image, accidental layout shift). Email + in-admin notifications when scores drop below your threshold.<\/li>\n<li><strong>Design Audit<\/strong> \u2014 Extracts your live design tokens (colors, fonts, spacing, components) and grades your design system&#8217;s internal consistency on a Design Debt Score.<\/li>\n<\/ul>\n<p><strong>How it works:<\/strong> QAProof is a thin WordPress plugin that talks to a hosted SaaS API (api.qaproof.io). The API runs the headless browser, calls the AI vision model, and returns structured reports. You need a QAProof account and API key \u2014 sign up free at https:\/\/qaproof.io.<\/p>\n<p><strong>Why a SaaS backend?<\/strong> Running Playwright + Anthropic Claude Vision in a WordPress request would crash most hosts (Chromium binary alone is 300 MB, image analysis runs 10\u201360 s). Doing it server-side keeps your hosting fast and lets us batch \/ cache \/ dedupe expensive operations.<\/p>\n<h3>External Services<\/h3>\n<p>QAProof is a SaaS-backed plugin. All test execution happens on the QAProof API server, which in turn calls Anthropic&#8217;s Claude Vision API and (optionally) Figma&#8217;s REST API. The WordPress plugin itself contacts ONE external service: the QAProof API at api.qaproof.io. It never contacts Anthropic or Figma directly.<\/p>\n<h4>Service: QAProof API<\/h4>\n<p>The plugin sends HTTPS requests to api.qaproof.io (default endpoint, configurable to a self-hosted host via the <code>QAPROOF_API_ENDPOINT<\/code> PHP constant). This is required for the plugin to function \u2014 without it, no test can run.<\/p>\n<p><strong>Test execution &amp; polling<\/strong><\/p>\n<ul>\n<li><code>POST   https:\/\/api.qaproof.io\/api\/compare<\/code> \u2014 start a new test (when the user clicks &#8220;Run test&#8221; or when a scheduled monitor fires). Sends: page URL, test type, design source (Figma URL or uploaded image bytes as base64), viewport size, WCAG conformance level, ignore-text flag.<\/li>\n<li><code>GET    https:\/\/api.qaproof.io\/api\/jobs\/{jobId}<\/code> \u2014 poll the status of an in-flight test (every 5 seconds while running). Sends: nothing in the body, just the job ID in the URL.<\/li>\n<li><code>DELETE https:\/\/api.qaproof.io\/api\/jobs\/{jobId}<\/code> \u2014 cancel an in-flight test when the user closes the browser tab. Sends: nothing.<\/li>\n<li><code>GET    https:\/\/api.qaproof.io\/api\/jobs\/{jobId}\/screenshots<\/code> \u2014 fetch the completed test&#8217;s screenshots after the test finishes. Sends: nothing.<\/li>\n<\/ul>\n<p><strong>Figma integration (optional)<\/strong><\/p>\n<ul>\n<li><code>POST   https:\/\/api.qaproof.io\/api\/figma-preview<\/code> \u2014 fetch a Figma frame as a PNG for the in-admin preview pane (only when the user selects a Figma URL). Sends: the Figma file URL.<\/li>\n<li><code>POST   https:\/\/api.qaproof.io\/api\/figma\/verify-access<\/code> \u2014 verify the plugin can access a Figma file before sending a full test. Sends: the Figma file URL.<\/li>\n<li><code>POST   https:\/\/api.qaproof.io\/api\/detect-elements<\/code> \u2014 extract individual UI elements from an uploaded design image. Sends: image bytes.<\/li>\n<li><code>POST   https:\/\/api.qaproof.io\/api\/figma-oauth\/start<\/code> \u2014 begin the Figma OAuth connection. Sends: nothing.<\/li>\n<li><code>GET    https:\/\/api.qaproof.io\/api\/figma-oauth\/status<\/code> \u2014 check the current Figma connection state. Sends: nothing.<\/li>\n<li><code>POST   https:\/\/api.qaproof.io\/api\/figma-oauth\/disconnect<\/code> \u2014 disconnect the workspace&#8217;s Figma OAuth tokens. Sends: nothing.<\/li>\n<\/ul>\n<p><strong>Account, plan &amp; health<\/strong><\/p>\n<ul>\n<li><code>GET    https:\/\/api.qaproof.io\/api\/me<\/code> \u2014 fetch the QAProof account&#8217;s plan and remaining quota, displayed in Settings <span aria-hidden=\"true\" class=\"wp-exclude-emoji\">\u2192<\/span> API. Sends: nothing.<\/li>\n<li><code>GET    https:\/\/api.qaproof.io\/api\/health<\/code> \u2014 connection health check from Settings <span aria-hidden=\"true\" class=\"wp-exclude-emoji\">\u2192<\/span> API. Sends: nothing.<\/li>\n<\/ul>\n<p><strong>Baselines (visual regression)<\/strong><\/p>\n<ul>\n<li><code>POST   https:\/\/api.qaproof.io\/api\/baselines<\/code> \u2014 create a baseline screenshot. Sends: page URL, baseline key.<\/li>\n<li><code>GET    https:\/\/api.qaproof.io\/api\/baselines<\/code> \u2014 list baselines.<\/li>\n<li><code>GET    https:\/\/api.qaproof.io\/api\/baselines\/{key}<\/code> \u2014 fetch a single baseline (including screenshot bytes).<\/li>\n<li><code>DELETE https:\/\/api.qaproof.io\/api\/baselines\/{key}<\/code> \u2014 delete a baseline.<\/li>\n<\/ul>\n<p><strong>Monitors (scheduled tests)<\/strong><\/p>\n<ul>\n<li><code>GET\/POST   https:\/\/api.qaproof.io\/api\/monitors<\/code> \u2014 list \/ create scheduled monitors. Sends on create: page URL, schedule, threshold score, notification email.<\/li>\n<li><code>GET\/PUT\/DELETE https:\/\/api.qaproof.io\/api\/monitors\/{id}<\/code> \u2014 read \/ update \/ delete a single monitor.<\/li>\n<li><code>GET   https:\/\/api.qaproof.io\/api\/monitors?schedule={daily|weekly|monthly}&amp;due=1<\/code> \u2014 WP-Cron queries monitors due to run.<\/li>\n<li><code>GET   https:\/\/api.qaproof.io\/api\/monitors\/{id}\/results<\/code> \u2014 fetch a monitor&#8217;s historical results.<\/li>\n<li><code>PUT   https:\/\/api.qaproof.io\/api\/results\/{id}\/approve<\/code> \u2014 approve a regression result (captures a fresh baseline).<\/li>\n<\/ul>\n<p><strong>Test history (cabinet sync)<\/strong><\/p>\n<ul>\n<li><code>POST  https:\/\/api.qaproof.io\/api\/history<\/code> \u2014 save a test result to the SaaS history. Sends: test type, page URL, score, summary, differences JSON, screenshot URLs \/ base64 thumbnails.<\/li>\n<li><code>GET   https:\/\/api.qaproof.io\/api\/history?...<\/code> \u2014 list history rows with pagination + filters.<\/li>\n<li><code>GET   https:\/\/api.qaproof.io\/api\/history\/{id}<\/code> \u2014 fetch a single history row (full result detail).<\/li>\n<li><code>DELETE https:\/\/api.qaproof.io\/api\/history\/{id}<\/code> \u2014 delete a history row from the SaaS.<\/li>\n<li><code>GET   https:\/\/api.qaproof.io\/api\/history\/stats?threshold=N<\/code> \u2014 fetch summary statistics for the dashboard tiles.<\/li>\n<\/ul>\n<p><strong>Email reports<\/strong><\/p>\n<ul>\n<li><code>POST  https:\/\/api.qaproof.io\/api\/send-report-email<\/code> \u2014 when the user clicks &#8220;Send to Email&#8221; on a test result, the plugin sends the generated PDF report (base64-encoded) and the recipient email address (the currently-logged-in WordPress administrator&#8217;s user email, with fall-back to the QAProof notification email or the site admin email) to the API. The API then emails the report from its outbound mail server (Amazon SES). The PDF and the recipient email leave the WordPress site and are processed by the QAProof API and its email provider.<\/li>\n<\/ul>\n<p><strong>Common request metadata sent on every call<\/strong><\/p>\n<ul>\n<li>Your <strong>QAProof API key<\/strong>, in the <code>Authorization: Bearer ...<\/code> header, so the API can authenticate the request.<\/li>\n<li>A <strong>WordPress \/ PHP version banner<\/strong> in the standard <code>User-Agent<\/code> header (<code>QAProof-WordPress\/&lt;plugin&gt; (WordPress\/&lt;wp&gt;; PHP\/&lt;php&gt;)<\/code>) so the API can detect known-incompatible host versions. The header does NOT contain your site URL \u2014 the API server learns the requesting IP only from the TCP connection itself.<\/li>\n<\/ul>\n<p>The plugin does NOT send: any post content, user passwords, page visitors&#8217; IP addresses, comments, cookies, or any other site content beyond the explicit URL the user types into the test form or its scheduled monitor configuration.<\/p>\n<p>QAProof Terms of Service: https:\/\/qaproof.io\/terms<br \/>\nQAProof Privacy Policy: https:\/\/qaproof.io\/privacy<\/p>\n<h4>Service: Anthropic Claude \u2014 used by QAProof API, NOT by this plugin<\/h4>\n<p>The QAProof API server calls Anthropic Claude Vision to perform the AI image analysis. This plugin does NOT call Anthropic directly \u2014 the WordPress site never opens a connection to Anthropic&#8217;s servers. Image bytes the QAProof API forwards to Anthropic are subject to Anthropic&#8217;s no-training, no-retention API terms.<\/p>\n<p>Anthropic Terms of Service: https:\/\/www.anthropic.com\/legal\/commercial-terms<br \/>\nAnthropic Privacy Policy: https:\/\/www.anthropic.com\/legal\/privacy<\/p>\n<h4>Service: Figma \u2014 used by QAProof API, NOT by this plugin<\/h4>\n<p>If you connect your Figma account via the in-admin OAuth flow or submit a public Figma URL, the QAProof API reads the specific Figma file(s) you submit for testing so it can export the design as a PNG image. The WordPress plugin itself never contacts Figma&#8217;s servers directly; the OAuth handshake redirects through api.qaproof.io.<\/p>\n<p>Figma Terms of Service: https:\/\/www.figma.com\/legal\/tos\/<br \/>\nFigma Privacy Policy: https:\/\/www.figma.com\/legal\/privacy\/<\/p>\n<h4>Trademarks<\/h4>\n<p>QAProof is an independent product. It is not affiliated with, endorsed by, or sponsored by Figma, Inc., Anthropic PBC, or Automattic Inc. &#8220;Figma&#8221; is a trademark of Figma, Inc. &#8220;Claude&#8221; is a trademark of Anthropic PBC. &#8220;WordPress&#8221; is a trademark of the WordPress Foundation.<\/p>\n<h3>Privacy<\/h3>\n<p><strong>Where test data lives.<\/strong> All test results, monitor definitions, monitor result history, and visual regression baselines live on the QAProof SaaS, scoped to your QAProof workspace. The plugin does NOT create custom database tables on fresh installs (a single legacy table \u2014 <code>{prefix}qaproof_monitors<\/code> \u2014 may exist on sites upgrading from a pre-1.7.0 release; its data is migrated to the SaaS on first upgrade and the table is dropped on uninstall).<\/p>\n<p><strong>Locally-stored data (in <code>wp_options<\/code> unless noted).<\/strong> All of the following carry the <code>qaproof_<\/code> prefix and the API-key option is forced non-autoloaded:<\/p>\n<ul>\n<li><code>qaproof_api_key<\/code> \u2014 your QAProof API key. Never displayed unmasked in the UI; non-autoloaded.<\/li>\n<li><code>qaproof_notify_email<\/code> \u2014 the configured notification recipient (defaults to the site admin email).<\/li>\n<li><code>qaproof_notify_email_enabled<\/code>, <code>qaproof_notify_admin_enabled<\/code>, <code>qaproof_default_threshold<\/code>, <code>qaproof_cron_hour<\/code> \u2014 notification preferences.<\/li>\n<li><code>qaproof_saved_designs<\/code> \u2014 page URL, Figma URL, optional cached PNG of the Figma design (bytes fetched from the connected Figma file). Non-autoloaded.<\/li>\n<li><code>qaproof_feedback_log<\/code> \u2014 ring buffer (max 200 entries, trimmed by age after 180 days) of in-admin &#8220;How was this test?&#8221; ratings. Each entry contains: the numeric rating, an optional free-text comment, the page URL, the test type, the score, the WordPress user ID of the author, and a timestamp.<\/li>\n<li><code>qaproof_figma_api_usage<\/code>, <code>qaproof_figma_rate_limit<\/code> \u2014 per-file Figma API request counts and rate-limit retry timers, used to back off when Figma&#8217;s per-plan quota is exhausted. No PII.<\/li>\n<li><code>qaproof_alert_count<\/code> \u2014 transient (30-day TTL) holding the admin-menu &#8220;you have N unread alerts&#8221; badge count.<\/li>\n<li><code>qaproof_db_version<\/code>, <code>qaproof_monitors_api_migrated<\/code> \u2014 version markers used by the one-time legacy migration.<\/li>\n<\/ul>\n<p><strong>Client-side (browser).<\/strong> The plugin&#8217;s JS sets the following <code>localStorage<\/code> keys (no cookies are set, no third-party storage is used):<\/p>\n<ul>\n<li><code>qaproof_theme<\/code> \u2014 your light \/ dark \/ auto theme preference.<\/li>\n<li><code>qaproof:design:&lt;id&gt;<\/code> \/ <code>qaproof:design:auto:&lt;id&gt;<\/code> \u2014 element-detection cache state per saved design so the in-admin UI shows the cached element overlay without a re-detection round-trip.<\/li>\n<\/ul>\n<p>Job IDs and a tab-open flag for active tests are written to <code>sessionStorage<\/code> (cleared when the tab closes).<\/p>\n<p><strong>WordPress privacy hooks (Tools <span aria-hidden=\"true\" class=\"wp-exclude-emoji\">\u2192<\/span> Export Personal Data \/ Erase Personal Data).<\/strong> The plugin registers a personal-data exporter and eraser covering: the notification recipient email and any feedback-log entries authored by the user whose email is requested. Local erasure removes these on this site only \u2014 it does NOT propagate to the QAProof SaaS. To delete SaaS-side test history, monitor results, or your QAProof account contact support@qaproof.io.<\/p>\n<p><strong>Where data is processed.<\/strong> api.qaproof.io is hosted in AWS us-east-1 (United States). The QAProof API forwards image bytes to Anthropic Claude (United States) for analysis, fetches Figma file exports from Figma&#8217;s API (United States) when you submit a Figma URL or connect Figma, and sends email reports via Amazon SES (United States). For EU-based site owners these are GDPR international transfers \u2014 see the QAProof Privacy Policy at https:\/\/qaproof.io\/privacy for the legal mechanisms in use.<\/p>\n<p><strong>Privacy Policy helper.<\/strong> The plugin contributes suggested copy to your site&#8217;s Privacy Policy via WordPress&#8217;s <code>wp_add_privacy_policy_content()<\/code>. Visit <strong>Settings <span aria-hidden=\"true\" class=\"wp-exclude-emoji\">\u2192<\/span> Privacy <span aria-hidden=\"true\" class=\"wp-exclude-emoji\">\u2192<\/span> Policy guide<\/strong> in your WordPress admin to review and merge it into your published Privacy Policy.<\/p>\n<p><strong>No analytics, no tracking.<\/strong> No tracking pixels, no fingerprinting, no analytics, and no third-party scripts run on the front-end of your site. All plugin assets (CSS, JS, fonts) are bundled locally \u2014 nothing is loaded from external CDNs.<\/p>","protected":false},"excerpt":{"rendered":"<p>Compare live pages against Figma, audit accessibility (WCAG 2.1), detect visual regressions, and analyze responsive behavior \u2014 powered by AI vision.<\/p>","protected":false},"author":1,"featured_media":9317,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[252],"tags":[829,1735,1736,1737,1723,555],"class_list":["post-10921","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-trends","tag-accessibility","tag-design-qa","tag-responsive","tag-visual-regression","tag-wcag","tag-wordpress-plugin"],"_links":{"self":[{"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/posts\/10921","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/comments?post=10921"}],"version-history":[{"count":0,"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/posts\/10921\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/media\/9317"}],"wp:attachment":[{"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/media?parent=10921"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/categories?post=10921"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/aeosub.com\/zh\/wp-json\/wp\/v2\/tags?post=10921"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}