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)
Data Entrada
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
2026-09-09 🔴 CONFIRMADO: POST /credenciamento quebrado em homologação (500, SQLGrammarException) — bloqueia toda a suíte que cria Administradora
2026-09-09 Painel: botões "✕ Ignorar" / "🗑 Ignorar todos" na fila de Falhas pendentes — limpa a fila pela tela, sem publicar nada no Azure
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)
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"
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
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
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á
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
2026-09-08 cypress/e2e/regressao/ está desatualizada? — auditoria: nenhum bug confirmado sem teste, só o flake conhecido do cancelamento segue sem decisão
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
2026-09-08 cy.expandirMenu() reforçado pra parar de vez com o timeout intermitente em ant-menu-inline (recorrente desde 20/08)
2026-09-04 "Falhas pendentes" vira fila mestre-detalhe (com screenshot), a pedido do usuário
2026-09-04 Painel: badge de falhas pendentes direto na aba "Azure DevOps" (nav)
2026-09-04 Fonte de código tirada de TODO lugar com número/data/contador no painel
2026-09-04 "0" não confunde mais com "8" — 2 tentativas até achar a raiz de verdade
2026-09-04 Filtro de módulos vira dropdown multi-select (marca vários, roda a combinação)
2026-09-04 Botão "⏹ Parar" cancela de verdade uma execução em andamento
2026-09-04 Scrollbar do painel acompanha o tema (claro/escuro)
2026-09-04 Migração retroativa: todo dado existente até hoje marcado como "dev" + regra permanente pra testes novos
2026-09-04 Flag global "Modo Dev": separa execução de desenvolvimento de teste válido
2026-09-04 Fila de falhas pendentes esvaziada por pedido explícito (as 3 de cross-tenant sairão pra re-teste)
2026-09-04 Dashboard: subtítulo de "Módulos com mais reprovações" também removido
2026-09-04 Dashboard: subtítulo do card "Work Items recentes" removido
2026-09-04 Painel: botão "Pular ›" removido da fila de falhas pendentes (redundante)
2026-09-04 Recorrência "Replicar decurso em subcontas" (16:34) — já conhecida, já vinculada
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)
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
2026-09-04 Cold-boot do login em modo headless: testado Chrome no lugar de Electron — não resolve sozinho
2026-09-04 cy.loginViaApi(): login 100% via API elimina o cold-boot — piloto rodado no Sanity, resultado forte
2026-09-04 cy.loginViaApi() estendido pra TODA a suíte — validado, só 1 recorrência já conhecida apareceu
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"
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)
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
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"
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
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)
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é
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
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 ▶
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
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
2026-09-04 Painel: aba Execução reorganizada (busca+chips / 3 sub-abas / console recolhível no rodapé) + modo claro/escuro no sistema todo
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
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
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)
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
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
2026-09-03 Correção: Bug #26951 NÃO cobre "Replicar decurso em subcontas" — só "Decurso personalizado" (desfeito o vínculo da entrada anterior)
2026-09-03 "Replicar decurso em subcontas" confirmado tratado no Bug #26951 (mesma demanda que cobre "Decurso personalizado")
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
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
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
2026-09-03 Bug #26954 ("Decurso personalizado") corrigido pelo dev: teste atualizado pra validar o comportamento correto
2026-09-03 Triagem de lote: execução completa da suíte (12 recorrências), todas de causas já conhecidas
2026-09-03 Triagem: mais recorrências (GUID Administradora x2, Decurso/Replicar x2), validando o novo Dashboard do painel
2026-09-03 Triagem de lote: mais recorrências (GUID Administradora, UX combobox, Decurso/Replicar), todas de causas já conhecidas
2026-09-03 Triagem: mais 2 recorrências do GUID de Administradora em Gerar Boleto (já confirmado, Task 25706)
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)
2026-09-03 subconta.cy.js: mais 1 recorrência de "conta não está ativa" → cascata (VS ainda não aprovando)
2026-09-03 Triagem de lote: recorrências de 01–03/09, todas de causas já conhecidas
2026-09-02 ⚠️ CONFIRMADO: mais 2 endpoints de Entidade aceitam cross-tenant (Buscar Boletos, Criar Condomínio) — Criar Conta Corrente ADM está protegido
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
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)
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
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)
2026-09-02 Provas de conceito novas (acessibilidade + performance) já nasceram medindo o cold-boot: 3 recorrências em <20min
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
2026-09-01 pre-commit (Husky) configurado: README sempre atualizado + 2ª camada contra segredo
2026-09-01 Triagem: mais 1 recorrência do job sem auth (já confirmado)
2026-09-01 Triagem de lote: recorrências do job sem auth (já confirmado) + cross-tenant de cancelamento
2026-09-01 Nova convenção: toda API nova exige teste de autenticação em autenticacaoObrigatoria.cy.js
2026-09-01 ⚠️ CONFIRMADO: POST /job/contas-digitais/atualizar-flag-emissao não exige autenticação
2026-09-01 Triagem de lote: 3 trackers de segurança, sem 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
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)
2026-08-31 Triagem de lote: resto da fila é recorrência já mapeada (2 trackers de segurança + smoke DDA/Conta Condominial pré-.skip)
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
2026-08-31 CONFIRMADO: PEDIDO_CANCELAMENTO não é terminal — boleto avança sozinho pra CANCELADO em poucos minutos (resolve achado pendente de 24/08)
2026-08-31 smoke.cy.js: "Usuários > Listar" travou no beforeEach (ant-menu-inline) — cascata de 22 pulados, recorrência já mapeada
2026-08-31 contaCorrente.cy.js: causa raiz real do "registro conhecido some da tabela" — paginação, não o filtro de data
2026-08-31 contaCorrente.cy.js: filtros de data pararam de reduzir o total — range de ano fixo trocado por "ano corrente até hoje"
2026-08-31 Triagem de lote: smoke DDA/Conta Condominial + 7ª/8ª ocorrência dos trackers de segurança, tudo recorrência já mapeada
2026-08-31 Triagem de lote: relatórios (regra dos 15min) + mais 1 ocorrência do cross-tenant (6ª), tudo recorrência já mapeada
2026-08-31 subconta.cy.js: 2 falhas em cadeia, recorrência já mapeada (VS não aprovando conta 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
2026-08-31 Triagem de lote: resto da fila (smoke DDA/Conta Condominial) é recorrência já mapeada
2026-08-31 4ª confirmação do cross-tenant em Cancelar Boleto — PEDIDO_CANCELAMENTO de novo (reforça que CANCELAMENTO_SOLICITADO foi o outlier)
2026-08-31 Falso alarme: timeout de login no before() de boletoRegressao.cy.js — e um buraco na captura automática
2026-08-28 Achado grande: API expõe Swagger/OpenAPI real e completo — resolveu investigação de endpoint novo em 1 chamada
2026-08-28 3ª confirmação do cross-tenant em Cancelar Boleto — e um status final diferente, ainda não explicado
2026-08-28 Triagem de lote: resto da fila é recorrência já mapeada (execução completa pós-manutenção)
2026-08-28 Lote de 15 falhas: ambiente inteiro em manutenção (503), não é bug — confirmado pelo usuário
2026-08-28 Corrigido: "Zoho Boletos Pagos VS" travava por combo virtualizado não renderizando o item no DOM
2026-08-28 CONFIRMADO: Cancelar Boleto aceita cancelamento cross-tenant (BOLA/IDOR, 2ª execução real)
2026-08-26/28 Triagem de lote: resto da fila é recorrência já mapeada, sem causa nova
2026-08-26 Tipo de relatório novo: "Indicação de Churn" — mapa desatualizado, não bug
2026-08-26 Investigação: suspeita de "Cria Administradora sem autenticação" — descartada (falso alarme)
2026-08-26 Incidente de processo: checagem de sintaxe pós-@cypress/grep rodou before() de 3 specs com_dados sem querer
2026-08-26 Triagem de lote (rodada 5, 10h16-10h17): mesmo grupo de 500 já mapeado
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
2026-08-26 Adicionado relatório HTML por execução (Mochawesome)
2026-08-26 Triagem de lote (rodada 3, 09h44-09h52): tudo recorrência conhecida
2026-08-26 relatorios.cy.js: causa real de "Transferências Pagas" falhando — não era timing, era o filtro :visible do jQuery
2026-08-26 Triagem de lote (rodada 2, 08h48-09h09): tudo recorrência conhecida
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
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)
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
2026-08-25 subconta.cy.js: describe "conta inativa" removido — o teste podia passar sem checar nada
2026-08-25 subconta.cy.js: habilitarSubcontaComRetry (6 tentativas, 5s cada) virou 1 tentativa só, a pedido do usuário
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
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
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
2026-08-25 subconta.cy.js (spec novo): botão "Habilitar Subconta" dava timeout "not visible" — fora da área visível sem rolar
2026-08-25 subconta.cy.js (spec novo): 404 na 1ª execução real — goToListagem() visitava /app/conta-digital sem o sufixo /listar
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
2026-08-25 boletoSimulaErroEmissao.cy.js: "cliente sem CPF/CNPJ" devolveu 400 de novo (2ª ocorrência) — ainda sem confirmar se é correção real
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
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
2026-08-25 CLAUDE.md não listava boletoRegressao.cy.js entre os specs que criam dado real
2026-08-24 cy.login() travava depois que o usuário de testes teve o 2FA removido
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
2026-08-24 Reorganização: cypress/e2e/dados-reais/ isola os specs que criam dado real em homologação
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
2026-08-24 BoletoPage.shouldShowDetalhes() passou a tolerar REGISTRO_CRIADO quando esperava GERADO
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
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
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
2026-08-24 Isolado: NÃO é outage geral do VS — só a aprovação de conta NOVA está travada, contas antigas funcionam normal
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
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
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
2026-08-21 Novo cy.criarContaCorrenteViaApi(), achado explorando a collection Postman a pedido do usuário
2026-08-21 regressao/relatorioRegressao.cy.js criado (completando a regressão com os candidatos já mapeados)
2026-08-21 Unificação do expandMenu(): 6 cópias viraram 1, e 4 delas nem eram usadas
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)
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"
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
2026-08-21 boletoSimulaErroEmissao.cy.js: "código externo repetido" pegou a mesma instabilidade de "conta digital não está ativa"
2026-08-21 boletoViaApi.cy.js: clique num botão desabilitado ao abrir Detalhes — instabilidade, não investigado a fundo
2026-08-21 contaGeradora.cy.js: validação pela listagem removida — tela não tem busca nem detalhe
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
2026-08-20 4 telas do menu retornam erro real de API (500) — achado navegando pra montar o smoke
2026-08-20 Achado à parte: a SPA falha transitoriamente ao carregar um chunk dinâmico, mas se autorrecupera com reload
2026-08-20 Esperar a animação do submenu "terminar" nunca funcionava em headless — trocado por .invoke('click')
2026-08-20 smoke.cy.js estava pulando "DDA > Aplicações" achando que "mesma URL" bastava
2026-08-20 Validado que o MutationObserver já pegava os erros de verdade + trocado por checagem de rede (mais direta)
2026-08-20 shouldTelaCarregada() aprovava tela com erro de API às vezes — causa real: corrida contra o toast se auto-fechando
2026-08-20 MenuPage.js: 3 correções na mesma rodada (design do smoke + 2 bugs reais)
2026-08-20 MenuPage.expandirMenu(): leitura única do DOM não esperava o menu montar
2026-08-20 smoke/smoke.cy.js: falha ao rodar headless não é bug do spec, é totpSecret ausente
2026-08-20 contaCorrente.cy.js: 3ª rodada — causa real da falha de datas/total (não era blur)
2026-08-20 contaCorrente.cy.js: 2ª rodada, mais 3 falhas (1 nova, 2 remanescentes)
2026-08-20 contaCorrente.cy.js: 11 dos 14 testes de filtro falharam na 1ª execução real
2026-08-20 2 testes de mensagem de validação quebraram: texto não é fixo entre execuções
2026-08-20 Investigação de erros em "Gerar Boleto": 1ª tentativa usou mock errado, corrigida
2026-08-20 relatorios.cy.js: "Transferências Pagas" nunca disparava a requisição
2026-08-20 boletoViaApi.cy.js: cancelamento não chega em CANCELADO (mesma rodada da entrada abaixo)
2026-08-20 boletoViaApi.cy.js: modal de Detalhes "not visible" (flake, não corrigido)
2026-08-20 boletoViaApi.cy.js: 2 falhas nos testes novos de vencimento retroativo e cancelamento
2026-08-20 relatorios.cy.js falhou nos 10 tipos ao rodar de novo dentro de 15 min
2026-08-20 docs/falhas-pendentes.md apontava pra screenshot que não existia
2026-08-20 Retry de ativação de conta quase esgotou as tentativas
2026-08-19 Guid da resposta de "Gerar Boleto" é provisório
2026-08-19 Assertion de valor falhando com strings visualmente idênticas
2026-08-19 Botão "Detalhes" nunca encontrado
2026-08-19 Scroll horizontal da tabela de Boletos não ficava no início
2026-08-19 cy.gerarBoletoViaApi criando dados duplicados / e-mails em excesso
2026-08-19 PUT .../configuracoes/boleto retornando 403 Acesso negado
2026-08-19 POST /contaDigital/remessa retornando 400 "Conta digital não está ativa"
2026-08-19 Menu de Contas Geradoras parou de abrir
2026-08-19 Zoho Boletos Pagos Core/VS não apareciam no combo de Tipo de Relatório
2026-08-19 Scroll da página "pulando" ao selecionar Tipo de Relatório / abrir calendário

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):

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 processossmoke/, sanity/, seguranca/, ux/, performance/, sandbox/ não foram tocados.

