今日已更新 84 条资讯 | 累计 37333 条内容
关于我们

标签:#playwright

找到 46 篇相关文章

AI 资讯

Playwright Email Testing: A Real End-to-End Tutorial (No Mocks)

Most "email testing" advice ends at stubbing the send call. You assert that your app tried to send a message, and the test goes green. That leaves the interesting half untested: whether the message actually left your infrastructure, whether the template rendered, and whether the six-digit code inside it matches the one your backend is willing to accept. This walks through the other approach — driving a real signup flow in Playwright , letting a real email get delivered to a real inbox, then reading it back over an API and typing the code into the page. No mail server to run, no shared QA mailbox to clean up. The shape of the problem A verification-email test has four moving parts: an address that is unique to this test run, the browser flow that triggers the send, a way to read the message that arrives, code extraction and the assertion. Steps 1 and 3 are the ones people get wrong, and they get them wrong in the same way: by sharing one mailbox across the suite. The moment two tests run in parallel, one of them reads the other's email. So the rule is one inbox per test , provisioned on the fly and thrown away afterwards. The inbox helper Any disposable-inbox API with a REST interface works here. I'll use MoeMail 's because it's open source and the free tier is enough for a CI suite — the shape is the same anywhere, so swap the base URL and the auth header if you use something else. // inbox.ts const API = ' https://moemail.app/api ' const KEY = process . env . MAIL_KEY ! export type Inbox = { id : string ; email : string } export async function createInbox ( ttlMs = 3 _600_000 ): Promise < Inbox > { const res = await fetch ( ` ${ API } /emails/generate` , { method : ' POST ' , headers : { ' X-API-Key ' : KEY , ' Content-Type ' : ' application/json ' }, // Omit `name` and a random local part is generated for you — which is // exactly what you want, so parallel tests can never collide. body : JSON . stringify ({ expiryTime : ttlMs , domain : ' moemail.app ' }), }) if

2026-08-29 原文 →
AI 资讯

A Unified KPI Framework for Automation Testing with Playwright & JavaScript

Measuring the impact of test automation goes beyond simple pass/fail ratios. To demonstrate real engineering excellence and business value, automation metrics must capture execution speed, suite stability, test coverage, maintenance cost, and CI/CD integration. Here is a comprehensive, unified KPI framework designed specifically for Playwright & JavaScript automation suites. 📊 Executive KPI Targets Category Metric Target Execution Speed Runtime Reduction 50% ↓ Efficiency Throughput +40% ↑ Stability Flaky Tests < 3% Reliability Retry Dependency < 5% Coverage Automation Coverage 80%+ Quality Defect Leakage 20–30% ↓ Productivity Script Dev Time 30% ↓ CI/CD Pipeline Time 40% ↓ ROI Automation ROI Positive (3–6 months) Cost Manual Effort Reduction 30–50% ↓ 1. Execution Efficiency & Speed Test Execution Time Reduction: Target 40–60% reduction vs legacy frameworks like Selenium. $$\text{Reduction \%} = \frac{\text{Old Time} - \text{New Time}}{\text{Old Time}} \times 100$$ Parallel Execution Efficiency: Measure tests executed per hour and parallel thread utilization. $$\text{Efficiency \%} = \frac{\text{Sequential Time} - \text{Parallel Time}}{\text{Sequential Time}} \times 100$$ Test Throughput: Maximize total test cases executed per CI window. CI/CD Pipeline Cycle Time: Aim for a 30–40% total reduction in build + test execution duration. 2. Stability & Reliability Flaky Test Rate: Keep flaky tests under 2–3% by leveraging Playwright's native auto-waiting and resilient locators. $$\text{Flakiness \%} = \frac{\text{Flaky Tests}}{\text{Total Tests}} \times 100$$ Retry Dependency Ratio: Track the percentage of tests passing only after retries to minimize false positives. Failure Root Cause Accuracy: Target >90% of test failures pointing directly to genuine application defects rather than script instability. 3. Coverage Metrics Automation Coverage: Maintain 80%+ regression coverage across all functional scenarios. Cross-Browser & Device Coverage: Measure test runs across Chromi

2026-08-26 原文 →
AI 资讯

End-to-End Setup Guide: Integrating Playwright + Cucumber with Harness CI

