The maintenance cost of end-to-end (E2E) tests comes from three places: tests that break when the interface changes but the behaviour did not, flaky failures that force reruns, and the time people spend working out why a test failed. Cut it by keeping the suite focused on critical flows, separating structural changes from behaviour changes, and giving every failure a quick, specific diagnosis.
The cost is mostly people's time
Browser minutes are rarely the expensive part of an E2E suite. The expensive part is attention. Someone has to update a test after a redesign. Someone has to rerun a red build and decide whether to trust it. Someone has to open a trace, compare it with the last good run and decide who owns the problem.
That time is spread across the whole team, so it rarely shows up as a line in a budget. It shows up as slower merges and as tests that people stop reading. When a team says its E2E suite is "too expensive", it usually means this hidden time, not the infrastructure bill.
Large engineering organisations have measured parts of it. Atlassian found that approximately 15% of Jira backend repo failures are attributed to flaky tests, necessitating reruns that waste over 150,000 hours of developer time each year [Atlassian]. Your numbers will differ, but the shape is common: reruns and investigation dominate.
Interface churn breaks tests that did not need to break
A large share of routine upkeep has nothing to do with bugs. A designer renames a button. A component library changes its markup. A form moves into a modal. The user flow works exactly as before, yet the tests fail because they looked for the element by a class name or a position in the page.
Each of these failures costs a person a context switch, a fix and a review. The fix teaches the team nothing about the product.
Two practices reduce this. First, find elements the way a user does: by role, label or visible text, not by generated class names or deep paths. Second, treat a structural change as a different event from a behaviour change. A moved button can be updated and recorded. A changed outcome needs a person. Mixing the two is what makes maintenance feel endless.
Flaky tests multiply every other cost
A flaky test passes and fails on the same code. It is costly because it trains people to distrust red builds. At Google, almost 16% of tests have some level of flakiness associated with them [Google Testing Blog], and about 84% of the pass-to-fail transitions Google observes involve a flaky test [Google Testing Blog]. At Atlassian, test flakiness was responsible for as much as 21% of master build failures in the Jira Frontend repository [Atlassian].
The causes are well studied. In a study of 201 commits that likely fix flaky tests in 51 open-source projects, the top three categories of flaky tests are Async Wait, Concurrency, and Test Order Dependency [University of Illinois at Urbana-Champaign / ACM FSE]. Async waits are the classic E2E problem: the test acts before the page is ready. Modern frameworks help here. Playwright performs a range of actionability checks on elements before making actions, auto-waits for all the relevant checks to pass, and fails the action with a TimeoutError if the checks do not pass within the given timeout [Microsoft (Playwright)]. Fixed sleeps in test code undo that help.
For a deeper look, see what causes flaky tests and retry or quarantine flaky tests.
Triage time is the hidden line item
Every red build asks the same question: is this an app bug, a test issue or an environment problem? Answering it by hand means downloading artefacts, reading logs and rerunning. When the answer is usually "test issue", people stop asking and start rerunning.
Automating the handling of known flaky failures has a large effect. After replacing the manual approach of handling test failures with an automated flaky test suppression system, Slack dropped test job failures from 57% to less than 5% [Engineering at Slack]. The lesson is general: make the first pass of triage automatic, and keep people for the decision.
Reduce the cost in this order
- Delete or merge tests that cover the same flow. Every test you keep has an ongoing cost, so keep the ones tied to real risk.
- Replace structural selectors with user-facing ones, and remove fixed sleeps.
- Detect flaky tests automatically, quarantine them with a named owner and a deadline.
- Record the same diagnostic data for every failure: failing step, screenshot, network log and a diff from the last passing run.
- Track how much time the team spends on test upkeep each week. You cannot reduce what you do not see.
How AI Testing Platform fits
AI Testing Platform heals locator and layout changes, such as a moved, renamed or restyled element, and records each change for review, while a changed behaviour fails the test. Each failure gets a triage card with the failing step, page state, the diff from the last passing run and a proposed classification. See self-healing and the healing docs.