Selenium en GitHub Actions CI/CD

Avanzado
Selenium
Selenium
Actualizado: 18/04/2026

GitHub Actions para pruebas Selenium

GitHub Actions es la plataforma de CI/CD integrada en GitHub. Los runners ubuntu-latest ya tienen instalados Chrome, Firefox y Java, lo que los hace ideales para ejecutar pruebas Selenium sin configuración adicional de navegadores.

Ventajas frente a otras soluciones CI/CD:

  • Integración nativa con GitHub (pull requests, issues, releases)
  • Runners gratuitos con 2000 minutos/mes en planes free
  • Chrome y Firefox preinstalados en los runners Ubuntu
  • Marketplace de actions con miles de acciones reutilizables

Workflow básico para Maven + Selenium

Crea el archivo .github/workflows/selenium-tests.yml:

# .github/workflows/selenium-tests.yml
name: Pruebas Selenium

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  selenium-tests:
    name: Tests Selenium en ${{ matrix.os }}
    runs-on: ubuntu-latest   # Chrome y Firefox preinstalados

    steps:
      # 1. Checkout del código
      - name: Obtener código fuente
        uses: actions/checkout@v4

      # 2. Configurar Java
      - name: Configurar JDK 21
        uses: actions/setup-java@v4
        with:
          java-version: "21"
          distribution: "temurin"
          cache: maven   # Caché automático de ~/.m2

      # 3. Verificar Chrome instalado
      - name: Verificar versión de Chrome
        run: google-chrome --version

      # 4. Ejecutar tests
      - name: Ejecutar pruebas Selenium
        run: mvn test -B
        env:
          CHROME_HEADLESS: "true"
          BASE_URL: ${{ vars.BASE_URL }}

      # 5. Publicar reporte de tests
      - name: Publicar reporte Surefire
        uses: actions/upload-artifact@v4
        if: always()   # Publicar aunque los tests fallen
        with:
          name: reporte-selenium-${{ github.run_number }}
          path: target/surefire-reports/
          retention-days: 30

Configurar ChromeDriver para CI

Los runners de GitHub Actions son entornos sin interfaz gráfica. Selenium Manager detecta automáticamente el Chrome instalado, pero es necesario configurar las opciones correctas:

// src/test/java/utils/DriverFactory.java
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

public class DriverFactory {

    public static WebDriver crearDriver() {
        String navegador = System.getProperty("navegador", "chrome");
        boolean headless = Boolean.parseBoolean(
            System.getenv().getOrDefault("CHROME_HEADLESS", "false")
        );

        return switch (navegador.toLowerCase()) {
            case "chrome" -> crearChrome(headless);
            case "firefox" -> crearFirefox(headless);
            default -> throw new IllegalArgumentException(
                "Navegador no soportado: " + navegador
            );
        };
    }

    private static WebDriver crearChrome(boolean headless) {
        var options = new ChromeOptions();

        if (headless) {
            options.addArguments("--headless=new");  // Chrome 112+ headless moderno
        }

        // Opciones esenciales para contenedores Docker / GitHub Actions
        options.addArguments("--no-sandbox");
        options.addArguments("--disable-dev-shm-usage");
        options.addArguments("--disable-gpu");
        options.addArguments("--window-size=1920,1080");
        options.addArguments("--disable-extensions");

        return new ChromeDriver(options);
    }

    private static WebDriver crearFirefox(boolean headless) {
        var options = new FirefoxOptions();

        if (headless) {
            options.addArguments("--headless");
        }

        return new FirefoxDriver(options);
    }
}

Workflow con matriz de navegadores y versiones

Ejecutar las mismas pruebas en múltiples navegadores y versiones de Java:

# .github/workflows/selenium-matrix.yml
name: Pruebas Selenium - Matriz

on:
  push:
    branches: [ main ]
  schedule:
    - cron: "0 6 * * 1-5"   # Lunes a viernes a las 6:00 AM

jobs:
  tests-matriz:
    name: Java ${{ matrix.java }} / ${{ matrix.navegador }}
    runs-on: ubuntu-latest

    strategy:
      fail-fast: false   # No cancelar otros jobs si uno falla
      matrix:
        java: [ "21", "17" ]
        navegador: [ "chrome", "firefox" ]

    steps:
      - uses: actions/checkout@v4

      - name: Configurar JDK ${{ matrix.java }}
        uses: actions/setup-java@v4
        with:
          java-version: ${{ matrix.java }}
          distribution: "temurin"
          cache: maven

      - name: Ejecutar tests con ${{ matrix.navegador }}
        run: mvn test -B -Dnavegador=${{ matrix.navegador }}
        env:
          CHROME_HEADLESS: "true"

      - name: Subir reporte
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: reporte-java${{ matrix.java }}-${{ matrix.navegador }}
          path: target/surefire-reports/

Workflow con Gradle

# .github/workflows/selenium-gradle.yml
name: Pruebas Selenium con Gradle

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  selenium:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Configurar JDK 21
        uses: actions/setup-java@v4
        with:
          java-version: "21"
          distribution: "temurin"

      # Caché manual para Gradle
      - name: Caché de Gradle
        uses: actions/cache@v4
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: gradle-

      - name: Hacer ejecutable el wrapper de Gradle
        run: chmod +x gradlew

      - name: Ejecutar tests
        run: ./gradlew test --no-daemon
        env:
          CHROME_HEADLESS: "true"

      - name: Publicar resultados de tests
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: resultados-gradle
          path: build/reports/tests/test/
          retention-days: 7

