<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Srikanth Srinivas</title>
    <description>The latest articles on DEV Community by Srikanth Srinivas (@srikanth_srinivas_22928e3).</description>
    <link>https://dev.to/srikanth_srinivas_22928e3</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2816086%2Fe8b27a62-c04d-46ff-b38e-a981054a9dcc.png</url>
      <title>DEV Community: Srikanth Srinivas</title>
      <link>https://dev.to/srikanth_srinivas_22928e3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/srikanth_srinivas_22928e3"/>
    <language>en</language>
    <item>
      <title>Playwright Studio from AIQEAcademy</title>
      <dc:creator>Srikanth Srinivas</dc:creator>
      <pubDate>Sat, 11 Apr 2026 02:26:21 +0000</pubDate>
      <link>https://dev.to/srikanth_srinivas_22928e3/-title-i-built-a-chrome-devtools-extension-to-record-assert-and-run-playwright-tests-without-45ic</link>
      <guid>https://dev.to/srikanth_srinivas_22928e3/-title-i-built-a-chrome-devtools-extension-to-record-assert-and-run-playwright-tests-without-45ic</guid>
      <description>&lt;p&gt;&lt;strong&gt;Playwright Studio&lt;/strong&gt; is a Chrome DevTools extension that lets you record interactions, add assertions, save tests with version history, and run them headlessly — all from inside DevTools. No terminal. No setup. No copy-pasting from &lt;code&gt;codegen&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem With Existing Tools
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;playwright codegen&lt;/code&gt; is excellent for a quick start. But it has real limitations in daily use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It opens a separate browser window — breaking your authenticated session&lt;/li&gt;
&lt;li&gt;Generated code needs manual cleanup before it's mergeable&lt;/li&gt;
&lt;li&gt;There's no way to add assertions interactively&lt;/li&gt;
&lt;li&gt;Nothing is saved — it's a one-shot dump to stdout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For teams doing continuous authoring — adding coverage as features ship — you need something embedded in your workflow. That's what Playwright Studio is.&lt;/p&gt;




&lt;h2&gt;
  
  
  What It Does
&lt;/h2&gt;

&lt;p&gt;The extension lives in your Chrome DevTools panel. Here's the core loop:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Record
&lt;/h3&gt;

&lt;p&gt;Click &lt;strong&gt;Record&lt;/strong&gt; and interact with the page normally. The extension captures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;page.goto()&lt;/code&gt; calls from navigation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;page.click()&lt;/code&gt; with Playwright-native locators (preferring &lt;code&gt;getByRole&lt;/code&gt;, &lt;code&gt;getByLabel&lt;/code&gt;, &lt;code&gt;getByText&lt;/code&gt; over brittle CSS selectors)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;page.fill()&lt;/code&gt; for inputs&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;page.selectOption()&lt;/code&gt; for dropdowns&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;page.check()&lt;/code&gt; / &lt;code&gt;page.uncheck()&lt;/code&gt; for checkboxes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every captured action generates idiomatic Playwright code in real time — you see it build line by line in the panel.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Example of what gets generated:&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User login flow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://myapp.com/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;••••••••&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sign in&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Welcome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})).&lt;/span&gt;&lt;span class="nf"&gt;toBeVisible&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Assert
&lt;/h3&gt;

&lt;p&gt;Right-click any element while recording and add assertions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Assertion&lt;/th&gt;
&lt;th&gt;Generated Code&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Visible&lt;/td&gt;
&lt;td&gt;&lt;code&gt;await expect(locator).toBeVisible()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Has text&lt;/td&gt;
&lt;td&gt;&lt;code&gt;await expect(locator).toHaveText('...')&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;URL matches&lt;/td&gt;
&lt;td&gt;&lt;code&gt;await expect(page).toHaveURL('...')&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ARIA role&lt;/td&gt;
&lt;td&gt;&lt;code&gt;await expect(locator).toHaveRole('button')&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Count&lt;/td&gt;
&lt;td&gt;&lt;code&gt;await expect(locator).toHaveCount(3)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;No manual &lt;code&gt;expect()&lt;/code&gt; wiring. You pick the element, pick the assertion type, and it slots into the generated test at the right position.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Save
&lt;/h3&gt;

&lt;p&gt;Tests are saved inside the extension with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt; and &lt;strong&gt;tags&lt;/strong&gt; for organization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version history&lt;/strong&gt; — every edit creates a new version, old ones are preserved&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Selector tracking&lt;/strong&gt; — the extension records which locators were used so you can spot fragility early&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metadata&lt;/strong&gt; — source, timestamp, test status&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Run
&lt;/h3&gt;

