惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
B
Blog RSS Feed
Microsoft Azure Blog
Microsoft Azure Blog
J
Java Code Geeks
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Google DeepMind News
Google DeepMind News
F
Fortinet All Blogs
V
V2EX
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Engineering at Meta
Engineering at Meta
月光博客
月光博客
阮一峰的网络日志
阮一峰的网络日志
M
MIT News - Artificial intelligence
IT之家
IT之家
博客园 - 【当耐特】
U
Unit 42
云风的 BLOG
云风的 BLOG
L
LangChain Blog
小众软件
小众软件
Microsoft Security Blog
Microsoft Security Blog
B
Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
宝玉的分享
宝玉的分享
N
Netflix TechBlog - Medium

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
How I built an AI reporter for Playwright that explains t...
Santiago Ech · 2026-05-14 · via DEV Community

After 6 years doing QA automation in Fintech, I got tired of the same cycle:

Test fails in CI
Download the report
Spend 20 minutes reading stack traces
Realize it was a one-line selector issue

So I built a custom Playwright reporter that does the debugging for you.
What it does
When a test fails, the reporter automatically:

Captures the test name, error message, and stack trace
Sends it to an AI with a structured prompt
Gets back a root cause, a TypeScript fix, and a prevention tip
Saves everything to test-results/ai-diagnosis.md

Here's what the output looks like:
❌ Login › locked out user sees lock message

🔍 Analyzing failure: "locked out user sees lock message"


❌ locked out user sees lock message

1. Root cause

The selector [data-test="error"] matched but the assertion
expected different text than what Sauce Demo returned.

2. Fix

await expect(loginPage.errorMessage).toContainText(
  'Epic sadface: Sorry, this user has been locked out.'
);

Enter fullscreen mode Exit fullscreen mode

3. Prevention

Always assert the exact error string shown in the UI, not a partial guess.

📄 Diagnosis saved → test-results/ai-diagnosis.md
The architecture
The key design decision was making the AI provider swappable at runtime via environment variable. No code changes needed — just update your .env:
bash# Free default
AI_PROVIDER=groq
GROQ_API_KEY=your_key

Or swap to Claude / OpenAI

AI_PROVIDER=claude
ANTHROPIC_API_KEY=your_key
This is powered by a simple AIProvider interface:
typescriptexport interface AIProvider {
analyzeFailure(testName: string, error: string): Promise;
}
Each provider (Groq, Claude, OpenAI) implements this interface. The factory reads the env var and returns the right one:
typescriptexport function createProvider(): AIProvider {
const provider = process.env.AI_PROVIDER ?? 'groq';
switch (provider) {
case 'claude': return new ClaudeProvider();
case 'openai': return new OpenAIProvider();
default: return new GroqProvider(); // free, no credit card
}
}
The reporter itself
Playwright lets you build custom reporters by implementing the Reporter interface. The key hook is onTestEnd:
typescriptexport class AIReporter implements Reporter {
async onTestEnd(test: TestCase, result: TestResult) {
if (result.status !== 'failed') return;

const provider = createProvider();
const diagnosis = await provider.analyzeFailure(
  test.title,
  result.error?.message ?? 'Unknown error'
);

console.log(`\n🔍 Analyzing failure: "${test.title}"\n`);
console.log(diagnosis);

fs.appendFileSync('test-results/ai-diagnosis.md', diagnosis);

Enter fullscreen mode Exit fullscreen mode

}
}
Clean and minimal — it only runs when a test fails, so it doesn't slow down passing suites.
The full project structure
The repo also includes a full working example with Sauce Demo:
playwright-ai-reporter/
├── src/ai/
│ ├── AIProvider.interface.ts # shared contract
│ ├── GroqProvider.ts # free default
│ ├── ClaudeProvider.ts
│ ├── OpenAIProvider.ts
│ └── providerFactory.ts
├── reporters/
│ └── AIReporter.ts
├── tests/saucedemo/
│ ├── login.spec.ts
│ ├── cart.spec.ts
│ └── checkout.spec.ts
├── pages/ # Page Object Models
├── fixtures/ # shared Playwright fixtures
└── .github/workflows/
└── playwright.yml # CI already configured
CI with GitHub Actions
The workflow runs on every push. It uploads the HTML report as an artifact always, and uploads ai-diagnosis.md only when there are failures — so you always know exactly what broke and why.
yaml- name: Upload AI diagnosis
if: failure()
uses: actions/upload-artifact@v4
with:
name: ai-diagnosis
path: test-results/ai-diagnosis.md
AI provider comparison
ProviderCostSpeedQualityBest forGroq (Llama 3)FreeVery fastGoodPortfolio, small teamsClaude Haiku~$0.001/testFastVery goodMedium teamsClaude Sonnet~$0.005/testMediumExcellentEnterpriseGPT-4o-mini~$0.003/testFastVery goodAlternative
I use Groq for local dev (free tier is more than enough) and would use Claude Sonnet for a production CI pipeline where diagnosis quality matters.
What's next
A few things I want to add:

Screenshot attachment in the diagnosis when available
Grouping repeated failures to avoid duplicate AI calls
Slack/Teams notification with the diagnosis embedded

Try it yourself
bashgit clone https://github.com/sechavarriar/playwright-ai-reporter
cd playwright-ai-reporter
npm install
npx playwright install chromium
cp .env.example .env

Add your free Groq key from console.groq.com

npm test
The repo is at https://github.com/sechavarriar/playwright-ai-reporter — feedback and PRs very welcome. Especially curious if anyone has ideas for handling flaky tests differently.