Series Navigation
→ Part 17: Headless Browsers and Docker
Jenkinsfile — Declarative Pipeline
// Jenkinsfile
pipeline {
agent any
tools {
maven 'Maven-3.8'
jdk 'JDK-11'
}
parameters {
choice(name: 'BROWSER', choices: ['chrome', 'firefox', 'edge'], description: 'Browser to test')
choice(name: 'ENVIRONMENT', choices: ['staging', 'prod'], description: 'Target environment')
booleanParam(name: 'HEADLESS', defaultValue: true, description: 'Run headless?')
}
environment {
BASE_URL = "${params.ENVIRONMENT == 'staging' ? 'https://staging.app.com' : 'https://app.com'}"
TIMESTAMP = sh(script: 'date +%Y%m%d_%H%M%S', returnStdout: true).trim()
}
stages {
stage('Checkout') {
steps {
git branch: 'main', url: 'https://github.com/yourname/selenium-project.git'
echo "Running on: ${env.NODE_NAME}"
}
}
stage('Validate') {
steps {
sh 'mvn --version'
sh 'java -version'
sh 'google-chrome --version || chromium --version'
}
}
stage('Download Dependencies') {
steps {
sh 'mvn dependency:resolve -q'
}
}
stage('Run Selenium Tests') {
steps {
sh """
mvn test \
-Dbrowser=${params.BROWSER} \
-Dheadless=${params.HEADLESS} \
-Dbase.url=${env.BASE_URL} \
-DsuiteXmlFile=src/test/resources/testng.xml \
2>&1 | tee test-output/maven-output.log
"""
}
post {
always {
// Archive screenshots on failure
archiveArtifacts artifacts: 'test-output/screenshots/**/*.png',
allowEmptyArchive: true
}
}
}
stage('Publish Reports') {
steps {
// Publish TestNG HTML report
publishHTML(target: [
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'test-output',
reportFiles: 'index.html',
reportName: 'TestNG Report'
])
}
}
}
post {
failure {
emailext(
subject: "FAILED: Selenium Tests — ${env.JOB_NAME} #${env.BUILD_NUMBER}",
body: """
<h2>Selenium Test Failure</h2>
<p><b>Job:</b> ${env.JOB_NAME}</p>
<p><b>Build:</b> #${env.BUILD_NUMBER}</p>
<p><b>Browser:</b> ${params.BROWSER}</p>
<p><b>Environment:</b> ${params.ENVIRONMENT}</p>
<p><b>Console:</b> <a href="${env.BUILD_URL}console">${env.BUILD_URL}console</a></p>
<p><b>Report:</b> <a href="${env.BUILD_URL}TestNG_Report">View TestNG Report</a></p>
""",
to: "team@example.com",
mimeType: 'text/html'
)
}
always {
// Archive full test output
archiveArtifacts artifacts: 'test-output/**', allowEmptyArchive: true
// Clean workspace
cleanWs()
}
}
}
Maven Surefire Plugin Configuration
<!-- pom.xml -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<!-- TestNG suite file -->
<suiteXmlFiles>
<suiteXmlFile>${suiteXmlFile}</suiteXmlFile>
</suiteXmlFiles>
<!-- System properties passed to tests -->
<systemPropertyVariables>
<browser>${browser}</browser>
<headless>${headless}</headless>
<base.url>${base.url}</base.url>
<environment>${environment}</environment>
</systemPropertyVariables>
<!-- Rerun failing tests up to 2 times -->
<rerunFailingTestsCount>2</rerunFailingTestsCount>
<!-- Fail build if tests fail -->
<testFailureIgnore>false</testFailureIgnore>
</configuration>
</plugin>
Default values in pom.xml properties:
<properties>
<browser>chrome</browser>
<headless>true</headless>
<base.url>https://staging.example.com</base.url>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</properties>
Reading System Properties in Tests
public class BaseTest {
protected static Properties config = new Properties();
static {
// System properties (from -Dproperty=value) override config file
config.setProperty("browser",
System.getProperty("browser", "chrome"));
config.setProperty("headless",
System.getProperty("headless", "false"));
config.setProperty("base.url",
System.getProperty("base.url", "https://staging.example.com"));
}
}
GitLab CI Integration
# .gitlab-ci.yml
image: maven:3.8-openjdk-11
stages:
- test
selenium-tests:
stage: test
before_script:
- apt-get update -qq && apt-get install -y -qq chromium chromium-driver
- export CHROME_BIN=/usr/bin/chromium
script:
- mvn test
-Dbrowser=chrome
-Dheadless=true
-Dbase.url=$STAGING_URL
artifacts:
when: always
paths:
- test-output/
reports:
junit: test-output/junitreports/*.xml
expire_in: 7 days
only:
- main
- merge_requests
What's Next
In Part 17 we run tests without a display — headless Chrome and Firefox on Linux CI servers, and fully containerised tests in Docker with zero system dependencies.
Discussion
Loading...Leave a Comment
All comments are reviewed before appearing. No links please.