Integrating end-to-end (E2E) automation suites into enterprise CI/CD pipelines requires robust reporting, dynamic execution controls, and seamless artifact management. Here is a guide on setting up a Node.js + Playwright + Cucumber.js test suite using Harness CI , configured with dual-repository dependencies, parallel execution capabilities, and dashboard-ready reporting. Key Architectural Setup Two-Repo Architecture: Repository A (Application Automation Repo): Contains application-specific feature files, page objects, and pipeline definitions. Repository B (Shared Framework Repo): Hosts core framework utilities, custom assertions, and base drivers consumed as a pinned dependency. Tech Stack: Node.js, Playwright, Cucumber.js, Allure/JUnit reporting. Step 1: Configure Harness Connectors & Secrets Set up these foundational resources within your Harness account: Connectors: GIT_CONNECTOR: Grants access to both application and framework GitHub repositories. K8S_CONNECTOR: Manages the Kubernetes build infrastructure. Secrets: CONNECT_URL, CONNECT_USERNAME, and CONNECT_PASSWORD (and proxy settings if required). Step 2: Configure Pipelines Import your execution configurations using YAML files inside .harness/: Standard Run (.harness/e2e-poc.yaml): Used for fast PR checks. Parallel Regression (.harness/e2e-regression-parallel.yaml): Used for scheduled, high-volume regression runs. Replace placeholders such as , , and to map to your cluster environment. Step 3: Define Pipeline Triggers Set up two primary execution workflows: Pull Request (PR) Trigger: Event: Pull Request to main/POC branch. Runtime Variables: cucumberTags= @smoke Scheduled Nightly Trigger: Event: Scheduled Cron. Runtime Variables: cucumberTags=@regression, cucumberParallel=4 Step 4: Test Report & Artifact Collection To ensure test metrics display properly on the Harness dashboard, configure both JUnit parsing and raw artifact archiving. Generated Outputs: reports/junit-report.xml (parsed by Harness for test

2026-08-18 原文 →
AI 资讯

How to Improve Playwright Test Coverage Using Agent Context

I don’t know how to play an instrument, so obviously I built one as an app. Literally, everyone in my family can sign or play an instrument, and I’m the odd one out. And I know what you’re thinking, “Who cares? With AI, you can build almost anything.” I’m more excited about the technique I chose to build the app with my agent. Specifically I used context from the agent session that built the app to find and fix the most important gap in its Playwright tests. Here’s how I did it. Step 1: Install Entire Entire captures the prompts, transcripts, tool calls, and decisions behind agent-generated code, seamlessly connecting that underlying context to your Git commits through lightweight checkpoints. On macOS: brew tap entireio/tap brew install --cask entire Check out these instructions to install on your operating system. Step 2: Create the project I created an empty directory (or you can ask your agent to do this) mkdir music-app cd music-app Step 3: Enable Entire Before handing off any work to the agent, I initialized Entire directly within the repository because I wanted to capture my agent sessions: entire enable -y You can also target a specific agent (I personally use Codex): entire enable -y --agent codex This sets up the background hooks Entire relies on to capture agent activity, binding that session context directly to the commits generated along the way. Step 4: Turn the vague idea into a plan Rather than starting with a rigid technical spec, I simply shared my initial idea: I'm not entirely sure about the app i want to build..but i want to build a music app that enables me to play instruments even though idk how..this should use computer vision and it should be able to work with real instruments or just like "air" instruments as in there's no instrument there..but i am moving fingers and sounds are being made..and it should like im making real music. idk if this should be sonic pi..but i know i should use media pipe for it. lets start working on a plan togethe

2026-08-18 原文 →
AI 资讯

Best Practices for Playwright Locators: Building Flake-Resistant Test Automation

Fragile element locators are one of the primary drivers of test flakiness in UI automation. Relying on auto-generated, deeply nested CSS selectors or long XPath expressions makes your test suite sensitive to minor layout changes, styling refactors, and DOM updates. Adopting a clear locator strategy simplifies maintenance and ensures tests remain reliable as applications evolve. Core Principles for Locator Selection Prioritize Intent-Revealing Attributes: Always prefer dedicated, stable testing attributes such as data-test, data-testid, or data-qa. Avoid Style-Driven Locators: Steer clear of brittle, structure-dependent CSS paths (e.g., div > div > span:nth-child(2)) and complex XPath queries unless absolutely necessary. Preferred Selector Patterns Buttons & Actions: button[data-test="login-submit"] Content & Inputs: [data-testid="product-name"] Practical Migration Tips Centralize Locators: Group and manage all selector definitions inside dedicated Page Object Model (POM) files rather than hard-coding strings within step definitions or tests. Collaborate for Testability: If a critical UI element lacks a distinct test attribute, submit a quick PR to your developer team to add a dedicated data-test attribute. Automate Audits: Implement a lightweight audit script in your workflow to scan and flag missing data-test attributes across key target pages before running full regressions.

2026-08-17 原文 →
AI 资讯

Playwright Automation Quick-Start Runbook: Setup, Execution, and Environment Config

Having a clear runbook speeds up onboarding for new team members and provides a standardized execution reference for CI/CD environments. Here is a quick-start automation runbook covering prerequisites, environment variables, execution commands, and output artifacts for a Playwright test suite. Prerequisites Node.js: 24.x (configured via package.json engines) Package Manager: npm Optional: Docker (for containerized pipeline runs) Quick Setup # 1. Install project dependencies cd <repo-root> npm ci # 2. Install Playwright browsers and dependencies npx playwright install --with-deps Execution Commands Full Test Suite: npm test (executes run-all-tests.js) API Suite Only: npm run test:api (executes run-api-tests.js) UI Suite Only: npm run test:ui (executes run-ui-tests.js) Generate Reports: npm run generate:reports Core Environment Variables Configure these keys inside your local .env file or CI secrets: API_BASE_URL — Base endpoint URL for API testing BASE_URL — Target website base URL for UI testing RETRY_COUNT — Maximum retry limit for flaky scenario reruns CUCUMBER_PARALLEL — Number of parallel workers for Cucumber execution Test Artifacts & Outputs Allure Execution Results: reports/allure-results Cucumber JSON Reports: reports/cucumber_report.json Failure Media (Videos/Screenshots): test-results/ (configured via config.js)

2026-08-17 原文 →
AI 资讯

How to Build a Playwright BDD Test Framework from Scratch: Step-by-Step Setup Guide

Setting up a fresh test automation framework can feel overwhelming without a clear blueprint. Having a structured setup process ensures that directory layouts, configuration files, and execution scripts are aligned right from day one. Here is a quick setup guide for initializing a hybrid BDD framework powered by Playwright, Cucumber, and JavaScript. Installation & Directory Setup Start by installing project dependencies and creating the core folder hierarchy for feature files, step definitions, page objects, and utilities: # Install dependencies npm install # Create required folder structure mkdir features features/API features/UI mkdir step-definitions step-definitions/API step-definitions/UI mkdir page-objects utils setup setup/fixtures mkdir test-data test-data/json test-data/excel mkdir reports logs test-results Key Framework Files Ensure your framework repository includes the following core files: Configuration: package.json, playwright.config.js, cucumber.config.js Page Models & Drivers: page-objects/PageManager.js, utils/ApiHelper.js Hooks & Fixtures: setup/hooks.js Step Definitions: step-definitions/API/PlaywrightAPISteps.js, step-definitions/API/JsonTestDataSteps.js Test Data Strategy & Execution Test Data Management: Primary test data is managed via JSON (test-data/json/testData.json, test-data/json/apiTestData.json), with optional Excel support for tabular data inputs. Environment Setup: Store key environment variables (e.g., BASE_URL, API_BASE_URL) inside your local .env configuration file. Execution Commands: # Run API test suite npm run test :api # Run UI test suite npm run test :ui # Run full execution suite npm run test

2026-08-17 原文 →
AI 资讯

Setting Up Playwright & Cucumber UI Tests in Azure DevOps with LambdaTest

Here is a step-by-step guide to configuring your Playwright/Cucumber test suite to run on LambdaTest Cloud via Azure DevOps pipelines, returning test results directly to Azure. 1. Prerequisites A GitHub repository containing your Playwright, Cucumber, and JavaScript automation code. An active Azure DevOps account with a project created. A LambdaTest account (you will need your username and access key). 2. Connect GitHub to Azure DevOps In Azure DevOps, navigate to Pipelines > New Pipeline. Select GitHub as the source and authenticate your account. Choose your repository and target branch (e.g., main). 3. Create LambdaTest Credentials Variable Group Go to Pipelines > Library in Azure DevOps. Click + Variable group and name it LambdaTest-Credentials. Add the following key-value pairs: LAMBDATEST_USERNAME = your_lambdatest_username LAMBDATEST_ACCESS_KEY = your_lambdatest_access_key (toggle "Keep this value secret") Save the group. 4. Add/Update Your azure-pipelines.yml Place this configuration file in your repository root directory: trigger : - main pool : vmImage : ' windows-latest' variables : - group : LambdaTest-Credentials - name : BASE_URL value : ' https://your-app-url.com' - name : LT_BROWSER value : ' chrome' - name : ENABLE_LAMBDATEST value : ' true' stages : - stage : Test jobs : - job : UITestsLambdaTest displayName : ' UI Tests (LambdaTest Cloud)' steps : - task : NodeTool@0 inputs : versionSpec : ' 20.x' displayName : ' Install Node.js 20.x' - script : npm ci displayName : ' Install Dependencies' - script : npm run test:ui:smoke displayName : ' Run UI Smoke Tests on LambdaTest' env : ENABLE_LAMBDATEST : ' true' LT_USERNAME : $(LAMBDATEST_USERNAME) LT_ACCESS_KEY : $(LAMBDATEST_ACCESS_KEY) LT_BROWSER : $(LT_BROWSER) BASE_URL : $(BASE_URL) - task : PublishTestResults@2 condition : always() inputs : testResultsFormat : ' JUnit' testResultsFiles : ' reports/junit-report.xml' testRunTitle : ' UI Tests - LambdaTest Cloud' 5. Update Your Test Code Ensure your tes

2026-08-17 原文 →
AI 资讯

My evidence pipeline was saving Cloudflare block pages as evidence

I build a web service that preserves evidence of harassment on social platforms. The core feature is a single thing: automatically capture a real screenshot of the offending post. There was no substitute for it. I built an alternative that pulled the text through an API and rendered a tidy "evidence card" image, and threw it away. An image you can author freely afterwards proves nothing. Here's the conclusion first. Third-party wrappers eventually die, and when they do, the failure comes back as a plausible-looking image rather than an error. The first approach was refused by the other side I started with Cloudflare Browser Rendering. The wiring worked. The capture didn't. X blocks headless browsers. The request times out YouTube refuses script injection under a Trusted Types CSP. There's no way to make it render the comment Neither is a bug in my implementation — that is how they are built. So I declared Cloudflare alone impossible for this and moved to a service with a real browser and bot avoidance behind it. Both captures started working. For X, open the post page and clip the tweet element. For YouTube, open the URL with &lc= and screenshot just that comment element. Element screenshots have one trap worth knowing: selector_algorithm=clip returns a blank image when the element sits below the fold. The selector matches, the capture "succeeds," and the file is empty. That took a while to see. ytd-comment-thread-renderer :has ( a [ href *= "lc=ID" ]) A parameter that had worked started returning 400 I wanted timestamps rendered in Japan time, so I passed time_zone: Asia/Tokyo . One day every request started coming back 400. Every capture failed. The provider had narrowed which timezones they accept. Nothing changed on my side. I could diagnose it immediately only because I was storing the raw error body in the database. The response went into rawPayload.screenshotError , so opening one row told me why. Without that, this starts as "captures stopped working, no ide

2026-08-15 原文 →
AI 资讯

Claude Code can make videos: it records the app, narrates with ElevenLabs, and syncs audio to video automatically

I'm a solo builder. I needed a 2-minute product demo for ClinTrialFinder — a free tool I built that matches cancer patients to clinical trials. I can fumble through OBS and iMovie, but I'm not proficient — and Claude Code does it faster. So I asked Claude Code — an agentic coding tool — to make it. And it did: a narrated walkthrough where the voiceover lands exactly on the on-screen action. I never opened a screen recorder. I never opened a video editor. I never manually lined up a single caption to a single frame. Here's the video it produced . This post is about the three things the agent did to make it — because I think that combination is new. 1. It recorded the app — no screen recording Instead of me screen-capturing a session by hand, the agent wrote a Playwright script that drives the real, live web app : it opens the site, fills out the 10-step patient wizard with a synthetic case, submits, and records the finished results page — all headless, straight to video. That means no manual take, no re-shooting when I fumble a click, no "oops the mouse jittered." The recording is code , so it's deterministic and repeatable. When the product changes, the agent re-runs the script and out comes a fresh clip. It even injected a fake cursor that glides between elements, because a headless recording has no real mouse pointer. 2. It generated the narration — no microphone I didn't record a voiceover. The agent wrote the narration script, then called the ElevenLabs text-to-speech API to synthesize it in a clean, consistent voice. If I want to change a line, it edits the text and regenerates that clip in seconds — no re-recording, no "let me find a quiet room," no matching my tone across takes. // the agent calls ElevenLabs per narration phrase const res = await fetch ( `https://api.elevenlabs.io/v1/text-to-speech/ ${ VOICE } ` , { method : ' POST ' , headers : { ' xi-api-key ' : KEY , ' Content-Type ' : ' application/json ' }, body : JSON . stringify ({ text , model_id : '

2026-08-15 原文 →
AI 资讯

开源项目从 0 到 1:我用 2 周业余时间搭建了多平台发布系统

开源项目从 0 到 1:我是怎么用 2 周业余时间搭建多平台发布系统的 起因:一个周三晚上的崩溃 故事开始于一个普通的周三晚上。 22:00,写完了一篇 Python 教程。22:35,还在复制粘贴第 6 个平台。 当时心里想的是: 「我写了 40 分钟文章,为什么还要花 30 分钟发布?」 作为一个程序员的本能反应——这个问题应该用代码解决。 Day 1-2:技术选型 动手之前花了两天调研。核心问题是: 怎么跟 9 个平台对话? 经过调研发现,平台分三类: 类型 代表 方案 有公开 API 掘金、CSDN、Dev.to HTTP 请求直接调 有半公开 API 知乎、博客园 需要逆向签名(x-zse-96、X-Ca) 没有 API 小红书、抖音 只能 Playwright 浏览器模拟 技术栈决策: 后端: Python + FastAPI - 选 Python 因为 Playwright 的 Python 绑定最成熟 - 选 FastAPI 因为异步支持好,自带文档 前端: 原生 HTML/CSS/JS - 不需要 React/Vue。一个管理后台而已,原生 JS 完全够用 - 零 npm 依赖,部署简单 数据库: SQLite - 单文件,不需要装 MySQL/PostgreSQL - 个人工具,并发不是问题 浏览器插件: Chrome Extension Manifest V3 - 一键提取 Cookie,用户不用手动 F12 不做的事情: ❌ 不用 Docker(增加复杂度,个人部署不需要) ❌ 不用 Redis(SQLite 足够) ❌ 不用前端框架(过度设计) Day 3-5:搭建骨架 先搭最小可用版本: 一个 API + 一个页面 + 一个平台 。 选掘金作为第一个平台——它有公开 API,最简单。 # 核心抽象:每个平台一个 Adapter class BasePlatform : async def publish ( self , title , content , tags , credentials ) -> PublishResult : raise NotImplementedError async def fetch_stats ( self , post_id , credentials ) -> StatsResult : raise NotImplementedError 这个阶段的关键决策: 策略模式 :每个平台是一个独立的 Adapter 类,新增平台不改核心逻辑 异步优先 :所有网络请求用 async/await,发布 9 个平台可以并发 失败隔离 :一个平台失败不影响其他平台 骨架搭完后,掘金能发了。但只有一个平台没意义——得把所有平台都接上。 Day 6-10:攻克硬骨头 知乎:逆向 x-zse-96 签名 知乎的 API 要求每个请求带一个 x-zse-96 签名头。签名的生成逻辑藏在知乎前端的混淆 JS 里。 花了两个晚上逆向:原来是 MD5(特定参数 + d_c0 Cookie) → AES-CBC 加密 → 拼接前缀 。 def _make_x_zse_96 ( url : str , d_c0 : str ) -> str : source = f " 101_3_3.0+/api/v4/ { url } + { d_c0 } " md5_hash = hashlib . md5 ( source . encode ()). hexdigest () # ... AES-CBC 加密 ... return " 2.0_ " + encrypted . hex () 搞定的那一刻,知乎文章秒发——那种感觉比写完代码还爽。 CSDN:阿里云网关签名 CSDN 用的是阿里云 API 网关的 HMAC-SHA256 签名方案。文档是中文的,但签名串的格式写得很隐晦——分隔符必须是 \n ,不能是空格。这个细节浪费了我两个小时。 博客园:2002 年的 XML-RPC 博客园的 API 是 MetaWeblog XML-RPC——一个 2002 年的协议。Python 标准库自带的 xmlrpc.client 直接用。但有个坑:分类里不加 [Markdown] ,文章就会被当 HTML 解析。 小红书:Playwright 兜底 小红书没有公开 API,只能上 Playwright。但每次启动浏览器要 2-3 秒。优化手段: Cookie 持久化,跳过登录 先通过 API 拿到图片上传地址,只让 Playwright 做最后的表单提交 在 Linux 服务器上用 Xvfb 虚拟显示 Day 11-14:打磨产品 核心功能跑通后,开始打磨: 数据看板 :每个平台的阅读/点赞/评论自动汇

2026-08-12 原文 →
AI 资讯

A 500-Line Flutter Login Test Became One Promt

Lets start with a bit of back story. I am a full stack developer. Developer being the keyword here, not a QA developer. But in my current role, I was recently asked to come up with a testing suite for the web application and the Flutter app I was managing and maintaining. At that time, I didn’t have anything better to do and thought this would be a fun little project to work on for a couple of weeks. Boy o boy, I was wrong. People in QA are so opinionated. Everyone has their preferred framework, structure, naming convention, abstraction, folder structure and a very strong opinion about why your approach is wrong. Starting with the industry best practices I started by trying to follow the trends and best practices used in the industry. Page Object Models, reusable helpers, proper assertions and all the usual bits and bobs. For the web application, which was built with React, I chose Playwright. For the Flutter app, I went with integration_test . Sounded simple enough. The login test that took three hours The first test I tried to write was a simple login flow. Open the application Enter the username and password Press the login button Wait for the dashboard Easy, right? It took me ages. And by ages, I mean roughly three hours just to get the web test to pass reliably. The actual Playwright test ended up being around 300 lines once I included the boilerplate, setup, selectors, assertions, waits, Page Object Model structure and everything else needed around the actual journey. Then came the Flutter app. That one was worse. The app has its own custom way of starting different flavors, and both the web application and Flutter app are white-labelled products. That means there are a lot of variations to cover. Different branding, configurations, screens and sometimes slightly different user journeys. Before I could even test the login flow, I needed a pile of setup code just to launch the correct version of the app. The Flutter test eventually went beyond 500 lines, includ

2026-08-06 原文 →
AI 资讯

Test smarter with Snagly: 30 open-source QA skills for AI coding agents

If you've experimented with AI-driven testing, you've probably lived this cycle: you ask an AI agent to "test the checkout flow," and it does something — clicks around, declares success, and leaves you unsure what was actually verified. The next day you ask again and it does something different. The browser automation works; the testing discipline is missing. That gap is what Snagly is for. Rather than describe it, I pointed it at softwaretestingtrends.com — my own production site, nothing fixed beforehand — and recorded the whole thing. It found eleven issues, including a critical accessibility bug on my own signup page. One of its findings turned out to be wrong, and I'll come back to that, because it matters more than the ones it got right. 📺 Watch the full walkthrough — installed from an empty folder, run against production, ~20 minutes. What it is Snagly is a free, MIT-licensed set of 30 skills for AI coding agents — GitHub Copilot , Claude Code , Cursor, Codex and 70+ others — that turn "an AI that can drive a browser" into "an AI that tests like a QA professional." A skill, if you haven't met them yet, is a reusable instruction set that teaches the agent a specific working method — when to use it, what rigor it requires, what evidence to capture, and what it must never do. Each skill in Snagly has one job, and they hand off to each other the way a real testing practice does: start-testing is the front door — say "what can you test here?" and it routes you to the right skill, checking prerequisites before handing off. Discovery & strategy : scenario-mapper explores your site and produces a prioritized list of test scenarios; test-case-writer expands any of them into a reviewable spec; test-plan sets strategy, cadence, and release exit criteria; qa-onboarding writes the guide for your next hire. Execution : flow-runner drives real user journeys step by step, asserting outcomes (not just that clicks happened) and capturing evidence the moment anything fails. cru

2026-08-05 原文 →
AI 资讯

The Test Framework Is Not the Product

A few years ago, the hardest part of building a browser test framework was getting started. You had to choose a runner, configure browsers, create page objects, wire up reporting, add retries, manage secrets, connect it to CI, and convince someone else on the team to learn how the whole thing worked. Today, you can open an AI assistant and ask it to generate most of that before lunch. That sounds like a dramatic improvement. In some ways, it is. But it also moves the bottleneck. The question is no longer, “Can we create a framework?” The question is, “Can we operate what was created?” That distinction matters more than it appears. Generation cost is not ownership cost A generated framework feels cheap because the first version arrives quickly. The code compiles, a few tests pass, and the pull request looks more complete than anything you could have written in an afternoon. Then reality starts applying pressure. The application changes. Authentication behaves differently in staging. A shared helper starts hiding failures. Parallel workers collide over test data. Someone upgrades a dependency and three reporters stop agreeing with one another. The initial generation was fast. The ownership cost was merely deferred. This is the central problem described in what actually breaks when Claude generates a large Playwright framework . Large generated systems often fail in the seams: fixtures, abstractions, environment assumptions, test data, and conventions that were never explicitly agreed upon. The code may be readable line by line while the system remains difficult to reason about as a whole. That is a dangerous form of complexity because it looks productive. More code can hide less understanding Teams sometimes evaluate AI-generated automation by counting output: number of test files; number of scenarios; number of passing checks; number of prompts completed; number of lines added. Those numbers are easy to produce and easy to report. They are also weak proxies for confi

2026-07-28 原文 →
AI 资讯

How Much of Your CI Pipeline Is Just Cucumber Scenarios You're Too Afraid to Delete

The CI job just hit 28 minutes. Again. You pull up the duration report expecting to blame a bloated integration test or a slow environment spin‑up. Instead the longest stage stares back at you: a collection of Cucumber feature files that haven’t caught a real bug in months. Maybe years. They run on every commit, green circle after green circle, while your team mutters about slow pipelines and nobody dares touch them. Most teams treat those scenarios like documentation. “They describe the system,” someone once said, as if a Gherkin file were a legal contract. Others cling to the sunk cost: a year ago a whole squad spent two sprints writing them, polishing the grammar, aligning step definitions. Deleting them would feel like admitting waste. Experienced engineers see it differently. They treat a scenario that never fails as a liability you’re paying for on every push. Not neutral. Liable. Compute cycles, developer attention, flake‑debugging time, and the quiet toll it takes on trust in the pipeline. The principle is blunt: if a test hasn’t failed in the last few sprints, you’re already paying its full cost and receiving nothing in return. That doesn’t mean you delete everything green. But it does mean you audit with the same seriousness you’d use for a memory leak. What the green wall actually costs The damage is not abstract. A pipeline bloated with stale scenarios hurts you in five concrete ways. First, feedback slows. Every extra minute between push and result stretches the loop that tells a developer they’re safe to merge. Multiply across a team and you’re losing hours per week to waiting. Second, flakiness increases. When you have many scenarios, a single unstable environment variable can produce a handful of failures that are not regressions at all. Engineers learn to retry, then to ignore. Third, confidence erodes. If half the suite is ceremonial, a genuine failure might be dismissed as “just another flaky test” until it reaches production. Fourth, maintenance

2026-07-27 原文 →
AI 资讯

3 Portfolio Mistakes Hiring Managers Spot Instantly

The manager opens your portfolio. Your resume says you have five years of automation experience. The README lists Selenium, Playwright, Appium, Jenkins, Docker, Kubernetes. He scrolls. There is no code. The browser tab closes. This is you. Not because you lack skill—you have it—but because your public proof reads like a shopping list. The tools you name say nothing about how you think when a flaky test fails at 2am, or how you convince a developer that a bug is real. If you’re serious about landing a role that demands more than record-and-playback, you need to stop treating your portfolio like a keyword bingo card. Here are three mistakes that kill your chances instantly, and exactly how to fix them. Mistake 1: Tool jockeying Listing every automation framework you’ve heard of is a reflex. A hiring manager sees "Proficient in Cypress, Playwright, Selenium, WebDriverIO" and assumes you ran npm init once in each and called it done. Most testers frontload tools because they’re scared of the empty space where code belongs. Experienced testers show one test, deliberately written, with a comment that explains a trade-off they chose. The difference is not volume. A single 30-line script that handles a login flow with a purposeful wait strategy teaches more about you than a six-tool résumé. I’ve deleted my own old projects after re-reading them and realizing they said nothing about why any assertion existed. That quiet cringe is the signal you’re ready to improve. What you ship in your portfolio must answer one question: "What did this person decide, and why?" Move your tool list to a footnote. Let a real test carry the message. Mistake 2: The perfect test trap A portfolio full of green builds is a trap. Every team knows that real automation breaks: the CI node runs slow, the third-party API throttles you, the DOM renders a fraction of a second late. Showing only passing tests hides how you handle the ugly parts of the job. Most testers polish every assertion until it’s spot

2026-07-27 原文 →
AI 资讯

The Manual Tester Who Can Write a SQL Join Will Always Beat the SDET Who Can't

Most people think the SDET title means you are automatically more valuable than a manual tester. The SDET writes Playwright scripts. The SDET configures CI pipelines. The SDET talks about page objects and retry strategies. The manual tester clicks through screens and writes bug reports. Here is the truth I have watched play out across teams: the manual tester who can write a SQL join will consistently outperform the SDET who cannot. Not because SQL is magic. Because SQL is the shortest path to understanding what the system actually stores, not what the UI shows you. The problem with automation-first thinking I have seen SDETs spend three sprints building a test suite that validates every button, every dropdown, every error toast. The suite passes in CI. The suite passes in staging. The suite passes in production. And the bug still ships. Why? Because the test checked that the UI rendered correctly. It never checked that the database actually saved the right record. The SDET wrote assertions against DOM elements, not against data. The manual tester, meanwhile, ran a simple query. Saw the order status was "pending" when it should have been "confirmed." Filed a bug with the exact SQL that proved the issue. The developer fixed it in ten minutes. That is not a story about manual versus automated. That is a story about data literacy versus UI obsession. What a SQL join gives you that a locator never will A Playwright locator tells you something is on the screen. A SQL join tells you something is true. When you write page.getByText('Order confirmed') , you are testing that the frontend displays those words. You are not testing that the backend actually confirmed the order. You are not testing that the payment gateway returned success. You are not testing that the inventory decremented. A SQL join connects those dots. SELECT o . id , o . status , p . status AS payment_status , i . quantity AS remaining_stock FROM orders o JOIN payments p ON o . id = p . order_id JOIN invent

2026-07-27 原文 →
AI 资讯

Your OpenAPI spec is already a test plan — here's how to turn it into Playwright tests automatically

If you're writing Playwright API tests manually from an OpenAPI/Swagger spec, you're doing work that should be automated. Every endpoint in your spec already tells you: What the request looks like (path, method, parameters, body schema) What responses to expect (200, 401, 404, 422...) What fields are required What security is needed That's not documentation — it's a test plan. You're just not running it yet. What I built I got tired of the boilerplate loop: read spec → write happy path → add 401 test → add missing-field test → repeat for 40 endpoints. So I built a tool that does it for you. swagger-to-playwright.vercel.app takes your OpenAPI 3.x spec (YAML or JSON) and generates a ready-to-run Playwright .spec.ts file. For each endpoint, it produces four tests: 1. Happy path — calls the endpoint with valid data, asserts 2xx response and key fields in the body. 2. Auth check — if your spec declares a security scheme, it calls without a token and asserts 401. Only generated when the spec actually says authentication is required — no false positives. 3. Input validation — sends a request with missing required fields (or wrong types, invalid enums) and asserts 422. Reads directly from your schema's required array and field types. 4. Contract validation — if there's a path parameter, it calls with an invalid value and asserts 404. What the output looks like Here's what you get for a POST /users endpoint with email and password required: import { test , expect } from ' @playwright/test ' ; test . describe ( ' POST /users ' , () => { test ( ' happy path — creates user successfully ' , async ({ request }) => { const res = await request . post ( ' /users ' , { data : { email : ' test@example.com ' , password : ' password123 ' } }); expect ( res . status ()). toBe ( 201 ); const body = await res . json (); expect ( body ). toHaveProperty ( ' id ' ); }); test ( ' auth — 401 without token ' , async ({ request }) => { const res = await request . post ( ' /users ' , { headers : {

2026-07-25 原文 →
AI 资讯

Why Most Web Change Monitors Fail: Solving DOM Mutations and False Positives

If you have ever tried building a website change detection system or visual testing tool, you’ve likely stumbled into the "False Positive Trap." You configure a cron job to monitor a target URL, take snapshots every 15 minutes, and compare them. But within hours, your inbox is flooded with alerts for: Tailwind CSS dynamic hash class mutations (e.g. class="bg-blue-500_a3f9" turning into class="bg-blue-500_b81c" after a deployment) Lazy-loaded images rendering at offset offsets Anti-bot verification scripts altering invisible DOM nodes Hydration mismatches in React/Vue single-page applications At PageWatch.tech , solving these exact edge cases was the primary focus of our engineering roadmap. In this article, I’ll share the 3 core algorithmic fixes we implemented to achieve reliable, noise-free website change monitoring. 🛑 Problem 1: Structural Hash Instability in Modern Frameworks Modern frontend frameworks like Next.js, Nuxt, and Remix insert dynamic build IDs, hydration keys, and inline CSS chunk hashes into the HTML structure. For example, a innocent paragraph tag might look like this today: <p class= "text-gray-700 css-1a2b3c" data-reactroot= "" > Product Price: $99 </p> And like this tomorrow after a routine production deployment: <p class= "text-gray-700 css-9x8y7z" data-reactroot= "" > Product Price: $99 </p> A standard raw string comparison flags this as a critical change even though zero user-facing content changed . The Solution: Attribute Normalization & CSS Class Sanitization Before computing DOM structural hashes, we run a normalize pass that strips generated hashes and framework-specific attributes: import * as htmlparser2 from " htmlparser2 " ; /** * Normalizes dynamic framework attributes and hashed CSS classes * before running DOM diff calculations. */ export function normalizeDOMNode ( node : any ): void { if ( node . attribs ) { // 1. Remove hydration and framework metadata const volatileAttrs = [ " data-reactroot " , " data-reactid " , " data-hydr

2026-07-23 原文 →