Skip to content

feat(findBy*): adds findBy* query type allowing for async element queries #224

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 19, 2019
Merged
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
1 change: 0 additions & 1 deletion src/__tests__/element-queries.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'jest-dom/extend-expect'
import {configure} from '../config'
import {render, renderIntoDocument} from './helpers/test-utils'

Expand Down
2 changes: 0 additions & 2 deletions src/__tests__/example.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// query utilities:
import {getByLabelText, getByText, getByTestId, queryByTestId, wait} from '../'
// adds special assertions like toHaveTextContent
import 'jest-dom/extend-expect'

function getExampleDOM() {
// This is just a raw example of setting up some DOM
Expand Down
8 changes: 5 additions & 3 deletions src/__tests__/helpers/test-utils.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import {getQueriesForElement} from '../../get-queries-for-element'

function render(html) {
const container = document.createElement('div')
function render(html, {container = document.createElement('div')} = {}) {
container.innerHTML = html
const containerQueries = getQueriesForElement(container)
return {container, ...containerQueries}
function rerender(newHtml) {
return render(newHtml, {container})
}
return {container, rerender, ...containerQueries}
}

function renderIntoDocument(html) {
Expand Down
125 changes: 125 additions & 0 deletions src/__tests__/queries.find.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import {render} from './helpers/test-utils'

test('find asynchronously finds elements', async () => {
const {
findByLabelText,
findAllByLabelText,

findByPlaceholderText,
findAllByPlaceholderText,

findByText,
findAllByText,

findByAltText,
findAllByAltText,

findByTitle,
findAllByTitle,

findByDisplayValue,
findAllByDisplayValue,

findByRole,
findAllByRole,

findByTestId,
findAllByTestId,
} = render(`
<div>
<div data-testid="test-id" aria-label="test-label">test text content</div>
<select><option>display value</option></select>
<input placeholder="placeholder" />
<img alt="test alt text" src="/lucy-ricardo.png" />
<span title="test title" />
<div role="dialog"></div>
</div>
`)
await expect(findByLabelText('test-label')).resolves.toBeTruthy()
await expect(findAllByLabelText('test-label')).resolves.toHaveLength(1)

await expect(findByPlaceholderText('placeholder')).resolves.toBeTruthy()
await expect(findAllByPlaceholderText('placeholder')).resolves.toHaveLength(1)

await expect(findByText('test text content')).resolves.toBeTruthy()
await expect(findAllByText('test text content')).resolves.toHaveLength(1)

await expect(findByAltText('test alt text')).resolves.toBeTruthy()
await expect(findAllByAltText('test alt text')).resolves.toHaveLength(1)

await expect(findByTitle('test title')).resolves.toBeTruthy()
await expect(findAllByTitle('test title')).resolves.toHaveLength(1)

await expect(findByDisplayValue('display value')).resolves.toBeTruthy()
await expect(findAllByDisplayValue('display value')).resolves.toHaveLength(1)

await expect(findByRole('dialog')).resolves.toBeTruthy()
await expect(findAllByRole('dialog')).resolves.toHaveLength(1)

await expect(findByTestId('test-id')).resolves.toBeTruthy()
await expect(findAllByTestId('test-id')).resolves.toHaveLength(1)
})

test('find rejects when something cannot be found', async () => {
const {
findByLabelText,
findAllByLabelText,

findByPlaceholderText,
findAllByPlaceholderText,

findByText,
findAllByText,

findByAltText,
findAllByAltText,

findByTitle,
findAllByTitle,

findByDisplayValue,
findAllByDisplayValue,

findByRole,
findAllByRole,

findByTestId,
findAllByTestId,
} = render(`<div />`)

// I just don't want multiple lines for these.
// qo = queryOptions
// wo = waitForElementOptions
const qo = {} // query options
const wo = {timeout: 10} // wait options

await expect(findByLabelText('x', qo, wo)).rejects.toThrow('x')
await expect(findAllByLabelText('x', qo, wo)).rejects.toThrow('x')

await expect(findByPlaceholderText('x', qo, wo)).rejects.toThrow('x')
await expect(findAllByPlaceholderText('x', qo, wo)).rejects.toThrow('x')

await expect(findByText('x', qo, wo)).rejects.toThrow('x')
await expect(findAllByText('x', qo, wo)).rejects.toThrow('x')

await expect(findByAltText('x', qo, wo)).rejects.toThrow('x')
await expect(findAllByAltText('x', qo, wo)).rejects.toThrow('x')

await expect(findByTitle('x', qo, wo)).rejects.toThrow('x')
await expect(findAllByTitle('x', qo, wo)).rejects.toThrow('x')

await expect(findByDisplayValue('x', qo, wo)).rejects.toThrow('x')
await expect(findAllByDisplayValue('x', qo, wo)).rejects.toThrow('x')

await expect(findByRole('x', qo, wo)).rejects.toThrow('x')
await expect(findAllByRole('x', qo, wo)).rejects.toThrow('x')

await expect(findByTestId('x', qo, wo)).rejects.toThrow('x')
await expect(findAllByTestId('x', qo, wo)).rejects.toThrow('x')
})

test('actually works with async code', async () => {
const {findByTestId, container, rerender} = render(`<div />`)
setTimeout(() => rerender(`<div data-testid="div">correct dom</div>`), 20)
await expect(findByTestId('div', {}, {container})).resolves.toBeTruthy()
})
1 change: 0 additions & 1 deletion src/__tests__/text-matchers.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'jest-dom/extend-expect'
import cases from 'jest-in-case'

import {getDefaultNormalizer} from '../'
Expand Down
2 changes: 0 additions & 2 deletions src/__tests__/wait-for-dom-change.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import {waitForDomChange} from '../'
// adds special assertions like toBeTruthy
import 'jest-dom/extend-expect'
import {render} from './helpers/test-utils'

const skipSomeTime = delayMs =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'jest-dom/extend-expect'
import {waitForElementToBeRemoved} from '../'
import {render} from './helpers/test-utils'

Expand Down
1 change: 0 additions & 1 deletion src/__tests__/wait-for-element-to-be-removed.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'jest-dom/extend-expect'
import {waitForElementToBeRemoved} from '../'
import {renderIntoDocument} from './helpers/test-utils'

Expand Down
2 changes: 0 additions & 2 deletions src/__tests__/wait-for-element.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import {waitForElement, wait} from '../'
// adds special assertions like toBeTruthy
import 'jest-dom/extend-expect'
import {render} from './helpers/test-utils'

const skipSomeTime = delayMs =>
Expand Down
33 changes: 33 additions & 0 deletions src/queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
queryAllByAttribute,
queryByAttribute,
} from './query-helpers'
import {waitForElement} from './wait-for-element'
import {getConfig} from './config'

// Here are the queries for the library.
Expand Down Expand Up @@ -375,6 +376,38 @@ function getByDisplayValue(...args) {
return firstResultOrNull(getAllByDisplayValue, ...args)
}

function makeFinder(getter) {
return (container, text, options, waitForElementOptions) =>
waitForElement(
() => getter(container, text, options),
waitForElementOptions,
)
}

export const findByLabelText = makeFinder(getByLabelText)
export const findAllByLabelText = makeFinder(getAllByLabelText)

export const findByPlaceholderText = makeFinder(getByPlaceholderText)
export const findAllByPlaceholderText = makeFinder(getAllByPlaceholderText)

export const findByText = makeFinder(getByText)
export const findAllByText = makeFinder(getAllByText)

export const findByAltText = makeFinder(getByAltText)
export const findAllByAltText = makeFinder(getAllByAltText)

export const findByTitle = makeFinder(getByTitle)
export const findAllByTitle = makeFinder(getAllByTitle)

export const findByDisplayValue = makeFinder(getByDisplayValue)
export const findAllByDisplayValue = makeFinder(getAllByDisplayValue)

export const findByRole = makeFinder(getByRole)
export const findAllByRole = makeFinder(getAllByRole)

export const findByTestId = makeFinder(getByTestId)
export const findAllByTestId = makeFinder(getAllByTestId)

export {
queryByPlaceholderText,
queryAllByPlaceholderText,
Expand Down
1 change: 1 addition & 0 deletions tests/setup-env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import 'jest-dom/extend-expect'