diff --git a/.eslintrc.js b/.eslintrc.js index 1c42e00ba5881f..938608a89b1883 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -26,7 +26,7 @@ const majorMinorRegExp = */ const developmentFiles = [ '**/benchmark/**/*.js', - '**/@(__mocks__|__tests__|test)/**/*.js', + '**/@(__mocks__|__tests__|test)/**/*.{js,ts,tsx}', '**/@(storybook|stories)/**/*.js', 'packages/babel-preset-default/bin/**/*.js', ]; diff --git a/packages/components/src/text/test/__snapshots__/index.js.snap b/packages/components/src/text/test/__snapshots__/index.tsx.snap similarity index 75% rename from packages/components/src/text/test/__snapshots__/index.js.snap rename to packages/components/src/text/test/__snapshots__/index.tsx.snap index 054a5522837431..2d962f51c74f65 100644 --- a/packages/components/src/text/test/__snapshots__/index.js.snap +++ b/packages/components/src/text/test/__snapshots__/index.tsx.snap @@ -1,5 +1,21 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Text should render align 1`] = ` +Snapshot Diff: +- Received styles ++ Base styles + +@@ -3,7 +3,8 @@ + "color": "#1e1e1e", + "font-size": "calc((13 / 13) * 13px)", + "font-weight": "normal", + "line-height": "1.2", + "margin": "0", ++ "text-align": "center", + }, + ] +`; + exports[`Text should render highlighted words with highlightCaseSensitive 1`] = ` .emotion-0 { color: #1e1e1e; diff --git a/packages/components/src/text/test/index.js b/packages/components/src/text/test/index.tsx similarity index 88% rename from packages/components/src/text/test/index.js rename to packages/components/src/text/test/index.tsx index ca51ddad141876..c5dc40f0ae8958 100644 --- a/packages/components/src/text/test/index.js +++ b/packages/components/src/text/test/index.tsx @@ -59,14 +59,20 @@ describe( 'Text', () => { test( 'should render as another element', () => { const { container } = render( Lorem ipsum. ); - expect( container.firstChild.nodeName ).toBe( 'DIV' ); + expect( container.firstChild?.nodeName ).toBe( 'DIV' ); } ); test( 'should render align', () => { - const { container } = render( + const { container: centerAlignedContainer } = render( Lorem ipsum. ); - expect( container.firstChild ).toHaveStyle( { textAlign: 'center' } ); + const { container: defaultAlignedContainer } = render( + Lorem ipsum. + ); + + expect( + defaultAlignedContainer.children[ 0 ] + ).toMatchStyleDiffSnapshot( centerAlignedContainer.children[ 0 ] ); } ); test( 'should render color', () => { @@ -89,7 +95,7 @@ describe( 'Text', () => { const wrapper = render( Lorem ipsum. ); - expect( wrapper.container.firstChild.childNodes ).toHaveLength( 5 ); + expect( wrapper.container.firstChild?.childNodes ).toHaveLength( 5 ); const words = await wrapper.findAllByText( 'm' ); expect( words ).toHaveLength( 2 ); words.forEach( ( word ) => expect( word.tagName ).toEqual( 'MARK' ) ); @@ -100,7 +106,7 @@ describe( 'Text', () => { Lorem ipsum. ); // It'll have a length of 1 because there shouldn't be anything but the single span being rendered. - expect( container.firstChild.childNodes ).toHaveLength( 1 ); + expect( container.firstChild?.childNodes ).toHaveLength( 1 ); } ); test( 'should render highlighted words with highlightCaseSensitive', () => { @@ -112,7 +118,7 @@ describe( 'Text', () => { expect( container.firstChild ).toMatchSnapshot(); // It'll have a length of 1 because there shouldn't be anything but the single span being rendered. - expect( container.firstChild.childNodes ).toHaveLength( 1 ); + expect( container.firstChild?.childNodes ).toHaveLength( 1 ); } ); test( 'should render isBlock', () => { diff --git a/packages/components/tsconfig.json b/packages/components/tsconfig.json index 53f2fde0352449..8f8b6c412715d0 100644 --- a/packages/components/tsconfig.json +++ b/packages/components/tsconfig.json @@ -3,7 +3,13 @@ "compilerOptions": { "rootDir": "src", "declarationDir": "build-types", - "types": [ "gutenberg-env" ], + "types": [ + "gutenberg-env", + "gutenberg-test-env", + "jest", + "@testing-library/jest-dom", + "snapshot-diff", + ], // Some errors in Reakit types with TypeScript 4.3 // Remove the following line when they've been addressed. "skipLibCheck": true, @@ -90,7 +96,7 @@ "src/**/*.native.js", "src/**/react-native-*", "src/**/stories/**.js", // only exclude js files, tsx files should be checked - "src/**/test", + "src/**/test/**.js", // only exclude js files, ts{x} files should be checked "src/ui/__storybook-utils", "src/ui/font-size-control" ] diff --git a/test/unit/config/matchers/to-match-style-diff-snapshot.js b/test/unit/config/matchers/to-match-style-diff-snapshot.js index 7c810aad1736ff..c0f31d6be62a2c 100644 --- a/test/unit/config/matchers/to-match-style-diff-snapshot.js +++ b/test/unit/config/matchers/to-match-style-diff-snapshot.js @@ -8,7 +8,7 @@ const getStyleSheets = () => /** * - * @param {Element} element + * @param {Element | null} element * @param {HTMLStyleElement[]} styleSheets */ const getStyleRulesForElement = ( element, styleSheets ) => { @@ -17,7 +17,7 @@ const getStyleRulesForElement = ( element, styleSheets ) => { try { Array.from( styleSheet.sheet.cssRules ).forEach( ( rule ) => { - if ( element.matches( rule.selectorText ) ) { + if ( element?.matches( rule.selectorText ) ) { found.push( rule.style ); } } ); @@ -58,9 +58,9 @@ const cleanStyleRule = ( rule ) => { }; /** - * @param {Element} received - * @param {Element} expected - * @param {string} testName + * @param {Element | null} received + * @param {Element | null} expected + * @param {string} testName */ function toMatchStyleDiffSnapshot( received, expected, testName ) { const styleSheets = getStyleSheets(); diff --git a/typings/gutenberg-test-env/index.d.ts b/typings/gutenberg-test-env/index.d.ts new file mode 100644 index 00000000000000..ea575406ca1f67 --- /dev/null +++ b/typings/gutenberg-test-env/index.d.ts @@ -0,0 +1,18 @@ +declare namespace jest { + interface Matchers< R > { + /** + * Similar to the [`toMatchDiffSnapshot` matcher], this custom matcher + * allows to snapshot only the difference between the _styles_ associated + * with different states of a component. + * + * @see [to-match-style-diff-snapshot.js] + * @see [Testing Overview docs] + * @cite https://github.com/testing-library/react-testing-library/issues/36#issuecomment-440442300 + * + * [`toMatchDiffSnapshot` matcher]: https://github.com/jest-community/snapshot-diff + * [to-match-style-diff-snapshot.js]: https://github.com/WordPress/gutenberg/blob/trunk/test/unit/config/matchers/to-match-style-diff-snapshot.js + * [Testing Overview docs]: https://github.com/WordPress/gutenberg/blob/trunk/docs/contributors/code/testing-overview.md#best-practices + */ + toMatchStyleDiffSnapshot( expected: Element | null ): R; + } +}