Skip to content

Release Beta #458

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 5 commits into from
Mar 12, 2020
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: 1 addition & 2 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
* text=auto
*.js text eol=lf
* text=auto eol=lf
5 changes: 0 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
node_modules
coverage
dist
.opt-in
.opt-out
.DS_Store
.eslintcache
yarn-error.log
.idea/

# these cause more harm than good
# when working with contributors
Expand Down
3 changes: 1 addition & 2 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
package.json
node_modules
dist
coverage
dist
11 changes: 0 additions & 11 deletions .prettierrc

This file was deleted.

1 change: 1 addition & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('kcd-scripts/prettier')
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ cache: npm
notifications:
email: false
node_js:
- 10.14
- 10.18
- 12
- node
install: npm install
Expand All @@ -13,7 +13,6 @@ script:
branches:
only:
- master
- next
- beta

jobs:
Expand Down
19 changes: 9 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@
"end-to-end",
"e2e"
],
"author": "Kent C. Dodds <[email protected]> (https://kentcdodds.com/)",
"author": "Kent C. Dodds <[email protected]> (https://kentcdodds.com)",
"license": "MIT",
"engines": {
"node": ">=8"
"node": ">=10.18"
},
"scripts": {
"build": "kcd-scripts build --ignore \"**/__tests__/**,**/__node_tests__/**,**/__mocks__/**\" && kcd-scripts build --bundle --no-clean",
"lint": "kcd-scripts lint",
"setup": "npm install && npm run validate -s",
"test": "kcd-scripts test",
"test:update": "npm test -- --updateSnapshot --coverage",
"test:debug": "node --inspect-brk ./node_modules/.bin/jest --watch --runInBand",
"validate": "kcd-scripts validate",
"setup": "npm install && npm run validate -s"
"test:update": "npm test -- --updateSnapshot --coverage",
"validate": "kcd-scripts validate"
},
"husky": {
"hooks": {
Expand All @@ -41,12 +41,10 @@
],
"dependencies": {
"@babel/runtime": "^7.8.4",
"@sheerun/mutationobserver-shim": "^0.3.2",
"@types/testing-library__dom": "^6.12.1",
"aria-query": "^4.0.2",
"dom-accessibility-api": "^0.3.0",
"pretty-format": "^25.1.0",
"wait-for-expect": "^3.0.2"
"pretty-format": "^25.1.0"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.1.1",
Expand All @@ -61,7 +59,8 @@
"rules": {
"import/prefer-default-export": "off",
"import/no-unassigned-import": "off",
"import/no-useless-path-segments": "off"
"import/no-useless-path-segments": "off",
"no-console": "off"
Copy link
Contributor

@weyert weyert Mar 4, 2020

Choose a reason for hiding this comment

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

Any reason why you globally disable no-console-rule? I am curious if you couldn't disable for only the specific files?

Copy link
Member Author

Choose a reason for hiding this comment

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

I did and it was annoying.

Copy link
Member

Choose a reason for hiding this comment

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

Once of those things where I'd like a different set of rules for local dev. Basically a set of rules for prod and dev. Because we do like to catch dangling debug statements but we do sometimes need them for debugging locally.

}
},
"eslintIgnore": [
Expand All @@ -71,7 +70,7 @@
],
"repository": {
"type": "git",
"url": "https://github.com/testing-library/dom-testing-library.git"
"url": "https://github.com/testing-library/dom-testing-library"
},
"bugs": {
"url": "https://github.com/testing-library/dom-testing-library/issues"
Expand Down
69 changes: 68 additions & 1 deletion src/__tests__/element-queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ test('can get elements labelled with aria-labelledby attribute', () => {
expect(getByLabelText('Section One').id).toBe('section-one')
})

test('can get sibling elements with aria-labelledby attrib ute', () => {
test('can get sibling elements with aria-labelledby attribute', () => {
const {getAllByLabelText} = render(`
<div>
<svg id="icon" aria-labelledby="icon-desc"></svg>
Expand All @@ -212,6 +212,73 @@ test('can get sibling elements with aria-labelledby attrib ute', () => {
expect(result[0].id).toBe('icon')
})

test('can filter results of label query based on selector', () => {
const {getAllByLabelText} = render(`
<div>
<label id="label1" for="input1">
Test Label
<input id="input2" />
</label>
<input id="input1" class="fancy-input" />
<span aria-labelledby="label1">Some hint text</span>
</div>
`)

const result = getAllByLabelText('Test Label', {selector: '.fancy-input'})
expect(result).toHaveLength(1)
expect(result[0].id).toBe('input1')
})

test('can find any form control when label text is inside other elements', () => {
const {getAllByLabelText} = render(`
<label>
<span>Test</span>
<span>Label</span>
<button />
<input />
<meter />
<output />
<progress />
<select />
<textarea />
</label>
`)

const result = getAllByLabelText('Test Label')
expect(result).toHaveLength(7)
})

test('can find non-input elements when aria-labelledby a label', () => {
const {getAllByLabelText} = render(`
<div>
<label id="label1">Test Label</label>
<ul aria-labelledby="label1">
<li>Hello</li>
</ul
</div>
`)

const result = getAllByLabelText('Test Label')
expect(result).toHaveLength(1)
expect(result[0].nodeName).toBe('UL')
})

test('can find the correct element when there are multiple matching labels', () => {
const {getByLabelText} = render(`
<label>
Test Label
<input />
</label>
<label>
Test Label
<textarea></textarea>
</label>
`)

const result = getByLabelText('Test Label', {selector: 'input'})
expect(result.nodeName).toBe('INPUT')
})

test('get can get form controls by placeholder', () => {
const {getByPlaceholderText} = render(`
<input id="username-id" placeholder="username" />,
Expand Down
52 changes: 52 additions & 0 deletions src/__tests__/fake-timers.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jest.useFakeTimers()
jest.resetModules()

const {
wait,
waitForElement,
waitForDomChange,
waitForElementToBeRemoved,
Expand All @@ -42,6 +43,15 @@ test('waitForElementToBeRemoved: times out after 4500ms by default', () => {
return promise
})

test('wait: can time out', async () => {
const promise = wait(() => {
// eslint-disable-next-line no-throw-literal
throw undefined
})
jest.advanceTimersByTime(4600)
await expect(promise).rejects.toThrow(/timed out/i)
})

test('waitForElement: can time out', async () => {
const promise = waitForElement(() => {})
jest.advanceTimersByTime(4600)
Expand Down Expand Up @@ -85,3 +95,45 @@ test('waitForDomChange: can specify our own timeout time', async () => {
// timed out
await expect(promise).rejects.toThrow(/timed out/i)
})

test('wait: ensures the interval is greater than 0', async () => {
// Arrange
const spy = jest.fn()
spy.mockImplementationOnce(() => {
throw new Error('first time does not work')
})
const promise = wait(spy, {interval: 0})
expect(spy).toHaveBeenCalledTimes(1)
spy.mockClear()

// Act
// this line will throw an error if wait does not make the interval 1 instead of 0
// which is why it does that!
jest.advanceTimersByTime(0)

// Assert
expect(spy).toHaveBeenCalledTimes(0)
spy.mockImplementationOnce(() => 'second time does work')

// Act
jest.advanceTimersByTime(1)
await promise

// Assert
expect(spy).toHaveBeenCalledTimes(1)
})

test('wait: times out if it runs out of attempts', () => {
const spy = jest.fn(() => {
throw new Error('example error')
})
// there's a bug with this rule here...
// eslint-disable-next-line jest/valid-expect
const promise = expect(
wait(spy, {interval: 1, timeout: 3}),
).rejects.toThrowErrorMatchingInlineSnapshot(`"example error"`)
jest.advanceTimersByTime(1)
jest.advanceTimersByTime(1)
jest.advanceTimersByTime(1)
return promise
})
27 changes: 1 addition & 26 deletions src/__tests__/helpers.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,5 @@
import {getDocument, newMutationObserver} from '../helpers'
import {getDocument} from '../helpers'

test('returns global document if exists', () => {
expect(getDocument()).toBe(document)
})

class DummyClass {
constructor(args) {
this.args = args
}
}

describe('newMutationObserver', () => {
if (typeof window === 'undefined') {
it('instantiates mock MutationObserver if not availble on window', () => {
expect(newMutationObserver(() => {}).observe).toBeDefined()
})
} else {
it('instantiates from global MutationObserver if available', () => {
const oldMutationObserver = window.MutationObserver
window.MutationObserver = DummyClass

try {
expect(newMutationObserver('foobar').args).toEqual('foobar')
} finally {
window.MutationObserver = oldMutationObserver
}
})
}
})
2 changes: 0 additions & 2 deletions src/__tests__/pretty-dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,3 @@ describe('prettyDOM fails with first parameter without outerHTML field', () => {
)
})
})

/* eslint no-console:0 */
2 changes: 0 additions & 2 deletions src/__tests__/role-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,5 +184,3 @@ test.each([

expect(isInaccessible(container.querySelector('button'))).toBe(expected)
})

/* eslint no-console:0 */
2 changes: 0 additions & 2 deletions src/__tests__/screen.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,3 @@ test('exposes debug method', () => {
`)
console.log.mockClear()
})

/* eslint no-console:0 */
8 changes: 8 additions & 0 deletions src/__tests__/wait-for-dom-change.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ beforeEach(() => {
jest.useRealTimers()
jest.resetModules()
waitForDomChange = importModule()
console.warn.mockClear()
})

test('waits for the dom to change in the document', async () => {
Expand All @@ -34,6 +35,13 @@ test('waits for the dom to change in the document', async () => {
},
]
`)
expect(console.warn.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"\`waitForDomChange\` has been deprecated. Use \`wait\` instead: https://testing-library.com/docs/dom-testing-library/api-async#waitfor.",
],
]
`)
})

test('waits for the dom to change in a specified container', async () => {
Expand Down
Loading