O que mudou:

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):

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:

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):

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):

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:

Ú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):

Correção (cypress/support/commands.js, cy.expandirMenu()) — dupla, pra não depender de acertar a causa exata:

  1. Espera 300ms depois do menu aparecer no DOM antes de clicar (dá tempo do Emotion terminar de injetar a regra de transição).
  2. 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 via localStorage) 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:

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 —

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:

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:

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:

Correção aplicada:

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:

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:

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:

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:

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:

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):

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):

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:

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:

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:

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:

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:

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:

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:

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:

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:

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):

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 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:

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):

  1. 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.
  2. Instrumentei Cypress.on('uncaught:exception', ...), window.onerror e window.onunhandledrejection pra capturar o que o handler global em cypress/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.
  3. 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 em cypress.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 é:

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:

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:

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:


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:

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.

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:

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:

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 vaziotext-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.75px207.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:

  1. Roda npm run readme:build e re-adiciona README.md ao staged — elimina de vez o risco de esquecer de regenerar a árvore de estrutura (regra que já existia no CLAUDE.md, dependia de alguém lembrar manualmente).
  2. Roda npm run check:secrets (scripts/check-secrets.js, novo) — varre os arquivos staged (conteúdo real que vai pro commit, via git show :arquivo, não o disco) atrás de padrão de segredo (token JWT, Personal Access Token do GitLab, chave AWS, totpSecret preenchido) e bloqueia nome de arquivo proibido (cypress.env.json, postman/*.postman_environment.json) mesmo que o .gitignore falhe 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.

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.

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:

  1. 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).
  2. 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.

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):

  1. 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 dedicado it('CNPJ', ...) (busca direto pelo CNPJ, resultado único).
  2. 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 de primeiroDiaDoAnoAtual() pra dataFutura(-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.

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.

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.jsConta 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.

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.

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.

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.

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:

  1. Sessão de login não validou (mesma instabilidade já documentada, sem relação com o teste)
  2. Mesma coisa de novo
  3. Chegou a rodar, mas o boleto não tinha chegado em GERADO a 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.

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"):

  1. "Cria Administradora" (pasta Credenciamento, com Api-Key/Application) → cria a Administradora A ("vítima"). Anota guid_administradora_A.
  2. POST /auth com o usuário/senha de A → token_A.
  3. "Cria Condomínio", AuthCG: token_A → cria o Condomínio de A. Anota guid_condominio_A.
  4. 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.
  5. "Gerar Boleto", AuthCG: token_A, codigo: guid_condominio_A → espera o status virar GERADO (GET .../boletos, é assíncrono).
  6. "Cria Administradora" de novo, com CNPJ/usuário diferentes → Administradora B ("atacante"). Não precisa de Condomínio pra ela.
  7. POST /auth com usuário/senha de B → token_B.
  8. 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 header AuthCG leva o token_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).

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:

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.

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.

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):

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:

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:

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:

  1. Grupo dda-api/webhook-api/adm/conta-digital-api retornando 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.
  2. "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) e boletoSimulaErroEmissao.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.
  3. /signin timeout no smoke (1 ocorrência, 24/08 15:44) — mesma limitação de totpSecret ausente 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:

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:

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:

  1. Os boletos que eu tinha gerado contra o Condomínio de fallback (0e90580b-...) estavam terminando em ERRO_VALIDACAO — não confirmava, sozinho, se o fallback realmente funcionava fim a fim. Investigando o campo validacoes (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 (status GERADO, Nosso Número real 0000001325612 — é o próprio guid_boleto curado em postman/core-homol2.postman_environment.json).
  2. 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 um fornecedor diferente. 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 compare boleto.cnpjCondominio contra a tela (como boletoViaApi.cy.js já 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:

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:

  1. 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 o expect original passava mesmo sem confirmar nada de verdade.
  2. 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:

  1. cy.criarContaCorrenteViaApi() criado em cypress/support/commands.js — duplica criarAdministradora()/autenticarAplicacao() de cy.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).
  2. contaCorrenteRegressao.cy.js reescrito pra criar sua própria Conta Corrente num before(), em vez de usar DADOS_REAIS hardcoded.

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:

  1. Criado cy.expandirMenu() em cypress/support/commands.js — fonte única da lógica corrigida (retry de verdade), acessível de qualquer Page Object ou spec.
  2. MenuPage.js: expandirMenu() agora só delega pro comando (removida a lógica duplicada e o elemento menuRoot, que ficou órfão).
  3. ContaGeradoraPage.js (o único uso real): goToCadastro() passou a chamar cy.expandirMenu() direto — ganhou a versão sem bug.
  4. Removido de ContaCorrentePage.js, AplicacaoPage.js, BoletoPage.js, RelatorioPage.js: método expandMenu(), elemento menuToggle, 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:

  1. "DDA > Aplicações continua levando pra MESMA URL que Aplicações solta no topo" — recebeu /app/dda/listar em vez de /app/aplicacao.
  2. "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):

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:

  1. 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).
  2. cypress/e2e/smoke/smoke.cy.js — ganhou 2 it()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.
  3. cypress/e2e/regressao/menuRegressao.cy.jsremovido, 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 em cypress/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):

  1. core-api/dda-api/* (host api-manager-homol2-contadigital...) — afeta as 4 telas de DDA (Aplicações, Empresas, Boletos, Consumo). TODA UMA delas chama dda-api/application ou dda-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.
  2. core-api/adm/conta-digital-api/listar/contas-condominiais (mesmo host acima, mas caminho adm/conta-digital-api — módulo diferente do DDA) — afeta só Conta Condominial > Geral. Sem relação com o grupo 1.
  3. webhook-api/v1/aplicacao, em outro host inteiro (orquestrador-homol.partnerbank.com.br, nem é o api-manager) — afeta só Conta Condominial

    Webhook. 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.jsabrirGrupo(), 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:

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:

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:

  1. cy.click() failed because... has CSS pointer-events: none — Status, Status Aprovação, Aplicação, Principal, Conta Geradora (todos os combos).
  2. cy.eq() failed... No elements (0 resultados) — Conta Corrente.
  3. cy.find() failed because the page updated... subject no longer attached to the DOM — Código Banco, Agência.
  4. 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):

  1. 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.
  2. 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.
  3. 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.
  4. Datas: .clear().type() não estava confiável rodando via Cypress (digitando manualmente, devagar, funcionava; via cy.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 + evento input, 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:


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:

  1. 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.
  2. 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 codigoExterno da REMESSA inteira, não só do boleto — são duas validações diferentes no backend. O teste real (boletoSimulaErroEmissao.cy.js) só duplica o codigoExterno do 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:


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):

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:

  1. 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.
  2. overrides.cancelarApos (em cy.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 estar RECEIVED/REGISTRO_CRIADO, não GERADO), e cancelar nesse estado é rejeitado. Descoberto também, nessa investigação: existe um status intermediário (REGISTRO_CRIADO) entre RECEIVED e GERADO/ERRO_VALIDACAO que não estava documentado.

Correçã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.jsscreenshotOnRunFailure: 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:coreauth.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).