Sitemap
Artificial Intelligence in Plain English

New AI, ML and Data Science articles every day. Follow to join our 3.5M+ monthly readers.

Stable Pipelines With Playwright API Testing and Mocked UI Tests

5 min readOct 25, 2026

--

Press enter or click to view image in full size
Stable Pipelines With Playwright API Testing and Mocked UI Tests

Ask a team why their Playwright pipeline keeps flaking and nine times out of ten you’ll hear “eh, it’s the backend.” Some UI test clicks through checkout, the API’s a bit slow or answers slightly differently than yesterday, and boom, red. Rerun it? Green. Of course.

Here’s what I think is really going on. A lot of teams ask one kind of test to cover two jobs. The same UI test is quietly vouching for the frontend and the backend, so when either one sneezes, the build turns red, and now you’re playing detective to figure out whose fault it was. Splitting that up helps more than you’d think. Mock the responses for the UI, save the real calls for Playwright API testing, and a jittery pipeline usually calms right down. So how does that split actually work?

Why UI tests and real backends don’t always mix

A UI test against a real backend isn’t really testing one thing. It’s testing a whole conga line. The browser, your frontend code, the network, the API, the database, whatever services sit behind that. Very realistic. Also a really long list of stuff that can wobble.

And when something does wobble, the error you get is basically never helpful. “Timed out waiting for selector.” Cool. Frontend bug? Slow query? Some third-party API having a moment? Now you’re elbow-deep in logs trying to figure out which layer even broke. Do that a few times a week across a busy team and people just stop believing red builds.

Mocking API responses for UI tests

So for most UI tests, I’d honestly just take the backend out of the equation. Playwright makes this weirdly easy. Its routing lets you step in front of whatever the page is about to fetch, and that’s really all it takes to mock API responses in Playwright: you answer the request yourself, right there in the test, and nothing ever goes out over the wire. The frontend has no idea. It thinks it’s chatting with the real API, but it’s getting a canned answer that never, ever changes.

That quietly changes what the test is about. It stops asking “does the entire system work?” and starts asking “if the API says exactly this, does the frontend behave?” Way sharper question. Way more stable, too.

Testing states that are hard to trigger for real

Mocks also let you poke at stuff that’s a real pain to trigger against an actual backend. What does the page look like when a user has zero orders? Hand back an empty list. Need to see that error banner? Answer with a 500. Wondering what happens if the network just dies mid-request? Abort it. Want the loading spinner to stick around? Make the response wait a bit.

Try getting a real backend to do any of that on demand. You’d need special test accounts, a feature flag or two, and a lot of patience. With mocks it’s barely any effort.

Keeping mock data realistic

Okay, one catch, and it’s a big one. A mock’s only worth anything if it actually looks like what the real API sends back. Write your mock responses by hand and eventually the real API changes while your mocks don’t. Your UI tests stay happily green. Production, meanwhile, does not.

Get Sancharini Panda’s stories in your inbox

Join Medium for free to get updates from this writer.

The easiest way to dodge that? Don’t make the mock data up. Start from something the API really sent back at some point, maybe a response you copied out of a test run and saved into a fixture file. That’s your starting point, and you tweak from there. When the API changes, refresh the fixtures. Some teams go a step further and record a HAR file from a real session, then let Playwright replay responses straight out of it. Hardly any extra work, and the mocks stay honest.

Testing the real API separately

Now, if the UI tests never touch the backend anymore, something else has to keep the backend honest. That’s the job for Playwright API testing.

These tests use Playwright’s request fixture to call your API directly. No browser at all. They check the stuff your mocked UI tests are quietly assuming, like the status codes, the general shape of the responses and the fields that really matter. Little detail worth knowing: those direct API calls skip right past the page-level routing you set up for mocks. They hit the real server, which is exactly the point here.

Line the two up and every layer’s got its own clear job. The UI tests are asking whether the frontend handles these responses right. The API tests are asking whether the backend actually sends them. When something breaks, whichever layer went red tells you where to start looking.

Keeping the API’s own dependencies stable

Of course, your API doesn’t live alone either. It’s got a database, maybe a cache, maybe a payment provider or some internal service another team owns. Point your API tests at a backend that’s calling all of that for real, and congrats, you’ve just moved the flakiness one floor down.

What fixes it is making those downstream calls predictable while the tests run. Keploy, an open-source tool, does this by recording a service’s real traffic with eBPF at the kernel level, with no code changes, and replaying its database queries and outbound API calls as mocks during API tests. So the backend gets the same downstream answers every single run. If an API test fails, it’s because your API changed, not because something it leans on was having a rough day.

Structuring the pipeline

In practice, I’d set this up as separate Playwright projects in the same config. One for the mocked UI tests, one for the API tests. They can run side by side, report on their own and fail on their own, so the second a build goes red you already know which side to look at.

I’d also hang on to a small handful of true end-to-end tests that hit everything for real. Just the flows you absolutely can’t afford to break, like signup or checkout. Think of them as a last sanity check that all the pieces still click together. The important part is keeping that group tiny. They’re the slow, heavy ones, so they really shouldn’t be redoing work the faster layers already cover.

Conclusion

The way I see it, a calm Playwright pipeline mostly comes down to giving every test one job and only one. Let the mocked UI tests worry about the frontend. Let Playwright API testing worry about the backend. Keep a tiny end-to-end set around to make sure it all still connects. Once those layers stop stepping on each other, a red build starts meaning something again.

Got a flaky pipeline right now? Try it on just one feature. Mock the API for that feature’s UI tests, write a few API tests for the endpoints behind it, and let both run side by side for a week. I think you’ll notice pretty quickly how much easier it gets to tell what actually broke.

--

--

Sancharini Panda
Sancharini Panda

I am a technical writer with experience in technology & software development space. I collaborate with engineering teams to create practical insights on DevOps.

Artificial Intelligence in Plain English
Artificial Intelligence in Plain English

New AI, ML and Data Science articles every day. Follow to join our 3.5M+ monthly readers.