&lt;p&gt;Hit &lt;strong&gt;Run&lt;/strong&gt; and the test executes headlessly inside Chrome using the Playwright runner bundled with the extension. Results come back as a step-by-step pass/fail report — no terminal needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Export
&lt;/h3&gt;

&lt;p&gt;One click exports a clean &lt;code&gt;.spec.ts&lt;/code&gt; file. Drop it into your existing Playwright project. It works.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;The extension is built on Chrome's &lt;strong&gt;Manifest V3&lt;/strong&gt; with three layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────┐
│  DevTools Panel (React)                       │
│  Recording UI · Test editor · Result viewer   │
└────────────────────┬─────────────────────────┘
                     │ chrome.runtime.sendMessage
┌────────────────────▼─────────────────────────┐
│  Background Service Worker                    │
│  State management · Test storage · Runner     │
└────────────────────┬─────────────────────────┘
                     │ chrome.scripting.executeScript
┌────────────────────▼─────────────────────────┐
│  Content Script                               │
│  DOM event capture · Selector generation      │
└──────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Selector Strategy
&lt;/h3&gt;

&lt;p&gt;The hardest part of any recorder is generating selectors that don't break the moment someone renames a CSS class. Playwright Studio uses a priority-ordered strategy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;getByRole()&lt;/code&gt; — if the element has a semantic ARIA role and accessible name&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getByLabel()&lt;/code&gt; — for form inputs bound to a &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getByText()&lt;/code&gt; — for elements with stable visible text&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getByTestId()&lt;/code&gt; — if &lt;code&gt;data-testid&lt;/code&gt; is present&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;locator('css=...')&lt;/code&gt; — last resort, flagged as potentially fragile&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each selector is stored alongside fallbacks, laying the groundwork for self-healing in a future release.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Runner
&lt;/h3&gt;

&lt;p&gt;Running tests from inside the extension uses a sandboxed execution context. The generated Playwright script is evaluated with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Action replay against the live page&lt;/li&gt;
&lt;li&gt;Step-level timing capture&lt;/li&gt;
&lt;li&gt;Console log collection&lt;/li&gt;
&lt;li&gt;Screenshot on failure&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What's Coming Next
&lt;/h2&gt;

&lt;p&gt;Playwright Studio v1 covers the core authoring loop. The roadmap includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud sync&lt;/strong&gt; — push tests from the extension to a cloud backend, run them remotely with full parallel execution across Chromium/Firefox/WebKit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI assertion generation&lt;/strong&gt; — right-click an element and Claude suggests the most meaningful assertion based on context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-healing selectors&lt;/strong&gt; — when a selector breaks, the extension proposes a fix based on the updated DOM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visual regression&lt;/strong&gt; — capture baseline screenshots and diff them on every run&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP integration&lt;/strong&gt; — expose tests to AI agents (Claude, Cursor, VS Code Copilot) via the Model Context Protocol&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://chromewebstore.google.com/detail/playwright-studio-by-aiqe/eodfkbagoeghobkkfpcfpacnnpgidhhd?authuser=0&amp;amp;hl=en" rel="noopener noreferrer"&gt;https://chromewebstore.google.com/detail/playwright-studio-by-aiqe/eodfkbagoeghobkkfpcfpacnnpgidhhd?authuser=0&amp;amp;hl=en&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Platform&lt;/strong&gt;: &lt;a href="https://aiqeacademy.onrender.com" rel="noopener noreferrer"&gt;aiqeacademy.onrender.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Early access&lt;/strong&gt;: Drop a comment or reach out directly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're building test automation tooling, working on Chrome extensions, or just have opinions about Playwright selector strategies — I'd love to hear from you.&lt;/p&gt;




</description>
      <category>productivity</category>
      <category>showdev</category>
      <category>testing</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Playwright Series #1 — What Is Playwright and Why It Beats Everything Else</title>
      <dc:creator>Srikanth Srinivas</dc:creator>
      <pubDate>Thu, 09 Apr 2026 01:06:08 +0000</pubDate>
      <link>https://dev.to/srikanth_srinivas_22928e3/playwright-series-1-what-is-playwright-and-why-it-beats-everything-else-200i</link>
      <guid>https://dev.to/srikanth_srinivas_22928e3/playwright-series-1-what-is-playwright-and-why-it-beats-everything-else-200i</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally published on&lt;br&gt;
&lt;a href="https://aiqeacademy.onrender.com/blog/playwright-01-introduction" rel="noopener noreferrer"&gt;AIQEAcademy&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What Is Playwright?&lt;br&gt;
Playwright is an open-source browser automation framework built by Microsoft. It lets you write tests that control a real browser — clicking buttons, filling forms, navigating pages — exactly as a real user would.&lt;/p&gt;

&lt;p&gt;What separates Playwright from everything that came before it:&lt;/p&gt;

&lt;p&gt;All browsers, one API — Chromium, Firefox and WebKit (Safari engine) from a single test file&lt;br&gt;
Auto-waiting — no more sleep(2000) hacks; Playwright waits for elements to be ready before acting&lt;br&gt;
Network interception — intercept, modify or mock any HTTP request from your tests&lt;br&gt;
Parallel by default — tests run in parallel across multiple workers out of the box&lt;br&gt;
Tracing — record a full video, screenshot timeline and network log of every test run&lt;br&gt;
Why Not Selenium?&lt;br&gt;
Selenium is 20 years old. It works, but it was designed in an era of synchronous web apps. You feel that age:&lt;/p&gt;

&lt;p&gt;Feature Selenium    Playwright&lt;br&gt;
Auto-waiting    ❌ Manual WebDriverWait    ✅ Built-in everywhere&lt;br&gt;
Network mocking ❌ Requires proxy setup    ✅ Native page.route()&lt;br&gt;
Parallel execution  ❌ Grid setup required ✅ Built-in workers&lt;br&gt;
Trace viewer    ❌ None    ✅ Full timeline recorder&lt;br&gt;
Setup time  Hours   Minutes&lt;br&gt;
Flakiness   High    Low&lt;br&gt;
Why Not Cypress?&lt;br&gt;
Cypress solved many Selenium problems but introduced its own constraints:&lt;/p&gt;

&lt;p&gt;No multi-tab support — Playwright handles multiple tabs and windows natively&lt;br&gt;
No cross-browser — Cypress only supports Chromium-based browsers and Firefox (no Safari)&lt;br&gt;
No multi-domain — Cypress historically struggled with navigating across different origins in one test&lt;br&gt;
JavaScript only — Playwright supports TypeScript, JavaScript, Python, Java and C#&lt;br&gt;
Why Not WebdriverIO?&lt;br&gt;
WebdriverIO is excellent and worth learning, but Playwright wins on:&lt;/p&gt;

&lt;p&gt;Simpler setup (no separate driver management)&lt;br&gt;
Better auto-waiting implementation&lt;br&gt;
Native trace viewer&lt;br&gt;
Faster test execution&lt;br&gt;
Installing Playwright&lt;br&gt;
You need Node.js 18 or higher. Check your version:&lt;/p&gt;

&lt;p&gt;node --version&lt;/p&gt;

&lt;h1&gt;
  
  
  should output v18.x.x or higher
&lt;/h1&gt;

&lt;p&gt;Create a new project and run the Playwright installer:&lt;/p&gt;

&lt;p&gt;mkdir my-playwright-project&lt;br&gt;
cd my-playwright-project&lt;br&gt;
npm init -y&lt;br&gt;
npm init playwright@latest&lt;br&gt;
The installer asks a few questions:&lt;/p&gt;

