Skip to content
This repository was archived by the owner on Aug 19, 2024. It is now read-only.

AG-8571 Add React Testing Lib tests #77

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@
"dev": "vite",
"buildx": "vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
"preview": "vite preview",
"test:e2e": "vitest run",
"test:watch": "vitest --ui"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"bootstrap": "4.5.0",
"@ag-grid-community/react": "~31.0.2",
"@ag-grid-community/core": "~31.0.2",
"@ag-grid-community/client-side-row-model": "~31.0.2",
"@ag-grid-community/core": "~31.0.2",
"@ag-grid-community/react": "~31.0.2",
"@ag-grid-community/styles": "~31.0.2",
"@ag-grid-enterprise/charts": "~31.0.2",
"@ag-grid-enterprise/clipboard": "~31.0.2",
"@ag-grid-enterprise/column-tool-panel": "~31.0.2",
Expand All @@ -51,16 +51,24 @@
"@ag-grid-enterprise/sparklines": "~31.0.2",
"@ag-grid-enterprise/status-bar": "~31.0.2",
"@ag-grid-enterprise/viewport-row-model": "~31.0.2",
"@ag-grid-community/styles": "~31.0.2"
"bootstrap": "4.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@testing-library/jest-dom": "^6.4.1",
"@testing-library/react": "^14.2.0",
"@testing-library/user-event": "^14.5.2",
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@vitejs/plugin-react": "^4.0.3",
"@vitest/ui": "^1.2.2",
"eslint": "^8.45.0",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
"vite": "^4.4.5"
"jsdom": "^24.0.0",
"vite": "^4.4.5",
"vitest": "^1.2.2"
}
}
}
49 changes: 49 additions & 0 deletions src/tests/basic.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
import { ColDef } from '@ag-grid-community/core';
import { AgGridReact } from '@ag-grid-community/react';
import { render, screen } from '@testing-library/react';
import React, { useRef, useState } from 'react';

import { expect, describe, test } from 'vitest';

interface RowData {
make: string;
model: string;
price: number;
}

const App = () => {
const gridRef = useRef<AgGridReact<RowData>>(null);

const [rowData] = useState<RowData[]>([
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxster', price: 72000 }
]);
const [colDefs, setColDefs] = useState<ColDef<RowData>[]>([
{ field: 'make' },
{ field: 'model' },
{ field: 'price' },
]);

return (
<div className="ag-theme-quartz" style={{ height: 400, width: 600 }}>
<AgGridReact<RowData>
ref={gridRef}
rowData={rowData}
columnDefs={colDefs}
modules={[ClientSideRowModelModule]} />
</div>
);
};

describe('Basic Grid', () => {

test('render basic grid', async () => {
render(<App />);
expect(screen.findByText('Boxster')).toBeDefined();
expect(screen.findByText('72000')).toBeDefined();

});

});
81 changes: 81 additions & 0 deletions src/tests/cellRenderer.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
import { ColDef } from '@ag-grid-community/core';
import { AgGridReact, CustomCellRendererProps } from '@ag-grid-community/react';
import { render, screen } from '@testing-library/react';
import React, { useRef, useState } from 'react';
import { act } from 'react-dom/test-utils';
import { describe, expect, test } from 'vitest';

interface RowData {
make: string;
model: string;
price: number;
bought: boolean;
}

// cell renderer that contains a button
const BuyCellRenderer = (props: CustomCellRendererProps<RowData, boolean>) => {
const buttonClick = () => {
props.node.setDataValue('bought', true);
};

return (
<>
{props.data?.bought ?
<span>Bought a {props.data?.make}</span> :
<button onClick={buttonClick}>Buy: {props.data?.make}</button>
}
</>
);
};


const App = () => {
const gridRef = useRef<AgGridReact<RowData>>(null);

const [rowData] = useState<RowData[]>([
{ make: 'Toyota', model: 'Celica', price: 35000, bought: false },
{ make: 'Ford', model: 'Mondeo', price: 32000, bought: false },
{ make: 'Porsche', model: 'Boxster', price: 72000, bought: false }
]);
const [colDefs, setColDefs] = useState<ColDef<RowData>[]>([
{ field: 'make' },
{ field: 'model' },
{ field: 'price' },
{ field: 'bought', cellRenderer: BuyCellRenderer }
]);

return (
<div className="ag-theme-quartz" style={{ height: 400, width: 600 }}>
<AgGridReact<RowData>
ref={gridRef}
rowData={rowData}
columnDefs={colDefs}
reactiveCustomComponents
modules={[ClientSideRowModelModule]} />
</div>
);
};

