FreeGridv1.15.1English

그리드 테스트하기

@freegridjs/testing은 jsdom, happy-dom, 실제 브라우저에서 사용자처럼 셀 읽기·편집·정렬·키 입력을 합니다. mockLayout으로 jsdom에 행이 그려지고, selectors는 Playwright·Cypress에 씁니다.

그리드가 있는 화면을 테스트하면 그리드 내부 DOM 때문에 깨지거나, jsdom에서는 행이 아예 안 나오기 쉽습니다. @freegridjs/testing은 사용자처럼 그리드를 다루고(더블클릭, 입력, Enter, 헤더 클릭) 화면에 보이는 것을 읽어 줍니다.

npm i -D @freegridjs/testing

단위 테스트(Vitest, Jest)

import { beforeAll, expect, it } from 'vitest';
import { createGrid } from '@freegridjs/core';
import { gridHarness, mockLayout } from '@freegridjs/testing';

// jsdom has no layout: without this every element is 0 × 0 and no rows are drawn
beforeAll(() => { mockLayout(); });

it('refuses a quantity over 99 and saves a good one', async () => {
  const host = document.createElement('div');
  document.body.append(host);
  const api = createGrid(host, { columns, data });
  const grid = gridHarness(host);
  await grid.waitForRows();

  expect(grid.headers()).toEqual(['Name', 'Qty', 'City']);
  expect(grid.edit(0, 'qty', '500').ok).toBe(false);   // the editor stays open with the message
  grid.press('Escape');

  expect(grid.edit(0, 'qty', '42')).toEqual({ ok: true });
  await grid.settle();
  expect(grid.cellText(0, 'qty')).toBe('42');
  expect(api.getModifiedRows().updated).toHaveLength(1);

  grid.clickHeader('qty');                           // sort
  await grid.settle();
  expect(grid.column('qty')).toEqual(['1', '2', '42']);
});
이름타입설명
mockLayout({ width?, height? })() => voidjsdom / happy-dom에서 요소에 크기를 줌(기본 1024 × 600, 약 20행)과 없는 canvas 경고를 끔. 되돌리는 함수를 돌려줌.
gridHarness(container)GridHarness요소 안의 그리드를 위한 도우미: createGrid에 준 요소, 컴포넌트의 host, 그리드 루트.
cell(r, colId) / cellText(r, colId)HTMLElement | null / string그려진 셀과 그 글자. 화면에 없으면 null / 빈 글자.
rows(colIds?) / column(colId)string[][] / string[]그려진 행의 글자(표시 순서).
headers() / columnIds() / rowCount()string[] / string[] / number보이는 컬럼의 헤더 글자와 id. 그려진 행 수.
click / dblclick / clickHeader / pressvoid사용자 같은 포인터·키 이벤트. press는 그리드에 포커스가 있는 것처럼 보냄.
edit(r, colId, text, finish?){ ok, message? }더블클릭 후 글자를 바꾸고 Enter(또는 'Tab', 'Escape'). 값이 저장됐을 때만 ok true: 'Escape'면 false, 규칙이 거부하면 ok false와 안내. 텍스트·숫자·날짜·서식 편집기용.
waitForRows(count?, timeout?) / settle()Promise<void>행이 그려질 때까지, 또는 다음 그리기까지 기다림.

React, Vue, Svelte, Angular와 함께

컴포넌트를 평소처럼 렌더링하고, 그 바깥 요소를 gridHarness에 넘기세요.

import { render } from '@testing-library/react';
import { FreeGrid } from '@freegridjs/react';
import { gridHarness, mockLayout } from '@freegridjs/testing';

beforeAll(() => { mockLayout(); });

it('shows the orders', async () => {
  const { container } = render(<FreeGrid columns={columns} data={orders} />);
  const grid = gridHarness(container);
  await grid.waitForRows(3);
  expect(grid.column('customer.name')).toEqual(['Kim', 'Lee', 'Park']);
});

브라우저 테스트(Playwright, Cypress)

실제 브라우저에서는 selectors를 쓰세요. 그리드 내부 구조가 바뀌어도 맞춰 바뀝니다.

import { selectors } from '@freegridjs/testing';

await page.locator(selectors.cell(0, 'qty')).dblclick();
await page.keyboard.type('42');
await page.keyboard.press('Enter');
await expect(page.locator(selectors.cell(0, 'qty'))).toHaveText('42');
await page.locator(selectors.header('qty')).click();     // sort

// Cypress
cy.get(selectors.cell(0, 'name')).should('have.text', 'Kim');
selectors.대상
root그리드 루트
cell(rowIndex, colId) / row(rowIndex)본문 셀 / 행. rowIndex는 표시 위치
header(colId) / headerLabel헤더 셀 / 그 안의 글자
editor / editorMessage열린 편집기 상자 / 그 안내
filterInput(colId) / overlay필터 행 입력칸 / "행 없음"·로딩 표시

테스트에서도 화면에 보이는 행만 그려집니다. 아래쪽 데이터는 API(getDisplayedRows, getCellValue)로 읽거나 먼저 scrollToRow로 스크롤하세요. 선택형 편집기(select, combo, 달력)는 단위 테스트에서 api.setCellValue로 넣는 것이 가장 쉽고, 브라우저에서는 옵션을 클릭하세요.

이 페이지에 대한 질문

Jest나 Vitest 테스트에서 그리드에 행이 하나도 안 나오는 이유는?

jsdom에는 레이아웃이 없어 모든 요소의 높이가 0이라 그리드가 행을 그리지 않습니다. 테스트 전에 @freegridjs/testing의 mockLayout()을 부르고(또는 직접 크기를 주고), gridHarness(el).waitForRows()로 행을 기다리세요.

Playwright나 Cypress에서 셀을 찾으려면?

@freegridjs/testing의 selectors.cell(rowIndex, colId)를 쓰세요. 예: page.locator(selectors.cell(0, 'name')). 행 번호는 정렬·필터 뒤의 표시 위치입니다.