Writing your first end-to-end test in Playwright

javascript dev.to

The first end-to-end test usually feels bigger than it is. A new project, a browser opening and closing, selectors that might break tomorrow, and a quiet suspicion that "real" engineers must have a cleaner way to do it. They do not. Most people start with one useful path, make it pass, then spend the next few runs learning what should have been obvious from the start.

Pick One User Journey and Keep It Small

A first test should cover a path a real user takes in under a minute. Login is the classic choice, but only if the app actually depends on authentication. A product search, a cart add, or a form submission can be better because the result is visible and easy to verify. The point is not to "cover the app." The point is to prove that the browser can drive one important flow from start to finish without hand-holding.

That sounds basic, but beginners often reach for too much. They script sign-up, email verification, profile setup, billing, and logout in one file, then wonder why every failure takes ten minutes to diagnose. A tighter start is a six-step path: open homepage, click sign-in, fill two fields, submit, wait for dashboard, verify one heading. That gives enough moving parts to learn navigation, selectors, waits, and assertions.

If the broader structure of testing still feels fuzzy, reviewing essential software testing concepts for end to end tests helps frame what this layer is meant to catch. End-to-end tests sit near the top of the stack. They are slower than unit checks, more exposed to UI changes, and valuable because they exercise the system the way a user does.

Set Up the Test Like a Reader Will Maintain It

A first Playwright file should be readable even after two bad weeks away from the codebase. That means clear naming, one scenario per test, and setup that stays close to the behavior. A lot of early pain comes from abstraction added too soon. If a selector is used once, keep it inline. If a helper hides five browser actions, ask whether the helper saves time or hides the thing that failed.

A simple structure works well: open the page, perform the action, verify the result. In practice, that might look like visiting /login, filling email and password, clicking submit, then checking for a visible account panel. If login requires test data, create a single known account for local runs rather than generating fresh users every time. Stable inputs make debugging less theatrical.

For people just getting oriented, the overview of Playwright and its core features is useful because it explains why the tool feels faster than older browser automation setups. Auto-waiting matters. Built-in locators matter. Cross-browser support matters too, though first tests should run in one browser until the flow is trustworthy.

A good first milestone is boring: one file, one path, one assertion that means something.

Use Locators and Assertions That Survive Real UI Changes

The first brittle Playwright test usually breaks because it targets the wrong thing. A CSS chain copied from devtools may pass today and explode after the next layout tweak. Better locators describe what the user can perceive: a button by role and name, an input by label, a heading by text, a form control by placeholder if nothing else exists.

That approach changes the maintenance cost. Suppose a checkout button moves from the sidebar to a sticky footer. A selector like div.wrapper > div:nth-child(2) button.primary dies instantly. A locator aimed at a button named "Checkout" often keeps working because the meaning stayed the same while the layout moved around it.

Assertions should also match the user outcome. After submitting a form, checking that the URL contains /dashboard can help, but a visible heading or account menu is usually a stronger signal. If a user would say "I know I'm logged in because I can see my account area," your test should verify something equally grounded.

If you want to see how working developers talk through these choices, engineers discuss practical approaches to writing Playwright tests in a way that feels closer to day-to-day practice than polished tutorials often do.

Treat Waiting, State, and Test Data as the Real Work

Most first-test frustration is not about syntax. It is about timing and state. The page loads before the data does. A click succeeds before the UI updates. A previous run leaves behind a user session and the login screen never appears. This is where new testers learn that "works on my machine" can happen inside automation too.

Playwright helps by waiting for elements to be actionable, but it cannot guess every business-level condition. If a report table takes a second to populate, verify that a specific row or empty-state message appears rather than sleeping for an arbitrary timeout. A hard wait of five seconds is easy to write and expensive to keep. Ten tests using the same habit can add almost a minute of dead time to a run.

State control matters just as much. Run each test with a known starting point. That can mean clearing storage, using a fresh browser context, or logging in through setup code and landing directly on the target page. The discussion around how system testing relates to end to end testing is useful here because it highlights the difference between validating a whole integrated system and checking a smaller behavior inside it. Your first test does not need to prove every dependency at once.

Expect Refactoring After the First Passing Run

A passing test is the start of the work, not the finish line. Once the path succeeds a few times, patterns become obvious. Repeated login steps should move into setup. Selectors that looked fine during the first run start to smell when copied into a second file. Screenshot and trace output becomes more useful after the first confusing failure than it ever was during the happy path.

This is also the point where many developers begin building a small framework around Playwright. That can be healthy if the extra structure solves a repeated problem. A page object for a noisy checkout screen makes sense after the third test touches it. A giant folder tree with base classes, utility layers, wrappers, and custom runners before test two usually creates more ceremony than value.

The most grounded advice often comes from people who just went through the messy part. In developer shares their first Playwright automation framework, you can see that tension clearly: structure is helpful, but only after the raw test cases reveal what should be extracted.

Conclusion

A first end-to-end test earns its value by teaching boundaries. It shows what the browser can verify, where the app is flaky, and how much hidden setup sits behind a "simple" user action. That lesson matters more than the single green checkmark. Teams that learn it early tend to write fewer oversized tests, choose stronger assertions, and treat test data as part of the product surface rather than background plumbing.

The smart next step is not to multiply test count as fast as possible. It is to make one test dependable, then add a second path that covers a different risk. If the first file proved login works, the next one might prove a user can complete a purchase or submit a request. After that, patterns worth abstracting reveal themselves on their own. Good Playwright suites usually grow from repeated evidence, not from grand design.

Source: dev.to

arrow_back Back to Tutorials