mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-12 22:13:05 +00:00
Compare commits
4 commits
93bda37c29
...
377a2c89b1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
377a2c89b1 | ||
|
|
ebbc662794 | ||
|
|
2f79e14a1b | ||
|
|
a4c2ab226a |
7 changed files with 87 additions and 8 deletions
5
.github/workflows/ci-pr.yml
vendored
5
.github/workflows/ci-pr.yml
vendored
|
|
@ -62,7 +62,10 @@ env:
|
|||
jobs:
|
||||
checks:
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
runs-on: ubuntu-latest
|
||||
# Playwright 1.58.2 has no ubuntu26.04 build and `ubuntu-latest` migrated
|
||||
# to 26.04 in Oct 2026 (run 42095564329). Pin 24.04 until the Playwright
|
||||
# bump lands; `ubuntu-latest` here breaks every PR at browser install.
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 50
|
||||
services:
|
||||
postgres-int:
|
||||
|
|
|
|||
4
.github/workflows/deploy.yml
vendored
4
.github/workflows/deploy.yml
vendored
|
|
@ -101,7 +101,9 @@ jobs:
|
|||
verify:
|
||||
needs: [preflight]
|
||||
if: needs.preflight.outputs.should_deploy == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
# Same pin as ci-pr: Playwright 1.58.2 has no ubuntu26.04 build and
|
||||
# `ubuntu-latest` migrated to 26.04 in Oct 2026.
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 50
|
||||
services:
|
||||
# OPS71 — GitHub hosted: jobs run on the runner VM, so services are
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
**Board da home — destaque com legenda de Instagram volta a ser truncado (2026-11-05):** o card em destaque da seção “Acompanhe de perto” perdeu o `line-clamp-3` na reescrita da S47; com o feed do Instagram na frente, a legenda inteira (889 caracteres no caso real) era renderizada a 31px e esticava o board. O `h3` do destaque voltou a limitar 3 linhas, `text-balance` saiu dos dois títulos (a combinação com `-webkit-line-clamp` não é confiável em todos os browsers), `break-words` e `min-w-0` evitam overflow de palavras longas, e o e2e do feed do Instagram passou a pinar o clamp do destaque — não só o do compacto. Sem migration, sem mudança de conteúdo no CMS e sem alterar a ordem por recência do board; o texto completo da legenda continua no DOM e no compartilhamento. Verificação: `pnpm gate:fast` verde (461 arquivos, 5.069 testes) e e2e afetado no CI.
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
# Post-mortem: card em destaque do board renderizava a legenda inteira do Instagram
|
||||
|
||||
> Template do `/bug-fix`. Fatos apurados nesta sessão; o que não foi apurado fica marcado como tal.
|
||||
|
||||
## Registro
|
||||
|
||||
| Campo | Valor |
|
||||
| ------------------- | ----------------------------------------------------------------------------------------- |
|
||||
| Data do post-mortem | 2026-11-05 |
|
||||
| Severidade | média (regressão visual na home; sem indisponibilidade, perda de dados ou erro funcional) |
|
||||
| Ambiente | prod |
|
||||
| Issue(s) | sem Issue |
|
||||
| PR do fix | [#1450](https://github.com/fsolla/teqo/pull/1450) |
|
||||
| Detectado por | humano (relato na sessão: “fontes super grandes e o texto não quebra” no board da home) |
|
||||
|
||||
## Timeline
|
||||
|
||||
| Momento | Data/hora | Evento |
|
||||
| --------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------ |
|
||||
| Início provável | 2026-10-22 | S47 (`5635e652`) reescreve `CampaignContentCard` e remove o `line-clamp-3` do título do card em destaque. |
|
||||
| Detecção | 2026-11-05 | Relato humano; o HTML de produção mostrava uma legenda de 889 caracteres como `h3` do destaque, a 31px, sem clamp. |
|
||||
| Correção implementada | 2026-11-05 | `fix/board-featured-caption-clamp`: clamp de 3 linhas no destaque, remoção de `text-balance`, `break-words` e `min-w-0`. |
|
||||
| Correção mergeada | não apurado | Pendente do CI/PR. |
|
||||
| Deploy | não apurado | Pendente; produção exige approve humano no environment `production`. |
|
||||
| Verificado em prod | não apurado | Pendente de confirmação humana pós-deploy. |
|
||||
|
||||
## O bug
|
||||
|
||||
Na home pública, o board “Acompanhe de perto” (seção de artigos, YouTube e Instagram) renderizava o card em destaque com a legenda completa de um post do Instagram. No caso real, eram **889 caracteres** em um `h3` de **31px** (25px no mobile), sem `line-clamp`, o que esticava a coluna e transformava o destaque em uma parede de texto. Os cards compactos tinham `line-clamp-3`, mas carregavam `text-balance`, que em alguns browsers quebra o funcionamento do `-webkit-line-clamp` — o texto deixava de truncar. Como o board é ordenado por recência e o Instagram era a fonte mais recente, as quatro posições eram legendas, não títulos de matéria.
|
||||
|
||||
## Causa-raiz
|
||||
|
||||
1. **Por que o texto ficou gigante?** Porque o `h3` do destaque não tinha `line-clamp` e usava o tamanho de título editorial (31px).
|
||||
2. **Por que não tinha clamp?** A S47 (`5635e652`) separou o card em `featured` e `compact`; o `h3` antigo, que aplicava `line-clamp-3` a todas as variantes, foi substituído por um `h3` de destaque sem clamp (o design assumia um título curto de matéria, não uma legenda de feed).
|
||||
3. **Por que a legenda inteira virou título?** `toInstagramCardData` usa `post.caption` como `title`; o board ordena posts + YouTube + Instagram por data e corta em 4. Com o feed do Instagram mais recente, a legenda ocupa o destaque.
|
||||
4. **Por que os compactos também falhavam em alguns browsers?** `text-balance` foi adicionado aos dois `h3`; a combinação com `-webkit-line-clamp` não é confiável em todos os motores.
|
||||
5. **Por que passou?** O e2e pinava o clamp apenas no card compacto (a legenda longa do stub), nunca no destaque; o card em destaque do stub tem legenda curta.
|
||||
|
||||
## Correção
|
||||
|
||||
- `src/components/CampaignContentCard.tsx`: `line-clamp-3` no `h3` do destaque; `text-balance` removido dos dois `h3`; `break-words` em ambos; `min-w-0` no wrapper do card.
|
||||
- `src/components/CampaignContentSection.tsx`: `min-w-0` nas duas colunas do grid (destaque e laterais).
|
||||
- `tests/e2e/frontend.e2e.spec.ts`: o teste do feed do Instagram agora exige `-webkit-line-clamp: 3` e `overflow: hidden` também no `h3` do card em destaque.
|
||||
|
||||
A causa é o card de destaque sem limite; o clamp restaura o comportamento anterior sem esconder a legenda do DOM (o texto completo continua acessível e compartilhável).
|
||||
|
||||
## Verificação
|
||||
|
||||
- Teste de regressão: `tests/e2e/frontend.e2e.spec.ts` → “renders the Instagram feed…” — a asserção do destaque falha sem o `line-clamp` e passa com o fix (verificação local de CSS; execução no CI).
|
||||
- Suíte: `pnpm gate:fast` verde (461 arquivos, 5.069 testes).
|
||||
- CI: pendente do PR.
|
||||
- Prod: pendente de approve/deploy e confirmação humana.
|
||||
|
||||
## Prevenção
|
||||
|
||||
| Estratégia | Custo | Estado |
|
||||
| --------------------------------------------------------------------------- | ------ | ------------------------------ |
|
||||
| Pinar o clamp no card em destaque no e2e (além do compacto) | barata | implementada agora |
|
||||
| Separar “título de exibição” de “legenda” no feed (excerpt curto na origem) | cara | documentada — não implementada |
|
||||
|
||||
**Estratégia implementada:** a asserção de `-webkit-line-clamp` no destaque fecha o buraco que deixou a regressão passar.
|
||||
|
||||
**Estratégia documentada (cara):** derivar um excerpt curto da legenda do Instagram para o card (primeira frase/limite de caracteres), mantendo a legenda completa apenas no `alt`/compartilhamento. Isso reduziria o nome acessível gigante do link e o texto do compartilhamento, mas mexe no contrato de conteúdo do board e merece decisão de produto.
|
||||
|
||||
## Lições
|
||||
|
||||
- Quando o design assume “título curto” e o dado real é uma legenda de feed, a proteção não pode depender do tamanho do conteúdo: o clamp é parte do componente, não da amostra do teste.
|
||||
- `text-balance` + `line-clamp` é uma combinação frágil entre motores; usar `text-balance` só em títulos curtos e estáveis (headings de seção).
|
||||
- O e2e deve pinar a variante que tem o maior tipo e a maior probabilidade de receber conteúdo longo — o destaque.
|
||||
|
|
@ -59,7 +59,7 @@ export const CampaignContentCard = ({ card, variant = 'compact' }: CampaignConte
|
|||
) : null}
|
||||
</div>
|
||||
<p className="mt-4 text-xs font-bold text-(--pt-red) lg:mt-5">{card.meta}</p>
|
||||
<h3 className="mt-2 max-w-[690px] font-[family-name:var(--font-exo2)] text-[25px] leading-[1.12] font-extrabold tracking-[-0.02em] text-balance lg:text-[31px] lg:leading-[1.1] lg:tracking-[-0.025em]">
|
||||
<h3 className="mt-2 line-clamp-3 max-w-[690px] font-[family-name:var(--font-exo2)] text-[25px] leading-[1.12] font-extrabold tracking-[-0.02em] break-words lg:text-[31px] lg:leading-[1.1] lg:tracking-[-0.025em]">
|
||||
{card.title}
|
||||
</h3>
|
||||
{card.subtitle ? (
|
||||
|
|
@ -74,7 +74,7 @@ export const CampaignContentCard = ({ card, variant = 'compact' }: CampaignConte
|
|||
) : (
|
||||
<>
|
||||
<p className="text-xs font-bold text-(--pt-red)">{card.meta}</p>
|
||||
<h3 className="mt-3 line-clamp-3 font-[family-name:var(--font-exo2)] text-xl leading-[1.18] font-extrabold tracking-[-0.02em] text-balance lg:text-[23px] lg:leading-[1.16]">
|
||||
<h3 className="mt-3 line-clamp-3 font-[family-name:var(--font-exo2)] text-xl leading-[1.18] font-extrabold tracking-[-0.02em] break-words lg:text-[23px] lg:leading-[1.16]">
|
||||
{card.title}
|
||||
</h3>
|
||||
<p className="mt-4 text-sm font-bold text-(--pt-red)">
|
||||
|
|
@ -84,7 +84,7 @@ export const CampaignContentCard = ({ card, variant = 'compact' }: CampaignConte
|
|||
)
|
||||
|
||||
return (
|
||||
<div className="group relative h-full">
|
||||
<div className="group relative h-full min-w-0">
|
||||
{card.external ? (
|
||||
<a
|
||||
href={card.href}
|
||||
|
|
|
|||
|
|
@ -174,10 +174,10 @@ export const CampaignContentSection = async () => {
|
|||
|
||||
{featured ? (
|
||||
<div className="mt-8 grid border-y border-(--campaign-line) lg:mt-10 lg:grid-cols-12">
|
||||
<article className="border-b border-(--campaign-line) py-7 lg:col-span-7 lg:border-r lg:border-b-0 lg:pr-8">
|
||||
<article className="min-w-0 border-b border-(--campaign-line) py-7 lg:col-span-7 lg:border-r lg:border-b-0 lg:pr-8">
|
||||
<CampaignContentCard card={featured} variant="featured" />
|
||||
</article>
|
||||
<div className="divide-y divide-(--campaign-line) lg:col-span-5 lg:pl-8">
|
||||
<div className="min-w-0 divide-y divide-(--campaign-line) lg:col-span-5 lg:pl-8">
|
||||
{rest.map((card) => (
|
||||
<article key={card.id}>
|
||||
<CampaignContentCard card={card} variant="compact" />
|
||||
|
|
|
|||
|
|
@ -666,7 +666,11 @@ test.describe('Campaign home content section', () => {
|
|||
|
||||
// Long captions are clamped with an ellipsis so a single post cannot
|
||||
// stretch the bento row (production captions run into hundreds of
|
||||
// characters; the stub's reel caption is deliberately long).
|
||||
// characters; the stub's reel caption is deliberately long). The
|
||||
// featured title must clamp too — it is the lead of the board and the
|
||||
// one that renders at the largest type size.
|
||||
await expect(featured.locator('h3')).toHaveCSS('-webkit-line-clamp', '3')
|
||||
await expect(featured.locator('h3')).toHaveCSS('overflow', 'hidden')
|
||||
const longCaptionTitle = section
|
||||
.getByRole('link', { name: /E2e Reel da caravana/ })
|
||||
.locator('h3')
|
||||
|
|
|
|||
Loading…
Reference in a new issue