diff --git a/README.md b/README.md
index 2122935..e93538e 100644
--- a/README.md
+++ b/README.md
@@ -57,7 +57,6 @@ This allows you to use all the useful
-
- [Installation](#installation)
- [With TypeScript](#with-typescript)
- [Usage](#usage)
@@ -79,7 +78,8 @@ npm install --save-dev @testing-library/cypress
### With TypeScript
-Typings are defined in `@types/testing-library__cypress` at [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/testing-library__cypress),
+Typings are defined in `@types/testing-library__cypress` at
+[DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/testing-library__cypress),
and should be added as follows in `tsconfig.json`:
```json
@@ -100,11 +100,12 @@ Add this line to your project's `cypress/support/commands.js`:
import '@testing-library/cypress/add-commands'
```
-You can now use all of `DOM Testing Library`'s `findBy`, `findAllBy`, `queryBy`
-and `queryAllBy` commands.
+You can now use all of `DOM Testing Library`'s `findBy` and `findAllBy`
+commands.
[See the `DOM Testing Library` docs for reference](https://testing-library.com)
-You can find [all Library definitions here](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/testing-library__cypress/index.d.ts).
+You can find
+[all Library definitions here](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/testing-library__cypress/index.d.ts).
To configure DOM Testing Library, use the following custom command:
@@ -113,46 +114,43 @@ cy.configureCypressTestingLibrary(config)
```
To show some simple examples (from
-[cypress/integration/query.spec.js](cypress/integration/query.spec.js) or [cypress/integration/find.spec.js](cypress/integration/find.spec.js)):
+[cypress/integration/find.spec.js](cypress/integration/find.spec.js)):
```javascript
-cy.queryAllByText('Button Text').should('exist')
-cy.queryAllByText('Non-existing Button Text').should('not.exist')
-cy.queryAllByLabelText('Label text', {timeout: 7000}).should('exist')
-cy.findAllByText('Jackie Chan').click();
+cy.findAllByText('Button Text').should('exist')
+cy.findAllByText('Non-existing Button Text').should('not.exist')
+cy.findAllByLabelText('Label text', {timeout: 7000}).should('exist')
+cy.findAllByText('Jackie Chan').click()
// findAllByText _inside_ a form element
-cy.get('form').within(() => {
- cy.findAllByText('Button Text').should('exist')
-})
-cy.get('form').then(subject => {
- cy.findAllByText('Button Text', {container: subject}).should('exist')
-})
-cy.get('form').findAllByText('Button Text').should('exist')
+cy.get('form')
+ .findAllByText('Button Text')
+ .should('exist')
```
### Differences from DOM Testing Library
`Cypress Testing Library` supports both jQuery elements and DOM nodes. This is
necessary because Cypress uses jQuery elements, while `DOM Testing Library`
-expects DOM nodes. When you pass a jQuery element as `container`, it will get
-the first DOM node from the collection and use that as the `container` parameter
-for the `DOM Testing Library` functions.
-
-`get*` queries are disabled. `find*` queries do not use the Promise API of
-`DOM Testing Library`, but instead forward to the `get*` queries and use Cypress'
-built-in retryability using error messages from `get*` APIs to forward as error
-messages if a query fails. `query*` also uses `get*` APIs, but disables retryability.
-
-`findAll*` can select more than one element and is closer in functionality to how
-Cypress built-in commands work. `findAll*` is preferred to `find*` queries.
-`find*` commands will fail if more than one element is found that matches the criteria
-which is not how built-in Cypress commands work, but is provided for closer compatibility
-to other Testing Libraries.
-
-Cypress handles actions when there is only one element found. For example, the following
-will work without having to limit to only 1 returned element. The `cy.click` will
-automatically fail if more than 1 element is returned by the `findAllByText`:
+expects DOM nodes. When you chain a query, it will get the first DOM node from
+`subject` of the collection and use that as the `container` parameter for the
+`DOM Testing Library` functions.
+
+`get*` and `query*` queries are disabled. `find*` queries do not use the Promise
+API of `DOM Testing Library`, but instead forward to the `get*` queries and use
+Cypress' built-in retryability using error messages from `get*` APIs to forward
+as error messages if a query fails.
+
+`findAll*` can select more than one element and is closer in functionality to
+how Cypress built-in commands work. `find*` commands will fail if more than one
+element is found that matches the criteria which is not how built-in Cypress
+commands work, but is provided for closer compatibility to other Testing
+Libraries.
+
+Cypress handles actions when there is only one element found. For example, the
+following will work without having to limit to only 1 returned element. The
+`cy.click` will automatically fail if more than 1 element is returned by the
+`findAllByText`:
```javascript
cy.findAllByText('Some Text').click()
@@ -237,6 +235,7 @@ Thanks goes to these people ([emoji key][emojis]):
+
This project follows the [all-contributors][all-contributors] specification.
diff --git a/cypress/integration/configure.spec.js b/cypress/integration/configure.spec.js
deleted file mode 100644
index beb113e..0000000
--- a/cypress/integration/configure.spec.js
+++ /dev/null
@@ -1,18 +0,0 @@
-///
-describe('configuring fallback globally', () => {
- beforeEach(() => {
- cy.visit('cypress/fixtures/test-app/')
- cy.configureCypressTestingLibrary({ fallbackRetryWithoutPreviousSubject: false })
- })
-
- it('findByText with a previous subject', () => {
- cy.get('#nested')
- .findByText('Button Text 1')
- .should('not.exist')
- cy.get('#nested')
- .findByText('Button Text 2')
- .should('exist')
- })
-})
-
-/* global cy */
diff --git a/cypress/integration/find.spec.js b/cypress/integration/find.spec.js
index 96fc2a0..d69443b 100644
--- a/cypress/integration/find.spec.js
+++ b/cypress/integration/find.spec.js
@@ -108,7 +108,7 @@ describe('find* dom-testing-library commands', () => {
it('findByText with a previous subject', () => {
cy.get('#nested')
- .findByText('Button Text 1', {fallbackRetryWithoutPreviousSubject: false})
+ .findByText('Button Text 1')
.should('not.exist')
cy.get('#nested')
.findByText('Button Text 2')
@@ -188,15 +188,6 @@ describe('find* dom-testing-library commands', () => {
cy.findByText(/^Button Text/i, {timeout: 100})
})
- it('findByText should not break existing code', () => {
- cy.window()
- .findByText('Button Text 1')
- .should('exist')
- cy.location()
- .findByText('Button Text 1')
- .should('exist')
- })
-
it('findByText should show as a parent command if it starts a chain', () => {
const assertLog = (attrs, log) => {
if (log.get('name') === 'findByText') {
@@ -218,17 +209,6 @@ describe('find* dom-testing-library commands', () => {
cy.on('log:added', assertLog)
cy.get('body').findByText('Button Text 1')
})
-
- it('should chain findBy* with subject different of document, element or window', () => {
- cy.wrap(true)
- .should('be.true')
- .findByText('Error message')
- .findByLabelText(/Required/i)
- .type('something')
- .findByText('Submit')
- .queryByText('Error message')
- .should('not.be.visible')
- })
})
/* global cy */
diff --git a/cypress/integration/query.spec.js b/cypress/integration/query.spec.js
index 24671d3..6075f89 100644
--- a/cypress/integration/query.spec.js
+++ b/cypress/integration/query.spec.js
@@ -1,208 +1,49 @@
-///
-describe('query* dom-testing-library commands', () => {
+describe('get* queries should error', () => {
beforeEach(() => {
cy.visit('cypress/fixtures/test-app/')
})
- // Test each of the types of queries: LabelText, PlaceholderText, Text, DisplayValue, AltText, Title, Role, TestId
-
- it('queryByLabelText', () => {
- cy.queryByLabelText('Label 1')
- .click()
- .type('Hello Input Labelled By Id')
- })
-
- it('queryAllByLabelText', () => {
- cy.queryAllByLabelText(/^Label \d$/).should('have.length', 2)
- })
-
- it('queryByPlaceholderText', () => {
- cy.queryByPlaceholderText('Input 1')
- .click()
- .type('Hello Placeholder')
- })
-
- it('queryAllByPlaceholderText', () => {
- cy.queryAllByPlaceholderText(/^Input \d$/).should('have.length', 2)
- })
-
- it('queryByText', () => {
- cy.queryByText('Button Text 1')
- .click()
- .should('contain', 'Button Clicked')
- })
-
- it('queryAllByText', () => {
- cy.queryAllByText(/^Button Text \d$/)
- .should('have.length', 2)
- .click({ multiple: true })
- .should('contain', 'Button Clicked')
- })
-
- it('queryByDisplayValue', () => {
- cy.queryByDisplayValue('Display Value 1')
- .click()
- .clear()
- .type('Some new text')
- })
-
- it('queryAllByDisplayValue', () => {
- cy.queryAllByDisplayValue(/^Display Value \d$/)
- .should('have.length', 2)
- })
-
- it('queryByAltText', () => {
- cy.queryByAltText('Image Alt Text 1').click()
- })
-
- it('queryAllByAltText', () => {
- cy.queryAllByAltText(/^Image Alt Text \d$/).should('have.length', 2)
- })
-
- it('queryByTitle', () => {
- cy.queryByTitle('Title 1').click()
- })
-
- it('queryAllByTitle', () => {
- cy.queryAllByTitle(/^Title \d$/).should('have.length', 2)
- })
-
- it('queryByRole', () => {
- cy.queryByRole('dialog').click()
- })
-
- it('queryAllByRole', () => {
- cy.queryAllByRole(/^dialog/).should('have.length', 2)
- })
-
- it('queryByTestId', () => {
- cy.queryByTestId('image-with-random-alt-tag-1').click()
- })
-
- it('queryAllByTestId', () => {
- cy.queryAllByTestId(/^image-with-random-alt-tag-\d$/).should('have.length', 2)
- })
-
- /* Test the behaviour around these queries */
-
- it('queryByText should show a deprecation warning', () => {
- let addedLog
- function addLog (_, log) {
- addedLog = log
- cy.off('log:added', addLog)
- }
- cy.on('log:added', addLog)
-
- cy.queryByText('Button Text 1')
- // query* doesn't retry more than once, but our log could be updated later depending on timing.
- // the `cy.wrap` adds a retryable step in to deal with possible timing issues of the assertions.
- cy.wrap(null).should(() => {
- const attrs = addedLog.toJSON()
- expect(attrs).to.have.property('state', 'failed')
- expect(attrs).to.have.nested.property('err.message')
- expect(attrs.err.message).to.contain(`@testing-library/cypress is deprecating all 'query*' commands.`)
+ const queryPrefixes = ['By', 'AllBy']
+ const queryTypes = [
+ 'LabelText',
+ 'PlaceholderText',
+ 'Text',
+ 'DisplayValue',
+ 'AltText',
+ 'Title',
+ 'Role',
+ 'TestId',
+ ]
+
+ queryPrefixes.forEach(queryPrefix => {
+ queryTypes.forEach(queryType => {
+ const obsoleteQueryName = `query${queryPrefix + queryType}`
+ const preferredQueryName = `find${queryPrefix + queryType}`
+ it(`${obsoleteQueryName} should error and suggest using ${preferredQueryName}`, () => {
+ const errorMessage = `You used '${obsoleteQueryName}' which has been removed from Cypress Testing Library because it does not make sense in this context. Please use '${preferredQueryName}' instead.`
+ cy.on('fail', err => {
+ expect(err.message).to.eq(errorMessage)
+ })
+
+ cy[`${obsoleteQueryName}`]('Irrelevant')
})
- })
-
- it('queryByText with .should(\'not.exist\')', () => {
- cy.queryAllByText(/^Button Text \d$/).should('exist')
- cy.queryByText('Non-existing Button Text', {timeout: 100}).should('not.exist')
- })
-
- it('queryByText within', () => {
- cy.get('#nested').within(() => {
- cy.queryByText('Button Text 2').click()
- })
- })
-
- it('queryByText should set the Cypress element to the found element', (done) => {
- // This test is a little strange since snapshots show what element
- // is selected, but snapshots themselves don't give access to those
- // elements. I had to make the implementation specific so that the `$el`
- // is the `subject` when the log is added and the `$el` is the `value`
- // when the log is changed. It would be better to extract the `$el` from
- // each snapshot
-
- cy.on('log:changed', (attrs, log) => {
- if (log.get('name') === 'queryByText') {
- expect(log.get('$el')).to.have.text('Button Text 1')
- done()
- }
- })
- cy.queryByText('Button Text 1')
- })
-
- it('query* will return immediately, and never retry', () => {
- cy.queryByText('Next Page').click()
+ it(`${obsoleteQueryName} should not log more than once`, () => {
+ let logCount = 0
+ cy.on('log:added', (attrs, log) => {
+ if (log.get('name') === obsoleteQueryName) {
+ logCount = logCount + 1
+ }
+ })
- const errorMessage = `Unable to find an element with the text: New Page Loaded.`
- cy.on('fail', err => {
- expect(err.message).to.contain(errorMessage)
- })
-
- cy.queryByText('New Page Loaded', { timeout: 300 }).should('exist')
- })
+ cy.on('fail', _ => {
+ expect(logCount).to.equal(1)
+ cy.removeAllListeners('log:added')
+ })
- it('query* in container', () => {
- return cy.get('#nested')
- .then(subject => {
- cy.queryByText(/^Button Text/, {container: subject}).click()
+ cy[`${obsoleteQueryName}`]('Irrelevant')
})
- })
-
- it('queryByText can return no result, and should not error', () => {
- const text = 'Supercalifragilistic'
-
- cy.queryByText(text, {timeout: 100})
- .should('have.length', 0)
- .and('not.exist')
- })
-
- it('queryAllByText can return no results message should not error', () => {
- const text = 'Supercalifragilistic'
-
- cy.queryAllByText(text, {timeout: 100})
- .should('have.length', 0)
- .and('not.exist')
- })
-
- it('queryAllByText should forward existence error message from @testing-library/dom', () => {
- const text = 'Supercalifragilistic'
- const errorMessage = `Unable to find an element with the text: Supercalifragilistic.`
- cy.on('fail', err => {
- expect(err.message).to.contain(errorMessage)
})
-
- cy.queryAllByText(text, {timeout: 100}).should('exist')
- })
-
- it('queryByLabelText should forward useful error messages from @testing-library/dom', () => {
- const errorMessage = `Found a label with the text of: Label 3, however no form control was found associated to that label.`
- cy.on('fail', err => {
- expect(err.message).to.contain(errorMessage)
- })
-
- cy.queryByLabelText('Label 3', {timeout: 100}).should('exist')
- })
-
- it('queryAllByText should default to Cypress non-existence error message', () => {
- const errorMessage = `Expected