RTL에서 overflow scroll 상태 테스트 — 실제 브라우저(Vitest browser mode·Playwright)에서만 돈다. jsdom 은 레이아웃을 하지 않아 scrollWidth·clientWidth 가 0 이라 아래에서 true 를 기대하는 단언이 둘 다 실패한다.1

// scrollWidth > clientWidth면 가로 스크롤 필요
const isOverflowScrollable = (el) => ({
  horizontal: el.scrollWidth > el.clientWidth,
  vertical: el.scrollHeight > el.clientHeight,
})

test('overflow 확인', () => {
  render(<ScrollableComponent parentWidth={300} childWidth={500} />)

  const parent = screen.getByTestId('parent-container')

  expect(isOverflowScrollable(parent).horizontal).toBe(true)
})

test('동적 크기 변경', () => {
  const { rerender } = render(<Comp parentWidth={400} childWidth={300} />)

  expect(isOverflowScrollable(screen.getByTestId('parent')).horizontal).toBe(
    false
  )

  rerender(<Comp parentWidth={400} childWidth={600} />)

  expect(isOverflowScrollable(screen.getByTestId('parent')).horizontal).toBe(
    true
  )
})

jsdom 에서 돌려야 하면 515 처럼 Object.defineProperty 로 scrollWidth·clientWidth 를 모킹한다. getBoundingClientRect() 도 jsdom 에선 전부 0이다.


Footnotes

  1. jsdom README — Unimplemented parts of the web platform: “Layout: the ability to calculate where elements will be visually laid out as a result of CSS, which impacts methods like getBoundingClientRects() or properties like offsetTop.” / “Currently jsdom has dummy behaviors for some aspects of these features, such as … returning zeros for many layout-related properties.” ↩

#521