Skip to content

feat(within): Support cy.within #11

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
Jun 5, 2018
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
3 changes: 2 additions & 1 deletion .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
"contributions": [
"code",
"doc",
"ideas"
"ideas",
"test"
]
}
],
Expand Down
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,16 @@ cy.getAllByText('Jackie Chan').click()
cy.queryByText('Button Text').should('exist')
cy.queryByText('Non-existing Button Text').should('not.exist')
cy.queryByLabelText('Label text', { timeout: 7000 }).should('exist')
cy.get('form').within(() => {
cy.getByText('Button Text').should('exist')
})
cy.get('form').then((subject) => {
cy.getByText('Button Text', { container: subject }).should('exist')
})
```

`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.

## Other Solutions

I'm not aware of any, if you are please [make a pull request][prs] and add it
Expand All @@ -87,7 +95,7 @@ Thanks goes to these people ([emoji key][emojis]):

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore -->
| [<img src="https://avatars.githubusercontent.com/u/1500684?v=3" width="100px;"/><br /><sub><b>Kent C. Dodds</b></sub>](https://kentcdodds.com)<br />[💻](https://github.com/kentcdodds/cypress-testing-library/commits?author=kentcdodds "Code") [📖](https://github.com/kentcdodds/cypress-testing-library/commits?author=kentcdodds "Documentation") [🚇](#infra-kentcdodds "Infrastructure (Hosting, Build-Tools, etc)") [⚠️](https://github.com/kentcdodds/cypress-testing-library/commits?author=kentcdodds "Tests") | [<img src="https://avatars2.githubusercontent.com/u/498274?v=4" width="100px;"/><br /><sub><b>Ivan Babak</b></sub>](https://sompylasar.github.io)<br />[💻](https://github.com/kentcdodds/cypress-testing-library/commits?author=sompylasar "Code") [🤔](#ideas-sompylasar "Ideas, Planning, & Feedback") | [<img src="https://avatars1.githubusercontent.com/u/4002543?v=4" width="100px;"/><br /><sub><b>Łukasz Gandecki</b></sub>](http://team.thebrain.pro)<br />[💻](https://github.com/kentcdodds/cypress-testing-library/commits?author=lgandecki "Code") [⚠️](https://github.com/kentcdodds/cypress-testing-library/commits?author=lgandecki "Tests") | [<img src="https://avatars1.githubusercontent.com/u/25429764?v=4" width="100px;"/><br /><sub><b>Peter Kamps</b></sub>](https://github.com/npeterkamps)<br />[💻](https://github.com/kentcdodds/cypress-testing-library/commits?author=npeterkamps "Code") [📖](https://github.com/kentcdodds/cypress-testing-library/commits?author=npeterkamps "Documentation") [🤔](#ideas-npeterkamps "Ideas, Planning, & Feedback") |
| [<img src="https://avatars.githubusercontent.com/u/1500684?v=3" width="100px;"/><br /><sub><b>Kent C. Dodds</b></sub>](https://kentcdodds.com)<br />[💻](https://github.com/kentcdodds/cypress-testing-library/commits?author=kentcdodds "Code") [📖](https://github.com/kentcdodds/cypress-testing-library/commits?author=kentcdodds "Documentation") [🚇](#infra-kentcdodds "Infrastructure (Hosting, Build-Tools, etc)") [⚠️](https://github.com/kentcdodds/cypress-testing-library/commits?author=kentcdodds "Tests") | [<img src="https://avatars2.githubusercontent.com/u/498274?v=4" width="100px;"/><br /><sub><b>Ivan Babak</b></sub>](https://sompylasar.github.io)<br />[💻](https://github.com/kentcdodds/cypress-testing-library/commits?author=sompylasar "Code") [🤔](#ideas-sompylasar "Ideas, Planning, & Feedback") | [<img src="https://avatars1.githubusercontent.com/u/4002543?v=4" width="100px;"/><br /><sub><b>Łukasz Gandecki</b></sub>](http://team.thebrain.pro)<br />[💻](https://github.com/kentcdodds/cypress-testing-library/commits?author=lgandecki "Code") [⚠️](https://github.com/kentcdodds/cypress-testing-library/commits?author=lgandecki "Tests") | [<img src="https://avatars1.githubusercontent.com/u/25429764?v=4" width="100px;"/><br /><sub><b>Peter Kamps</b></sub>](https://github.com/npeterkamps)<br />[💻](https://github.com/kentcdodds/cypress-testing-library/commits?author=npeterkamps "Code") [📖](https://github.com/kentcdodds/cypress-testing-library/commits?author=npeterkamps "Documentation") [🤔](#ideas-npeterkamps "Ideas, Planning, & Feedback") [⚠️](https://github.com/kentcdodds/cypress-testing-library/commits?author=npeterkamps "Tests") |
| :---: | :---: | :---: | :---: |
<!-- ALL-CONTRIBUTORS-LIST:END -->

Expand Down
4 changes: 4 additions & 0 deletions cypress/fixtures/test-app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ <h2>getByPlaceholderText</h2>
<section>
<h2>getByText</h2>
<button onclick="this.innerText = 'Button Clicked'">Button Text</button>
<div id="nested">
<h3>getByText within</h3>
<button onclick="this.innerText = 'Button Clicked'">Button Text</button>
</div>
</section>
<section>
<h2>getByLabelText</h2>
Expand Down
14 changes: 14 additions & 0 deletions cypress/integration/commands.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@ describe('dom-testing-library commands', () => {
cy.queryByText('Button Text').should('exist')
cy.queryByText('Non-existing Button Text').should('not.exist')
})

it('getByText within', () => {
cy.get('#nested')
.within(() => {
cy.getByText('Button Text').click()
})
})

it('getByText in container', () => {
cy.get('#nested')
.then((subject) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear from the documentation https://docs.cypress.io/api/commands/then.html#DOM-element , but as I remember, .then callback gets a jQuery collection in its first argument, not a single DOM element. Could you please verify this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see, you use Cypress.dom.isJquery(element) to accept both jQuery collection and a single element as the container. This wasn't the case before, so likely requires a documentation update where the container option type is described.

cy.getByText('Button Text', { container: subject }).click()
})
})
})

