Answer
Complete GitHub Actions Pipeline for Selenium Java
Directory Structure
CODE
selenium-framework/
├── .github/
│ └── workflows/
│ ├── ci.yml ← runs on every push/PR
│ └── nightly.yml ← full regression at 2 AM
├── src/
│ └── test/java/...
├── testng.xml
├── smoke-testng.xml
└── pom.xml
CI Workflow — Every Push and PR
YAML
# .github/workflows/ci.yml
name: Selenium Test Suite
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
browser:
type: choice
options: [chrome, firefox, edge]
default: chrome
environment:
type: choice
options: [staging, qa]
default: staging
suite:
type: choice
options: [testng.xml, smoke-testng.xml]
default: smoke-testng.xml
env:
JAVA_VERSION: '17'
BROWSER: ${{ inputs.browser || 'chrome' }}
ENVIRONMENT: ${{ inputs.environment || 'staging' }}
SUITE: ${{ inputs.suite || 'smoke-testng.xml' }}
MAVEN_OPTS: '-Xmx1024m'
jobs:
selenium-tests:
name: "${{ env.SUITE }} on ${{ env.BROWSER }} (${{ env.ENVIRONMENT }})"
runs-on: ubuntu-latest
steps:
# 1. Get the code
- name: Checkout repository
uses: actions/checkout@v4
# 2. Set up Java with Maven cache
- name: Set up JDK ${{ env.JAVA_VERSION }}
uses: actions/setup-java@v4
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: temurin
cache: maven
# 3. Install Chrome for headless execution
- name: Install Google Chrome
run: |
sudo apt-get update -q
sudo apt-get install -y google-chrome-stable
google-chrome --version
# 4. Run Selenium tests
- name: Run Selenium Tests
id: test-run
run: |
mvn test \
-Dbrowser=${{ env.BROWSER }} \
-Denv=${{ env.ENVIRONMENT }} \
-Dsurefire.suiteXmlFiles=${{ env.SUITE }} \
-Dheadless=true
env:
BASE_URL: ${{ secrets.BASE_URL }}
DB_USER: ${{ secrets.DB_USER }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
continue-on-error: true
# 5. Upload test reports (always)
- name: Upload Surefire Reports
if: always()
uses: actions/upload-artifact@v4
with:
name: surefire-${{ env.BROWSER }}-${{ github.run_number }}
path: target/surefire-reports/
retention-days: 14
- name: Upload Allure Results
if: always()
uses: actions/upload-artifact@v4
with:
name: allure-results-${{ github.run_number }}
path: target/allure-results/
retention-days: 14
# 6. Upload screenshots on failure
- name: Upload failure screenshots
if: failure() || steps.test-run.outcome == 'failure'
uses: actions/upload-artifact@v4
with:
name: screenshots-${{ github.run_number }}
path: screenshots/
if-no-files-found: ignore
# 7. Notify Slack on failure
- name: Slack notification on failure
if: failure()
uses: slackapi/slack-github-action@v1.26.0
with:
payload: |
{
"text": "❌ *Tests FAILED*: ${{ github.repository }} | Branch: ${{ github.ref_name }} | Browser: ${{ env.BROWSER }} | <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Run>"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
# 8. Fail the job if tests failed
- name: Fail if tests failed
if: steps.test-run.outcome == 'failure'
run: exit 1
Nightly Regression Workflow
YAML
# .github/workflows/nightly.yml
name: Nightly Regression
on:
schedule:
- cron: '0 2 * * 1-5' # 2 AM UTC weekdays
jobs:
regression:
strategy:
fail-fast: false
matrix:
browser: [chrome, firefox]
runs-on: ubuntu-latest
name: Regression on ${{ matrix.browser }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: '17'
distribution: temurin
cache: maven
- run: sudo apt-get install -y google-chrome-stable firefox
- name: Full regression
run: mvn test -Dbrowser=${{ matrix.browser }} -Dsurefire.suiteXmlFiles=testng.xml
env:
BASE_URL: ${{ secrets.STAGING_URL }}
- if: always()
uses: actions/upload-artifact@v4
with:
name: nightly-${{ matrix.browser }}
path: target/surefire-reports/
Java Headless Driver Config
Java
// Read from system property set by Maven
boolean headless = Boolean.parseBoolean(System.getProperty("headless", "false"));
ChromeOptions opts = new ChromeOptions();
if (headless) {
opts.addArguments("--headless=new", "--no-sandbox",
"--disable-dev-shm-usage", "--window-size=1920,1080");
}
driver = new ChromeDriver(opts);
