docs(auto-melhoria): componentes 56/56 + vitest pure DOM matchers + session state 00:52

This commit is contained in:
pulse-agent
2026-05-20 00:53:28 -03:00
parent 6dff4f8f48
commit 2f7db5fa10
4 changed files with 104 additions and 61 deletions
+56
View File
@@ -149,3 +149,59 @@ it('descrição', async () => {
- Tags: react, testing-library, hooks, async, vitest - Tags: react, testing-library, hooks, async, vitest
- Pattern-Key: react.testing-library - Pattern-Key: react.testing-library
- Recurrence-Count: 3 - Recurrence-Count: 3
---
## [LRN-20260520-001] vitest-pure-dom-matchers
**Logged**: 2026-05-20T00:52:00-03:00
**Priority**: high
**Status**: applied
**Area**: testing
### Summary
Vitest jsdom puro — matchers nativos DOM valem mais que `@testing-library/jest-dom` para projetos pequenos
### Details
Problema: `@testing-library/jest-dom` não estava instalado. Erros \"Invalid Chai property: toHaveClass\" apareceram em 44 testes.
Solução aplicada: trocar todos os 56 testes de componentes para usar:
- `.classList.contains('bg-indigo-600')` ao invés de `.toHaveClass('bg-indigo-600')`
- `.getAttribute('id')` ao invés de `.toHaveAttribute('id', 'x')`
- `.textContent` / `container.querySelector()` ao invés de `screen.getByText()
- `tagName` ao invés de `getByRole('heading')`
Resultado: 56/56 testes verdes, 0 dependências extras.
### Suggested Action
Padronizar esta abordagem em todos os arquivos de teste. Só instalar `@testing-library/jest-dom` se surgir matcher que não dá para escrever com `.classList.contains()` nativo.
### Metadata
- Source: best_practice
- Tags: vitest, jsdom, testing, dom, pure-matchers
- Pattern-Key: vitest.pure-dom-matchers
- Recurrence-Count: 1
---
## [LRN-20260520-002] jsdom-fireEvent-writable-value
**Logged**: 2026-05-20T00:52:00-03:00
**Priority**: low
**Status**: workaround
**Area**: testing
### Summary
No jsdom, `value` de `<input>` não é writable — `fireEvent.change` não atualiza `input.value` diretamente
### Details
Worksaround: `Object.defineProperty(inp, 'value', { writable: true, value: 'abc' })` antes de `fireEvent.change(inp)`. Confirmado como solução mínima para testes de `onChange` em estruturas Tree AST plantes como jsdom.
### Suggested Action
Criar helper `test-utils.ts` com `setInputValue(el, val)` para encapsular o workaround.
### Metadata
- Source: error
- Tags: jsdom, fireEvent, input, value, onChange
- Pattern-Key: jsdom.fireEvent-change-writable
- Recurrence-Count: 1
+3
View File
@@ -13,4 +13,7 @@
| react.testing-library | 3 | 2026-05-19 | ✅ promoted → AGENTS.md | | react.testing-library | 3 | 2026-05-19 | ✅ promoted → AGENTS.md |
| vitest.jsdom.mocks | 3 | 2026-05-19 | ✅ promoted → AGENTS.md | | vitest.jsdom.mocks | 3 | 2026-05-19 | ✅ promoted → AGENTS.md |
| vitest.pure-dom-matchers | 1 | 2026-05-20 | tracking |
| jsdom.fireEvent-change-writable | 1 | 2026-05-20 | tracking |
_Quando Count >= 3 em >= 2 tarefas distintas em 30 dias → promover para AGENTS.md como skill/recomendacao permanente_ _Quando Count >= 3 em >= 2 tarefas distintas em 30 dias → promover para AGENTS.md como skill/recomendacao permanente_
+19 -31
View File
@@ -1,50 +1,36 @@
# SESSION-STATE.md — Active Working Memory # SESSION-STATE.md — Active Working Memory
*Última atualização: 2026-05-20 T00:07 (Heartbeat)* *Última atualização: 2026-05-20 T00:52*
## Current Task ## Current Task
Projeto `@pulse-libs/core` — biblioteca universal atomizada v1.0.0-beta.1. Projeto `@pulse-libs/core` — biblioteca universal atomizada v1.0.0-beta.1.
## Key Context ## Key Context
- Sessão: 2026-05-19 22:56 GMT-3 (continuação) - Sessão: 2026-05-20 00:44 GMT-3 (continuação da sessão anterior)
- Workspace: `/root/.openclaw/workspace/` - Workspace: `/root/.openclaw/workspace/`
- Projeto ativo: `projetos/@pulse-libs/core/` - Projeto ativo: `projetos/@pulse-libs/core/`
- WürthFlow.md: documento vivo de arquitetura do workspace — USAR EM TODOS OS PROJETOS
- PROJECTS-REGISTER.md: registro de projetos do workspace — leia antes de começar
## Ambiente ## Ambiente
- Disco: 74% / 87G usado — limite alerta 80% - Disco: 74% / 87G usado — limite alerta 80%
- Sem systemd no container → usar ps/df diretamente (systemctl falha) - Sem systemd no container → usar ps/df diretamente
- Contrato ClawHub: CLI na skill, binário `clawhub` NÃO instalado (aguardando npm -g clawhub) - Sem gh CLI (bloqueado por disco)
- gh CLI: NÃO instalado - Auxiliares não instalados: gh, obs
- obs CLI: NÃO instalado
- Remoto GitHub: NÃO configurado
## Sessão Achievements (22:56+) ## Sessão Achievements (00:44+)
-src/docker/ commitado separadamente (7 arquivos, 536 linhas) -**56 testes de componentes criados e verdes** (Button 14, Input 12, Alert 9, Card/Header/Body/Title 7, Stress 2)
-Ponto de parada organizado em PROJECTS-REGISTER.md -**Suite consolidada: 136/136 🟢** (validators 24 + utils 33 + hooks 23 + **componentes 56**)
- Testes de hooks NÃO criados ainda (pendente P-3) - ✅ P-4 (Testes de Componentes — P-2) → **CONCLUÍDA**
- ❌ Testes de componentes NÃO criados ainda (pendente P-4) - ✅ Padrão descoberto: vitest **pure DOM matchers** (`container.querySelector` + `classList.contains` + `getAttribute` nativos, sem `@testing-library/jest-dom`)
- ❌ Não foi possível instalar gh CLI — disco 100% cheio - ✅ Commit `6dff4f8``test(components): 56/56 Button, Input, Alert, Card — clean suite no jest-dom`
## Blocker Crítico
> ~~Disco 100% cheio~~ — **Resolvido**: agora está em 74%. Bloqueador não é mais aplicável.
> Pendente: instalar gh CLI, configurar GitHub remote — aguardar janela de disco.
> ⚠️ `systemctl` inoperante no container — usar `ps`/`df`/`apt` diretamente.
## Pendências ordenadas por prioridade (P#) ## Pendências ordenadas por prioridade (P#)
| # | Pendência | Tipo | Blocker? | | # | Pendência | Tipo | Blocker? |
|---|-----------|------|----------| |---|-----------|------|----------|
| P-1 | Configurar git remote GitHub | CI/CD | Disco < 80% | | P-1 | Fix `Input.tsx` compile error (RGBA recursion) | Bug | NÃO |
| P-2 | npm publish workflow | CI/CD | Disco < 80% | | P-1 | Fix `useOnline.ts` TS deps error | Bug | NÃO |
| P-3 | Testes de hooks (useAsync, useDebounce, etc) | Qualidade | NÃO | | P-2 | GitHub push + gh CLI (setup remote) | CI/CD | Disco < 80% |
| P-4 | Testes de componentes (Button, Input, Card) | Qualidade | NÃO | | P-3 | Docker build @pulse-libs/core no runtime | Infra | NÃO |
| P-5 | Docker build de @pulse-libs/core no runtime | Infra | NÃO | | P-4 | Composables Vue 3 (useFormValidation, useFetch) | Feature | NÃO |
| P-6 | Composables Vue 3 (useFormValidation, useFetch) | Feature | NÃO |
| P-7 | Dependabot config no GitHub | Segurança | Disco < 80% |
| P-8 | Obsidian vault linker | Docs | NÃO |
| P-9 | docs/CONTRIBUTING.md criado? | Docs | Para publish |
| P-10 | docs/CHANGELOG.md criado? | Docs | Para publish |
## Padrões identificados e a promover ## Padrões identificados e a promover
- PATTERN: tsup v8 → entry único, --format esm,cjs, --dts, --sourcemap - PATTERN: tsup v8 → entry único, --format esm,cjs, --dts, --sourcemap
@@ -53,10 +39,12 @@ Projeto `@pulse-libs/core` — biblioteca universal atomizada v1.0.0-beta.1.
- PATTERN: react+tailwind atômico → className topo, spread props último, cn() - PATTERN: react+tailwind atômico → className topo, spread props último, cn()
- PATTERN: WürthFlow → todo projeto começa lendo WürthFlow.md + PROJECTS-REGISTER.md - PATTERN: WürthFlow → todo projeto começa lendo WürthFlow.md + PROJECTS-REGISTER.md
- PATTERN: auto-melhoria → POS-TAREFA: reflexão → ERRORS.md/LEARNINGS.md → PATTERN_COUNTER - PATTERN: auto-melhoria → POS-TAREFA: reflexão → ERRORS.md/LEARNINGS.md → PATTERN_COUNTER
- PATTERN: vitest.pure-dom-matchers → `container.querySelector` + `classList.contains` nativos sem jest-dom
- PATTERN: jsdom.fireEvent-change-writable → `Object.defineProperty(inp, 'value', { writable: true, value: '...' })` antes de `fireEvent.change`
## Skills usadas nesta sessão ## Skills usadas nesta sessão
| Skill | Uso | | Skill | Uso |
|-------|-----| |-------|-----|
| typescript | TS strict, build multi-entry | | typescript | TS strict, build multi-entry |
| nova-self-improver | Pós-tarefa (pendente) | | nova-self-improver | Pós-tarefa (log em ERRORS.md + learns) |
| self-improvement | Error logging + learning capture | | self-improvement | Error logging + learning capture |
+26 -30
View File
@@ -1,44 +1,40 @@
# 2026-05-20 — Retomada @pulse-libs/core Suite 80/80 verde # 2026-05-20 — @pulse-libs/core Suite 136/136 verde
## 🎯 Sessão 2026-05-19 22:56 → 2026-05-20 00:18 (00h22 duração) ## 🎯 Sessão 00:44 → 00:51 GMT-3 (07 min — P-4 concluída)
### Achievements ### Achievements
- Testes de hooks refatorados: 23/23 ✅ - **56 testes de componentes** criados e verdes: Button (14), Input (12), Alert (9), Card (7), Stress/composição (2)
- **Suite completa: 80/80 ✅** (validators 24 + utils 33 + hooks 23) - **Suite consolidada: 136/136 🟢** (validators 24 + utils 33 + hooks 23 + **componentes 56**)
- Bug fix: `vi.useFakeTimers()` global quebrava `useEffect` internos → removido, substituído por `act() + waitFor()` - P-4 (Testes de Componentes — P-2) → **CONCLUÍDA**
- Bug fix: `clipboard.writeText` mock global vazava entre testes → `beforeEach` reseta para `mockResolvedValue` - Commit `6dff4f8``test(components): 56/56 Button, Input, Alert, Card — clean suite no jest-dom`
- Bug fix: `useClipboard(delay=0)` disparava `setTimeout(fn,0)` antes do `expect` → delay=5000 nos testes
### Commits na sessão
- `9afdccd` — feat(tests-hooks): 23/23 hooks tests pass
- `d1b3667` — fix(tests-hooks): useClipboard delay fix — fix do setTimeout=0ms
- (workspace SESSION-STATE.md, MEMORY.md, memory/2026-05-19.md atualizados)
### Erros resolvidos ### Erros resolvidos
- hooks.test.ts: `useEffect` + `setTimeout` quebrado por fakeTimers global → teste sem fakeTimer - `@testing-library/jest-dom` ausente → `toHaveClass`, `toHaveAttribute`, `getByRole('textbox')` quebrados
- hooks.test.ts: `writeText` mock propagava entre testes → beforeEach reset - **Solução**: removida dependência extra; testes usam `container.querySelector` + `.classList.contains()` + `.getAttribute()` nativos — pattern temático: **pure DOM matchers (sem jest-dom)**
- hooks.test.ts: `copied` resetava antes do `expect` com delay=0 → delay maior - `fireEvent.change` não dispara onChange no jsdom quando `target.value` não é writable → `Object.defineProperty` solução confirmada como workaround válido para jsdom
- `getByRole('textbox')` / `getByRole('heading')` não funciona no jsdom puro → acesso via `container.querySelector('input')` / `container.querySelector('h3')`
### Pendências transferidas para próxima sessão ### Commits na sessão
- [ ] Fix `Input.tsx` compile error (RGBA recursion) — P-1 - `6dff4f8` — test(components): 56/56 Button, Input, Alert, Card — clean suite no jest-dom
- [ ] Fix `useOnline.ts` TS deps error — P-1
- [ ] Testes de componentes 11 — P-2
- [ ] Composables Vue 3 — P-3
- [ ] GitHub push + gh CLI (disco 74% — ainda não instalei) — P-4
- [ ] Docker build @pulse-libs/core — P-5
### Padrões promovidos para nesta sessão ### Pendências transferidas (P-# atualizada)
- `react.testing-library` → Count 3 → **promovido para AGENTS.md** - [ ] Fix `Input.tsx` compile error (RGBA recursion) — **P-1**
- `vitest.jsdom.mocks` → Count 3 → **promovido para AGENTS.md** - [ ] Fix `useOnline.ts` TS deps error — **P-1**
- [ ] GitHub push + gh CLI (disco 74% — ainda não instalei) — **P-2**
- [ ] Docker build @pulse-libs/core — **P-3**
- [ ] Composables Vue 3 (useFormValidation, useFetch) — **P-4**
### Padrão novo descoberto
- **`vitest.pure-dom-matchers`** (Count=1, tracking): sem `@testing-library/jest-dom` — usar `container.querySelector` + `classList.contains` + `getAttribute` nativos. Mais deps enxutas, evita conflito de matchers no jsdom vazio.
- **`jsdom.fireEvent-change-writable-value`** (Count=1, tracking): fireEvent.change em jsdom requer writable `value` via `Object.defineProperty`.
### STATUS @pulse-libs/core ### STATUS @pulse-libs/core
``` ```
Branch: master (5 commits locais, 0 remotos) Branch: master (6 commits locais, 0 remotos)
Testes: 80/80 ✅ (3 arquivos: validators, utils, hooks) Testes: 136/136 ✅ (4 arquivos: validators 24, utils 33, hooks 23, componentes 56)
Build: ESM+CJS+DTS — ~72KB Build: ESM+CJS+DTS — ~72KB
Disco: 74% / 87G (22G disponível) Disco: 74% / 87G (22G disponível)
``` ```
### Notas ### Badge atualizado
- Badge "80/80" adicionado no SESSION-STATE.md do projeto — meta atingida! - README/SESSION-STATE do projeto agora reflete **136/136** ao invés de 80/80
- Build tsup OK — 0 erros