Testing with ag-Grid | Vue.js & Cypress

This post shows a brief example of using Cypress to interact with a Vue.js application to check that an ag-grid is Rendering, Sorting and Filtering Data. Full source code is available on Github.

The full project is available on Github.

Getting started


First you'll need to follow the Get Started with ag-Grid and Vue guide to create the app that will be tested. Alternatively, you can download the code from our StackBlitz example.

Install Cypress:

$ npm i cypress --save-dev

Add the following script to the package.json file:

{ "cypress:open": "cypress open" }

Run the Cypress Test Runner:

$ npm run cypress:open

In the cypress/integration directory, create a test file and open it in the test runner:

Writing tests


Before each test run cy.visit(###) and pass the URL of the port our app is running on:

 beforeEach(() => {
 	cy.visit('http://localhost:8081');
 });
An advantage of End-to-end testing with Cypress is that all DOM queries are wrapped with retry and timeout logic. This allows for leaner tests as we don't need to include additional code that ensures that the grid has been rendered before running tests.

Rendering rows


Each cell in the grid has a col-id attribute specifying which column the cell is rendered in.

The data of the first row in the grid is shown below:

{ make: "Toyota", model: "Celica", price: 35000 }

We can test that cells in a given row are rendering the correct values by querying the DOM and evaluating the contents of each cell:

it('renders the first row', () => {
        assertCellValueInFirstRow('make', 'Toyota');
        assertCellValueInFirstRow('model', 'Celica');
        assertCellValueInFirstRow('price', '35000');
    });
    
 function assertCellValueInFirstRow(colId, value) {
	cy.get('.ag-center-cols-container .ag-row')
		.first()
		.find(`[col-id="${colId}"]`)
		.then(cell => {
			expect(cell).to.have.text(value);
		});
}
Tests and assertions for renders first row

Sorting Data


By default nodes are not rearranged in the DOM to match their sorted order. Instead the row-index property of each row is updated upon sorting and the rows position in the browser is calculated and set with CSS.

This means that querying the DOM will always return the nodes in their original order, regardless of whether the rows are being sorted or not.

If you would like for the rows in the DOM to appear in their displayed order then include the flag ensureDomOrder in gridOptions.
Sorting does not cause nodes to be rearranged.

To test that data is being sorted correctly we'll first need to query the DOM and sort the rows using their row-index property:

cy.get('.ag-center-cols-container .ag-row')
	.then(rows => {
		return rows.sort((a, b) => {
			return +a.getAttribute('row-index') - +b.getAttribute('row-index');
		})
	})

The expected order when applying an ascending sort to the 'make' column is shown below:

const EXPECTED_ORDER = ['Ford', 'Porsche', 'Toyota'];

We can now evaluate whether the queried cells follow that order by iterating over the sorted rows:

it('sorts the data', () => {
	cy.get('.ag-header-cell')
		.first()
		.click()

    cy.get('.ag-center-cols-container .ag-row')
		.then(rows => {
			return rows.sort((a, b) => {
				return +a.getAttribute('row-index') - +b.getAttribute('row-index');
			})
		})
		.then(sortedRows => {
			const EXPECTED_ORDER = ['Ford', 'Porsche', 'Toyota'];
			sortedRows.each((ind, row) => {
				let makeCell = row.querySelector('[col-id="make"]');
                expect(makeCell).to.have.text(EXPECTED_ORDER[ind]);
			})
		})
});
Tests and assertions for sorts the data

Filtering Data


To filter on a column we need to:

  • Open the column menu
  • Change tabs to the filter menu
  • Enter text into the mini-filter and press enter
Filtering for 'Toyota'.
If you would like to filter directly onto the grid you can configure floating filters.

As with sorting, we can test that the correct values are being filtered by querying the cells in the filtered column and evaluating their contents:

it('filters for Toyota', () => {
	cy.get('.ag-icon-menu')
		.first()
		.click()

	cy.get('.ag-tab')
		.then(tabs => tabs[1])
		.click()

	cy.get('.ag-filter-filter')
		.type('Toyota{enter}')

	cy.get('.ag-center-cols-container .ag-row')
		.find(`[col-id="make"]`)
		.then(cells => {
			cells.each((_, cell) => {
				expect(cell).to.have.text('Toyota');
			});
		})
});
Tests and assertions for 'filters for Toyota'

What's next?


If you would like to try out ag-Grid check out our getting started guides (JS / React / Angular / Vue)

And the full project used in this blog post is available on Github.

Happy coding!