describe('Basic Grid', () => {

test('render basic grid', async () => {
render(<App />);
await screen.findByText('Boxster')
});

test('render grid and then sort by price', async () => {
render(<App />);

let porcheButton = await screen.findByText('Buy: Porsche');
expect(porcheButton).toBeDefined();

// Handy debug function to see the center rows of the grid
// screen.debug(document.querySelector('.ag-center-cols-container')!);

act(() => porcheButton.click());

let bought = await screen.findByText('Bought a Porsche');
expect(bought).toBeDefined();
});
});
85 changes: 85 additions & 0 deletions src/tests/clickingRows.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
import { ColDef, RowClickedEvent } from '@ag-grid-community/core';
import { expect, describe, test, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React, { useCallback, useRef, useState } from 'react';
import { AgGridReact } from '@ag-grid-community/react';

interface RowData {
make: string;
model: string;
price: number;
}

const App = () => {
const gridRef = useRef<AgGridReact<RowData>>(null);

const [rowData] = useState<RowData[]>([
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxster', price: 72000 }
]);
const [colDefs, setColDefs] = useState<ColDef<RowData>[]>([
{ field: 'make' },
{ field: 'model' },
{ field: 'price' },
]);

const [rowClicked, setRowClicked] = useState<RowData | null>(null);
const [rowDoubleClicked, setRowDoubleClicked] = useState<RowData | null>(null);

const onRowClicked = useCallback((params: RowClickedEvent) => {
setRowClicked(params.data);
}, []);

const onRowDoubleClicked = useCallback((params: RowClickedEvent) => {
setRowDoubleClicked(params.data);
}, []);

return (
<div>
<div data-testid="rowClicked">Row Clicked: {rowClicked?.make}</div>
<div data-testid="rowDoubleClicked">Row Double Clicked: {rowDoubleClicked?.make}</div>
<div className="ag-theme-quartz" style={{ height: 400, width: 600 }}>
<AgGridReact<RowData>
ref={gridRef}
rowData={rowData}
columnDefs={colDefs}
onRowClicked={onRowClicked}
onRowDoubleClicked={onRowDoubleClicked}
modules={[ClientSideRowModelModule]} />
</div>
</div>
);
};

describe('Row Clicks Grid', () => {

// render basic AgGridReact
test('render grid and click a row', async () => {
render(<App />);

let row = await screen.findByText('Ford');
expect(row).toBeDefined();

await userEvent.click(row);

let rowClicked = await screen.findByTestId('rowClicked');
expect(rowClicked.textContent).toBe('Row Clicked: Ford');
});

// render basic AgGridReact
test('render grid and double click a row', async () => {
render(<App />);

let row = await screen.findByText('Porsche');
expect(row).toBeDefined();

await userEvent.dblClick(row);

let rowClicked = await screen.findByTestId('rowDoubleClicked');
expect(rowClicked.textContent).toBe('Row Double Clicked: Porsche');
});

});
63 changes: 63 additions & 0 deletions src/tests/editor.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
import { ColDef } from '@ag-grid-community/core';
import { AgGridReact } from '@ag-grid-community/react';
import { describe, test, expect } from 'vitest';
import { fireEvent, render, screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React, { useRef, useState } from 'react';

interface RowData {
make: string;
model: string;
price: number;
}

const App = () => {
const gridRef = useRef<AgGridReact<RowData>>(null);

const [rowData] = useState<RowData[]>([
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxster', price: 72000 }
]);
const [colDefs, setColDefs] = useState<ColDef<RowData>[]>([
{ field: 'make' },
{ field: 'model' },
{ field: 'price', editable: true, valueFormatter: (params) => "$" + params.value.toLocaleString()},
]);

return (
<div className="ag-theme-quartz" style={{ height: 400, width: 600 }}>
<AgGridReact<RowData>
ref={gridRef}
rowData={rowData}
columnDefs={colDefs}
modules={[ClientSideRowModelModule]} />
</div>
);
};

describe('Edit Cell Grid', () => {

test('double click cell to edit', async () => {
render(<App />);

let porschePrice = await screen.findByText('$72,000')
expect(porschePrice).toBeDefined();

// double click to enter edit mode
await userEvent.dblClick(porschePrice);

let input: HTMLInputElement = within(porschePrice).getByLabelText('Input Editor');

await userEvent.keyboard('100000');

// press enter to save
fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' });

porschePrice = await screen.findByText('$100,000')
expect(porschePrice).toBeDefined();

});

});
Loading