Skip to content

feat(e2e): spec REAL de aprovação de desconto (B-4) + 8 data-testids + fix build main#12

Merged
adm01-debug merged 1 commit into
mainfrom
feat/e2e-discount-approval-real
May 19, 2026
Merged

feat(e2e): spec REAL de aprovação de desconto (B-4) + 8 data-testids + fix build main#12
adm01-debug merged 1 commit into
mainfrom
feat/e2e-discount-approval-real

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

@adm01-debug adm01-debug commented May 19, 2026

Contexto

Próximo round aprovado pelo PO depois do PR #11: E2E ponta-a-ponta real de aprovação de desconto, atendendo ao cenário do bloqueador B-4 da auditoria pré-prod (trigger SQL validate_quote_real_discount com bypass NULL).

O que muda

Spec novo (192 linhas)

e2e/flows/04c-quote-discount-approval.spec.ts — 3 testes que cobrem o fluxo do vendedor ao solicitar aprovação:

Test 1 — UI alterna botão quando excede limite

adiciona produto → aplica desconto 75% via discountInput
↓
botão "Criar/Salvar" some
botão "Solicitar Aprovação" (cor âmbar) aparece

Test 2 — Dialog mostra valores corretos

clica em "Solicitar Aprovação" → dialog renderiza
↓
cards "Seu Limite" e "Solicitado" visíveis
"Solicitado" contém "75"

Test 3 — Submit persiste e redireciona

preenche justificativa → "Enviar para Aprovação"
↓
redirect /orcamentos/{uuid}
reload → confere persistência

Skip controlado: se vendedor não tem limite em seller_discount_limits (ou limite ≥75%), os testes pulam com mensagem explícita explicando a configuração necessária.

Infra — 8 data-testids essenciais

Adicionados em QuoteBuilderSummaryColumn.tsx:

testid onde
quote-discount-input CurrencyInput de valor
quote-discount-type-select toggle % vs R$
quote-request-approval-button botão âmbar "Solicitar Aprovação"
quote-approval-dialog DialogContent do approval
quote-approval-limit card "Seu Limite" no dialog
quote-approval-requested card "Solicitado" no dialog
quote-approval-justification textarea de motivo
quote-approval-submit botão "Enviar para Aprovação"

SSOT — Sel.quote expandido

e2e/fixtures/selectors.ts ganhou 8 novos campos: discountInput, discountTypeSelect, requestApprovalButton, approvalDialog, approvalLimit, approvalRequested, approvalJustification, approvalSubmit.

Fix colateral — src/hooks/ui/useMediaQuery.ts (NOVO)

Achado durante validação: build do main estava quebrado.

[vite:load-fallback] Could not load /workspace/repos/we-dream-big/src/hooks/ui/useMediaQuery 
(imported by src/components/layout/SidebarReorganized.tsx): ENOENT

SidebarReorganized.tsx:49 faz import { useMediaQuery } from "@/hooks/ui/useMediaQuery"; mas o arquivo simplesmente não existia. Criada implementação SSR-safe (45 linhas) com:

  • Fallback para false em SSR / sem window.matchMedia
  • Sync no mount via useEffect
  • Listener com addEventListener("change") + fallback addListener para Safari < 14

Sem isso, vite build falha antes de testar qualquer coisa. Este PR desbloqueia o build E entrega o E2E novo.

Diferenças vs e2e/discount-approval.spec.ts existente

O spec antigo (37 linhas, 4 testes) só verifica que rotas /admin/aprovacoes-desconto redirecionam para login — smoke puro. Nenhum exercita o fluxo do vendedor ao solicitar aprovação. Este PR cobre o caminho do dinheiro real.

Validação

  • vite build: 1m37s, zero erros (depois do fix useMediaQuery)
  • npx playwright test --list -g "discount approval":
    [chromium-authed] › flows/04c-quote-discount-approval.spec.ts:104 › UI alterna botão
    [chromium-authed] › flows/04c-quote-discount-approval.spec.ts:128 › dialog mostra valores
    [chromium-authed] › flows/04c-quote-discount-approval.spec.ts:157 › submeter justifica e redireciona
    

