Testes que só rodam no seu laptop não bloqueiam nada. Um desenvolvedor pode fazer merge de código que quebra sua suite de testes, e você só vai descobrir quando rodar os testes manualmente.

O que CI/CD significa para QA

CI é Continuous Integration. A ideia: toda vez que um desenvolvedor faz push de código, um processo automatizado roda, compila o código, executa os testes e reporta os resultados. Problemas são identificados em minutos após serem introduzidos, não dias depois durante o QA manual.

CD é Continuous Delivery (ou Deployment). Depois que o CI passa, o código é automaticamente publicado em um ambiente de staging, ou até em produção.

Para um QA engineer, a parte relevante é o CI. Seus testes rodam no pipeline. Todo pull request os aciona. Se os testes falham, o PR não pode fazer merge. Esse é o contrato.

Testes que só rodam no seu laptop não forçam nada. Testes no CI forçam o padrão de qualidade em cada mudança, automaticamente.

GitHub Actions: comece aqui

GitHub Actions é a ferramenta de CI mais fácil de aprender e a mais usada em projetos novos. É gratuita para repositórios públicos e tem um tier gratuito generoso para privados.

O conceito: você define um workflow em um arquivo YAML dentro do seu repositório. O GitHub executa esse workflow sempre que um evento de trigger acontece: um push, um pull request, um agendamento.

Crie .github/workflows/playwright.yml na raiz do seu projeto:

mkdir -p .github/workflows

# .github/workflows/playwright.yml
name: Playwright Tests

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

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Install Playwright browsers
        run: npx playwright install --with-deps

      - name: Run Playwright tests
        run: npx playwright test

      - name: Upload test report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 14

Faça commit desse arquivo, push para o GitHub e abra a aba Actions. Você vai ver o workflow rodando. Ele instala Node, instala os navegadores do Playwright, executa seus testes e faz upload do relatório HTML como um artefato para download.

O if: always() no passo de upload significa que o relatório é enviado mesmo quando os testes falham, que é exatamente quando você mais precisa dele.

Entendendo o arquivo de workflow

on: define o que aciona o workflow. A configuração acima roda em pushes para main e em pull requests direcionados ao main. Adicione workflow_dispatch: se quiser um botão de acionamento manual na interface do GitHub. runs-on: ubuntu-latest é o tipo de máquina. Ubuntu é o padrão para Playwright. É no que a imagem Docker do Playwright é baseada, e as dependências de navegador funcionam sem configuração extra. npm ci em vez de npm install. O ci instala exatamente o que está no package-lock.json sem modificá-lo, o que importa para reprodutibilidade no CI. npx playwright install --with-deps instala os navegadores E suas dependências de sistema. Em um runner Ubuntu limpo, os navegadores precisam de bibliotecas de sistema que não estão pré-instaladas. O --with-deps resolve isso automaticamente.

Variáveis de ambiente no GitHub Actions

Nunca coloque credenciais hardcoded no arquivo de workflow. Guarde-as como GitHub Secrets e referencie-as como variáveis de ambiente.

Vá para seu repositório → Settings → Secrets and variables → Actions → New repository secret. Adicione TEST_USER e TEST_PASS.

Referencie-os no workflow:

      - name: Run Playwright tests
        run: npx playwright test
        env:
          TEST_USER: ${{ secrets.TEST_USER }}
          TEST_PASS: ${{ secrets.TEST_PASS }}
          BASE_URL: https://lab.becomeqa.com

Nos seus testes, acesse-os como process.env.TEST_USER. Secrets são mascarados nos logs. O GitHub substitui seus valores por * se aparecerem no output.

Rodando testes mais rápido com sharding

Por padrão o Playwright usa múltiplos workers em uma única máquina. Para suites grandes, você pode dividir entre múltiplas máquinas usando sharding.

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        shard: [1, 2, 3, 4]

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test --shard=${{ matrix.shard }}/4

Isso roda 4 jobs em paralelo, cada um processando 25% dos testes. Uma suite que leva 20 minutos em uma máquina leva 5 minutos dividida em quatro.

Comece sem sharding. Adicione quando sua suite demorar mais de 5 minutos para rodar. Sharding adiciona complexidade. Não otimize antes de precisar.

GitLab CI

O GitLab CI usa os mesmos conceitos do GitHub Actions mas com sintaxe diferente. O arquivo de configuração é .gitlab-ci.yml na raiz do projeto.

# .gitlab-ci.yml
image: mcr.microsoft.com/playwright:v1.44.0-jammy

stages:
  - test

playwright:
  stage: test
  script:
    - npm ci
    - npx playwright test
  artifacts:
    when: always
    paths:
      - playwright-report/
    expire_in: 1 week
  variables:
    TEST_USER: $TEST_USER
    TEST_PASS: $TEST_PASS

Diferenças principais em relação ao GitHub Actions:

O campo image: especifica uma imagem Docker para o job. Usar a imagem oficial do Playwright (mcr.microsoft.com/playwright) significa que os navegadores já estão instalados, então não é necessário npx playwright install.

artifacts no GitLab equivale ao upload-artifact no GitHub Actions. O when: always garante o upload mesmo em caso de falha.