Gestión de secretos y variables de entorno

# .github/workflows/selenium-con-secretos.yml
jobs:
  tests:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: "21"
          distribution: "temurin"
          cache: maven

      - name: Ejecutar tests de integración
        run: mvn test -B -Dgroups=integracion
        env:
          CHROME_HEADLESS: "true"
          # Variables de entorno de configuración (GitHub Actions Variables)
          BASE_URL: ${{ vars.STAGING_URL }}
          APP_TIMEOUT: ${{ vars.TEST_TIMEOUT }}
          # Secretos (GitHub Actions Secrets - no se muestran en logs)
          TEST_USER_EMAIL: ${{ secrets.TEST_USER_EMAIL }}
          TEST_USER_PASSWORD: ${{ secrets.TEST_USER_PASSWORD }}
          API_KEY: ${{ secrets.API_KEY }}

Lectura en Java:

// src/test/java/config/ConfiguracionPruebas.java
public class ConfiguracionPruebas {

    public static String getBaseUrl() {
        return System.getenv().getOrDefault("BASE_URL", "http://localhost:8080");
    }

    public static String getUsuarioPrueba() {
        return System.getenv().getOrDefault("TEST_USER_EMAIL", "test@local.com");
    }

    public static String getPasswordPrueba() {
        return System.getenv().getOrDefault("TEST_USER_PASSWORD", "test_password");
    }

    public static int getTimeoutSegundos() {
        return Integer.parseInt(
            System.getenv().getOrDefault("APP_TIMEOUT", "10")
        );
    }
}

Notificaciones de resultados en Pull Requests

      # Publicar resumen de resultados en el PR
      - name: Publicar resumen de tests
        uses: dorny/test-reporter@v1
        if: always()
        with:
          name: Resultados Selenium
          path: target/surefire-reports/*.xml
          reporter: java-junit
          fail-on-error: true

Workflow completo con todas las optimizaciones

# .github/workflows/selenium-completo.yml
name: Suite Completa Selenium

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main, develop ]

env:
  JAVA_VERSION: "21"
  MAVEN_OPTS: "-Xmx2048m"

jobs:
  # Fase 1: Compilación y tests unitarios
  compilar:
    name: Compilar y tests unitarios
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: ${{ env.JAVA_VERSION }}
          distribution: temurin
          cache: maven
      - run: mvn compile test-compile -B

  # Fase 2: Tests Selenium en paralelo
  selenium:
    name: Selenium (${{ matrix.grupo }})
    runs-on: ubuntu-latest
    needs: compilar
    strategy:
      fail-fast: false
      matrix:
        grupo: [ autenticacion, catalogo, checkout, perfil ]

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-java@v4
        with:
          java-version: ${{ env.JAVA_VERSION }}
          distribution: temurin
          cache: maven

      - name: Tests del grupo ${{ matrix.grupo }}
        run: mvn test -B -Dgroups=${{ matrix.grupo }}
        env:
          CHROME_HEADLESS: "true"
          BASE_URL: ${{ vars.STAGING_URL }}
          TEST_USER_EMAIL: ${{ secrets.TEST_USER_EMAIL }}
          TEST_USER_PASSWORD: ${{ secrets.TEST_USER_PASSWORD }}

      - name: Captura de pantallas en fallos
        uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: capturas-fallo-${{ matrix.grupo }}
          path: target/capturas/
          retention-days: 7

      - name: Reportes de tests
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: reporte-${{ matrix.grupo }}-${{ github.run_number }}
          path: target/surefire-reports/
          retention-days: 14

Solución de problemas comunes en CI

Chrome falla en GitHub Actions

// Añadir siempre estas opciones en CI
options.addArguments("--headless=new");
options.addArguments("--no-sandbox");          // Requerido en contenedores
options.addArguments("--disable-dev-shm-usage"); // Evita crashes por falta de memoria compartida
options.addArguments("--disable-gpu");         // Evita problemas de renderizado
options.addArguments("--window-size=1920,1080"); // Resolución fija
options.addArguments("--remote-debugging-port=9222");

Tests lentos por timeouts

      - name: Ejecutar tests con timeout extendido
        run: mvn test -B
        timeout-minutes: 30   # Timeout a nivel de GitHub Actions
        env:
          CHROME_HEADLESS: "true"
          APP_TIMEOUT: "20"   # Timeout de esperas Selenium en segundos

Verificar que Chrome está disponible

      - name: Información del entorno
        run: |
          echo "Chrome: $(google-chrome --version)"
          echo "Firefox: $(firefox --version)"
          echo "Java: $(java -version 2>&1)"
          echo "Maven: $(mvn -version)"

Fuentes y referencias

Documentación oficial y recursos externos para profundizar en Selenium

Documentación oficial de Selenium
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Selenium es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Selenium

Explora más contenido relacionado con Selenium y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

Crear un workflow de GitHub Actions que ejecute tests Selenium en cada push y PR. Configurar Chrome headless en entornos Ubuntu de GitHub Actions. Usar matrices de versiones para probar en múltiples versiones de Java y navegadores. Guardar y publicar reportes HTML de Surefire como artefactos de GitHub Actions. Gestionar variables de entorno y secretos para URLs y credenciales de prueba. Optimizar el pipeline con caché de dependencias Maven/Gradle para builds más rápidos.