Observações honestas

  1. Não rodei contra browser real desta sessão (sem E2E_USER_* configurado). Validei sintaxe + listagem Playwright + build. Para correr de verdade:
    • Configurar E2E_USER_EMAIL/E2E_USER_PASSWORD no CI
    • Garantir que o vendedor de teste tem seller_discount_limits.max_discount_percent cadastrado e menor que 75
  2. Skip controlado quando o vendedor não tem limite: o spec NÃO falha — pula com mensagem explicando a config necessária. Isso é proposital pra não bloquear CI por estado de DB.
  3. Test 3 testa só a UI, não o trigger SQL validate_quote_real_discount em si (que é o bloqueador B-4 server-side). Validar o trigger fail-closed na NULL bypass é tarefa de DB migration + teste SQL, não E2E.

Próximo round natural

Se este spec entrar verde, os próximos do mesmo molde seriam:

  • E2E real de sync com Bitrix (B-2 — endpoint sem auth)
  • E2E real de export PDF
  • Teste SQL do trigger validate_quote_real_discount com fail-closed em NULL (fecha o B-4 server-side)

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Melhorada compatibilidade com renderização do lado do servidor (SSR) em componentes de consulta de mídia.
    • Adicionado fallback para navegadores antigos sem suporte a addEventListener.
  • Tests

    • Ampliada cobertura de testes E2E para fluxo de aprovação de desconto em orçamentos, incluindo validação de limites de desconto e persistência de dados.

Review Change Stack

Copilot AI review requested due to automatic review settings May 19, 2026 18:03
@vercel
Copy link
Copy Markdown

vercel Bot commented May 19, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
we-dream-big Ready Ready Preview, Comment May 19, 2026 6:04pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 2026

Walkthrough

O PR introduz fluxo E2E completo para aprovação de desconto quando vendedor excede limite cadastrado (com persistência), adicionando seletores data-testid, marcadores de teste no componente e testes validando UI, diálogo e submissão. Também reimplementa useMediaQuery com suporte SSR e fallback para Safari.

Changes

Quote Discount Approval Flow

Layer / File(s) Summary
Test selectors for discount and approval
e2e/fixtures/selectors.ts
Expande Sel.quote com discountInput, discountTypeSelect, requestApprovalButton, approvalDialog, approvalLimitValue, approvalRequestedValue, approvalJustification, approvalSubmit.
Component with approval flow testids
src/components/quotes/QuoteBuilderSummaryColumn.tsx
Adiciona data-testid em campos de desconto (input/select), botão de solicitação, diálogo, blocos limite/solicitado, textarea de justificativa e botão de envio.
E2E approval flow tests with persistence validation
e2e/flows/04c-quote-discount-approval.spec.ts
Helper setupQuoteWithHighDiscount cria orçamento e aplica desconto alto; testes validam visibilidade de "Solicitar Aprovação" quando limite é excedido, conteúdo do diálogo com cards de limite e solicitado, submissão com justificativa e persistência após redirect para /orcamentos/<uuid>.

useMediaQuery SSR Support

Layer / File(s) Summary
SSR-compatible implementation with default export
src/hooks/ui/useMediaQuery.ts
Inicialização retorna false em SSR; useEffect verifica window/matchMedia, sincroniza MediaQueryList imediatamente após criação (hydration), suporta addEventListener e fallback addListener (Safari); adiciona default export mantendo named export.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed O título descreve com precisão os três componentes principais da mudança: spec E2E real de aprovação de desconto, adição de 8 data-testids e correção de build.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/e2e-discount-approval-real

Comment @coderabbitai help to get the list of available commands and usage tips.