Variáveis são definidas no GitLab → Projeto → Settings → CI/CD → Variables. Referencie-as com $NOME_VARIAVEL na configuração.

Se você conhece GitHub Actions, consegue aprender GitLab CI em um dia. O modelo mental é idêntico: triggers, jobs, steps, artefatos. Só um YAML diferente.

Jenkins

O Jenkins é mais antigo, mais complexo e ainda dominante em ambientes enterprise de grande porte. Você vai encontrá-lo em empresas com infraestrutura legada.

O Jenkins usa um Jenkinsfile na raiz do projeto:

pipeline {
  agent {
    docker {
      image 'mcr.microsoft.com/playwright:v1.44.0-jammy'
    }
  }

  environment {
    TEST_USER = credentials('test-user')
    TEST_PASS = credentials('test-pass')
  }

  stages {
    stage('Install') {
      steps {
        sh 'npm ci'
      }
    }

    stage('Test') {
      steps {
        sh 'npx playwright test'
      }
      post {
        always {
          publishHTML(target: [
            reportDir: 'playwright-report',
            reportFiles: 'index.html',
            reportName: 'Playwright Report'
          ])
        }
      }
    }
  }
}

O Jenkins requer um servidor Jenkins rodando. Não é um serviço em nuvem. Alguém precisa instalar, configurar e manter. Por isso o GitHub Actions tem substituído o Jenkins em projetos novos.

Para QA especificamente: se você entrar em uma empresa que usa Jenkins, não precisa entender a administração do Jenkins. Precisa entender a sintaxe do Jenkinsfile bem o suficiente para adicionar ou modificar stages de teste. O pipeline DSL (a sintaxe acima) é o que os QA engineers usam no dia a dia.

Qual ferramenta aprender primeiro

A decisão é direta:

Aprenda GitHub Actions primeiro. É gratuito, não requer configuração de servidor, tem a maior comunidade, e é usado na maioria dos projetos novos. Você pode ter testes rodando no CI em uma hora a partir de um repositório zero. GitLab CI em segundo se você está mirando empresas que usam GitLab (comum em enterprise europeu, serviços financeiros, governo). Os conceitos se transferem diretamente do GitHub Actions. Jenkins em terceiro. Não porque está morrendo, mas porque entender GitHub Actions primeiro torna o Jenkins mais fácil de aprender. O conhecimento de Jenkins é mais útil em ambientes onde um time de CI já gerencia o servidor. Você não vai configurar o Jenkins do zero como QA engineer.

Como um pipeline de CI real parece

Um pipeline Playwright maduro em um projeto real tipicamente tem mais do que apenas "rodar testes":

# Pipeline realista de produção
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npx tsc --noEmit        # verificação de tipos TypeScript
      - run: npx eslint tests/       # lint dos arquivos de teste

  test:
    needs: lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20, cache: 'npm' }
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test --project=chromium  # feedback rápido em um navegador
        env:
          BASE_URL: ${{ vars.BASE_URL }}
          TEST_USER: ${{ secrets.TEST_USER }}
          TEST_PASS: ${{ secrets.TEST_PASS }}
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: playwright-report/

  test-cross-browser:
    needs: test
    if: github.ref == 'refs/heads/main'  # apenas no branch main
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20, cache: 'npm' }
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test  # todos os navegadores

O padrão: feedback rápido primeiro (lint + Chromium), depois cross-browser completo no branch main. Pull requests recebem resultados rápidos; merges recebem cobertura completa.

Não rode testes cross-browser em todo PR desde o início. Isso triplica o tempo de CI e a maioria dos bugs não é específica de navegador. Rode cross-browser apenas em merges para main até a suite estar madura.

FAQ

Meus testes passam localmente mas falham no GitHub Actions. O que está errado?

Verifique três coisas: variáveis de ambiente (secrets não definidos no Actions), base URL (localhost hardcoded que não existe no CI), e timing. Runners de CI são mais lentos, então adicione retries: 1 no playwright.config.ts para CI.

Como vejo o relatório do Playwright de uma execução de CI que falhou?

No GitHub Actions: vá para a execução que falhou → Summary → Artifacts → baixe playwright-report. Extraia o zip e abra index.html em um navegador.

Posso rodar apenas os testes alterados no CI?

Não nativamente no Playwright. Alguns times usam filtragem por caminho: rodar apenas testes em tests/auth/ quando arquivos em src/auth/ mudam. É complexo de configurar de forma confiável. Comece rodando a suite completa e otimize depois se ficar muito lenta.

Como rodo testes em um agendamento (ex: todo dia à noite)?

Adicione um trigger de schedule:

on:
  schedule:
    - cron: '0 2 * * *'   # 2h UTC toda noite
  push:
    branches: [main]

Execuções noturnas são úteis para pegar falhas intermitentes que não aparecem em todo PR.

→ Veja também: GitHub Actions para Testes Playwright: A Configuração Completa (2026) | GitLab CI + Playwright: Guia Completo de Configuração | Jenkins + Playwright: Construindo um Pipeline CI do Zero | Execução Paralela no Playwright: Workers, Shards e Sharding para Velocidade