mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 23:25:18 +00:00
No Orion/Safari os seis tiles de modelos colapsavam (só os rótulos ficavam): a caixa do CardModelTile tirava a altura de um `aspect-ratio` inline sendo filha de um flex com `overflow: hidden` — o construto do bug WebKit #265243 (fix só no WebKit main 2026-05), invisível para o CI Chromium-only. O tile passa a tirar a altura de um espaçador em fluxo com padding-bottom percentual (data-card-tile-ratio). Guardas: unit por modelo (RED sem o fix), sweep de convenção nos cards e e2e de geometria após relayout forçado. Post-mortem + changelog na mesma entrega.
53 lines
2.1 KiB
TypeScript
53 lines
2.1 KiB
TypeScript
import { cleanup, render } from '@testing-library/react'
|
|
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
import { CardModelTile } from '@/components/cards/CardModelTile'
|
|
import { CARD_MODELS } from '@/lib/cardModels'
|
|
|
|
type MockImageProps = React.ImgHTMLAttributes<HTMLImageElement> & {
|
|
fill?: boolean
|
|
priority?: boolean
|
|
}
|
|
|
|
vi.mock('next/image', () => ({
|
|
default: ({ alt, fill: _fill, priority: _priority, ...props }: MockImageProps) => (
|
|
// eslint-disable-next-line @next/next/no-img-element
|
|
<img alt={alt} {...props} />
|
|
),
|
|
}))
|
|
|
|
// The name-tile canvas draws through the real font/canvas pipeline (jsdom has
|
|
// no canvas); the tile geometry under test does not depend on it.
|
|
vi.mock('@/components/cards/CardNameTileCanvas', () => ({
|
|
CardNameTileCanvas: () => null,
|
|
}))
|
|
|
|
afterEach(cleanup)
|
|
|
|
/**
|
|
* WebKit #265243: `aspect-ratio` on a flex item loses its height on relayout
|
|
* (fixed only in WebKit main, 2026-05). The model tile cannot depend on
|
|
* `aspect-ratio` for its box — the ratio must come from an in-flow spacer
|
|
* (percentage padding), which every engine resolves against the tile width.
|
|
*/
|
|
describe('CardModelTile — proporção do tile não usa aspect-ratio', () => {
|
|
it.each(CARD_MODELS.map((model) => [model.id, model] as const))(
|
|
'tile %s tira a altura do espaçador de proporção',
|
|
(_id, model) => {
|
|
const { container } = render(<CardModelTile model={model} fontFamily="Brexter" />)
|
|
|
|
const spacer = container.querySelector<HTMLElement>('[data-card-tile-ratio]')
|
|
expect(spacer).toBeTruthy()
|
|
|
|
const ratio = Number(spacer!.dataset.cardTileRatio)
|
|
expect(ratio).toBeCloseTo(model.height / model.width, 6)
|
|
// The computed style serializes integer percentages without decimals.
|
|
expect(parseFloat(spacer!.style.paddingBottom)).toBeCloseTo(ratio * 100, 3)
|
|
|
|
// The tile box (the spacer parent) must not carry the WebKit-fragile
|
|
// `aspect-ratio`; nothing inside the tile may either.
|
|
expect(spacer!.parentElement!.getAttribute('style') ?? '').not.toContain('aspect-ratio')
|
|
expect(container.innerHTML).not.toContain('aspect-ratio')
|
|
},
|
|
)
|
|
})
|