/* global cy */
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
"test": "npm-run-all --parallel test:unit test:cypress",
"test:unit": "kcd-scripts test --no-watch",
"test:unit:watch": "kcd-scripts test",
"test:cypress:serve": "serve -l 13370 ./cypress/fixtures/test-app",
"test:cypress:run": "cypress run",
"test:cypress:serve": "serve --listen 13370 ./cypress/fixtures/test-app",
"test:cypress:run": "wait-port --timeout 10000 localhost:13370 && cypress run",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

"test:cypress:open": "cypress open",
"test:cypress": "npm-run-all --silent --parallel --race test:cypress:serve test:cypress:run",
"test:cypress:dev": "npm-run-all --silent --parallel --race test:cypress:serve test:cypress:open",
Expand Down Expand Up @@ -45,7 +45,8 @@
"cypress": "^3.0.1",
"kcd-scripts": "^0.37.0",
"npm-run-all": "^4.1.2",
"serve": "^7.2.0"
"serve": "^7.2.0",
"wait-port": "^0.2.2"
},
"peerDependencies": {
"cypress": "^2.1.0 || ^3.0.0"
Expand Down
4 changes: 2 additions & 2 deletions src/add-commands.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {commands} from './'

commands.forEach(({name, command}) => {
Cypress.Commands.add(name, command.bind(null, cy))
Cypress.Commands.add(name, command)
})

/* global Cypress, cy */
/* global Cypress */
13 changes: 8 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {queries, waitForElement} from 'dom-testing-library'
import {getContainer} from './utils'

const defaults = {
timeout: 3000,
Expand All @@ -7,17 +8,19 @@ const defaults = {
const commands = Object.keys(queries).map(queryName => {
return {
name: queryName,
command: (cy, ...args) => {
command: (...args) => {
const lastArg = args[args.length - 1]
const waitOptions = (typeof lastArg === 'object')
? Object.assign({}, defaults, lastArg)
: defaults

const queryImpl = queries[queryName]
const baseCommandImpl = doc =>
waitForElement(() => queryImpl(doc, ...args), Object.assign({}, waitOptions, {
container: doc,
const baseCommandImpl = doc => {
const container = getContainer(waitOptions.container || doc);
return waitForElement(() => queryImpl(container, ...args), Object.assign({}, waitOptions, {
container,
}))
}
let commandImpl
if (
queryName.startsWith('queryBy') ||
Expand Down Expand Up @@ -64,4 +67,4 @@ const commands = Object.keys(queries).map(queryName => {
export {commands}

/* eslint no-new-func:0 */
/* globals Cypress */
/* globals Cypress, cy */
21 changes: 21 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
function getFirstElement(jqueryOrElement) {
if (Cypress.dom.isJquery(jqueryOrElement)) {
return jqueryOrElement.get(0)
}
return jqueryOrElement
}

function getContainer(container) {
const withinContainer = cy.state('withinSubject')
if (withinContainer) {
return getFirstElement(withinContainer)
}
return getFirstElement(container)
}

export {
getFirstElement,
getContainer,
}

/* globals Cypress, cy */