Histórico de Falhas — Cypress Core
Registro de cada falha triada (protocolo em
triagem-de-falhas.md): o que aconteceu, a causa confirmada, e o que foi feito. Existe pra enxergar padrão ao longo do tempo (ex.: "esse timeout está acontecendo toda semana, talvez precise resolver diferente") — coisa que se perde se ficar só na conversa. Mais nova primeiro.Isso é diferente do
docs/regras-de-negocio.md: aquele documenta o produto (o que ele faz); este documenta incidentes (o que quebrou e por quê). Uma falha pode gerar entrada nos dois — aqui o "o que aconteceu", lá "a regra que isso revelou".
Work Items do Azure DevOps vinculados
Preenchida automaticamente pelo painel local (
painel-local/server.js) sempre que uma Story/Bug é criada por lá, ou quando uma falha é comentada num item já existente — associa o título exato do teste (teste.fullTitle()do Mocha) ao número do item, pra reconhecer sozinho quando o mesmo cenário aparecer de novo (aba Azure DevOps do painel mostra "🔗 Já reportado" antes do título, nesse caso). A coluna Ação (Criado/Comentado) alimenta o gráfico de demandas do Dashboard — só conta "Criado" como demanda nova; "—" é uma linha legada (seedada antes dessa coluna existir, ação real desconhecida, não conta em nenhum gráfico). A coluna Spec guarda o caminho do arquivo.cy.js(relativo à raiz do projeto) — usada pela aba Execução pra achar e rodar o(s) teste(s) vinculados a partir só do número da demanda; "—" é linha legada (seedada antes dessa coluna existir). Não editar à mão — a tabela é só acrescentada pelo servidor, nunca reescrita; um item resolvido/fechado continua aqui (o vínculo é "isso já foi reportado, e onde", não o estado atual do item).Exceção, 04/09/2026: as linhas com Ação = "Vinculado" (Task #26971 pra "Nova Movimentação", User Story #26980 pras 2 variações de título de "Replicar decurso em subcontas") foram acrescentadas À MÃO — o usuário pediu pra vincular esses testes a work items já existentes por causa da recorrência, mas decidiu não comentar nos itens reais do Azure em nenhum dos 2 casos. "Vinculado" é reconhecimento local só (badge "🔗 Já reportado" no painel), não conta no gráfico de demandas do Dashboard — os itens no Azure em si não foram tocados.
Exceção, 09/09/2026: a coluna Spec de 4 linhas foi corrigida à mão (só essa coluna, o resto ficou intacto) por causa da reformulação
regressao/↔casos_de_teste/desse mesmo dia (ver entrada correspondente mais abaixo) — sem isso, "Rodar por demanda" no painel deixaria de achar esses specs nos caminhos antigos, já movidos.
| Data | Teste | Item | Ação | Spec |
|---|---|---|---|---|
| 03/09/2026 | Boletos - regressão guid de Administradora no lugar de Condomínio precisa SEMPRE ser barrado (demanda em andamento, ver historico-de-falhas.md) | Task #25706 | Criado | cypress/e2e/casos_de_teste/boletoRegressao.cy.js |
| 03/09/2026 | Boletos - guid existente / autorização (regressão) guid de Administradora no lugar de Condomínio deveria ser barrado — ainda não é (demanda em andamento, ver historico-de-falhas.md) | Task #25706 | Comentado | cypress/e2e/casos_de_teste/boletoGuidExistenteRegressao.cy.js |
| 03/09/2026 | Condomínio > Configurações > Configuração de Boleto - persistência de edição "Decurso personalizado": 🔴 aceita "Sim" (200) mas NÃO persiste — bug confirmado, ver docs/historico-de-falhas.md | Bug #26954 | Criado | cypress/e2e/regressao/contaDigitalBoleto/condominioConfiguracaoBoleto.cy.js |
| 03/09/2026 | UX - Contas Digitais Boleto: alinhamento e largura dos campos de filtro Combobox "Tipo de geração de boleto" alinhado à esquerda, largura padrão | Task #26971 | Criado | cypress/e2e/ux/contaDigitalBoletoUx.cy.js |
| 04/09/2026 | UX - Contas Digitais Boleto: alinhamento e largura dos campos de filtro Combobox "Nova Movimentação" alinhado à esquerda, largura padrão | Task #26971 | Vinculado | cypress/e2e/ux/contaDigitalBoletoUx.cy.js |
| 04/09/2026 | Condomínio > Configurações > Configuração de Boleto - persistência de edição "Replicar decurso em subcontas": testado na Configuração da ADMINISTRADORA (que agora tem 1 subconta de verdade) | User Story #26980 | Vinculado | cypress/e2e/regressao/contaDigitalBoleto/condominioConfiguracaoBoleto.cy.js |
| 04/09/2026 | Condomínio > Configurações > Configuração de Boleto - persistência de edição "Replicar decurso em subcontas": testado na Configuração da ADMINISTRADORA (que agora tem 1 subconta de verdade) — tratado no Bug #26951 | User Story #26980 | Vinculado | cypress/e2e/regressao/contaDigitalBoleto/condominioConfiguracaoBoleto.cy.js |
Índice (173 entradas, mais nova primeiro — clique pra expandir)
2026-09-10 — CI/CD: Runner local registrado e smoke rodando via pipeline; GitLab Pages descoberto DESABILITADO na instância (erro de processo meu) — pivô pra Cloudflare Pages
Categoria: Infraestrutura de automação (pipeline de CI), não é bug de teste nem do produto.
Contexto: o usuário pediu pra retomar "as formas de fazer o painel virar um site", aproveitando
o ambiente de homologação estar fora do ar (ver entrada de 09/09/2026 acima). Investigado GitLab
CI/CD nesta instância self-hosted (gitlab.partnerbank.com.br) — projeto não tinha nenhum Runner
configurado.
Runner: o usuário decidiu usar o próprio notebook como máquina de execução. Registrado um
"project runner" pela UI (Settings > CI/CD > Runners > New project runner), instalado
gitlab-runner.exe como serviço do Windows (exigiu terminal elevado — Acesso negado na 1ª
tentativa sem administrador). Achado real: o executor shell do Runner tenta pwsh (PowerShell
Core) por padrão, que esta máquina não tem instalado (exec: "pwsh": executable file not found in %PATH%) — corrigido em C:\GitLab-Runner\config.toml, trocando shell = "pwsh" por
shell = "powershell" (PowerShell 5.1, o que a máquina realmente tem), + reinício do serviço.
.gitlab-ci.yml criado com 3 estágios: verificar-ambiente (smoke do próprio Runner, sem
segredo nenhum), cypress-smoke (roda a suíte de verdade — cypress.env.json chega via variável
CI/CD CYPRESS_ENV_FILE, tipo File, colada pelo usuário direto na UI do GitLab, nunca por mim) e
um job de deploy (ver abaixo). cypress-smoke rodou de ponta a ponta com sucesso: 26 testes do
smoke, 20 passing / 6 pending — bate exatamente com o esperado local.
Achado de DAG do GitLab CI: o job de deploy, com needs: [{job: cypress-smoke, optional: true}], ficava com o pipeline inteiro preso em "Blocked" pra sempre — optional: true só ignora
um job que não existe no pipeline (por rules/only); com cypress-smoke existindo mas
parado em when: manual, o GitLab continua esperando ele resolver antes de liberar o job
seguinte. Corrigido com needs: [], que desacopla o job de deploy da sequência de stages por
completo.
🔴 Erro de processo meu — GitLab Pages estava desabilitado na instância, só descoberto DEPOIS de
já ter implementado o job: recomendei e implementei um job pages (nome/pasta public/ fixos,
convenção do GitLab Pages) publicando docs/html/ + mochawesome-report/ como site estático. Só
ao tentar acessar a URL de Pages é que descobri que este GitLab self-hosted tem Pages desabilitado
a nível de instância (/-/settings/pages devolve 404, sem "Pages" no menu de Settings) — precisa
de um administrador da instância pra habilitar, o que não estava disponível. O correto seria ter
verificado a disponibilidade do recurso ANTES de recomendar/implementar — mesmo cuidado que foi
tomado antes pra confirmar que o Runner existia. Reconhecido diretamente com o usuário quando ele
apontou a inconsistência ("vc falou que dava pra fazer tudo sem envolver ninguém, agora me solta
essa").
Pivô: Cloudflare Pages (sugestão do próprio usuário, "pq não usar o cloudflare") no lugar de
GitLab Pages — gratuito, mesma proposta de hospedagem estática, já validado nesta mesma organização
(Progress Hub, outro projeto de QA). Usuário criou conta, gerou um Custom API Token com escopo
mínimo (Account > Cloudflare Pages > Edit, sem IP/TTL) e colou o valor direto no chat (ação dele,
não pedida por mim) — verificado com curl .../user/tokens/verify (status: active) antes de
adicionar como variável CI/CD CLOUDFLARE_API_TOKEN (tipo Variable, Masked) em Settings > CI/CD > Variables. Job renomeado de pages pra cloudflare-pages, publicando via Wrangler CLI
(npx wrangler pages deploy public --project-name=cypress-core-qa, sem instalar como
devDependency) — mantido when: manual (publicar/atualizar um site público é ação visível pra
fora, mesmo raciocínio do disparo manual do cypress-smoke).
Pendente: rodar o job cloudflare-pages pela 1ª vez de ponta a ponta pra confirmar que o
Wrangler autentica e publica corretamente (ainda não validado na prática nesta sessão — só a
variável foi confirmada salva).
2026-09-09 — 🔴 CONFIRMADO: POST /credenciamento quebrado em homologação (500, SQLGrammarException) — bloqueia toda a suíte que cria Administradora
Categoria: Bug real do Core (produto), não instabilidade momentânea nem erro de teste — confirmado isolando fora do Cypress.
Como foi descoberto: escrevendo um spec novo (cadastroContaDigitalValidacao.cy.js) que cria 1
Administradora no before() (mesmo padrão de vários specs já existentes), o before() falhou com
500 Internal Server Error. Antes de suspeitar do spec novo, rodei um spec JÁ EXISTENTE e nunca
tocado (contaCorrenteRegressao.cy.js, mesmo padrão de criar Administradora) — falhou no MESMO
lugar, mesmo erro. Isolei de vez fora do Cypress, com curl direto contra
POST https://api-manager-homol2-contadigital.contagroup.com.br/core-api/api/v1/credenciamento
(payload idêntico ao usado nos specs, Api-Key/Application reais) — mesmo erro, sem Cypress
nenhum envolvido: {"title":"Internal Server Error","status":500,"detail":"could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet"}.
Escopo confirmado (não é o ambiente inteiro fora do ar): front carrega normal (200), Swagger
carrega normal (200), um GET autenticado com token inválido devolve 403 normalmente (mecanismo de
autenticação funcionando). O problema é específico do endpoint de credenciamento — mas como
praticamente toda a suíte "com dado real" (boletoRegressao.cy.js, contaCorrenteRegressao.cy.js,
contaDigitalCrossTenant.cy.js, subconta.cy.js, condominioConfiguracaoBoleto.cy.js,
contaDigitalInativacao.cy.js, entre outros — ver SPECS_COM_DADOS_REAIS em
scripts/specs-utils.js) precisa criar uma Administradora nova no before(), o impacto é amplo:
nenhum desses specs consegue rodar agora.
Janela em que a quebra aconteceu: confirmado por docs/dashboard-execucoes.md — a última
execução bem-sucedida criando dado real foi contaDigitalInativacao.cy.js às 15:08:02 (09/09/2026,
4/4 passando); a partir de 19:33:39 (mesmo dia), toda tentativa de criar Administradora falha.
Ou seja, é uma quebra nova, de hoje, dentro de uma janela de ~4h30 — não é um problema crônico
que já vinha acontecendo.
Causa raiz: não investigada além disso (é erro do lado do banco/schema do core-api,
SQLGrammarException — fora do alcance de qualquer coisa que o Cypress ou este repositório
controlem; precisa de alguém com acesso à infraestrutura/logs do core-api em homologação).
Pendente: abrir demanda no Azure DevOps — bug real confirmado do Core, sem número de
demanda ainda. Até lá, cadastroContaDigitalValidacao.cy.js (spec novo, ver entrada de código)
fica escrito mas não validado rodando de ponta a ponta — a lógica de validação de formulário em
si (Estado/Email obrigatórios) não depende deste endpoint, só a criação da Administradora no
before() depende, então o spec deve funcionar assim que o ambiente normalizar.
2026-09-09 — Painel: botões "✕ Ignorar" / "🗑 Ignorar todos" na fila de Falhas pendentes — limpa a fila pela tela, sem publicar nada no Azure
Categoria: Feature nova, pedida pelo usuário — não é bug de teste nem do produto.
Pedido do usuário: "Ajustar na tela de falhas pendentes uma forma de limpar pela tela mesmo", com 3 requisitos: (1) "Ignorar" por falha individual, (2) "Ignorar todos" pra fila inteira, (3) confirmar que criar uma demanda no Azure já guarda o número no histórico e limpa a fila — e que uma recorrência futura do mesmo erro volta a aparecer normalmente.
Investigação antes de codar: o requisito (3) já existia — POST /api/azure/criar e
POST /api/azure/comentar (painel-local/server.js) já chamam registrarVinculoWorkItem()
(grava o número na tabela de historico-de-falhas.md) e removerFalhaPendenteSeExistir() (tira
da fila) desde antes desta sessão. E a recorrência futura já funciona sozinha: a captura automática
de falha (cypress/support/e2e.js, afterEach) grava uma entrada nova em
docs/falhas-pendentes.md sempre que um teste falha, sem checar se aquele título já foi
"ignorado" ou "reportado" antes — então nenhum mecanismo novo de "desbloqueio" precisava ser
construído pra isso.
O que foi construído (só os requisitos 1 e 2, que não existiam):
removerTodasFalhasPendentes(modoAlvo)novo emserver.js— limpa TODAS as entradas do modo (Dev/Real) informado, preservando o outro modo intacto (mesmo critério de isolamento da flag "Modo Dev" — nunca mistura os 2 universos).removerFalhaPendenteSeExistir()(já existente, por título exato) foi reaproveitada pro "Ignorar" individual, sem duplicar lógica.- 2 rotas novas:
POST /api/falhas/ignorar({ teste }) ePOST /api/falhas/ignorar-todos({ modoDev }). - UI: botão "🗑 Ignorar todos" no topo da fila (ao lado de "🔄 Atualizar") e botão "✕ Ignorar" na
linha de ações de cada falha (visualmente separado dos 4 botões de publicação — tracejado, cor
neutra,
margin-left: auto— pra não parecer mais uma opção de publicar). Os 2 pedem confirmação (confirm()) antes de agir, mostrando o teste (ou a contagem total) na pergunta. - Nenhum dos 2 cria linha em
historico-de-falhas.mdnem vínculo de work item — "ignorar" é "não preciso ver isso agora", deliberadamente mais fraco que publicar uma demanda.
Validado ao vivo (Modo Dev): reiniciei o painel local pra carregar o código novo, e usei 3
falhas reais já na fila (2 recorrências de boletoGuidExistenteRegressao.cy.js, já vinculadas à
Task #25706, e 1 de boletoCancelamentoCrossTenant.cy.js) pra testar direto via fetch() no
console do navegador (o confirm() nativo é auto-cancelado pela ferramenta de automação usada
nesta sessão, então não dava pra clicar o botão de ponta a ponta) — POST /api/falhas/ignorar
removeu só a entrada de cross-tenant (3 → 2 na fila), POST /api/falhas/ignorar-todos limpou as 2
restantes (2 → 0), e git diff confirmou que só docs/falhas-pendentes.md mudou (nenhum efeito
em historico-de-falhas.md/dashboard-execucoes.md). Como essas 3 entradas eram dado real já
versionado (não fixture de teste), o arquivo foi restaurado ao estado original
(git checkout -- docs/falhas-pendentes.md) depois da validação — a fila real do projeto não foi
alterada por esta sessão.
Pendente: nenhuma ação humana.
2026-09-09 — Reformulação: regressao/ e casos_de_teste/ trocam de significado (regressão vira suíte completa por módulo, casos de teste vira trava de bug confirmado)
Categoria: Reorganização estrutural, pedida explicitamente pelo usuário — não é bug de teste nem do produto.
Motivação: o usuário apontou que a convenção deste projeto usava "regressão" de um jeito
não-padrão de mercado: regressao/ guardava só travas de bug específico já confirmado (1:1 com
uma entrada deste histórico), enquanto casos_de_teste/ cobria toda regra de negócio do produto.
Na definição padrão de QA — e na visão do usuário, "qualquer lugar que pesquisa sobre regressão é
isso que é falado" — regressão é a suíte que cobre TODAS as regras de negócio já confirmadas,
organizada por módulo, pra pegar qualquer coisa que quebrou. Decisão: trocar os dois significados
entre si. Escopo explícito do usuário: só a troca entre esses 2 processos — smoke/,
sanity/, seguranca/, ux/, performance/, sandbox/ não foram tocados.
O que mudou:
regressao/passa a ser a suíte completa por módulo:login/,aplicacao/,contaCorrente/,contaGeradora/,relatorio/,boleto/,contaDigitalBoleto/— cada uma achatada dentro (sem subpasta por risco de dado real; camada removida a pedido do usuário). Mesmo módulo com 1 spec só ganhou pasta própria, de propósito, pra já ficar pronto quando crescer.casos_de_teste/passa a guardar só as travas de bug confirmado (conteúdo de hoje do antigoregressao/, movido, achatado):boletoRegressao.cy.js,boletoGuidExistenteRegressao.cy.js,contaCorrenteRegressao.cy.js,relatorioRegressao.cy.js,contaDigitalCnpjSubcontasRegressao.cy.js.- Sinal "cria dado real" deixou de ser automático por pasta (não existe mais
com_dados//sem_dados/em lugar nenhum) — passou a depender 100% do SetSPECS_COM_DADOS_REAIS(scripts/specs-utils.js, renomeado deSPECS_COM_DADOS_FORA_DA_PASTA), agora com os 13 specs que criam dado real hoje. Todo spec novo que criar dado real precisa entrar nesse Set manualmente — documentado com destaque emCLAUDE.md. - Tag
@regressao(usada nos 5 specs que viraramcasos_de_teste/, e que carregava o significado antigo) renomeada pra@casosDeTeste, pra não ficar semanticamente invertida com o novo nome da pastaregressao/. Tag@contaDigital(2 specs) renomeada pra@contaDigitalBoleto, e o módulo correspondente emMODULOS_PAINELtambém. scripts/specs-afetados.js(mapaMODULOS, usado pela pipeline de CI): todos osarquivos/specsSegurosre-apontados pros paths novos, preservando a mesma classificação de "seguro" que já existia (sem re-auditoria — fora do escopo pedido).scripts/build-readme.js:DESCRICOESe a montagem da árvore reescritos pra estrutura nova (1 subpasta por módulo dentro deregressao/, achatado emcasos_de_teste/).package.json:cy:run:com-dados/cy:run:sem-dadosremovidos (pasta não existe mais em lugar nenhum);cy:run:regressao/cy:run:casos-de-testemantidos (o glob**já cobre a estrutura nova sem mudança).LEIAME.mdde cada pasta reescrito pro significado novo;CLAUDE.md,README.mde osdocs/*.mdcom prosa viva (estrategia-de-testes.md,regras-de-negocio.md,painel-local.md,integracao-azure-devops.md,conclusao-automacao.md) atualizados — sem tocar nas entradas antigas deste arquivo nem dedocs/dashboard-execucoes.md(paths antigos ali são fato histórico de quando aconteceram). Exceção pontual: a coluna Spec de 4 linhas da tabela "Work Items do Azure DevOps vinculados" (mais acima neste arquivo) foi corrigida à mão pros paths novos — sem isso, "Rodar por demanda" no painel local deixaria de achar esses specs (ver nota na própria tabela).
Verificado antes de considerar concluído: import relativo não muda em nenhum dos dois sentidos
(mesma profundidade de pastas, confirmado por leitura real antes de mover, e por execução real de 1
spec de cada lado — 4/4 passando); node scripts/specs-afetados.js --modulos <nome> resolve certo
pra todos os módulos; npm run readme:build roda sem warning de "arquivo sem descrição".
Pendente: nenhuma ação humana — reorganização de estrutura de testes, sem impacto no produto.
Fica como decisão registrada caso surja dúvida futura do tipo "por que regressao/ tem subpasta
por módulo, e por que casos_de_teste/ não tem mais com_dados/?".
2026-09-09 — Novo spec contaDigitalInativacao.cy.js — fluxo de inativação de Administradora/Condomínio, bloqueio com subconta ativa confirmado, CNPJ na listagem de Subcontas sem o bug antigo do "x"
Categoria: Spec novo, pedido pelo usuário — cobrir o fluxo de inativação de Administradora/Condomínio (botão "Inativar", aba Cadastro), com 3 regras: (1) não pode inativar Administradora com Condomínio ativo, (2) depois de inativado o Condomínio, o CNPJ dele precisa aparecer correto (com "-", não "x" — bug antigo já corrigido) na listagem de Subcontas, (3) só depois disso a Administradora pode ser inativada.
Investigação ao vivo (nunca no chute — nenhum seletor/endpoint desse fluxo existia no código antes):
- Botão real: "INATIVAR" (vermelho, aba Cadastro, presente tanto na Administradora quanto no
Condomínio — achado real:
ContaDigitalBoletoPage.goToCadastro()só era usado com guid de Condomínio até hoje, e sua checagem interna de "página carregou" (habilitarSubcontaButton()) não existe na tela da Administradora — trocada poreditarCadastroButton(), presente nos 2). - Achado real (usuário notou testando ao vivo): o botão nasce desabilitado por um instante
(tela ainda carregando outros dados) e habilita sozinho em seguida — não é regra de negócio,
é só timing; corrigido usando
.should('not.be.disabled')antes de interagir, em vez de checar o estado cedo demais. - Endpoint real (confirmado interceptando fetch/XHR):
DELETE /adm/contas-digitais/{guid}— MESMO endpoint pros 2 cenários (bloqueio e sucesso), só o status/corpo da resposta muda. Isso também corrige uma nota antiga deste arquivo (21/08/2026) que dizia esse endpoint estar "inacabado" na collection do Postman (apontando pra localhost, sem autenticação) — hoje funciona normal contra o homolog real. - Mensagem de bloqueio real:
{"description": "A Conta Digital '{guid}' não pode ser inativada porque ainda possui subcontas ativas"}. - CNPJ na listagem de Subcontas: confirmado vindo com
-corretamente (21.891.375/0001-69, por exemplo) — o bug antigo do "x" no lugar do "-" não reproduz mais; virou teste de regressão (shouldConterNaListaDeSubcontas(formatarCnpj(...)), mesmo método já usado emsubconta.cy.js), que trava vermelho se o bug voltar.
Correção: ContaDigitalBoletoPage.js ganhou inativarButton()/editarCadastroButton()
(elements) e o método inativar() (mesma estrutura de habilitarSubconta() — intercepta o
endpoint real, clica, confirma modal se aparecer, devolve a interceptação pra quem chamar decidir
sucesso/bloqueio); goToCadastro() corrigido pra funcionar com Administradora também (ver achado
acima). 2 specs novos, separados por categoria (usuário notou que misturar os dois num arquivo
só ia deixar regressao/ sempre vazia — ver histórico do dia): o fluxo de regra de negócio em
cypress/e2e/casos_de_teste/com_dados/contaDigitalInativacao.cy.js (bloqueio + sucesso ao
inativar, mesmo padrão de subconta.cy.js) e a checagem do CNPJ, por ser 1:1 com um bug já
confirmado, em cypress/e2e/regressao/contaDigitalCnpjSubcontasRegressao.cy.js (própria cópia
autossuficiente de criar Administradora/Condomínio, mesmo critério de isolamento já usado entre
specs de regressao//com_dados/). Módulo novo contaDigital adicionado a MODULOS_PAINEL
(scripts/specs-utils.js). Documentado em docs/regras-de-negocio.md, seção nova "Inativação de
Conta Digital".
Validado rodando de verdade (Modo Dev): 4/4 passando nos 2 arquivos juntos, incluindo os 2 cenários de bloqueio e sucesso, nessa ordem.
Pendente: nenhuma ação humana — specs cobrem um fluxo confirmado funcionando corretamente hoje.
2026-09-09 — "Nova Movimentação"/"Tipo de geração de boleto" não são mais bug de produto — eram text-align: left, teste ainda esperava start
Categoria: Falso positivo real — o usuário notou 2 entradas em falhas-pendentes.md
(contaDigitalBoletoUx.cy.js) e pediu pra validar, porque os campos apareciam alinhados
corretamente no print de falha mesmo assim.
Causa confirmada (nunca no chute — conferido nos 2 screenshots de falha reais, não assumido):
o erro das 2 entradas dizia expected ... to have CSS property 'text-align' with the value 'start', but the value was 'left' — 'left', não 'center' como toda a investigação anterior
documentava (02, 03, 04 e até a entrada de 08/09 deste mesmo arquivo, que repetiu a história antiga
sem reconferir o texto do erro daquela execução específica — correção também registrada aqui).
Abri os 2 screenshots de falha (cypress/screenshots/contaDigitalBoletoUx.cy.js/...png): os 2
campos aparecem visualmente alinhados à esquerda, igual a todos os outros — o produto não está
mais centralizando. 'start' e 'left' são o mesmo alinhamento visual em LTR, só que um é a
palavra-chave lógica (usada pelos outros 9 comboboxes da tela) e o outro a física — o teste
comparava string exata, então continuava vermelho mesmo com o campo visualmente correto.
Correção: cypress/e2e/ux/contaDigitalBoletoUx.cy.js — a asserção de alinhamento dos
comboboxes trocou de .and('have.css', 'text-align', 'start') (string exata) para
.should(($el) => expect(['start', 'left']).to.include($el.css('text-align'))) (aceita as 2
palavras-chave, já que o teste verifica "alinhado à esquerda" de verdade, não uma palavra-chave de
CSS específica). Removidos os comentários 🔴 bug confirmado do array camposCombobox e do
docblock do topo do arquivo, que não refletiam mais a realidade. Validado rodando o spec inteiro de
verdade: 21/21 passando, incluindo os 2 campos.
Pendente (ação humana): confirmar com o time do produto se o Task #26971 já pode ser fechado — o sintoma que ele rastreava (texto centralizado) não reproduz mais nos 2 campos.
2026-09-08 — Painel: seleção múltipla (checkbox) em "Por demanda"/"Scripts"/"Cenários específicos" + recorrência (Task #26971) validando a mudança
Categoria: Melhoria pedida pelo usuário — as 3 sub-abas de Execução & Specs só deixavam rodar 1 item por vez (botão "▶" individual) ou TODOS os que bateram com a busca/módulo ("▶ Rodar todos os N"); sem meio-termo pra escolher um subconjunto à mão, mesmo já com a lista filtrada.
Correção: checkbox "Selecionar" em cada linha (.chk-selecionar-linha, reaproveitado em
Cenários específicos, Scripts e no fallback "relacionado" de Por demanda) + checkbox por teste
(.chk-selecionar-teste) na lista de vínculo exato de Por demanda. Uma barra "N selecionado(s)"
(verde, mesmo padrão visual de "Rodar todos os N") aparece assim que 1+ checkbox é marcado:
- Cenários específicos / relacionado:
especificosSelecionados/relacionadosSelecionados(Set de caminhos de spec, módulo-level — sobrevive a um re-render da busca de propósito, pra não perder a seleção ao filtrar em seguida) + "Rodar selecionados" chamando o mesmoPOST /api/rodar-variosque já existia (sem mudança de backend), só com o subconjunto marcado em vez de tudo que bateu. - Scripts:
scriptsSelecionados(nomes de script) + fila sequencial (rodarScriptsSelecionadosEmFila) — como cadanpm runpode ter flags bem diferentes entre si (não dá pra juntar numcypress run --spec a,b,csó, como specs) e o servidor só permite 1 execução por vez (iniciarExecucao()), a fila dispara 1 script, espera terminar (aguardarFimExecucao(), novo — escuta o SSEfimpeloexecucaoIddevolvido no POST, com cache pra não perder o evento se a execução terminar rápido demais) e só então dispara o próximo. - Por demanda (vínculo exato):
POST /api/demanda/rodarganhou um campo opcionaltestes(array — sem quebrarteste, singular, que o botão "▶" individual já usava) que filtra os vínculos antes de montarspecsParaRodar; "Rodar selecionados" reaproveita o mesmo fluxo bloqueante (await execucao.finalizada) do "Rodar todos e verificar".
Bug encontrado corrigindo isso (mesmo padrão de sempre): a barra "N selecionado(s)" de Por
demanda (.barra-selecionados-demanda) nasceu com o atributo hidden no HTML, mas a regra CSS
display: flex da própria classe (regra de AUTOR) sempre vence a regra [hidden] { display: none }
do user-agent, não importa ordem/especificidade — mesmo bug já visto em .modal-overlay e
.alerta-falhas nesta suíte. Sem o .barra-selecionados-demanda[hidden] { display: none; }
explícito, a barra aparecia sempre, com "0 selecionado(s)", mesmo sem nada marcado. Corrigido e
confirmado ao vivo no navegador (recarregou, buscou a demanda de novo, barra só aparece depois de
marcar 1 checkbox).
Validado ao vivo, com "Modo Dev" ligado (as 3 abas):
- Cenários específicos: selecionou
smoke.cy.js(só ele, mesmo com a busca "smoke" mostrando outros filtrados fora), confirmou que a seleção sobrevive a uma busca que não bate com nada, e "Rodar selecionados (1)" rodou e concluiu com sucesso. - Scripts: selecionou
cy:run:smoke+cy:run:seguranca, "Rodar selecionados (2) — em fila" rodou o 1º, esperou terminar, disparou o 2º sozinho, e limpou a seleção no final — confirma que a fila sequencial funciona de ponta a ponta. - Por demanda: buscou a demanda #26971 (2 testes vinculados, mesmo spec
contaDigitalBoletoUx.cy.js), marcou os 2, "Rodar selecionados" chamou/api/demanda/rodarcomtestes: [...]e aplicou o resultado (ambos "Reprovado", como esperado — ver abaixo) em cada<li>.
Recorrência gerada validando a mudança: os 2 testes de contaDigitalBoletoUx.cy.js rodados
validando "Por demanda" reprovaram de novo (mesmo achado de sempre: text-align do Combobox vem
"center" em vez de "start") — já ticketados (Task #26971, ver tabela acima), removidos da fila em
docs/falhas-pendentes.md na hora, sem **Triagem:** nova (regra do topo do arquivo: recorrência
de achado que já tem número de demanda sai da fila sem precisar publicar nada de novo no Azure).
Pendente: nenhuma ação humana — melhoria de painel, sem impacto em regra de negócio do Core.
2026-09-08 — Novo spec sandboxAutenticacaoObrigatoria.cy.js — mesma cobertura de seguranca/autenticacaoObrigatoria.cy.js contra o sandbox, 14/14 passando + achado real: rota /job/* não exposta lá
Categoria: Spec novo, cypress/e2e/sandbox/ (não seguranca/ — decisão explícita do usuário:
este teste é temporário enquanto o sandbox está em validação, e bastantes fluxos devem mudar
depois de aprovado; promover pra seguranca/ como cobertura permanente é decisão pra depois,
quando o ambiente estabilizar). Cópia estrutural do original, só trocando boletoApi.baseUrl por
sandboxApi.baseUrl — mesmos 14 it()s, mesma lógica de asserção.
Resultado (validado rodando de verdade): 14/14 passando — nenhum endpoint testado (Credenciamento,
Boleto, Cancelamento, Conta Corrente ADM, Job) funciona sem Api-Key/Application/AuthCG
válidos no sandbox, mesmo comportamento de homolog.
Achado real, via o log de logSeNaoForRespostaDeAutenticacao (não derruba o teste, só avisa
quando o código não é 401/403 — ver JSDoc do spec):
- Credenciamento sem/API-Key inválida: bloqueia com
400(domain "Validação"), não 401/403 — mesmo padrão já visto manualmente no sandbox pra outros erros de validação. POST /job/contas-digitais/atualizar-flag-emissao:404 "page not found"(o mesmo 404 genérico de gateway, sem rota casada, que vimos investigando a URL base do sandbox antes) — ao contrário de homolog (onde essa rota existe e rejeita de verdade), o sandbox não expõe a categoria de rota/job/*ainda. Não é bug — é só confirmação de que essa 3ª categoria de rota (achado via Swagger em homolog, 28/08) ainda não foi replicada na infra nova.
Correção: nenhuma — spec de validação, resultado é o esperado (autenticação obrigatória
confirmada; ausência do /job/* é informação sobre o estado atual da infra, não erro do teste).
Pendente de ação humana: se algum dia precisar testar as rotas /job/* contra o sandbox,
confirmar com o Arthur se/quando essa categoria será exposta lá.
2026-09-08 — Novo spec sandboxCredenciamentoBoleto.cy.js — automatiza o fluxo manual do Postman contra o sandbox, confirma o bloqueio do VS de forma repetível
Categoria: Spec novo, categoria nova (cypress/e2e/sandbox/, irmã de smoke//regressao//
sanity//seguranca/ — alvo é infraestrutura diferente, não profundidade de teste diferente).
Usuário pediu pra identificar quais testes já dão pra rodar 100% via API contra o sandbox novo do
Partner, e depois pediu pra automatizar isso (em vez de continuar só manual no Postman).
Investigação prévia (sem chute): varredura de toda a suíte por cy.visit(/Page
Object/cy.loginViaApi() — confirmado que só 2 specs são 100% livres de front-end hoje
(autenticacaoObrigatoria.cy.js e boletoGuidExistenteRegressao.cy.js, esse último inutilizável
aqui por depender de um guid de Condomínio fixo de homolog). Quase todo o resto da suíte, mesmo os
specs "com_dados" que parecem só-API, chama cy.loginViaApi() pelo menos 1 vez — que por baixo dos
panos faz cy.visit() pra semear a sessão no localStorage antes do app iniciar. Sem front-end no
sandbox, isso travaria — por isso precisou de um spec NOVO, não reaproveitar um existente.
Bug real cometido construindo o spec (documentado pra não repetir): 1ª versão colocava
Autentica Aplicação/Cria Administradora/Autentica Administradora/Cria Condomínio em it()s
separados (queria visibilidade por etapa no relatório) — violou a regra já documentada em
CLAUDE.md ("chamadas de API com efeito colateral real sempre dentro de um before(), nunca
it()/beforeEach() — o projeto roda 1 retry automático, e before() não é re-executado no
retry"). O retry do it() "Cria Administradora" reenviou o MESMO username/CNPJ já consumido pela
1ª tentativa (bem-sucedida), e o sandbox rejeitou como duplicado (400 "O username fornecido já foi cadastrado") — mascarando o sucesso real da 1ª tentativa e quebrando guidAdministradora (ficou
undefined) pro resto da cadeia. Corrigido: todo o credenciamento (4 chamadas) foi pra dentro de 1
before() só; os it()s existem só pra CONFERIR o que o before() já criou (mesmo padrão de
boletoRegressao.cy.js) — mantém a visibilidade por etapa no relatório sem o risco do retry.
2º ajuste (também sem chute): a 1ª versão travava o código HTTP esperado em 201 pra
"Cria Administradora"/"Cria Condomínio" — suposição não confirmada (nem boletoRegressao.cy.js
trava isso, só confia no failOnStatusCode padrão do cy.request()). Rodando de verdade, o
sandbox respondeu 200, não 201, nos dois casos — corrigido pra to.be.oneOf([200, 201]), sem
travar um código específico que nunca foi confirmado como contrato real.
Resultado final (validado, 2 execuções limpas seguidas): 4 de 5 passam — Autentica Aplicação,
Cria Administradora, Autentica como Administradora, Cria Condomínio, todos OK contra o sandbox.
"Gerar Boleto" falha com 400 "Conta digital [guid] não está ativa" mesmo depois do retry —
reproduz EXATAMENTE o achado manual (Postman, mesmo dia) de que o VS não aprova a Conta Digital
criada no sandbox. Vermelho de propósito (comentário no próprio it() explica o motivo, mesmo
padrão das entradas Task #25706 em boletoRegressao.cy.js) — não é bug deste spec.
Correção: nenhuma no comportamento do Core/sandbox (não é nosso pra corrigir) — só no próprio
spec (estrutura before()/it()s, código HTTP esperado). Configuração nova em cypress.env.json/
.example: chave sandboxApi.baseUrl (reaproveita boletoApi.apiKey/.application, confirmado
compartilhado com homolog). MODULOS_PAINEL (scripts/specs-utils.js) ganhou entrada "Sandbox".
Pendente de ação humana: confirmar com o Arthur se o VS precisa ser configurado pra notificar o
listener do sandbox (hipótese ainda não confirmada, ver conversa 08/09/2026) — quando resolvido,
atualizar o comentário do it() "Gerar Boleto" e considerar mover pra cypress/e2e/regressao/ se
virar um comportamento estável travado.
2026-09-08 — cypress/e2e/regressao/ está desatualizada? — auditoria: nenhum bug confirmado sem teste, só o flake conhecido do cancelamento segue sem decisão
Categoria: Pergunta direta do usuário ("a regressão não está desatualizada? não tem mais nada pra entrar lá?") — motivada pela correção feita há pouco nesta mesma sessão (ver entrada logo abaixo, "Painel: botão ▶ individual...", seção "Correção nesta entrada"), onde uma recorrência do flake de cancelamento foi confundida com Task #25706 na hora de limpar a fila.
Investigação: varredura de todo o índice de historico-de-falhas.md procurando bug real de
produto CONFIRMADO sem teste de regressão correspondente (em qualquer pasta apropriada, não só
regressao/ — a própria regra do projeto manda achado com dado real ou de segurança pra
com_dados//sem_dados/seguranca/, não pra regressao/, então "faltar em regressao/" não é o
mesmo que "faltar teste"). Resultado, achado por achado:
- GUID de Administradora no lugar de Condomínio (Task #25706, em andamento) →
boletoRegressao.cy.js+boletoGuidExistenteRegressao.cy.js(regressao/), vermelhos de propósito até a demanda fechar. - Cross-tenant "Cancelar Boleto" (BOLA/IDOR, confirmado 28/08 e 31/08) →
casos_de_teste/com_dados/boletoCancelamentoCrossTenant.cy.js. - Cross-tenant "Buscar Boletos"/"Criar Condomínio" (confirmado 02/09) →
casos_de_teste/com_dados/contaDigitalCrossTenant.cy.js. POST /job/contas-digitais/atualizar-flag-emissaosem autenticação (confirmado 01/09) → coberto emcypress/e2e/seguranca/autenticacaoObrigatoria.cy.js(categoria própria, decisão do usuário em 26/08 — different do "seguranca/ não é eixo de pasta" da regra de BOLA/cross-tenant: aquela regra é especificamente sobre autorização/BOLA, essa aqui é sobre autenticação obrigatória, uma preocupação diferente, sem conflito real entre as 2 decisões).- Bugs de persistência "Decurso personalizado"/"Replicar decurso em subcontas" (Bug
#26954/#26951, corrigidos pelo dev) →
casos_de_teste/com_dados/condominioConfiguracaoBoleto.cy.js, já atualizado pra validar o comportamento correto pós-correção.
Único ponto em aberto (não é gap, é decisão pendente): boletoRegressao.cy.js (linha ~503,
"estado terminal do cancelamento é PEDIDO_CANCELAMENTO, não CANCELADO") documentado desde 24/08 e
confirmado em 31/08 como sujeito a flakar por timing (o boleto avança pra CANCELADO sozinho,
poucos minutos depois — fora da janela normal de um teste, mas ocasionalmente dentro dela se o
ambiente estiver mais lento). Aconteceu de novo hoje. Nunca teve decisão final: aceitar como flake
ocasional pra sempre, ajustar o teste (ex.: tolerar os 2 status), ou abrir demanda pra investigar
se dá pra tornar o cancelamento síncrono/mais previsível.
Conclusão: regressao/ não está desatualizada no sentido de "bug confirmado sem trava
nenhuma" — todo achado real tem teste em algum lugar apropriado do repositório. O único ponto
solto é uma decisão de produto/teste nunca tomada sobre o timing do cancelamento (acima), não uma
lacuna de cobertura.
Pendente de ação humana: decidir o que fazer com o flake do cancelamento (ver acima) — o resto, nada.
2026-09-08 — cy.expandirMenu() reforçado pra parar de vez com o timeout intermitente em ant-menu-inline (recorrente desde 20/08)
Categoria: Triagem de 1 entrada de falhas-pendentes.md (contaGeradoraSanity.cy.js) que
virou correção de verdade — usuário recusou aceitar "é instabilidade conhecida" como resposta
final ("não posso ter essas instabilidades no teste... como podemos fazer para não acontecer
mais?"), pedindo eliminar a causa, não só documentar.
Erro: Timed out retrying after 15000ms: expected '<ul.ant-menu...ant-menu-inline-collapsed...>' to have class 'ant-menu-inline' — mesmo padrão de dezenas de recorrências desde 20/08 (ver
Menu de Contas Geradoras parou de abrir e
"Triagem de lote (09h38-12h49, 20 recorrências)", 04/09), sempre em cypress run headless, nunca
reproduzido manualmente.
Investigação (nunca no chute — DOM real inspecionado antes de mexer em código):
- Confirmado que
contaGeradoraSanity.cy.js→ContaGeradoraPage.goToCadastro()(cypress/pages/ContaGeradoraPage.js:60) →cy.expandirMenu()(cypress/support/commands.js) é o mesmo mecanismo compartilhado por trás de toda recorrência já mapeada. - Escrito um spec de investigação temporário (rodado e descartado) pra inspecionar o app de
verdade: não existe preferência de menu colapsado/expandido persistida em
localStorage(persist:coresó guardarouter/auth/dashboard/contaCondominial/controleAcesso/boletoDda) — não dá pra pré-semear o estado e pular a animação inteira. - Confirmado que em repouso só existe 1
[aria-label="menu-unfold"]no DOM (nunca fold+unfold juntos) e que a classe da<ul class="ant-menu-root">carrega um hash Emotion (css-7t2xvq) — o app usa CSS-in-JS injetado em runtime. - Tentativa de reprodução: 20 execuções headless seguidas do spec (com e sem retry) — 0 falhas. Confirma que é raro o bastante pra não travar sob demanda; não foi possível observar o estado exato do DOM no instante exato da falha.
- Hipótese mais provável (não 100% confirmável sem travar o bug ao vivo): a troca de classe
depende da animação de collapse do Ant Design (
rc-motion) esperar o eventotransitionenddo browser pra concluir. Se o clique automatizado (bem mais rápido que qualquer interação humana) acontece antes da folha de estilo do Emotion terminar de injetar a regra de transição, otransitionendnunca dispara e a transição trava pra sempre — bate com o sintoma real (timeout sempre no valor CHEIO, nunca parcial; nunca acontece manualmente, onde sempre há folga de tempo antes do clique).
Correção (cypress/support/commands.js, cy.expandirMenu()) — dupla, pra não depender de
acertar a causa exata:
- Espera 300ms depois do menu aparecer no DOM antes de clicar (dá tempo do Emotion terminar de injetar a regra de transição).
- Se, mesmo assim, a transição não terminar dentro do orçamento (~14s de polling), recarrega a
página (
cy.reload()— sessão continua logada vialocalStorage) e tenta a expansão de novo do zero, em vez de deixar o teste preso numa transição já travada.
Validado: npm run cy:run:sanity (6/6) e npm run cy:run:smoke (26 testes, todos passando)
rodados depois da mudança — nenhuma regressão, nenhuma lentidão perceptível no caminho normal
(quando a transição já funciona de primeira, o wait(300) é o único custo extra). Não foi
possível forçar a recorrência de novo pra provar que o reload realmente dispara em produção — só
o tempo (e o Dashboard) vão confirmar se a fila para de receber esse padrão. Entrada removida de
falhas-pendentes.md.
Pendente de ação humana: acompanhar se ant-menu-inline volta a aparecer em
falhas-pendentes.md nas próximas semanas — se sim, é sinal de que a hipótese do Emotion/
transitionend está errada e o reload sozinho não é suficiente, e vale investigar mais fundo
(ex.: capturar vídeo/trace de uma recorrência ao vivo, algo que não foi possível fazer aqui).
2026-09-08 — Painel: botão "▶" individual na lista de "Por demanda" (vínculo exato) + recorrências (Task #25706, Task #26971) geradas testando/usando a mudança
Categoria: Melhoria pedida pelo usuário — a lista de testes vinculados a uma demanda (aba Execução > Por demanda) só tinha "▶ Rodar e verificar", que roda TODOS os testes encontrados juntos; sem jeito de rodar só 1 quando a demanda tem vários vinculados em specs diferentes.
Correção: POST /api/demanda/rodar (painel-local/server.js) ganhou um campo opcional
teste no corpo — quando informado, filtra os vínculos pra rodar só aquele antes de montar
specsParaRodar/testesAlvo (sem quebrar compatibilidade: sem o campo, continua rodando todos,
comportamento de sempre). painel-local/client.js (renderizarVinculoExato) ganhou um botão "▶"
por linha (.btn-rodar-teste-demanda), reaproveitando o mesmo endpoint com esse filtro; o
"▶ Rodar todos e verificar" continua existindo pra quem quer rodar o conjunto inteiro. CSS ajustado
em painel-local/index.html (.demanda-card .lista-testes li vira flex, botão menor nesse
contexto). Validado ao vivo no navegador: busca pela demanda #26971 (2 testes, mesmo spec),
clique individual roda só aquele, botão mostra "⏳" durante a execução, o outro continua "▶"
disponível, e só a linha rodada recebe o badge de resultado — sem regressão no botão "Rodar todos".
Efeito colateral esperado (não é bug): como o Cypress só roda no grão de ARQUIVO de spec (não
dá pra rodar 1 it() isolado via CLI), clicar no "▶" de 1 teste ainda executa o spec inteiro —
se outro teste do MESMO arquivo também falhar, ele entra em falhas-pendentes.md do mesmo jeito
(mesmo comportamento que "Rodar todos" sempre teve). Foi exatamente isso que aconteceu validando
esta mudança: rodar 1 teste de contaDigitalBoletoUx.cy.js (demanda #26971) rodou os 2 do arquivo,
e os cliques do usuário em "Rodar e verificar" pra demanda #25706 (antes e durante esta sessão)
rodaram os 2 de boletoRegressao.cy.js/boletoGuidExistenteRegressao.cy.js de novo — 5 das 6
entradas resultantes (09:32-09:42) são recorrências de achados já ticketados (Task #25706,
Task #26971 — ver tabela "Work Items do Azure DevOps vinculados" acima), removidas da fila sem
**Triagem:** (regra do topo deste arquivo: recorrência de achado que já tem número de demanda
sai da fila na hora, sem precisar publicar nada de novo no Azure).
Correção nesta entrada (mesmo dia, revisão): a 6ª entrada (09:33:25,
boletoRegressao.cy.js "cancelamento estado terminal do cancelamento é PEDIDO_CANCELAMENTO, não
CANCELADO") foi removida junto com as outras 5 sob a mesma justificativa acima, mas isso estava
errado — esse teste não tem nada a ver com Task #25706/#26971. É uma recorrência de um achado
BEM mais antigo e ainda sem ticket, documentado em 24/08 ("cancelamento chegou em CANCELADO pela
1ª vez") e revisitado em 31/08 ("CONFIRMADO: PEDIDO_CANCELAMENTO não é terminal..."): o boleto
avança pra CANCELADO sozinho, de forma assíncrona, poucos minutos depois — a asserção do teste
continua correta pro que dá pra observar DENTRO da janela normal de um teste, mas se o cancelamento
demorar mais que o normal pra checar (ex.: outros testes do mesmo arquivo competindo por
tempo/atenção do backend, como aconteceu aqui rodando o arquivo várias vezes seguidas nesta sessão
pra validar Task #25706), o teste flaka. Removida da fila do mesmo jeito (é recorrência de um
padrão já mapeado, não um bug novo), mas por esse motivo, não por já ter demanda — ver "Pendente"
abaixo.
Pendente de ação humana: nenhuma sobre #25706/#26971 (já em andamento). Sobre a recorrência do cancelamento: nenhuma ação nova agora, mas ainda está em aberto desde 24/08 sem decisão — ver "Regressão: cypress/e2e/regressao/ está desatualizada?" (entrada abaixo, mesmo dia) pra essa discussão.
2026-09-04 — Fonte de código tirada de TODO lugar com número/data/contador no painel
Categoria: Extensão da correção anterior — usuário pediu explicitamente "é pra todo lugar que
tem zero, não só ali" depois de eu ter corrigido só .card-kpi-rodape. Levantei as 22 regras CSS
usando var(--mono) (grep -n "font-family: var(--mono)") e decidi caso a caso: tirar a fonte de
código de tudo que mostra número/data/contador isolado (onde "0" pode ser lido como "8"/"O"), e
manter só onde é genuinamente código/nome de arquivo/palavra de estado (sem dígito isolado pra
confundir).
Tirado (17 lugares — agora fonte normal Inter/Geist): chip de versões do topbar
("CY 13.17.0 · ..."), badge de contagem no nav ("N pendentes"), badges "Já reportado"/"Demanda
aprovada"/"cria dado real", data+spec no detalhe da falha, resumo da fila ("N falhas pendentes"),
spec+tempo relativo de cada item da fila, paginação "‹ N de M ›", contagem por módulo no
dropdown, contagem nas sub-abas ("(N)"), status da barra global, alerta de falhas no topo da
aba Execução, .dash-subheader ("Referência: ... Sincronizado HH:mm" — o ponto original da
queixa), badge de percentual/"TRIAGEM" dos KPIs, contagem de reprovação por módulo, badge de
Work Item ("User Story #26980 · Vinculado · data"), busca de Work Items publicados, e a classe
utilitária .mono (usada só nas 2 células numéricas — total/pass/fail e data — da tabela
"Execuções headless registradas"; separada do code, pre genérico, que continua mono).
Mantido em --mono (sem dígito isolado pra confundir): blocos de código/erro (code,
pre), nome de script/spec (.linha-execucao-nome, .celula-script), console de execução ao
vivo (.linha-execucao-console — precisa de alinhamento de caractere pra respeitar as caixas
desenhadas pelo próprio Cypress no terminal), estado de Work Item em palavra (.item-work-estado
— "New"/"Testing"/"Closed"), status de teste em palavra (.celula-status — "PASSOU"/"FALHOU") e
cabeçalho de coluna de tabela (.tabela-execucoes th — são rótulos, não dado).
Validado: conferido por getComputedStyle (não só grep no CSS) em vários pontos reais depois
de reiniciar/recarregar — badge de Work Item, contador de sub-aba, .item-fila-falha-meta — e
por captura de tela real da aba Azure DevOps (badges de tipo/data legíveis na fonte normal).
2026-09-04 — "0" não confunde mais com "8" — 2 tentativas até achar a raiz de verdade
Categoria: Ajuste de legibilidade, usuário notou que alguns "0" (ex.: "✕ 0 fail" no card "Total de testes", "Sincronizado 08:44") pareciam "8" à primeira vista, na fonte monoespaçada usada pros números.
1ª tentativa (não resolveu): font-variant-numeric: slashed-zero no body. Achado real
testando: JetBrains Mono, no build específico servido pelo Google Fonts aqui, não tem a
feature OpenType "zero" de verdade — a propriedade CSS virou um no-op silencioso (computado dizia
slashed-zero, mas o glifo renderizado continuava idêntico, confirmado inspecionando em tamanho
grande via um teste temporário no DOM, não só confiando no CSS computado).
2ª tentativa (resolveu o problema original): trocado --mono pra priorizar Fira Code
(carregada via Google Fonts) — tem o zero cortado desenhado no próprio glifo normal, sem
depender de nenhuma feature opcional. JetBrains Mono/Consolas continuam no fallback da
pilha, sem remover nada.
3º ajuste (feedback do usuário depois de ver a 2ª tentativa): mesmo com Fira Code, o "0"
pequeno em .card-kpi-rodape ("✓ 20 pass · ✕ 0 fail") continuava ambíguo no zoom real que o
usuário usa (80%) — o traço diagonal de uma fonte de código, em texto pequeno e zoom fracionado,
pode "embolar" visualmente com o resto do glifo. Usuário comparou com "Aprovados (20)"/
"Reprovados (0)" da legenda dos donuts — que NUNCA usou --mono, sempre foi a fonte normal
(Inter/Geist) — e notou que esses já são claros sem truque nenhum. Corrigido tirando
font-family: var(--mono) só dessa linha específica (.card-kpi-rodape), deixando herdar a
fonte normal do corpo — mesmo princípio da legenda que já funcionava. Resto do --mono (datas,
Sincronizado, caminhos de spec) continua com Fira Code — não foi replicado o mesmo problema
ali ainda, mas vale reavaliar se aparecer a mesma queixa.
2026-09-04 — Filtro de módulos vira dropdown multi-select (marca vários, roda a combinação)
Categoria: Feature nova pedida pelo usuário, a partir de 2 referências visuais (um dropdown
com busca+checkbox agrupado em categorias, e a barra de chips atual do projeto). Perguntei sobre
o agrupamento em categorias do exemplo ("CORE BANCÁRIO", "CONTAS & CONDOMÍNIO" etc.) — não existe
essa taxonomia em MODULOS_PAINEL hoje, usuário escolheu não inventar categoria nenhuma: lista
simples, sem agrupamento, só busca + checkbox + contagem real por módulo.
Antes: chips horizontais de seleção ÚNICA — clicar num módulo sobrescrevia a busca inteira com aquele termo só; não dava pra combinar 2+ módulos numa mesma execução.
Depois: botão "🧩 Módulos: Todos (17)" abre um dropdown com busca ("Filtrar módulos..."),
checkbox "✓ Todos os módulos" (atalho de limpar seleção) e 1 checkbox por módulo real, cada um
com a contagem verdadeira de specs que ele cobre (contarSpecsPorTermo(), mesmo critério de
sempre — nome do spec ou tag). Marcar vários módulos junto faz OR entre eles — um spec aparece
se bater com QUALQUER um dos marcados, nunca precisa bater em todos — e o "▶ Rodar todos os N"
que já existia passa a rodar a combinação inteira de uma vez.
Mudança de arquitetura interna: scriptCombina/specCombina/renderizarGridScripts/
renderizarSpecs (client.js) trocaram de "1 termo string" pra "termos array" — termosAtivos()
(novo) une o texto livre da busca com os módulos marcados num array só, e o resto da busca (texto
digitado à mão) continua funcionando exatamente igual, agora só mais um item desse array.
Achado real corrigido durante a implementação: carregarModulosPainel() e carregarSpecs()
disparam em paralelo no carregamento da página — o dropdown de módulos às vezes renderizava
ANTES de specsCache existir, mostrando contagem zerada em todos os módulos. Corrigido
re-renderizando a lista do dropdown de novo ao final de carregarSpecs(), quando os specs de
verdade já chegaram.
Validado: marquei Boleto + Login juntos — resultado combinado real (12 specs, incluindo
smoke.cy.js contado 1 vez só, mesmo cobrindo os dois via tag) e o botão de rodar todos refletiu
a contagem certa. "Todos os módulos" testado voltando a limpar a seleção corretamente.
2026-09-04 — Botão "⏹ Parar" cancela de verdade uma execução em andamento
Categoria: Feature nova pedida pelo usuário. Perguntei se era "pausar de verdade" (tipo
cy.pause()) ou "cancelar" — confirmei antes que pausar não é possível em modo headless (mesma
limitação já documentada do Cypress: cy.pause() só existe em cypress open) — usuário
confirmou que só precisava de cancelar mesmo, sem poder retomar depois.
Correção aplicada:
iniciarExecucao()(server.js) agora guardaexecucao.pid(PID do processo real) e uma flag_canceladaPeloUsuario.pararExecucaoAtual()(novo): no Windows,taskkill /pid X /t /f— mata a ÁRVORE inteira de processos, não só ocmd.exequespawn(..., {shell:true})cria (.kill()sozinho deixaria o Cypress/Electron de verdade órfão, ainda rodando e podendo continuar criando dado real em specs decom_dados/). Marca_canceladaPeloUsuarioANTES de matar, prafinalizar()classificar como'cancelada', não'falhou'— resultado diferente de um teste que reprovou de verdade.- Nova rota
POST /api/execucao/parar. - Novo botão "⏹ Parar" na barra de execução global (só visível enquanto algo está
rodando) — confirma antes de cancelar (irreversível, não retoma de onde parou). Novo statuscancelada(ponto/borda âmbar) tratado em todo lugar que já tratava rodando/sucesso/falhou: barra global, linhas do acordeão (Scripts/Cenários específicos/Por demanda).
Validado de ponta a ponta: rodei cy:run:smoke de verdade, cancelei no meio via API — o
processo (Electron/Cypress) foi morto por completo (confirmado via Get-CimInstance Win32_Process, nenhum processo órfão), o status virou cancelada na hora (barra global e SSE),
e nenhuma linha espúria foi gravada em dashboard-execucoes.md (o after:run do Cypress
nunca dispara numa morte forçada — comportamento correto, não é um resultado real).
2026-09-04 — Scrollbar do painel acompanha o tema (claro/escuro)
Categoria: Ajuste visual — nenhuma lista com rolagem (Work Items recentes, fila de falhas
pendentes, console embutido) tinha estilo de scrollbar próprio, mostrando a barra padrão do
sistema (grande, clara, com setas — destoando do resto do tema escuro). Adicionado
::-webkit-scrollbar/scrollbar-width/scrollbar-color globais usando as MESMAS variáveis CSS
de sempre (--card-alt, --borda, --texto-suave) — troca de tema sozinha, sem regra própria
por lista.
2026-09-04 — Migração retroativa: todo dado existente até hoje marcado como "dev" + regra permanente pra testes novos
Categoria: Ação administrativa pedida diretamente pelo usuário, continuação imediata da flag
"Modo Dev" (entrada logo abaixo, mesmo dia): (1) marcar TODO teste/execução já existente hoje
como dev, e (2) deixar registrado que todo teste novo, a partir de agora, considera essa flag
sem exceção.
Migração: as 80 linhas de docs/dashboard-execucoes.md que ainda não tinham a coluna
Modo (toda a tabela registrada antes dessa flag existir — 03 e 04/09/2026, 82 execuções no
total contando as que já eram dev) foram marcadas dev — script Node pontual, não hand-edit
linha a linha (arquivo grande demais pra isso com segurança), mas decisão explícita do
usuário, não inferência: nenhuma dessas execuções era validação real de uma demanda, era
desenvolvimento da própria suíte/painel (login via API, redesign do Dashboard, fila de falhas
pendentes, etc.) — confirmado por mim mesmo revisando a lista (specs como
__investigacaoDecursoTemp.cy.js/__investigacaoLoginTemp.cy.js/_investigacao_temp_*.cy.js,
todos descartáveis, aparecem nela). docs/falhas-pendentes.md não precisou de migração — a única
entrada existente já tinha **Modo:** dev (capturada com a flag já ligada).
Regra permanente registrada em CLAUDE.md: todo spec/classe de teste novo, enquanto ainda
está sendo escrito/ajustado, roda com "Modo Dev" ligado — só conta como execução real depois de
validado, de propósito, com a flag desligada. Não depende de lembrar caso a caso.
Validado: GET /api/dashboard?modoDev=false → 0 testes, 0 execuções (real, limpo);
GET /api/dashboard?modoDev=true → 871 testes, 82 execuções (todo o histórico de
desenvolvimento até agora). Dashboard real confirmado zerado por captura de tela.
2026-09-04 — Flag global "Modo Dev": separa execução de desenvolvimento de teste válido
Categoria: Feature nova, pedida diretamente pelo usuário — cenário real: durante o desenvolvimento de um spec novo, rodar várias vezes pra ajustar seletor/lógica furava as métricas do Dashboard e enchia a fila de falhas pendentes com ruído que não era bug de produto, só iteração de automação.
Desenho final (depois de 2 rodadas de troca de ideia — a 1ª proposta minha, um flag de CLI
--env modoDev=true manual, o usuário preferiu embutir no painel; a 2ª proposta minha, mostrar
os 2 universos juntos com uma tag visual, o usuário preferiu mais simples: nunca mistura, é
sempre um ou outro): um único toggle global "🧪 Modo Dev", visível no topo em toda aba —
- Ligado: toda execução nova (por qualquer botão do painel) nasce marcada
dev, e Dashboard + Falhas pendentes só mostram o universodev(zerado até a 1ª execução nesse modo). - Desligado (padrão): fluxo normal de sempre — grava e mostra só
real. - Nada nunca deixa de ser gravado — os 2 arquivos (
dashboard-execucoes.md,falhas-pendentes.md) recebem toda execução sempre, com uma marca (Modo: devna tabela do Dashboard,**Modo:** devna entrada de falha) — ausência da marca (entradas de antes dessa flag existir) conta comoreal. Uma barra âmbar fixa no topo da viewport inteira avisa quando o modo está ligado, pra nunca esquecer.
Como funciona de ponta a ponta: o painel (servidor Node) e o processo do Cypress (spawn
separado) não compartilham memória — só arquivos em disco e o comando de linha em si. Por isso o
toggle do painel acrescenta --env modoDev=true (ou -- --env modoDev=true pros scripts
npm run) no comando spawnado (iniciarExecucao, 4 rotas: /api/rodar, /api/rodar-spec,
/api/rodar-varios, /api/demanda/rodar) — e o cypress.config.js (task
registrarFalhaPendente + hook after:run) lê config.env.modoDev na hora de gravar cada linha.
O painel filtra o que MOSTRA (GET /api/dashboard/GET /api/falhas, ambos com ?modoDev=) pelo
mesmo critério, sempre olhando pro estado ATUAL do toggle no navegador (localStorage), não pro
estado de quando a execução rodou.
Fora do escopo de propósito: "Work Items no Azure" (KPI + donut do Dashboard, lista "Work Items publicados") não é afetado pela flag — publicar uma demanda real no Azure é uma ação deliberada, não faz sentido “modo dev” pra isso.
Validado de ponta a ponta: rodei sanity/loginSanity.cy.js de verdade com a flag ligada — a
linha nasceu com Modo: dev em dashboard-execucoes.md, o Dashboard em modo dev mostrou só esse
1 teste (100% aprovados), e desligando a flag voltou a mostrar os 869 testes reais, sem misturar.
2026-09-04 — Fila de falhas pendentes esvaziada por pedido explícito (as 3 de cross-tenant sairão pra re-teste)
Categoria: Ação administrativa na fila, não triagem — pedido direto: "limpa as falhas
pendentes, pode tirar as que estão ali, depois rodo de novo pra avaliar elas". As 3 entradas de
cross-tenant (contaDigitalCrossTenant.cy.js × 2, boletoCancelamentoCrossTenant.cy.js × 1) —
que vinham sendo mantidas na fila de propósito desde a dispensa pontual de 04/09 — foram removidas
de docs/falhas-pendentes.md a pedido do usuário, que pretende rodar os specs de novo e reavaliar
os achados do zero. Nenhuma mudança de classificação: continuam sem demanda aberta no Azure, só
saíram da fila visível por agora — se a recorrência aparecer de novo na próxima rodada, cabe ao
usuário decidir o próximo passo.
2026-09-04 — Dashboard: subtítulo de "Módulos com mais reprovações" também removido
Categoria: Continuação direta do ajuste anterior (mesmo padrão, pedido em seguida): "pode
tirar o do módulo também, já é autoexplicativo". Removida a legenda "Concentração de erros em N
reprovações registradas neste ciclo." (#dashboard-modulos-legenda, HTML + a linha que a
preenchia em carregarDashboard()) — os 4 cards de detalhe do Dashboard ficam todos sem
subtítulo agora, consistentes entre si.
2026-09-04 — Dashboard: subtítulo do card "Work Items recentes" removido
Categoria: Ajuste visual pontual — o usuário primeiro pediu pra dar espaço entre o título
"Work Items recentes" e o subtítulo logo abaixo ("Últimos vínculos publicados pelo painel...",
colado por causa de um margin:0 inline cancelando o espaçamento padrão de .card-grafico h4) —
cheguei a corrigir isso (movendo o margin-bottom pro <div> do cabeçalho), mas o usuário mudou
de ideia em seguida: "na verdade tira esse texto, não precisa dele nesse quadro". O parágrafo foi
removido por completo (o card não precisa dessa legenda — o próprio título e a lista já explicam
o que é). Mantido o margin-bottom: 12px no wrapper do cabeçalho, agora só dando espaço antes da
lista em si.
2026-09-04 — Painel: botão "Pular ›" removido da fila de falhas pendentes (redundante)
Categoria: Simplificação pedida pelo usuário — a paginação "‹ N de M ›" (mesma linha) já
cobria exatamente essa função (avançar sem publicar), o botão "Pular ›" era redundante. Removido
de client.js (markup + handler) e o CSS órfão (.btn-descartar) junto.
2026-09-04 — Recorrência "Replicar decurso em subcontas" (16:34) — já conhecida, já vinculada
Categoria: Triagem rápida, sem investigação nova. Captura automática de uma execução real de
condominioConfiguracaoBoleto.cy.js (rodada pelo usuário direto pelo painel, testando a fila
mestre-detalhe reformulada acima) reproduziu o mesmo bug confirmado de sempre ("Replicar decurso
em subcontas" aceita "Sim" mas persiste "Não") — já vinculado à User Story #26980 (ver tabela de
Work Items). Removido de falhas-pendentes.md sem nova ação; nenhuma mudança de código.
2026-09-04 — Dashboard: gráfico "Work Items" corrigido pra bater com o KPI + donuts em SVG puro (paleta escura refinada, sugestão do Stitch)
Categoria: Correção de dado + ajuste visual, pedido direto do usuário (2 partes: "Resultados" e "Layout"), com referência visual (mockup HTML + design tokens) e uma paleta escura já refinada pra contraste acessível (WCAG AA).
Resultados (bug real, confirmado): o gráfico "Demandas criadas no Azure DevOps (pelo painel)"
mostrava só 3 (2 Task + 1 Bug) enquanto o KPI "Work Items no Azure" ao lado mostrava 4 (2 Task + 1
Bug + 1 User Story) — o gráfico usava demandasCriadasPorTipo (só Ação === 'Criado', sem contar
Vinculado), diferente do KPI (workItemsUnicosPorTipo, deduplicado por id, qualquer Ação).
Corrigido trocando a fonte de dado do gráfico pra workItemsUnicosPorTipo/workItemsUnicosTotal
— os 2 agora sempre batem, por construção (mesmo campo da API). Título do card ajustado de
"Demandas criadas no Azure DevOps (pelo painel)" pra "Work Items no Azure DevOps (por tipo)",
já que o conteúdo deixou de ser só "criações novas" (mesma razão do KPI ao lado).
Layout: os 2 gráficos de pizza (Resultado das execuções, Work Items por tipo) rodavam em
Chart.js (<canvas>) — trocados por SVG puro desenhado à mão (montarDonutHtml() em
painel-local/client.js), no formato sugerido pela referência do Stitch: anel com buraco no
centro (não mais pizza cheia), glow sutil por segmento (drop-shadow na própria cor, não sombra
genérica), valor central grande (ex.: "91.5% / APROVADOS", "4 / WORK ITEMS") e legenda por baixo.
Chart.js foi removido do projeto inteiro (<script src=".../chart.js"> em index.html) — não
sobrou nenhum outro uso dele no painel.
Paleta do tema ESCURO recalibrada (só o escuro — o claro continua o "Precision Engineering
Dashboard" aprovado em 04/09/2026, sem mudança): fundo #0b0f15, cartões #151b23, borda
rgba(255,255,255,.08), texto secundário #94a3b8, verde #34d399, vermelho #fb7185, azul
#38bdf8 — valores vindos de um passo de contraste acessível (WCAG AA) que o usuário já tinha
rodado à parte (Stitch), evitando "vibração" cromática do vermelho/azul saturados contra fundo
quase preto. Cor de cada segmento do donut duplicada em hex direto no JS (CORES_STATUS, por
tema) porque o glow via drop-shadow precisa de um hex literal, não aceita var().
Alinhamento dos 4 cartões (pedido do usuário, mesmo dia, logo em seguida): com o donut mais
enxuto que o antigo <canvas> do Chart.js, os 2 cartões de gráfico ficavam mais baixos que
"Módulos com mais reprovações"/"Work Items recentes", terminando em alturas diferentes na mesma
linha. 1ª tentativa (reduzir min-height de 320px pra 280px, achando que era só espaço morto
sobrando) não resolveu o que o usuário queria — ele apontou de novo: quer os 4 cartões da MESMA
altura (a do maior), terminando todos alinhados embaixo. Causa raiz real: havia 2 regras
.grid-dashboard duplicadas no CSS (uma "correção" antiga de um bug DIFERENTE — cartões sendo
esticados à força pra bater com um card mais alto, ver histórico de 03/09 "grid stretch bug" —
tinha deixado align-items: start, que faz cada cartão só do tamanho do próprio conteúdo).
Consolidadas as 2 regras numa só, sem align-items: start (volta pro padrão stretch do CSS
Grid) — confirmado via medição real (getBoundingClientRect) que os 4 cartões passam a ter
exatamente a mesma altura (382px numa janela de 1400px de largura), e visualmente confirmado por
captura de tela. Achado de processo: testar isso na janela estreita do navegador embutido (~780px)
mascarava o problema — nessa largura o grid colapsa pra 1 coluna só, onde align-items não faz
diferença nenhuma (cada "linha" tem 1 item só); só foi possível confirmar de verdade emulando uma
janela de 1400px.
Pendente de ação humana: nenhuma — validado nos 2 temas (claro/escuro) e no alinhamento dos 4 cartões via medição real + captura de tela, numa largura de janela onde o layout de 4 colunas realmente ocorre.
2026-09-04 — Painel: "Falhas pendentes" vira fila mestre-detalhe (com screenshot), a pedido do usuário
Categoria: Reformulação de UX pedida pelo usuário, a partir de uma referência visual (mockup de um layout mestre-detalhe: fila navegável + painel de detalhe). Decisão explícita: reaproveitar só dado real — nenhuma "severidade" P1/P2/P3 nem "Sprint"/"Área de Negócio" fictícios do mockup entraram; onde não existe equivalente real, o campo simplesmente não foi incluído (mesmo critério já usado na reformulação do Dashboard, 04/09/2026).
Antes: docs/falhas-pendentes.md virava uma pilha de cards (.card-falha) empilhados, cada
um com seu próprio formulário de publicação — rolagem longa pra achar uma falha específica, sem
filtro nenhum.
Depois: fila à esquerda (lista compacta, com indicador de status real — cinza "ainda não reportado" / amarelo "já reportado" / vermelho "demanda aprovada, ainda falha" — reaproveitando os mesmos 2 sinais que já existiam, nunca uma severidade inventada) + painel de detalhe à direita (erro formatado, screenshot automático quando existe, os mesmos 4 botões de publicação de sempre, paginação "N de M"). Principais peças novas:
- Screenshot em tela:
screenshotUrl(novo campo emlistarFalhasPendentes(), server.js) — converte o caminho salvo em**Screenshot:**(separador nativo do SO) numa URL servível; nova rotaGET /screenshots/*reaproveita o mesmoservirDiretorio()já usado pro Mochawesome/docs. Se o arquivo não existir mais no disco (normal —cypress/screenshots/não é permanente, uma execução nova do mesmo spec sobrescreve), a imagem só desaparece de forma limpa (onerroresconde a seção) em vez de mostrar ícone de imagem quebrada — confirmado testando de propósito contra um caso real sem arquivo.loading="lazy"foi removido da tag depois de confirmado que atrasava oonerroro suficiente pra parecer que não funcionava. - Filtro por módulo real:
modulos(novo campo, mesma falha) — mesmo critério (nome do spec xMODULOS_PAINEL) já usado em "Módulos com mais reprovações" do Dashboard. Chips só aparecem pros módulos que têm pelo menos 1 falha na fila agora. - Busca livre (teste/spec/erro) + paginação (
‹ N de M ›) dentro da lista filtrada. - "Pular ›": avança pra próxima falha sem publicar nada — não remove a falha da fila (só
ajuda quem não quer decidir agora), diferente de publicar (que remove de verdade, via
removerFalhaPendenteSeExistirno servidor). Depois de publicar com sucesso, a fila recarrega sozinha e mostra a próxima — antes ficava o card antigo até clicar em "Atualizar" na mão.
Bug real encontrado e corrigido durante a implementação: o <pre> do erro, dentro do novo
painel de detalhe, ficou sem nenhuma regra de quebra de linha — o CSS antigo (.card-falha pre)
só valia dentro de .card-falha, classe que não existe mais em lugar nenhum do HTML depois da
reformulação. Um erro real (JSON longo numa linha só) forçava a página inteira pra ~8800px de
largura, com scroll horizontal — usuário notou e mandou print. Corrigido apontando as regras pro
container certo (.detalhe-falha .meta/.detalhe-falha pre) e reforçando com
grid-template-columns: 300px minmax(0, 1fr) (não só 1fr — grid não encolhe abaixo do tamanho
intrínseco do conteúdo sem isso) + min-width: 0 no painel de detalhe. Confirmado via medição
real (scrollWidth bateu com innerWidth), não só visual.
Ajustes de tamanho (mesmo dia, várias idas e vindas): usuário pediu repetidamente pra
"aumentar o card" — demorou a acertar o que exatamente crescer, porque as 2 colunas (fila à
esquerda, detalhe à direita) tinham tratamentos diferentes: .detalhe-falha já tinha
min-height (260px → 520px, depois testei reduzir pra 280px achando que era isso que pedia,
usuário corrigiu: "aumentou não" — voltei pra 520px), enquanto .fila-falhas-coluna (busca + fila
à esquerda) não tinha estilo de card nenhum — só crescia com o conteúdo (3 itens = bem baixa),
por isso parecia que nada aumentava por mais que eu mexesse só no lado direito. Corrigido dando à
coluna esquerda o mesmo tratamento de card (fundo/borda/min-height: 520px) — as duas colunas
terminam na mesma altura, confirmado por medição real (getBoundingClientRect, 520px nos dois
lados).
A causa raiz de verdade só apareceu depois: nada disso era sobre altura/tamanho do card — o
título de cada item na fila estava truncado com "..." (.item-fila-falha-titulo com
white-space: nowrap; text-overflow: ellipsis), e o usuário queria ler o título INTEIRO, não um
card maior. "Aumentar" o card em pixels nunca ia resolver isso (o texto continuava cortado do
mesmo jeito, só com mais espaço vazio ao redor) — daí a sequência inteira de tentativas erradas.
Corrigido de vez trocando pra white-space: normal; overflow-wrap: break-word (quebra em várias
linhas, título completo sempre visível) + align-items: flex-start no cabeçalho do item (o dot de
status alinha no topo do texto agora, não mais centralizado verticalmente contra um bloco maior).
Ainda faltava largura, porém — com a coluna em 300px o título quebrava em muitas linhas curtas;
usuário confirmou "aumenta para a direita" (mais largura, não mais altura) e a coluna da fila foi
pra 460px (grid-template-columns, era 300px minmax(0, 1fr)).
Espaçamento da lista "Work Items publicados" (mesmo dia, feedback à parte — não é sobre a fila
de falhas pendentes, é a outra sub-aba): os itens dessa lista estavam colados um no outro, sem gap
nenhum. Bug real, não só "valor pequeno demais": a regra CSS mirava .lista-work-items-completa
(seletor de CLASSE), mas o <div> só tem id="lista-work-items-completa" — nunca teve essa
classe, então a regra nunca aplicou nada (nem o gap: 8px original, sempre foi gap: normal,
confirmado via getComputedStyle). Primeira tentativa (só aumentar 8px→14px, mantendo o seletor
de classe errado) não resolveu nada — usuário confirmou "o espaçamento não foi feito" mostrando o
antes/depois idênticos. Corrigido de vez trocando o seletor pra #lista-work-items-completa
(ID, batendo com o HTML real) — confirmado por medição real (getComputedStyle(...).gap === '14px')
antes de reportar como resolvido.
"Vinculado · data · spec" reaproximado do número da demanda (mesmo dia, "Work Items
publicados"): esse texto ficava jogado no canto direito da linha (.item-work-topo com
justify-content: space-between), longe do badge "User Story #26980"/etc — usuário pediu pra
ficar perto. Trocado pra justify-content: flex-start (rótulo + ação/data/spec agrupados à
esquerda) — o selo de estado ("New"/"Testing"/"Closed", só existe na lista completa) continua no
canto direito via margin-left: auto nele mesmo, não mais pelo space-between do container.
Filtro por módulo removido (mesmo dia, pedido direto: "pode tirar esse filtro"): os chips
"Todas (N)"/"Boleto (N)" acima da busca saíram de vez — #fila-falhas-filtros (HTML),
falhaFiltroModulo + o trecho de montagem dos chips (client.js), e modulosDaFalha()/campo
modulos (server.js, não consumido por mais nada) removidos por completo, não só escondidos. A
busca livre (teste/spec/erro) continua — só o filtro por módulo saiu.
Pendente de ação humana: nenhuma — validado com dado real (as 3 falhas de cross-tenant já na fila), incluindo o caso sem screenshot no disco. Anexar o screenshot como anexo do work item no Azure (em vez de só mostrar em tela) foi perguntado ao usuário antes e ficou explicitamente pra depois ("ainda não faz").
2026-09-04 — Painel: badge de falhas pendentes direto na aba "Azure DevOps" (nav)
Categoria: Melhoria de UX pedida pelo usuário (viu o indicador numa referência visual e pediu pra reaproveitar aqui) — ver quantas falhas estão pendentes de triagem sem precisar abrir a aba.
Correção aplicada: <span id="badge-nav-azure-pendentes"> dentro do botão "Azure DevOps" da
navegação (painel-local/index.html), estilo pill âmbar (mesma linguagem visual do "TRIAGEM"/
"Falhas pendentes" do Dashboard). atualizarBadgeNavAzurePendentes() (novo, client.js)
atualiza o texto/visibilidade e é chamado em 2 lugares — carregarDashboard() (roda sempre, no
load da página, usando dados.falhasPendentesCount) e carregarFalhas() (mantém em dia quando a
própria aba é aberta/atualizada, reaproveitando a mesma contagem que já alimentava
#contagem-azure-pendentes dentro da aba). Fica escondido quando a fila está vazia (0 falhas).
Pendente de ação humana: nenhuma — validado no navegador embutido (badge aparece "3 pendentes" na nav e continua sincronizado com "Falhas pendentes (3)" dentro da própria aba).
2026-09-04 — cy.loginViaApi() estendido pra TODA a suíte — validado, só 1 recorrência já conhecida apareceu
Categoria: Continuação direta da entrada logo abaixo (piloto no Sanity). Usuário confirmou
explicitamente estender a troca pra TODOS os specs que chamavam cy.login(), sem exceção —
inclusive login.cy.js/sanity/loginSanity.cy.js (avisei antes que isso tira da suíte qualquer
cobertura da tela de login DE VERDADE; usuário optou por trocar mesmo assim, ciente do trade-off).
Correção aplicada: cy.login() → cy.loginViaApi() em 19 specs (todo lugar que chamava,
exceto o cenário de credenciais inválidas de login.cy.js, que usa LoginPage.login() direto e
continua exercitando a tela de verdade — única cobertura de UI de login que sobra na suíte).
Docstrings/comentários que citavam cy.login() por nome (smoke.cy.js, loginSanity.cy.js,
login.cy.js) reescritos à mão pra continuar precisos — a troca mecânica por sed teria deixado
alguns lendo errado (ex.: uma nota sobre timeout do cy.login() apontando pra
commands.js/cy.loginViaApi(), que não é onde essa nota vive). cy.login() em si não foi
removido — continua existindo em commands.js como infraestrutura/fallback (2FA automático via
totpSecret, modo assistido com cy.pause()), só não é mais chamado por nenhum spec hoje.
Validação: rodei os specs que NÃO criam dado real (smoke, todo o Sanity, casos_de_teste/ sem_dados/*, ux/*, performance/performance.cy.js, regressao/relatorioRegressao.cy.js) — 14
specs, 93 testes, 85 passando, 6 pending (specs marcados .skip de propósito, sem relação com
login) e só 2 falhas, ambas em ux/contaDigitalBoletoUx.cy.js ("Nova Movimentação" e "Tipo de
geração de boleto" — texto não alinhado à esquerda). Essas 2 são recorrência já conhecida e já
vinculada ao Task #26971 (ver tabela de Work Items acima) — nada a ver com a troca de login,
confirma inclusive que o problema é independente do método de autenticação. Notável: mesmo o
teste smoke.cy.js "Dashboard carrega após login" (que tem a asserção de URL com timeout de 45s,
a mesma família do cold-boot) passou de primeira nesta rodada.
Atualização, mesmo dia: usuário pediu pra rodar os specs de dado real também (confirmado
ciente do custo — e-mails reais, "Habilitar Subconta" irreversível em 2 specs). Rodados os 8 de
casos_de_teste/com_dados/ + boletoRegressao.cy.js + contaCorrenteRegressao.cy.js (10 specs,
49 testes): 44 passando, 4 falhas — todas recorrências já conhecidas, nenhuma nova, nenhuma
relacionada à troca de login:
boletoRegressao.cy.js(guid de Administradora aceito no lugar de Condomínio) — já linkado ao Task #25706, fica vermelho de propósito até a demanda corrigir (comentário no próprio teste já avisa isso). Removido defalhas-pendentes.md.condominioConfiguracaoBoleto.cy.js("Replicar decurso em subcontas" não persiste) — já linkado à User Story #26980. Removido defalhas-pendentes.md.contaDigitalCrossTenant.cy.js(2 falhas) +boletoCancelamentoCrossTenant.cy.js(1 falha) — os mesmos 3 achados de BOLA/IDOR que o usuário já tinha pedido pra só ignorar por enquanto, sem virar regra (ver entrada de triagem em lote mais abaixo, mesmo dia: "essa do cross tenant pode só ignorar por enquanto... se aparecer de novo deixa aí na lista"). Mantidos emfalhas-pendentes.mdsem nova investigação, exatamente como combinado.
Com isso, cy.loginViaApi() está validado em TODA a suíte (29 specs no total entre as duas
rodadas) — nenhuma regressão causada pela troca em nenhum deles.
2026-09-04 — cy.loginViaApi(): login 100% via API elimina o cold-boot — piloto rodado no Sanity, resultado forte
Categoria: Mitigação de instabilidade (opção 2 da conversa anterior sobre cold-boot), agora testada de verdade — continuação direta da entrada logo abaixo (teste do Chrome, que só reduziu o problema sem eliminar). Usuário pediu pra avançar pra essa opção e usar o Sanity como exemplo/piloto: "bora para a opção 3 [...] ja usa ele como exemplo para essa mudança para o login via api".
Investigação (nunca no chute): antes de escrever qualquer código, capturei o tráfego real de
rede de um cy.login() de verdade (via cy.intercept num spec descartável, deletado depois — mesmo
padrão já usado nesta sessão para investigar persist:core) para confirmar o contrato exato, em vez
de assumir o Swagger sozinho:
POST {boletoApi.baseUrl}/auth{ username, password }→ 200,{ token (JWT cru, 266 chars, 3 segmentos), name, guid, application, permissions, dateCreated, ttl, qrCode, exibeCodigoValidacao: false }— confirma [[ambiente-homolog-sem-totp]]: HML não pediu segundo fator nenhuma vez.GET {boletoApi.adminBaseUrl}/usuarios/atual— autenticado por headerAuthCG(nãoAuthorization/Bearer) carregando o JWT cru — confirmado também que SEM esse header a API responde 403. Resposta é oUsuarioVMcompleto.localStorage["persist:core"]guarda cada slice do Redux como string JSON separada; a sliceauthé{ token: { jwt: <claims decodificadas>, raw: <JWT cru> }, user: <corpo exato de /usuarios/atual> }— confirmado inspecionando o storage real após login.GET {boletoApi.baseUrl}/auth/validar-token(header AuthCG) → 200true; sem o header → 403. Endpoint leve o bastante pra substituir o "espera a URL virar /app/dashboard/inicio" dovalidate()decy.login()— que é exatamente o passo que trava no cold-boot.
Correção aplicada:
cypress/support/commands.js: novo comandocy.loginViaApi([username], [password])— autentica pelas 2 chamadas acima, decodifica o payload do JWT na mão (base64url), escrevepersist:coreviacy.visit(url, { onBeforeLoad })(populando o localStorage ANTES de qualquer script da página rodar, pro redux-persist reidratar já autenticado na 1ª renderização — nunca visita a tela de login).validate()docy.session()usado por ele também não visita/espera a SPA renderizar — só confirma o token com/auth/validar-token.- Trocado
cy.login()→cy.loginViaApi()em 5 dos 6 specs de Sanity:aplicacaoSanity.cy.js,boletoSanity.cy.js,contaCorrenteSanity.cy.js,contaGeradoraSanity.cy.js,relatorioSanity.cy.js.sanity/loginSanity.cy.jsecasos_de_teste/sem_dados/login.cy.jsficam de propósito comcy.login()— são os specs que testam o login em si; trocar removeria o próprio propósito do teste (mesma lógica já combinada com o usuário: "deixando abrir a tela de login no teste de login separado mesmo").
Resultado do piloto (3 rodadas seguidas, cypress run headless, browser padrão Electron —
não Chrome, pra não misturar as 2 mitigações): os 5 specs com cy.loginViaApi() passaram 15/15,
sempre rápidos (2-8s cada, sem nenhuma variância chamativa). A ÚNICA falha nas 3 rodadas foi
loginSanity.cy.js — que continua com cy.login() de propósito — com o mesmo sintoma exato já
documentado à exaustão (timeout de 45000ms esperando /app/dashboard/inicio). Isso isola o
problema: o cold-boot é especificamente do fluxo de UI (SPA renderizando/roteando depois do
login), e cy.loginViaApi() sidesteps ele por completo — nunca visita a tela de login nem espera
o router mudar de rota.
Pendente de ação humana: decidir com o usuário se/quando estender cy.loginViaApi() pros
demais specs do projeto (fora login.cy.js/loginSanity.cy.js) — combinado explicitamente fazer
"por partes", este piloto no Sanity é só o 1º passo. A instabilidade de login.cy.js/
loginSanity.cy.js continua existindo (é o preço de testar a tela de verdade) — não é escopo
desta mudança resolver isso, já que testar o login real exige passar pela SPA de qualquer jeito.
2026-09-04 — Cold-boot do login em modo headless: testado Chrome no lugar de Electron — não resolve sozinho
Categoria: Instabilidade passageira (ambiente/bootstrap da SPA), mesma família já registrada várias vezes neste histórico — não é falha nova de causa, é uma tentativa de mitigação testada e descartada como solução completa.
Contexto: usuário relatou que o timeout de login em cy.session().validate() (expected '.../app' to include '/app/dashboard/inicio', 45000ms) está acontecendo com frequência incômoda
em cypress run headless, mas nunca em cypress open. Perguntou se não havia o que fazer, e
propôs 2 alternativas: (1) trocar o browser headless de Electron pra Chrome, (2) reescrever login
pra ser 100% via API (exceto login.cy.js, que continuaria testando a tela de verdade). Pediu
pra testar só a opção 1 primeiro, "por partes".
Investigação (nunca no chute): confirmado via npx cypress info que Chrome/Edge/Firefox
estão instalados e detectados. Rodei cypress/e2e/sanity/**/*.cy.js (6 specs) com
--browser chrome --headless duas vezes seguidas:
- 1ª rodada: 6/6 passou, 34s total — limpo.
- 2ª rodada: 5/6 —
aplicacaoSanity.cy.jsfalhou com o mesmo sintoma exato já documentado (timeout de 45000ms validando a sessão, mesma URL esperada), eboletoSanity.cy.jsficou visivelmente mais lento (55s vs 6s na 1ª rodada) — sinal de lentidão geral do ambiente naquele momento, não de um problema específico do Chrome.
Também apareceram no meio dessa investigação (capturados automaticamente pelo hook global) mais 2
recorrências do mesmo sintoma, via a execução de outros specs no mesmo período:
cypress/e2e/casos_de_teste/sem_dados/login.cy.js (13:48:22) e o já citado
aplicacaoSanity.cy.js (14:12:26) — mesma mensagem de erro, mesma causa já conhecida.
Causa confirmada: trocar o browser headless de Electron pra Chrome reduz mas não elimina a instabilidade — o sintoma (bootstrap da SPA client-side demorando mais que o timeout antes de qualquer chamada de API disparar) reproduziu igual sob Chrome. Isso enfraquece a hipótese de que a causa fosse só "Electron headless sem aceleração de GPU/compositor" — parece estar mais ligado a variação de carga/tempo de resposta do próprio ambiente de homologação (agravada, possivelmente, por eu mesmo ter rodado dezenas de execuções headless seguidas nesta sessão) do que ao motor de renderização local escolhido.
Correção aplicada: nenhuma mudança de código — não faz sentido trocar o browser padrão do
projeto (cypress.config.js/scripts cy:run*) baseado numa mitigação parcial não confirmada.
docs/falhas-pendentes.md: as 2 entradas novas (login.cy.js 13:48:22, aplicacaoSanity.cy.js
14:12:26) removidas — mesma causa já conhecida e documentada, sem informação nova.
Pendente de ação humana: decidir o próximo passo com o usuário — rodar mais amostras em Chrome pra estimar taxa de falha real, aceitar a instabilidade residual como inerente ao ambiente, ou avançar pra opção 2 (login via API, cogitada mas explicitamente adiada: "vamos por partes").
2026-09-04 — "Nova Movimentação" vinculado ao Task #26971 (só localmente, sem comentar no Azure) — mesma Task que já cobre "Tipo de geração de boleto"
Categoria: Ajuste de rastreio (não é falha nova) — continuação direta da triagem de lote logo abaixo, mesmo dia. O usuário pediu pra vincular o achado "Nova Movimentação" (que a triagem tinha deixado na fila por não ter demanda RASTREADA por este painel) ao Task #26971.
Verificação antes de agir (nunca no chute): consultei o Task #26971 de verdade
(npm run azure:ler -- 26971) antes de vincular — o título é genérico e no PLURAL
("alinhamento campos de filtro Combobox", não "campo"), mesmo a descrição detalhando só o
cenário de "Tipo de geração de boleto" nos passos de reprodução. Perguntei ao usuário se queria
publicar um comentário de verdade no item explicando o 2º campo, ou só registrar aqui — escolheu
só registrar aqui.
Correção aplicada:
docs/historico-de-falhas.md: nova linha na tabela "Work Items do Azure DevOps vinculados" pro teste "Nova Movimentação", apontando pro Task #26971, com um valor de Ação novo —Vinculado— que não conta como "Criado" no gráfico de demandas do Dashboard (é só reconhecimento local, não uma publicação nova). Nota acrescentada na introdução da tabela explicando essa exceção (a linha foi acrescentada à mão, não pelo servidor).docs/falhas-pendentes.md: as 2 entradas de "Nova Movimentação" (que tinham ficado na fila comTriagem:na rodada anterior) removidas — o teste agora tem número de demanda reconhecido localmente, badge "🔗 Já reportado" já aparece pra ele no painel.
Pendente de ação humana: nenhuma — o item real no Azure não foi tocado, só nosso rastreio local. Se no futuro quiser deixar isso explícito pro time do produto também, dá pra comentar no Task #26971 depois.
2026-09-04 — Painel: faixa de status global volta a ser expansível (3ª versão do dia) — execução em lote tinha ficado sem jeito de acompanhar a saída ao vivo
Categoria: Ajuste de UX (não é falha de teste) — o usuário notou, testando "Rodar todos" numa busca (2 specs), que não tinha mais nenhum jeito de ver a saída ao vivo daquela execução: a 2ª simplificação do console (entrada anterior de hoje) tinha reduzido a faixa do rodapé pra só uma linha de status, sem abrir/fechar — o que funciona bem pra execução de 1 script/spec só (o acordeão mostra o console inline), mas deixa execução em lote (que não aponta pra nenhuma linha do acordeão) sem UI nenhuma pra acompanhar linha a linha.
Correção aplicada:
painel-local/index.html:.barra-execucao-globalganha de volta um cabeçalho (.barra-execucao-cabecalho) + botão "▸ Expandir"/"▾ Minimizar" + um<pre>(#console-saida-global) pra saída completa — tudo recolhido por padrão (hiddenno HTML), diferente da 1ª versão (que abria sozinha quando uma execução começava). Clicar em qualquer lugar do cabeçalho (não só no botão) também abre/fecha.painel-local/client.js:escreverNaBarraGlobal()(mesmo padrão de auto-scroll condicional de antes) alimenta o<pre>em todo eventolinhado SSE, incondicionalmente — diferente da linha do acordeão (sincronizarLinhaAoVivo), que só atualiza quando acha uma chave batendo; a faixa global mostra TUDO, sempre, então serve tanto pra execução única (redundante com a linha, mas inofensivo) quanto em lote (única fonte).
Confirmado ao vivo: cliquei em "▶ Rodar todos os 2" numa busca, depois em "▸ Expandir" na
faixa do rodapé — mostrou a saída real da execução em lote (login.cy.js + loginSanity.cy.js,
"Falhou (código 1)") crescendo ao vivo; cliquei em "▾ Minimizar" e recolheu de volta.
Pendente de ação humana: nenhuma.
2026-09-04 — Painel: KPI "Work Items no Azure" corrigido pra contar itens ÚNICOS — usuário notou que não batia com a aba "Work Items publicados"
Categoria: Bug real de painel (Dashboard mostrando número errado), achado pelo usuário comparando 2 telas ao vivo: o KPI "Work Items no Azure" mostrava 3, enquanto a aba Azure DevOps > "Work Items publicados" mostrava (7) logo ao lado na mesma sessão de uso.
Causa confirmada: o KPI reaproveitava demandasCriadasPorTipo — a mesma agregação usada pelo
gráfico de pizza "Demandas criadas no Azure DevOps", que só conta Ação = Criado (3 linhas:
Task #25706, Bug #26954, Task #26971) — ignorando as linhas Comentado/Vinculado e sem
deduplicar por número de item. O "(7)" da aba é o total de LINHAS da tabela (inclui repetição:
o mesmo Task #26971 aparece 2x — uma Criado, uma Vinculado — e o User Story #26980 também 2x,
ambas Vinculado). Nem o "3" nem o "7" era a resposta certa pro que o KPI deveria significar:
quantos Work Items DISTINTOS estão vinculados, no total.
Correção aplicada:
painel-local/server.js(montarDadosDashboard): novo bloco dedup porid(itemPorId,Map) — cada número de item conta 1 vez, não importa quantas linhas/Ações apontam pra ele. Novos camposworkItemsUnicosTotal/workItemsUnicosPorTipona resposta de/api/dashboard, sem alterardemandasCriadasPorTipo(continua só "Criado", pizza inalterada de propósito — é uma pergunta diferente: "quantas demandas este painel abriu" vs. "quantos Work Items existem vinculados no total").painel-local/client.js: KPI "Work Items no Azure" passa a usar os novos campos.docs/painel-local.md: bullet do KPI explicando a diferença entre os 2 números.
Confirmado ao vivo: com os dados reais desta sessão (Task #25706, Bug #26954, Task #26971, User Story #26980 — 4 números distintos, 7 linhas na tabela por causa de vínculos repetidos), o KPI passou a mostrar 4 ("2 Task · 1 Bug · 1 User Story"), a pizza "Demandas criadas" continuou em 3 (2 Task · 1 Bug) — os 2 números agora fazem sentido lado a lado, cada um respondendo uma pergunta diferente.
Pendente de ação humana: nenhuma.
2026-09-04 — 3 achados de cross-tenant tirados da fila por pedido explícito do usuário — dispensa pontual, NÃO virou regra (se recorrer, volta pra fila normal)
Categoria: Ajuste de fila (não é falha nova, nem investigação) — os 3 achados de segurança
cross-tenant que sobraram na fila depois da triagem de lote e das 2 vinculações acima
(contaDigitalCrossTenant.cy.js x2, boletoCancelamentoCrossTenant.cy.js x1) foram removidos de
falhas-pendentes.md a pedido direto do usuário: "essa do cross tenant pode só ignorar por
enquanto, não precisa colocar como regra não, se aparecer de novo deixa aí na lista, mas pode
tirar esse agora".
Importante — isso NÃO é uma regra nova de triagem: diferente das outras entradas desta
sessão (que saíram da fila por já terem demanda vinculada, Criado/Comentado/Vinculado), este
achado continua sem número de demanda nenhum. A remoção foi só pontual, pedida explicitamente
pra esta rodada. Da próxima vez que contaDigitalCrossTenant.cy.js ou
boletoCancelamentoCrossTenant.cy.js falharem, a entrada deve aparecer normalmente na fila —
sem nenhum **Triagem:** automático nem supressão — igual qualquer falha nova, pra ser
re-avaliada naquele momento (talvez a demanda já exista até lá, talvez o usuário decida agir
diferente). Achado de segurança confirmado continua documentado nas entradas de 28/08 e 02/09
deste arquivo, isso não muda.
Correção aplicada: docs/falhas-pendentes.md esvaziado (0 pendências) — nenhuma mudança em
CLAUDE.md nem no protocolo de triagem (triagem-de-falhas.md).
Pendente de ação humana: os 3 achados de segurança continuam reais e sem demanda aberta — só não estão mais visíveis na fila deste painel por enquanto.
2026-09-04 — "Replicar decurso em subcontas" vinculado à User Story #26980 (só localmente, sem comentar no Azure) — descrição do work item bate exatamente com o comportamento capturado no teste
Categoria: Ajuste de rastreio (não é falha nova) — mesmo padrão da vinculação do Task #26971 acima, pedido do usuário logo em seguida: vincular o achado "Replicar decurso em subcontas" (2 entradas na fila, títulos ligeiramente diferentes — ver abaixo) à User Story #26980.
Verificação antes de agir (nunca no chute): consultei a User Story #26980 de verdade
(npm run azure:ler -- 26980) antes de vincular. Título: "Persistência e restrição de
visibilidade da replicação de decurso em subcontas". Descrição bate exatamente com o
comportamento que o teste captura: "na tela da administradora, ao alterar para 'Sim' e salvar, o
banco replica o valor apenas na primeira execução, mas o campo na interface e no registro reverte
para 'Não'. Quando o operador precisa alterar o prazo de novo, o sistema exige selecionar 'Sim'
outra vez" — mesmíssimo sintoma do it() (expected [...] to contain text 'Sim', but the text was 'Não'). Match de conteúdo, não só de nome de campo — confiança alta. Perguntou-se
implicitamente pelo pedido do usuário ("só vincular, sem mudar nada no Azure") se deveria comentar
no item real — decisão: não.
Correção aplicada:
docs/historico-de-falhas.md: 2 linhas novas na tabela de Work Items vinculados (Ação =Vinculado, mesmo padrão da entrada anterior) — uma pra cada título exato que já apareceu na fila pra esse mesmo achado (o atual, sem sufixo, e o legado "— tratado no Bug #26951", órfão desde que aquele vínculo foi desfeito em 03/09) — cobre os 2 pra nenhum recapturar sem o badge "🔗 Já reportado" no futuro.docs/falhas-pendentes.md: as 2 entradas removidas (a de 04/09 e a legada de 03/09) —falhas-pendentes.mdcai de 5 pra 3 pendências (só os 3 achados de cross-tenant sem demanda ainda restam).
Pendente de ação humana: nenhuma — item real no Azure não foi tocado, só o rastreio local. A
User Story #26980 já existe (estado "New") independente deste painel; validação de ponta a ponta
do comportamento seguirá pendente por causa do ambiente (subconta nova nasce em AVALIACAO, não
ATIVA), como já registrado antes.
2026-09-04 — Triagem de lote (09h38-12h49, 20 recorrências): cold-boot/ant-menu-inline/subconta/regressões já ticketadas saem da fila; cross-tenant, UX "Nova Movimentação" e "Replicar decurso" seguem sem demanda
Categoria: Triagem da fila acumulada durante a sessão de trabalho no painel local (várias
execuções de smoke/sanity/UX disparadas pra testar a interface nova) — usuário pediu pra conferir
falhas-pendentes.md. Todas as 20 entradas batem com causa já confirmada antes; nenhuma
investigação nova precisou ser feita, só confirmar que cada uma bate com o padrão já mapeado
(nunca no chute — cada uma comparada contra a entrada original abaixo).
Saem da fila (instabilidade de ambiente já mapeada, ou já ticketado — nenhuma ação nova):
smoke.cy.js(3x) — 1x timeout de sessão pós-login (cold-boot do Electron, "Investigação funda do cold-boot headless", 03/09), 2x timeout emant-menu-inline(instabilidade de render do menu já documentada desde 20/08).boletoSanity.cy.js(2x),contaCorrenteSanity.cy.js(1x),aplicacaoSanity.cy.js(1x) — mesmo cold-boot de sessão pós-login acima.subconta.cy.js(par, 1x cada) — "Habilitar Subconta" 400 "não está ativa" → cascata noit()seguinte ("subconta da subconta"), mesmo padrão de dezenas de recorrências desde 24/08 (causa raiz: VS não aprova a conta, só reinício manual da aplicação em HML resolve — não é bug de produto nem de teste).boletoRegressao.cy.js(1x),boletoGuidExistenteRegressao.cy.js(1x) — regressão do guid de Administradora, já tem Task #25706 em andamento; teste fica vermelho de propósito até a correção.contaDigitalBoletoUx.cy.js"Tipo de geração de boleto" (2x) — combobox centralizado, já tem Task #26971.
Ficam na fila (bug real confirmado, mas sem número de demanda no Azure ainda — ganharam
**Triagem:** na entrada pra não reinvestigar do zero na próxima sessão):
contaDigitalBoletoUx.cy.js"Nova Movimentação" (2x) — mesmo combobox centralizado do achado de 02/09 ("Novo eixo de teste UX...") — demanda existe, mas fora do nosso rastreio (reportada direto pelo usuário ao time do produto, nunca criada por este painel).contaDigitalCrossTenant.cy.js(2x: Buscar Boletos, Criar Condomínio) eboletoCancelamentoCrossTenant.cy.js(1x) — achados de segurança confirmados (BOLA/IDOR, 02/09 e 28/08 em diante) — "Pendente de ação humana: reportar" ainda não foi feito.condominioConfiguracaoBoleto.cy.js"Replicar decurso em subcontas" (testado na Administradora, 1x) — mesmo achado já investigado 03/09 (ver entrada mais abaixo, "Correção: Bug #26951 NÃO cobre..."); esta é só mais uma recorrência do mesmoit(), sem título "tratado no Bug #26951" (o vínculo já tinha sido desfeito antes desta rodada).
Correção: nenhuma de código — é triagem pura. falhas-pendentes.md reduzido de 20 pra 7
entradas (as 6 acima + a que já estava com Triagem: de antes).
Pendente de ação humana: abrir demanda no Azure pros 3 itens ainda sem número (cross-tenant x3, "Nova Movimentação" já tem demanda externa então é só vincular se/quando publicarem algo aqui, "Replicar decurso" segue precisando de validação de ambiente antes de virar demanda de verdade).
2026-09-04 — Painel: nova sub-aba "Work Items publicados" (lista completa, com busca e estado ao vivo) + bug real corrigido nas sub-abas (2 grupos se atropelavam)
Categoria: Melhoria no painel (UX/funcionalidade nova) — pedido do usuário: sentia falta de consultar TODAS as demandas já criadas no Azure pelo painel, não só as últimas 8 do card "Work Items recentes" do Dashboard; sugeriu uma aba/funcionalidade dedicada, ou um "ver mais" no Dashboard levando pra lá.
Correção aplicada:
painel-local/server.js: nova rotaGET /api/work-items, devolvendo TODA a tabela "Work Items do Azure DevOps vinculados" (não só as últimas 8), mais recente primeiro, cada item enriquecido com o estado atual consultado ao vivo na API do Azure (enriquecerVinculosComEstado, mesmo padrão deenriquecerComEstadoDemandajá usado em "Falhas pendentes" — tolerante a erro/PAT ausente, só fica sem o estado ao vivo nesse caso).painel-local/index.html/client.js: aba Azure DevOps ganhou 2 sub-abas (mesmo padrão "tabs-execucao"/"painel-execucao" já usado em Execução & Specs) — "Falhas pendentes" (conteúdo de sempre) e "Work Items publicados" (lista nova, busca por título/número/tipo/spec, badge de estado ao vivo com destaque verde pra item já em Testing/Validation/Deployment/Closed). Card "Work Items recentes" do Dashboard ganhou botão "Ver todos →" que abre direto nessa sub-aba.- Bug real encontrado e corrigido nesse meio tempo: o wiring de sub-abas
(
document.querySelectorAll('.tab-execucao')...) era GLOBAL — com 2 grupos de sub-abas na mesma página agora (Execução & Specs e Azure DevOps), clicar numa aba de um grupo desmarcava a aba ativa do OUTRO grupo também (a busca por.tab-execucao/.painel-execucaonão distinguia a qual grupo cada botão pertencia). Corrigido escopando pelo<section>mais próximo (botao.closest('section')) antes de buscar botões/painéis — cada seção só mexe nas próprias sub-abas agora. Sem essa correção, a nova sub-aba teria esse mesmo problema ao ser adicionada.
Confirmado ao vivo: clique em "Ver todos →" abre a aba Azure DevOps já na sub-aba "Work Items publicados", mostrando os 4 work items reais com estado ao vivo (1 "Closed" com destaque verde, 3 "Testing"). Busca por "Bug" filtrou corretamente pra 1 resultado. Confirmado via inspeção do DOM que trocar sub-aba em Azure DevOps não mexe mais na sub-aba ativa de Execução & Specs (e vice-versa) — antes desse fix, trocaria.
Pendente de ação humana: nenhuma.
2026-09-04 — Painel: lista "relacionado" de Por demanda também vira acordeão + toast corrigido pra não sobrepor a faixa de status do rodapé
Categoria: Melhoria no painel (UX/layout, não falha de teste) — continuação direta das 3
entradas anteriores (mesmo dia). O usuário mandou um screenshot da lista de sugestões "relacionado"
(aba Por demanda, quando a demanda não tem vínculo exato) ainda no estilo antigo (linha de texto
simples + botão pequeno "Rodar") e pediu pra aplicar o mesmo acordeão das outras listas. No mesmo
fôlego, notou que a mensagem de erro "já tem uma execução em andamento" aparecia colada em cima da
faixa de status do rodapé (as duas são position: fixed perto do rodapé) e pediu pra ajustar.
Correção aplicada:
painel-local/client.js:renderizarRelacionado()reescrita pro mesmo HTML de acordeão (.linha-execucao) já usado em Scripts/Cenários específicos, reaproveitandoligarLinhasExecucao()e a classe.rodar-spec(mesmo listener de sempre, só que escopado a este container). Como o MESMO spec pode aparecer simultaneamente nesta lista E em "Cenários específicos", o pareamento execução→linha precisou virar robusto a duplicata:acharLinhaPorTitulo()(retornava 1 elemento, exigia exatamente 1 candidato) virouacharChaveLinhaPorTitulo()(retorna a CHAVE — string —, tolera várias linhas com a mesma chave) esincronizarLinhaAoVivo()agora usaquerySelectorAll(nãoquerySelector) pra atualizar TODAS as linhas com aquela chave ao mesmo tempo, não só a primeira que achar.painel-local/index.html:.toasttinhabottom: 20px, a mesma faixa que a.barra-execucao-global(rodapé fixo, ~37px de altura) ocupa — subiu prabottom: 76px(folga de sobra acima da faixa) +max-width: 380px(mensagens mais longas, tipo a de "já tem execução em andamento", não esticavam até virar ilegível).docs/painel-local.md: bullet do acordeão atualizado citando as 3 listas agora cobertas (Scripts, Cenários específicos, Por demanda/relacionado) e a sincronização por chave duplicada.
Confirmado ao vivo: busquei a demanda #20755 (sem vínculo exato) — a lista de sugestões
"Boleto" já nasce em acordeão idêntico às outras 2 abas. Cliquei ▶ num spec sem "cria dado real"
(boletoSanity.cy.js) com outra execução ainda rodando — toast "já tem execução em andamento"
apareceu com bottom: 644px contra o topo da faixa de status em top: 683px (39px de folga,
sem sobreposição, confirmado via geometria real do DOM, não só visual).
Pendente de ação humana: nenhuma.
2026-09-04 — Painel: console do rodapé simplificado pra faixa de status global (sem abrir/fechar, sem botões) — detalhe agora só na linha do acordeão
Categoria: Melhoria no painel (UX/layout, não falha de teste) — continuação direta da entrada anterior (mesmo dia, poucos minutos depois). Com o console ao vivo embutido em cada linha do acordeão (entrada anterior), o console completo no rodapé (abre/recolhe, botão "Limpar") ficou redundante — o usuário pediu pra simplificar: deixar só uma faixa fixa mostrando que tem execução rolando (visível em qualquer aba, não só Execução & Specs) e, ao terminar, só passou/falhou — quem quiser detalhe vai na linha do teste.
Correção aplicada:
painel-local/index.html: bloco.console-execucao/.console-cabecalho/.console-acoes/.console-saidaremovido; novo.barra-execucao-global, 1 linha só (.console-statusreaproveitado, mesma classe/id de antes). Markup saiu de dentro de<section id="execucao">(só existia com a aba ativa) e virou irmão de<main>, composition: fixed— por isso aparece em QUALQUER aba enquanto tem execução rolando, não só na de Execução & Specs.mainganhoupadding-bottomextra pra a faixa fixa não tampar o fim do conteúdo.painel-local/client.js:elConsoleSaida,elConsolePainel,elBtnMinimizar,definirConsoleAberto()eescreverNoConsole()removidos — o SSE ('linha') agora só alimentadetectarVersoes()(chip de versão do topbar) e a linha ao vivo do acordeão (sincronizarLinhaAoVivo(), sem mudança de comportamento aí).atualizarStatusConsole()ganhouelBarraGlobal.hidden = false— a faixa só aparece depois da 1ª execução real da sessão.docs/painel-local.md: bullet do console reescrito explicando a 2ª simplificação.
Confirmado ao vivo: faixa aparece embaixo em qualquer aba (testado no Dashboard, com uma execução real rodando em segundo plano) — sem console cheio, sem botão, só "Rodando: npm run cy:run:X" com bolinha azul, virando "Concluído"/"Falhou" no final.
Pendente de ação humana: nenhuma — vale lembrar que execuções em LOTE ("Rodar todos"/"Rodar
por demanda") não têm mais nenhuma UI pra ver a saída linha a linha (só o status curto); o
servidor ainda guarda tudo em memória (execucaoAtual.linhas) enquanto a execução não troca, só
não tem botão pra abrir isso agora — se fizer falta, dá pra reintroduzir só pra esses casos.
2026-09-04 — Painel: Scripts/Cenários específicos viram acordeão (não mais cards em grade) — console ao vivo embutido na própria linha ao clicar ▶
Categoria: Melhoria no painel (UX/layout, não falha de teste) — continuação direta da entrada anterior (mesmo dia). O usuário mandou 2 screenshots do relatório-acordeão do projeto de referência (linhas com ✓/⊗, badges PASS/FAIL, duração, chevron de expandir) e perguntou por que a aba "Execução & Specs" não tinha ficado parecida — explicou que queria tirar "aqueles quadros" (os cards em grade de Scripts/Cenários específicos, que achou feios) e, no lugar, um botão ▶ que roda E expande a própria linha mostrando o console, em vez de conteúdo estático tipo "SMK-02".
Isso resolve, de um jeito concreto, o conflito que eu tinha sinalizado na pergunta anterior desta mesma sessão (a aba do exemplo é um visualizador de relatório pronto; a nossa dispara execução) — a resposta do usuário aqui é usar o PADRÃO VISUAL do acordeão pra cobrir o disparo de execução de verdade, com o console ao vivo no lugar do conteúdo fictício.
Correção aplicada:
painel-local/index.html:.grid-scripts/.card-script/.grid-specs/.card-specremovidos; novo conjunto.lista-execucao/.linha-execucao(+-cabecalho/-status-icone/-info/-nome/-sub/-acoes/-corpo/-console) — 1 linha por script/spec, com ícone de status (círculo, muda de cor conforme rodando/sucesso/falhou), botão ▶ (.btn-play) e chevron (.btn-chevron). Containers HTML (grid-scripts-gerais/grid-scripts-categoria) trocaram a classe pralista-execucao(mantiveram oid, então nada no JS que já os referenciava precisou mudar).painel-local/client.js:cardScriptHtml()/renderizarSpecs()reescritos pra gerar o HTML do acordeão em vez do card antigo. Nova função compartilhadaligarLinhasExecucao()(clique no cabeçalho expande/recolhe; clique no ▶ para propagação e só roda — não expande/recolhe por conta própria, quem faz isso é a execução de verdade começando). Novo bloco "linha ao vivo":acharLinhaPorTitulo()acha, entre todas as.linha-execucaorenderizadas, a única cujodata-chavebate com otituloda execução atual (npm run <script>ou o caminho do spec — mesmotituloqueiniciarExecucao()já usa no servidor, nenhum campo novo); quando bate exatamente 1, essa linha abre sozinha e recebe a mesma saída que já ia pro console global (escreverNoConsole), sem duplicar a conexão SSE. Execução em lote (/api/rodar-varios,/api/demanda/rodar) não bate em nenhuma linha só — continua só no console global docado, intencional (não tem 1 linha específica pra apontar).sincronizarLinhaAoVivo()é chamada também depois de todo re-render da busca (aplicarBusca()), pra sobreviver a digitar no campo de busca no meio de uma execução sem perder o console daquela linha.docs/painel-local.md: seção "Aba Execução" ganhou o bullet "Acordeão, não mais cards em grade" explicando o mecanismo.
Confirmado ao vivo: cliquei ▶ em cy:run:smoke (Scripts por categoria) — a linha ganhou borda
azul, expandiu sozinha e mostrou a saída real do Cypress (cypress-core@1.0.0 cy:run:smoke,
versão/browser/node, Running: smoke.cy.js) crescendo ao vivo dentro da própria linha, com o
console global docado mostrando a mesma coisa em paralelo. Testado nas 2 sub-abas (Scripts e
Cenários específicos).
Pendente de ação humana: nenhuma.
2026-09-04 — Painel: Dashboard reconstruído a partir de um projeto de referência completo (React) — KPIs/lista de Work Items/tabela de execuções reais no lugar dos widgets fictícios do exemplo
Categoria: Melhoria no painel (UX/layout, não falha de teste) — continuação direta das 2 entradas anteriores (mesmo dia). O usuário mandou o projeto React/Vite/Tailwind completo gerado pela AI Studio que deu origem às telas de referência já usadas ("Gostei muito desse layout"), e pediu pra seguir "praticamente igual" pro resto do painel (só Mochawesome/Documentação HTML ficam de fora, por serem iframes de conteúdo real).
Investigação: li os componentes reais (App.tsx, Header.tsx, NavigationTabs.tsx,
DashboardView.tsx, ExecutionSpecsView.tsx, AzureDevOpsView.tsx) — é um mockup de IA com dado
100% fictício (branch/commit/autor por execução, painel "Azure Backlog" com sync própria, botão
"AI Assist" simulando geração de texto, IDs de teste tipo "SMK-02", link de screenshot num CDN que
não existe). Achei um conflito real: a aba "Execução & Specs" do exemplo é um VISUALIZADOR DE
RELATÓRIO já rodado (acordeão por teste, screenshot) — a nossa aba de mesmo nome serve pra
DISPARAR execuções (chips, sub-abas, console). Perguntei ao usuário antes de mexer: resposta foi
manter o disparo e só trocar o visual (opção recomendada).
Correção aplicada:
painel-local/server.js(montarDadosDashboard): 4 campos novos, todos derivados de dado já rastreado —execucoesRegistradasNoMes(linhas dedashboard-execucoes.mdno mês),falhasPendentesCount(tamanho defalhas-pendentes.md),execucoesRecentes(últimas 20 linhas dedashboard-execucoes.md, qualquer mês),workItemsRecentes(últimos 8 vínculos da tabela de Work Items).modulosComMaisReprovacoesganhou campopercentual(usado pra colorir a barra).painel-local/index.html/client.js— Dashboard: subheader com referência/sync/atualizar, 4 KPIs (Total de testes, Execuções no mês, Falhas pendentes, Work Items no Azure), gráfico de Módulos trocado de Chart.js pra barra HTML (permite mostrar % real por módulo com cor por severidade), card novo "Work Items recentes" (substitui o "Azure Backlog" fictício, mas com vínculos reais e link pro Azure de verdade), tabela nova "Execuções headless registradas" com busca client-side (substitui a tabela de branch/commit/autor fictícios — mostra script, total/pass/fail e specs com falha, que é o que a gente realmente tem).- Aba Execução & Specs: faixa de alerta vermelha "N falhas pendentes de triagem" no topo (só
aparece quando
falhasPendentesCount > 0) — mesmo dado do KPI do Dashboard, não decorativo. - Aba Azure DevOps: callout "Modo Direto" com pill de status do Azure real (mesma checagem do
topbar) + categoria do erro (
TIMEOUT/ASSERTION FAILED/CYPRESS ERROR/E2E FAILURE) derivada do texto real do erro (tipoDeErro(), client.js) — nunca um campo à parte que pudesse divergir. - Logo trocada pra
logo_transparent.png(nova marca, sem texto, funciona nos 2 temas sem variante separada) — arquivo antigoLogo.pngnão existe mais no projeto. - Modo escuro passou a ser o padrão (antes seguia
prefers-color-schemedo sistema) — pedido explícito do usuário.
Achado real durante a implementação: o card "Work Items recentes" (8 itens) ficava muito mais
alto que os outros 3 cards da mesma linha da grade — grid-template-columns com
align-items: stretch (padrão do CSS Grid) forçava TODOS os cards da linha a esticar pra bater
com o mais alto, deixando espaço vazio enorme dentro dos cards mais curtos (donut, pizza). Corrigido
com align-items: start na grade + max-height/rolagem própria na lista de Work Items.
Confirmado ao vivo: Dashboard, Execução & Specs e Azure DevOps testados nos 2 temas — dados reais em todo lugar (401 testes/50 execuções/2 falhas pendentes/3 Work Items no mês corrente, 20 execuções reais na tabela com busca funcionando, categoria de erro "TIMEOUT" batendo com o texto real do erro).
Pendente de ação humana: nenhuma.
2026-09-04 — Painel: paleta/tipografia/topbar redesenhados a partir de um design system de referência aprovado pelo usuário — versão e status do Azure ao vivo, badges viram indicador colorido
Categoria: Melhoria no painel (UX/visual, não falha de teste) — continuação direta da entrada
anterior (mesmo dia). O usuário mandou 3 screenshots + um .md de design system ("Precision
Engineering Dashboard": paleta zinc neutra, azul/verde/âmbar/vermelho só pra status de execução,
Geist/Inter/JetBrains Mono, raios pequenos, bordas finas) e pediu pra seguir esse layout "seguindo
nossas regras" — ou seja, adaptar a linguagem visual sem inventar dado falso (as 2 telas de
exemplo do usuário tinham IDs de teste fictícios tipo "SMK-02"/"BOL-01" e um painel de commits com
autor/branch inventados — nada disso existe de verdade no projeto, então não foi replicado).
Correção aplicada:
painel-local/index.html::rootreescrito com a paleta zinc (claro:#fafafa/#ffffff/#f4f4f5; escuro:#09090b/#121215/#18181b) + 4 cores de status (--azul#0066ff,--verde#10b981,--amarelo#f59e0b,--vermelho#ef4444) que são as MESMAS nos 2 temas — simplificação real: os badges antes tinham um par de hex escolhido à mão por tema (--amarelo-bg/--amarelo-texto/--amarelo-bordaetc., 2x); agora é 1 cor base +color-mix()pra derivar fundo/borda tingidos, exatamente como o design de referência descreve ("10% opacity tinted background matching status color"). Fontes Geist/Inter/JetBrains Mono via Google Fonts. Console vira "terminal de verdade" com superfície própria quase preta (#050507) fixa nos 2 temas — não muda com o tema do resto do app, de propósito (mesmo padrão de qualquer terminal/log de ferramenta de dev).- Topbar reconstruído (
<header>): marca "PartnerBank QA / Cypress" (nome real da empresa, não fabricado — já documentado em CLAUDE.md) + pill "Homologação" (ambiente real) + chip de versões do Cypress/Electron/Node + pill de status do Azure DevOps. Nav vira tira de texto plano ("Dashboard", "Execução & Specs", "Relatório (Mochawesome)", "Documentação (HTML)", "Azure DevOps") sem ícone decorativo, mais perto do "Technical Minimalism" do documento de referência. painel-local/client.js:detectarVersoes()— nova função que lê as linhas reais do console de execução (Cypress: X/Browser: Electron X/Node Version: vX, sempre impressas porcypress run) e preenche o chip do topbar só com o que já foi visto de verdade nesta sessão — nunca um número fixo que poderia ficar desatualizado sozinho se o Cypress for atualizado nopackage.jsone ninguém lembrar de mudar uma string solta.atualizarStatusAzureTopbar()— chamaGET /api/iteracao-atual(rota que já existia) só pra saber se o PAT/API do Azure está respondendo, sem inventar um "Sync OK" decorativo. Todo emoji usado como INDICADOR DE STATUS (✅/❌/⚠️/🔗/⚪/🔵) trocado por um ponto colorido de 6px (.dot) — badge "já reportado", badge "demanda aprovada", badge "cria dado real", resultado de teste em "Rodar por demanda", status do console. Ícones decorativos em botões (🔎/🧹/🔄/⛶) ficaram de fora de propósito — não eram o que o usuário pediu, e trocar todos de uma vez inflaria o diff sem necessidade.docs/painel-local.md: nova seção "Visual (04/09/2026)".
Confirmado ao vivo: topbar mostrando "CY 13.17.0 · Electron 118 · Node v24.19.0" (detectado de verdade na execução da entrada anterior, ainda em memória do servidor) e "Azure DevOps: conectado" (PAT válido) — nos 2 temas, e nas 3 abas testadas (Dashboard, Execução & Specs, Azure DevOps).
Pendente de ação humana: nenhuma — mas os ícones decorativos de botão continuam com emoji, se quiser ir mais longe na limpeza visual depois.
2026-09-04 — Painel: aba Execução reorganizada (busca+chips / 3 sub-abas / console recolhível no rodapé) + modo claro/escuro no sistema todo
Categoria: Melhoria no painel (UX/layout, não falha de teste) — pedido do usuário em 3 rodadas na mesma sessão: (1) trocar "cada Rodar abre uma janela cmd separada" por um console embutido na própria aplicação; (2) esse console (1ª tentativa: coluna fixa à direita, sempre aberta) deixou o resto do conteúdo espremido e o usuário achou "péssimo"; (3) pedido pra também ter modo escuro.
Investigação/decisão de design: como nem o usuário nem eu somos fortes em design (dito
explicitamente), em vez de tentar uma 3ª correção no escuro, usei a ferramenta de mockup (widget
interativo, fora do código real) pra propor uma direção nova e pedir aprovação ANTES de mexer em
painel-local/index.html/client.js de novo — evitou um 3º ciclo de tentativa-e-erro no código
de produção. Direção aprovada: barra lateral de módulos vira chips horizontais junto da busca; as
3 seções (Rodar por demanda / Scripts / Cenários específicos), antes todas empilhadas numa
rolagem só, viram sub-abas (só uma visível por vez); console vira uma faixa fina no rodapé,
recolhida por padrão, que abre sozinha só quando uma execução começa.
Correção aplicada:
painel-local/index.html::rootganhou um jogo completo de variáveis de cor (--card-alt,--azul-fraco,--amarelo-*,--vermelho-*,--sombra) e um bloco:root[data-tema="escuro"]redefinindo as MESMAS variáveis — nenhuma regra de estilo precisa saber qual tema está ativo. Toda cor hardcoded (#fff,#f0f1f4, badges âmbar/vermelho etc.) foi trocada por essas variáveis. Seção#execucaoreescrita: sidebar →.chips-modulos; as 3 seções →.tabs-execucao.painel-execucao(umaativopor vez); console →.console-execucaofixo no rodapé (position: sticky; bottom: 0, sangrando até a borda da janela), classeminimizadopor padrão. Botão 🌙/☀️ novo no cabeçalho.
painel-local/client.js: tema aplicado viadocument.documentElement.dataset.tema, persistido emlocalStorage, padrão = preferência do sistema (prefers-color-scheme) na 1ª visita.carregarDashboard()setaChart.defaults.color/borderColorna mão (Chart.js não lê variável CSS) e é rechamada ao trocar de tema. Nova função de troca de sub-aba (.tab-execucao/.painel-execucao). Console:definirConsoleAberto()chamada nos eventos SSEinicio(sempre abre) eestado(abre só sestatus === 'rodando', pra um reload no meio de uma execução reabrir sozinho, mas um reload depois que já terminou não force abrir à toa).renderizarGridScripts()/renderizarSpecs()passam a devolver a contagem de matches, usada pra pintar "Scripts (N)"/"Cenários específicos (N)" no rótulo da própria aba — sem isso um resultado filtrado numa aba fechada passaria batido pro usuário.CLAUDE.md: nota atualizada na seção "Chips 'Módulos'" (era "Barra lateral").docs/painel-local.md: seção "Aba Execução" reescrita + nova seção "Tema claro/escuro".
Confirmado ao vivo: testado em 1440px (3 colunas de scripts sem espremer) e em modo mobile
(chips quebrando linha, console com padding menor) — nos 2 temas. Clique em "Rodar" abre o
console sozinho e mostra a saída real de um cy:run:smoke completo; reload da página no meio de
uma execução reconecta e mostra o que já rodou; toggle de tema recolore os gráficos do Dashboard
na hora.
Pendente de ação humana: nenhuma.
2026-09-04 — Painel/smoke.cy.js: filtro por módulo passa a considerar tags de it(), não só nome de arquivo — "Termos Aceite"/"Integrador"/"Notificações" agora acham smoke.cy.js
Categoria: Melhoria no painel (continuação direta da entrada anterior, mesmo dia) — usuário
testou a ampliação de MODULOS_PAINEL e confirmou o problema que eu já tinha antecipado ao
documentar a entrada anterior: "Termos Aceite", "Notificações" e "Integrador" existem de verdade
como it() dentro de smoke.cy.js, mas o filtro só olhava NOME DE ARQUIVO — então esses 3
módulos (e outros sem spec dedicado) sempre davam 0 resultado, mesmo tendo cobertura real.
Correção aplicada:
scripts/specs-utils.js: nova funçãoextrairTagsDoSpec()— lê o arquivo de verdade e extrai as tags{ tags: '@x' }/{ tags: ['@x','@y'] }(@cypress/grep), escopado só dentro da propriedadetags:(não em qualquer@do arquivo — achado real: um regex livre pegava@condominio.comde dentro de um e-mail de teste emcypress/support/commands.js, falso positivo).listarSpecsCypress()agora devolvetagspor spec.cypress/e2e/smoke/smoke.cy.js: adicionadas tags nosit()s que ainda não tinham —@unidadeOrganizacional,@usuarios(Listar/Perfil),@termosAceite,@contaCondominial(as 4 telas, incluindo as 2.skipadas),@integrador,@notificacoes.cypress/e2e/casos_de_teste/com_dados/condominioConfiguracaoBoleto.cy.js: a tag@condominiojá existente foi renomeada pra@condominioConfiguracaoBoleto— o nome curto tinha exatamente o mesmo problema de colisão com "Conta Condominial" que o termo deMODULOS_PAINELjá tinha sido corrigido pra evitar (entrada anterior) — deixando a tag com o nome curto de novo abriria a mesma brecha, só que num lugar diferente.painel-local/client.js(specCombina) epainel-local/server.js(fallback de "Rodar por demanda"): passam a considerar a tag do spec, além do nome do arquivo, ao decidir se um spec bate com um módulo.CLAUDE.md: nova regra em "Padrão de código" (pedido explícito do usuário) — tododescribe/it()novo precisa citar seu módulo via tag, usando o mesmo nome de alguma entrada deMODULOS_PAINEL, pra não repetir esse mesmo problema com uma tela nova no futuro.
Confirmado ao vivo: clicar em "Termos Aceite" na barra lateral agora mostra smoke.cy.js em
"Cenários específicos" (antes: "Nada aqui bate com a busca").
Pendente de ação humana: nenhuma — mas vale lembrar (documentado na nova regra do CLAUDE.md) de sempre marcar a tag ao adicionar teste novo, pra esses filtros continuarem funcionando.
2026-09-04 — MODULOS_PAINEL ampliada pro menu real inteiro (não só onde já tem spec) + bug real corrigido: termo composto nunca batia contra texto natural com espaço
Categoria: Melhoria no painel + correção de bug (achado testando a própria melhoria) — usuário mostrou o menu lateral REAL do produto (print) e pediu pra melhorar a divisão por módulo considerando o menu inteiro, não só os módulos que já têm spec dedicado.
Investigação real antes de mudar nada (nunca no chute): em vez de inventar nome de módulo a
partir do print, usei cypress/e2e/smoke/smoke.cy.js como fonte — é o mapa do menu inteiro,
navegado manualmente item por item em 20/08/2026 (já documentado ali), incluindo as tags
{ tags: '@x' } que o próprio smoke já usa pra agrupar item de menu em módulo (ex.: "Remessa" e
"Notificações > Boletos" já são @boleto — não precisavam de entrada nova). Achado importante:
"Condomínio / Config." (termo antigo: condominio) colidia de verdade com "Conta Condominial",
um item de menu BEM diferente (dashboard/despesas/webhook de condomínio — nada a ver com a
Configuração de Boleto que condominioConfiguracaoBoleto.cy.js testa). Renomeado pra
"Configuração de Boleto (Condomínio)" com termo mais específico
(condominioConfiguracaoBoleto), e "Conta Condominial" ganhou entrada própria de verdade.
Correção aplicada: MODULOS_PAINEL (scripts/specs-utils.js) foi de 11 pra 17 entradas —
adicionadas Conta Condominial, Usuários, Unidade Organizacional, Termos Aceite, Integrador,
Notificações (todas sem spec dedicado ainda, 0 resultado na busca/sidebar por enquanto — o
propósito principal delas agora é alimentar o fallback de "Rodar por demanda" com mais precisão).
"DDA" ficou de fora de propósito: os 4 it()s do menu estão .skipados no smoke ("não utilizado
no momento") e as partes ativas já caem em @aplicacao/@boleto.
Bug real encontrado testando a ampliação: ao verificar se um termo composto tipo
unidadeOrganizacional batia contra uma demanda real, percebi que NUNCA batia — nem os termos
antigos já existentes (contaCorrente, contaGeradora) batiam contra texto natural. Causa: o
termo é 1 palavra só (camelCase, pra bater com nome de arquivo), mas texto de demanda escreve
"Conta Corrente" COM espaço — .includes() nunca reconhecia isso. removerAcentos() virou
normalizarParaCompararModulo() (painel-local/server.js), que agora também remove espaço antes
de comparar — confirmado com teste real que "Conta Corrente do cliente" agora bate com o termo
contaCorrente.
Pendente de ação humana: nenhuma — mas o achado de "Condomínio / Config." colidindo com "Conta Condominial" é um lembrete pra sempre verificar o menu real do produto antes de nomear um módulo novo daqui pra frente, não só o nome do arquivo de spec.
2026-09-04 — Painel: fallback de "Rodar por demanda" passa a checar a Tag da demanda primeiro (mais confiável que título/descrição)
Categoria: Melhoria no painel (mais uma volta na conversa sobre o mesmo mecanismo) — usuário
testou o fallback por título/descrição da entrada anterior com uma demanda real (Task #26763,
"centralização do filtro nova movimentação") e não achou nada, porque nem o título nem a
descrição citam qualquer termo de MODULOS_PAINEL. Perguntou qual seria a opção "mais garantida"
— algo pra preencher no Azure, ou algo no código.
Investigação real antes de decidir (nunca no chute): consultei alguns work items reais via
npm run azure:ler — descobri que o Task #26971 (já vinculado no painel) tem a Tag
"Boleto API" no Azure, mas #26763, #26954 e #25706 não têm tag nenhuma. Não é um hábito
universal do time, mas confirma que a Tag já é usada às vezes, e é um sinal muito mais confiável
que texto solto (é uma marcação deliberada, não uma palavra que apareceu por acaso).
Decisão (do usuário): usar a Tag como sinal PRIMÁRIO — com "contém", não igualdade exata
("Boleto API" tem que bater com o termo boleto, mesma regra do fallback por texto) — e manter o
fallback por título/descrição da entrada anterior como sinal SECUNDÁRIO, só quando a Tag não
bater com nada.
Correção aplicada:
scripts/azure-devops.js:lerWorkItem()agora também devolvetags(System.Tags, string separada por "; ").painel-local/server.js:GET /api/demandacheca Tag primeiro, texto depois; resposta ganhouorigem: 'tag' | 'texto', pra deixar rastreável qual sinal achou o módulo.painel-local/client.js: mensagem da UI mostra a origem do match ("achei N cenário(s) da área X (pela tag)" ou "(pelo título/descrição)").
Achado colateral, não corrigido de propósito: testando outros work items reais pra validar, a demanda #26940 ("Ajuste no fluxo de cancelamento de reserva") bateu com o módulo "Condomínio / Config." pelo fallback de TEXTO — a descrição cita "Condomínio: RO Res Blvd Excellen" porque o cliente é uma administradora de condomínios, não porque o achado seja sobre a tela de Configuração de Boleto do Condomínio (a demanda é sobre o módulo de Reservas, que nem existe nesta suíte). Confirma na prática o limite já esperado do fallback por texto — é só sugestão, nunca vínculo confirmado, por isso a UI sempre deixa isso explícito.
Pendente de ação humana: nenhuma no código — mas vale levar pro time a ideia de usar Tag com
nome de módulo (boleto, condominio, subconta...) ao abrir demandas relacionadas a este
projeto, já que isso já é um hábito parcial e ajuda o painel a achar de forma bem mais confiável.
2026-09-03 — Painel: "Rodar por demanda" ganha fallback por módulo (título/descrição da demanda) quando não há vínculo exato
Categoria: Melhoria no painel (desenhada em conversa, mesmo padrão das 2 entradas anteriores) — usuário apontou um buraco real no Cenário 2: uma demanda que nunca passou pelo painel (nunca virou Story/Bug/Task nem foi comentada por ele) simplesmente não achava nada, mesmo sendo, digamos, claramente sobre "boleto".
Desenho final: sem vínculo exato, GET /api/demanda consulta o título + descrição reais da
demanda no Azure (lerWorkItem) e procura, nesse texto, algum termo de MODULOS_PAINEL (a mesma
lista curada dos atalhos da barra lateral "Módulos" — reaproveitada, não reinventada). Achando,
sugere os specs daquele módulo, deixando bem claro na UI que é sugestão ("🔍 Nenhum vínculo
direto... mas achei N cenário(s)"), nunca confundindo com o vínculo confirmado do Cenário 1.
Rodar esses specs usa o caminho normal do resto da aba (/api/rodar-spec//api/rodar-varios,
terminal aberto, sem esperar resultado) — diferente do fluxo bloqueante do vínculo exato, porque
aqui não tem 1 teste específico pra confirmar passou/reprovou, só specs relacionados.
Achado ao testar com um caso real: Bug #26951 (mesma demanda já usada pra outras
investigações desta sessão) não tem vínculo no painel, mas sua descrição real cita "conta boleto
do condomínio" — bateu com o termo boleto e sugeriu 8 specs. Confirma que o fallback funciona
sem precisar inventar dado de teste.
1 detalhe técnico que precisou de atenção: o termo curado é sempre sem acento (condominio,
não condomínio) porque casa contra NOME DE ARQUIVO (sempre sem acento); mas o texto da demanda
é português normal, COM acento ("Condomínio"). Comparar direto nunca bateria. removerAcentos()
(NFD + descarta diacrítico) normaliza o texto da demanda antes de comparar — confirmado com teste
real ("Condomínio".toLowerCase() não contém "condominio" sem essa normalização).
Pendente de ação humana: nenhuma — funcionalidade pronta pra uso.
2026-09-03 — Painel: "Demanda em X, teste ainda falha" (badge) e "Rodar por demanda do Azure DevOps" (aba Execução) — 2 cenários desenhados em conversa, implementados
Categoria: Melhoria no painel (2 cenários desenhados junto com o usuário numa conversa inteira antes de codar) — nenhum dos dois publica/altera nada no Azure, só leitura (GET) e execução local.
Cenário 1 — badge de estado ao vivo da demanda (aba Azure DevOps): pra cada falha pendente já
vinculada a um work item, o painel agora consulta o estado ATUAL dele na API (não fica só no que
foi salvo na hora do vínculo) e mostra "⚠️ Demanda em '{estado}' — teste ainda falha" quando esse
estado já passou do desenvolvimento — sinal de que a correção pode não ter chegado neste ambiente,
ou é regressão. Estados reais confirmados via API antes de definir o que conta como "aprovado"
(nunca no chute): Bug/User Story vão New → Refinement → Development → Review → Testing →
Validation → Deployment → Closed; Task vai New → Active → Testing → Closed — Testing existe nos
2 fluxos numa posição equivalente, por isso o mesmo conjunto (Testing/Validation/Deployment/
Closed) serve pros dois tipos.
Cenário 2 — "Rodar por demanda do Azure DevOps" (aba Execução): campo novo pra digitar um
número de demanda; o painel acha (na tabela de Work Items vinculados) qual(is) teste(s)/spec(s)
estão ligados a ela, mostra a lista, e um botão roda de verdade e mostra ✅/❌ por teste na mesma
tela — diferente do resto do painel (que só abre um terminal e segue), essa rota espera o
cypress run terminar de verdade antes de responder.
Pré-requisito que precisou de esquema novo: a tabela "Work Items do Azure DevOps vinculados"
só guardava o título do teste, não o arquivo — sem saber o .cy.js, não dava pra montar o
--spec. Adicionada coluna Spec (preenchida a partir de agora automaticamente; as 4 linhas já
existentes foram preenchidas na mão, confirmando cada caminho por grep real antes de escrever —
nunca no chute).
2 bugs reais encontrados testando ao vivo (não só no papel):
cypress-mochawesome-reporterapaga a pasta.jsons/(o dado bruto por teste) depois de mesclar no relatório HTML final, por padrão — o painel precisava ler exatamente esse dado logo depois de rodar.removeJsonsFolderAfterMerge: falseemcypress.config.jsresolve (ooverwrite: trueque já existia continua limpando tudo no INÍCIO de cadacypress run, então não acumula lixo entre execuções mesmo mantendo isso).escapeHtml()(função já existente no painel) escapa</>/&mas não escapa aspas duplas — correto pra texto solto, mas quebra um atributo HTML tipodata-teste="..."no meio quando o título do teste contém"(ex.: o próprio teste do Task #26971 tem"Tipo de geração de boleto"no título) — o atributo cortava ali e virava lixo de atributos soltos. Corrigido evitando esse padrão inteiro: a lista de testes encontrados agora usadata-index(um número, sem risco de quebrar atributo) e casa o resultado por comparação em JS puro, nunca por um atributo HTML com texto arbitrário dentro.
Efeito colateral da verificação: rodar contaDigitalBoletoUx.cy.js de verdade 2 vezes (pra
testar o Cenário 2 contra um caso real, Task #26971 — a 1ª tentativa ficou presa no bug do
.jsons/ acima, por isso rodei de novo já com o fix) capturou 2 recorrências em
docs/falhas-pendentes.md, ambas de causas já conhecidas: o mesmo bug de UX confirmado (combobox
centralizado) na 1ª rodada, e o mesmo cold-boot de sessão já documentado ("Investigação funda do
cold-boot headless", mais abaixo) na 2ª — removidas depois de confirmar que nenhuma é causa nova.
Pendente de ação humana: nenhuma — funcionalidade pronta pra uso.
2026-09-03 — Correção: Bug #26951 NÃO cobre "Replicar decurso em subcontas" — só "Decurso personalizado" (desfeito o vínculo da entrada anterior)
Categoria: Correção de entendimento (desfaz a entrada logo abaixo) — o usuário voltou e corrigiu: o Bug #26951 trata só o campo "Decurso personalizado" — "Replicar decurso em subcontas" não foi e não será tratado nessa demanda, apesar da Obs do work item citar "subconta" (essa observação, na prática, não se traduz em correção desse 2º campo).
Causa confirmada: informação direta do usuário, que acompanha a demanda no Azure DevOps — mais confiável que inferir a partir só do texto da Obs do work item (que foi o que motivou a entrada anterior a linkar os 2 campos).
Correção aplicada: desfeito tudo que a entrada anterior tinha adicionado:
condominioConfiguracaoBoleto.cy.js: título doit()e JSDoc de "Replicar decurso em subcontas" voltaram a dizer "ainda sem work item aberto" (sem citar #26951).docs/regras-de-negocio.md: mesma reversão.- Tabela "Work Items do Azure DevOps vinculados" (acima): removida a linha que linkava esse teste ao Bug #26951 — o campo continua sem work item registrado.
Pendente de ação humana: abrir uma demanda própria pra "Replicar decurso em subcontas" quando fizer sentido (ainda não existe nenhuma) — e, quando existir, aí sim vincular de verdade.
2026-09-03 — "Replicar decurso em subcontas" confirmado tratado no Bug #26951 (mesma demanda que cobre "Decurso personalizado")
⚠️ Corrigido logo acima (mesmo dia) — o usuário esclareceu que o Bug #26951 trata só "Decurso personalizado", não "Replicar decurso em subcontas". O vínculo descrito nesta entrada foi desfeito; fica registrada só como histórico de como o engano aconteceu.
Categoria: Referência de rastreio (não investigação nova) — usuário confirmou que a falha de "Replicar decurso em subcontas" já está sendo tratada no Bug #26951 ("[Homol] Não permitindo personalizar decurso de prazo", estado "Development", time de produto).
Confirmado consultando o work item real (npm run azure:ler -- 26951, não no chute): a
descrição cobre explicitamente os 2 campos — o corpo principal é sobre "Decurso personalizado"
(mesmo comportamento do Bug #26954), e a observação final do próprio ticket já diz "as regras de
dependência de pool e subconta de subconta devem ser respeitadas e validadas" — ou seja, #26951 é
a demanda "guarda-chuva" que cobre ambos os campos da Configuração de Boleto, não só o primeiro.
Correção aplicada: referência ao Bug #26951 adicionada em
condominioConfiguracaoBoleto.cy.js
(JSDoc + título do it()) e em docs/regras-de-negocio.md. Linha nova na tabela "Work Items do
Azure DevOps vinculados" acima (Ação "—": o vínculo foi feito manualmente, referenciando um work
item que já existia antes, não criado/comentado pelo painel local desta vez).
Pendente de ação humana: nenhuma nova — a demanda já está em desenvolvimento pelo time de produto; a validação de ponta a ponta deste lado (achado no Bug #26954, mais abaixo) continua pendente do jeito já descrito.
2026-09-03 — Investigação funda do cold-boot headless: não é exceção JS, não é lentidão que mais timeout resolve — app trava sem disparar nem a 1ª chamada de API
Categoria: Investigação de instabilidade (sem correção de código — ver "Pendente de ação
humana") — usuário pediu diretamente pra resolver a instabilidade "só em cypress run, nunca em
cypress open" que várias entradas anteriores já vinham documentando como "lentidão variável do
Electron headless" (cy.session().validate(), timeout de 45s em cy.login(),
cypress/support/commands.js). Investiguei a fundo em vez de só aceitar como conhecida de novo.
O que foi feito: 3 rodadas de instrumentação temporária (specs descartáveis, nunca commitados):
- Capturei uma falha real (screenshot) durante a investigação: a SPA carrega o SHELL (header
"PartnerBank", avatar, rodapé "Copyright Partner Bank"), mas a área de conteúdo fica 100%
em branco — sem menu, sem dashboard. A aba de rede mostra só 2 chamadas:
POST /cdn-cgi/rum(beacon do Cloudflare, não é da aplicação) — nenhuma chamada real da aplicação (/auth,/adm/usuarios/atual) chegou a disparar. - Instrumentei
Cypress.on('uncaught:exception', ...),window.onerrorewindow.onunhandledrejectionpra capturar o que o handler global emcypress/support/e2e.js(Cypress.on('uncaught:exception', () => false)) normalmente esconde. Reproduzi a falha de novo (mesmo erro de timeout, 45s) — zero exceções, zero erros de window, zero promises rejeitadas capturadas. A aplicação trava sem lançar nada detectável — não é um bug de JS que dá pra "pegar" e corrigir no lado do teste. - Bumped
cy.login()'s timeout pra 150000ms temporariamente (revertido depois) pra descobrir se era só "mais lento que 45s" (resolveria com mais tempo) ou "trava de vez" (mais tempo não ajuda). Resultado: numa rodada, a duração total reportada (~2m30s) bateu exatamente com "1ª tentativa travou os 150s inteiros, 2ª tentativa (retry automático já configurado emcypress.config.js,retries.runMode: 1) resolveu em ~5s" — ou seja, o retry que já existe frequentemente mascara o travamento, e quando NÃO mascara (2 tentativas travando em sequência, como já visto numa rodada anterior desta mesma investigação), o teste falha de vez, não importa quanto timeout se dê.
Causa confirmada: ainda não é possível afirmar a causa raiz exata — o que dá pra afirmar com confiança (evidência real, não suposição) é o que ela NÃO é:
- Não é uma exceção JS lançada pela aplicação (nada capturado nos 3 listeners).
- Não é "só lentidão" que mais timeout resolve — quando trava, trava de verdade (nenhuma chamada de API chega a disparar, nem depois de 150s).
- Não é algo que o retry já configurado sempre resolve — às vezes falha nas 2 tentativas.
A evidência (shell carrega, conteúdo nunca monta, nenhuma chamada de API dispara) aponta pra algo
travando MUITO cedo no próprio bootstrap client-side da SPA — antes dela sequer tentar chamar
/auth — de um jeito que não lança erro nenhum capturável. Isso é consistente com o Electron
headless (sem aceleração de GPU/compositor) se comportando diferente do Chrome/headed em alguma
dependência de renderização/timing que a aplicação usa no próprio bootstrap (ex.: algo baseado em
requestAnimationFrame, IntersectionObserver/ResizeObserver, ou um chunk lazy que falha ao
carregar sem lançar uma promise rejeitada capturável) — mas isso é hipótese, não confirmado; só
o time de produto, com acesso ao código-fonte da SPA, consegue confirmar de verdade.
Correção aplicada: nenhuma — commands.js foi revertido pro timeout original (45000ms) depois
do experimento; bumping não resolve nada, só atrasa a hora de falhar. Não implementei um retry
adicional client-side (ex.: reload automático dentro de validate()) porque a evidência mostra
que o retry que JÁ EXISTE (cypress.config.js, 1 tentativa extra) às vezes falha 2x seguidas — um
retry a mais no mesmo padrão provavelmente só adiaria a mesma falha, sem resolver a causa raiz.
Pendente de ação humana: isso parece um problema de estabilidade do carregamento inicial da SPA especificamente no ambiente headless (Electron sem GPU) — vale levar pro time de produto como um possível problema de robustez do próprio bootstrap da aplicação (silencioso, sem erro capturável), não algo que o lado de teste consiga corrigir sozinho. Enquanto isso, o comportamento observado (falha ocasional, às vezes recuperada pelo retry já configurado) continua sendo a realidade da suíte rodando headless.
2026-09-03 — Corrigido de vez: "Replicar decurso em subcontas" — o teste nunca criava subconta de verdade, e o campo é da Administradora, não do Condomínio
Categoria: Correção de setup de teste (não achado de bug novo) — usuário revisou a tela real
(print da aba Subcontas da Administradora usada no teste) e apontou 2 problemas na entrada
anterior ("Bug #26954 corrigido pelo dev", mais abaixo): (1) o before() nunca criava uma
subconta de verdade — só 1 Administradora + 1 Condomínio, sem par nenhum; a investigação anterior
que criou uma subconta foi só num script temporário, nunca chegou no spec commitado; (2)
"Replicar decurso em subcontas" precisa ser testado na Configuração da Administradora, não do
Condomínio — é ela replicando o próprio decurso pros Condomínios (subcontas) dela.
Causa confirmada: ambas as correções descritas pelo usuário fazem sentido e foram aplicadas.
Correção aplicada em condominioConfiguracaoBoleto.cy.js:
before()agora, depois de criar Administradora+Condomínio+seed de config (fluxo de sempre), também clica em "Habilitar Subconta" de verdade (ContaDigitalBoletoPage.habilitarSubconta(), irreversível — mesma cautela desubconta.cy.js) e cria um 2º Condomínio com o MESMO CNPJ na mesma Administradora — exatamente o fluxo desubconta.cy.js, só que dentro deste spec (arquivo autossuficiente, sem importar desubconta.cy.js, mesma convenção do resto do projeto).- O
it()de "Replicar decurso em subcontas" agora navega explicitamente praContaDigitalBoletoPage.goToConfiguracoes(guidAdministradora), não maisgoToConfiguracoes(guidCondominio)como os outrosit()s do describe. CLAUDE.md("Cuidado com dados reais") ganhou a entrada decondominioConfiguracaoBoleto.cy.jscomo spec que também faz "Habilitar Subconta" irreversível (não estava listado lá antes).docs/regras-de-negocio.mdatualizado com a regra corrigida (campo da Administradora) e o setup correto do teste.
Resultado (rodado contra o ambiente real, 03/09/2026): os outros 7 it()s do describe
continuam verdes. "Replicar decurso em subcontas" continua vermelho mesmo com a subconta
criada e confirmada de verdade (subcontaDaSubconta: true via API) — mesma suspeita já registrada
na entrada anterior: a subconta nasce em status AVALIACAO, não ATIVA (mesmo problema de
ambiente do VS não aprovando conta nova), e isso pode estar impedindo a persistência. Ainda não dá
pra confirmar se é essa a causa final ou se falta mais alguma coisa — decisão do usuário
(reafirmada): deixar vermelho por enquanto.
Pendente de ação humana: mesma de antes — decidir como validar de ponta a ponta apesar do ambiente não ativar subcontas novas na hora.
2026-09-03 — Corrigido: relatório HTML (mochawesome) parava de ser gerado desde que o hook do Dashboard foi adicionado — 2 on('after:run', ...) se sobrescreviam
Categoria: Bug real na própria suíte (regressão introduzida nesta mesma sessão) — usuário notou que a aba Relatório do painel não mostrava a falha de "Replicar decurso em subcontas" (ver entrada logo abaixo), apesar dela ter falhado de verdade na execução.
Causa confirmada: cypress-mochawesome-reporter/plugin registra o próprio
on('after:run', afterRunHook) dentro de setupNodeEvents (mescla os .jsons de cada spec e
gera o HTML final em mochawesome-report/index.html). Ao construir o hook do Dashboard mais
cedo nesta sessão, um SEGUNDO on('after:run', ...) foi registrado logo depois — e o Cypress só
guarda 1 handler por evento: o segundo on() substitui o primeiro em vez de somar. Isso
significa que, desde que o Dashboard foi implementado, mochawesome-report/index.html parava de
ser gerado em toda execução (cypress run) — só o .jsons/mochawesome.json bruto continuava
existindo, sem nenhum erro visível no terminal ([mochawesome] Report JSON saved to ... continua
aparecendo normalmente, mascarando o problema). Confirmado inspecionando
node_modules/cypress-mochawesome-reporter/plugin.js diretamente (não no chute) e reproduzindo:
rodar um spec e checar que mochawesome-report/ só tinha a pasta .jsons, sem index.html.
Correção aplicada: cypress.config.js — em vez de require('cypress-mochawesome-reporter/plugin')(on)
direto, intercepta a chamada com um on "de mentira" que captura o handler de after:run que o
plugin registraria (repassando todo o resto pro on real, sem mudar nada). O on('after:run', ...)
do Dashboard agora chama esse handler capturado PRIMEIRO (await afterRunDoMochawesome(results)),
garantindo o relatório HTML sempre, e só depois roda a lógica do Dashboard. Testado rodando
login.cy.js do zero (removendo mochawesome-report/ antes): HTML report successfully created! voltou a aparecer, mochawesome-report/index.html existe de novo, e a linha do
Dashboard continuou sendo gravada normalmente — os dois convivem agora.
Pendente de ação humana: nenhuma — mas fica registrado como alerta pra quem for mexer em
setupNodeEvents de novo: nunca chamar on('after:run', ...) (ou qualquer evento que um
plugin de terceiros já registre) sem antes checar se algo já está usando aquele evento — sempre
compor os handlers, nunca simplesmente adicionar mais um on() pro mesmo evento.
2026-09-03 — Bug #26954 ("Decurso personalizado") corrigido pelo dev: teste atualizado pra validar o comportamento correto
Categoria: Confirmação de correção (não é achado novo) — o Bug #26954, aberto pra "Decurso personalizado" (aceita "Sim" mas nunca persiste), era bug real do Core, e já foi corrigido pelo dev (confirmado pelo usuário: o campo "Dias para decurso de prazo" não estava liberando/ aparecendo na tela quando o combo ia pra "Sim" — o dev ajustou isso, e é por causa desse ajuste que hoje o campo aparece e a persistência funciona quando preenchido). Esta entrada existe pra atualizar o teste e a documentação pro comportamento CORRETO pós-correção — não pra questionar o bug original.
Contexto: o usuário também trouxe a regra real de "Replicar decurso em subcontas": só mantém "Sim" se o registro tiver pelo menos 1 subconta de verdade — pediu pra incluir o fluxo de criar subconta no teste antes de testar esse campo.
Causa confirmada (Decurso personalizado): comportamento pós-correção confirmado ao vivo.
Toggle "Decurso personalizado" pra "Sim" agora revela corretamente diasDecursoPrazo (número,
Mui-readOnly/oculto quando o combo é "Não"). Salvando "Sim" sem preencher esse campo, o
backend aceita a chamada (200) mas mantém "Não" internamente — esse é o comportamento correto
esperado (é validação, não teria por que salvar "Sim" sem dia nenhum definido). Preenchendo
(ex.: "5"), "Sim" persiste normalmente junto com o valor. Confirmado com um teste dedicado contra
Administradora/Condomínio reais, isolando o campo (2 cenários: sem dias / com dias).
Causa confirmada (Replicar decurso em subcontas): PARCIAL, ainda pendente. Tentei validar a
regra completa de ponta a ponta — criar uma Administradora+Condomínio, habilitar subconta nele
(ContaDigitalBoletoPage.habilitarSubconta(), irreversível, mesma cautela de subconta.cy.js),
criar um 2º Condomínio com o mesmo CNPJ (vira subconta do 1º) e testar "Replicar decurso em
subcontas" — tanto no Condomínio matriz quanto na Administradora, com e sem "Decurso
personalizado" configurado junto. Em todos os cenários, reverteu "Não", mesmo com a subconta
de fato existindo e aparecendo em GET /adm/contas-digitais?guidContaMatriz={guidAdministradora}
(subcontaDaSubconta: true). Causa provável: a subconta recém-criada nasce em status
AVALIACAO, não ATIVA — mesmo problema de ambiente já documentado em "Causa raiz de 'Conta
digital não está ativa'" (mais abaixo neste arquivo): só o VS aprovando (ou reinício da aplicação
em HML) resolve, não é algo que o teste force sozinho. Não deu pra confirmar se "ter uma
subconta" (mesmo em avaliação) já deveria bastar, ou se precisa estar ATIVA — inconclusivo por
causa do ambiente, não por falta de tentativa.
Correção aplicada:
condominioConfiguracaoBoleto.cy.js: oit()de "Decurso personalizado" virou 2 (sem dias / com dias preenchidos, validando o comportamento correto pós-correção do dev), ambos verdes contra o ambiente real.docs/regras-de-negocio.mdatualizado: "Decurso personalizado" documentado com o comportamento correto (Sim exige dias preenchidos); "Replicar decurso em subcontas" documentado com a regra descrita pelo usuário e a ressalva de validação pendente por causa do ambiente.cypress/pages/ContaDigitalBoletoPage.js: JSDoc atualizado.it()de "Replicar decurso em subcontas" continua vermelho de propósito (não mexi na asserção, decisão do usuário) — documentando o comportamento atual, até validar de forma determinística.
Bug #26954 no Azure DevOps: confirmado — era bug real, já corrigido pelo dev. Nenhuma ação adicional no ticket (o usuário não pediu pra comentar nem fechar).
Pendente de ação humana:
- Decidir como validar "Replicar decurso em subcontas" de ponta a ponta apesar do ambiente não
ativar subcontas novas na hora — ex.: reaproveitar um par Condomínio+subconta já ativo e
existente (mesmo padrão de
GUID_CONDOMINIO_FALLBACK_ATIVOemboletoRegressao.cy.js), se existir um assim no ambiente. Por ora, decisão do usuário foi deixar vermelho.
2026-09-03 — Triagem de lote: execução completa da suíte (12 recorrências), todas de causas já conhecidas
Categoria: Triagem em lote (não investigação nova) — 12 entradas acumuladas em
docs/falhas-pendentes.md (14:10:13–14:22:02), de uma execução da suíte inteira pra validar o
painel. Todas recorrências de achados já confirmados, nenhuma causa nova:
- Cross-tenant em Entidade (
contaDigitalCrossTenant.cy.js, 2x: Buscar Boletos, Criar Condomínio) — mesmo achado CONFIRMADO em 02/09. - Cancelamento cross-tenant (
boletoCancelamentoCrossTenant.cy.js) — mesmo tracker de posse não validada, CONFIRMADO desde 28/08 (BOLA/IDOR em "Cancelar Boleto"). - Job sem autenticação (
autenticacaoObrigatoria.cy.js, 2x: Recalcular Flag de Emissão com/sem AuthCG) — mesmo achado CONFIRMADO em 01/09. - UX combobox centralizado (
contaDigitalBoletoUx.cy.js, 2x: "Nova Movimentação", "Tipo de geração de boleto") — recorrência dos 2 campos já confirmados em 02/09. - Configuração de Boleto (
condominioConfiguracaoBoleto.cy.js, 2x: "Decurso personalizado", "Replicar decurso em subcontas") — recorrência dos 2 bugs já confirmados (Bug #26954 cobre o 1º; o 2º ainda sem work item aberto). - GUID de Administradora em Gerar Boleto (
boletoRegressao.cy.js,boletoGuidExistenteRegressao.cy.js) — mesmo achado, Task 25706. - Timeout de sessão pós-login (
aplicacaoSanity.cy.js, 45s) — mesmo cold-boot do Electron headless já documentado várias vezes.
Causa confirmada: nenhuma causa nova — todas já documentadas em entradas anteriores.
Correção aplicada: nenhuma.
Pendente de ação humana: os de sempre — nenhum item novo além do que já está em aberto (Task 25706; Bug #26954 + abrir ticket pro campo "Replicar decurso em subcontas"; correção dos endpoints cross-tenant e do job sem auth; correção dos 2 comboboxes de UX).
2026-09-03 — Triagem: mais recorrências (GUID Administradora x2, Decurso/Replicar x2), validando o novo Dashboard do painel
Categoria: Triagem em lote (não investigação nova) — 4 entradas acumuladas em
docs/falhas-pendentes.md, todas recorrências de achados já confirmados. Origem diferente do
normal: rodei cypress run de propósito (login.cy.js, boletoGuidExistenteRegressao.cy.js) pra
validar de verdade o hook after:run novo (docs/dashboard-execucoes.md) que alimenta a aba
Dashboard do painel local — as falhas capturadas são efeito colateral esperado dessa
validação, não achado novo.
- GUID de Administradora em Gerar Boleto (
boletoGuidExistenteRegressao.cy.js, 2x) — mesmo achado, Task 25706. - Configuração de Boleto ("Decurso personalizado", "Replicar decurso em subcontas") — recorrência dos 2 bugs já confirmados.
Causa confirmada: nenhuma causa nova.
Correção aplicada: nenhuma.
Pendente de ação humana: os de sempre (Task 25706 no Azure; correção dos 2 campos de Configuração de Boleto).
2026-09-03 — Triagem de lote: mais recorrências (GUID Administradora, UX combobox, Decurso/Replicar), todas de causas já conhecidas
Categoria: Triagem em lote (não investigação nova) — 6 entradas acumuladas em
docs/falhas-pendentes.md (12:41–12:43), todas recorrências de achados já confirmados:
- GUID de Administradora em Gerar Boleto (
boletoRegressao.cy.js,boletoGuidExistenteRegressao.cy.js) — mesmo achado, Task 25706. A partir de agora esses 2 testes já aparecem automaticamente com o selo "🔗 Já reportado" no painel local (ver tabela "Work Items do Azure DevOps vinculados" acima), seedada com esse vínculo nesta mesma sessão. - UX combobox centralizado ("Nova Movimentação", "Tipo de geração de boleto") — recorrência dos 2 campos já confirmados em 02/09.
- Configuração de Boleto ("Decurso personalizado", "Replicar decurso em subcontas") —
recorrência dos 2 bugs já confirmados na entrada de
condominioConfiguracaoBoleto.cy.jsacima.
Causa confirmada: nenhuma causa nova — todas já documentadas em entradas anteriores.
Correção aplicada: nenhuma (nada novo a corrigir).
Pendente de ação humana: os de sempre (correção do produto pro GUID de Administradora, Task 25706; correção do alinhamento dos 2 comboboxes de UX; correção dos 2 campos de Configuração de Boleto que não persistem).
2026-09-03 — Triagem: mais 2 recorrências do GUID de Administradora em Gerar Boleto (já confirmado, Task 25706)
Categoria: Triagem pontual (não investigação nova) — 2 recorrências de
boletoGuidExistenteRegressao.cy.js (10:19:27 e 10:40:18) capturadas em
docs/falhas-pendentes.md batem com o achado já confirmado e rastreado no Azure DevOps (Task
25706): guid de Administradora no lugar de Condomínio em Gerar Boleto ainda é aceito — "vermelho
de propósito" até o produto corrigir.
Causa confirmada: nenhuma novidade — mesmo achado já documentado extensivamente neste arquivo e comentado na Task 25706.
Correção aplicada: nenhuma (nada novo a corrigir).
Pendente de ação humana: o de sempre — correção do produto pro GUID de Administradora (Task 25706 no Azure DevOps).
2026-09-03 — Novo spec condominioConfiguracaoBoleto.cy.js: 2 bugs confirmados de persistência na Configuração de Boleto (Decurso personalizado, Replicar decurso em subcontas)
Categoria: Achado de bug real, confirmado — descoberto ao construir um spec novo pra "Core > Contas Digitais Boleto > Condomínio > Configurações" (pedido do usuário), não uma investigação de falha reportada.
Contexto: o usuário já sabia que "Decurso de prazo" (campo "Decurso personalizado" na tela) não salvava como "Sim" — pediu pra validar a persistência de TODOS os campos editáveis da Configuração de Boleto após clicar em "Editar". Confirmado ao vivo (sessão logada, sem 2FA em HML), criando 1 Administradora + 1 Condomínio reais via API e editando campo por campo pela tela, com reload real entre cada edição e a checagem (nunca no chute).
Resultado, campo por campo:
| Campo | Resultado |
|---|---|
| Conta Geradora | ✅ persiste |
| Conta geradora fixa | ✅ persiste (Não→Sim é aceito; ver regra de "não pode combinar com troca de Conta Geradora" em docs/regras-de-negocio.md) |
| Taxa Serviço | ✅ persiste |
| Taxa Boleto | ✅ persiste |
| Decurso personalizado | 🔴 aceita "Sim" (200, toast de sucesso), mas volta pra "Não" ao recarregar — confirma o que o usuário já suspeitava |
| Replicar decurso em subcontas | 🔴 mesmo bug — achado NOVO, não mencionado pelo usuário |
Causa confirmada: os 2 campos aceitam a edição sem erro nenhum (a API responde 200, "Dados atualizados com sucesso"), mas o valor persistido de verdade nunca muda — comportamento do backend, não da tela nem do teste (reproduzido isolando cada campo, sem misturar com a troca de Conta Geradora, que tem sua própria regra de rejeição documentada à parte).
Novo spec: cypress/e2e/casos_de_teste/com_dados/condominioConfiguracaoBoleto.cy.js
— cria Administradora + Condomínio reais no before() (mesmo padrão de boletoRegressao.cy.js),
1 it() por campo, com reload real entre editar e checar. Os 2 it()s do Decurso ficam
vermelhos de propósito até o produto corrigir — mesmo padrão de boletoRegressao.cy.js pra
achado confirmado ainda sem correção.
Correção aplicada: nenhuma (é achado de bug do produto, não do teste) — regra nova
documentada em docs/regras-de-negocio.md (seção "Configuração de Boleto do
Condomínio/Administradora").
Pendente de ação humana: reportar os 2 campos (Decurso personalizado, Replicar decurso em subcontas) pro time do produto — nenhum work item aberto ainda no Azure DevOps pra este achado.
2026-09-03 — subconta.cy.js: mais 1 recorrência de "conta não está ativa" → cascata (VS ainda não aprovando)
Categoria: Instabilidade de ambiente já confirmada (não é bug do teste nem do produto) — mesmo padrão documentado desde 24/08/2026 (causa raiz: VS não aprova a conta digital recém-criada a tempo; só volta reiniciando a aplicação manualmente em HML), e explicitamente já é o comportamento esperado do design atual do teste (25/08/2026: "1 tentativa, sem retry").
Erro: "quando a conta está ativa, habilita a subconta..." recebeu 400 "Conta Digital [...] não está ativa" ao clicar em "Habilitar Subconta" no before(); o it() seguinte ("criar
outro Condomínio com o mesmo CNPJ vira subconta da subconta") reprovou em cascata como
consequência direta (setup não completou).
Causa confirmada: nenhuma novidade — mesma instabilidade já registrada dezenas de vezes neste arquivo pra este spec.
Correção aplicada: nenhuma (nada a corrigir).
Pendente de ação humana: nenhum — comportamento esperado do design atual.
2026-09-03 — Triagem de lote: recorrências de 01–03/09, todas de causas já conhecidas
Categoria: Triagem em lote (não investigação nova) — as ~30 entradas acumuladas em
docs/falhas-pendentes.md entre 01/09 17:14 e 03/09 09:18 batem com causas já confirmadas antes:
- Cross-tenant (Buscar Boletos, Criar Condomínio, Cancelamento) — recorrências do achado já registrado na entrada de 02/09 logo abaixo. Nenhuma novidade.
- GUID de Administradora em Gerar Boleto (
boletoRegressao.cy.js,boletoGuidExistenteRegressao.cy.js) — "vermelho de propósito", segue sem correção do produto. Mesmo achado agora também rastreado no Azure DevOps (Task 25706) — verdocs/integracao-azure-devops.md. Comentário postado na Task 25706 em 02/09 com essa evidência. - Job sem autenticação (
autenticacaoObrigatoria.cy.js) — recorrência do 🔴 já confirmado no backlog de segurança. - UX combobox (
contaDigitalBoletoUx.cy.js) — recorrência dos 2 campos já confirmados em 02/09. - Cold-boot de sessão (
performance.cy.js,aplicacaoSanity.cy.js) — mesma instabilidade de Electron headless já documentada várias vezes neste arquivo. - "Limpar Seleção" —
expected 1 to equal 6445(contaCorrente.cy.js) — mesmo padrão já rastreado como "achado novo, não investigado ainda" (entrada de 31/08/2026), ainda pendente de confirmação definitiva.
Causa confirmada: nenhuma causa nova — todas já documentadas em entradas anteriores deste arquivo.
Correção aplicada: nenhuma (nada novo a corrigir).
Pendente de ação humana: os itens já pendentes de sempre — correção do produto pro GUID de
Administradora (Task 25706 no Azure), confirmação final do "Limpar Seleção" (contaCorrente.cy.js).
docs/falhas-pendentes.md foi limpo (voltou a ficar só com o cabeçalho) depois deste registro.
2026-09-02 — ⚠️ CONFIRMADO: mais 2 endpoints de Entidade aceitam cross-tenant (Buscar Boletos, Criar Condomínio) — Criar Conta Corrente ADM está protegido
Categoria: Achado de segurança real, confirmado — extensão direta dos 2 já confirmados
(Gerar Boleto, Cancelar Boleto). Item 🟠 Alta de docs/estrategia-de-testes.md (backlog de
segurança), até então "não escrito ainda".
Novo spec: cypress/e2e/casos_de_teste/com_dados/contaDigitalCrossTenant.cy.js
— mesma arquitetura de boletoCancelamentoCrossTenant.cy.js (2 Administradoras reais criadas no
before(), Administradora B sem relação nenhuma tenta agir sobre dado de A), sem a complexidade de
gerar/esperar boleto (nenhum dos 3 endpoints precisa disso).
Resultado, rodando de verdade:
| Endpoint | Resultado | Status |
|---|---|---|
GET .../contaDigital/{guid}/boletos (Buscar Boletos) |
🔴 Vulnerável — Administradora B consultou boletos do Condomínio de A (200, lista vazia só porque A não tinha boleto nesta rodada — o ponto é que não rejeitou) | Confirmado |
POST /contaDigital/{guid} (Criar Condomínio) |
🔴 Vulnerável — Administradora B criou um Condomínio de verdade dentro da árvore de A (200, parentId = guid de A, código real c90aa690-17a5-491f-bf8e-56c91b73a334, razão social CONDINTRUSO_thmpy05j) |
Confirmado — criou dado real como efeito colateral do próprio achado |
POST .../contas-digitais/{guid}/contas-correntes (Criar Conta Corrente ADM) |
✅ Protegido — rejeitou a tentativa de B | Confirmado seguro |
Efeito colateral real: a investigação do 2º item, ao confirmar a vulnerabilidade, criou um
Condomínio real e permanente (CONDINTRUSO_thmpy05j, guid c90aa690-17a5-491f-bf8e-56c91b73a334)
dentro da Administradora A de teste — sem endpoint de exclusão usado neste projeto pra desfazer
(mesma limitação já documentada pra Administradora/Condomínio/Subconta).
Padrão que já emerge, com 3 endpoints confirmados vulneráveis + 1 protegido: os 3 vulneráveis (Gerar Boleto, Cancelar Boleto, Buscar Boletos, Criar Condomínio — 4, não 3) são todos endpoints que operam dentro de uma árvore já existente (Condomínio/boleto de outra Administradora, ou criar filho dentro da árvore de outra). O único protegido (Criar Conta Corrente ADM) é estruturalmente parecido — vale investigar por que esse difere, pode ser pista da causa raiz real.
Contexto importante, esclarecido pelo usuário depois deste achado (mesma data): o Core em si é
uma ferramenta interna, usada por funcionário da Partner — a tela de backoffice já mostra
QUALQUER Administradora/Condomínio pra quem tem acesso, por design (não é bug, é a ferramenta
funcionando certo). O achado acima é sobre outra coisa: o token AuthCG (Entidade, o que
credenciarAdministradora() gera) — a dúvida em aberto é quem realmente segura esse token no
mundo real. O cliente final (a empresa Administradora/Condomínio) acessa via um ERP, sistema
separado — não confirmado se esse ERP usa o AuthCG pra falar com o Core, ou se esse token é
100% interno (só sistema da Partner, nunca chega no cliente/ERP). Sem essa confirmação, a
gravidade real não dá pra cravar: se o token nunca sai do lado interno, isso é falta de
camada de proteção (real, vale corrigir, mas sem exploração ativa por terceiro hoje); se o ERP
usa esse token, é exposição de dado entre clientes reais, igual eu tinha assumido antes. O achado
técnico em si (a API não confere posse) continua confirmado do mesmo jeito nos 2 casos — só a
urgência/enquadramento muda.
Pendente de ação humana: reportar os 2 novos endpoints (Buscar Boletos, Criar Condomínio) pro
time do Core, junto com os 2 já reportados — mesma família de causa, faz sentido corrigir junto.
Reportar também o dado real órfão criado (CONDINTRUSO_thmpy05j) pra quem tiver acesso de
exclusão. Pergunta adicional pro time, que decide a gravidade real: o token AuthCG de
Administradora/Condomínio chega a ser usado por algum ERP externo, ou é estritamente interno à
Partner?
2026-09-02 — Teste visual construído, testado nos 2 sentidos, e depois removido: decisão do usuário de não seguir com acessibilidade nem teste visual
Categoria: Não é falha — é decisão de escopo do usuário, registrada pra ficar rastreável.
O que foi construído e testado de verdade, antes da decisão: cypress-visual-regression@5.3.0
(a versão mais nova exige Cypress ≥15, ficaria incompatível com a 13.17.0 deste projeto — mesma
razão já documentada pra adiar essa atualização). POC na tela de Login (a mais estática, sem dado
real): baseline gerado, comparação limpa passou, e — pra provar que o diff funciona de verdade —
injetei uma borda vermelha de propósito no campo de usuário: o teste reprovou e a imagem de diff
destacou exatamente o pixel alterado. Achado à parte: o diff visual sempre destaca todo pixel
diferente (inclusive ruído sub-pixel de sombra/borda, mesmo padrão já visto na largura de UX) —
o threshold de tolerância do plugin já filtrou isso corretamente (só reprovou com a mudança real).
Decisão do usuário, depois de ver funcionando: não seguir com teste visual nem com
acessibilidade (que já estava em produção desde antes, com 1 tela auditada e 3 achados reais —
"Nova Movimentação" e "Tipo de geração de boleto" centralizados, mais os 3 achados de cypress-axe
no Dashboard). Pedido explícito: remover todo o código/estrutura dos 2, não só a menção nos docs.
Removido de verdade: cypress/e2e/acessibilidade/, cypress/e2e/visual/, cypress/snapshots/,
cy.checarAcessibilidade() (commands.js), configureVisualRegression/addCompareSnapshotCommand
(cypress.config.js/support/e2e.js), pacotes cypress-axe/axe-core/cypress-visual-regression
(package.json + npm uninstall), scripts cy:run:acessibilidade/cy:run:visual/cy:run:visual:base,
entradas correspondentes no .gitignore. Confirmado rodando o resto da suíte depois da remoção —
sem quebra.
docs/conclusao-automacao.md também ajustado: os 2 saem da lista de "falta" (não são mais pendência de automação, foi decisão explícita de não fazer) — junto com o app de conta digital/backoffice (que nunca foi código, sempre foi demanda pausada, não devia estar contado como "nossa pendência" desde o início). Percentual recalculado: 70% (era 55% antes desse ajuste de escopo — a mudança não é progresso, é a régua de comparação ficando menor).
Pendente de ação humana: nenhuma.
2026-09-02 — UX: campos de filtro passam a ser preenchidos antes de checar (usuário achou o print de falha em branco) — corrigido também um 2º falso positivo (largura de data muda ao digitar)
Categoria: 2 achados de metodologia de teste (não do produto).
Achado 1 — print de evidência em branco: usuário revisou o mochawesome-report e reparou que
o print da falha de "Nova Movimentação" não mostrava o campo desalinhado como evidência. Causa:
os testes checavam o campo vazio — text-align: center vs left num campo sem texto nenhum
não produz diferença visual nenhuma pra aparecer no print. Confirmado ao vivo, tirando print do
campo depois de selecionar "Sim": o texto aparece claramente centralizado, igual ao print original
trazido pelo usuário. Corrigido: os 2 specs de UX agora sempre preenchem um valor real antes de
checar alinhamento (opção real de cada combobox levantada abrindo a tela — nunca a 1ª opção da
lista, que é sempre "Todos"/"Todas", vazia; foi isso que produziu resultado vazio numa tentativa
intermediária de corrigir isso).
Achado 2, descoberto corrigindo o achado 1 — largura de campo de DATA muda ao digitar: ao
preencher os campos de data antes de checar, a largura despencou de propósito (243.75px →
207.75px) — um ícone de "limpar" aparece dentro do campo quando tem valor, reduzindo o espaço
visível do input. Comportamento normal da UI, não é bug — mas quebrou a checagem de largura, que
assumia (errado) que largura não muda com conteúdo. Corrigido: largura de campo de data é conferida
antes de digitar (estado limpo); alinhamento é conferido depois (com valor, pra ter
evidência visual). Campo de texto/combobox não têm esse comportamento — largura continua conferida
com o campo já preenchido nesses 2 tipos, sem problema.
Pendente de ação humana: nenhuma nova.
2026-09-02 — UX expandido: largura de campo (com correção de falso positivo sub-pixel), 2ª tela (Contas Correntes) e responsividade mobile nas 2 telas
Categoria: 2 achados de metodologia de teste (não do produto) + 1 tela nova mapeada, sem bug de produto novo confirmado.
Achado 1 — largura por string exata é frágil: ao adicionar checagem de width (além do
text-align já existente), uma execução real capturou o mesmo campo com 255.75px numa rodada e
255.72222900390625px noutra — variação de sub-pixel, não é bug de layout de verdade. Corrigido
criando cy.terLarguraProxima(valorEsperadoPx, tolerancia) (cypress/support/commands.js), que
parseia e compara com tolerância (1px padrão) em vez de string exata.
Achado 2 — "campo invisível" em mobile pode ser falso alarme: 1ª tentativa de testar
responsividade (cy.viewport(375, 812)) usou .should('be.visible') sem rolar antes, e reportou 9
de 17 campos "invisíveis" em Contas Correntes, e a própria navegação (goToListagem()) travou em
Contas Digitais Boleto (botão "Pesquisar" "not visible"). Antes de reportar como bug, conferi o
print real: formulário empilha em coluna única, dentro de um container com scroll VERTICAL normal
— os campos "invisíveis" só estavam abaixo da dobra, não quebrados. O sinal real de responsividade
quebrada é outro: scrollWidth > clientWidth (scroll horizontal forçado) — checado nas 2 telas,
ausente nas duas (375px = 375px). Testes de responsividade adicionados em
cypress/e2e/ux/contaCorrenteUx.cy.js/contaDigitalBoletoUx.cy.js checam esse sinal, não
visibilidade de campo individual.
Cobertura também completada: contaDigitalBoletoUx.cy.js cobria só 16 dos 20 campos reais da
tela (faltavam os 4 campos de data) — adicionados. Nova tela mapeada:
contaCorrenteUx.cy.js (17 campos, alinhamento e
largura, tudo consistente — sem bug, mas com guarda de regressão daqui pra frente).
Pendente de ação humana: nenhuma nova — a pergunta em aberto sobre o campo "Guid" (largura 234.75px vs 279.75px dos outros campos de texto, achado registrado na entrada anterior) continua sem resposta.
2026-09-02 — Novo eixo de teste "UX": Contas Digitais Boleto tem 2 comboboxes centralizados por engano (Nova Movimentação + achado novo, Tipo de geração de boleto)
Categoria: Bug real de UI (inconsistência visual), confirmado — não é falha de teste.
Contexto: usuário trouxe um print mostrando o combobox "Nova Movimentação" (tela "Contas Digitais
Boleto", /app/conta-digital/listar) com o texto centralizado, enquanto os campos ao redor ficam à
esquerda — já existe demanda em andamento pra corrigir esse campo específico.
Investigação (nunca no chute): antes de escrever qualquer teste, rodei um diagnóstico real
(getComputedStyle em cada um dos 20 campos da tela, via sessão logada de verdade) em vez de
assumir que era só o campo do print. Resultado: 19 dos 20 campos usam text-align: start/left
(consistente); 2 usam center — o "Nova Movimentação" já reportado, e "Tipo de geração de
boleto", que ninguém tinha reportado até agora.
Correção: nenhuma no produto (achado de UI, não é escopo deste repo corrigir) — criado
cypress/e2e/ux/contaDigitalBoletoUx.cy.js, novo
eixo de teste (@ux, npm run cy:run:ux), 1 it() por campo (16 no total), afirmando
text-align correto. Os 2 campos com bug confirmado ficam vermelhos de propósito até a
correção — mesmo padrão já usado em boletoRegressao.cy.js pra achado confirmado, ainda não
corrigido pelo produto.
Pendente de ação humana: reportar "Tipo de geração de boleto" pro time do produto (o "Nova Movimentação" já tinha demanda aberta; esse é achado novo).
2026-09-02 — Provas de conceito novas (acessibilidade + performance) já nasceram medindo o cold-boot: 3 recorrências em <20min
Categoria: Instabilidade passageira, sem causa nova — mesma classe de cold-boot do login/dashboard em Electron headless, já documentada (20/08-31/08, "Timed out retrying after 45000ms... validating the created session").
O que aconteceu: ao montar as provas de conceito de acessibilidade (cy.checarAcessibilidade())
e performance (cy.medirTempo()) descritas na conversa desta sessão, os 3 primeiros it()s que
dependiam de cy.login() bateram nessa mesma instabilidade — inclusive as 2 medições de tempo
propostas especificamente pra rastrear esse tipo de lentidão, que acabaram nem chegando a medir
nada (a falha acontece dentro do validate() do cy.session(), antes da medição começar).
Valor do achado, mesmo sem causa nova: confirma ao vivo, sem precisar de mais nenhuma investigação, que essa é a instabilidade de maior frequência real da suíte hoje — 3 ocorrências em menos de 20 minutos, batendo em specs recém-criados que nem tinham relação direta entre si. Reforça a prioridade dada a "orçamento de performance" na conversa desta sessão sobre próximos passos de evolução do projeto.
Correção: nenhuma — mesma decisão de sempre (instabilidade passageira, rodar de novo). As 2
provas de conceito (cypress/e2e/acessibilidade/, cypress/e2e/performance/) continuam válidas;
só não geraram amostra de tempo real ainda nesta 1ª tentativa.
Pendente de ação humana: nenhuma nova — rodar npm run cy:run:performance de novo quando
quiser uma 1ª amostra real de tempo.
2026-09-02 — smoke.cy.js: "Boletos" travou no beforeEach (ant-menu-inline) — mesma instabilidade recorrente, usuário confirmou tela abrindo normal na mão
Categoria: Instabilidade passageira, sem causa nova — mesma classe de timeout de render do
menu já documentada em 20/08 (causa raiz + correção), 24/08, 26/08 e 31/08 (ant-menu-inline),
agora batendo no teste "Boletos".
Sintoma reportado pelo usuário: "deu um resultado falso no smoke, deu erro no boleto mas la nao ta com erro, a tela ta abrindo normalmente" — checou a tela de Boletos de verdade, sem erro nenhum.
Causa confirmada (print do attempt 2 em cypress/screenshots/smoke/smoke.cy.js/): o teste
nunca chegou a abrir a tela de Boletos. O browser estava parado na tela de Início (dashboard),
com o menu lateral ainda recolhido (só ícone, sem texto) — o cy.expandirMenu() do beforeEach
clicou em [aria-label="menu-unfold"], mas a assertion cy.get('.ant-menu-root').should('have.class', 'ant-menu-inline') estourou os 15s de timeout sem o menu terminar de expandir. Mesmo padrão de
sempre: o nome do teste que falha ("Boletos") é só qual it() estava rodando quando o beforeEach
comum a todos travou — não indica nada sobre a tela em si, que nunca chegou a ser visitada. Confirma
o entendimento do usuário: não é falha real da tela de Boletos.
Correção: nenhuma — mesma decisão já tomada nas 4 ocorrências anteriores (ver 20/08 pra a
correção estrutural que já existe, e 24/08/26/08/31/08 pra recorrências sem causa nova). Já
recorreu 5 vezes; se continuar aparecendo com essa frequência, vale reconsiderar (aumentar o
timeout de expandirMenu(), ou trocar a espera por um sinal mais robusto que a classe CSS) — não
feito agora, fica registrado como sinal pra decisão futura.
Pendente de ação humana: nenhuma nova — só rodar de novo (mesma recomendação de sempre).
2026-09-01 — pre-commit (Husky) configurado: README sempre atualizado + 2ª camada contra segredo
Categoria: Melhoria de ferramental (não é falha) — a pedido do usuário, agora que o projeto tem controle de versão de verdade.
O que foi feito: instalado husky (npm install --save-dev husky, npx husky init), com
hook .husky/pre-commit fazendo 2 coisas antes de qualquer commit:
- Roda
npm run readme:builde re-adicionaREADME.mdao staged — elimina de vez o risco de esquecer de regenerar a árvore de estrutura (regra que já existia noCLAUDE.md, dependia de alguém lembrar manualmente). - Roda
npm run check:secrets(scripts/check-secrets.js, novo) — varre os arquivos staged (conteúdo real que vai pro commit, viagit show :arquivo, não o disco) atrás de padrão de segredo (token JWT, Personal Access Token do GitLab, chave AWS,totpSecretpreenchido) e bloqueia nome de arquivo proibido (cypress.env.json,postman/*.postman_environment.json) mesmo que o.gitignorefalhe por algum motivo (ex.:git add -f). Segunda camada, não substitui o.gitignore— complementa.
Verificado rodando de verdade: criado um arquivo temporário com um PAT falso do GitLab
(glpat-...), staged, npm run check:secrets bloqueou corretamente com a mensagem certa
(exit code 1) — depois removido, não faz parte do commit real.
Correção: nenhuma de código do produto — só ferramental do próprio repositório.
Pendente de ação humana: nenhuma — instalado e testado, funciona sozinho a partir de agora em todo commit.
2026-09-01 — Triagem: mais 1 recorrência do job sem auth (já confirmado)
Categoria: Recorrência, sem causa nova.
autenticacaoObrigatoria.cy.js— os 2it()s do job (sem AuthCG/com AuthCG inválido) seguem vermelhos de propósito, mesmo achado já registrado — comportamento esperado até o backend corrigir.
Nenhuma correção nova; nenhuma causa nova.
2026-09-01 — Triagem de lote: recorrências do job sem auth (já confirmado) + cross-tenant de cancelamento
Categoria: Recorrência, sem causa nova.
autenticacaoObrigatoria.cy.js— os 2it()s do job (sem AuthCG/com AuthCG inválido) seguem vermelhos de propósito, confirmando de novo o achado já registrado (entrada logo abaixo) — é o comportamento esperado até o backend corrigir.boletoCancelamentoCrossTenant.cy.js— mais 1 ocorrência do tracker de posse não validada em Cancelar Boleto, vermelho de propósito.
Nenhuma correção nova; nenhuma causa nova.
2026-09-01 — Nova convenção: toda API nova exige teste de autenticação em autenticacaoObrigatoria.cy.js
Categoria: Decisão de processo (não é falha) — motivada diretamente pelo achado de segurança do job (entrada logo abaixo).
O que aconteceu: depois de confirmar que o job atualizarFlagEmissao ficou semanas sem
exigir autenticação sem ninguém perceber (só descoberto porque o usuário pediu pra confirmar
isso explicitamente), o usuário decidiu formalizar a regra: toda API nova que este projeto
passa a usar precisa ganhar teste de autenticação (sem/com AuthCG inválido) desde o início,
não só quando alguém lembrar de pedir.
Registrado em docs/estrategia-de-testes.md, nova seção "Convenção: toda API nova exige
teste de autenticação" — inclui o lembrete de que a exclusão de /adm/* do escopo de
autenticacaoObrigatoria.cy.js (decisão de 26/08/2026) era só "ainda não investigado", não uma
isenção permanente, e que as ~30 rotas novas de ADM/ContaDigital/ADM/ContaDigitalApi
(descobertas ontem) ainda não têm esse teste.
Correção: nenhuma de código — é regra de processo pra próximas vezes. Pendente de ação
humana: nenhuma imediata — a regra vale a partir de agora, retroagir pras rotas /adm/* já
existentes fica como item do backlog de segurança (ver docs/estrategia-de-testes.md).
2026-09-01 — ⚠️ CONFIRMADO: POST /job/contas-digitais/atualizar-flag-emissao não exige autenticação
Categoria: Falha de segurança CONFIRMADA (achado novo) — demanda explícita do usuário pra garantir que esse endpoint exige autenticação, motivada pela migração Java 25/Spring Boot 3.5.7 em andamento.
O que aconteceu: adicionados 2 it()s novos em
autenticacaoObrigatoria.cy.js pro job
Recalcular Flag de Emissão, mesmo padrão já usado pro resto da API de Entidade (chamar sem
AuthCG e com AuthCG inválido, esperar rejeição). Rodando de verdade:
Recalcular Flag de Emissão (Job) sem AuthCG — NÃO deveria funcionar sem autenticação
(status 204, body: ""): expected 204 to not be one of [ 200, 201, 202, 204 ]
Recalcular Flag de Emissão (Job) com AuthCG inválido — NÃO deveria funcionar sem autenticação
(status 204, body: ""): expected 204 to not be one of [ 200, 201, 202, 204 ]
Confirmado: o endpoint executa o recálculo completo da flag "Sem Emissão"/"Com Emissão" em
TODAS as contas digitais ativas, sem checar autenticação nenhuma — nem a ausência total do
header AuthCG, nem um valor inválido, bloqueiam a chamada. Qualquer um com a URL consegue
disparar o job.
Contradiz o achado da investigação original (ver entrada de 28/08 "Achado grande: API expõe Swagger..."): na época, testando manualmente sem headers, a resposta tinha sido 403 "Acesso negado". Duas explicações possíveis, nenhuma confirmada:
- Regressão real introduzida por alguma mudança recente (a migração Java 25/Spring Boot 3.5.7 que o usuário está acompanhando é candidata plausível — mexe em segurança/autenticação de forma ampla no backend).
- O teste manual original foi feito de forma diferente do que documentado (menos provável — 403 é uma resposta específica demais pra ter sido um falso positivo por acaso).
Correção: nenhuma de código (não é algo que se corrija no Cypress) — 2 testes automatizados
adicionados travam esse comportamento pra sempre a partir de agora (ficam vermelhos até o backend
corrigir). docs/regras-de-negocio.md atualizado com esse achado na seção de segurança.
Pendente de ação humana: reportar formalmente pro time responsável pelo core-api/job — é
exatamente a resposta (negativa) pra demanda que motivou esse teste. Prioridade alta: esse
endpoint processa TODAS as contas digitais ativas de uma vez, sem controle de acesso nenhum.
2026-09-01 — Triagem de lote: 3 trackers de segurança, sem causa nova
Categoria: Recorrência, sem causa nova.
boletoCancelamentoCrossTenant.cy.js— mais 1 ocorrência do tracker de posse não validada em Cancelar Boleto, vermelho de propósito.boletoRegressao.cy.js/boletoGuidExistenteRegressao.cy.js— mais 1 ocorrência cada do tracker de posse não validada em/contaDigital/remessa(guid de Administradora aceito), vermelho de propósito.
Nenhuma correção nova; nenhuma causa nova.
2026-08-31 — contaCorrente.cy.js: recorrência confirmada (checagem de CNPJ frágil de novo) + range de 1 dia no lugar do ano inteiro
Categoria: Bug no teste, mesma raiz já documentada 2x hoje — correção definitiva aplicada (as anteriores só resolviam parte do problema).
O que aconteceu: usuário trouxe de volta o mesmo padrão de falha em "Data Cadastro"/"Data
Modificação" — shouldConterNaTabela(DADOS_REAIS.cnpj) não achando o CNPJ-âncora na página 1,
exatamente a causa já confirmada e documentada há pouco (paginação + registro-âncora sendo
empurrado por dado novo todo dia).
Correção aplicada (definitiva, não só diagnóstico):
- Removida a asserção
shouldConterNaTabela(DADOS_REAIS.cnpj)dos 2 testes de data — frágil por natureza (depende de posição na 1ª página). A cobertura de CNPJ já existe, sem essa fragilidade, no teste dedicadoit('CNPJ', ...)(busca direto pelo CNPJ, resultado único). - Rodando de novo pra confirmar, apareceu um 2º problema real:
expected 6439 to be below 6439— o range "ano corrente até hoje" (da correção anterior, mesmo dia) parou de excluir qualquer coisa, porque literalmente nenhum registro do ambiente tem data fora desse intervalo (tudo é 2026, nada é futuro). Trocado o Início deprimeiroDiaDoAnoAtual()pradataFutura(-1)(ontem) — range de 1 dia garante exclusão de verdade (sempre existe histórico de dias anteriores, dado o volume diário de execução), em vez de depender de um registro futuro/antigo existir "por sorte".
Verificado rodando de verdade (npx cypress run --spec contaCorrente.cy.js): a 1ª rodada
completa confirmou as duas correções — sem o erro de CNPJ, sem o erro de redução. 2 rodadas
seguintes travaram no login antes de chegar nos testes de data (Timed out... 45000ms... /app/dashboard/inicio — mesma instabilidade de cold-boot já documentada, máquina sob carga de
muita execução headless hoje, não relacionado a este spec) — não deu pra confirmar de novo por
esse motivo, mas a 1ª rodada já foi evidência suficiente.
Achado novo, não investigado ainda: na mesma 1ª rodada, "Limpar Seleção" falhou com
expected 1 to equal 6439 — depois de limparSelecao() (que já espera a chamada de rede
terminar), o total lido continuou sendo o filtrado (1), não o total completo. Pode ser flake
pontual (mesma leva de instabilidade de hoje) ou uma causa real (lerTotalResultados() lendo
antes do DOM re-renderizar, mesmo com a rede já resolvida). Pendente de investigação — não
mexido ainda, precisa reproduzir de novo antes de concluir qualquer coisa.
2026-08-31 — Triagem de lote: 2 trackers de segurança + 2 timeouts de login (cold-boot, mesma causa da investigação de contaCorrente.cy.js acima)
Categoria: Recorrência, sem causa nova.
boletoCancelamentoCrossTenant.cy.js,boletoRegressao.cy.js,boletoGuidExistenteRegressao.cy.js— mais 1 ocorrência de cada tracker de posse não validada, vermelho de propósito.contaCorrente.cy.js— 2 timeouts de login (Timed out... 45000ms... /app/dashboard/inicio) nas 2 rodadas usadas pra tentar reconfirmar o fix de datas (entrada logo acima) — mesma instabilidade de cold-boot, máquina sob carga de muita execução headless hoje.
Nenhuma correção nova; nenhuma causa nova.
2026-08-31 — Triagem de lote: resto da fila é recorrência já mapeada (2 trackers de segurança + smoke DDA/Conta Condominial pré-.skip)
Categoria: Recorrência, sem causa nova.
boletoCancelamentoCrossTenant.cy.js— mais 1 ocorrência do tracker de posse não validada em Cancelar Boleto, vermelho de propósito.boletoRegressao.cy.js/boletoGuidExistenteRegressao.cy.js— mais 1 ocorrência cada do tracker de posse não validada em/contaDigital/remessa(guid de Administradora aceito), vermelho de propósito.smoke.cy.js— 7 entradas de DDA/Conta Condominial de execuções anteriores à mudança pra.skip(entrada logo abaixo, inclui uma falha debefore eachde menu — mesma instabilidade de sempre, não relacionada às telas em si) — mesmo grupo de 500 já mapeado, resolvido por essa mudança daqui pra frente.
Nenhuma correção nova; nenhuma causa nova.
2026-08-31 — smoke.cy.js: 6 telas "Não utilizado no momento" (DDA x4, Conta Condominial x2) marcadas .skip a pedido do usuário
Categoria: Decisão de produto/processo — telas em HML sem previsão de liberação, não bug.
O que aconteceu: as 6 telas do grupo dda-api/webhook-api/adm/conta-digital-api (500
recorrente, extensivamente documentado desde 21/08/2026 — dezenas de entradas neste arquivo) foram
identificadas pelo usuário como telas sem previsão de ir pra produção. Pediu pra parar de deixar
o smoke vermelho por causa delas, sem apagar o código (guardar pra quando a liberação tiver data).
Ação: os 6 it()s trocados pra it.skip(...) em smoke.cy.js —
Conta Condominial > Geral, Conta Condominial > Webhook, DDA > Aplicações, DDA > Empresas,
DDA > Boletos, DDA > Consumo. Comentário acima de cada bloco explica o motivo e quando tirar o
.skip. Não apagados — só desativados, código (seletor, índice de menu) continua íntegro.
Verificação: npx cypress run --spec smoke.cy.js headless — 20 passing, 0 failing, 6 pending (as 6 puladas, exatamente as esperadas). Nenhuma outra tela quebrou.
Efeito colateral esperado: essas 6 telas vão parar de gerar entrada em falhas-pendentes.md
daqui pra frente — se algum dia a API delas voltar a funcionar (ou o módulo for liberado), tirar o
.skip pra voltar a cobri-las de verdade.
2026-08-31 — CONFIRMADO: PEDIDO_CANCELAMENTO não é terminal — boleto avança sozinho pra CANCELADO em poucos minutos (resolve achado pendente de 24/08)
Categoria: Regra de negócio confirmada — resolve um "achado pendente de confirmação" antigo, não corrigido até agora por falta de uma 2ª evidência.
O que aconteceu: olhando a tela real de "Boletos" (não um teste — o usuário navegando de
propósito, poucos minutos depois de rodar o cenário de cancelamento), um boleto de teste
(cliente: "Cypress QA Cancelamento", nome fixo que só existe no cenário de cancelamento de
boletoViaApi.cy.js, gerado hoje às 09:34:33) apareceu com status CANCELADO, não
PEDIDO_CANCELAMENTO.
Por que isso resolve o achado de 24/08 (ver entrada "boletoRegressao.cy.js: cancelamento
chegou em CANCELADO pela 1ª vez"): naquela época só tínhamos 1 execução de teste mostrando
CANCELADO em vez do PEDIDO_CANCELAMENTO esperado, e ficou em aberto — podia ser coincidência
de timing daquela execução específica, sem evidência suficiente pra mudar a documentação. Agora
temos uma 2ª observação, independente e com tempo aproximado conhecido (poucos minutos, ~2-5min,
segundo o usuário) — confirma que CANCELADO é o destino real, só que assíncrono e fora da
janela de um teste, mas rápido (não é questão de horas).
O que muda: docs/regras-de-negocio.md atualizado — PEDIDO_CANCELAMENTO agora documentado
como intermediário (não terminal), CANCELADO como o terminal de verdade, alcançado em poucos
minutos.
O que NÃO muda: os testes que travam PEDIDO_CANCELAMENTO como resultado esperado (em
boletoRegressao.cy.js e boletoViaApi.cy.js) continuam corretos — é o que de fato dá pra
observar dentro da janela de um teste. Nenhuma asserção foi alterada, só a documentação da regra
de negócio (o comentário "estado terminal" nesses specs ficou impreciso à luz disso, mas não
chega a ser errado o suficiente pra justificar mexer no código só por isso agora).
Pendente de ação humana: nenhuma — é só documentação mais precisa agora.
2026-08-31 — smoke.cy.js: "Usuários > Listar" travou no beforeEach (ant-menu-inline) — cascata de 22 pulados, recorrência já mapeada
Categoria: Instabilidade passageira, sem causa nova — mesma classe de timeout de render do
menu já documentada em 20/08, 24/08 e 26/08 (ant-menu-inline), agora batendo em "Usuários >
Listar".
Sintoma: rodando o smoke inteiro depois da mudança pra .skip (entrada logo abaixo), o
usuário viu 3 passing, 1 failing, 22 skipped e estranhou — parecia que a mudança tinha quebrado
quase tudo.
Causa confirmada: não tem relação com o .skip aplicado. O beforeEach (abre o menu antes de
cada teste) deu timeout esperando a classe ant-menu-inline — mesma instabilidade pontual de
sempre, batendo dessa vez no 4º teste do arquivo. Comportamento padrão do Mocha: quando um
beforeEach falha, ele marca só aquele teste como falha e pula todo o resto do describe —
por isso 22 "skipped" de uma vez, efeito cascata de 1 timeout só, não 22 telas quebradas. Mesma
dúvida já respondida antes (ver entrada de 26/08, "Dashboard carrega após login").
Correção: nenhuma — recomendado só rodar de novo.
2026-08-31 — contaCorrente.cy.js: causa raiz real do "registro conhecido some da tabela" — paginação, não o filtro de data
Categoria: Bug no teste (dependência frágil de página 1) — causa confirmada, correção ainda pendente de decisão (ver "Pendente" abaixo).
O que aconteceu: depois da correção do range de data (entrada logo abaixo), rodando de novo
mais tarde, "Data Cadastro" e "Data Modificação" voltaram a falhar — mas com um sintoma
diferente do original: não é mais expected X to be below X (a redução de total continua
funcionando), é shouldConterNaTabela(DADOS_REAIS.cnpj) não achando o CNPJ-âncora
(40.954.333/0001-74) no texto da tabela.
Causa confirmada, olhando o código real (ContaCorrentePage.js:273-276):
shouldConterNaTabela() só olha table tbody — ou seja, só a página atual (10 linhas,
size=10 na chamada real), não pagina atrás do texto. O erro capturado mostra a página inteira:
10 registros, todos com Data Modificação entre 26/08 e 31/08/2026, ordenados do mais recente pro
mais antigo — nenhum é o registro-âncora. Como specs como contaCorrenteRegressao.cy.js criam
Conta Corrente de verdade via API a cada execução (ver CLAUDE.md, seção "Cuidado com dados
reais"), o volume de registro recente cresce todo dia — e o registro-âncora (fixo desde
20/08/2026, nunca mais modificado) vai inevitavelmentte sendo empurrado pra fora da página 1 pelos
registros novos. Não é falha do filtro de data (que está funcionando, confirmado na entrada
abaixo) — é o teste depender de um registro fixo continuar visível numa 1ª página que só cresce.
Pendente de decisão (ainda não corrigido): algumas opções, nenhuma aplicada ainda —
(a) aumentar size da consulta pra caber mais páginas, (b) ordenar a busca de um jeito que não
empurre o registro-âncora pra fora, (c) remover essa checagem específica dos 2 testes de data (a
redução de total já cobre a parte principal do filtro) e deixar a checagem de CNPJ só no teste
dedicado de "CNPJ" (que já busca por ele diretamente, sem depender de página). Fica pra decidir com
o usuário antes de mexer.
2026-08-31 — contaCorrente.cy.js: filtros de data pararam de reduzir o total — range de ano fixo trocado por "ano corrente até hoje"
Categoria: Bug no teste (range de data hardcoded, não a API/tela) — corrigido a pedido do usuário, sem precisar confirmar a causa exata primeiro (ver "Causa" abaixo pra o porquê).
Sintoma: "Data Modificação (Início + Fim)" falhou com expected 6437 to be below 6437 — o
filtro (01/01/2026 a 31/12/2026, hardcoded) não reduziu o total de resultados nem 1.
Causa (hipótese, não confirmada com certeza absoluta — mas o usuário decidiu a correção
independente disso): os 3 filtros de data de contaCorrente.cy.js (Data Cadastro, Data Modificação, Data Última Aprovação) e o teste de "Limpar Seleção" usavam um range com o Fim
fixo em 31/12/2026. Isso tem 2 problemas, um deles provavelmente já em efeito: (1) o range
cobre o ano inteiro pra sempre — num ambiente onde dado de teste se acumula o ano inteiro, é
plausível que hoje não sobre nenhuma Conta Corrente com data fora desse range, o que faria o
filtro nunca reduzir nada (2) mesmo que não fosse esse o caso agora, o Fim fixo vira passado
sozinho assim que o calendário passar de 2026, quebrando o teste de novo sem ninguém ter mexido em
nada — problema estrutural, independente da causa exata de hoje.
Correção: cypress/support/datas.js ganhou 2 funções novas — hoje() e
primeiroDiaDoAnoAtual(), calculadas na hora que o teste roda, nunca fixas no código. Os 4 lugares
com '01/01/2026'/'31/12/2026' hardcoded em contaCorrente.cy.js foram trocados pra usar essas
funções.
Confirmado rodando de verdade (npx cypress run --spec contaCorrente.cy.js, headless, logo
em seguida): os 15 testes do arquivo passaram, incluindo os 3 filtros de data —
Data Cadastro (Início + Fim) (7006ms), Data Modificação (Início + Fim) (5317ms — o que tinha
falhado) e Data Última Aprovação (Início + Fim) (5864ms). Confirma que existe sim Conta Corrente
com data fora do range [01/01/ano atual, hoje] no ambiente — o range antigo (31/12/2026 fixo)
é que estava incluindo registro demais (provavelmente algum com data futura indevida), não que
faltasse dado fora do intervalo.
2026-08-31 — Triagem de lote: smoke DDA/Conta Condominial + 7ª/8ª ocorrência dos trackers de segurança, tudo recorrência já mapeada
Categoria: Recorrência, sem causa nova.
smoke.cy.js— 6 telas (DDA > Consumo/Boletos/Empresas/Aplicações, Conta Condominial > Webhook/Geral) com 500 — mesmo grupo extensivamente documentado desde 21/08.boletoCancelamentoCrossTenant.cy.js— 7ª ocorrência real do tracker de posse não validada em Cancelar Boleto, vermelho de propósito.boletoGuidExistenteRegressao.cy.js— mesmo tracker do outro achado de posse (guid de Administradora aceito em/contaDigital/remessa), vermelho de propósito, nenhuma novidade.
Nenhuma correção nova; nenhuma causa nova.
2026-08-31 — Triagem de lote: relatórios (regra dos 15min) + mais 1 ocorrência do cross-tenant (6ª), tudo recorrência já mapeada
Categoria: Recorrência, sem causa nova.
relatorios.cy.js— 3 tipos ("Cadastro Condomínios", "Boletos Pagos Mensal", "Boletos Gerados") comExpected to find content: '/sucesso/i'— regra dos 15 minutos (bloqueio de geração duplicada do mesmo tipo de relatório), mapeada desde 20/08 e reconfirmada em 26/08. Suíte rodou de novo antes de passar a janela da execução anterior.boletoCancelamentoCrossTenant.cy.js— 6ª ocorrência real do mesmo achado de segurança (posse não validada em Cancelar Boleto), vermelho de propósito, tracker da demanda em andamento.
Nenhuma correção nova; nenhuma causa nova.
2026-08-31 — subconta.cy.js: 2 falhas em cadeia, recorrência já mapeada (VS não aprovando conta nova)
Categoria: Instabilidade já mapeada, sem causa nova — mesmo padrão do VS não aprovando conta nova em HML, extensivamente documentado desde 24/08.
"quando a conta está ativa, habilita a subconta e desabilita o botão"— 400 "Conta Digital [...] não está ativa" ao tentar habilitar subconta — a conta simplesmente não tinha sido aprovada pelo VS a tempo."criar outro Condomínio com o mesmo CNPJ vira subconta da subconta"— falhou em cadeia, como consequência direta da falha acima (o 2º Condomínio depende do 1º ter habilitado subconta com sucesso nobefore()).
Nenhuma correção nova; nenhuma causa nova.
2026-08-31 — Reforço do achado de segurança: cancelamento cross-tenant não fica só no status — completa mesmo, o boleto da vítima chega em CANCELADO de verdade
Categoria: Reforço de falha de segurança já confirmada (ver entradas de 24-31/08, "CONFIRMADO: Cancelar Boleto...") — aumenta a severidade documentada, não é achado novo em si.
O que aconteceu: usuário conferiu na tela real de "Boletos" um boleto envolvido numa das
execuções de boletoCancelamentoCrossTenant.cy.js de hoje (emitido hoje, cancelamento tentado por
uma Administradora sem relação nenhuma — o it() correspondente falhou, como esperado, porque a
API aceitou o cancelamento que deveria ter sido barrado) — o boleto aparece com status
CANCELADO, não só PEDIDO_CANCELAMENTO/CANCELAMENTO_SOLICITADO (os status vistos até agora
nas respostas de API/teste).
Por que isso importa: até agora a evidência de que o cancelamento cross-tenant "funciona de
verdade" vinha do status intermediário mudando ou da resposta HTTP aceitando (200). Isso já bastava
pra confirmar a falta de validação de posse, mas deixava uma dúvida menor em aberto: será que esse
cancelamento indevido segue até o fim, ou fica "preso" nesse estado intermediário (o que ainda
seria ruim, mas menos grave)? Essa observação fecha essa dúvida: o cancelamento indevido segue o
mesmo caminho até CANCELADO que um cancelamento legítimo seguiria (ver entrada logo acima,
confirma que isso leva poucos minutos). Não é uma falha "cosmética" — é um cancelamento completo e
real de um recurso que não pertence a quem cancelou.
Correção: nenhuma — não muda a conclusão de segurança, só reforça a severidade. Trava já
existente em boletoCancelamentoCrossTenant.cy.js. docs/regras-de-negocio.md atualizado pra
deixar essa gravidade explícita.
Pendente de ação humana: nenhuma nova — segue a mesma pendência já registrada (reportar ao time do Core os 2 achados de falta de validação de posse).
2026-08-31 — Triagem de lote: resto da fila (smoke DDA/Conta Condominial) é recorrência já mapeada
Categoria: Instabilidade já mapeada, sem causa nova.
smoke.cy.js— 6 telas (DDA > Consumo/Boletos/Empresas/Aplicações, Conta Condominial > Webhook/Geral) com 500 emdda-api/webhook-api/adm/conta-digital-api— mesmo grupo extensivamente documentado desde 21/08 (ver entradas anteriores com o mesmo grupo de endpoints). Todas as telas envolvidas estão marcadas "Não utilizado no momento" no menu — sem efeito prático além do próprio smoke ficar vermelho.
Nenhuma correção nova; nenhuma causa nova.
2026-08-31 — 4ª confirmação do cross-tenant em Cancelar Boleto — PEDIDO_CANCELAMENTO de novo (reforça que CANCELAMENTO_SOLICITADO foi o outlier)
Categoria: Reconfirmação de falha de segurança já confirmada (ver entradas de 24-28/08, "CONFIRMADO: Cancelar Boleto...") — sem correção, só mais um dado pra pergunta em aberto sobre o nome do status.
O que aconteceu: rodando a suíte de novo (a pedido do usuário, conferindo os logs após a
investigação do teste de token), boletoCancelamentoCrossTenant.cy.js falhou pela 4ª vez de
verdade — mesmo padrão de sempre, a Administradora sem relação nenhuma com o Condomínio/boleto
consegue cancelar boleto alheio usando o próprio token:
boleto-alvo não deveria ter sido cancelado por uma Administradora sem relação com ele:
expected 'PEDIDO_CANCELAMENTO' to equal 'GERADO'
Dado novo pra pergunta em aberto (ver entrada de 28/08 "3ª confirmação..."): dessa vez o
status final voltou a ser PEDIDO_CANCELAMENTO — o mesmo das 2 primeiras ocorrências. Contagem
agora: 3 de 4 ocorrências deram PEDIDO_CANCELAMENTO, só 1 deu CANCELAMENTO_SOLICITADO. Reforça
a ideia de que CANCELAMENTO_SOLICITADO foi a exceção (talvez um estado intermediário pego em
timing diferente, não um rename definitivo) — mas ainda não confirmado, continua exigindo
confirmação com o time do Core.
Correção: nenhuma — a conclusão de segurança já estava confirmada desde a 1ª ocorrência; isso só adiciona dado à pergunta secundária sobre o nome do status.
Não relacionado: na mesma rodada, boletoRegressao.cy.js também reproduziu o vermelho
esperado de propósito ("guid de Administradora no lugar de Condomínio precisa SEMPRE ser
barrado") — é o tracker de sempre do achado de 21-24/08, continua vermelho porque a demanda ainda
não corrigiu, nenhuma novidade.
2026-08-31 — Falso alarme: timeout de login no before() de boletoRegressao.cy.js — e um buraco na captura automática
Categoria: Instabilidade passageira (mesmo padrão de cold-boot do Electron já documentado em
25/08) + achado de processo (falha de before all não é capturada em falhas-pendentes.md).
O que aconteceu: usuário trouxe um print de boletoRegressao.cy.js com 1 falha:
AssertionError: Timed out retrying after 45000ms: expected '.../app' to include '/app/dashboard/inicio', dentro do before() do describe raiz (chama cy.login() antes de
tudo). Como foi falha de before all, o Mocha pulou a suíte inteira — inclusive o it() de
"token (AuthCG) inválido/expirado" que aparecia no código exibido pelo Cypress logo abaixo do
erro, gerando dúvida se a API tinha aceitado o token inválido.
Causa confirmada: nada a ver com o teste do token — é o mesmo cold-boot da SPA no Electron
headless já documentado em 25/08 (ver entrada correspondente abaixo), estourando dessa vez até a
margem de 45s (provável: ambiente ainda se recuperando da manutenção recente). Rodando o spec de
novo isoladamente (a pedido do usuário), passou limpo: 7 passing, 1 failing — a falha remanescente
é a esperada de propósito ("guid de Administradora no lugar de Condomínio precisa SEMPRE ser
barrado", tracker do achado de segurança já registrado em 21-24/08). O teste do token inválido
passou (403 "Acesso negado", não cria boleto).
Achado de processo: falha de hook (before/beforeEach de nível de suíte) não passa pelo
afterEach global (cypress/support/e2e.js) que grava em falhas-pendentes.md — o Mocha não
dispara afterEach quando quem falha é um hook, não um teste. Esse tipo de falha só aparece se
alguém trouxer manualmente (como aqui) ou olhando o relatório/terminal direto — é um ponto cego
real da captura automática. Documentado em docs/triagem-de-falhas.md.
Nenhuma correção de código — nem no spec, nem em cy.login()/commands.js (a margem de 45s
segue sendo a decisão certa; foi 1 pico pontual, não indício de que precisa aumentar mais).
2026-08-28 — Achado grande: API expõe Swagger/OpenAPI real e completo — resolveu investigação de endpoint novo em 1 chamada
Categoria: Achado de ferramenta/processo — não é falha, é um recurso novo que muda como
investigações de contrato de API deveriam ser feitas daqui pra frente (ver CLAUDE.md).
O que aconteceu: usuário recebeu de um colega a URL de um endpoint novo, nunca visto em
nenhuma collection do Postman (POST /core-api/job/contas-digitais/atualizar-flag-emissao).
Testado manualmente: exigia autenticação (403 sem headers), aceitava com AuthCG (204), mas um
caso real testado não mostrou o efeito esperado — sem saber o porquê.
Achado (usuário já conhecia esse Swagger, indicado por ele): a API expõe um Swagger UI
completo e real em /core-api/swagger-ui/index.html (JSON puro em /core-api/v3/api-docs),
cobrindo toda a superfície da API — inclusive uma 3ª categoria de rotas (/job/*) que não
tinha aparecido em nenhuma collection do Postman investigada até agora. Consultando o JSON direto
(a UI não expande via automação de forma confiável), a descrição oficial do endpoint deu a
primeira pista: "Recalcula a flag Sem Emissão/Com Emissão das contas digitais ativas com base
nos dias desde a última emissão de boleto bem-sucedida. Disparado por rotina externa agendada." —
sem parâmetro nenhum, processa todas as contas ativas de uma vez.
Causa raiz confirmada pelo próprio usuário, depois de mais 1 teste real que também não mostrou
efeito (mesmo com o dev confirmando que já tinha funcionado antes, usando o mesmo Swagger): o
Condomínio usado no teste tinha status ERRO_CADASTRO — não é uma conta "ativa" de verdade,
então o job pula ela corretamente, mesmo a chamada HTTP funcionando 100% certo. Não era falta de
parâmetro nem problema de autenticação — o exemplo de teste não se encaixava no critério.
Correção: nenhuma de código — atualizado o registro da request no Postman (nome + descrição)
com o contrato real e a causa raiz confirmada, e CLAUDE.md ganhou seção nova documentando o
Swagger como fonte de consulta pra investigações futuras.
Pendente de ação humana: nenhuma pro endpoint em si (contrato e comportamento confirmados).
Vale revisitar o Swagger completo numa próxima sessão pra mapear as outras rotas /job/*/Routes
que apareceram na lista mas não foram investigadas ainda.
2026-08-28 — 3ª confirmação do cross-tenant em Cancelar Boleto — e um status final diferente, ainda não explicado
Categoria: Reconfirmação de falha de segurança já confirmada (ver entrada de 28/08 "CONFIRMADO: Cancelar Boleto...") + 1 pergunta nova, em aberto.
O que aconteceu: rodando toda a suíte de uma vez, boletoCancelamentoCrossTenant.cy.js falhou
de novo — 3ª vez que isso acontece de verdade (as 2 anteriores já bastaram pra confirmar a falha,
essa é reforço):
boleto-alvo não deveria ter sido cancelado por uma Administradora sem relação com ele:
expected 'CANCELAMENTO_SOLICITADO' to equal 'GERADO'
A diferença dessa vez: o status final veio CANCELAMENTO_SOLICITADO — nas 2 execuções
anteriores (e em todo o resto da suíte, incluindo boletoRegressao.cy.js) o status documentado
sempre foi PEDIDO_CANCELAMENTO. Dois nomes diferentes pro que parece ser o mesmo estado.
Tentei confirmar se isso é só nesse fluxo (cancelamento indevido) ou se o nome do status mudou
de forma geral — rodando boletoRegressao.cy.js (cancelamento de boleto pela própria dona,
fluxo legítimo) pra comparar. 3 tentativas, nenhuma chegou na resposta:
- Sessão de login não validou (mesma instabilidade já documentada, sem relação com o teste)
- Mesma coisa de novo
- Chegou a rodar, mas o boleto não tinha chegado em
GERADOa tempo do cancelamento (400 "pendente de envio para o banco") — nada a ver com a pergunta
Não confirmado ainda: se CANCELAMENTO_SOLICITADO é um status novo/renomeado que passou a
valer em geral, ou se é específico de alguma condição (ex.: cancelamento vindo de fora, sem
posse). Fica em aberto — próxima vez que boletoRegressao.cy.js (fluxo legítimo) rodar até essa
asserção com sucesso, comparar os dois valores.
Correção: nenhuma — não muda a conclusão de segurança (continua confirmado que o cancelamento cross-tenant funciona de verdade, independente do nome exato do status final).
Pendente de ação humana: confirmar com o time do Core se CANCELAMENTO_SOLICITADO e
PEDIDO_CANCELAMENTO são o mesmo status com nomes diferentes (ex.: um rename em andamento) ou
duas coisas distintas.
2026-08-28 — Triagem de lote: resto da fila é recorrência já mapeada (execução completa pós-manutenção)
Categoria: Recorrência, sem causa nova.
smoke.cy.js— 4 telas (DDA > Consumo/Boletos/Empresas/Aplicações, Conta Condominial > Geral) com 500 emdda-api/adm/conta-digital-api— mesmo grupo já extensivamente documentado.subconta.cy.js— par "não está ativa" → cascata, mesmo padrão de sempre (VS não aprovando a tempo).boletoRegressao.cy.jseboletoGuidExistenteRegressao.cy.js— o teste "guid de Administradora deveria ser barrado" reconfirmou o comportamento já sabido (status 200, aceita) — mesma falha já documentada, não é achado novo.boletoSimulaErroEmissao.cy.js(2 ocorrências) — mesmo par de sempre: "código externo duplicado" pegou ruído "não está ativa"; "cliente sem CPF/CNPJ" voltou 400 em vez do 500 esperado (mesmo comportamento "em fluxo" já sinalizado, ainda sem confirmar se é correção real).
Correção: nenhuma — todas já com causa raiz confirmada em entradas anteriores.
Pendente de ação humana: nenhuma nova.
2026-08-28 — Lote de 15 falhas: ambiente inteiro em manutenção (503), não é bug — confirmado pelo usuário
Categoria: Instabilidade de ambiente externa — não é falha de teste nem de produto.
O que aconteceu: 15 entradas em falhas-pendentes.md, todas entre 11:38:56 e 11:40:01 de
28/08/2026 (menos de 1,5 min de intervalo — 1 única execução completa), cobrindo specs de todas
as categorias (smoke.cy.js, todos os 6 de sanity/, relatorioRegressao.cy.js,
login.cy.js, aplicacao.cy.js, contaCorrente.cy.js, contaGeradora.cy.js,
relatorios.cy.js). Todas com o mesmo erro exato: cy.visit() falhando ao carregar a
própria home (https://core-homol2-contadigital.contagroup.com.br/) com 503 Service
Unavailable — não é uma tela específica ou uma chamada de API pontual, é o site inteiro
recusando conexão.
Causa confirmada: usuário confirmou diretamente que o ambiente entrou em manutenção nessa janela — bate exatamente com o padrão (503 na própria home, todos os specs afetados ao mesmo tempo, janela de menos de 2 minutos).
Correção: nenhuma — nenhum dos 15 é falha de teste ou de produto.
Pendente de ação humana: nenhuma. Se esse padrão específico (503 na home, todos os specs de uma vez) se repetir, é o mesmo diagnóstico — não precisa investigar de novo.
2026-08-28 — Corrigido: "Zoho Boletos Pagos VS" travava por combo virtualizado não renderizando o item no DOM
Categoria: Falha de teste (seletor), causa raiz confirmada e corrigida — não é bug de produto.
O que aconteceu: relatorios.cy.js falhava consistentemente ao tentar selecionar "Zoho
Boletos Pagos VS" no combo "Tipo de Relatório" — Timed out retrying after 10000ms: Expected to find content: '/^Zoho Boletos Pagos VS$/i'... but never did. Recorrente desde pelo menos
26/08/2026.
Investigação (ao vivo, com print real do combo aberto): o combo (Ant Design, lista
virtualizada rc-virtual-list) só tinha 8 dos 11 itens renderizados no DOM no momento da
falha — parava em "Projeção de MRR"; "Transferências Pagas", "Zoho Boletos Pagos Core" e "Zoho
Boletos Pagos VS" simplesmente não existiam ainda. Isso contradizia a suposição documentada no
código (RelatorioPage.js): "os itens já ficam todos no DOM ao abrir o combo, não é lazy-render"
— suposição que valia com 10 itens, mas deixou de valer a partir de 11 (o combo passou a
lazy-renderizar de verdade). Coincide com a adição de "Indicação de Churn" ao tipo de relatório
(ver entrada de 26/08 sobre esse tipo novo) — não é culpa dessa adição em si, só expôs um
comportamento do componente que não tinha sido testado nesse volume antes.
Correção: RelatorioPage.js (selectTipoRelatorio) — antes de tentar localizar a opção,
busca via jQuery puro (sem o retry automático do Cypress, que travava em timeout esperando um
elemento que genuinamente não existia) e, se não achar, rola o holder da lista em incrementos
(clientHeight por vez, até 8 tentativas) até o item aparecer no DOM — só então calcula a
posição real e centraliza antes de clicar. Corrigido um bug próprio nessa mesma correção
(optionEl.getBoundingClientRect is not a function): o Cypress envolve automaticamente um
elemento DOM devolvido de .then() num objeto jQuery ao repassar pra próxima etapa da chain —
Cypress.$(...)[0] desembrulha de volta, funciona com ou sem esse envolvimento.
Confirmado ao vivo: rodado isolado (--env grep="Zoho Boletos Pagos VS") 3 vezes — 1ª
reproduziu a falha original, 2ª expôs o bug do jQuery-wrap na correção, 3ª passou limpo
(21787ms, sem flakiness).
Pendente de ação humana: nenhuma.
2026-08-28 — CONFIRMADO: Cancelar Boleto aceita cancelamento cross-tenant (BOLA/IDOR, 2ª execução real)
Categoria: Falha de segurança confirmada (BOLA/IDOR) — mesma família da falta de checagem de posse já confirmada na remessa.
Desenho do teste (cypress/e2e/casos_de_teste/com_dados/boletoCancelamentoCrossTenant.cy.js):
cria 2 Administradoras sem relação nenhuma entre si. Administradora A ("vítima") ganha 1
Condomínio + 1 boleto real, gerado com o próprio token. Administradora B ("atacante") é
criada só depois, sem Condomínio nenhum, sem vínculo algum com A. Na chamada de cancelamento, a
URL usa o guid do Condomínio/boleto reais da Administradora A (a vítima) — só o header
AuthCG vem trocado, com o token da Administradora B (a atacante). Ou seja: token de B, mas
apontando pro recurso de A.
1ª execução real (28/08, 10:26:10) — passou pela chamada e a asserção de efeito colateral falhou:
boleto-alvo não deveria ter sido cancelado por uma Administradora sem relação com ele:
expected 'PEDIDO_CANCELAMENTO' to equal 'GERADO'
O boleto da Administradora A mudou de status de verdade — o cancelamento aconteceu.
2ª execução real (28/08, 10:52:45, rodada pelo usuário) — dessa vez a PRÓPRIA resposta HTTP já veio como sucesso, sem nem parecer rejeitar:
esperado que a API REJEITE cancelamento vindo de uma Administradora sem relação com o
Condomínio/boleto (status 200, body: {"guid":"ab270700-9b8e-471d-b16a-37c1c0f5c3aa",
"status":"RECEIVED"}): expected 200 to not be one of [ 200, 201, 202 ]
Duas execuções reais, dois sinais diferentes do mesmo problema (efeito colateral real numa, e
resposta HTTP 200 direta na outra) — confirmado, não é mais achado parcial. O endpoint
POST .../boleto/{codigo}/cancelamento valida que o token é válido, mas não valida que esse
token pertence a uma Administradora com relação com o Condomínio/boleto alvo — mesma classe de
falha já confirmada em POST /contaDigital/remessa (boletoGuidExistenteRegressao.cy.js).
Correção: nenhuma no código de teste — boletoCancelamentoCrossTenant.cy.js já trava
corretamente esse comportamento (fica vermelho até o Core corrigir). regras-de-negocio.md
atualizado de "achado parcial" pra confirmado.
Importante, pra quem for reproduzir isso na mão (sem Cypress): o request de cancelamento não
leva guid de Administradora em lugar nenhum — só guid_condominio + código do boleto na URL.
A "posse" violada é implícita, carregada só pelo token no header AuthCG; não tem campo separado
pra "quem está pedindo o cancelamento" que a API poderia cruzar contra o dono do Condomínio.
Como reproduzir manualmente no Postman (mesmas requests já mapeadas na collection "CORE HOMOL V1"):
- "Cria Administradora" (pasta Credenciamento, com
Api-Key/Application) → cria a Administradora A ("vítima"). Anotaguid_administradora_A. POST /authcom o usuário/senha de A →token_A.- "Cria Condomínio",
AuthCG: token_A→ cria o Condomínio de A. Anotaguid_condominio_A. - Configurar Conta Geradora do Condomínio A — ⚠️ único passo que não dá pra fazer só com Api-Key: precisa de sessão de backoffice (login com 2FA pela tela). Sem isso o Condomínio fica sem banco configurado e não gera boleto.
- "Gerar Boleto",
AuthCG: token_A,codigo: guid_condominio_A→ espera o status virarGERADO(GET .../boletos, é assíncrono). - "Cria Administradora" de novo, com CNPJ/usuário diferentes → Administradora B ("atacante"). Não precisa de Condomínio pra ela.
POST /authcom usuário/senha de B →token_B.- O passo que prova o problema — "Cancelar Boleto"
(
POST /contaDigital/{guid_condominio_A}/boleto/{código_do_boleto_A}/cancelamento): URL aponta pro Condomínio/boleto de A, mas o headerAuthCGleva otoken_B. Se voltar 200/201 em vez de 401/403, confirma a falha — sem depender do Cypress rodando nada.
Pendente de ação humana: reportar pro time do Core como achado de segurança real — mesma gravidade/urgência da falta de checagem de posse já confirmada na remessa. Os dois juntos sugerem que a checagem de posse pode estar ausente de forma sistemática na API de Entidade, não só nesses 2 endpoints — vale considerar uma varredura mais ampla depois que esses 2 forem corrigidos.
2026-08-26/28 — Triagem de lote: resto da fila é recorrência já mapeada, sem causa nova
Categoria: Recorrência, sem causa nova (várias entradas de falhas-pendentes.md, 26 a
28/08/2026).
smoke.cy.js— DDA (Consumo/Boletos/Empresas/Aplicações) e Conta Condominial (Webhook/Geral) com 500 emdda-api/webhook-api/adm/conta-digital-api— 9 ocorrências nesse intervalo, mesmo grupo já extensivamente documentado (entradas de 20-21/08 e várias rodadas anteriores).subconta.cy.js— par "não está ativa" → cascata (habilitar subconta + subconta da subconta), mesmo padrão de sempre (VS não aprovando a tempo).login.cy.js— timeout de 45s validando sessão pós-login (cold-boot variável do Electron headless, já documentado).boletoRegressao.cy.jseboletoGuidExistenteRegressao.cy.js(3 ocorrências) — o teste "guid de Administradora deveria ser barrado" (ainda vermelho de propósito, demanda em andamento) pegou ruído de ambiente ("não está ativa") antes de conseguir validar a regra em si — o próprio guard de detecção de ruído (já implementado nesses specs) pegou isso certo.boletoSimulaErroEmissao.cy.js(2 ocorrências) — "código externo duplicado" pegou "não está ativa" no lugar (mesmo ruído); "cliente sem CPF/CNPJ" voltou 400 em vez do 500 esperado — o mesmo comportamento "em fluxo" já sinalizado no JSDoc deboletoRegressao.cy.js(achado de 21/08 ainda sem confirmar se é correção real do backend ou instabilidade do dia).
Correção: nenhuma — todas já com causa raiz confirmada em entradas anteriores.
Pendente de ação humana: nenhuma nova. Segue valendo a nota já registrada sobre o 400 vs 500
de boletoSimulaErroEmissao.cy.js: só travar uma regressão formal quando esse comportamento
ficar estável.
2026-08-26 — Tipo de relatório novo: "Indicação de Churn" — mapa desatualizado, não bug
Categoria: Produto mudou / mapa desatualizado (mesmo padrão de "Notificações > Boletos" e "DDA
Aplicações" em 20-21/08) — não é falha de teste nem de produto.
O que aconteceu: usuário identificou, direto na tela ("Tipo de Relatório"), um tipo não
mapeado em nenhum lugar do projeto: "Indicação de Churn". A lista de 10 tipos documentada em
regras-de-negocio.md/relatorios.cy.js/RelatorioPage.js não incluía esse valor.
Correção: adicionado em todos os lugares que enumeram os tipos —
cypress/e2e/casos_de_teste/com_dados/relatorios.cy.js (TIPOS_RELATORIO, posição alfabética
entre "Financeiro" e "Projeção de MRR" — inferida pelo padrão da lista, não re-verificada item a
item na tela), docs/regras-de-negocio.md (tabela de tipos, 10 → 11), docs/estrategia-de-testes.md
(2 inventários) e os comentários que citavam "10 tipos" como contagem
(RelatorioPage.js, relatorioRegressao.cy.js, regressao/LEIAME.md).
Pendente de ação humana: nenhuma. Não foi confirmado se a lista completa da tela tem exatamente 11 tipos agora (só esse 1 novo foi reportado) — se aparecer outro tipo não mapeado, mesmo processo.
2026-08-26 — Investigação: suspeita de "Cria Administradora sem autenticação" — descartada (falso alarme)
Categoria: Investigação de segurança concluída sem bug — não é regra de negócio nova, é o registro de uma suspeita descartada.
Suspeita do usuário: POST /credenciamento (endpoint que cria uma Administradora nova)
estaria aceitando a chamada sem autenticação — evidência inicial: uma request "Cria
Administradora" no Postman retornando 200 com um print mostrando a aba Authorization como
"Inherit auth from parent" → "No Auth".
Investigação: escrito cypress/e2e/seguranca/autenticacaoObrigatoria.cy.js (categoria nova de
teste, irmã de smoke/regressao/sanity — decisão do usuário) cobrindo 12 checagens (sem header /
com header inválido) em 6 endpoints da API de Entidade. Rodado ao vivo: os 12 passaram — nenhum
endpoint funcionou sem autenticação válida, incluindo credenciamento (400 tanto sem
Api-Key/Application quanto com valores forjados). Isso contradizia a suspeita inicial, então
em vez de descartar sem confirmar (nunca no chute), pedimos pro usuário inspecionar a request real
do Postman que gerou o 200: aba Headers (não a Authorization) mostrou Api-Key e
Application presentes, marcados, com valores reais — digitados direto como header manual, não
pelo sistema de "Authorization" do Postman (por isso aquela aba mostrava "No Auth": é um mecanismo
separado, que essa request simplesmente não usa).
Causa raiz da suspeita: leitura da aba errada do Postman — "Authorization" só reflete o sistema de auth automático do Postman; não mostra headers digitados manualmente na aba "Headers". A request sempre teve autenticação de verdade, só não estava óbvio em qual aba ela aparecia.
Correção: nenhuma — não há bug. cypress/e2e/seguranca/autenticacaoObrigatoria.cy.js
permanece como está, travando o comportamento correto (já confirmado) pra pegar se isso regredir
no futuro.
Pendente de ação humana: nenhuma. Nota à parte (não relacionada ao bug): o print da aba
Headers, compartilhado durante a investigação, expôs o valor real de Api-Key/Application do
Postman em texto simples no chat — não foi registrado em nenhum arquivo deste projeto, mas se
houver preocupação com essa exposição, considerar regenerar a Api-Key no Postman.
2026-08-26 — Incidente de processo: checagem de sintaxe pós-@cypress/grep rodou before() de 3 specs com_dados sem querer
Categoria: Incidente de processo (suíte de teste), não bug do produto.
O que aconteceu: ao implementar tags (@cypress/grep) em todos os specs, tentei validar que
nenhum arquivo ficou com erro de sintaxe depois de editar ~20 describe()/it() de uma vez,
rodando npx cypress run --env grepTags=@tag-inexistente (ideia: nenhum teste bateria com uma tag
que não existe, então nada executaria de verdade). Isso funciona pra pular it()s — mas não pula
o before() do describe, que roda de qualquer forma (limitação conhecida do @cypress/grep; só
grepFilterSpecs=true, não usado aqui, evitaria isso pré-filtrando arquivo inteiro). Resultado: os
3 specs de com_dados/regressao que passaram nesse lote (boletoRegressao.cy.js,
boletoViaApi.cy.js, boletoCancelamentoCrossTenant.cy.js) tiveram seus before() executados de
verdade — os 3 apareceram como "before all hook" falhando, não passando, então é provável que a
chamada de credenciamento real (Administradora, possivelmente Condomínio) já tinha disparado antes
de falhar mais adiante pela mesma instabilidade de VS já reportada pelo usuário nesta sessão.
Não foi possível confirmar até onde cada before() chegou — o log detalhado desse run se
perdeu (comando com | tail -80 cortou a saída antes de salvar, e o relatório Mochawesome
seguinte sobrescreveu o anterior, overwrite: true). Sem acesso de leitura à listagem real de
Administradoras do ambiente pra confirmar/descartar, fica em aberto.
Causa confirmada: escolha errada de método de verificação — usar cypress run de verdade (com
tag inexistente) pra "só checar sintaxe" não é seguro quando o spec tem before() com efeito
colateral real; deveria ter sido uma checagem estática (node --check arquivo.cy.js, que não
executa nada, só valida a sintaxe) desde o início.
Correção: nenhuma no código do produto (não é bug de produto). No processo: as sintaxes das
tags foram na verdade confirmadas corretas via node --check em todos os 19 specs, sem side
effect algum — é o método que deveria ter sido usado desde a primeira tentativa.
Pendente de ação humana: nenhuma ação corretiva possível (mesma limitação de sempre — sem endpoint de exclusão usado neste projeto). Se o usuário notar Administradoras de teste extras/ e-mails de notificação inesperados no ambiente por volta deste horário, a causa é esta.
Adendo (mesmo dia, ~15h06-15h12): 2ª ocorrência confirmada, desta vez pelo próprio usuário —
rodou npx cypress run --env grepTags=@boleto+@regressao (sem --spec) e o relatório Mochawesome
mostrou boletoCancelamentoCrossTenant.cy.js (tags @boleto @seguranca, sem @regressao — não
deveria ter sido tocado por esse filtro) com 1 teste "FAILED", erro batendo exatamente com a
asserção do PRÓPRIO before() do arquivo ("boleto-alvo precisa estar GERADO...") — confirma que
o before() rodou de verdade (criando Administradora real) mesmo o describe inteiro estando fora
do filtro pedido. Mesmo padrão num describe aninhado de boletoViaApi.cy.js ("cancelamento de
boleto", também sem @regressao). Correção: README atualizado (seção "Rodar por tag") com
recomendação explícita de sempre combinar grepTags com --spec ou grepFilterSpecs=true pra
evitar esse efeito colateral.
2026-08-26 — Triagem de lote (rodada 5, 10h16-10h17): mesmo grupo de 500 já mapeado
Categoria: Recorrência, sem causa nova.
smoke.cy.js — 5 telas (DDA > Consumo/Boletos/Empresas/Aplicações, Conta Condominial >
Webhook/Geral) com 500 em dda-api/webhook-api/adm/conta-digital-api — mesmo grupo já
extensivamente documentado (entradas de 20/08, 21/08, e várias rodadas de hoje).
Correção: nenhuma. falhas-pendentes.md limpo.
Pendente de ação humana: nenhuma nova (backend de homologação estabilizando esses 3 grupos de endpoint, fora do escopo deste projeto).
2026-08-26 — Triagem de lote (rodada 4, 09h57-10h07): "sucesso" não encontrado era a regra dos 15 min, não bug — resto é recorrência
Categoria: Investigação de um padrão que parecia crescente (3 ocorrências de "sucesso" não encontrado) — resolvido, não é bug novo.
Achado principal: os 3 casos de relatorios.cy.js com "Expected to find content: '/sucesso/i'
but never did" (DIMP Clientes antes; Boletos Gerados e Boletos Pagos Mensal nesta rodada) não
são o toast sumindo rápido demais — o log de rede do próprio Cypress (visível no Command Log)
mostrou a causa real numa das falhas: a chamada POST .../relatorio/solicitar respondeu 400,
não 200. Investigando de novo com um spec temporário focado só nessa chamada, a MESMA chamada
respondeu 200 normal dessa vez — inconsistente, mas exatamente como o próprio relatorios.cy.js
já avisa no seu docblock: "se a suíte inteira for rodada de novo antes de passar 15 minutos da
execução anterior, o PRIMEIRO clique de cada tipo pode já vir rejeitado". Rodamos
relatorios.cy.js várias vezes hoje (o usuário + minhas investigações) — alguns tipos caíram
dentro da janela de 15 min de uma execução anterior, e a 1ª tentativa recebeu a rejeição de
duplicado em vez do sucesso esperado.
Correção: nenhuma — é a regra de negócio já documentada mordendo por causa da frequência de execuções de hoje, não um bug de código ou de seletor.
Recorrências, sem causa nova:
smoke.cy.js: "Dashboard carrega após login" bateu no timeout de 45s de novo — quando obeforeEachfalha, Mocha marca só esse teste como falha e o RESTO do describe vira "pending" (não roda) — é assim que qualquer test runner Mocha se comporta, não é bug do relatório Mochawesome (dúvida do usuário, respondida: é comportamento padrão, confirmado batendo com a causa raiz já conhecida do timeout).subconta.cy.js,boletoSimulaErroEmissao.cy.js,boletoRegressao.cy.js,boletoGuidExistenteRegressao.cy.js: mesmos padrões de sempre (VS não aprovando, guards de ruído funcionando certo).
Pendente de ação humana: nenhuma nova — se quiser evitar esse ruído específico do "sucesso",
espaçar mais as execuções completas de relatorios.cy.js (>15min entre elas) ou aceitar que é
esperado quando se roda em sequência.
2026-08-26 — Adicionado relatório HTML por execução (Mochawesome)
Categoria: Melhoria de ferramental (não é falha) — a pedido do usuário, depois de discutir formas de ver o resultado de uma execução com mais detalhe do que a tabela de resumo do Cypress.
Motivação: docs/falhas-pendentes.md já lista toda falha em detalhe, mas é um registro
cumulativo (de todas as execuções). Faltava algo pra ver rápido, num HTML só, o resultado de uma
execução específica — cada teste, tempo, status, print inline — sem precisar abrir o Cypress de
novo.
Mudança: cypress-mochawesome-reporter instalado (npm install --save-dev) — pacote único e
atual, substitui o setup antigo de 3 pacotes separados. Configurado em
cypress.config.js (reporter + reporterOptions no nível raiz, plugin
registrado dentro de setupNodeEvents) e registrado em
cypress/support/e2e.js (import 'cypress-mochawesome-reporter/register').
Gera mochawesome-report/index.html a cada execução (cypress open ou cypress run),
sobrescrito toda vez (overwrite: true) — pasta adicionada ao .gitignore, mesmo padrão de
cypress/screenshots/.
Decisão consciente, a pedido do usuário: o print nativo do Mochawesome (screenshotOnRunFailure
do reporterOptions) ficou ligado, duplicando com o print que o projeto já tira sozinho via
afterEach (cypress/support/e2e.js) — de propósito, pra comparar os dois por um tempo antes de
decidir se desliga um deles.
Verificação: node -e "require('./cypress.config.js')" confirma que o config carrega sem
erro; rodei de verdade (sem_dados/**) e confirmei mochawesome-report/index.html gerado com
sucesso (log do próprio Mochawesome: "HTML report successfully created!").
Pendente de ação humana: nenhuma — só usar e decidir depois se quer desligar o print duplicado.
2026-08-26 — Triagem de lote (rodada 3, 09h44-09h52): tudo recorrência conhecida
Categoria: Sanity check das mudanças de hoje (mochawesome + fix do relatorios.cy.js) gerou mais
uma leva pequena de falhas-pendentes.md — nenhuma causa nova.
aplicacao.cy.js: timeout de 45s no cold-boot do dashboard — mesma ressalva já registrada (máquina sob carga de várias execuções headless seguidas hoje).smoke.cy.js: "Notificações > Cadastros" estourou timeout emant-menu-inline— mesma classe de instabilidade pontual já documentada (Contas Geradoras > Alteração em Lote, 20/08), agora num item de menu diferente.Conta Condominial > Webhook/Geral— mesmo grupo de 500 já mapeado.boletoRegressao.cy.jseboletoGuidExistenteRegressao.cy.js: guards de ruído de ambiente funcionando certo de novo.boletoSimulaErroEmissao.cy.js: mesma instabilidade de VS nobefore(), sem guard próprio (oportunidade já registrada antes).subconta.cy.js: par "não está ativa" → cascata, mesmo padrão.
Correção: nenhuma nova. falhas-pendentes.md limpo.
Pendente de ação humana: nenhuma nova.
2026-08-26 — relatorios.cy.js: causa real de "Transferências Pagas" falhando — não era timing, era o filtro :visible do jQuery
Categoria: Correção de diagnóstico — 2 tentativas anteriores no mesmo dia partiram da hipótese errada (timing/renderização lenta). Só descobri a causa real investigando ao vivo com um spec temporário (sem clicar em "Gerar Relatório", sem criar solicitação real), depois que o usuário reportou que o problema persistia mesmo depois do "fix" anterior.
Causa real, confirmada ao vivo: os rótulos <p class="MuiTypography-root...">Guid Administradora</p> / ...Guid Condominio</p> existem no DOM com dimensão real
(getBoundingClientRect > 0, display: block, visibility: visible, opacity: 1) — mas o
pseudo-seletor :visible do jQuery devolve false pra eles, sempre, não importa quanto se
espere. preencherCamposGuidSeExistirem() usava p.MuiTypography-root:visible — por isso nunca
encontrava esses 2 rótulos específicos, em nenhuma das 2 versões anteriores (a que lia 1 vez só, e
a que tentava de novo por até 20s). Não era um problema de tempo — era o filtro em si.
Como cheguei lá: um 1º spec de investigação (variando o tempo de espera) continuou dando zero
resultados mesmo depois de 20s — o que já era estranho o suficiente pra abandonar a hipótese de
timing. Um 2º spec, checando o mesmo rótulo diretamente via Cypress.$(el).is(':visible') e
getComputedStyle, mostrou o paradoxo: dimensão real na tela, mas :visible falso. A partir daí
ficou claro que o filtro em si era o problema, não a espera.
Correção: preencherCamposGuidSeExistirem() não usa mais :visible na busca do rótulo — só
p.MuiTypography-root (sem esse filtro) + o próprio filtro de texto (/^guid/i). Nenhum retry
extra é necessário: os outros 9 tipos continuam seguros (sem :visible ou com ele, zero rótulos
"guid" continua sendo zero pra eles, confirmado ao vivo também). Removida também a tentativa
anterior de rastrear tipoSelecionadoAtual — não fazia mais sentido depois da causa real
descoberta.
Verificação: rodei o fluxo completo (login → ir pra Relatórios → selecionar "Transferências Pagas" → preencher datas → preencher Guids), SEM clicar em "Gerar Relatório" — confirmei os 2 campos preenchidos com guid gerado, e que o tipo sem campo Guid continua processando rápido (spec inteiro em 14s, contra 35-60s+ das versões anteriores com retry desnecessário). Não cliquei em "Gerar Relatório" de propósito (evita criar solicitação real só pra validar isso).
Pendente de ação humana: rodar relatorios.cy.js de ponta a ponta pra confirmar que
"Transferências Pagas" completa o fluxo inteiro (clique + mensagem de sucesso), não só o
preenchimento dos campos.
2026-08-26 — Triagem de lote (rodada 2, 08h48-09h09): tudo recorrência conhecida
Categoria: Usuário rodou a suíte completa; triagem de mais uma leva de falhas-pendentes.md.
smoke.cy.js: 500 emdda-api/webhook-api/adm/conta-digital-api— mais 2 rodadas completas do mesmo grupo de 5 telas já mapeado (08h57-08h58 e 09h08-09h09).subconta.cy.js: par "não está ativa" → cascata — mais 1 ocorrência (09h04).boletoRegressao.cy.jseboletoGuidExistenteRegressao.cy.js: os 2 testes "guid de Administradora deveria ser barrado" pegaram ruído de ambiente ("não está ativa") nas suas respectivas rodadas (08h48, 08h53, 08h54) — os guards de detecção de ruído funcionaram certo nos 2 arquivos, abortaram sem concluir nada errado.boletoSimulaErroEmissao.cy.js: 2 cenários ("cliente sem CPF/CNPJ", "código externo repetido") também pegaram "conta não está ativa" na criação da Administradora/Condomínio dobefore()— mesma causa raiz de sempre (VS não aprovando), diferente manifestação (aqui não tem guard de ruído específico porque obefore()desse arquivo não passa pelo fallback deboletoRegressao.cy.js/commands.js— é oportunidade de melhoria, não crítico agora).
Correção: nenhuma nova — tudo já mapeado. falhas-pendentes.md limpo.
Nota à parte: durante a investigação do "Transferências Pagas" (entrada acima), meu próprio
spec temporário bateu 1x no timeout de 45s do cold-boot do dashboard (cy.login()) — depois de
muitas execuções headless seguidas nesta máquina hoje. Mesma ressalva já registrada antes: pode
ser só a máquina sob carga da minha própria investigação, não necessariamente prova que 45s é
insuficiente em condição normal.
Pendente de ação humana: nenhuma nova além das já registradas (VS aprovando contas novas, backend de homologação estabilizando os 5 endpoints).
2026-08-26 — Triagem de lote (25/08 16h – 26/08 08h): 1 regressão real corrigida, 1 arquivo novo documentado, resto é recorrência conhecida
Categoria: Triagem de várias entradas acumuladas de uma vez — a maioria recorrência já extensivamente documentada, 2 achados novos de verdade.
1) Regressão real, corrigida — ⚠️ atualizada mais tarde no mesmo dia, ver entrada abaixo:
relatorios.cy.js — "Transferências Pagas" parou de disparar clickGerarRelatorio(). O diagnóstico
inicial (retry de 8x/500ms por achar que era timing de renderização) não era a causa real —
corrigido de verdade horas depois, ver "relatorios.cy.js: causa real de 'Transferências Pagas'
falhando" mais abaixo.
2) Arquivo novo, não documentado: boletoGuidExistenteRegressao.cy.js reapareceu em
cypress/e2e/regressao/ — havia sido removido nesta mesma sessão (mesclado em
boletoRegressao.cy.js, ver entrada de 24/08). A versão nova é DIFERENTE e mais completa: usa um
guid de Condomínio REAL E FIXO do ambiente (566fd5e1-..., indicado pelo usuário em 21/08) — não
um recém-criado pela própria execução — pra testar "a API confere POSSE, não só TIPO?". Isso
complementa boletoRegressao.cy.js (que só testa Administradora/Condomínio da MESMA hierarquia,
ou seja, só valida tipo) e responde diretamente a uma dúvida levantada nesta sessão sobre se o
token carrega vínculo de posse — resposta confirmada ao vivo em 21/08: não carrega, e o servidor
também não confere (200 aceito). npm run readme:build já sinalizava "sem descrição" — corrigido:
adicionado ao manifesto (scripts/build-readme.js), a LEIAME.md e à seção "Cuidado com dados
reais" do CLAUDE.md (risco maior que o padrão: boleto de verdade contra Condomínio real que não
é dado de teste nosso).
3) Recorrências, sem causa nova (mesmo padrão já documentado várias vezes):
smoke.cy.js: 500 emdda-api/webhook-api/adm/conta-digital-api— 2 rodadas completas (25/08 16h20, 26/08 08h43) do mesmo grupo de 5 telas já mapeado.subconta.cy.js: par "não está ativa" → cascata — 3 ocorrências a mais (25/08 16h27 x2, 26/08 08h38 x1). Confirma de novo o design de 1 tentativa (sem retry) funcionando como esperado.boletoGuidExistenteRegressao.cy.js: oit()"guid de Administradora deveria ser barrado" pegou ruído de ambiente ("não está ativa") — o mesmo guard de detecção de ruído já usado emboletoRegressao.cy.jsfuncionou certo, abortou sem concluir nada errado.relatorios.cy.js: "This session already exists" (mesma pegadinha de editarcommands.jscomcypress openaberto, já documentada) e "DIMP Clientes" com mensagem de sucesso não encontrada (1 ocorrência isolada — já é uma incerteza conhecida e documentada no próprioRelatorioPage.js: o texto exato do toast de sucesso nunca foi confirmado, "passa rápido demais"; não é evidência suficiente pra mudar nada ainda).
Verificação: sintaxe conferida (node --check) no RelatorioPage.js corrigido. Não rodei
relatorios.cy.js de ponta a ponta (cria solicitação real por tipo).
Pendente de ação humana: confirmar rodando de verdade que "Transferências Pagas" volta a
disparar a chamada; capturar o texto exato do toast de sucesso pra tirar a incerteza de
successMessage (pendência antiga, ainda de pé).
2026-08-25 — relatorios.cy.js parou de clicar em "Gerar Relatório": preencherCamposGuidSeExistirem() travava em cy.get() quando o tipo não tem campo Guid (9 dos 10 tipos)
Sintoma: usuário reportou que os testes de Relatórios (com_dados/relatorios.cy.js) pararam
de chegar no clique em "Gerar Relatório". 6 entradas em falhas-pendentes.md (25/08, 16:03-16:08),
tipos "Boletos Gerados", "Boletos Pagos Mensal" e "Cadastro Condomínios" — nenhum deles usa o campo
"Guid" (só "Transferências Pagas" usa). Erro: Timed out retrying after 10000ms: Expected to find element: 'p.MuiTypography-root:visible', but never found it (ou a variante apontando pro
.filter() seguinte na cadeia).
Causa confirmada (investigação ao vivo, spec temporário só de leitura — sem clicar em "Gerar
Relatório", sem criar solicitação real): guidLabels() (RelatorioPage.js) usava
cy.get('p.MuiTypography-root:visible') — um comando que trava e estoura timeout se achar ZERO
elementos, mesmo isso sendo o resultado normal pra 9 dos 10 tipos de relatório (não existe rótulo
"Guid X" nenhum na tela pra eles). Inspecionando o DOM real: os p.MuiTypography-root de "Tipo de
Relatório"/"Período" EXISTEM e a query funciona na maioria das vezes — mas quando a renderização
demora (mesmo padrão de lentidão variável do Electron headless já confirmado hoje no cold-boot do
dashboard, ver entrada anterior), a busca por ZERO resultados (o caso comum) e a busca por
resultados-que-demoraram-a-aparecer (o caso raro) ficam indistinguíveis pro cy.get() — os dois
estouram o mesmo timeout de 10s.
Correção: preencherCamposGuidSeExistirem() não usa mais cy.get() pra essa checagem —
consulta o DOM direto via jQuery dentro de cy.get('body').then(($body) => ...), mesmo padrão já
usado em preencherUltimos10Dias() (que nunca teve esse problema, por já seguir esse desenho).
Uma lista vazia deixa de ser erro — é o caminho normal esperado pra quase todo tipo de relatório.
guidLabels() (o getter em elements) continua existindo, só não é mais usado por esse método.
Achado à parte, mesma leva de falhas: 1 ocorrência isolada (16:03) de
"tela de segundo fator OU login concluído: expected false to be true" (a checagem de 2FA/sem-2FA
adicionada ontem em cy.login()) — mesmo padrão de lentidão variável do Electron headless, não uma
causa nova. Timeout dessa checagem aumentado de 15s pra 30s por precaução (mesmo raciocínio do
timeout do dashboard).
Verificação: sintaxe conferida (node --check) nos 2 arquivos alterados
(RelatorioPage.js, commands.js). Não rodei relatorios.cy.js de ponta a ponta pra confirmar
(cria solicitação real por tipo) — a investigação em DOM real já confirmou a estrutura, e o fix
reaproveita um padrão já comprovado no mesmo arquivo.
Pendente de ação humana: rodar npm run cy:run:com-dados (ou só relatorios.cy.js) uma vez
de verdade pra confirmar que os 10 tipos passam da etapa de Guid sem travar.
2026-08-25 — subconta.cy.js: 7 recorrências de "conta não está ativa" (VS ainda não aprovando) — novo design (1 tentativa, sem retry) funcionando como esperado
Categoria: Instabilidade/ambiente já mapeada (não é bug novo) — só registro de continuidade.
Sintoma: 7 entradas em falhas-pendentes.md (25/08, 11:38-11:47), sempre o mesmo par: o it()
"quando a conta está ativa..." reprova com 400 "Conta Digital [guid] não está ativa" (guid
diferente a cada rodada — conta nova, credenciada na hora), e o it() seguinte ("criar outro
Condomínio... vira subconta da subconta") reprova em cascata porque o 2º Condomínio nunca chegou
a ser criado (depende do 1º ter dado certo).
Causa confirmada: mesmo padrão já extensivamente documentado neste histórico — o VS não está aprovando contas novas nesta janela de tempo (não é lentidão, só volta com reinício da aplicação em HML). Nenhuma causa nova.
Confirma o design novo funcionando: essas 7 rodadas são, na prática, a primeira validação real das duas mudanças de hoje — 1 tentativa só (sem os 6 retries/30s de antes) e sem o describe "conta inativa" separado. O resultado é exatamente o esperado: falha rápida (sem gastar 30s em retry inútil) e com a mensagem exata do 400 visível na própria falha — nenhuma tentativa mascarada, nenhum "passou sem checar nada".
Correção: nenhuma — comportamento correto do teste diante de um ambiente que genuinamente não está aprovando contas agora.
Pendente de ação humana: mesma de sempre — reinício da aplicação em HML (fora do escopo deste projeto). Rodar de novo quando o VS estiver aprovando normalmente, pra ver o describe passar de ponta a ponta com a nova estrutura.
Atualização (mesmo dia, 11:52-11:53): mais 4 ocorrências, exatamente o mesmo padrão (guids
diferentes, sempre 400 "não está ativa" na 1ª tentativa, cascata no 2º it()). VS segue sem
aprovar contas novas nesta janela — nenhuma informação nova, só mais confirmação de continuidade.
2026-08-25 — subconta.cy.js: describe "conta inativa" removido — o teste podia passar sem checar nada
Achado do usuário: o it() do describe "Subconta - conta inativa (fluxo acaba aqui)" tinha um
if (statusCode !== 400) { log(...); return; } no início — ou seja, se a resposta não fosse
exatamente 400 "não está ativa", o teste saía sem rodar NENHUMA asserção, e mesmo assim aparecia
✓ verde (Mocha conta "sem asserção falhou" como passou). Não dava pra distinguir, olhando só o
resultado, "confirmei de verdade o comportamento" de "não testei nada nessa execução" — os dois
casos ficavam idênticos visualmente.
Decisão do usuário: em vez de consertar essa distinção (cogitado: this.skip() quando não for
400), simplificar removendo o describe inteiro. Raciocínio: "não está ativa" não é um cenário
válido a testar separadamente — é um ERRO que não deveria acontecer numa conta recém-credenciada,
e precisa aparecer como falha visível. Isso já é exatamente o que o describe "conta ativa +
subconta da subconta" faz (seu primeiro it() reprova mostrando a resposta 400 quando a conta não
ativa, e segue o fluxo normal — criar o 2º Condomínio, checar subconta — quando ativa). Manter os
dois describes era redundante: o "conta inativa" só existia pra reafirmar, com um teste à parte
(e uma Administradora+Condomínio real extra), algo que o outro describe já cobre como efeito
colateral do seu próprio fluxo principal.
Correção: describe "Subconta - conta inativa (fluxo acaba aqui)" removido inteiro de
subconta.cy.js. O arquivo ficou com 2 describes (antes 3): "conta ativa + subconta da subconta"
e "CNPJ duplicado sem permissão de subconta" — 1 Administradora+Condomínio real a menos criada por
execução completa do spec.
Verificação: sintaxe conferida (node --check) — não rodei de verdade (mesma cautela de
sempre, cria dado real). scripts/build-readme.js e README.md atualizados (a descrição do
arquivo não citava mais um cenário "conta inativa" à parte).
Pendente de ação humana: rodar de verdade uma vez pra confirmar que o describe restante reprova claramente quando a conta vem inativa (comportamento já esperado, só falta ver rodando).
2026-08-25 — subconta.cy.js: habilitarSubcontaComRetry (6 tentativas, 5s cada) virou 1 tentativa só, a pedido do usuário
Contexto: o describe "Subconta - conta ativa + subconta da subconta" tentava "Habilitar
Subconta" até 6x (5s de espera entre cada) esperando o VS aprovar a conta — mesmo raciocínio do
gerarBoletoComRetry de boletoRegressao.cy.js. Rodando de verdade, isso gastava ~30s pra sempre
terminar em 400 "não está ativa" mesmo assim (o VS não estava aprovando contas novas nesta janela
de tempo).
Pedido do usuário: "não precisa tentar clicar em habilitar subcontas tantas vezes, só uma vez é suficiente, retornou inativa segue o fluxo" — coerente com o que este histórico já confirmou: "não está ativa" não é uma questão de tempo que retry resolve (só reinício da aplicação em HML) — insistir com retry só atrasa o resultado sem mudar nada.
Correção: removida a função habilitarSubcontaComRetry — o describe "conta ativa + subconta
da subconta" agora clica em "Habilitar Subconta" 1 vez só, igual ao describe "conta inativa" já
fazia. Se voltar "não está ativa", os it()s reprovam mostrando essa resposta na hora — sem
esperar 30s pra chegar no mesmo resultado.
Nota: as 3 falhas que motivaram essa mudança (falhas-pendentes.md, 25/08 11:30-11:35, todas
"Conta Digital [...] não está ativa" no describe "conta ativa + subconta da subconta") não são bug
— são o comportamento correto agora: o VS não estava aprovando contas novas nesse intervalo (mesmo
padrão de sempre), e o teste, com 1 tentativa só, reporta isso direto, sem mascarar atrás de
retry. Nenhuma ação adicional necessária nelas.
Pendente de ação humana: rodar de novo quando o VS estiver aprovando contas normalmente, pra confirmar que o describe "conta ativa + subconta da subconta" passa de ponta a ponta com 1 tentativa só (sem precisar do retry que foi removido).
2026-08-25 — cypress open aberto durante a investigação anterior: "This session already exists" — não é bug, é cache de sessão do próprio Cypress
Categoria: Pegadinha operacional (não é bug de teste nem de produto) — vale documentar porque
vai se repetir sempre que alguém editar commands.js com um cypress open já aberto.
Sintoma: logo depois do ajuste de timeout da entrada anterior, aplicacaoSanity.cy.js passou
a falhar com CypressError: This session already exists. You may not create a new session with a previously used identifier... call cy.session() with a unique identifier other than anibal.neto.
Causa confirmada: o cypress open do usuário ficou aberto (watch mode) durante toda a
investigação anterior, e cy.session('anibal.neto', setupFn, { validate }) guarda em memória, por
processo, a função de setup/validate usada a primeira vez que rodou. Cada salvamento de
commands.js com um validate() diferente (testei 3 versões: sem timeout extra, com
cy.intercept de investigação, timeout final de 45s) reexecuta o teste com código novo mas o
MESMO identificador de sessão (user, vindo de cypress.env.json) — e o Cypress recusa,
de propósito, criar uma sessão "diferente" sob o mesmo nome, pra evitar comportamento
inconsistente entre testes que pensam estar usando a mesma sessão.
Correção: nenhuma no código — não é bug. Resolvido reiniciando o cypress open (ou clicando
em "Clear All Sessions" na barra lateral do Test Runner), que limpa o cache em memória e recarrega
a versão atual do arquivo do zero.
Lição pra próxima vez: editar cypress/support/commands.js (principalmente a definição de
cy.session() dentro de cy.login()) enquanto um cypress open está aberto SEMPRE vai disparar
esse erro depois da 2ª edição em diante — reiniciar o runner (ou fechar antes de editar, reabrir
depois) evita a confusão. Mesma categoria de cuidado que já existia pra specs de dado real (nunca
deixar cypress open salvando repetidamente), mas por um motivo diferente aqui — não é dado real
criado, é cache de sessão em memória.
Pendente de ação humana: nenhuma.
2026-08-25 — Cold boot da SPA depois do login estoura o timeout padrão (10s) só em Electron headless — sem 2FA, o headless agora chega longe o suficiente pra esbarrar nisso
Sintoma: usuário reportou aplicacaoSanity.cy.js (spec de sanity, cypress/e2e/sanity/) e
smoke.cy.js ("Dashboard carrega após login") falhando em cypress run (headless) com Timed out retrying after 10000ms: expected '.../app' to include '/app/dashboard/inicio' — mas
confirmou que rodando com interface (cypress open) e navegando na mão no produto real,
tudo funciona normal. Ou seja: nem bug de produto, nem bug geral de automação — só acontece em
cypress run.
Causa confirmada (investigação ao vivo, cy.intercept({url:'**'}) temporário dentro do
validate() de cy.session, ver protocolo em triagem-de-falhas.md): depois do login, a SPA
faz um cold boot — baixa e processa vários chunks JS lazy-loaded (react-router-dom,
AuthenticatedApp, partner-bank-light, date-pickers, Breadcrumbs, Link, etc.) e só DEPOIS
disso chama GET .../adm/usuarios/atual e redireciona pra /app/dashboard/inicio. Rodando esse
boot repetidas vezes hoje, o tempo total variou bastante — de ~9s a ~35-40s — sempre com todas
as chamadas respondendo 200, nunca um erro de API real envolvido. Ou seja: é lentidão de
renderização no Electron headless (sem aceleração de GPU), não instabilidade de backend (diferente
de praticamente todo outro achado deste histórico até agora).
Por que só apareceu agora: antes da remoção do 2FA do usuário de testes (ver entrada de
24/08 sobre cy.login()), login em headless NUNCA completava sem totpSecret — o teste sempre
morria na tela de código, bem antes de chegar nesse cold boot. Sem 2FA, o headless finalmente
avança o suficiente pra esbarrar nesse teto de tempo que sempre existiu, só nunca tinha sido
alcançado.
Correção: timeout explícito maior nas duas asserções que checam a URL do dashboard logo após
login — cy.url({ timeout: 45000 }) em vez do padrão de 10s implícito:
cy.login()→validate()decy.session, emcypress/support/commands.js.smoke.cy.js, teste "Dashboard carrega após login".
45s dá margem sobre o pior caso observado hoje (~35-40s). Nenhuma outra tela/spec precisou de
ajuste — só essas duas fazem essa checagem específica logo após um cy.visit('/') fresco.
Verificação: aplicacaoSanity.cy.js passou de forma consistente depois do ajuste (rodado
várias vezes). Não foi possível confirmar com o mesmo rigor em smoke.cy.js completo dentro desta
sessão — a suíte inteira é mais pesada e este ambiente já estava sob uso intenso de repetidas
execuções ao longo da investigação, o que pode ter inflado a lentidão observada além do normal.
Pendente de ação humana: rodar npm run cy:run:smoke e npm run cy:run:sanity numa máquina
"descansada" (sem dezenas de execuções Cypress em sequência antes) pra confirmar que 45s é
suficiente em condições normais de uso — se continuar estourando, considerar investigar o motivo
do cold boot em si ser tão mais lento no Electron headless (não só aumentar o timeout de novo).
2026-08-25 — subconta.cy.js (spec novo): cenário "conta inativa" pegou 200 em vez do 400 esperado — VS aprovou rápido demais, não é bug
Categoria: Instabilidade de ambiente já conhecida (timing de aprovação do VS, ver "Causa raiz de 'Conta digital não está ativa'" em entradas anteriores deste histórico) — afetando um teste novo pela 1ª vez, corrigido pra tolerar.
Sintoma: status ao habilitar subconta numa conta recém-criada: expected 200 to equal 400 —
depois de corrigir os 2 problemas anteriores (URL da listagem, scroll do botão), o cenário "conta
inativa" (clica em Habilitar Subconta logo após criar, sem esperar) recebeu sucesso (200) em vez
da rejeição por conta inativa que o teste esperava.
Causa confirmada: não é bug — o VS aprovou a conta rápido o bastante, no tempo entre a criação via API e o clique pela tela (login + navegação + render), pra ela já estar ativa nesse instante. Mesma variabilidade de timing já extensivamente documentada neste histórico pro fluxo de Boletos — só que aqui, pela 1ª vez, "rápido demais" quebra o teste (ali era sempre "devagar demais" que quebrava).
Correção: subconta.cy.js — o it() do cenário "conta inativa" agora confere o status
primeiro: se vier diferente de 400, registra um aviso (cy.task('log', ...)) explicando que o
cenário não teve chance de disparar nessa execução, e sai sem reprovar o teste por um motivo que
não é nosso — mesmo padrão já usado em BoletoPage.shouldShowDetalhes() pro aviso de
"REGISTRO_CRIADO".
Efeito colateral real: como a resposta foi 200, a subconta desse cenário específico foi
habilitada de verdade (irreversível) — não afeta os outros 2 describes (cada um cria sua
própria Administradora/Condomínio), só um detalhe a mais de dado real criado nesta execução.
Pendente de ação humana: rodar de novo pra ver o spec completo passar — ainda sem 1ª execução de ponta a ponta confirmada (2 bugs de seletor + esta tolerância corrigidos até aqui, mas o resto do fluxo — conta ativa, subconta da subconta, CNPJ duplicado — segue sem confirmação real).
2026-08-25 — subconta.cy.js (spec novo): botão "Habilitar Subconta" dava timeout "not visible" — fora da área visível sem rolar
Categoria: Bug real no teste (Page Object novo), corrigido — achado logo depois de corrigir o 404 anterior (mesmo spec, mesma sessão de 1ª execução real).
Sintoma: Timed out retrying after 10000ms: expected <button...> to be 'visible' — This element is not visible because its content is being clipped by one of its parent elements, which has a CSS property of overflow: hidden, scroll or auto, na asserção .should('be.visible') de
goToCadastro() sobre o botão "Habilitar Subconta". Usuário confirmou rolando a tela na mão que o
botão aparece normal — não é um problema de renderização, só de área visível.
Causa confirmada: o botão fica no fim de um formulário longo, abaixo da dobra. .should('be.visible')
sozinho não rola a página — diferente de .click()/.type(), que rolam o elemento pra área
visível automaticamente antes de agir. Como goToCadastro() só fazia a asserção de visibilidade
(sem nenhuma ação antes), o elemento nunca saía da área clicada por overflow.
Correção: ContaDigitalBoletoPage.js
goToCadastro() — .scrollIntoView() antes do .should('be.visible').
Pendente de ação humana: rodar subconta.cy.js de novo pra confirmar — ainda sem 1ª execução
completa de ponta a ponta.
2026-08-25 — subconta.cy.js (spec novo): 404 na 1ª execução real — goToListagem() visitava /app/conta-digital sem o sufixo /listar
Categoria: Bug real no teste (Page Object novo), corrigido — achado na 1ª execução de verdade de um spec recém-criado.
Sintoma: rodando subconta.cy.js pela 1ª vez (cy.open), o app caiu numa tela 404 ("Oops,
página não encontrada!") em algum ponto do fluxo de ContaDigitalBoletoPage.goToCadastro(). O
usuário confirmou que fazendo a mesma navegação na mão (filtrar Administradora → clicar
"Cadastro") funcionava normal — descartando regra de negócio quebrada, apontando pra algo
específico da automação.
Causa confirmada: ContaDigitalBoletoPage.goToListagem() visitava /app/conta-digital —
mas a URL real da listagem é /app/conta-digital/listar, com o sufixo. Sem o sufixo, a
navegação cai num redirecionamento estranho que deixa a página num estado inconsistente; como
goToCadastro() antigo passava por goToListagem() antes de buscar/expandir/clicar, a sequência
inteira ficava comprometida e terminava no 404. Confirmado comparando 2 screenshots reais do
usuário: a barra de endereço durante a navegação manual mostrou /app/conta-digital/listar
(listagem) e /app/conta-digital/{guid}/cadastro (detalhe) — as 2 URLs reais, uma delas
diferente do que o código tinha.
Correção:
ContaDigitalBoletoPage.jsgoToListagem()corrigido pra/app/conta-digital/listar.goToCadastro(guid)simplificado: a URL de detalhe (/app/conta-digital/{guid}/cadastro) também foi confirmada real nesse mesmo screenshot — trocado o fluxo antigo (busca por Guid → expande linha → clica link "Cadastro") porcy.visit()direto nela, eliminando 3 passos frágeis de uma vez (mesmo raciocínio já usado emBoletoPage/RelatorioPage/AplicacaoPage: ir direto pra URL em vez de depender de timing de UI).
Pendente de ação humana: rodar subconta.cy.js de novo com a correção pra confirmar que
resolve — ainda não validado de ponta a ponta (o resto do fluxo, cenários de conta ativa/inativa
e subconta da subconta, continua sem 1ª execução real completa).
2026-08-25 — relatorios.cy.js: os 10 tipos de relatório falharam em p.MuiTypography-root:visible/.filter() — hipótese levantada, causa NÃO confirmada
Categoria: Achado pendente de investigação no DOM real — triado a partir de falhas-pendentes.md
(10 entradas, uma por tipo de relatório, todas na mesma execução de 25/08 entre 08:42 e 08:49).
Sintoma: todo it() de relatorios.cy.js (os 10 tipos, sem exceção) falhou no mesmo lugar —
metade com Expected to find element: p.MuiTypography-root:visible, but never found it, a outra
metade com Expected to find element: filter, but never found it. Queried from: > cy.get(p.MuiTypography-root:visible)
(a mesma cadeia de comando, só que o retry do Cypress atribuiu o timeout ao .filter()
encadeado em vez de ao cy.get() em si — provavelmente diferença de timing entre as execuções,
não uma causa diferente).
Hipótese (não confirmada — sem sessão logada aberta pra inspecionar o DOM real):
RelatorioPage.preencherCamposGuidSeExistirem() é chamado incondicionalmente pra TODO tipo de
relatório (relatorios.cy.js, linhas 48 e 57 — não só pra "Transferências Pagas", que é o único
tipo que de fato tem campos Guid). Esse método depende de guidLabels(), que faz
cy.get('p.MuiTypography-root:visible') sem condicional — e cy.get() estoura timeout se o
seletor não casar NENHUM elemento na tela. Os 10 tipos que falharam batem exatamente com os 10
tipos de TIPOS_RELATORIO, na mesma ordem de execução — ou seja, é sistêmico, não específico de
"Transferências Pagas". Isso sugere que p.MuiTypography-root:visible não está mais casando
NENHUM elemento nessa tela hoje, pra nenhum tipo — mudança de biblioteca/CSS/estrutura mais ampla
do que o método original previa, não só um campo Guid quebrado.
Por que não fui além: confirmar isso exige abrir a tela de verdade (sessão logada) e inspecionar
o DOM — não é algo que dá pra concluir só lendo código/erro de fila, e o CLAUDE.md deste projeto
é explícito sobre nunca corrigir seletor no chute. Esta sessão não tem uma sessão logada aberta
agora pra fazer essa inspeção.
Correção: nenhuma ainda — RelatorioPage.js/relatorios.cy.js não foram tocados.
⚠️ Cuidado ao investigar: relatorios.cy.js mora em com_dados/ — cada execução gera
solicitação real. Reproduzir isso rodando a suíte de novo repetidamente pra depurar tem o mesmo
risco já documentado (efeito colateral real a cada tentativa) — melhor reproduzir manualmente 1
tipo na tela antes de rodar o spec de novo.
Pendente de ação humana: abrir a tela de Relatórios de verdade, selecionar um tipo que NÃO seja
"Transferências Pagas" e inspecionar se existe algum p.MuiTypography-root:visible na página nesse
momento — confirma ou derruba a hipótese acima antes de qualquer correção em RelatorioPage.js.
2026-08-25 — boletoSimulaErroEmissao.cy.js: "cliente sem CPF/CNPJ" devolveu 400 de novo (2ª ocorrência) — ainda sem confirmar se é correção real
Categoria: Reforço de um achado já pendente (ver entrada de 21/08, "possível correção real, ainda NÃO confirmada") — mesma incerteza, agora com mais um data point.
Sintoma: o mesmo teste (cliente sem CPF/CNPJ... API vaza erro 500 de banco) falhou de novo
com expected 400 to equal 500, dessa vez em 25/08 — 4 dias depois da 1ª ocorrência (21/08), em
execução separada.
Por que isso importa: a entrada de 21/08 já registrava que não dava pra descartar que o 400
fosse efeito da instabilidade geral do ambiente daquele dia (mesma execução também pegou ruído de
"conta não está ativa" no teste vizinho). Essa 2ª ocorrência, em outro dia, sem o mesmo ruído
associado nesta fila específica, é evidência a favor de ser uma mudança real de comportamento —
mas ainda não é confirmação: a fila automática, de novo, só capturou resposta.status, não o
corpo completo do 400 (mesma limitação já registrada). Continua sem saber se o 400 vem com uma
mensagem de validação de verdade (ex.: "cpfCnpj é obrigatório").
Correção: nenhuma ainda — boletoSimulaErroEmissao.cy.js continua com a asserção 500
(comportamento documentado, não mudar no chute).
Pendente de ação humana: mesma pendência de 21/08 — rodar de novo e olhar resposta.body
completo do 400 (ex.: via Postman ou log manual) antes de decidir se atualiza o teste +
docs/regras-de-negocio.md. Com 2 ocorrências agora, vale priorizar confirmar isso.
2026-08-24/25 — Recorrências de instabilidades já documentadas (16 entradas de falhas-pendentes.md) — nenhuma causa nova, nenhuma correção de código
Categoria: Instabilidade/ambiente já mapeada — só registro de continuidade, pra manter o histórico fiel (ver protocolo: registrar mesmo sem correção).
Triando o restante de falhas-pendentes.md (25/08), o resto se encaixa em 3 padrões já
extensivamente documentados neste arquivo antes — nenhum é informação nova:
- Grupo
dda-api/webhook-api/adm/conta-digital-apiretornando 500 (12 entradas: DDA > Consumo/Boletos/Empresas/Aplicações, Conta Condominial > Webhook/Geral — 2 rodadas completas do smoke, 24/08 ~08:38 e 25/08 ~09:00). Mesmos 3 grupos de endpoint, mesmos status, já mapeados em detalhe nas entradas de 21/08 ("Causa raiz de 'Conta digital não está ativa'..." e "🔎 Mapa completo dos 3 grupos de erro 500"). Backend de homologação, fora do nosso controle. - "conta digital não está ativa" (ruído de ambiente já esperado pelo próprio código do teste)
— 3 ocorrências:
boletoRegressao.cy.js"guid de Administradora... precisa SEMPRE ser barrado" (2x, 24/08) eboletoSimulaErroEmissao.cy.js"código externo repetido" (1x, 25/08). Os 2 testes já têm lógica própria pra detectar esse ruído e abortar sem concluir nada de errado (mensagem "Rodar de novo" no 1º caso) — comportamento funcionando como projetado, não bug. /signintimeout no smoke (1 ocorrência, 24/08 15:44) — mesma limitação detotpSecretausente neste ambiente local, já documentada extensivamente (entradas de 20/08, 21/08, 24/08).
Correção: nenhuma — nenhum dos 3 padrões acima é acionável do lado do teste.
Pendente de ação humana: nenhuma nova (as pendências já registradas nas entradas originais —
totpSecret real em cypress.env.json, e o backend de homolog resolver a instabilidade de
ativação — continuam de pé).
2026-08-24 — smoke.cy.js: "Contas Geradoras > Alteração em Lote" voltou a estourar timeout em ant-menu-inline — 1 ocorrência isolada, provável lentidão pontual
Categoria: Instabilidade passageira (não regressão do fix de 20/08).
Sintoma: expected '<ul.ant-menu...ant-menu-inline-collapsed...>' to have class 'ant-menu-inline'
— mesma mensagem de erro da classe de bug já corrigida em 20/08 (MenuPage.expandirMenu() lia o
DOM 1x só, sem esperar o menu montar).
Por que não é a mesma causa de volta: expandirMenu() já foi reescrito em 20/08 pra usar
cy.get('.ant-menu-root', {timeout: 15000}) com retry de verdade — essa correção segue no código.
Só 1 execução, entre várias rodadas completas de smoke nos últimos 2 dias, apresentou isso — não é
um padrão se repetindo (diferente do que aconteceria se o fix tivesse regredido). Leitura mais
provável: ambiente/rede lento o bastante naquele momento pra estourar até o timeout de 15s já
alargado — mesmo tipo de lentidão já visto em outros contextos neste histórico.
Correção: nenhuma — se voltar a se repetir (virar padrão, não caso isolado), reconsiderar como "Seletor/DOM desatualizado" e investigar de novo com o DOM real.
Pendente de ação humana: nenhuma, a menos que volte a acontecer com frequência.
2026-08-25 — CLAUDE.md não listava boletoRegressao.cy.js entre os specs que criam dado real
Categoria: Lacuna de documentação (não é falha de teste) — achada durante uma varredura pedida
pelo usuário pra achar .cy.js redundante/sem necessidade na suíte.
Contexto: ao comparar boletoViaApi.cy.js (pontual) com boletoRegressao.cy.js (regressão)
pra avaliar se um deveria absorver o outro, reli o cabeçalho de boletoRegressao.cy.js e reparei
que ele mesmo avisa: "⚠️ Cuidado com dados reais: cria 1 Administradora + 1 Condomínio de verdade
em homologação [...] e-mail de notificação real incluído" — mas a seção "Cuidado com dados reais"
do CLAUDE.md (a lista que existe justamente pra alguém saber, antes de rodar algo, quais specs
têm efeito colateral real) não mencionava esse arquivo, só boletoViaApi.cy.js,
relatorios.cy.js, contaGeradora.cy.js, boletoSimulaErroEmissao.cy.js e
contaCorrenteRegressao.cy.js.
Risco real: alguém (humano ou Claude, em outra sessão) lendo só o CLAUDE.md pra decidir se é
seguro deixar cypress open em watch mode com regressao/ aberto não teria como saber que
boletoRegressao.cy.js também cria Administradora/Condomínio reais a cada execução — o mesmo tipo
de incidente de spam de e-mail já registrado antes (ver entrada de 19/08) poderia se repetir por
esse spec especificamente, sem aviso.
Não foi correção de código de teste — os 3 candidatos a fusão/remoção levantados na varredura
(contaCorrente.cy.js × contaCorrenteRegressao.cy.js, boletoViaApi.cy.js ×
boletoRegressao.cy.js, aplicacao.cy.js × aplicacaoSanity.cy.js) foram todos confirmados como
não redundantes — cada um testa algo que o outro não cobre (fonte de dado diferente, camada
UI×API diferente, ou regra de negócio só coberta num deles). Nenhum spec foi removido/fundido.
Correção: CLAUDE.md, seção "Cuidado com dados reais" — boletoRegressao.cy.js adicionado à
lista de specs que criam dado real, e à nota final que explica por que contaCorrenteRegressao.cy.js
mora em regressao/ mesmo criando dado real (agora cobre os dois).
Pendente de ação humana: nenhuma.
2026-08-24 — cy.login() travava depois que o usuário de testes teve o 2FA removido
Sintoma: usuário reportou ter removido a autenticação de dois fatores do usuário de testes.
Rodando a suíte depois disso, smoke.cy.js (teste "Dashboard carrega após login") falhou no
before each, dentro de cy.session: AssertionError: Timed out retrying after 10000ms: expected '.../signin' to not include '/signin' — o mesmo texto de erro da limitação conhecida
de totpSecret ausente, mas por uma causa DIFERENTE dessa vez.
Causa confirmada: cy.login() (cypress/support/commands.js) sempre assumia que a tela de
segundo fator ia aparecer depois de usuário/senha — LoginPage.elements.otpInputs().should('be.visible')
sem condicional nenhuma. Sem 2FA configurado pra esse usuário, a tela de OTP nunca aparece (o
login vai direto pro dashboard) — o comando ficava esperando por um elemento que nunca ia existir,
até estourar timeout.
Correção: cy.login() passou a esperar por QUALQUER UM dos dois sinais depois de enviar
usuário/senha — a tela de OTP aparecer, ou o login já ter concluído direto (input[name="username"]
sumiu da tela) — em vez de assumir que o segundo fator sempre vai pedir. Só entra no fluxo de OTP
(automático via totpSecret, ou cy.pause() assistido) se a tela realmente pedir; se não pedir,
loga isso via cy.log() e segue direto pras asserções finais de "saiu da tela de login". Com 2FA
ainda ativo (caso de outros usuários, ou se for reativado depois), o comportamento não muda.
Verificação: sanity check headless de login.cy.js neste ambiente (onde o usuário configurado
em cypress.env.json ainda pede 2FA) — continua batendo na limitação já conhecida de totpSecret
ausente, comportamento idêntico a antes da mudança. Não dá pra confirmar aqui o caminho "sem 2FA"
de ponta a ponta (esse ambiente de sandbox não tem acesso ao usuário real do usuário com 2FA
removido) — precisa confirmar rodando a suíte de verdade no ambiente dele.
Pendente de ação humana: rodar cypress open (ou cy:run:smoke/cy:run:login headless, já
que sem 2FA não depende mais de totpSecret) no ambiente onde o 2FA foi removido, pra confirmar
que o login conclui sem passar pelo cy.pause().
2026-08-24 — Reorganização (2ª passada): dados-reais/ virou casos_de_teste/com_dados + casos_de_teste/sem_dados, e achamos 1 spec mal classificado
Categoria: Mudança de estrutura de projeto (não é falha de teste) — segue a entrada anterior
sobre a criação de dados-reais/, agora substituída por essa segunda passada.
Motivação: discutindo a organização com o usuário, ficou claro que agrupar por categoria
(smoke/regressão/pontual) e só o pontual ter uma subdivisão por dado-real (dados-reais/ como
exceção visível, resto da raiz implicitamente seguro) exigia já saber a convenção pra interpretar
"arquivo solto = seguro". Trocado por uma pasta-mãe casos_de_teste/ com dois filhos nomeados
explicitamente — com_dados/ e sem_dados/ — pra nenhum lado ficar implícito. smoke/ e
regressao/ não mudaram (o usuário foi explícito: a mudança é só nos specs que antes estavam na
raiz de cypress/e2e/ + dados-reais/).
Mudança:
cypress/e2e/dados-reais/{boletoViaApi,contaGeradora,relatorios}.cy.js→cypress/e2e/casos_de_teste/com_dados/.cypress/e2e/{aplicacao,contaCorrente,login}.cy.js(raiz) →cypress/e2e/casos_de_teste/sem_dados/.- Imports relativos dos 7 arquivos corrigidos (3 níveis de profundidade agora, era 1 pros que
estavam na raiz e 2 pros que já estavam em
dados-reais/). scripts/build-readme.js,README.md,CLAUDE.md,package.json(cy:run:login,cy:run:dados-reais) edocs/regras-de-negocio.mdatualizados pros caminhos novos.
Achado durante a correção (não é sobre a reorganização em si): ao decidir em qual das duas
pastas cada spec entrava, o docblock de boletoSimulaErroEmissao.cy.js revelou que ele cria 1
Administradora + 1 Condomínio reais em homologação no before(), com e-mail de notificação
real — informação que já estava documentada no próprio arquivo, mas nunca tinha sido cruzada
com a lista de specs "seguros" da 1ª reorganização (ele ficou de fora de dados-reais/ na
passada anterior, sem nunca ter sido reavaliado). Corrigido: também foi pra com_dados/, e o
CLAUDE.md (seção "Cuidado com dados reais") passou a citá-lo explicitamente junto dos outros 3.
Sem essa 2ª passada mais rigorosa (nomear os dois lados, não só marcar a exceção), esse spec teria
continuado do lado "seguro" indefinidamente.
Verificação: sanity check headless de toda a árvore
(npx cypress run --spec "cypress/e2e/casos_de_teste/**/*.cy.js") — os 7 specs foram coletados
sem erro de import/sintaxe; todas as falhas foram a limitação de login headless já conhecida
(totpSecret ausente neste ambiente) — nenhuma falha nova.
Correção: nenhuma (é reorganização, não bug) além da reclassificação do
boletoSimulaErroEmissao.cy.js descrita acima. Pendente de ação humana: nenhuma.
Atualização (mesmo dia, comandos npm por pasta): criados cy:run:casos-de-teste,
cy:run:com-dados (substituindo cy:run:dados-reais, pra bater com o nome real da pasta) e
cy:run:sem-dados em package.json, um por pasta de cypress/e2e/, todos headless por padrão
(cypress run já é sem interface — só cy:open abre UI). Rodei npm run cy:run:sem-dados
isolado pra confirmar a resolução do script em si (glob batendo nos 3 arquivos certos) — mesma
limitação de login já conhecida, nenhuma falha nova.
2026-08-24 — Reorganização: cypress/e2e/dados-reais/ isola os specs que criam dado real em homologação
Categoria: Mudança de estrutura de projeto (não é falha de teste) — registrada aqui pela própria disciplina de documentação do projeto (toda mudança estrutural entra no histórico).
Motivação: a distinção "esse spec cria dado de verdade em homologação" x "esse é seguro de
rodar a qualquer momento" só existia em prosa (seção "Cuidado com dados reais" do CLAUDE.md) —
não dava pra ver isso olhando a árvore de cypress/e2e/. Pedido do usuário ("a organização das
pasta ta boa mesmo?"), confirmado via pergunta direta.
Mudança: boletoViaApi.cy.js, relatorios.cy.js e contaGeradora.cy.js (os 3 specs da raiz
de cypress/e2e/ com efeito colateral real — cria Administradora/Condomínio/Boleto, relatório
solicitado, Conta Geradora) moveram para cypress/e2e/dados-reais/. Ajustes que essa mudança
exigiu:
- Imports relativos dos 3 arquivos corrigidos (
../pages/X→../../pages/X,../support/Y→../../support/Y, um nível a mais de profundidade). scripts/build-readme.js: manifestoDESCRICOEScom as novas chaves de caminho, novolistar('cypress/e2e/dados-reais', ...)e bloco de árvore correspondente (mesmo padrão desmoke//regressao/, já quelistar()não é recursivo).README.md: árvore regenerada (npm run readme:build), prosa da seção "Smoke, regressão e testes pontuais" atualizada explicando a subdivisão, e o exemplo de--speccom múltiplos arquivos corrigido pro novo caminho.CLAUDE.md: seção "Cuidado com dados reais" agora referencia a pasta nova.package.json: novo scriptcy:run:dados-reais, mesmo padrão decy:run:smoke/cy:run:regressao.docs/html/regenerado (npm run docs:build).contaCorrenteRegressao.cy.js(também cria dado real, viacy.criarContaCorrenteViaApi) não foi movido — já mora emregressao/por outro motivo (é 1:1 com incidente confirmado), e mover misturaria os dois critérios de organização. A cautela com dado real pra ele continua só em prosa, agora citada explicitamente noCLAUDE.md.
Verificação: sanity check headless dos 3 arquivos movidos
(npx cypress run --spec "cypress/e2e/dados-reais/*.cy.js") — os 3 specs foram coletados sem erro
de import/sintaxe; todas as falhas foram a limitação de login headless já conhecida (totpSecret
ausente em cypress.env.json neste ambiente, ver entradas de 2026-08-20/21 abaixo) — nenhuma
falha nova. Confirma que a reorganização não quebrou nada.
Correção: nenhuma (é reorganização, não bug). Pendente de ação humana: nenhuma.
Achado incidental (não é sobre a reorganização, sobre a captura automática): rodando
boletoViaApi.cy.js sozinho, os 5 describes falharam no próprio before all (mesma causa —
totpSecret ausente), mas nenhuma entrada apareceu em falhas-pendentes.md pra esse arquivo
(0 screenshots também) — diferente de contaGeradora.cy.js/relatorios.cy.js, que falharam no
before each e geraram entrada normalmente. Indício de que a captura automática (afterEach
global) não roda quando é um before all que falha e pula a suíte inteira. Não investigado a
fundo agora (fora do escopo desta reorganização) — só registrado aqui pra não se perder, caso uma
falha real de before all passe despercebida no futuro por não gerar entrada.
2026-08-24 — boletoRegressao.cy.js: cancelamento chegou em CANCELADO pela 1ª vez (era sempre PEDIDO_CANCELAMENTO) — achado pendente de confirmação, NÃO alterado ainda
Categoria: Achado pendente de confirmação — só 1 observação, não é o suficiente pra mudar a
asserção (mesmo padrão de cautela já usado antes neste projeto pra achados de 1 execução só, ver
entrada sobre cpfCnpj 400 vs 500).
Sintoma: o teste "estado terminal do cancelamento é PEDIDO_CANCELAMENTO, não CANCELADO" (que
documenta um comportamento confirmado antes — "esperando bem mais que o timeout de um teste, o
status nunca avançava sozinho além de PEDIDO_CANCELAMENTO") falhou com expected 'CANCELADO' to equal 'PEDIDO_CANCELAMENTO' — ou seja, desta vez o boleto avançou além do que já foi documentado
como terminal.
Por que ainda não mudei o teste: só uma execução mostrando isso não é prova de que o comportamento mudou de vez — pode ser uma coincidência de timing (esse boleto específico teve mais tempo pra processar, já que essa mesma execução tinha outros testes fazendo retry longo por causa da instabilidade do VS, documentada na entrada logo abaixo). Precisa reproduzir de novo, em execuções mais "limpas" (sem os outros testes competindo por tempo/atenção do backend), antes de considerar isso uma mudança real de comportamento.
Correção: nenhuma ainda — boletoRegressao.cy.js continua com a asserção PEDIDO_CANCELAMENTO
(comportamento documentado, não mudar no chute). Pendente: rodar esse cenário isolado (só o
sub-describe "cancelamento") algumas vezes e ver se CANCELADO se repete ou foi só dessa vez.
2026-08-24 — BoletoPage.shouldShowDetalhes() passou a tolerar REGISTRO_CRIADO quando esperava GERADO
Categoria: Correção de teste (não bug de produto) — usuário reportou "diversos erros" em
boletoViaApi.cy.js depois do fallback entrar em commands.js. Causa: nada a ver com o
fallback em si — shouldShowDetalhes() sempre exigiu status: 'GERADO' de forma rígida, e como
o VS está fora do ar (ver entradas acima), o boleto (recém-criado OU do Condomínio de fallback,
tanto faz) fica parado em REGISTRO_CRIADO — um estado intermediário real do fluxo, já
documentado antes, não um bug. O usuário confirmou: "vai retornar como REGISTRO_CRIADO... nesse
cenário tá certo".
Correção: BoletoPage.shouldShowDetalhes() — quando o teste espera 'GERADO' mas a tela
mostra 'REGISTRO_CRIADO', não reprova mais: loga um aviso claro no terminal
(cy.task('log', ...)) explicando a causa (VS não terminou de processar) e pula as checagens de
Nosso Número/Linha Digitável/PIX (campos que só existem quando o boleto está GERADO de verdade —
cobrar a presença deles nesse cenário reprovaria por um motivo que não é nosso). Qualquer OUTRO
status inesperado (ex.: esperava GERADO, veio ERRO_VALIDACAO) continua reprovando normalmente —
só o par específico GERADO-esperado/REGISTRO_CRIADO-real é tolerado.
Verificação: sanity check headless — boletoViaApi.cy.js, 5 testes coletados, sem erro de
sintaxe, morre na limitação de login já conhecida.
Pendente: confirmar via cypress open (2FA manual) que o aviso aparece certo e os campos são
pulados de verdade quando o VS estiver preso — mesma pendência das entradas acima.
Atualização 24/08/2026, 12:53: rodando de verdade (usuário, cypress open), achei mais um
campo com o MESMO problema que a correção acima não cobria: "Código Banco Gerador" também só
existe no DOM quando o boleto está GERADO — um boleto preso em REGISTRO_CRIADO dava timeout
"never found it" nesse campo específico (input[name="codigoBanco"]), mesma causa raiz de Nosso
Número/Linha Digitável/PIX. Corrigido com o mesmo padrão (pularPorRegistroCriado(), já extraído
pra reaproveitar entre os 4 campos). Ou seja, a seção "dados de emissão" do modal de Detalhes tem
4 campos que só existem pós-GERADO, não 3 como o comentário original do arquivo documentava —
codigoBanco entra no grupo.
2026-08-24 — Fallback: guid trocado pro indicado pelo usuário, e confirmado que REGISTRO_CRIADO (não GERADO) é esperado quando o VS está fora
Categoria: Ajuste rápido — a investigação anterior (entrada logo abaixo) tinha ido fundo
demais nas causas do Condomínio de fallback escolhido por mim; o usuário pediu pra simplificar e
indicou o guid certo pra usar: 0a76c9d8-dee4-4c24-afd2-0b7591f9d94a (CNPJ real
73324688000139, razão social COND_d36d414w, confirmado que já tem boleto GERADO de
verdade). Trocado em support/commands.js e boletoRegressao.cy.js.
Esclarecimento do usuário, importante pra não reabrir essa dúvida: com o VS fora do ar, o
boleto gerado contra o Condomínio de fallback fica em REGISTRO_CRIADO (não avança até
GERADO) — isso é o comportamento CORRETO nesse cenário, não um sinal de que o fallback está
quebrado. A checagem do fallback (nos 2 arquivos) já está alinhada com isso: confere só a
resposta IMEDIATA do POST (200/201 = aceito), nunca exige um status final específico.
2026-08-24 — Fallback refinado: log visível no terminal, replicado pra cy.gerarBoletoViaApi() (afeta boletoViaApi.cy.js), e 2 correções encontradas na própria investigação
Categoria: Continuação/correção do fallback implementado na entrada logo abaixo — usuário
reforçou o pedido original (mostrar o erro claramente + usar Condomínio existente) depois de ver
o fallback "funcionar" sem deixar rastro visível, e pediu o mesmo padrão em boletoViaApi.cy.js.
Correção 1 — log invisível: cy.log() só aparece no Command Log da UI do Cypress, NUNCA no
terminal em cypress run (headless, como a maioria das execuções roda) — confirmado. Trocado
por cy.task('log', ...), com uma task nova (log) em cypress.config.js que só faz
console.log() do lado Node — essa sim aparece no terminal nos dois modos.
Correção 2 — achado sério, quase espalhado no chute: ao replicar o fallback pra
cy.gerarBoletoViaApi() (usado por boletoViaApi.cy.js, que confere CNPJ/Razão Social do
Condomínio na TELA de Detalhes), descobri 2 coisas que a entrada anterior não tinha confirmado:
- Os boletos que eu tinha gerado contra o Condomínio de fallback (
0e90580b-...) estavam terminando emERRO_VALIDACAO— não confirmava, sozinho, se o fallback realmente funcionava fim a fim. Investigando o campovalidacoes(só visível no modal de Detalhes da tela, não em nenhuma resposta de API):"Sequencia para gerador de nosso numero da conta bancaria(89), não existe."— uma instabilidade TOTALMENTE diferente do problema do VS (sequência de numeração de boleto, não aprovação de conta), mas não permanente: o MESMO Condomínio já tinha gerado um boleto de verdade antes (statusGERADO, Nosso Número real0000001325612— é o próprioguid_boletocurado empostman/core-homol2.postman_environment.json). - Mais importante: o modal de Detalhes mostra o CNPJ/Razão Social REAIS do Condomínio
(
70.047.325/0001-05/COND_94d931f9) — confirmado inspecionando o boleto que caiu em ERRO_VALIDACAO — mesmo o payload de "Gerar Boleto" tendo enviado umfornecedordiferente. Eu tinha assumido (com base num teste anterior, mais raso) que a API "não cruza" esses campos — verdade só pra ACEITAR a requisição, não pra o que a TELA exibe depois. Se o fallback usasse um CNPJ/razão social inventados (como a 1ª versão fazia), qualquer teste que compareboleto.cnpjCondominiocontra a tela (comoboletoViaApi.cy.jsjá faz) quebraria na hora do fallback disparar.
Correção aplicada: FORNECEDOR_FALLBACK (em commands.js e boletoRegressao.cy.js) agora
usa os dados REAIS do Condomínio de fallback (70047325000105 sem máscara, COND_94d931f9), não
mais um placeholder inventado.
Onde o fallback foi replicado: cy.gerarBoletoViaApi() (support/commands.js) — usado por
TODOS os describes de boletoViaApi.cy.js. gerarBoletoComRetry() não lança mais erro
especificamente pro caso "não está ativa" esgotado (continua lançando pra qualquer outro erro);
gerarBoleto() detecta esse caso, loga (cy.task('log', ...)) e refaz a chamada contra o
Condomínio de fallback. O resultado (guidCondominio/cnpjCondominio/razaoSocialCondominio/
usouCondominioFallback) reflete o Condomínio REALMENTE usado — inclusive nas chamadas
subsequentes de overrides.cancelarApos/overrides.statusEsperado, que antes usavam a variável
guidCondominio original (capturada antes do possível fallback) e ficariam erradas se o
fallback tivesse disparado.
Verificação: sanity check headless — boletoRegressao.cy.js (8 testes) e boletoViaApi.cy.js
(5 testes) juntos, 13 testes coletados, sem erro de sintaxe, morrem na limitação de login
já conhecida (esperado — não dá pra rodar o fluxo completo do fallback sem 2FA manual).
Pendente: confirmar o fluxo completo via cypress open (2FA manual) no momento em que o VS
estiver preso de novo — inclusive conferir se boletoViaApi.cy.js realmente mostra
70.047.325/0001-05/COND_94d931f9 na tela quando o fallback dispara, fechando o ciclo dessa
correção.
2026-08-24 — boletoRegressao.cy.js ganhou fallback: quando o VS não aprova a conta nova, troca pra um Condomínio já existente e ativo
Categoria: Melhoria de resiliência do teste (a pedido do usuário) — não é bug de produto nem
correção de asserção, é sobre o before() continuar dando um resultado ÚTIL mesmo quando bate na
instabilidade real do VS (ver as 2 entradas logo abaixo).
Problema que motivou: sem fallback, quando o VS não aprova a Administradora/Condomínio
recém-criados, o before() NÃO lança erro (o gerarBoletoComRetry original só devolve a última
resposta, não lança) — só que codigoExternoOriginal/guidCondominio ficam "montados" em cima
de um boleto que nunca existiu de verdade. Resultado: TODOS os it()s do arquivo falham, cada um
com uma mensagem diferente e nenhuma delas aponta claramente pra causa raiz (VS não aprovou) —
alguém investigando teria que already saber do problema pra entender o padrão.
Correção: o before() agora detecta esse cenário específico (mesma mensagem "não está
ativa" persistindo depois do retry) e troca guidCondominio/cnpjCondominio/
razaoSocialCondominio por um Condomínio JÁ EXISTENTE e confirmadamente ativo no ambiente
(mesmo guid usado na investigação de causa raiz — 0e90580b-46a9-4f61-b3f8-ef8b2ed28f34, também
curado em postman/core-homol2.postman_environment.json). Os testes seguintes continuam
validando o comportamento real da API, só que contra um Condomínio estável em vez do recém-criado
— e um cy.log() explícito, mais a variável usouCondominioFallback, deixam claro quando isso
aconteceu (não esconde o problema, só evita que ele bloqueie a suíte inteira).
Por que o fornecedor do boleto não usa o CNPJ/razão social reais desse Condomínio:
confirmado testando (nesta mesma investigação) que a API não cruza esses campos com o guid
informado em codigo — aceita qualquer valor. Por isso usa um valor genérico, claramente
identificado como fallback, em vez de buscar o dado real (que nem seria necessário).
Verificação: sanity check headless — 8 testes coletados, sem erro de sintaxe, morre no login
(esperado — definirContaGeradora precisa da sessão). A lógica do fallback em si já foi validada
nos 2 blocos que a compõem, separadamente: conta nova presa em "não está ativa" (confirmado, 66s
sem ativar) e o Condomínio de fallback aceitando "Gerar Boleto" normalmente (confirmado, 200).
Validação fim a fim dentro do Cypress (com o before() de verdade acionando o fallback) fica
pendente de uma execução via cypress open no momento em que o VS estiver preso.
Pendente: nenhuma ação de código — só confirmar o fluxo completo quando o VS estiver preso de
novo numa execução real via cypress open.
2026-08-24 — Isolado: NÃO é outage geral do VS — só a aprovação de conta NOVA está travada, contas antigas funcionam normal
Categoria: Continuação da investigação de causa raiz (ver entrada logo abaixo, sobre "não está ativa" precisar de reinício em HML) — usuário pediu pra achar o que está causando isso.
Teste feito: com o VS confirmadamente travado agora (uma Administradora+Condomínio novos,
criados isolados, sem nada mais rodando em paralelo, ficaram 66s sem ativar — 20 tentativas, 3s
cada), testei gerar boleto pro guid_condominio REAL e ANTIGO já curado no ambiente Postman de
contrato (0e90580b-46a9-4f61-b3f8-ef8b2ed28f34, não criado por mim agora) — usando uma
Administradora nova só pra ter um token (confirmado antes: a API não valida posse nesse campo).
Resultado: aceito na hora (200, RECEIVED) — sem nenhum erro. Condomínio antigo funciona
100% normal, no MESMO instante em que conta nova não aprova.
O que isso prova: não é um outage geral do VS (se fosse, o Condomínio antigo também falharia agora). É especificamente a APROVAÇÃO DE CONTA NOVA que está travada — contas já aprovadas antes continuam funcionando sem problema nenhum. Isso é consistente com um worker/processo específico de aprovação de conta nova que travou (precisa reiniciar a aplicação em HML pra voltar, conforme o usuário já tinha dito) — não com o VS inteiro fora do ar.
Relevância pra pergunta original do usuário ("o código pode estar causando isso?"): esse
achado é um dado a mais, não uma resposta definitiva — ainda não dá pra provar CAUSA sem acesso
ao log/monitoramento do próprio VS. Mas confirma que o problema é ESPECÍFICO do fluxo "aprovar
conta nova" — exatamente o fluxo que cy.gerarBoletoViaApi(), cy.criarContaCorrenteViaApi(),
boletoRegressao.cy.js e toda investigação desta sessão martelam repetidamente, criando
Administradora+Condomínio novos a cada execução. Reforça (sem provar) a hipótese de volume como
gatilho.
Pendente: só quem administra o VS consegue confirmar de fato, cruzando log/monitoramento com horário das criações. Recomendo perguntar especificamente: "o worker de aprovação de conta nova trava sob volume alto de credenciamento?" — pergunta mais precisa agora do que antes deste teste.
2026-08-24 — Causa raiz de "Conta digital não está ativa" finalmente confirmada: não é lentidão/fila, é o VS não aprovando — só volta com reinício manual da aplicação em HML
Categoria: Correção de entendimento — várias entradas anteriores neste arquivo (20/08, 21/08,
24/08) tratavam essa mensagem como "instabilidade"/"lentidão de ativação assíncrona" e usavam
retry com espera (gerarBoletoComRetry, até 25 tentativas em algumas investigações) supondo que
mais tempo resolveria. Essa suposição estava errada.
Causa real, confirmada pelo usuário: a conta digital não é aprovada pelo VS — por causa disso o token dela nunca é gerado, e ela nunca sai do estado "não está ativa". Não é questão de tempo: esperar mais (retry, 2s, 10s, 50s, minutos) nunca resolve sozinho. Só volta a funcionar quando alguém reinicia a aplicação em homologação.
O que isso corrige, retroativamente:
- A hipótese de "volume de requisições da nossa suíte sobrecarregando uma fila" (levantada numa pergunta do usuário nesta mesma sessão) não se aplica — não é fila, é aprovação que falha e não se recupera sozinha.
- As investigações que ficaram "inconclusivas" por causa dessa mensagem (ex.: os testes de guid de Administradora vs. Condomínio, entradas anteriores nesta mesma data) não estavam inconclusivas por retry insuficiente — estavam inconclusivas porque, nesses momentos, o VS estava realmente fora do ar pro CORE, e nenhum retry, por mais longo, resolveria isso.
- O padrão de retry (
gerarBoletoComRetry,esperarStatusBoleto) usado em vários specs (commands.js,boletoRegressao.cy.js, etc.) continua correto pro caso em que a ativação é genuinamente assíncrona e termina sozinha (esse mecanismo existe e funciona na maioria das vezes) — só não serve, e não tem como servir, pro cenário específico "VS não aprovou": aí o teste vai continuar falhando com essa mensagem até alguém reiniciar a aplicação em HML, não importa quanto tempo o teste espere.
Correção: nenhuma no código — não há nada que o lado Cypress possa fazer pra evitar ou contornar isso. Fica registrado aqui pra, da próxima vez que "Conta digital não está ativa" aparecer, já ir direto pra pergunta certa ("o VS reiniciou recentemente em HML?") em vez de insistir em mais retry ou suspeitar de volume/fila da nossa própria suíte.
Pendente: nenhuma ação do lado deste projeto — é reinício de infraestrutura, fora do escopo da automação.
2026-08-24 — boletoGuidExistenteRegressao.cy.js incorporado a boletoRegressao.cy.js: o guid fixo era um dado da nossa própria suíte, não um dado real de produção
Categoria: Correção de desenho de teste (o meu), não bug de produto — o arquivo separado
criado horas antes (ver entrada logo abaixo) usava um guid fixo (12508ba9-...) que o usuário
indicou como "Condomínio já existente". Investigando um resultado inconsistente (ver próxima
seção), descobri: esse guid, confirmado na tela real (Contas Digitais Boleto, busca por Guid), É
um Condomínio de verdade — mas com razão social COND_s8u6q3e1 e Administradora dona
ADM_2aaezs8n, nomes que batem exatamente com o padrão textoAleatorio('COND')/('ADM') deste
projeto (support/cnpj.js). Ou seja: não é um dado de produção externo, é um Condomínio que a
PRÓPRIA suíte criou numa execução anterior (provavelmente boletoViaApi.cy.js ou
boletoRegressao.cy.js, ambos criam pares assim) — o usuário pegou esse guid na tela sem saber
que era um dado de teste nosso.
Resultado inconsistente que motivou a investigação: rodando os 2 cenários (guid de Condomínio correto vs. guid de Administradora no lugar) em momentos diferentes, a API ora aceitava (200) um guid de Administradora de verdade, ora barrava esse Condomínio de teste alegando "é uma administradora e não pode gerar boletos para si mesma" — 2 resultados contraditórios que juntos sugeriam a validação nova (da demanda em andamento) estar checando o campo errado, ou pelo menos inconsistente.
Decisão do usuário: em vez de investigar mais a fundo esse guid específico ou trocar por outro fixo, o usuário pediu pra criar a Administradora e o Condomínio dinamicamente (autossuficiente, sem depender de nenhum guid fixo do ambiente) — regra clara: "em nenhum dos 2 cenários pode aceitar a ADM no lugar do Condomínio".
Correção: o arquivo separado foi removido; os 2 it()s (guid de Condomínio correto → aceito;
guid de Administradora no mesmo campo → sempre barrado) foram incorporados a
boletoRegressao.cy.js, reaproveitando a MESMA Administradora/Condomínio que o before() raiz
daquele arquivo já cria (e já confirma ativa, via o boleto baseline existente) — evita criar mais
um par de dado real só pra isso. guidAdministradora (antes uma const local ao before())
virou variável do describe, pra ficar acessível nos novos testes.
Verificação: sanity check headless — 8 testes coletados (6 originais + 2 novos), sem erro de sintaxe, morreu na limitação de login já conhecida.
Pendente: rodar de novo (via cypress open, 2FA manual) quando o ambiente estiver sem a
instabilidade "conta não está ativa" do dia, pra confirmar se a validação (guid de Administradora
barrado) já está estável — a entrada abaixo documenta o histórico completo da investigação.
Atualização 24/08/2026, 11:34 (ainda no arquivo antigo, antes da incorporação): mais uma
rodada confirmou exatamente o mesmo padrão contraditório — o guid fixo 12508ba9-... barrado de
novo (400 "é uma administradora"), e uma Administradora nova, criada pelo teste, aceita (200) de
novo. Pattern estável ao longo de 3 rodadas (10:10, 11:34) — não foi coincidência de timing. Mais
um motivo pra confiar na decisão de tirar o guid fixo do teste.
2026-08-21/24 — boletoGuidExistenteRegressao.cy.js (removido nesta mesma sessão): falta validação de posse confirmada, e o próprio teste quase deu falso-positivo 2 vezes
Categoria: Novo spec de regressão (a pedido do usuário) + 2 correções no PRÓPRIO teste antes de estabilizar — nenhuma delas é bug de produto, são falhas de desenho do teste que eu mesmo encontrei e corrigi antes de considerar pronto.
Pedido original: usuário pediu 2 fluxos — (1) gerar boleto usando um guid de Condomínio já
existente no ambiente (12508ba9-15e9-410d-916b-0493dd9ff8b5, indicado por ele, com o payload
exato que ele mesmo usa no Postman), e (2) o mesmo fluxo, mas com um guid de Administradora no
lugar — que precisa ser barrado. Contexto: "hoje não está dando erro quando tenta criar boleto
com guid de administradora, tem uma demanda ajustando isso" — ou seja, bug confirmado, correção
em andamento.
Achado 1 (produto, confirmado ao vivo): uma Aplicação recém-autenticada, SEM NENHUMA relação
com o Condomínio 12508ba9-..., consegue gerar boleto pra ele mesmo assim (200) — não há
validação de POSSE no campo codigo de POST .../contaDigital/remessa. Isso é mais amplo que
só "guid de administradora": é qualquer guid alheio.
Achado 2 (falha no MEU teste, corrigida antes de finalizar): a 1ª versão do teste "guid de Administradora deveria ser barrado" dava falso positivo (passava verde) por 2 motivos possíveis, nenhum relacionado à validação real de tipo de guid:
- Se a conta ainda não tivesse terminado de ativar, a API devolve 400 "não está ativa" — que
também cai fora de
[200, 201], então oexpectoriginal passava mesmo sem confirmar nada de verdade. - Confirmado forçando um retry bem mais longo que o normal (25 tentativas, ~50s, num script
fora do Cypress): depois de tempo demais nesse loop, o token de autenticação expira e a
API passa a devolver 403 "Acesso negado"/"não está autenticado" — também fora de
[200, 201], também sem relação nenhuma com a validação de guid.
Correção: o teste agora detecta os 2 padrões de ruído (mensagem contendo "não está ativa" ou
"não está autenticado") e reprova explicitamente se a resposta bater em algum deles — só aceita
como "validação funcionando" um status fora de [200, 201] que NÃO seja um desses 2 ruídos.
Rodando de verdade (24/08/2026): o teste reprovou com a mensagem "resposta parece ruído de
ambiente... não dá pra confirmar nada com essa resposta" — a instabilidade "conta não está
ativa" (já documentada extensivamente neste arquivo) seguia ativa no ambiente no momento do
teste, então não deu pra confirmar se a validação de tipo já existe ou não. Esse é o
comportamento CORRETO do teste nessa situação — falhar alto e claro em vez de aprovar escondido.
Pendente: rodar de novo quando o ambiente estiver estável (sem a instabilidade "conta não está ativa" do dia) pra ter um resultado de verdade — hoje o teste não conseguiu confirmar nem que a validação existe, nem que ainda não existe.
Atualização 24/08/2026, 12:06-12:36: 8 rodadas seguidas (execução real do usuário via
cypress open) confirmaram o mesmo padrão — VS seguiu sem aprovar contas novas a manhã toda,
teste reprovando alto e claro como projetado (a pedido do usuário: "manter reprovando").
Atualização 24/08/2026, 13:27-13:39: mais 2 rodadas, mesmo padrão — VS segue sem aprovar conta nova no início da tarde.
Atualização 24/08/2026, 08:45-08:46: mais uma rodada de smoke.cy.js (execução em paralelo
do usuário) confirmou os mesmos 3 grupos de erro de API já mapeados (DDA > Empresas/Aplicações/
Boletos/Consumo, Conta Condominial > Webhook/Geral) — mesmos endpoints, mesmos status 500.
Consistente com tudo já registrado; a instabilidade "conta não está ativa" e os 3 grupos de erro
500 parecem ser o mesmo pano de fundo do ambiente hoje.
2026-08-21 — Novo cy.criarContaCorrenteViaApi(), achado explorando a collection Postman a pedido do usuário
Categoria: Melhoria de infraestrutura de teste (não incidente) — usuário pediu pra ver se
tinha algo na collection Postman "CORE HOMOL V1" que ajudasse o projeto, "igual fizemos com os
boletos" (referência a cy.gerarBoletoViaApi()).
O que foi encontrado, investigando a collection (pasta "Conta Corrente"): endpoints reais e
testados na própria collection (assert de status 201) pra criar Conta Corrente via API — "Criar
Conta Corrente ADM" (POST .../contas-digitais/{guid_administradora}/contas-correntes) e "Criar
Conta Corrente SubConta" (POST .../{guid_condominio}/contas-correntes-subconta). Isso ataca a
mesma fragilidade que motivou cy.gerarBoletoViaApi(): contaCorrenteRegressao.cy.js (e
contaCorrente.cy.js) dependiam de um registro PRÉ-EXISTENTE no ambiente (DADOS_REAIS,
achado inspecionando a tela manualmente) — sem forma de recriar se sumir/mudar um dia.
Também explorados, sem resultado útil: "ATIVAR" (esperava que resolvesse a instabilidade "conta
digital não está ativa" já documentada várias vezes aqui — na verdade é sobre "origem de
movimentação", nada a ver) e "Inativar Conta Digital" (DELETE .../adm/contas-digitais/{guid}
— existe na collection mas está claramente inacabado: URL aponta pra localhost:8080, sem
nenhuma autenticação configurada, nunca adaptado pro homolog). "Descredenciar Subconta" (POST .../contaDigital/{guid_condominio}/descredenciar, 204) parece promissor como possível endpoint
de limpeza de dado real — mas fica pendente de investigação futura (o usuário escolheu priorizar
Conta Corrente primeiro).
Verificação (nunca no chute): antes de escrever cy.criarContaCorrenteViaApi(), rodei um
script Node standalone (fora do Cypress, mesmas credenciais do cypress.env.json) reproduzindo
a cadeia Cria Administradora → Autentica → Criar Conta Corrente ADM — confirmou 201 real com
guid. Depois, busquei o registro criado na tela real de Contas Correntes (mesma sessão logada) —
apareceu na listagem em poucos segundos, filtrável por Agência+Conta sem dígito, exatamente como
esperado.
Achado importante durante a verificação: a Conta Corrente criada via API NÃO nasce com
status: "ATIVA"/statusAprovacao: "REJEITADO" como o registro real DADOS_REAIS tem — nasce
como status: "ERRO_CADASTRO" e statusAprovacao: "PENDENTE". Por isso o novo comando só
substituiu contaCorrenteRegressao.cy.js (que só precisa de Agência/Conta conhecidos) —
contaCorrente.cy.js continua ancorado em DADOS_REAIS, porque vários dos seus filtros
(Status, Status Aprovação, Principal) dependem de valores que a Conta Corrente criada via API
não tem.
Correção:
cy.criarContaCorrenteViaApi()criado emcypress/support/commands.js— duplicacriarAdministradora()/autenticarAplicacao()decy.gerarBoletoViaApi()de propósito (são funções privadas daquele closure; extrair pra um lugar comum arriscaria regredir o fluxo de boleto já validado por uma dívida de duplicação pequena).contaCorrenteRegressao.cy.jsreescrito pra criar sua própria Conta Corrente numbefore(), em vez de usarDADOS_REAIShardcoded.
Verificação final: sanity check headless — 3 testes coletados, before() (criação via API)
passou de verdade (chegou até a falha conhecida de login no beforeEach, não travou antes).
Pendente: validar via cypress open (2FA manual) fica a critério do usuário. Investigar
"Descredenciar Subconta" como possível solução pro "sem endpoint de exclusão usado neste
projeto" (CLAUDE.md) fica pra quando o usuário priorizar.
2026-08-21 — regressao/relatorioRegressao.cy.js criado (completando a regressão com os candidatos já mapeados)
Categoria: Trabalho planejado (não incidente) — a pedido do usuário, completando a suíte de
regressão com o que já estava listado em regressao/LEIAME.md como candidato.
O que entrou: 1 comportamento, já confirmado em docs/regras-de-negocio.md ("Relatórios" >
Regras): o tipo "Transferências Pagas" pede 2 campos a mais que nenhum outro tipo tem ("Guid
Administradora", "Guid Condominio") — sem os dois preenchidos, "Gerar Relatório" não dispara
NENHUMA requisição, silenciosamente. RelatorioPage.js ganhou 3 métodos novos pra esse cenário
específico (interceptarSolicitarRelatorio, clickGerarRelatorioSemEsperarRequest,
shouldNaoTerDisparadoSolicitacao) — diferentes dos já existentes porque não tem resposta
nenhuma pra esperar com cy.wait('@alias') (o ponto inteiro do teste é confirmar que a chamada
nunca acontece).
O que NÃO entrou: o outro candidato listado ("mesmo tipo solicitado 2x em menos de 15 min →
rejeição") — já é coberto genericamente pelo spec pontual relatorios.cy.js, testado pros 10
tipos (inclusive "Transferências Pagas"). Duplicar como regressão não agregaria nada; mesmo
raciocínio já usado antes pra não criar uma regressão separada da coluna "Principal" de Contas
Correntes. regressao/LEIAME.md atualizado documentando a decisão.
Verificação: sanity check headless — 1 teste coletado, sem erro de sintaxe, morreu na
limitação de login já conhecida (totpSecret).
Pendente: validar via cypress open (2FA manual) fica a critério do usuário.
2026-08-21 — Unificação do expandMenu(): 6 cópias viraram 1, e 4 delas nem eram usadas
Categoria: Limpeza de código (dívida técnica), não bug de produto — achado numa varredura geral do projeto pedida pelo usuário ("varre o projeto e vê se tem algo que precisa de atenção").
Situação encontrada: o método expandMenu() (abre o menu lateral, caso esteja recolhido)
existia copiado, praticamente idêntico, em 6 lugares: MenuPage.js (versão corrigida, com
retry — ver entrada de 20/08/2026 sobre esse bug) e mais 5 Page Objects (ContaCorrentePage,
AplicacaoPage, BoletoPage, ContaGeradoraPage, RelatorioPage), todas com a versão ANTIGA
(cy.get('body').then(...), uma foto única do DOM, sem retry — a mesma classe de bug já
documentada e corrigida em MenuPage.js, mas nunca replicada pra essas 5).
Investigando mais fundo (grep por .expandMenu() em todo cypress/), descobri que só 1 das 5
cópias era realmente CHAMADA: ContaGeradoraPage.js (a única tela sem URL fixa de cadastro —
precisa navegar pelo menu de verdade). As outras 4 (ContaCorrentePage, AplicacaoPage,
BoletoPage, RelatorioPage) navegam direto via cy.visit() — o método, o elemento
menuToggle, e em 3 delas também um elemento de menu específico (menuAplicacoes,
menuBoletos, menuRelatorios) eram código morto: definidos, nunca usados. Provavelmente
sobra de um design anterior (antes da decisão de navegar direto por URL, documentada nos
comentários dessas mesmas páginas), nunca removido.
Correção:
- Criado
cy.expandirMenu()emcypress/support/commands.js— fonte única da lógica corrigida (retry de verdade), acessível de qualquer Page Object ou spec. MenuPage.js:expandirMenu()agora só delega pro comando (removida a lógica duplicada e o elementomenuRoot, que ficou órfão).ContaGeradoraPage.js(o único uso real):goToCadastro()passou a chamarcy.expandirMenu()direto — ganhou a versão sem bug.- Removido de
ContaCorrentePage.js,AplicacaoPage.js,BoletoPage.js,RelatorioPage.js: métodoexpandMenu(), elementomenuToggle, e os elementos de menu órfãos.
Verificação: sanity check headless dos 6 specs afetados (contaCorrente.cy.js,
aplicacao.cy.js, boletoViaApi.cy.js, contaGeradora.cy.js, relatorios.cy.js,
smoke.cy.js) — 61 testes coletados ao todo, sem erro de sintaxe; todas as falhas foram a
limitação de login já conhecida (totpSecret) ou recorrências já mapeadas dos 3 grupos de erro
de API do ambiente — nada novo, nada quebrado pela mudança.
Pendente: nenhuma ação humana — validar via cypress open (2FA manual) fica a critério do
usuário, mas a mudança é só reorganização interna, sem alterar comportamento observável de
nenhum teste.
2026-08-21 — menuRegressao.cy.js pegou o produto de verdade mudando: "DDA > Aplicações" virou tela própria, "Notificações > Boletos" ganhou 2 filhos reais (Geral, Bolepix)
Categoria: Mudança real de produto, não bug de teste — o teste de regressão funcionou exatamente pra isso (pegar uma divergência do que estava documentado). Spec removido depois, não corrigido — ver motivo abaixo.
Sintoma: ao rodar menuRegressao.cy.js de verdade pela 1ª vez via cypress open (2FA
manual, feito pelo usuário), os 2 it()s falharam:
- "DDA > Aplicações continua levando pra MESMA URL que Aplicações solta no topo" — recebeu
/app/dda/listarem vez de/app/aplicacao. - "Notificações > Boletos continua sendo um item morto" — o
should('not.exist')nos itens- filho falhou porque eles EXISTEM agora.
Investigação (ao vivo, navegador real, mesma sessão logada — nunca no chute):
/app/dda/listaré uma tela própria de verdade: título "Cadastro de Aplicações", breadcrumb "App › Dda › Listar", filtros Status/Guid/Nome da Aplicação, colunas Nome/Ativa/Data Cadastro/Data Descredenciamento, botões Ativar/Inativar. Comparada lado a lado com/app/aplicacao/listar("Aplicações", botão "Nova Aplicação", coluna "Conta Geradora", 9 registros reais) — são 2 telas genuinamente diferentes, não a mesma tela por trás de 2 entradas de menu (que era o comportamento confirmado em 20/08/2026)..ant-menu-submenude "Boletos" dentro de "Notificações", que em 20/08/2026 não tinha<ul>nenhum, agora abre revelando 2li.ant-menu-itemreais: "Geral" (/app/notificador/boleto/geral, tela "Notificações de Boletos", com filtro e tabela) e "Bolepix" (/app/notificador/boleto/pix, tela "Notificações de Bolepix", idem). Confirmado clicando em cada um e conferindo a tela renderizada, não só odata-menu-id.
Por que essas 2 particularidades sumiram: não investigado (fora do escopo — é uma pergunta pro time de produto, não algo que dá pra responder só inspecionando o front). O fato relevante aqui é só que MUDOU, entre 20/08 e 21/08/2026.
Correção:
docs/regras-de-negocio.md— mapa do menu e as 2 particularidades corrigidos pro estado atual (particularidade #3, sobre as telas com controle real, continua valendo).cypress/e2e/smoke/smoke.cy.js— ganhou 2it()s novos ("Notificações > Boletos > Geral" e "> Bolepix", cobrindo as telas que passaram a existir); comentários que citavam o comportamento antigo (mesma URL / item morto) corrigidos.cypress/e2e/regressao/menuRegressao.cy.js— removido, não corrigido. As 2 asserções que ele travava eram sobre um estado que não existe mais; não sobrou nenhum "bug confirmado" real pra travar ali (ver motivo completo emcypress/e2e/regressao/LEIAME.md). A cobertura das telas novas passou a ser papel do smoke test, que é o lugar certo pra "essa tela existe e carrega".
Pendente: nenhuma ação humana — documentação e testes já refletem o estado atual, confirmado ao vivo.
2026-08-21 — Sanity check headless de menuRegressao.cy.js + contaCorrenteRegressao.cy.js: login trava no /signin, boletoRegressao.cy.js pegou de novo a instabilidade de "conta digital não está ativa"
Categoria: 2 causas distintas, nenhuma nova — 1 limitação já documentada (login headless sem
totpSecret), 1 recorrência da instabilidade de backend que o próprio usuário já sinalizou como
em andamento hoje ("nao vai da pra testar agora pq estamos com problema nas apis de boleto de
novo") — sem investigação adicional, por instrução explícita.
Sintoma 1 — menuRegressao.cy.js e contaCorrenteRegressao.cy.js (specs novos, ainda sem
nenhuma execução real via cypress open): rodados apenas como sanity check headless (npx cypress run, só pra confirmar que compilam e os it()s são coletados certo) — os dois morreram
no before each com expected '.../signin' to not include '/signin'. Mesma limitação já
registrada várias vezes neste histórico: cypress.env.json não tem totpSecret configurado
neste ambiente, então cy.pause() (usado no login assistido de 2FA) não tem efeito em modo
headless. Não é bug dos specs novos — os dois specs colhem corretamente 2 e 3 it()s cada,
sem erro de sintaxe.
Sintoma 2 — boletoRegressao.cy.js (rodado antes, ~15:45-15:46, também sanity check): os
testes de "código externo duplicado" e "guid provisório" pegaram, de novo, a mesma instabilidade
de "Conta digital [guid] não está ativa"/400 já documentada extensivamente hoje (ver entrada
"boletoViaApi.cy.js: as 5 suítes falharam..." abaixo). Consistente com o próprio usuário
confirmando que os problemas nas APIs de boleto voltaram nesta mesma data.
Correção: nenhuma — nenhuma das duas causas é sobre o código dos specs. Confirmação pendente
de contaCorrenteRegressao.cy.js/menuRegressao.cy.js via cypress open (2FA manual) quando o
usuário rodar; boletoRegressao.cy.js só volta a ser confiável quando a instabilidade de boleto
passar (mesma situação já em acompanhamento).
2026-08-21 — boletoSimulaErroEmissao.cy.js: "cliente sem CPF/CNPJ" devolveu 400 em vez do 500 documentado — possível correção real, ainda NÃO confirmada
Categoria: Achado pendente de confirmação — não é bug de teste, é uma possível melhoria de produto que ainda precisa de evidência antes de virar mudança de código
Sintoma: o teste "cliente sem CPF/CNPJ... API vaza erro 500 de banco (bug real, não é
validação)" falhou com expected 400 to equal 500 — o próprio teste já tinha um comentário
deixado de propósito antecipando esse dia ("Se algum dia isso for corrigido pra devolver 400... este teste deve falhar aqui — é o sinal de que dá pra atualizar a expectativa (e comemorar)").
Por que ainda não foi confirmado: a entrada da fila só capturou resposta.status, não o
corpo da resposta — não dá pra saber se o 400 veio com uma mensagem de validação de verdade
(ex.: "cpfCnpj é obrigatório") ou se é outro efeito colateral qualquer. Reforça a dúvida: na
MESMA execução, o teste vizinho ("código externo do boleto repetido") pegou a instabilidade de
"conta digital não está ativa" que já está documentada como ativa hoje — então não dá pra
descartar que esse 400 também seja produto da instabilidade geral do ambiente (um caminho de
erro diferente sendo acionado), não uma correção de verdade na validação.
Correção: nenhuma ainda — boletoSimulaErroEmissao.cy.js continua com a asserção 500
(comportamento documentado, não mudar no chute). Pendente: rodar de novo e olhar
resposta.body completo do 400 antes de decidir se atualiza o teste + regras-de-negocio.md.
2026-08-21 — boletoSimulaErroEmissao.cy.js: "código externo repetido" pegou a mesma instabilidade de "conta digital não está ativa"
Categoria: Mesma instabilidade já documentada hoje, sem correção de código
Sintoma: o teste esperava a mensagem "códigos externos duplicados" e recebeu "Conta digital
[guid] não está ativa." — mesmo padrão de instabilidade de credenciamento/ativação já visto hoje
em boletoViaApi.cy.js e no grupo dda-api/webhook-api/conta-digital-api, agora afetando
também o before() autossuficiente deste spec (que monta sua própria Administradora/Condomínio).
Correção: nenhuma — instabilidade de ambiente, não bug de teste.
2026-08-21 — boletoViaApi.cy.js: clique num botão desabilitado ao abrir Detalhes — instabilidade, não investigado a fundo
Categoria: Falha real de ambiente, classificada pelo usuário como instabilidade — sem correção de código
Sintoma: "boleto com dados padrão › confere os dados no modal de Detalhes" falhou com
cy.click() failed because this element is disabled num <button> MUI (não o chip
div[role="button"] de "Detalhes"/"Histórico" já documentado) — o screenshot mostra a tabela de
resultados da busca por Guid vazia (0 linhas) no momento da falha.
Causa: não investigada a fundo — o usuário confirmou direto que foi instabilidade (mesmo
padrão do dia: backend de credenciamento/indexação com atraso, já visto hoje em
boletoViaApi.cy.js "conta digital não está ativa" e no grupo dda-api/webhook-api/
conta-digital-api retornando 500). Hipótese não confirmada em detalhe: a busca por Guid não
achou o boleto ainda indexado, e algum botão de paginação/estado vazio (desabilitado por não ter
resultado) foi o alvo do clique seguinte.
Correção: nenhuma — decisão do usuário de não investigar mais fundo agora, classificado como mais um sintoma da mesma instabilidade de ambiente já documentada hoje.
2026-08-21 — contaGeradora.cy.js: validação pela listagem removida — tela não tem busca nem detalhe
Categoria: Desenho de teste corrigido a pedido do usuário, com evidência real por trás
Contexto: ao adicionar o fluxo "salva de verdade" em Contas Geradoras (ContaGeradoraPage. shouldEstarSalvaCorretamente()), a validação recarregava a listagem, ia pra última página da
paginação e procurava a linha pelo codigoExterno. Rodando de verdade (3 execuções: 10:43,
10:46, 10:49), todas falharam com Expected to find content: 'QA_CYPRESS_SALVAR_...' within the selector: 'table tbody tr' but never did — o registro salvava (passava do salvarContaGeradora(),
201 confirmado), mas a busca pela linha na listagem depois nunca achava.
Causa: não investigada a fundo — o usuário pediu pra simplesmente remover essa validação ("pode tirar a validação se existe, não tem pesquisa nessa tela, então só a confirmação de sucesso do cadastro já é suficiente"), com razão: a tela realmente não tem busca/filtro nenhum (só uma tabela com paginação fixa de 10 por página), então qualquer heurística de "ir pra última página" pra achar um registro específico é frágil por natureza — não é um filtro de verdade, depende de contar/estimar quantas páginas existem.
Correção: ContaGeradoraPage.shouldEstarSalvaCorretamente() removido (junto com
goToListagem(), linhasResultado e ultimaPaginaButton, que só existiam pra isso).
contaGeradora.cy.js agora valida só pela resposta HTTP do próprio Salvar
(salvarContaGeradora(), confere o 201) — sem 2ª etapa de conferência.
2026-08-21 — boletoViaApi.cy.js: as 5 suítes falharam em "Conta digital não está ativa" — janela de instabilidade no backend, não é sobre qual banco
Categoria: Bug real de ambiente (backend), não de teste — usuário reportou suspeita de que o problema fosse "gerando pro banco Sicoob, era pra gerar sempre pro Bradesco".
Sintoma: as 5 suítes de boletoViaApi.cy.js (dados padrão, campos customizados, vencimento
retroativo, cancelamento, remessa múltipla) falharam no before all, todas no mesmo ponto: depois
de criar Administradora + Condomínio + configurar Conta Geradora (tudo 200), o POST .../contaDigital/remessa voltava 400 com "Conta digital [guid] não está ativa." — em TODAS as
6 tentativas do retry já existente (gerarBoletoComRetry, linha ~378 de commands.js,
que já existe de propósito pra esperar exatamente esse tipo de corrida — não é bug do teste).
Hipótese do usuário: que o problema fosse específico do banco Sicoob (o código deveria usar
sempre Bradesco). Conferido no código primeiro: CONTAS_GERADORAS só tem BRADESCO
(contasGeradoras.js), e commands.js:665 usa
overrides.guidContaGeradora || CONTAS_GERADORAS.BRADESCO — nenhum teste passa override, então o
teste sempre pede Bradesco de verdade. Confirmado também na tela "Contas Digitais Boleto"
(/app/conta-digital/listar), buscando pelo guid de uma das contas criadas nesse run
(37059829-d798-4c9b-926a-d881433fbe77): Banco Gerador = "Conta do Bradesco" — a API recebeu
o banco certo. O que estava errado era o Status = ERRO_CADASTRO (não "Avaliação"/pendente).
Causa confirmada (lendo a tabela real, sem depender do filtro da tela — que tem bug de UI, não aplicava o filtro clicado):
| Conta | Banco | Criada às | Resultado |
|---|---|---|---|
| ADM_6xi06x60 | Itaú | 10:00:48 | ERRO_CADASTRO |
| ADM_va2nie5d | SICOOB | 10:01:03 | ERRO_CADASTRO |
| COND_7bmoxbcp | Bradesco | 10:01:04 | ERRO_CADASTRO |
| ADM_3hs693wa | Santander | 10:01:18 | ERRO_CADASTRO |
| ADM_94cde69a | Itaú | 10:06:10 | ERRO_CADASTRO |
| COND_ca8f5e26 | Bradesco | 10:06:17 | ERRO_CADASTRO |
| ADM_202b7fb7 | SICOOB | 10:14:25 | ATIVA |
| COND_d859b484 | Santander | 10:14:34 | ATIVA |
TODO banco (Bradesco, Sicoob, Itaú, Santander) errou igual entre 10:00 e 10:06, e TODO banco voltou a funcionar a partir de 10:14 — não é sobre qual banco, é uma janela de instabilidade no backend de credenciamento/ativação de conta digital (~14 min), que afetou tudo igual. Quando funciona, a ativação é praticamente instantânea (1s) — não é processo normalmente lento, então nem aumentar o retry ajudaria durante essa janela (o backend estava fora do ar pra isso, não só devagar).
Correção: nenhuma no teste — o retry já existente está correto, só não cobre "backend fora do
ar por minutos". Fica pendente de ação humana: reportar a instabilidade observada (10:00–10:14,
21/08) pra quem mantém o backend de credenciamento. Vale considerar juntar com o achado de hoje
mais cedo sobre dda-api/adm/conta-digital-api/webhook-api retornando 500 — mesmo ambiente,
janela de tempo próxima, pode ser o mesmo incidente maior.
2026-08-20 — 4 telas do menu retornam erro real de API (500) — achado navegando pra montar o smoke
Categoria: Bug real de produto (backend), não de teste — descoberto por fora de um it()
falhando, navegando manualmente pra levantar o mapa completo do menu (ver
docs/regras-de-negocio.md, seção "Mapa do menu do produto").
Sintoma: as 4 telas abaixo mostram o toast vermelho "Erro na API, favor contactar o administrador do sistema" ao carregar, mesmo com a tela em si (breadcrumb, formulário de filtro) renderizando normalmente:
| Tela | Endpoint que falhou | Status |
|---|---|---|
| Conta Condominial > Geral | GET .../adm/conta-digital-api/listar/contas-condominiais?page=0&size=10 |
500 |
| Conta Condominial > Webhook | GET https://orquestrador-homol.partnerbank.com.br/webhook-api/v1/aplicacao |
500 |
| DDA > Aplicações | GET .../core-api/dda-api/application?size=10&page=0&sort=createdAt,DESC |
500 |
| DDA > Empresas | GET .../core-api/dda-api/application/obter-todas, GET .../core-api/dda-api/user-cip?size=10&page=0&sort=createdAt,DESC |
500 |
| DDA > Boletos | GET .../core-api/dda-api/application/obter-todas, GET .../core-api/dda-api/user-cip/obter-todas, GET .../core-api/dda-api/boleto?size=10&page=0&sort=createdAt,DESC |
500 |
| DDA > Consumo | GET .../core-api/dda-api/application/obter-todas + 6 endpoints dda-api/request-ticket/* (total, usuarios, boletos-dia 2x, aplicacoes-requisicoes, aplicacoes-usuarios) |
500 |
(endpoints acima confirmados depois, quando o detector do smoke passou a checar a resposta HTTP
em vez do toast — ver entrada mais recente sobre prepararDetectorDeErroDeApi(); a base comum
GET .../core-api/dda-api/application* falhando explica por que as 4 telas de DDA erram juntas —
provavelmente a mesma dependência de backend, ex.: um serviço/tabela específico do módulo DDA
fora do ar.)
Atualização 2026-08-21: rodei de novo (dia seguinte) — as MESMAS 5 telas falharam, desta vez as 5 de uma vez, na mesma execução (não intermitente feito da última vez). Ou seja, o backend desse ambiente segue com esses problemas reais, sem sinal de melhora — continua pendente de reportar pra quem mantém o backend. O smoke reprovou certinho as 5, como deve.
Atualização 2026-08-21, mais tarde: as mesmas 6 telas (5 do grupo dda-api/webhook + Conta
Condominial > Geral) voltaram a falhar em 4 execuções seguidas do smoke, entre 10:20 e 10:39
— ou seja, dessa vez não foi um pico isolado, ficou consistentemente quebrado por pelo menos
~20 min seguidos. Reforça que vale reportar como incidente de verdade, não como instabilidade
pontual.
Atualização 2026-08-21, 14:53-14:54: as mesmas 6 telas falharam de novo, mais uma rodada — instabilidade segue ativa horas depois, sem sinal de resolução.
Atualização 2026-08-21, 16:35: "Conta Condominial > Geral" (grupo 2,
contas-condominiais) E "Conta Condominial > Webhook" (grupo 3, webhook-api/v1/aplicacao)
falharam de novo, numa execução real de smoke.cy.js via cypress open (rodando em paralelo a
esta sessão). Mesmos endpoints, mesmos status (500) — os 2 grupos seguem sem sinal de resolução;
o grupo 1 (dda-api) apareceu logo em seguida, na mesma execução — as 4 telas de DDA
(Aplicações, Empresas, Boletos, Consumo) falharam junto, cada uma no(s) endpoint(s) já mapeado(s)
(dda-api/application, dda-api/user-cip, dda-api/boleto, dda-api/request-ticket/*). Os 3
grupos seguem ativos e independentes entre si nesta janela.
Atualização 2026-08-21, 16:44-16:48: sanity check headless rodado depois da unificação do
expandMenu() (ver entrada própria abaixo) reproduziu os mesmos 3 grupos de novo (Conta
Condominial > Geral e Webhook, as 4 telas de DDA) — nenhuma novidade, só mais uma confirmação de
que a instabilidade segue ativa. O restante das entradas dessa mesma rodada é só a limitação de
login headless sem totpSecret (contaCorrente.cy.js, aplicacao.cy.js, contaGeradora.cy.js,
relatorios.cy.js, smoke.cy.js) — já documentada, não é novidade.
Causa confirmada: só o sintoma (status HTTP + endpoint, quando capturado) — a causa raiz no backend não foi investigada (fora do escopo desta tarefa, que era montar o smoke test, não triar bugs de produto).
Correção (nota adicionada depois — as 4 telas são INTERMITENTES, não sempre): a afirmação original aqui ("reproduzido 2x, não é flakiness passageira") estava errada. Testando de novo várias vezes depois: "Conta Condominial > Webhook" carregou sem erro nenhum em 3 das 4 tentativas seguintes — só "DDA > Consumo" reproduziu de forma mais consistente. Ou seja, o backend falha às vezes, não sempre (possível cold-start ou instabilidade pontual, não investigado a fundo). Isso não muda a conclusão (é bug real, vale reportar), só a certeza sobre a frequência — importante pra quem for investigar no backend não esperar 100% de reprodução.
Correção: nenhuma — é bug de produto, não de teste. Fica pendente de ação humana: reportar pra quem mantém o backend. Não são 6 bugs, são 3 (agrupando pela URL — host + caminho — não pela tela, que foi o que revelou a repetição):
core-api/dda-api/*(hostapi-manager-homol2-contadigital...) — afeta as 4 telas de DDA (Aplicações, Empresas, Boletos, Consumo). TODA UMA delas chamadda-api/applicationoudda-api/application/obter-todas— esse é o denominador comum, forte indício de causa única (o serviço/recurso "application" do módulo DDA fora do ar, e as outras telas dependem dele por baixo). 1 causa, 4 sintomas.core-api/adm/conta-digital-api/listar/contas-condominiais(mesmo host acima, mas caminhoadm/conta-digital-api— módulo diferente do DDA) — afeta só Conta Condominial > Geral. Sem relação com o grupo 1.webhook-api/v1/aplicacao, em outro host inteiro (orquestrador-homol.partnerbank.com.br, nem é oapi-manager) — afeta só Conta CondominialWebhook. Infraestrutura de backend separada dos outros 2 grupos.
Nota sobre o smoke test (corrigida — ver entrada mais recente abaixo): a 1ª versão desta
entrada dizia que smoke.cy.js não falhava nessas 4 telas de propósito (só conferia o
breadcrumb). O usuário corrigiu essa decisão: uma tela com toast de erro visível precisa
reprovar o smoke, senão o teste "passa" numa tela quebrada. MenuPage.shouldTelaCarregada() foi
alterado pra também conferir que nenhum toast .notification-error apareceu — essas 4 telas
agora fazem o smoke falhar de verdade, como deve ser.
2026-08-20 — Achado à parte: a SPA falha transitoriamente ao carregar um chunk dinâmico, mas se autorrecupera com reload
Categoria: Comportamento observado do ambiente, sem correção de código
Sintoma: durante a mesma navegação manual acima, 2 telas ("Unidade Organizacional" e "Contas
Geradoras > Distribuição Percentual") vieram completamente em branco no primeiro carregamento,
com o console mostrando TypeError: Failed to fetch dynamically imported module: .../assets/index-XXXXX.js (hash do chunk mudando entre as duas ocorrências). Nos dois casos, um
reload forçado da mesma URL resolveu — a tela carregou normal na tentativa seguinte.
Causa confirmada: comportamento real da SPA (Vite/import dinâmico), não do ambiente de
automação — reproduzido no navegador real (via Claude in Chrome, sessão logada do usuário), não
numa ferramenta de automação isolada. Provavelmente relacionado a um novo deploy trocando os
hashes dos chunks enquanto a página já estava carregada (index.html antigo em cache pedindo um
chunk que não existe mais). Não investigado a fundo (fora do escopo desta tarefa).
Correção: nenhuma — comportamento do ambiente, não bug de teste. Relevante registrar porque explica, em parte, a instabilidade "página em branco" já vista antes neste projeto na tela de Boletos (ver entradas mais antigas abaixo) — não prova que era a MESMA causa daquela vez (aquele caso nunca foi confirmado, e a entrada correspondente foi corrigida/removida na época), mas mostra que esse tipo de falha transitória acontece de verdade neste ambiente, então vale desconfiar dela (tentar reload) antes de assumir bug de produto ou de teste da próxima vez que uma tela vier em branco sem motivo aparente.
2026-08-20 — Esperar a animação do submenu "terminar" nunca funcionava em headless — trocado por .invoke('click')
Categoria: Bug real no teste, corrigido — a correção anterior (esperar
ant-motion-collapse-enter* sumir) parecia certa mas não sobrevivia a cypress run de verdade.
Sintoma: rodando headless, Usuários > Listar (um caso SIMPLES, nem aninhado) falhou com
Timed out retrying after 10000ms: submenu ainda em transição (ant-motion-collapse-enter*): expected '...ant-motion-collapse-enter ant-motion-collapse-enter-start...' not to match /ant-motion-collapse-enter/ — a espera nunca terminava, nem depois do timeout inteiro.
Causa confirmada: a correção anterior partia de uma reprodução manual (fora do Cypress) onde
a transição TAMBÉM ficava presa — na hora achei que fosse só uma aba em segundo plano do meu
navegador de teste (Chrome joga requestAnimationFrame fora do ar em aba não visível). Rodando
de verdade em cypress run (Electron headless, que roda sem janela real do jeito que o Chrome
entende "visível"), a mesma trava acontece: a transição do rc-motion/Ant Design nunca avança de
enter-start pra enter-active/completo, porque depende de requestAnimationFrame, que
Electron headless não dispara de forma confiável. Ou seja: minha correção anterior tinha o
diagnóstico certo (é a animação que trava) mas a solução errada (esperar ela terminar nunca
funciona em headless — não é questão de timeout maior, ela literalmente não avança).
Correção: MenuPage.js — abrirGrupo(), clicarItem() e
clicarItemPorIndice() trocaram .should('be.visible').click() por
.scrollIntoView().invoke('click'). .invoke('click') chama o .click() nativo do elemento
via jQuery, sem passar pela checagem de visibilidade/clipping do Cypress — os itens do submenu já
existem de verdade no DOM assim que o React atualiza o estado (só a REVELAÇÃO visual é que fica
animando/travada), então não tem por que esperar a animação pra clicar neles. Removido
esperarSubmenuTerminarAnimacao() e o elemento submenusAbertos (não servem mais pra nada).
2026-08-20 — smoke.cy.js estava pulando "DDA > Aplicações" achando que "mesma URL" bastava
Categoria: Gap de cobertura no smoke, corrigido — reportado pelo usuário
Sintoma: smoke.cy.js não tinha it() pra "DDA > Aplicações" — na 1ª versão, eu tinha
decidido pular esse item porque ele leva pra MESMA URL de "Aplicações" solta no topo do menu
(/app/aplicacao/listar, confirmado navegando nos dois manualmente), documentando isso como
"item sem it() próprio, de propósito". O usuário apontou o gap: "ta faltando um dda, existe o
dda aplicações".
Causa: decisão errada minha — o objetivo do smoke é cobrir toda OPÇÃO do menu (testar a navegação em si, item por item, como o usuário pediu desde o início: "vai passando menu por menu"), não só toda URL única. Duas entradas de menu levando pra mesma tela ainda são 2 cliques diferentes que precisam funcionar.
Correção: smoke.cy.js ganhou o it('DDA > Aplicações carrega'), usando clicarItemPorIndice('Aplicações', 1) (mesmo padrão de "Boletos"/"Geral" —
"Aplicações" também aparece 2x no DOM com o grupo DDA aberto: a solta do topo primeiro, a
aninhada do DDA depois). Só "Notificações > Boletos" continua de fora — esse sim não leva a
lugar nenhum (submenu vazio, ver docs/regras-de-negocio.md).
2026-08-20 — Validado que o MutationObserver já pegava os erros de verdade + trocado por checagem de rede (mais direta)
Categoria: Melhoria (a pedido do usuário), não bug — a correção anterior já funcionava
Contexto: depois da correção do MutationObserver (entrada logo abaixo), o usuário rodou de
novo e o log mostrou 5 falhas reais capturadas corretamente (expected true to be false em
"Conta Condominial > Geral", "Conta Condominial > Webhook", "DDA > Empresas", "DDA > Boletos",
"DDA > Consumo") — ou seja, a correção do MutationObserver já estava funcionando, pegando erro
de verdade. O usuário então perguntou (não reportou bug novo): "a validação do erro vc fez por
request? no caso validando se esta retornando 200 ou algum status de erro?" — resposta honesta:
não, era pelo toast na tela (MutationObserver), não pela resposta HTTP.
Por que trocar mesmo funcionando: checar a resposta HTTP em si é estritamente mais direto e
mais informativo que inferir pelo toast — não depende da UI sempre renderizar o toast certinho
pra qualquer tipo de falha, e a mensagem de erro da asserção já mostra o endpoint e o status
exatos (chamada(s) de API com erro: [{"method":"GET","url":"...","status":500}]), em vez de só
"expected true to be false" (que não diz qual chamada quebrou, obrigando a abrir o screenshot).
Correção: MenuPage.js prepararDetectorDeErroDeApi()
reescrito pra usar cy.intercept({url: '**'}, (req) => { req.on('response', (res) => {...}) })
em vez do MutationObserver — intercepta TODA chamada de rede (qualquer origem, já que as telas
chamam pelo menos 2 hosts diferentes), acumula as que vierem com status >= 500 (só erro real de
servidor, não 4xx) numa lista de módulo, e shouldTelaCarregada() confere que essa lista está
vazia. O MutationObserver foi removido.
2026-08-20 — shouldTelaCarregada() aprovava tela com erro de API às vezes — causa real: corrida contra o toast se auto-fechando
Categoria: Bug real no teste, corrigido — o usuário reportou de novo depois da correção
anterior (checagem de toast com cy.wait(2000) + .should('not.exist')): "ta aprovando as telas
que estao retornando erro de api".
Sintoma: rodando várias vezes, a mesma tela com erro real de API (toast vermelho visível) às vezes fazia o smoke falhar (certo) e às vezes passava (errado) — inconsistente, não sempre.
Causa confirmada: medi no navegador real, sem chutar (poll a cada 500ms contando
.notification-error no DOM): o toast aparece rápido (~1s depois da tela montar) e some
sozinho depois de ~3-3.7s — não fica preso na tela pra sempre. A checagem antiga fazia
cy.wait(2000) (contado a partir de quando o breadcrumb já tinha aparecido) e SÓ DEPOIS conferia
se o toast existia no DOM naquele instante exato — uma corrida real contra o auto-dismiss: se o
clique+render da tela naquela execução foi um pouco mais lento, a checagem caía depois do toast
já ter sumido sozinho, e o teste aprovava uma tela quebrada. Não era flakiness aleatória — era
literalmente esperado que falhasse às vezes, por construção.
Correção: MenuPage.js ganhou
prepararDetectorDeErroDeApi() — liga um MutationObserver (chamado no beforeEach, antes de
qualquer navegação) que marca uma flag persistente em window.__smokeApiErrorSeen assim que o
toast aparecer pela 1ª vez. A flag continua true mesmo depois do toast sumir sozinho.
shouldTelaCarregada() agora confere a flag, não o DOM ao vivo.
Validado de verdade, não só no código: reproduzi o cenário exato no navegador (observer
ligado, navegação client-side pro menu, sem reload) em "DDA > Consumo" — 5s depois de montar a
tela, flag: true (o observer pegou o erro) e toastAgora: 0 (o toast já tinha sumido sozinho).
Prova direta que o jeito antigo (checar o DOM ali) teria dado falso negativo exatamente nesse
caso, e o novo não.
2026-08-20 — MenuPage.js: 3 correções na mesma rodada (design do smoke + 2 bugs reais)
Categoria: 1 correção de design (feedback do usuário) + 2 bugs reais no teste, todos corrigidos
1) Smoke tinha que falhar com toast de erro de API, e não falhava. Decisão errada minha (ver
entrada acima, já corrigida): um smoke que só confere "o breadcrumb apareceu" deixa passar uma
tela que carrega a casca mas falha ao buscar dado nenhum — o usuário apontou isso corretamente
("se ta dando erro de api tem que retornar erro no smoke"). shouldTelaCarregada() agora também
confere .notification-error (classe do toast, confirmada no DOM real) com not.exist, depois
de um cy.wait(2000) deliberado — sem esperar, a checagem passaria sempre, rápido demais pra dar
tempo da resposta de erro da API chegar (cada tela chama endpoints diferentes; não dá pra
interceptar um único endpoint genérico aqui).
2) clicarItemPorIndice() nunca funcionava — erro de API do Cypress, não de DOM.
Sintoma: rodando de verdade, "Conta Condominial > Dashboard > Geral" e "DDA > Boletos"
falhavam com Expected to find element: \1`, but never found itemcy.contains(li.ant-menu-item, ...)`.
Causa confirmada: cy.contains(seletor, texto) no Cypress sempre resolve a UM único
elemento (o 1º que bate), mesmo passando um seletor — não é uma coleção com todos os matches.
O código antigo fazia cy.contains('li.ant-menu-item', /^Geral$/).eq(1): .eq(1) num resultado
que já era 1 elemento só nunca acha nada, não importa quantos "Geral" existissem de verdade no
DOM. Confirmei reproduzindo os 2 elementos reais no navegador (document.querySelectorAll via
JS) antes de mexer no código — o DOM estava certo, o comando Cypress que estava errado.
Correção: trocado por cy.get('li.ant-menu-item').filter((_, el) => el.textContent.trim() === nome) — isso sim devolve a coleção completa, aí .eq(indice) funciona.
3) "DDA > Consumo" clicava num item clipado pelo scroll interno do menu.
Sintoma: <li.ant-menu-item> is not visible ... clipped by ... overflow: hidden/scroll/auto.
Causa confirmada: o menu lateral tem scroll PRÓPRIO, separado do scroll da página. "DDA" fica perto do fim da lista; depois de abrir o grupo, os itens filhos (principalmente o último, "Consumo") ficam fora da área visível do menu. O auto-scroll padrão do Cypress antes de clicar não deu conta nesse caso (grupo tinha acabado de expandir, mudando a altura da lista).
Correção: .scrollIntoView() explícito antes do .click() em abrirGrupo(), clicarItem()
e clicarItemPorIndice().
Atualização (mesmo dia, rodando de novo): o .scrollIntoView() sozinho não bastou —
"DDA > Boletos" e "DDA > Consumo" continuaram falhando com o mesmo "clipped by overflow".
Reproduzi no navegador real (sessão logada, fora do Cypress): depois de abrir o grupo "DDA", o
<ul class="ant-menu-sub"> dos filhos fica preso um tempo nas classes de transição do
rc-motion/Ant Design (ant-motion-collapse-enter-start), com altura computada 0px mesmo já
tendo o scrollHeight final certo (180px) — ou seja, não é (só) posição de scroll, é a
ANIMAÇÃO de abrir ainda não ter terminado quando o clique seguinte tenta acontecer.
abrirGrupo() agora chama esperarSubmenuTerminarAnimacao() logo depois do clique — um
.should(callback) que espera toda ul.ant-menu-sub aberta sair dessas classes de transição,
em vez de um cy.wait() de duração fixa (a duração real da transição pode variar).
2026-08-20 — MenuPage.expandirMenu(): leitura única do DOM não esperava o menu montar
Categoria: Bug real no teste (Page Object novo), corrigido
Sintoma: rodando o smoke de verdade (cypress run, sessão logada real do usuário — passou do
login desta vez), expandirMenu() falhava toda execução:
expected '<ul.ant-menu...ant-menu-inline-collapsed...>' to have class 'ant-menu-inline'.
Causa confirmada: expandirMenu() copiou o padrão de expandMenu() já usado nas outras Page
Objects do projeto (ContaGeradoraPage, AplicacaoPage, etc.): cy.get('body').then(($body) => { if ($body.find('[aria-label="menu-unfold"]').length) {...} }). Esse padrão é uma FOTO ÚNICA do
DOM no instante da chamada — sem retry. Rodando via cy.login() de verdade (não a navegação
direta por URL que as outras Page Objects fazem antes de checar o menu), o <ul class="ant-menu- root"> às vezes ainda não tinha montado no instante exato dessa checagem: o if batia em falso,
nenhum clique acontecia, e a asserção de classe que eu adicionei depois (have.class 'ant-menu-inline') — que as outras Page Objects não têm — sempre estourava o timeout, porque
nada nunca clicava o botão de verdade. Mesma classe de bug já documentada aqui antes pra
contaCorrente.cy.js: uma leitura única do DOM não espera algo que ainda vai aparecer.
Correção: MenuPage.js expandirMenu() reescrito pra usar
cy.get('.ant-menu-root', {timeout: 15000}).then(...) — essa consulta tem retry de verdade,
esperando o menu existir antes de decidir se clica. Também troquei o clique em si pra mirar só
[aria-label="menu-unfold"] (não o seletor combinado com menu-fold, que corre risco de casar 2
elementos ao mesmo tempo — cy.click() recusa clicar em mais de 1).
Pendente: as outras Page Objects do projeto (ContaGeradoraPage, AplicacaoPage,
RelatorioPage, BoletoPage, ContaCorrentePage) têm o mesmo padrão de foto única em
expandMenu() — não corrigido nelas porque nunca tiveram uma asserção logo depois que exponha o
problema (o clique que vem em seguida, no item de menu de verdade, tem seu próprio retry e
mascara a falha). Fica como candidato pra revisar se algum dia aparecer flakiness parecida lá.
2026-08-20 — smoke/smoke.cy.js: falha ao rodar headless não é bug do spec, é totpSecret ausente
Categoria: Ambiente local, sem correção de código (limitação já documentada)
Sintoma: rodando npx cypress run --spec "cypress/e2e/smoke/**/*.cy.js" logo depois de criar
o spec, o before each (dentro de cy.login()) falhou: expected '.../signin' to not include '/signin', com timeout de 10s.
Causa confirmada: cypress.env.json deste ambiente não tem totpSecret configurado
(confirmado lendo o arquivo — chave ausente). Sem ele, cy.login() cai no modo assistido
(cy.pause()), que não tem efeito em modo headless (comportamento já documentado em
CLAUDE.md e no README, seção "Segundo fator") — o teste segue sem preencher o código, nunca sai
da tela de login, e a checagem de URL estoura o timeout. Não é um bug no smoke.cy.js: ele só
reutiliza cy.login() e os goTo...() já existentes de cada Page Object, nenhum seletor novo.
Correção: nenhuma — não há o que corrigir no spec. Fica pendente de ação humana: configurar
totpSecret real em cypress.env.json (ver README, seção "Segundo fator") pra validar o smoke
de ponta a ponta em modo headless, ou rodar npm run cy:open (modo assistido, confirmando o
código no celular na hora) enquanto isso não acontece.
Atualização (mesmo dia, spec reescrito pra cobrir todo o menu — 23 it()s): rodei de novo
depois de expandir o smoke pra navegar item por item do menu (MenuPage.js) — mesma causa
exata, mesmo ponto de falha. O Cypress listou os 23 testes normalmente antes de falhar no
before each (prova que o spec novo não tem erro de sintaxe/import), então a conclusão acima
continua valendo sem mudança.
2026-08-20 — contaCorrente.cy.js: 3ª rodada — causa real da falha de datas/total (não era blur)
Categoria: Instabilidade passageira (corrigida com espera de verdade, não mais um retry cego)
Sintoma: depois da 2ª correção (blur no campo de data — ver entrada abaixo), rodando de novo:
os 3 filtros de data com the argument to below must be a number, e "Limpar Seleção" com
expected 1 to equal null. Erros novos, diferentes dos anteriores — sinal de que a correção do
blur não tinha resolvido nada de verdade (só mudou o sintoma).
Causa confirmada: lerTotalResultados()/shouldTerMenosResultadosQue() liam o texto de
paginação ("X - Y de Z") sem esperar a busca assíncrona terminar. Como o texto tem o MESMO
formato antes e depois de uma busca (só o número muda), não tinha nada ali que desse pra "esperar
aparecer" — então às vezes a leitura pegava o total ANTIGO (ainda não tinha atualizado) e às
vezes pegava o texto ainda vazio (a tela nem tinha carregado a 1ª vez). O blur da correção
anterior não tinha nada a ver com essa causa — por isso continuou falhando, só que de um jeito
diferente (mais raro de bater exatamente nos mesmos dois valores iguais).
Correção:
ContaCorrentePage.js:pesquisar()elimparSelecao()agora interceptam a chamada real (GET .../adm/contas-correntes?size=...&page=..., confirmado na aba de rede) e esperam ela terminar antes de devolver o controle — elimina a corrida na raiz, em vez de tentar adivinhar um jeito de "esperar o texto mudar".lerTotalResultados()também ganhou um.should()que espera o texto bater no padrão esperado antes de extrair o número, cobrindo o caso do 1º carregamento da tela (antes de qualquer busca).
Lição: a correção anterior (blur) foi aplicada sem confirmar a causa raiz — só uma hipótese plausível que "parecia" fazer sentido pro sintoma na hora. Não resolveu, e só ficou claro que estava errada quando o sintoma mudou de cara numa 3ª rodada. Da próxima vez, glue: sem conseguir reproduzir a falha investigando por fora do Cypress, vale desconfiar mais da própria hipótese antes de aplicar como se fosse a causa confirmada.
2026-08-20 — contaCorrente.cy.js: 2ª rodada, mais 3 falhas (1 nova, 2 remanescentes)
Categoria: Seletor/DOM desatualizado (Principal — confirmado) + causa não 100% confirmada (datas)
Sintoma: depois da 1ª correção (ver entrada abaixo), rodando de novo: Principal falhou com
expected '' to include 'Sim'; os 3 filtros de data continuaram com expected 6420 to be below 6420 (a correção anterior não resolveu); e o teste novo de "Limpar Seleção" falhou com expected 1 to equal 6420 (não voltou pro total completo).
Causa confirmada — Principal: a coluna não mostra texto "Sim"/"Não" — mostra um ícone SVG
(data-testid="DoneIcon") quando verdadeiro, célula vazia quando falso. textContent de um SVG
é sempre "", por isso a asserção de texto nunca batia.
Causa NÃO totalmente confirmada — datas: testado manualmente (fora do Cypress, replicando
exatamente a lógica do Page Object) e o valor É aplicado corretamente, a busca É restringida —
não consegui reproduzir a falha fora do Cypress. Hipótese aplicada: o campo de data só finaliza
a validação/máscara interna ao perder o foco (blur), e o Page Object não disparava esse evento.
Ainda não confirmado que isso resolve — precisa rodar de novo pra saber.
Correção:
ContaCorrentePage.js:shouldTodasAsLinhasTeremIconeNaColuna()novo, pra colunas de ícone (Principal).totalResultadosTextotrocado pra seletor de classe (.MuiTablePagination-displayedRows), mais preciso que ocy.contains(regex)solto anterior — pode também ter efeito no problema do "Limpar Seleção" (não confirmado).preencherCampo()ganhou umdispatchEvent(blur)no final.contaCorrente.cy.js: teste de Principal usa o novo método de ícone em vez de texto.
Pendente: confirmar rodando de novo se o blur resolveu as datas e se o "Limpar Seleção"
passou a voltar pro total certo.
2026-08-20 — contaCorrente.cy.js: 11 dos 14 testes de filtro falharam na 1ª execução real
Categoria: Seletor/DOM desatualizado + Regra de negócio nova (múltiplas causas diferentes)
Sintoma: rodando pela 1ª vez de verdade (interativo, com 2FA), 11 dos 14 filtros falharam, com 4 tipos de erro diferentes:
cy.click() failed because... has CSS pointer-events: none— Status, Status Aprovação, Aplicação, Principal, Conta Geradora (todos os combos).cy.eq() failed... No elements(0 resultados) — Conta Corrente.cy.find() failed because the page updated... subject no longer attached to the DOM— Código Banco, Agência.expected 6420 to be below 6420(filtro não restringiu nada) — Data Cadastro, Data Modificação, Data Última Aprovação.
Causa confirmada (cada uma investigada direto no DOM real antes de corrigir):
- Combos:
input[name="..."]não é o elemento clicável — é um campo oculto (aria-hidden,pointer-events:none) que o MUI usa só pra semântica de formulário. O elemento de verdade é um<div role="combobox">irmão desse input. - Conta Corrente / Agência: a tela mostra o valor COM dígito verificador ("22378320-1", "111-1"), mas o filtro só aceita o valor SEM ele ("22378320", "111") — confirmado testando os dois formatos direto na API/tela.
- Código Banco / Agência (staleness): o Page Object usava
.each() + cy.wrap()pra conferir cada linha — quando a tabela re-renderiza entre uma linha e outra, a referência guardada fica órfã. Padrão clássico do Cypress com listas que re-renderizam. - Datas:
.clear().type()não estava confiável rodando via Cypress (digitando manualmente, devagar, funcionava; viacy.type()no teste real, não). Não foi possível confirmar a causa exata (mask/timing) com certeza — a correção adotada (setar o valor direto via setter nativo + eventoinput, sem depender de digitação caractere a caractere) é a mesma técnica que já tinha se mostrado 100% confiável durante a investigação, então resolve independente da causa exata.
Correção:
ContaCorrentePage.js:comboTrigger()novo (seleciona o[role="combobox"], não o input oculto);preencherCampo()reescrito pra setar valor direto;shouldTodasAsLinhasTeremColuna()trocado de.each()+cy.wrap()pra.should(callback)(reconsulta sozinho a cada retry) e de igualdade exata pra "contém" (a coluna Agência tem um sufixo que o filtro não usa).contaCorrente.cy.js:DADOS_REAIS.agencia/.contacorrigidos pro formato sem dígito verificador.regras-de-negocio.mdatualizado com a regra do dígito verificador.
2026-08-20 — 2 testes de mensagem de validação quebraram: texto não é fixo entre execuções
Categoria: Bug no teste (asserção presumia texto fixo — corrigida pra checar padrão)
Sintoma 1 — boletoViaApi.cy.js, "vencimento retroativo": expected 'Erro: O prazo de desconto deve ser superior a data de hoje.' to equal 'Erro: Boleto não pode ser gerado com data de vencimento anterior a hoje.' — o teste já tinha passado antes com o 2º texto; dessa vez saiu
o 1º.
Sintoma 2 — boletoSimulaErroEmissao.cy.js, "código externo do boleto repetido": expected 'A conta digital [...] possui códigos externos duplicados: [...]' to include 'já cadastrado' —
falhou nas 3 vezes que rodou, sempre com essa mesma mensagem (diferente da que eu tinha fixado no
teste).
Causa confirmada:
- Rodando "vencimento retroativa" 3x seguidas manualmente (fora do Cypress), sempre saiu o
MESMO texto ("Boleto não pode ser gerado...") — então não é aleatório a esse ponto, mas o fato
de existir pelo menos 1 execução real (a do Cypress) com o outro texto confirma que não é
garantido ser sempre o mesmo. Hipótese mais provável (não 100% confirmada): o payload usa a
mesma data retroativa em 4 campos ao mesmo tempo (
dataVencimento,prazoDesconto,dataCarenciaMulta,dataCarenciaJuros) — mais de uma validação falha ao mesmo tempo, e qual delas "ganha" a mensagem reportada não parece ser determinístico. - O "código externo duplicado" tinha uma causa DIFERENTE e totalmente explicável: minha
verificação manual anterior (que gerou a mensagem "já cadastrado" que virou a asserção do
teste) sem querer reaproveitou o
codigoExternoda REMESSA inteira, não só do boleto — são duas validações diferentes no backend. O teste real (boletoSimulaErroEmissao.cy.js) só duplica ocodigoExternodo BOLETO (correto, é o que o teste se propõe a checar) — e essa validação usa outra mensagem ("A conta digital [...] possui códigos externos duplicados: [...]"), confirmada consistente em 3 execuções seguidas.
Correção:
BoletoPage.js: novo suporte amensagemValidacaoRegex(além domensagemValidacaode texto exato) emshouldShowDetalhes().boletoViaApi.cy.js: "vencimento retroativo" agora usamensagemValidacaoRegex: /^Erro: .*(anterior a hoje|superior a data de hoje)\.$/em vez do texto exato.boletoSimulaErroEmissao.cy.js: asserção de duplicidade corrigida pra mensagem real, com checagem mais forte (confere que o guid do condomínio e o codigoExterno original aparecem na mensagem, não só um trecho solto).regras-de-negocio.mdatualizado nos dois pontos, incluindo a descoberta de que existem 2 validações de duplicidade diferentes (remessa vs. boleto).
2026-08-20 — Investigação de erros em "Gerar Boleto": 1ª tentativa usou mock errado, corrigida
Categoria: Bug no teste (abordagem inicial não testava nada de verdade — corrigida)
Sintoma: pedido era mapear o que acontece quando a API de "Gerar Boleto" devolve cada erro do
catálogo (400/401/403/409/422/500/503, ver print do usuário com exemplos de retorno). Primeira
implementação (overrides.simularErroEmissao em commands.js + mock do Postman "Banco - Emissao
de Remessa (Mock)") trocava a URL da chamada inteira pelo mock — resultado: nenhum dos 9
cenários (nem os 2 de sucesso, 200/201) criava um boleto de verdade. O usuário apontou
corretamente que isso não bate com a prática ("impossível").
Causa confirmada: a implementação nunca chegava a bater no Core real — um servidor à parte (o mock) respondendo "sucesso" não tem como fazer o Core real persistir nada. A conclusão "nenhum erro cria boleto" não vinha de testar o produto, vinha de testar um servidor de mentira que nunca conversou com o produto. Erro de abordagem, não de execução.
Correção: reescrito do zero — overrides.simularErroEmissao/mock removidos de
commands.js (voltou ao estado original). Novo boletoSimulaErroEmissao.cy.js bate DIRETO na
API real de homologação com entradas propositalmente inválidas (token quebrado, guid de
condomínio inexistente, campo obrigatório faltando, código externo repetido) — cada uma testada
manualmente primeiro (fora do Cypress) antes de virar teste. Achados reais (tabela completa em
regras-de-negocio.md):
- Token inválido → 403 (não 401), síncrono, sem criar boleto.
- Condomínio inexistente → 404, síncrono, sem criar boleto.
- Campo obrigatório faltando (
cliente.cpfCnpj) → 500 com erro de banco cru vazado — bug real do produto, não devia estourarConstraintViolationExceptionpro cliente da API. - Código externo duplicado → 400 "já cadastrado", síncrono, não duplica o boleto original.
- (Já sabíamos) Data retroativa → único caso que É aceito (200) e o boleto É criado, terminando
em
ERRO_VALIDACAOdepois — o único cenário onde "boleto criado com erro visível" realmente acontece.
Regra de negócio atualizada: Boletos → o que acontece quando Gerar Boleto recebe um erro — reescrita.
2026-08-20 — relatorios.cy.js: "Transferências Pagas" nunca disparava a requisição
Categoria: Regra de negócio nova
Sintoma: cy.wait() timed out esperando a 1ª requisição pra solicitarRelatorio — "No
request ever occurred." Só acontecia com "Transferências Pagas"; os outros 9 tipos sempre
passaram (já sinalizado como suspeito numa entrada anterior — ver mais abaixo — mas não
investigado a fundo até essa falha isolada acontecer de novo).
Causa confirmada: testando manualmente na tela (fora do Cypress), com a rede monitorada:
"Transferências Pagas" tem 2 campos a mais que nenhum outro tipo pede — "Guid
Administradora" e "Guid Condominio" (texto livre). RelatorioPage.preencherUltimos10Dias() só
preenche campos de data (.ant-picker-input), então esses 2 ficavam sempre vazios. Sem eles, o
clique em "Gerar Relatório" não dá nenhum erro visível — só não dispara requisição nenhuma
(confirmado: rede zerada). Preenchendo os 2 com qualquer valor (testado com um guid aleatório,
sem relação com nenhuma Administradora/Condomínio real), a chamada foi aceita normalmente (200).
Correção: RelatorioPage.js ganhou
preencherCamposGuidSeExistirem() — genérico por rótulo ("começa com Guid"), igual ao padrão já
usado pras datas, não uma lista fixa de 2 nomes. Chamado logo depois de
preencherUltimos10Dias() em relatorios.cy.js, nas duas
gerações (1ª e a de bloqueio de 15 min). regras-de-negocio.md atualizado.
2026-08-20 — boletoViaApi.cy.js: cancelamento não chega em CANCELADO (mesma rodada da entrada abaixo)
Categoria: Bug no teste (asserção presumia um status final errado — corrigido)
Sintoma: depois de corrigir a falha de cancelamento descrita na entrada abaixo (esperar
GERADO antes de cancelar), o usuário rodou de novo e bateu numa 2ª falha, diferente:
expected 'PEDIDO_CANCELAMENTO' to equal 'CANCELADO' — o cancelamento em si funcionou (sem mais
400), mas o status nunca chegou em CANCELADO dentro da espera do teste (10 tentativas × 2s).
Causa confirmada: consultado o mesmo boleto direto na tela bem depois (minutos, não segundos,
passados desde a falha) — o status continuava PEDIDO_CANCELAMENTO. Não é falta de espera, é
que PEDIDO_CANCELAMENTO é o status que o cancelamento efetivamente alcança num prazo observável;
CANCELADO provavelmente depende de processamento fora do alcance de um teste automatizado (ver
regras-de-negocio.md).
Correção: overrides.cancelarApos (em cy.gerarBoletoViaApi, commands.js) e o teste
correspondente (boletoViaApi.cy.js) agora esperam/validam PEDIDO_CANCELAMENTO, não
CANCELADO. regras-de-negocio.md atualizado com o status novo.
2026-08-20 — boletoViaApi.cy.js: modal de Detalhes "not visible" (flake, não corrigido)
Categoria: Flake (suspeita de bug do Cypress/MUI — não confirmado a ponto de corrigir)
Sintoma: expected <div.MuiPaper-root...MuiDialog-paper...> to be 'visible' ... its ancestor has position: fixed CSS property and it is overflowed by other elements ao abrir "Detalhes" no
teste "boleto com dados padrão" — mas o screenshot da falha mostra o modal perfeitamente
renderizado e com todos os dados certos (Status GERADO, Nosso Número, Seu Número, etc.).
Causa (não confirmada): o texto do erro e o screenshot conflitam — visualmente está tudo
certo, então isso tem cara de falso-negativo do cálculo de visibilidade do Cypress (heurística de
position: fixed + overflow de ancestral), possivelmente relacionado ao scrollTo('left') que
BoletoPage.abrirDetalhes() faz na tabela um pouco antes de abrir o modal. Só ocorreu 1 vez até
agora — não investiguei a fundo nem apliquei correção nenhuma (seguindo a regra de não corrigir
seletor no chute); documentando aqui pra ter contexto se voltar a acontecer.
Correção: nenhuma. Se voltar a acontecer, revisar abrirDetalhes() em
BoletoPage.js — provável ponto de partida: resetar o scroll
horizontal da tabela antes (não só depois) de abrir o modal, ou trocar .should('be.visible') por
uma espera mais tolerante à transição de abertura do MuiDialog.
2026-08-20 — boletoViaApi.cy.js: 2 falhas nos testes novos de vencimento retroativo e cancelamento
Categoria: Bug no teste (código do teste presumia um comportamento errado — corrigido)
Sintoma 1 — "boleto com vencimento retroativo": Timed out retrying after 10000ms: Expected to find element: input[name="nossoNumero"], but never found it ao tentar checar
deveTerNossoNumero: false no modal de Detalhes de um boleto ERRO_VALIDACAO. Capturada
automaticamente em falhas-pendentes.md.
Sintoma 2 — "cancelamento de boleto": falha no before() (por isso não foi capturada
automaticamente — o hook afterEach que grava falhas-pendentes.md só roda em volta de um
it() que chegou a executar; ver nota abaixo). cy.request() na chamada de cancelamento voltou
400: "Cancelamento não pode ser efetuado, pois boleto está pendente de envio para o banco."
Causa confirmada: os dois vieram de suposições erradas escritas no código do teste/comando, não de bug no produto — confirmado reproduzindo cada cenário direto na API (fora do Cypress), repetidamente:
- A seção inteira de "dados de emissão" do modal (Nosso Número, Linha Digitável, PIX, Código
Banco, Conta Geradora, Tipo de Emissão) não existe no DOM enquanto o boleto não chega em
GERADO— não é só valor vazio, o<input>simplesmente não é renderizado. O código (BoletoPage.shouldShowDetalhes) assumia valor vazio (cy.get(...).invoke('val').should('be.empty')), que exige o elemento existir. overrides.cancelarApos(emcy.gerarBoletoViaApi) cancelava o boleto assim que o guid real (identificadorContaGroup) existia — mas esse guid é atribuído bem antes do boleto terminar de processar (o status ainda podia estarRECEIVED/REGISTRO_CRIADO, nãoGERADO), e cancelar nesse estado é rejeitado. Descoberto também, nessa investigação: existe um status intermediário (REGISTRO_CRIADO) entreRECEIVEDeGERADO/ERRO_VALIDACAOque não estava documentado.
Correção:
BoletoPage.js:deveTerNossoNumero/deveTerLinhaDigitavelagora checamexist/not.existno modal, não o valor. Adicionado suporte ao campovalidacoes(o único lugar, em toda a API/tela, que mostra o motivo de umERRO_VALIDACAO).commands.js:overrides.cancelarAposagora espera o boleto chegar emGERADO(viaesperarStatusBoleto) antes de chamar o cancelamento.esperarStatusBoletotambém teve o número de tentativas aumentado (6 → 10) por segurança, já que o caminho atéGERADOpode passar pelo estado intermediário.regras-de-negocio.mdatualizado: statusREGISTRO_CRIADO, campovalidacoes(com a mensagem exata), pré-condição deGERADOpro cancelamento, e a renderização condicional da seção de dados de emissão.
Gap identificado (não corrigido nesta rodada): falha em before()/before all não é
capturada por falhas-pendentes.md — o afterEach global (support/e2e.js) só roda em volta de
um teste (it()) que efetivamente começou a rodar; quando o hook de setup falha, o Mocha pula os
it()s da suíte sem executá-los, e o afterEach nunca dispara. Foi assim que a falha do
cancelamento passou batido da captura automática — só apareceu porque o usuário colou o erro
manualmente. Vale considerar um hook global adicional (Cypress.on('fail') ou similar) se isso se
repetir.
2026-08-20 — relatorios.cy.js falhou nos 10 tipos ao rodar de novo dentro de 15 min
Categoria: Regra de negócio (o teste bateu na própria regra que ele mesmo valida — não é bug)
Sintoma: rodando a suíte inteira 2x seguidas (de propósito, pra testar o mecanismo de
falhas-pendentes.md), os 10 tipos falharam na 2ª rodada — 9 com
Expected to find content: '/sucesso/i' but never did (Boletos Gerados, Boletos Pagos Mensal,
DIMP Transações, DIMP Clientes, Cadastro Condomínios, Financeiro, Projeção de MRR, Zoho Boletos
Pagos Core, Zoho Boletos Pagos VS) e Transferências Pagas com cy.wait() nunca vendo a
requisição solicitarRelatorio acontecer — nas duas rodadas. (Investigado de verdade depois,
numa falha isolada — ver entrada acima "Transferências Pagas nunca disparava a requisição".)
Causa confirmada: confirmado pelo usuário — foi ele mesmo quem rodou a suíte inteira 2x
seguidas de propósito, especificamente pra testar se a captura automática em
falhas-pendentes.md funcionava. A 1ª geração de cada tipo (que o teste espera que dê sucesso)
caiu, na 2ª rodada, numa 2ª tentativa daquele tipo dentro de 15 min — a regra de bloqueio do
próprio sistema entrou em ação (ver Relatórios — regra dos 15
min), então a mensagem de bloqueio apareceu no lugar da de
sucesso. Confirmado também olhando a aba "Visualizar Relatório" antes da 2ª rodada terminar: os
tipos já solicitados tinham Data de Solicitação em sequência corrida, mesmo padrão temporal do
teste rodando. O caso de "Transferências Pagas" (clique não disparou a requisição) repetiu nas
duas rodadas — sintoma diferente dos outros 9, mas não investigado a fundo aqui por instrução
direta do usuário (só validar o fluxo de captura, não corrigir); vale investigar de verdade numa
próxima falha isolada desse tipo específico.
Correção: nenhuma — não é bug no teste nem no produto, é a suíte funcionando certo contra uma
regra de negócio real. O teste já existe justamente pra validar esse bloqueio (2ª geração de cada
tipo, no mesmo it()); rodar a suíte inteira de novo antes de 15 minutos passarem naturalmente
recria esse cenário pra 1ª geração também.
Regra de negócio atualizada: nenhuma nova — apenas confirma a regra já documentada em Relatórios.
2026-08-20 — docs/falhas-pendentes.md apontava pra screenshot que não existia
Categoria: Seletor/DOM desatualizado (bug na nossa própria infraestrutura de captura, não no app)
Sintoma: o caminho de screenshot registrado automaticamente em docs/falhas-pendentes.md
não existia no disco — dois problemas somados: (1) o Cypress só tira print sozinho
(screenshotOnRunFailure) em cypress run, nunca em cypress open (confirmado na documentação
oficial, depois de eu ter afirmado errado sem checar primeiro); (2) mesmo tirando o print na mão
(cy.screenshot() num afterEach), o Cypress acrescenta sozinho um sufixo (attempt N) no nome
do arquivo quando é uma tentativa de retry — mesmo passando um nome customizado — e o caminho que
eu calculava não prevía isso.
Causa confirmada: testado rodando um spec que falha de propósito via cypress run (com
retry ativo): o arquivo real gerado tinha (attempt 2) no nome; o caminho gravado em
falhas-pendentes.md não tinha.
Correção: cypress.config.js — screenshotOnRunFailure: false (desliga a nativa, que só
funciona em run mesmo). cypress/support/e2e.js — o afterEach agora chama cy.screenshot()
manualmente (funciona nos dois modos) e calcula o sufixo (attempt N) da mesma forma que o
Cypress, usando _currentRetry, antes de gravar o caminho.
Regra de negócio atualizada: — (infraestrutura de teste, não regra do produto)
2026-08-20 — Retry de ativação de conta quase esgotou as tentativas
Categoria: Instabilidade passageira
Sintoma: rodando cy.gerarBoletoViaApi() de novo (mesmo comando do dia anterior), o passo
"Gerar Boleto" precisou de ~5 das 6 tentativas de retry (400 "Conta digital não está ativa"
repetido) antes de conseguir — no dia anterior tinha resolvido em 1–2 tentativas.
Causa confirmada: a ativação assíncrona da conta digital variou de duração entre os dois dias — sem evidência de bug no código, só o ambiente mais lento nesse dia.
Correção: nenhuma aplicada ainda. Ficou combinado subir a margem de segurança (mais
tentativas e/ou espera maior em gerarBoletoComRetry e consultarGuidDoBoleto,
cypress/support/commands.js) — pendente.
Regra de negócio atualizada: —
2026-08-19 — Guid da resposta de "Gerar Boleto" é provisório
Categoria: Regra de negócio nova
Sintoma: buscar na tela de Boletos pelo guid devolvido na hora da criação não encontrava o
registro (ou o usuário sinalizou que o valor batia com um "guid provisório" visto no Postman,
diferente do usado pela tela).
Causa confirmada: o guid de POST /contaDigital/remessa é provisório. O identificador real
usado na busca da tela (identificadorContaGroup) só existe consultando
GET /contaDigital/{guid_condominio}/boletos depois.
Correção: adicionada a função consultarGuidDoBoleto() em cypress/support/commands.js,
chamada após "Gerar Boleto", com o mesmo padrão de retry (a consulta também pode não achar o item
de imediato, por ser assíncrono).
Regra de negócio atualizada: Boletos → dois identificadores diferentes
2026-08-19 — Assertion de valor falhando com strings visualmente idênticas
Categoria: Seletor/DOM desatualizado (comparação de valor, não seletor em si)
Sintoma: expected 'R$ 275,50' to equal 'R$ 275,50' — as duas strings pareciam idênticas no
print do erro.
Causa confirmada: a tela formata o valor com um espaço não-quebrável ( / )
entre "R$" e o número; formatarValorBRL() gera espaço comum — caracteres diferentes, aparência
igual.
Correção: BoletoPage.shouldShowDetalhes() normaliza espaços (\s+ → espaço comum) dos dois
lados antes de comparar.
Regra de negócio atualizada: —
2026-08-19 — Botão "Detalhes" nunca encontrado
Categoria: Seletor/DOM desatualizado
Sintoma: cy.contains('button', /^detalhes$/i) nunca achava o elemento, mesmo visível na
tela.
Causa confirmada: não é um <button> — é um MUI Chip (<div class="MuiChip-root" role="button">). Confirmado inspecionando o DOM real e clicando via JS puro no navegador.
Correção: seletor trocado pra [role="button"] em BoletoPage.detalhesButton.
Regra de negócio atualizada: —
2026-08-19 — Scroll horizontal da tabela de Boletos não ficava no início
Categoria: Seletor/DOM desatualizado (comportamento do Cypress, não do app)
Sintoma: mesmo chamando scrollTo('left') antes de clicar na seta de expandir, a tabela
continuava fora do início e o clique falhava.
Causa confirmada: o próprio Cypress rola o elemento pra posição que ele calcula como ideal
antes de clicar, desfazendo o scrollTo manual — confirmado clicando via JS puro (sem o Cypress
no meio) e vendo que o scroll não mudava sozinho.
Correção: { scrollBehavior: false } no .click() de BoletoPage.abrirDetalhes(), pra
desligar esse auto-scroll do Cypress.
Regra de negócio atualizada: —
2026-08-19 — cy.gerarBoletoViaApi criando dados duplicados / e-mails em excesso
Categoria: Instabilidade passageira (configuração do projeto, não do ambiente)
Sintoma: múltiplas Administradoras criadas por execução, um e-mail de notificação por cada uma — usuário reportou volume alto de e-mails.
Causa confirmada: duas causas somadas — (1) o watch mode do cypress open reroda a suíte a
cada arquivo salvo, e cada rerun já criava a Administradora antes de falhar mais adiante; (2)
cypress.config.js tem 1 retry automático em cypress run — com a criação dentro do próprio
it(), cada falha na validação da tela duplicava a criação inteira.
Correção: criação via API movida para dentro de um before() (não it()/beforeEach()) em
boletoViaApi.cy.js — hooks before() não são re-executados em retry. Processos Cypress.exe
encerrados na hora pra parar o watch mode.
Regra de negócio atualizada: —
2026-08-19 — PUT .../configuracoes/boleto retornando 403 Acesso negado
Categoria: Regra de negócio nova
Sintoma: chamada pra definir a Conta Geradora do condomínio falhava com 403, mesmo com token válido (o da administradora recém-criada).
Causa confirmada: essa rota é de back-office (/adm/...) — só aceita o token da sessão
logada de um usuário staff, não o token de uma Administradora/Condomínio (API /api/v1/...).
Confirmado inspecionando o localStorage do navegador autenticado
(persist:core → auth.token.raw).
Correção: definirContaGeradora() passou a extrair o token da sessão logada
(pegarTokenDaSessaoLogada()) em vez de reaproveitar o token da administradora; cy.login()
precisa rodar antes de cy.gerarBoletoViaApi().
Regra de negócio atualizada: Autenticação e permissões
2026-08-19 — POST /contaDigital/remessa retornando 400 "Conta digital não está ativa"
Categoria: Regra de negócio nova
Sintoma: "Gerar Boleto" falhava logo após criar o condomínio, com esse erro específico.
Causa confirmada: a ativação da conta digital do condomínio é assíncrona — rodando na mão no Postman, o tempo entre clicar em cada requisição já era suficiente; disparando em sequência imediata pelo Cypress, a chamada às vezes chegava antes da ativação terminar.
Correção: gerarBoletoComRetry() — retry de até 6 tentativas / 2s, só pra esse erro
específico; qualquer outro erro continua falhando na hora.
Regra de negócio atualizada: Credenciamento → ativação assíncrona
2026-08-19 — Menu de Contas Geradoras parou de abrir
Categoria: Seletor/DOM desatualizado (regressão de uma correção anterior)
Sintoma: goToCadastro() parou de conseguir clicar em "Contas Geradoras" no menu lateral.
Causa confirmada: regressão de um fix anterior no mesmo dia (ver entrada abaixo) — desativar
scrollIntoView globalmente pra resolver o scroll de Relatórios também quebrou o uso interno que
o próprio Cypress faz de scrollIntoView pra rolar itens de menu até a área visível antes de
clicar.
Correção: patch de scrollIntoView em cypress/support/e2e.js reescrito pra só restaurar a
posição de scroll do document.scrollingElement depois da chamada nativa, em vez de bloquear a
chamada inteira — containers internos (menu, listas) voltaram a rolar normalmente.
Regra de negócio atualizada: —
2026-08-19 — Zoho Boletos Pagos Core/VS não apareciam no combo de Tipo de Relatório
Categoria: Seletor/DOM desatualizado
Sintoma: selectTipoRelatorio() não conseguia selecionar os 2 últimos tipos da lista.
Causa confirmada: os 10 itens já existem no DOM ao abrir o combo (não é lazy-render), mas o
container da lista (.rc-virtual-list-holder) tem altura fixa menor que o conteúdo total — os 2
últimos ficam fora da área visível/clicável. Uma tentativa anterior de checar "já está
renderizado?" com :visible do jQuery dava falso positivo (não detecta itens clipados por
overflow:hidden do pai).
Correção: selectTipoRelatorio() calcula a posição real da option via
getBoundingClientRect() e ajusta o scrollTop do holder antes de interagir, sem depender de
:visible.
Regra de negócio atualizada: —
2026-08-19 — Scroll da página "pulando" ao selecionar Tipo de Relatório / abrir calendário
Categoria: Seletor/DOM desatualizado
Sintoma: parte do formulário de Relatórios ficava escondida atrás do cabeçalho fixo depois de selecionar o tipo ou abrir um campo de data.
Causa confirmada: o rc-virtual-list (biblioteca por trás dos componentes Ant Design
virtualizados) chama scrollIntoView() no item focado — sem um ancestral com overflow contido,
isso rolava a página inteira em vez de só a lista/calendário.
Correção: primeira tentativa (desativar scrollIntoView globalmente) causou a regressão do
menu de Contas Geradoras (ver entrada acima) — corrigido de vez restaurando só a posição do
document.scrollingElement depois da chamada nativa, em cypress/support/e2e.js.
Regra de negócio atualizada: —
Como adicionar uma entrada
Copiar o formato acima: data, categoria (uma das 4 do protocolo), sintoma, causa confirmada,
correção (ou "nenhuma" se não coube corrigir código), e link pra regras-de-negocio.md se a
causa revelou uma regra nova. Entrada nova sempre no topo (mais recente primeiro).