Pipelines do GitLab CI para Playwright exigem uma decisão de design antecipada: instalar os navegadores durante o pipeline ou usar a imagem Docker oficial do Playwright. A abordagem com Docker é mais rápida. Ela evita o modo de falha mais comum: uma incompatibilidade de versão entre a tag da imagem e o @playwright/test no package.json quebra o pipeline com um erro executable doesn't exist.
Pré-requisitos
- Projeto Playwright funcionando localmente com
npx playwright test - Repositório no GitLab (gitlab.com ou self-hosted)
.gitlab-ci.ymlainda não existe (ou você está adicionando a ele)
O pipeline mínimo funcional
Crie .gitlab-ci.yml na raiz do projeto:
image: mcr.microsoft.com/playwright:v1.44.0-jammy
stages:
- test
playwright-tests:
stage: test
script:
- npm ci
- npx playwright test
artifacts:
when: always
paths:
- playwright-report/
expire_in: 7 daysÉ isso. Faça push desse arquivo e o GitLab CI vai rodar seus testes em cada commit.
Explicação linha a linha
image: mcr.microsoft.com/playwright:v1.44.0-jammy
Esse é o container Docker dentro do qual o pipeline roda. A imagem Docker oficial do Playwright vem com:
- Node.js
- Todas as dependências de navegadores do Playwright pré-instaladas
- Ambiente Linux
Essa é a abordagem recomendada: sem instalação de navegador necessária no pipeline.
Fixe a versão (v1.44.0, não latest) para que o pipeline não quebre quando o Playwright lançar uma nova versão. Atualize manualmente quando fizer upgrade do Playwright localmente.
npm ci vs. npm install
No CI, sempre use npm ci em vez de npm install:
npm ciinstala exatamente o que está nopackage-lock.json(determinístico)npm cié mais rápido em ambientes de CInpm cifalha se opackage-lock.jsonestiver ausente ou inconsistente
artifacts
O Playwright gera um relatório HTML em playwright-report/ após cada execução. A seção artifacts diz ao GitLab para salvar essa pasta para você poder baixar e visualizar.
when: always— salva artefatos mesmo se os testes falharem (você mais precisa do relatório quando os testes falham!)expire_in: 7 days— o GitLab deleta artefatos automaticamente após 7 dias
Para ver o relatório: GitLab CI → o pipeline → o job → "Download artifacts" → abra playwright-report/index.html.
Um pipeline mais completo
Para projetos reais, você vai querer mais estrutura:
image: mcr.microsoft.com/playwright:v1.44.0-jammy
stages:
- test
variables:
# Armazenar node_modules em cache entre runs para velocidade
npm_config_cache: "$CI_PROJECT_DIR/.npm"
cache:
key: "$CI_COMMIT_REF_SLUG"
paths:
- .npm/
- node_modules/
playwright-tests:
stage: test
# Rodar em merge requests e na branch main
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
script:
- npm ci
- npx playwright test --reporter=html,junit
artifacts:
when: always
paths:
- playwright-report/
- test-results/
reports:
junit: test-results/results.xml
expire_in: 7 days
# Timeout para o job inteiro
timeout: 20 minutesO que há de novo aqui:
variables: Define variáveis de ambiente para o job. npm_config_cache diz ao npm para usar um diretório de cache específico.
cache: Os módulos Node são armazenados em cache entre runs do pipeline. Primeiro run: lento (baixa tudo). Runs subsequentes: rápido (lê do cache). A chave é o nome da branch, então branches diferentes têm caches separados.
rules: Controla quando esse job roda. A configuração acima roda em:
- Merge requests (para ver os resultados antes de fazer merge)
- Pushes para
main(após fazer merge)
--reporter=html,junit: Gera tanto o relatório HTML quanto o XML JUnit. O formato JUnit é entendido pelo GitLab e mostra os resultados dos testes diretamente na UI do pipeline.
reports: junit: Diz ao GitLab onde está o XML JUnit. O GitLab então mostra uma aba "Tests" no pipeline com passou/falhou por teste.
Usando variáveis de ambiente (segredos)
Nunca coloque senhas ou chaves de API no .gitlab-ci.yml. Use variáveis CI/CD do GitLab:
1. Project → Settings → CI/CD → Variables
2. Adicione: BASE_URL, ADMIN_EMAIL, ADMIN_PASSWORD, API_KEY
3. Marque as sensíveis como "Masked" (ocultas nos logs)
4. Marque as específicas de ambiente como "Protected" (só roda em branches protegidas)
Usando no pipeline:playwright-tests:
script:
- npm ci
- npx playwright test
variables:
BASE_URL: $BASE_URL # Das variáveis CI do GitLab
ADMIN_EMAIL: $ADMIN_EMAIL # Das variáveis CI do GitLab// playwright.config.ts
import dotenv from 'dotenv';
dotenv.config();
export default defineConfig({
use: {
baseURL: process.env.BASE_URL || 'http://localhost:3000',
},
});Variáveis CI do GitLab estão disponíveis como variáveis de ambiente no job: process.env.BASE_URL funciona.
Execução paralela e sharding
Para suites de testes grandes, rode os testes em paralelo:
playwright-tests:
stage: test
parallel:
matrix:
- SHARD: ["1/4", "2/4", "3/4", "4/4"]
script:
- npm ci
- npx playwright test --shard=$SHARD
artifacts:
when: always
paths:
- playwright-report/
expire_in: 7 daysIsso cria 4 jobs paralelos, cada um rodando 25% dos testes. O tempo total de testes é dividido por 4.
Atenção: juntar os relatórios HTML divididos exige steps adicionais (o comando merge-reports do Playwright).
Rodando em modo headed (debugging)
Por padrão, o Playwright roda headless no CI. Se precisar debugar visualmente:
playwright-debug:
stage: test
script:
- npm ci
- npx playwright test --headed --video=on
when: manual # Só roda quando disparado manualmente
artifacts:
when: always
paths:
- test-results/ # Vídeos são salvos aqui
expire_in: 1 daywhen: manual significa que esse job não roda automaticamente: você o dispara manualmente pela UI do GitLab quando precisar debugar.
Lidando com testes flaky
O Playwright tem lógica de retry integrada. Configure para CI:
// playwright.config.ts
export default defineConfig({
retries: process.env.CI ? 2 : 0, // Retry 2 vezes apenas no CI
});Ou no .gitlab-ci.yml, permita que o próprio job tente novamente em caso de falha:
playwright-tests:
retry:
max: 1 # Tenta novamente o job inteiro uma vez se falhar
when:
- runner_system_failure
- stuck_or_timeout_failureRetry no nível do job (GitLab) é para falhas de infraestrutura. Retry no nível de teste (config do Playwright) é para testes flaky. Use os dois.
Exemplo completo com múltiplos ambientes
image: mcr.microsoft.com/playwright:v1.44.0-jammy
stages:
- test
.playwright-base:
script:
- npm ci
- npx playwright test --reporter=html,junit
artifacts:
when: always
paths:
- playwright-report/
reports:
junit: test-results/results.xml
expire_in: 7 days
timeout: 20 minutes
playwright-staging:
extends: .playwright-base
variables:
BASE_URL: https://staging.seuapp.com
rules:
- if: $CI_COMMIT_BRANCH == "develop"
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
playwright-production:
extends: .playwright-base
variables:
BASE_URL: https://seuapp.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
environment:
name: productionIsso roda os testes de staging na branch develop e nos PRs, e os testes de produção apenas ao fazer merge na main.
Resolvendo problemas comuns
Erro "Executable doesn't exist":Você não está usando a imagem Docker do Playwright, ou está na versão errada. Use mcr.microsoft.com/playwright:v1.44.0-jammy e a versão deve corresponder exatamente à sua versão do @playwright/test.
Máquinas de CI são mais lentas. Aumente os timeouts no playwright.config.ts:
export default defineConfig({
timeout: 60000, // 60s por teste (acima do padrão de 30s)
actionTimeout: 15000, // 15s por ação
});Você tem uma dependência que não está no package.json. Rode npm install localmente e faça commit do package.json e package-lock.json atualizados.
Adicione cache (mostrado no exemplo completo acima). O primeiro run vai ser lento; os runs seguintes vão ser rápidos.
Checklist rápido
Antes de fazer push do seu primeiro pipeline:
- [ ]
.gitlab-ci.ymlestá na raiz do projeto - [ ] Usando a imagem Docker do Playwright com versão fixada
- [ ]
npm ci(nãonpm install) - [ ] Artefatos configurados para salvar
playwright-report/ - [ ] Segredos nas variáveis CI do GitLab, não no arquivo YAML
- [ ]
retriesdo Playwright configurado para o ambiente de CI - [ ]
timeoutdefinido noplaywright.config.ts(máquinas de CI são mais lentas)
Com esse setup, cada push para o repositório vai rodar automaticamente a suite de testes e disponibilizar os resultados na visualização do pipeline do GitLab.