-
Notifications
You must be signed in to change notification settings - Fork 470
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BREAKING CHANGE: Remove deprecated `waitFormDOMChange` BREAKING CHANGE: Remove deprecated `waitForElement` BREAKING CHANGE: The `timeout` in `waitFor(callback, { interval, timeout } )` now uses the same clock as `interval`. Previously `timeout` was always using the real clock while `interval` was using the global clock which could've been mocked out. For the old behavior I'd recommend `waitFor(callback, { interval, timeout: Number.POSITIVE_INFINITY })` and rely on your test runner to timeout considering real timers. BREAKING CHANGE: `<script />`, `<style />` and comment nodes are now ignored by default in `prettyDOM` .If you whish to return to the old behavior, use a custom `filterNode` function. In this case `prettyDOM(element, { filterNode: () => true })`. BREAKING CHANGE: node 10 is no longer supported. It reached its end-of-life on 30.04.2021. Co-authored-by: Tim Deschryver <[email protected]>
- Loading branch information
1 parent
56a4c75
commit d347302
Showing
46 changed files
with
798 additions
and
792 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
{ | ||
"sandboxes": ["github/kentcdodds/react-testing-library-examples"] | ||
"sandboxes": ["github/kentcdodds/react-testing-library-examples"], | ||
"node": "12" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,7 @@ | |
"author": "Kent C. Dodds <[email protected]> (https://kentcdodds.com)", | ||
"license": "MIT", | ||
"engines": { | ||
"node": ">=10" | ||
"node": ">=12" | ||
}, | ||
"scripts": { | ||
"build": "kcd-scripts build --no-ts-defs --ignore \"**/__tests__/**,**/__node_tests__/**,**/__mocks__/**\" && kcd-scripts build --no-ts-defs --bundle --no-clean", | ||
|
@@ -46,15 +46,15 @@ | |
"chalk": "^4.1.0", | ||
"dom-accessibility-api": "^0.5.6", | ||
"lz-string": "^1.4.4", | ||
"pretty-format": "^26.6.2" | ||
"pretty-format": "^27.0.2" | ||
}, | ||
"devDependencies": { | ||
"@testing-library/jest-dom": "^5.11.6", | ||
"jest-in-case": "^1.0.2", | ||
"jest-serializer-ansi": "^1.0.3", | ||
"jest-watch-select-projects": "^2.0.0", | ||
"jsdom": "^16.4.0", | ||
"kcd-scripts": "^7.5.3", | ||
"kcd-scripts": "^11.0.0", | ||
"typescript": "^4.1.2" | ||
}, | ||
"eslintConfig": { | ||
|
@@ -63,6 +63,7 @@ | |
"plugin:import/typescript" | ||
], | ||
"rules": { | ||
"@typescript-eslint/prefer-includes": "off", | ||
"import/prefer-default-export": "off", | ||
"import/no-unassigned-import": "off", | ||
"import/no-useless-path-segments": "off", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,261 @@ | ||
/** | ||
* Source: https://github.com/facebook/jest/blob/e7bb6a1e26ffab90611b2593912df15b69315611/packages/pretty-format/src/plugins/DOMElement.ts | ||
*/ | ||
/* eslint-disable -- trying to stay as close to the original as possible */ | ||
/* istanbul ignore file */ | ||
import type {Config, NewPlugin, Printer, Refs} from 'pretty-format' | ||
|
||
function escapeHTML(str: string): string { | ||
return str.replace(/</g, '<').replace(/>/g, '>') | ||
} | ||
// Return empty string if keys is empty. | ||
const printProps = ( | ||
keys: Array<string>, | ||
props: Record<string, unknown>, | ||
config: Config, | ||
indentation: string, | ||
depth: number, | ||
refs: Refs, | ||
printer: Printer, | ||
): string => { | ||
const indentationNext = indentation + config.indent | ||
const colors = config.colors | ||
return keys | ||
.map(key => { | ||
const value = props[key] | ||
let printed = printer(value, config, indentationNext, depth, refs) | ||
|
||
if (typeof value !== 'string') { | ||
if (printed.indexOf('\n') !== -1) { | ||
printed = | ||
config.spacingOuter + | ||
indentationNext + | ||
printed + | ||
config.spacingOuter + | ||
indentation | ||
} | ||
printed = '{' + printed + '}' | ||
} | ||
|
||
return ( | ||
config.spacingInner + | ||
indentation + | ||
colors.prop.open + | ||
key + | ||
colors.prop.close + | ||
'=' + | ||
colors.value.open + | ||
printed + | ||
colors.value.close | ||
) | ||
}) | ||
.join('') | ||
} | ||
|
||
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType#node_type_constants | ||
const NodeTypeTextNode = 3 | ||
|
||
// Return empty string if children is empty. | ||
const printChildren = ( | ||
children: Array<unknown>, | ||
config: Config, | ||
indentation: string, | ||
depth: number, | ||
refs: Refs, | ||
printer: Printer, | ||
): string => | ||
children | ||
.map(child => { | ||
const printedChild = | ||
typeof child === 'string' | ||
? printText(child, config) | ||
: printer(child, config, indentation, depth, refs) | ||
|
||
if ( | ||
printedChild === '' && | ||
typeof child === 'object' && | ||
child !== null && | ||
(child as Node).nodeType !== NodeTypeTextNode | ||
) { | ||
// A plugin serialized this Node to '' meaning we should ignore it. | ||
return '' | ||
} | ||
return config.spacingOuter + indentation + printedChild | ||
}) | ||
.join('') | ||
|
||
const printText = (text: string, config: Config): string => { | ||
const contentColor = config.colors.content | ||
return contentColor.open + escapeHTML(text) + contentColor.close | ||
} | ||
|
||
const printComment = (comment: string, config: Config): string => { | ||
const commentColor = config.colors.comment | ||
return ( | ||
commentColor.open + | ||
'<!--' + | ||
escapeHTML(comment) + | ||
'-->' + | ||
commentColor.close | ||
) | ||
} | ||
|
||
// Separate the functions to format props, children, and element, | ||
// so a plugin could override a particular function, if needed. | ||
// Too bad, so sad: the traditional (but unnecessary) space | ||
// in a self-closing tagColor requires a second test of printedProps. | ||
const printElement = ( | ||
type: string, | ||
printedProps: string, | ||
printedChildren: string, | ||
config: Config, | ||
indentation: string, | ||
): string => { | ||
const tagColor = config.colors.tag | ||
return ( | ||
tagColor.open + | ||
'<' + | ||
type + | ||
(printedProps && | ||
tagColor.close + | ||
printedProps + | ||
config.spacingOuter + | ||
indentation + | ||
tagColor.open) + | ||
(printedChildren | ||
? '>' + | ||
tagColor.close + | ||
printedChildren + | ||
config.spacingOuter + | ||
indentation + | ||
tagColor.open + | ||
'</' + | ||
type | ||
: (printedProps && !config.min ? '' : ' ') + '/') + | ||
'>' + | ||
tagColor.close | ||
) | ||
} | ||
|
||
const printElementAsLeaf = (type: string, config: Config): string => { | ||
const tagColor = config.colors.tag | ||
return ( | ||
tagColor.open + | ||
'<' + | ||
type + | ||
tagColor.close + | ||
' …' + | ||
tagColor.open + | ||
' />' + | ||
tagColor.close | ||
) | ||
} | ||
|
||
const ELEMENT_NODE = 1 | ||
const TEXT_NODE = 3 | ||
const COMMENT_NODE = 8 | ||
const FRAGMENT_NODE = 11 | ||
|
||
const ELEMENT_REGEXP = /^((HTML|SVG)\w*)?Element$/ | ||
|
||
const testNode = (val: any) => { | ||
const constructorName = val.constructor.name | ||
const {nodeType, tagName} = val | ||
const isCustomElement = | ||
(typeof tagName === 'string' && tagName.includes('-')) || | ||
(typeof val.hasAttribute === 'function' && val.hasAttribute('is')) | ||
|
||
return ( | ||
(nodeType === ELEMENT_NODE && | ||
(ELEMENT_REGEXP.test(constructorName) || isCustomElement)) || | ||
(nodeType === TEXT_NODE && constructorName === 'Text') || | ||
(nodeType === COMMENT_NODE && constructorName === 'Comment') || | ||
(nodeType === FRAGMENT_NODE && constructorName === 'DocumentFragment') | ||
) | ||
} | ||
|
||
export const test: NewPlugin['test'] = (val: any) => | ||
val?.constructor?.name && testNode(val) | ||
|
||
type HandledType = Element | Text | Comment | DocumentFragment | ||
|
||
function nodeIsText(node: HandledType): node is Text { | ||
return node.nodeType === TEXT_NODE | ||
} | ||
|
||
function nodeIsComment(node: HandledType): node is Comment { | ||
return node.nodeType === COMMENT_NODE | ||
} | ||
|
||
function nodeIsFragment(node: HandledType): node is DocumentFragment { | ||
return node.nodeType === FRAGMENT_NODE | ||
} | ||
|
||
export default function createDOMElementFilter( | ||
filterNode: (node: Node) => boolean, | ||
): NewPlugin { | ||
return { | ||
test: (val: any) => val?.constructor?.name && testNode(val), | ||
serialize: ( | ||
node: HandledType, | ||
config: Config, | ||
indentation: string, | ||
depth: number, | ||
refs: Refs, | ||
printer: Printer, | ||
) => { | ||
if (nodeIsText(node)) { | ||
return printText(node.data, config) | ||
} | ||
|
||
if (nodeIsComment(node)) { | ||
return printComment(node.data, config) | ||
} | ||
|
||
const type = nodeIsFragment(node) | ||
? `DocumentFragment` | ||
: node.tagName.toLowerCase() | ||
|
||
if (++depth > config.maxDepth) { | ||
return printElementAsLeaf(type, config) | ||
} | ||
|
||
return printElement( | ||
type, | ||
printProps( | ||
nodeIsFragment(node) | ||
? [] | ||
: Array.from(node.attributes) | ||
.map(attr => attr.name) | ||
.sort(), | ||
nodeIsFragment(node) | ||
? {} | ||
: Array.from(node.attributes).reduce<Record<string, string>>( | ||
(props, attribute) => { | ||
props[attribute.name] = attribute.value | ||
return props | ||
}, | ||
{}, | ||
), | ||
config, | ||
indentation + config.indent, | ||
depth, | ||
refs, | ||
printer, | ||
), | ||
printChildren( | ||
Array.prototype.slice | ||
.call(node.childNodes || node.children) | ||
.filter(filterNode), | ||
config, | ||
indentation + config.indent, | ||
depth, | ||
refs, | ||
printer, | ||
), | ||
config, | ||
indentation, | ||
) | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`getByLabelText query will throw the custom error returned by config.getElementError 1`] = `"My custom error: Unable to find a label with the text of: TEST QUERY"`; | ||
exports[`getByLabelText query will throw the custom error returned by config.getElementError 1`] = `My custom error: Unable to find a label with the text of: TEST QUERY`; | ||
|
||
exports[`getByText query will throw the custom error returned by config.getElementError 1`] = `"My custom error: Unable to find an element with the text: TEST QUERY. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible."`; | ||
exports[`getByText query will throw the custom error returned by config.getElementError 1`] = `My custom error: Unable to find an element with the text: TEST QUERY. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.`; |
Oops, something went wrong.