@adm01-debug adm01-debug changed the title feat(e2e): spec REAL de aprovação de desconto (B-4) + 8 data-testids + fix build do main feat(e2e): spec REAL de aprovação de desconto (B-4) + 8 data-testids + fix build main May 19, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/quotes/QuoteBuilderSummaryColumn.tsx`:
- Around line 504-510: The rendered data-testid attributes in the
QuoteBuilderSummaryColumn component are inconsistent with the SSOT in Sel.quote,
breaking E2E selectors; update the two divs currently using
data-testid="quote-approval-limit" and data-testid="quote-approval-requested" to
the expected IDs "quote-approval-limit-value" and
"quote-approval-requested-value" respectively so tests can find the elements
(keep the existing content/formatting logic for maxDiscountPercent and the
discountType/discountValue rendering unchanged).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e712055b-d2b1-4605-9d93-85e647a75d37

📥 Commits

Reviewing files that changed from the base of the PR and between 570a897 and 7c3c309.

📒 Files selected for processing (4)
  • e2e/fixtures/selectors.ts
  • e2e/flows/04c-quote-discount-approval.spec.ts
  • src/components/quotes/QuoteBuilderSummaryColumn.tsx
  • src/hooks/ui/useMediaQuery.ts

Comment on lines +504 to 510
<div data-testid="quote-approval-limit">
<p className="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">Seu Limite</p>
<p className="text-sm font-semibold mt-0.5">{maxDiscountPercent}%</p>
</div>
<div>
<div data-testid="quote-approval-requested">
<p className="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">Solicitado</p>
<p className="text-sm font-bold text-amber-500 mt-0.5">{discountType === "percent" ? `${discountValue}%` : formatCurrency(discountValue)}</p>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Inconsistência de data-testid quebra os seletores E2E do diálogo

Os IDs usados aqui não batem com o SSOT em Sel.quote: o spec espera quote-approval-limit-value e quote-approval-requested-value, mas o componente renderiza quote-approval-limit e quote-approval-requested.

Diff sugerido
-                <div data-testid="quote-approval-limit">
+                <div data-testid="quote-approval-limit-value">
                   <p className="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">Seu Limite</p>
                   <p className="text-sm font-semibold mt-0.5">{maxDiscountPercent}%</p>
                 </div>
-                <div data-testid="quote-approval-requested">
+                <div data-testid="quote-approval-requested-value">
                   <p className="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">Solicitado</p>
                   <p className="text-sm font-bold text-amber-500 mt-0.5">{discountType === "percent" ? `${discountValue}%` : formatCurrency(discountValue)}</p>
                 </div>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/quotes/QuoteBuilderSummaryColumn.tsx` around lines 504 - 510,
The rendered data-testid attributes in the QuoteBuilderSummaryColumn component
are inconsistent with the SSOT in Sel.quote, breaking E2E selectors; update the
two divs currently using data-testid="quote-approval-limit" and
data-testid="quote-approval-requested" to the expected IDs
"quote-approval-limit-value" and "quote-approval-requested-value" respectively
so tests can find the elements (keep the existing content/formatting logic for
maxDiscountPercent and the discountType/discountValue rendering unchanged).

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7c3c309f54

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +504 to +508
<div data-testid="quote-approval-limit">
<p className="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">Seu Limite</p>
<p className="text-sm font-semibold mt-0.5">{maxDiscountPercent}%</p>
</div>
<div>
<div data-testid="quote-approval-requested">
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Align approval-card test IDs with shared selectors

Update these data-testid values to match Sel.quote.approvalLimitValue and Sel.quote.approvalRequestedValue (quote-approval-limit-value / quote-approval-requested-value) defined in e2e/fixtures/selectors.ts; as written, the new spec looks up IDs with the -value suffix and will fail to find the cards in the approval dialog, causing the "dialog de aprovação mostra limite vs solicitado" flow to fail despite correct UI behavior.

Useful? React with 👍 / 👎.

@adm01-debug adm01-debug merged commit ed0a4bd into main May 19, 2026
23 of 33 checks passed
@adm01-debug adm01-debug deleted the feat/e2e-discount-approval-real branch May 19, 2026 18:06
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a real Playwright E2E flow for quote discount approval, expands quote test selectors, and restores the missing useMediaQuery hook needed by the app layout/build.

Changes:

  • Adds a new discount-approval E2E spec covering high-discount UI behavior, approval dialog, and persistence after submit.
  • Adds new quote-related data-testid hooks and selector constants.
  • Reintroduces an SSR-safe useMediaQuery hook used by layout code.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
e2e/flows/04c-quote-discount-approval.spec.ts New real E2E spec for the discount approval flow.
e2e/fixtures/selectors.ts Adds selector constants for discount/approval UI elements.
src/components/quotes/QuoteBuilderSummaryColumn.tsx Adds data-testid attributes to discount and approval dialog controls.
src/hooks/ui/useMediaQuery.ts Restores responsive media query hook for layout usage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +504 to +508
<div data-testid="quote-approval-limit">
<p className="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">Seu Limite</p>
<p className="text-sm font-semibold mt-0.5">{maxDiscountPercent}%</p>
</div>
<div>
<div data-testid="quote-approval-requested">
Comment on lines +184 to +190

// Reload e confere que rota continua válida (quote foi persistido)
await page.reload({ waitUntil: "domcontentloaded" });
expect(page.url()).toContain("/orcamentos/");
await expect(
page.getByText(/Or[çc]amento n[ãa]o encontrado|not found/i),
).toHaveCount(0);
Comment on lines +63 to +68
// Step 1 — sem empresa
const companySearch = page.locator('[data-testid="company-search-input"]').first();
await companySearch.waitFor({ state: "visible", timeout: 10_000 });
await companySearch.click();
await page.locator(Sel.quote.noCompanyOption).first().click();

