Answer
Script Works Locally but Fails in CI/CD — Diagnosis Guide
This is one of the most common real-world Selenium problems. Work through these causes in order:
Root Cause 1 — Missing Headless Mode
CI servers have no display. You must run headless:
Java
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new");
options.addArguments("--no-sandbox"); // required in Docker/Linux
options.addArguments("--disable-dev-shm-usage"); // prevents memory crashes
options.addArguments("--disable-gpu");
options.addArguments("--window-size=1920,1080"); // headless has no screen size
WebDriver driver = new ChromeDriver(options);
Root Cause 2 — Timing / Waits
CI machines are slower than your dev machine. Replace all Thread.sleep() with proper waits:
Java
// Bad
Thread.sleep(3000);
// Good
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(15));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("result")));
Root Cause 3 — Browser/Driver Version Mismatch
Pin versions in CI to match what's installed:
Java
// Use WebDriverManager to auto-manage driver versions
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
Or in pom.xml:
XML
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>5.7.0</version>
</dependency>
Root Cause 4 — File Paths
Local absolute paths break in CI:
Java
// Bad
String filePath = "C:\\Users\\nagen\\test.csv";
// Good — relative to project root
String filePath = System.getProperty("user.dir") + "/src/test/resources/test.csv";
Root Cause 5 — Environment Config
Use environment variables or property files for URLs and credentials:
Java
String baseUrl = System.getenv("BASE_URL");
// Set BASE_URL in Jenkins/GitHub Actions env config
CI/CD Failure Checklist
| Issue | Fix |
|---|---|
| No display | Add --headless=new flag |
| Element not found | Increase explicit waits |
| Driver not found | Use WebDriverManager |
| Wrong path | Use relative paths |
| Wrong URL | Use env variables |
| Memory crash | --disable-dev-shm-usage |
| Screenshot on fail | Capture in @AfterMethod |
