From c67414de3d9e09b4db256d253a51d17daa6a6cc5 Mon Sep 17 00:00:00 2001 From: Nicholas Boll Date: Thu, 30 Jan 2020 10:13:14 -0700 Subject: [PATCH 1/7] feat: add more helpful debugging information to queries * Add element selector information for debugging (outlines element when you click on command) (fixes #103) * Add @testing-library/dom errors (from `get*` queries) to failure messages - these are more helpful than the generic `find*('input') does not exist` messages (fixes #103) * Add retryability to `findBy*` when multiple elements are found (fixes #83) * Add option to disable logging of all commands * `query*` and `find*` have a consistent code path and error messaging (fixes #103) * Remove usage of Cypress commands in queries (fixes #103) --- README.md | 35 ++++++- cypress/fixtures/test-app/index.html | 21 ++++ cypress/integration/find.spec.js | 63 +++++++++++- cypress/integration/query.spec.js | 57 +++++++++-- package.json | 2 +- src/index.js | 139 ++++++++++++++++++--------- 6 files changed, 250 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index ba56524..eaf7cfc 100644 --- a/README.md +++ b/README.md @@ -109,24 +109,49 @@ 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)): ```javascript -cy.queryByText('Button Text').should('exist') -cy.queryByText('Non-existing Button Text').should('not.exist') -cy.queryByLabelText('Label text', {timeout: 7000}).should('exist') +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({multiple: true}) + +// findAllByText _inside_ a form element cy.get('form').within(() => { - cy.findByText('Button Text').should('exist') + cy.findAllByText('Button Text').should('exist') }) cy.get('form').then(subject => { - cy.findByText('Button Text', {container: subject}).should('exist') + cy.findAllByText('Button Text', {container: subject}).should('exist') }) +cy.get('form').findAllByText('Button Text').should('exist') ``` +### Differences 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. + +`findBy*` is less useful in Cypress compared to `findAllBy*`. If you intend to limit +to only 1 element, the following will work: + +```javascript +cy.findAllByText('Some Text').should('have.length', 1) +``` + +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() +``` + ## Other Solutions I'm not aware of any, if you are please [make a pull request][prs] and add it diff --git a/cypress/fixtures/test-app/index.html b/cypress/fixtures/test-app/index.html index 42a4b7e..36a3fc3 100644 --- a/cypress/fixtures/test-app/index.html +++ b/cypress/fixtures/test-app/index.html @@ -29,6 +29,9 @@

*ByLabel and *ByPlaceholder

+ +

Intentionally inaccessible label for error checking

+

*ByText

@@ -89,6 +92,24 @@

*AllByText

*ByText on another page

Next Page
+
+

Eventual existence

+ + +
+
+

Eventual non-existence

+ + +