Next-Gen App & Browser Testing Cloud
Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

How to run E2E tests in pull requests without stalling code review: set a time budget, control flakiness, gate on real devices, and show reviewers the cause.

Himanshu Sheth
Author

Japneet Singh Chawla
Reviewer
Published on: August 27, 2026
A reviewer opens a pull request that changes a checkout button. The diff is nine lines and reads fine. At the bottom of the page sits a red check named e2e (shard 3/4), and the only way to find out what it means is to open a CI log in another tab, scroll past four hundred lines of setup, and guess whether the failure has anything to do with those nine lines.
That moment decides whether a team keeps its gate. Running E2E tests in pull requests is not hard to set up, and almost every team that abandons the practice abandons it after the setup worked. What breaks is the relationship between the reviewer and the check.
Key Takeaways
Running E2E tests in pull requests means every proposed change is validated against a real browser or device before it merges. The gate survives when it finishes inside the reviewer's attention span, fails only for real defects, and explains itself in the pull request. Speed, trust, and legibility decide whether the team keeps it.
A pull request gate is a CI job triggered by the pull_request event that runs a selected set of end-to-end testing scenarios against the proposed change, then reports back as a status check on the pull request. When that check is marked required in branch protection, a red result blocks the merge button.
The distinction that matters is where validation happens relative to review. Running the same suite after merge tells you the main branch is broken; running it on the pull request tells the author while they still have the code in their head.
Industry data suggests the post-merge model is losing ground. CircleCI's 2026 State of Software Delivery reports that feature branch throughput rose 15% year over year while main branch throughput fell 7%, meaning more verification work is shifting onto branches before they land.
Three properties separate a gate that lasts from one that gets removed:
Most published advice covers the first property and treats the other two as tooling details. In practice, trust and legibility are what determine whether the gate is still required six months later.
Gates are rarely removed in a single decision. They decay through a sequence that is recognisable across teams, and each step is individually reasonable.
The failure rate that drives this loop is rising rather than falling. Bitrise's Mobile Insights report, published in November 2025 and drawn from more than 10 million builds between January 2022 and June 2025, found the proportion of teams experiencing any test flakiness grew from 10% to 26%.
What that erosion costs downstream is visible in main branch health. CircleCI's 2026 data puts main branch success rates at 70.8%, the lowest in more than five years and well under its recommended benchmark of 90%, with the typical team taking 72 minutes to get back to green against a 60-minute benchmark.
A gate that is bypassed does not fail quietly. It relocates the failure to the branch everyone shares, where recovery is measured in hours rather than in the minutes a pull request run would have taken.
Published guidance tends to assert a number, usually five or ten minutes, without showing where it comes from. A borrowed number is not useful, because the same ten minutes is trivial for a team merging four pull requests a week and unaffordable for one merging forty a day.
Derive your own budget from three figures you already have:
Multiply the three and the answer arrives in engineer-hours per week. A team merging 20 pull requests a day at 2.5 runs each spends roughly 4 engineer-hours per week for every minute the gate takes, which makes the difference between a 6-minute and a 16-minute gate about 40 hours weekly.
That calculation reframes the question. The budget is not a best practice to adopt; it is the point where the waiting cost exceeds what catching a defect early is worth to you, and it moves as your merge rate moves.
When the budget is tighter than the suite, the first lever is parallelism rather than deletion. Splitting work across workers and shards is covered in depth in this guide to Playwright parallel testing with workers and sharding, and the same arithmetic applies to any framework.
This is the one question where credible sources openly disagree, and the disagreement is worth stating plainly because most articles present only one side.
All three are defensible, and which one applies to you depends on a property you can measure rather than a preference. Use your suite's flake rate as the decision rule.
| Your suite's flake rate | What to gate on | Why |
|---|---|---|
| Under 1% | Full suite, required | The signal is trustworthy enough that blocking on it costs less than the defects it catches |
| 1% to 5% | Risk-ranked subset, required | A smaller, stabler set keeps the gate credible while the rest of the suite runs post-merge |
| Above 5% | Informational only | Blocking merges on this suite trains the team to bypass checks, which is worse than not gating |
Selecting the subset by user-visible risk beats selecting it by folder or by tag inherited from a previous team. Authentication, checkout, and any path that moves money or data earn a slot ahead of a test that asserts a settings label. The practice of smoke testing in a CI/CD pipeline gives a reasonable starting shape for that selection.
One category deserves a specific mention because functional assertions miss it entirely. A change can pass every interaction test and still ship a broken layout, which is what visual regression testing is designed to catch on a diff.
Retries are where most gates quietly lose their meaning. A test that fails and then passes on attempt two renders in the pull request as a green check, visually identical to a test that passed the first time, so the reviewer cannot tell the difference and neither can the merge button.
The fix is to make retries conditional on the kind of failure rather than on the fact of failure. Infrastructure signatures such as a dropped session or a resolver timeout are worth absorbing; an assertion that says the total was wrong is never worth retrying.
TestMu AI's HyperExecute test orchestration cloud implements that distinction directly in configuration. Retries can be scoped to matching error patterns, so a known infrastructure exception is retried while a failed assertion fails immediately:
retryOnFailure: true
maxRetries: 3
retryOptions:
errorRegexps: ["org.openqa.selenium.NoSuchElementException"]
failFast:
maxNumberOfTests: 2
level: scenarioThe failFast block in the same file addresses the opposite waste. When a change breaks something fundamental, the job aborts after the configured number of consecutive failures instead of burning the full gate budget proving the same breakage twenty more times, and the counter resets on any pass so intermittent flakiness does not trigger it.
Two further HyperExecute behaviours shorten the feedback loop on a pull request. Previously failing tests are automatically reordered to run first, so a reintroduced defect surfaces early rather than at minute nine, and dynamicAllocation hands test cases to workers at runtime so a fast machine pulls more work instead of idling while a slower one finishes.
Configuration alone will not fix a suite that is genuinely unstable, and the underlying causes are worth understanding before tuning retries. This reference on flaky tests and how to detect them covers the detection side in detail.
Note: Flaky tests are cheaper to quarantine than to argue about. TestMu AI detects inconsistent tests across runs, categorises each failure as an application bug, a script bug, or an environment problem, and can auto-mute a test after a configurable number of consecutive failures so a known-bad test stops blocking merges while it is being fixed. Try TestMu AI free!
Almost every guide on this topic asserts that failures should be actionable, and almost none of them show what that looks like in the pull request. The gap matters because the default GitHub experience for a failed end-to-end job is a check name, a red cross, and a link to a log.
A failure is legible when the reviewer can answer three questions without leaving the pull request:
TestMu AI's GitHub App integration is built around that constraint. It posts a comment that updates as the run progresses, lists the test cases that executed with links into Test Manager, and finishes with a validation report carrying pass and fail counts, individual failure detail, root cause analysis, and an explicit approve, request-changes, or investigate recommendation.
The root cause layer is what turns a log into a diagnosis. It separates the primary cause from the cascading symptoms that follow it, labels the failure category, and returns numbered remediation steps, with manual analysis documented to complete in 20 to 30 seconds.
Triage can also be scoped so the reviewer is not buried in noise. Automatic analysis can be limited to new failures, defined as a test that failed after passing at least 10 consecutive times, or to consistent failures that failed in all of the previous 5 runs, which are the two categories most likely to represent a real regression in the diff under review.
None of this replaces human judgement about the change itself. It removes the tab-switching tax that makes reviewers stop reading red checks, which is the specific behaviour that kills gates. The wider practice around that review loop is covered in this guide to the code review process.
Web gates run headless browsers on hosted Linux runners, which is appropriate for a web application and silently inadequate for a mobile one. A hosted runner never encounters a notch cutting into a fixed header, a gesture conflict with the system back navigation, or the memory pressure that only appears on a mid-range handset.
Gating a mobile pull request means the CI job builds the artifact from the branch, uploads it, and runs the selected scenarios across a device matrix before the check reports back. TestMu AI's real device cloud provides 10,000+ real Android and iOS devices for that step, which removes the physical device lab from the critical path of a merge.
Three constraints apply to a device gate that do not apply to a browser gate:
The mobile case is also where flakiness data is most sobering. The same Bitrise research found that teams using monitoring tools experience 25% fewer flaky reruns, which is a direct argument for instrumenting the gate rather than only building it.
Promoting a green job to a required status check exposes several mechanics that setup guides skip, and each one has produced a broken gate in a real repository.
The fork constraint is documented in GitHub's guide to using secrets in GitHub Actions. For an open-source repository, the workable pattern is an advisory run on fork pull requests and a full authenticated gate once a maintainer has reviewed the diff.
Wiring the execution itself is deliberately uniform. The pattern is to download the CLI in the job, supply LT_USERNAME and LT_ACCESS_KEY from repository secrets, and invoke the binary against a configuration file:
name: E2E Gate
on:
pull_request:
types: [opened, synchronize, reopened]
paths-ignore:
- '**/*.md'
- 'docs/**'
jobs:
e2e:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run gated E2E suite
env:
LT_USERNAME: ${{ secrets.LT_USERNAME }}
LT_ACCESS_KEY: ${{ secrets.LT_ACCESS_KEY }}
run: |
wget https://downloads.lambdatest.com/hyperexecute/linux/hyperexecute
chmod u+x hyperexecute
./hyperexecute --config pr-gate.yamlThe same three steps apply to GitLab, CircleCI, Jenkins, Azure DevOps, and Bitbucket, because any system that can run a CLI command can run the gate. Setup details are in the HyperExecute documentation, and a framework-specific walkthrough is available for running Cypress tests with GitHub Actions.
A gate that becomes required on its first day will fail on someone's unrelated pull request within the week, and that first bad experience sets the team's opinion of it. Earning the required flag over four weeks avoids that.
Publish the flake number where the team can see it. A gate that is trusted because everyone has seen its measured reliability behaves differently from one that is trusted because a lead asserted it.
If your suite does not exist yet, the sequencing question changes. The related discussion of E2E test coverage on every pull request covers building that coverage, and the broader mechanics of integrating E2E tests into your CI/CD pipeline apply once the gate is stable.
Open your repository insights, count the pull requests merged in the last thirty days, and divide by working days. Multiply that by 2.5 runs and by the minutes your current suite takes, and you have the weekly engineer-hours your gate costs today. That single number tells you whether your problem is speed, selection, or trust before you change any configuration.
Then run the gate non-blocking for a week and measure its flake rate on an unchanged commit. The selection table above maps that rate to a decision, and running E2E tests in pull requests only pays off once the rate is low enough for the row you land on.
For the execution side, HyperExecute runs suites up to 70% faster than traditional grids by keeping the test script and its execution components in one isolated environment, and it carries the retry scoping, fail-fast, and failure reordering controls a gate depends on. Pair it with the GitHub App so failures arrive as a diagnosis inside the pull request rather than as a link the reviewer will not open.
Author
Himanshu Sheth is the Director of Marketing (Technical Content) at TestMu AI, with over 8 years of hands-on experience in Selenium, Cypress, and other test automation frameworks. He has authored more than 130 technical blogs for TestMu AI, covering software testing, automation strategy, and CI/CD. At TestMu AI, he leads the technical content efforts across blogs, YouTube, and social media, while closely collaborating with contributors to enhance content quality and product feedback loops. He has done his graduation with a B.E. in Computer Engineering from Mumbai University. Before TestMu AI, Himanshu led engineering teams in embedded software domains at companies like Samsung Research, Motorola, and NXP Semiconductors. He is a core member of DZone and has been a speaker at several unconferences focused on technical writing and software quality.
Reviewer
Japneet Singh Chawla is an Engineering Manager at TestMu AI (formerly LambdaTest), where he leads a team driving HyperExecute, the AI-native Test Orchestration Cloud Platform, and integrations with Cypress, Provar, Tosca, and Selenium, improving test execution efficiency and driving adoption across 500+ enterprise clients. He also spearheaded zero-downtime deployments that cut release-related downtime by 90%, and mentors new engineers into productive contributors. He brings 9+ years of experience building and scaling distributed systems, SaaS platforms, and developer tools, with deep hands-on backend engineering across Golang, Python, Node.js, Kafka, and Redis. Earlier at Sumo Logic he built award-winning developer tools, including a VS Code Parser Linter, and at Indus Valley Partners he was a founding member of the Sentiment Analyzer team, building ML-powered solutions for financial clients. Japneet holds an MCA in Computer Science from GGSIPU.
Did you find this page helpful?
More Related Blogs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance