npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

testing-library-table-queries

v0.4.0

Published

Additional testing-library queries for querying tables like a user

Downloads

9,847

Readme

testing-library-table-queries

Additional testing-library queries for querying tables like a user

NPM

Install

yarn add -D testing-library-table-queries

Usage

These examples all use @testing-library/react, but there isn't anything tying use of this library to that, it should work with anything @testing-library/dom-based.

Inline

import {
  getRowByFirstCellText,
  getAllCells
} from 'testing-library-table-queries'

const { container } = render(<MyTable />)
expect(getRowByFirstCellText(container, 'John Smith')).toBeVisible()
const cells = getAllCells(getRowByFirstCellText(container, 'John Smith'))

Global custom query

For e.g. React, we can add the custom queries to a global custom render (see docs)

import { render, queries } from '@testing-library/react'
import tableQueries from 'testing-library-table-queries'

const customRender = (ui, options) =>
  render(ui, { queries: { ...queries, ...tableQueries }, ...options })

// re-export everything
export * from '@testing-library/react'

// override render method
export { customRender as render }

You can then use the queries just like any other query:

const { getRowByFirstCellText } = render(<MyTable />)
expect(getRowByFirstCellText('John Smith')).toBeVisible()
const cells = within(getRowByFirstCellText('John Smith')).getAllCells()

Limitations

  • Assumes tables are using standard semantic table HTML elements (tbody, thead, tr etc.) with valid DOM nesting.
  • Doesn't handle tables with cells spanning multiple rows (rowspan)
    • But colspan is fine!

Queries

All queries have the standard set of get/getAll/query/queryAll/find/findAll variants. The pluralisation varies slightly to make them sensible.

Rows

const { getAllRows } = render(<MyTable />)
expect(getAllRows()).toHaveLength(5)

Just a shorthand to get all rows. No better than getAllByRole('row'), but used internally by some other queries, so might as well export it.

Cells

const { getAllCells } = render(<MyTable />)
expect(getAllCells()).toHaveLength(48)

Shorthand to get all cells, whether th or td. Most useful when combined with other queries (as is done internally).

expect(within(headerRow).getAllCells()).toHaveLength(6)

Row groups

const { getByRowgroupType, queryByRowgroupType } = render(<MyTable />)
const header = getByRowgroupType('thead')
expect(within(header).getAllCells()).toHaveLength(6)
expect(queryByRowgroupType('tfoot')).toBeNull()

Finds row groups, based on which type of grouping it is (thead, tbody or tfoot). These would typically be indicated to a user through styling.

Rows by row groups

const { getAllRowsByRowgroupType } = render(<MyTable />)
expect(getAllRowsByRowgroupType('tbody')).toHaveLength(8)

Finds rows, based on which type of rowgroup they are in.

Rows by first cell text

const { getRowByFirstCellText } = render(<MyTable />)
expect(getRowByFirstCellText('John Smith')).toBeVisible()
fireEvent.click(within(getRowByFirstCellText('John Smith')).getByText('Delete'))

Users will generally find rows by scanning the content in the first column, then reading across the row. This finds that row (rather than just the first cell), which can then be used to identify other items within that row.

Column cells by header text

const { getAllColumnCellsByHeaderText } = render(<MyTable />)
const ageCells = getAllColumnCellsByHeaderText('Age')
ageCells.forEach((cell, index) => {
  expect(cell).toHaveTextContent(expectedValues[index])
})

Returns an array of cells based on the text in the column header. Note that there is no DOM 'column' element, so it is an array of cells. If multiple columns have the same header text, the first is used. Optionally, this also supports an index (starting from zero) to support having multiple header rows:

const { getAllColumnCellsByHeaderText } = render(<MyTable />)
const ageCells = getAllColumnCellsByHeaderText('Age', 1) // Use the second header row, rather than the first

Cell by row and column headers

const { getCellByRowAndColumnHeaders } = render(<MyTable />)
expect(getCellByRowAndColumnHeaders('John Smith', 'Age')).toHaveTextContent(
  '28'
)

If a user is trying to find a specific value for a specific entity, they might scan from the row and column headers. This finds cells based on those headers. Like column cells by header text, it only uses the first column with the specified header text (but will handle multiple rows), and supports a header index.

Examples

See example tests

Future changes

  • Address the first column limitation
  • Allow custom text normalisation/matching
  • Allow Nth cell in a row, rather than just first

Development

TODO:

  • Set up changelog stuff
  • Publish from CI

Publishing

Run

yarn publish

This will ask for the version bump, publish to NPM, commit the bump to git, tag it.

License

MIT © lexanth