Comment on lines +74 to +78
const searchInput = page.locator(Sel.quote.productSearchInput).first();
await searchInput.waitFor({ state: "visible", timeout: 10_000 });

const productCount = await page.locator(Sel.quote.productSearchOption).count();
test.skip(productCount === 0, "Catálogo vazio — sem produto pra adicionar (não é falha do spec)");
adm01-debug added a commit that referenced this pull request May 19, 2026
…(sem suffix -value) (#13)

Fix de inconsistência introduzida no PR #12: SSOT e spec apontavam para quote-approval-limit-value/-requested-value (-value suffix), mas os data-testids no componente são quote-approval-limit/quote-approval-requested (sem suffix). 4 linhas em 2 arquivos.
adm01-debug added a commit that referenced this pull request May 24, 2026
* fix: resolve TS/ESLint errors in items #9#17 (exhaustive bug fix batch)

#9 price-response.adapter.ts — typed 4 helper fns (asRec/str/num/bool/optStr)
to eliminate 61 TS errors from snake/camelCase + null-safety issues

#10 AdminProductFormPage.tsx — fixed PromobrindProduct field access after
expanding ~50 optional fields in product-types.ts

#11 AddressTab.tsx — replaced Record<string,unknown> form props with typed
interfaces, eliminating 56 TS errors

#12 BasicDataTab.tsx — same root cause as #11, typed interfaces applied,
32 TS errors resolved

#13 CompareTableView.tsx — changed import from @/types/product.ts (DB
snake_case) to @/types/product-catalog.ts (UI camelCase), fixing 26 TS errors

#14 SupabaseConnectionsTab.tsx — replaced 17 non-null assertions (!) with
nullish coalescing (??) + type casts

#15 CatalogContent.tsx + ProductQuickView.tsx — removed unused imports/vars,
resolving 32 ESLint warnings

#16 useSimulatorWizard.ts — added dispatch to all 15 useCallback/useEffect
dep arrays; useGlobalSearch.ts — removed unused imports, stabilised callback,
fixed non-null assertions and missing deps

#17 T-FIX-5b ESLint guardrail added to eslint.config.js; guards added before
forEach+expect loops in commercial-intelligence.test.ts; baselines updated
to grandfather existing violations in magic-up tests

Baselines: .tsc-baseline.json (1065 errors frozen), .eslint-baseline.json (405)

* fix(#17): fix all T-FIX-5b forEach+expect violations in magic-up tests

- magic-up-result-panel-keyboard.test.tsx: 64 violations fixed
  - getDots()/getThumbs() forEach (getAllByRole throws on empty): eslint-disable-next-line
  - Literal arrays [prev,next], [0,1,2]: eslint-disable-next-line
  - calls/elements/observedIndices: expect(var).not.toHaveLength(0) guards added
  - REQUIRED_*_CLASSES consts: eslint-disable-next-line
  - ids/thumbNames/liveRegions: guards added

- magic-up-onda5.test.tsx: 29 violations fixed
  - required/select.allCards/allMarcar/literal arrays: eslint-disable-next-line
  - cards/listitems/winnerButtons/buttons/tabIndices: guards added
  - REQUIRED_FOCUS_CLASSES const: eslint-disable-next-line

ESLint baseline updated: 405 → 401 errors (positive drift on all T-FIX-5b work)

* fix(#17): suppress T-FIX-5b in commercial-intelligence (guards already in place)

All 14 remaining forEach+expect violations suppressed with
// eslint-disable-next-line no-restricted-syntax after the existing
expect(array).not.toHaveLength(0) guards. Arrays are provably non-empty
static constants (PERIOD_OPTIONS=9, MOCK_TRENDING=4, MOCK_OPPORTUNITIES=4)
or deterministic generators (generateDateMap(30), generateMockMarketData(360)).

Pattern applied consistently with magic-up test fixes from previous commit:
- Guard documents intent (catches accidental empty-array mutation)
- Disable comment acknowledges guard is in place and suppresses the lint rule

Result: 0 T-FIX-5b errors in all 3 test files. T-FIX-5b work fully complete.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Codex Simulation <codex-simulation@example.local>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants