Skip to main content

Posts

Showing posts from May, 2025

Blog #27: ๐Ÿ›’๐Ÿ’ป A Tale of Dynamic Pages & Adaptive Code - Helping a Friend Debug a Playwright Test

The other day, a friend messaged me, a bit stuck on a Playwright test: “I’m trying to add all 3 products to the cart, but only 2 are getting added, and then it crashes! ๐Ÿคฏ” I couldn’t resist helping out and it turned into a fun little debugging adventure. Let me share how we cracked it! ๐ŸŒŸ The Scenario It was a practice website with exactly 3 products. My friend’s mission: ๐Ÿ‘‰ Log in ๐Ÿ‘‰ Add all 3 items to the cart ๐Ÿ‘‰ Validate that everything worked smoothly. Sounds simple, right? But the page had a dynamic twist! ๐Ÿ› The Initial Problem Here’s what he was using at first: const addToCartButtons = page . locator ( 'button:has-text("Add to Cart")' );     for ( let i = 0 ; i < 3 ; i ++ ) {         await addToCartButtons . nth ( i ). click ();     } But… it would only add 2 items and then fail with a timeout error! Turns out, Playwright was trying to click a button that no longer existed after the page updated. ๐Ÿ” What Was Happening? When yo...

Blog #26: Everything I Know About Playwright Syntax in One Post (So Far!)

Whether you're just starting your automation journey or transitioning from manual testing, Playwright is a powerful framework for modern end-to-end testing. In this blog, I’ll walk you through Playwright syntax in detail, including locators , assertions , waits , and more—all in one place. ✅ 1. Installation & Setup npm init -y npm install -D @playwright/test npx playwright install This sets up everything you need, including Chromium, Firefox, and WebKit. ๐Ÿงช 2. Basic Test Structure import { test, expect } from '@playwright/test'; test('basic test', async ({ page }) => { await page.goto('https://www.google.com/'); const title = await page.title(); expect(title).toBe('Google'); }); test() defines a test case. expect() is used for assertions. ๐Ÿ” 3. All About Locators ๐ŸŽฏ Playwright-Specific Locators page.getByText('Login');   // matches visible text page.getByRole('button', { name: 'Submit' }); ...

๐Ÿ’ฅBlog # 25: From Red to Green: Taming Unreliable Tests with Playwright’s Retry Magic

 Hey folks ๐Ÿ‘‹ If you’ve ever shouted "But it worked yesterday!" at your test suite — welcome to the club. In today’s post, I’m sharing my real-world experience dealing with flaky tests in Playwright and how I used retry logic to keep my sanity intact (well, mostly!). ๐Ÿงช The Problem: Tests That Fail Randomly (A Tester’s Nightmare) Picture this: I wrote a test that checked for a simple piece of text on a page. It ran smoothly on my machine—until suddenly, it didn’t. ๐Ÿ˜ค Sometimes it failed due to timeouts. Sometimes due to delayed elements. Sometimes the page just didn’t load fast enough. That’s when I learned the infamous name for this phenomenon: Flaky Tests. ๐Ÿ˜ˆ ๐Ÿ” Enter Retries – Playwright’s Built-In Magic Playwright offers a super handy way to automatically rerun failed tests. You can set this up in the config file or directly via CLI. ๐Ÿ”ง Retry via playwright.config.js // playwright.config.js export default {   retries : 2 , // Retry failed tests up to 2 times ...

๐ŸŽฏBlog # 24: Playwright Reporters Demystified: Know What Your Tests Are Saying

Whether you're running a handful of tests or scaling up to hundreds, knowing what happened, where it failed, and how to debug it fast is crucial. That’s where Playwright reporters become your best friends. In this blog, I’ll take you on a tour of Playwright’s built-in reporters, show you sample test scripts, and (yes!) include screenshots of each report in action so you can see the difference. ๐Ÿง  What Are Reporters? Reporters are like your test suite's storytellers. After executing your tests, they summarize the results—either in your terminal or in beautiful visual formats. Think of them as: Terminal dashboards  Structured outputs for CI/CD Visual tools for debugging Data sources for analytics ๐Ÿงช Sample Test File Here’s the test script I’m using for this blog. Each test is designed to showcase one type of reporter: const { test, expect } = require('@playwright/test'); test('List reporter example (updated)', async ({ page }) => {     await page.goto('http...

✍️ Blog #23: What I Learned About Annotations in Playwright

When I started, I thought writing tests was just about getting them to pass. But as the number of tests grew, I realized that being able to control which ones run, which to skip, and how to debug easily — is just as important. Let me take you through everything I’ve learned so far about Playwright’s annotations. ๐Ÿ” What Are Annotations? Annotations are special helpers in Playwright that let you modify test behavior without changing the actual logic of the test. They're great for: Focusing on a single test ( test.only ) Skipping unfinished or flaky ones ( test.skip ) Flagging tests that need fixing  ( test.fixme ) Allowing known failures  ( test.fail ) Marking slow tests  ( test.slow ) Think of them like post-it notes or switches you can stick on your tests to manage them better during testing. ✅ Test-Level Annotations These annotations go directly on individual tests. ๐Ÿงช test.only – Focus on One Test test. only ( 'run this test only' , async ...

Blog # 22: Group, Organize, Breathe: How "DESCRIBE" Helped Me Clean Up My Playwright Tests

 Welcome back to my Playwright blog series! As someone who’s learning Playwright step by step , I’ve come to realize that keeping tests organized is just as important as writing them . In this post, I’ll share how I started using describe blocks to structure my tests better. If you’re also a beginner like me, this might help make your test files cleaner and easier to manage! ๐Ÿงฉ What I Struggled With When my test file grew to 50+ tests, it looked like this: test ( 'Login valid' , () => {}); test ( 'Login invalid' , () => {}); test ( 'Add to cart' , () => {}); test ( 'Checkout' , () => {}); //  // ...and 46 more! I couldn't find anything quickly. Tests felt scattered like socks in a laundry room! ๐Ÿงฆ ๐ŸŽ My Discovery: describe = Test Folders Playwright's describe lets you group tests like drawers in a filing cabinet: describe ( 'Login Tests' , () => { // All login-related tests here }); describe ( 'Cart Tests' ,...