18. 12. 2025 Marco Berlanda Development, Front-end, UI, Vue

API contracts don’t protect Vue 3 frontends. Integration tests do.

In a previous article, we looked at Vue 3 reactivity and how something elegant and powerful can occasionally work against us. This time, we move slightly higher in the stack and focus on a different illusion, one that is deeply rooted in modern frontend and backend collaboration.

The idea that a passing API contract means the frontend is safe.

API contracts are formal, automated, and reassuring. When they pass, pipelines turn green and deployments feel justified. The problem is that contracts answer a very specific question, and it is not the one users care about.

A contract tells you whether a response is valid.
It does not tell you whether the application still works.

So, in layman’s words, it’s a classic case of “the operation was extremely successful, unfortunately the patient is dead” – how ironic.

When everything is OK but the UI is not

Most teams have lived through a variation of this scenario.

  • A backend endpoint evolves as new requirements appear.
  • A new optional field is added or an existing one becomes richer.
  • OpenAPI or Pact tests pass without hesitation.
  • A limited set of end to end tests runs on the happy paths.

The release goes out.

Shortly after, subtle issues appear.

  • A dashboard renders an empty state with no visible error.
  • A computed property behaves differently because undefined became null or an empty string or something.
  • A longer string stretches a layout and pushes an important action out of view.

It’s important to highlight that:

  • From the backend perspective, nothing broke
  • From the contract perspective, everything is correct
  • From the user perspective, something is clearly wrong

How could this happen you ask? Why do backenders hate frontenders you wonder? I’m afraid I can only answer the former, so let’s start with that.

What API contracts do and do not protect

API contracts are not the enemy. They are extremely good at what they are designed to do.

They protect:

  • The shape of requests and responses, consistency you might say
  • Required and optional fields,
  • Types and structural compatibility

They do not protect:

  • How the frontend branches on data
  • How Vue templates react to new or newly populated fields
  • How real data affects layout, visibility, and interaction

These problems only appear when real responses flow through real components.

That is an integration problem, not a contract problem.

The jsdom comfort zone and its hard limits

For years, Vue component tests have been executed in Vitest or Jest using jsdom. This setup is fast, accessible, and well suited for unit level testing. It becomes problematic when the goal shifts to verifying real integrations.

jsdom is not a browser. It is a JavaScript approximation of one. That distinction matters in several practical ways.

  • There is no real browser network stack. CORS, cookies, and modern fetch behavior are simplified or missing
  • There is no layout engine. jsdom cannot tell you whether something is visible, overlapped, or pushed off screen
  • Many modern Web APIs are missing or incomplete, leading to heavy mocking

At that point, tests start validating assumptions instead of behavior.

If the question is whether a real API change breaks the UI, a simulated browser is simply not enough.

Running integration tests where users actually are

Instead of extending the simulation, we moved the tests into a real browser.

Vitest Browser Mode, using Playwright under the hood, allows Vue tests to run inside actual browser engines such as Chromium, Firefox, and WebKit.

This creates a useful middle ground.

  • It is not a full end to end test
  • It does not require navigation flows or authentication
  • It focuses on components and compositions, not entire applications

At the same time, it gives us:

  • Real network behavior
  • Real CSS and layout calculations
  • The full Vue lifecycle as it runs in production

The environment stops being theoretical and starts behaving like the user’s machine.

Using snapshots as a functional safety net

Once tests run in a real browser, snapshots become far more meaningful.

We treat the API response as input and the rendered UI as output.

Key aspects of this approach:

  • We snapshot real API payloads from staging or production, not idealized mocks
  • These payloads can include edge cases such as large strings, null values, and deeply nested objects
  • We snapshot the rendered DOM, not just data structures

A simplified example looks like this:

If an API change causes a conditional rendering to flip or a computed property to behave differently, the snapshot fails immediately in CI.

No manual verification is required.

When the DOM is correct but the UI Is still broken

DOM snapshots are effective, but they are not the final word. It is entirely possible for the HTML structure to be correct while the visual result is not.

To catch these cases, we are adding visual regression testing using Playwright powered screenshot comparisons.

This allows us to detect:

  • Layout shifts caused by unexpected content
  • Components overflowing or collapsing
  • Visual regressions that contracts and DOM snapshots cannot describe

At this point, the test does not just verify correctness. It verifies that literally nothing has been damaged in the process (pretty cool right?)

Peace of mind is the real outcome

The primary benefit of this approach is not higher test coverage. It is confidence.

When the frontend is automatically verified against real API responses:

  • Backend teams can evolve APIs more freely
  • Adding new fields becomes trivial, not riskier
  • Frontend robustness is continuously validated, not assumed

We moved from hoping the UI would survive API changes to know for a fact that it did. Not bad right?

By stepping outside the limits of jsdom and embracing real browser based integration testing with Vitest and Playwright, we gained something extremely valuable, a reliable way to make sure that a butterfly that flaps its wings in Brazil, won’t create a hurricane somewhere else.

If anybody tells you this not impressive, you do not need that person in your life, I assure you.

Thanks for your time, we hope this can help you too!


These Solutions are Engineered by Humans

Did you find this article interesting? Does it match your skill set? Programming is at the heart of how we develop customized solutions. In fact, we’re currently hiring for roles just like this and others here at Würth Phoenix.

Marco Berlanda

Marco Berlanda

UX Front-end engineer by day, UX wizard by night, and an Interaction design ninja all the time. Always on the hunt for those ‘wow, didn’t see that coming!’ solutions to problems.

Author

Marco Berlanda

UX Front-end engineer by day, UX wizard by night, and an Interaction design ninja all the time. Always on the hunt for those ‘wow, didn’t see that coming!’ solutions to problems.

Leave a Reply

Your email address will not be published. Required fields are marked *

Archive