Integração com Azure DevOps
Status: prova de conceito validada com dados reais (02/09/2026) — script funcional, testado
de ponta a ponta contra o board de verdade (https://dev.azure.com/group-software/PartnerBank).
Ainda não está conectado a nenhum gatilho automático do Cypress (ver "O que falta" no fim).
Por que existe
Ideia original: ter uma forma automática de ligar o board do Azure DevOps (onde vivem as Tasks/Bugs/Validations do time) com a suíte Cypress — ler o que precisa ser testado, e eventualmente criar/comentar itens a partir de um resultado de teste. Hoje resolve a parte de "cola" (ler/comentar/criar no Azure); a parte de "julgamento" (decidir sozinho quando algo é um bug novo de verdade, sem alguém pedir) fica pra depois — motivo detalhado em "O que falta".
Onde mora
- Script:
scripts/azure-devops.js— Node puro, sem dependência nova (usafetchnativo, Node 18+). Roda solto, fora do Cypress. - Config: bloco
azureDevOpsemcypress.env.json(local, fora do Git — vercypress.env.json.examplepro formato):"azureDevOps": { "organization": "group-software", "project": "PartnerBank", "pat": "SEU_PERSONAL_ACCESS_TOKEN_AQUI" } - Comandos npm:
npm run azure:ler -- <id>,azure:comentar -- <id> "texto",azure:criar -- <Tipo> "Título" "Descrição".
Autenticação (PAT) — cuidado real já encontrado
Usa Basic Auth (base64(':' + PAT)). Duas coisas que já morderam durante os testes:
- A organização restringe criação de PAT por allowlist (
Organization Settings → Policies → Restrict personal access token (PAT) creation) — nem todo usuário (mesmo Project Administrator) consegue gerar o próprio token sozinho. Precisa ser adicionado à "Allow list" por quem tem acesso a essa tela. - O PAT usado define de QUEM é a ação — todo comentário/criação aparece no Azure como tendo sido feito pela pessoa dona do token, não de quem rodou o script. Confirmado na prática: um teste usando um PAT específico gerou itens/comentários atribuídos à pessoa dona daquele token, não a quem executou o comando.
O PAT nunca é colado em chat/memória — mesma regra de totpSecret/apiKey do Postman neste
projeto.
As 4 funções
lerWorkItem(id) — leitura, sempre segura
Devolve título, tipo, estado, área, sprint, responsável e descrição de um item real. Não muda nada no Azure.
comentarWorkItem(id, texto) — publica, só com confirmação
Posta um comentário. Achado importante: a API do Azure DevOps grava o comentário como
format: "html" sempre — ela não converte markdown (**negrito**) sozinha. Quando alguém
digita direto na caixa de comentário do site, é o navegador que converte antes de mandar pra
API. Mandar **texto** cru pela API faz aparecer literal (**texto**), sem negrito, e quebras de
linha simples (\n) colapsam num parágrafo só (HTML ignora \n solto).
formatarComentarioEstruturado({ ... }) — o modelo padrão do time
Monta um comentário já em HTML de verdade, no formato usado pelo time (visto num comentário real do Leonardo): Motivo do retorno / Comportamento esperado / Comportamento encontrado / Passos para reproduzir / Exemplo. Usar esta função em vez de montar a string na mão.
criarWorkItem(tipo, titulo, descricao, camposExtras, opcoes) — publica, só com confirmação
Cria um item novo. tipo precisa ser um dos tipos reais do projeto — confirmado por consulta
direta à API (GET .../_apis/wit/workitemtypes): Bug, Task, User Story, Validation,
Epic, Feature, entre outros. descricao tem a mesma pegadinha de HTML do comentário.
camposExtras aceita qualquer campo (System.IterationPath, System.Tags, etc.).
opcoes.paiId cria já vinculado como filho de um item existente.
Sinalização de origem (decisão do usuário, 03/09/2026): todo item criado por este script leva
(Cypress) no final do título, sempre — automático, sem precisar pedir a cada vez. Ex.: título
"Criação de story automática pelo cypress" vira "Criação de story automática pelo cypress
(Cypress)". Objetivo: qualquer pessoa olhando o board consegue distinguir de longe o que veio
dessa automação do que foi criado manualmente.
⚠️ Cuidado de hierarquia, achado na prática: o Taskboard do Sprint só renderiza bem 2 níveis (item de backlog — User Story/Bug — na linha de cima, Task como card embaixo). Criar um Bug como filho de uma Task (3º nível) faz a Task sumir da visualização do Taskboard — o vínculo continua correto nos dados (confirmado via API), só a tela não sabe desenhar 3 níveis. Preferir Bug como irmão da User Story (os dois filhos diretos da mesma Story/Feature), não filho da Task.
trocarPai(id, novoPaiId) — publica, só com confirmação
Corrige o pai de um item já criado — remove a relação de hierarquia atual (se tiver) e aponta pra um novo pai. Usado justamente pra corrigir o caso acima (Bug filho de Task → Bug filho de Story).
Fluxo de teste real, ponta a ponta (02/09/2026)
Usando a Task real 25706 ("Não permitir a geração de boletos para conta matriz (administradora)", Sprint 28) como base:
lerWorkItem(25706)— leu título/descrição/estado reais.- Avaliação (manual, eu lendo a descrição): bati com o bug já rastreado em
cypress/e2e/casos_de_teste/boletoRegressao.cy.js(path atual — em 02/09/2026, antes da reformulação de 09/09/2026, esse spec morava emregressao/) — "vermelho de propósito" até o produto corrigir. - Rodei
boletoRegressao.cy.jsde verdade contra homologação: 7 passando, 1 falhando — o cenário do próprio bug ainda falha (API ainda aceita GUID de Administradora, deveria rejeitar). Ou seja: mesmo a Task estando em estado "Testing", a correção não está efetiva em homolog. comentarWorkItem(25706, ...)— postou esse resultado real na Task (formato antigo, semformatarComentarioEstruturado— já corrigido pras próximas vezes).- Depois, cadeia de teste isolada pra validar criação + vínculo, sem misturar com a 25706:
criarWorkItem('User Story', ...)→ 26922,criarWorkItem('Task', ..., { paiId: 26922 })→ 26923,criarWorkItem('Bug', ..., { paiId: 26923 })→ 26924, depoistrocarPai(26924, 26922)pra corrigir a hierarquia (ver aviso do Taskboard acima). Hierarquia final confirmada via API:26922 → { 26923, 26924 }(Task e Bug como irmãos).
O que falta (de propósito, ainda não construído)
- Nenhum gatilho automático — nada no Cypress chama esse script sozinho hoje. Toda leitura, comentário e criação até agora foi disparada manualmente, com conteúdo real e confirmação explícita a cada publicação.
- A camada de "julgamento" (decidir sozinho se uma falha de teste é um bug novo de verdade ou
ruído já conhecido — flakiness de login,
casos_de_teste/vermelho de propósito, token expirado) não existe. Rastreado desde antes disso emdocs/triagem-de-falhas.mdcomo "modo agendado", ainda não implementado. Precisa de um agente (não script determinístico) — cogitado usar o mecanismo de/scheduledo Claude Code pra isso, discussão adiada até essa base (a "cola") estar mais madura. - Mapear qual spec Cypress corresponde a qual item do Azure — hoje as Tasks não têm nenhuma
tag/campo indicando módulo (confirmado: campo
Tagsvazio nos itens testados). O projeto já resolve um problema parecido pro GitLab via labelmodulo:<nome>(verscripts/specs-afetados.js) — reaproveitável se o time adotar a mesma convenção nas Tags do Azure.