Skip to main content
L3gitUI & API TEST AUTOMATION
[ PRODUCT ][ PRICING ][ DOCS ][ VERIFIED ][ REGULATED ][ COMPARE ][ ACCOUNT ] Start Free Trial

/// Selenium Grid alternative

Run Selenium in parallel without a Selenium Grid

A Grid is a hub, nodes, a version matrix to babysit, and a hub outage that takes every suite down at once. L3git writes you a Jenkins Matrix pipeline instead: shards × browsers, every cell on a Jenkins agent you already own, each running only its slice of a plain Cucumber + Selenium suite. Same tests, no Grid.

Grid vs. your own agents

Selenium Grid / cloud grid

  • A hub and N nodes to install, patch and keep version-matched to every browser and driver.
  • One hub outage, every pipeline red.
  • Cloud grids meter by the minute; parallelism is a line item.
  • Air-gapped and government networks often cannot reach a cloud grid at all.

Jenkins matrix on your agents

  • Agents need JDK 17, Maven and the browser IT already installs. Nothing else to run.
  • One agent down = one cell retried, not a dead suite.
  • $0 per run. Parallelism is however many agents you point a label at.
  • Works offline and air-gapped: bundled WebDrivers, installed Edge, local AI.

What L3git writes for you

Jenkins needs matrix axes written literally into the Jenkinsfile — they cannot come from a build parameter. So the tool asks at generate time and writes them. Four shards × Edge and Chrome gives you this (trimmed):

// Jenkins MATRIX pipeline for Checkout - generated by L3git.
pipeline {
  agent none
  stages { stage('Matrix') { matrix {
    axes {
      axis { name 'SHARD';   values '1', '2', '3', '4' }
      axis { name 'BROWSER'; values 'edge', 'chrome' }
    }
    agent { label 'ui-test' }
    environment { SHARDS = '4'; HEALING_BROWSER = "${BROWSER}"; HEALING_HEADLESS = 'true' }
    stages { stage('Test') { steps { script {
      // ShardSelector returns a Cucumber tag expression naming this cell's scenarios
      def shard = sh(script: "java -cp target/test-classes com.example.support.ShardSelector ${SHARD}/${SHARDS}", returnStdout: true).trim()
      sh "mvn -B test -Dcucumber.filter.tags=\"${shard}\""
    } } } }
    post { always { junit 'target/surefire-reports/*.xml' } }
  } } }
}

Eight cells run at once. Blue Ocean shows them as a grid; JUnit merges them into one report. TAGS stays a build parameter and combines with the shard.

How the move works

01 · LABEL YOUR AGENTS

JDK 17, Maven and the browsers you ship on, on agents you already run. Label them ui-test. Air-gapped? Drop the matching WebDriver on disk; the generated project ships them.

02 · PICK THE MATRIX

In L3git’s startup window, under CI / Maven project: shards, browsers, agent label. The tool writes the Jenkinsfile; you never hand-edit axes.

03 · POINT JENKINS AT THE REPO

Commit, create a Pipeline from SCM job, run. Change the fan-out later by regenerating — L3git rewrites a Jenkinsfile it wrote and leaves a hand-edited one alone.

Why the split is safe to rely on

Deterministic shards

Scenarios are assigned by hashing their stable @l3id tag. The same test always lands on the same shard; adding or renaming a test never reshuffles the others. Flake history stays attached to the right scenario.

verify: java -cp target/test-classes com.example.support.ShardSelector 2/4

Nothing proprietary in the loop

The suite is plain Cucumber + Selenium on Maven. ShardSelector is a 1-file Java class in your repo. Remove L3git and the pipeline still runs.

Browser per cell, not per hub

HEALING_BROWSER is set from the matrix axis, so each cell drives the browser installed on its own agent. Self-healing locators keep working across all of them.

Keep a Grid for what a Grid is for

Many browser versions or operating systems from one job is the one case a Grid or cloud still wins. One property in healing.properties points the same suite at BrowserStack, Sauce Labs, LambdaTest or your own hub.

Who moves off the Grid

Compared with other approaches

No-code SeleniumSection 508 testingAir-gapped & regulatedSimple setup guide (no jargon)Guide: Jenkins matrix setupFull comparison table

Common questions

Do I have to run a Selenium Grid to run tests in parallel?

No. The Jenkinsfile L3git generates is a declarative Matrix pipeline: each cell is a shard x browser, runs on a Jenkins agent with your label, drives the browser installed on that agent and runs only its slice of the suite. Parallelism comes from agents you already have, not from a hub.

How are scenarios split between shards?

By a hash of each scenario's stable @l3id tag. The same scenario always lands on the same shard, and adding or renaming tests never reshuffles the others, so results stay comparable from run to run. Add --balance for perfectly even counts.

What happens to my tests when I move off the Grid?

Nothing changes in the tests. They are ordinary Cucumber + Selenium on Maven; only the Jenkinsfile and one property differ. If you later want a Grid or a cloud again, one property in healing.properties points the same suite back at a hub.

Which browsers can the matrix cover?

Any of Edge, Chrome and Firefox that are installed on the agent. Tick the browsers at generate time and the matrix gets one row per browser. Many browser versions or operating systems from one job is the one case where a Grid or cloud still earns its keep.

Does this work on GitHub Actions or GitLab?

The generated GitHub Actions workflow has the same split as a matrix (raise total). Any CI that can run N jobs with a shard index can call ShardSelector k/n the same way.

What does it cost?

Nothing per run. L3git UI is $49 per user per month (annual) with unlimited runs in your CI; Suite with API testing is $169. A 14-day trial needs no key or card.

Download the 14-day trial The 7-step setup guide