I’ve been thinking about testing lately. Not the kind that makes you anxious, but the kind that makes you sleep better at night. You know the feeling—you push a change, everything looks fine, but then a user reports a button that doesn’t work in Firefox. It’s frustrating. That’s why I started looking at how we test our applications, and I kept hitting the same wall: speed. Or rather, the lack of it.
Traditional end-to-end testing often feels like waiting for paint to dry. You write a test, trigger the run, and then wait through a full build process just to see if your button clicks. By the time you get feedback, you’ve already moved on to three other tasks. The context switching kills productivity. This led me to a simple question: What if we could test our applications as fast as we can change the code?
That’s where two tools come together in a way that feels almost magical. On one side, you have a testing framework built for the modern web. It lets you write scripts that control real browsers—Chrome, Firefox, Safari—just like a real user would. On the other side, you have a build tool that serves your application with incredible speed, updating the browser instantly when you save a file. Combining them changes everything.
Let’s talk about setup. It’s straightforward. You’re likely already using the build tool for development. Adding the testing framework is a matter of a few commands. First, you install it as a development dependency.
npm install --save-dev @playwright/test
Next, you initialize it. This command creates a basic configuration file and installs the necessary browser engines.
npx playwright install
The real integration happens in the configuration. You need to tell the testing framework to use your development server. You create a configuration file, playwright.config.ts. Here, you define a web server that starts your build tool’s dev server before the tests run.
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
webServer: {
command: 'npm run dev',
url: 'http://localhost:5173',
reuseExistingServer: !process.env.CI,
},
use: {
baseURL: 'http://localhost:5173',
},
});
With this, every time you run your test suite, it automatically starts your development environment. The tests run against a live, updating version of your app. No waiting for a production build.
Why does this matter for your daily work? Imagine you’re building a login form. You want to test the flow: a user visits the page, fills in their email and password, and clicks submit. With a typical setup, you’d write the test, run a build command, and then execute the test. It could take a minute or more. Now, the server is already running. You save your test file and run it. The feedback is near-instantaneous.
Here’s what a simple test for that login form might look like.
// tests/login.spec.js
import { test, expect } from '@playwright/test';
test('user can log in successfully', async ({ page }) => {
// Go to the application homepage
await page.goto('/');
// Find the email input and type into it
await page.getByLabel('Email').fill('user@example.com');
// Find the password input and type into it
await page.getByLabel('Password').fill('securepassword123');
// Click the login button
await page.getByRole('button', { name: 'Sign In' }).click();
// Assert that the user is redirected to the dashboard
await expect(page).toHaveURL('/dashboard');
await expect(page.getByText('Welcome back!')).toBeVisible();
});
You write this, save it, and run npx playwright test. The test opens a browser, navigates to your running app, and performs the actions. If something fails, you get a clear error. Was the label wrong? Did the button not exist? You know immediately.
But what about when things go wrong? A test fails, and you’re left wondering what the page actually looked like at that moment. This is another area where this combination shines. The testing framework has built-in tools to help you see what happened. It can take a screenshot the moment a test fails. It can even record a full video of the test run or capture a detailed trace file you can open in a visual explorer.
You enable this in the configuration. It adds a few lines, but the debugging power it gives you is immense.
// In your playwright.config.ts, inside the `use` section
use: {
baseURL: 'http://localhost:5173',
screenshot: 'only-on-failure',
trace: 'retain-on-failure',
},
Now, when a test fails, you get an image of the screen and a trace file. You can open the trace to see a step-by-step replay of the test, inspect the DOM at each point, and check network requests. It turns a cryptic error message into a clear visual story.
Have you considered how you test across different browsers? A feature might work perfectly in Chrome but have a layout issue in Safari. Running tests on one browser is good; running them on three is robust. The setup we’re discussing makes this trivial. The same tests can run on Chromium, Firefox, and WebKit with a single command. You configure it to run in parallel, and suddenly you have a comprehensive view of your app’s compatibility.
This approach is perfect for modern applications. Are you using a frontend framework like React, Vue, or Svelte? The build tool handles them natively. Are you building a Progressive Web App or using Web Components? The testing framework can interact with them without special plugins. It’s designed for the web as it exists today.
The development experience is transformative. You start writing a component. You write a test for how it should behave. You run the test, watch it fail, then implement the component until the test passes. The loop is so tight it feels like a conversation with your code. It encourages you to think about user interaction from the very beginning.
Let’s not forget about the team. When this setup is part of your continuous integration pipeline, every pull request can be automatically tested in multiple browsers. It provides a safety net that catches regressions before they reach your users. It turns testing from a chore into a core part of your development rhythm.
I moved to this setup because I was tired of the slow feedback. I stayed for the confidence it gives me. When I deploy an application, I know it has been interacted with, clicked, and typed into across the major browsers. I know the core user journeys work. That peace of mind is worth its weight in gold.
So, give it a try. Start with one test. See how fast you can go from an idea to a verified, working feature. Share your experiences in the comments below—what was the first test you wrote? Did you catch a bug you would have otherwise missed? If you found this breakdown helpful, please like and share it with a teammate who’s also passionate about building reliable software. Let’s build things that work, for everyone, everywhere.
As a best-selling author, I invite you to explore my books on Amazon. Don’t forget to follow me on Medium and show your support. Thank you! Your support means the world!
101 Books
101 Books is an AI-driven publishing company co-founded by author Aarav Joshi. By leveraging advanced AI technology, we keep our publishing costs incredibly low—some books are priced as low as $4—making quality knowledge accessible to everyone.
Check out our book Golang Clean Code available on Amazon.
Stay tuned for updates and exciting news. When shopping for books, search for Aarav Joshi to find more of our titles. Use the provided link to enjoy special discounts!
📘 Checkout my latest ebook for free on my channel!
Be sure to like, share, comment, and subscribe to the channel!
Our Creations
Be sure to check out our creations:
Investor Central | Investor Central Spanish | Investor Central German | Smart Living | Epochs & Echoes | Puzzling Mysteries | Hindutva | Elite Dev | JS Schools
We are on Medium
Tech Koala Insights | Epochs & Echoes World | Investor Central Medium | Puzzling Mysteries Medium | Science & Epochs Medium | Modern Hindutva