&lt;p&gt;✔ Do you want to use TypeScript or JavaScript? › TypeScript&lt;br&gt;
✔ Where to put your end-to-end tests? › tests&lt;br&gt;
✔ Add a GitHub Actions workflow? › false  (we'll cover CI in Part 10)&lt;br&gt;
✔ Install Playwright browsers? › true&lt;br&gt;
Say yes to installing browsers. This downloads Chromium, Firefox and WebKit — about 300MB total. Only needed once per machine.&lt;/p&gt;

&lt;p&gt;What Got Created&lt;br&gt;
After installation your project looks like this:&lt;/p&gt;

&lt;p&gt;my-playwright-project/&lt;br&gt;
├── tests/&lt;br&gt;
│   └── example.spec.ts      ← sample test Playwright generates&lt;br&gt;
├── playwright.config.ts      ← all configuration lives here&lt;br&gt;
├── package.json&lt;br&gt;
└── node_modules/&lt;br&gt;
Your First Look at playwright.config.ts&lt;br&gt;
Open playwright.config.ts. The defaults are sensible, but let's understand the key parts:&lt;/p&gt;

&lt;p&gt;import { defineConfig, devices } from '@playwright/test';&lt;/p&gt;

&lt;p&gt;export default defineConfig({&lt;br&gt;
  // Where your test files live&lt;br&gt;
  testDir: './tests',&lt;/p&gt;

&lt;p&gt;// Run tests in parallel&lt;br&gt;
  fullyParallel: true,&lt;/p&gt;

&lt;p&gt;// Retry failed tests once in CI&lt;br&gt;
  retries: process.env.CI ? 1 : 0,&lt;/p&gt;

&lt;p&gt;// Number of parallel workers&lt;br&gt;
  workers: process.env.CI ? 2 : undefined,&lt;/p&gt;

&lt;p&gt;// Test timeout (30 seconds per test)&lt;br&gt;
  timeout: 30_000,&lt;/p&gt;

&lt;p&gt;// Reporter — list in dev, HTML report in CI&lt;br&gt;
  reporter: [['list'], ['html', { open: 'never' }]],&lt;/p&gt;

&lt;p&gt;use: {&lt;br&gt;
    // Base URL so you can write await page.goto('/login') instead of full URL&lt;br&gt;
    baseURL: '&lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;',&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Capture trace on first retry
trace: 'on-first-retry',

// Take screenshot on failure
screenshot: 'only-on-failure',
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;},&lt;/p&gt;

&lt;p&gt;// Run tests against these browsers&lt;br&gt;
  projects: [&lt;br&gt;
    { name: 'chromium', use: { ...devices['Desktop Chrome'] } },&lt;br&gt;
    { name: 'firefox',  use: { ...devices['Desktop Firefox'] } },&lt;br&gt;
    { name: 'webkit',   use: { ...devices['Desktop Safari'] } },&lt;br&gt;
  ],&lt;br&gt;
});&lt;br&gt;
Running the Sample Test&lt;br&gt;
Run the sample test Playwright generated:&lt;/p&gt;

&lt;p&gt;npx playwright test&lt;br&gt;
You'll see output like:&lt;/p&gt;

&lt;p&gt;Running 6 tests using 6 workers&lt;/p&gt;

&lt;p&gt;✓  tests/example.spec.ts:3:5 › has title (1.2s)&lt;br&gt;
  ✓  tests/example.spec.ts:3:5 › has title (chromium) (1.2s)&lt;br&gt;
  ✓  tests/example.spec.ts:3:5 › has title (firefox) (1.8s)&lt;br&gt;
  ✓  tests/example.spec.ts:3:5 › has title (webkit) (2.1s)&lt;br&gt;
  ...&lt;/p&gt;

&lt;p&gt;6 passed (5.3s)&lt;br&gt;
All three browsers. No setup. No driver management. It just works.&lt;/p&gt;

&lt;p&gt;Viewing the HTML Report&lt;br&gt;
After the run, open the HTML report:&lt;/p&gt;

&lt;p&gt;npx playwright show-report&lt;br&gt;
This opens a browser with a full breakdown of every test, browser, timing and any screenshots.&lt;/p&gt;

&lt;p&gt;The Playwright VS Code Extension&lt;br&gt;
If you use VS Code, install the official Playwright extension:&lt;/p&gt;

&lt;p&gt;Open Extensions (Cmd+Shift+X / Ctrl+Shift+X)&lt;br&gt;
Search Playwright Test for VSCode (Microsoft)&lt;br&gt;
Install&lt;br&gt;
The extension gives you:&lt;/p&gt;

&lt;p&gt;Run/debug individual tests with a click&lt;br&gt;
Built-in test recorder (generate test code by clicking through a page)&lt;br&gt;
Inline test results&lt;br&gt;
Useful CLI Commands to Know&lt;/p&gt;

&lt;h1&gt;
  
  
  Run all tests
&lt;/h1&gt;

&lt;p&gt;npx playwright test&lt;/p&gt;

&lt;h1&gt;
  
  
  Run a specific file
&lt;/h1&gt;

&lt;p&gt;npx playwright test tests/login.spec.ts&lt;/p&gt;

&lt;h1&gt;
  
  
  Run tests matching a name pattern
&lt;/h1&gt;

&lt;p&gt;npx playwright test --grep "checkout"&lt;/p&gt;

&lt;h1&gt;
  
  
  Run only on one browser
&lt;/h1&gt;

&lt;p&gt;npx playwright test --project=chromium&lt;/p&gt;

&lt;h1&gt;
  
  
  Run in headed mode (see the browser)
&lt;/h1&gt;

&lt;p&gt;npx playwright test --headed&lt;/p&gt;

&lt;h1&gt;
  
  
  Run in debug mode (step through tests)
&lt;/h1&gt;

&lt;p&gt;npx playwright test --debug&lt;/p&gt;

&lt;h1&gt;
  
  
  Open the interactive UI mode
&lt;/h1&gt;

&lt;p&gt;npx playwright test --ui&lt;/p&gt;

&lt;h1&gt;
  
  
  Generate a test by recording clicks
&lt;/h1&gt;

&lt;p&gt;npx playwright codegen &lt;a href="https://example.com" rel="noopener noreferrer"&gt;https://example.com&lt;/a&gt;&lt;br&gt;
--ui mode is particularly useful — it's an interactive test runner that shows you the browser, lets you filter and rerun tests, and updates in real time as you save files.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Read more free tutorials at &lt;a href="https://aiqeacademy.onrender.com" rel="noopener noreferrer"&gt;AIQEAcademy&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Papio Framework Generator</title>
      <dc:creator>Srikanth Srinivas</dc:creator>
      <pubDate>Sat, 14 Mar 2026 05:03:16 +0000</pubDate>
      <link>https://dev.to/srikanth_srinivas_22928e3/papio-framework-generator-5a07</link>
      <guid>https://dev.to/srikanth_srinivas_22928e3/papio-framework-generator-5a07</guid>
      <description>&lt;p&gt;"Stop Writing Test Framework Manually — I Built a Chrome Extension That Does It For You (Playwright, Cypress, WebdriverIO, Selenium&lt;/p&gt;

&lt;p&gt;If you've spent time in test automation, you know the selector problem.&lt;/p&gt;

&lt;p&gt;You open DevTools, inspect an element, and then manually craft something like:&lt;br&gt;
driver.findElement(By.xpath("//div[&lt;a class="mentioned-user" href="https://dev.to/class"&gt;@class&lt;/a&gt;='container']//button[contains(text(),'Submit')]"))&lt;/p&gt;

&lt;p&gt;Two sprints later, the UI changes. The class is gone. The test breaks. You fix it. The cycle repeats indefinitely.&lt;/p&gt;

&lt;p&gt;After 20+ years in QA automation — working across Toyota Connected, Caesars Digital, and enterprise Fortune 500 environments — I decided to build the tool I always wished existed: Papio Selector.&lt;/p&gt;

&lt;p&gt;What is Papio Selector?&lt;br&gt;
Papio Selector is a Chrome DevTools extension that automatically generates production-ready test selectors for five major automation frameworks — simultaneously — from a single click on any element.&lt;/p&gt;

&lt;p&gt;The Core Problem: Framework Fragmentation&lt;br&gt;
Modern QA teams rarely use just one framework. You might have:&lt;br&gt;
• Legacy Selenium tests from 2018&lt;br&gt;
• New Playwright tests your team added last year&lt;br&gt;
• Cypress for component testing&lt;br&gt;
• WebdriverIO for mobile/cross-browser&lt;/p&gt;

&lt;p&gt;Each framework has its own selector API. Maintaining consistency across all of them manually is error-prone and time-consuming. Papio generates idiomatic code for all of them from a single inspection.&lt;/p&gt;

&lt;p&gt;Shadow DOM — The Elephant in the Room&lt;br&gt;
Shadow DOM support is where most tools fail. Web components, Lit elements, Angular components using ViewEncapsulation — these all create shadow roots that standard CSS selectors can't pierce. Papio detects shadow roots automatically and generates the correct piercing selectors for each framework.&lt;/p&gt;

&lt;p&gt;Selector Priority Algorithm&lt;br&gt;
Not all selectors are equal. Papio uses a priority system that mirrors accessibility and maintainability best practices:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;data-testid / data-cy attributes (most stable)&lt;/li&gt;
&lt;li&gt;ARIA roles and labels&lt;/li&gt;
&lt;li&gt;ID attributes&lt;/li&gt;
&lt;li&gt;Unique CSS class combinations&lt;/li&gt;
&lt;li&gt;Structural/positional selectors (last resort)
This means Papio-generated selectors are inherently more resilient to UI changes than manually crafted ones.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Install &amp;amp; Try It&lt;br&gt;
Available free on the Chrome Web Store. Search 'Papio Selector' or visit &lt;a href="https://chromewebstore.google.com/detail/papio-test-framework-gene/blmnefcnhccikfcghoaphpnmfpffbknd" rel="noopener noreferrer"&gt;https://chromewebstore.google.com/detail/papio-test-framework-gene/blmnefcnhccikfcghoaphpnmfpffbknd&lt;/a&gt; &lt;br&gt;
I'd love feedback from the Dev.to community — especially on edge cases, accessibility patterns, and framework-specific conventions I may have missed.&lt;/p&gt;

&lt;p&gt;Srikanth | Senior Automation Architect | IEEE Senior Member | Creator of Papio Selector&lt;/p&gt;

</description>
      <category>qa</category>
      <category>playwright</category>
      <category>beginners</category>
      <category>automation</category>
    </item>
  </channel>
</rss>
