diff --git a/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json b/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json index 0a42b7d4cd1..e45cf8218e1 100644 --- a/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json +++ b/packages/react-scripts/fixtures/kitchensink/.template.dependencies.json @@ -1,12 +1,7 @@ { "dependencies": { - "@babel/plugin-transform-modules-commonjs": "7.0.0-beta.46", - "@babel/polyfill": "7.0.0-beta.46", - "@babel/register": "7.0.0-beta.46", - "bootstrap": "4.1.0", - "chai": "3.5.0", - "jsdom": "9.8.3", - "mocha": "3.2.0", + "bootstrap": "4.1.1", + "jest": "23.6.0", "node-sass": "4.8.3", "normalize.css": "7.0.0", "prop-types": "15.5.6", diff --git a/packages/react-scripts/fixtures/kitchensink/README.md b/packages/react-scripts/fixtures/kitchensink/README.md index 4e7725ce15f..0e64a76aed3 100644 --- a/packages/react-scripts/fixtures/kitchensink/README.md +++ b/packages/react-scripts/fixtures/kitchensink/README.md @@ -51,4 +51,3 @@ An usual flow for the test itself is something similar to: - since `initDOM` returns a `Document` element, the previous `id` attribute is used to target the feature's DOM and `expect` accordingly -These tests are run by **mocha** (why not **jest**? See [this issue](https://github.com/facebook/jest/issues/2288)) and the environments used are both `development` and `production`. diff --git a/packages/react-scripts/fixtures/kitchensink/integration/env.test.js b/packages/react-scripts/fixtures/kitchensink/integration/env.test.js index b1f5f5d5544..79de16706dc 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/env.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/env.test.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import { expect } from 'chai'; import initDOM from './initDOM'; describe('Integration', () => { @@ -15,23 +14,23 @@ describe('Integration', () => { expect( doc.getElementById('feature-file-env-original-1').textContent - ).to.equal('from-original-env-1'); + ).toBe('from-original-env-1'); expect( doc.getElementById('feature-file-env-original-2').textContent - ).to.equal('override-from-original-local-env-2'); + ).toBe('override-from-original-local-env-2'); if (process.env.NODE_ENV === 'production') { - expect(doc.getElementById('feature-file-env').textContent).to.equal( + expect(doc.getElementById('feature-file-env').textContent).toBe( 'production' ); - expect(doc.getElementById('feature-file-env-x').textContent).to.equal( + expect(doc.getElementById('feature-file-env-x').textContent).toBe( 'x-from-production-env' ); } else { - expect(doc.getElementById('feature-file-env').textContent).to.equal( + expect(doc.getElementById('feature-file-env').textContent).toBe( 'development' ); - expect(doc.getElementById('feature-file-env-x').textContent).to.equal( + expect(doc.getElementById('feature-file-env-x').textContent).toBe( 'x-from-development-env' ); } @@ -41,9 +40,7 @@ describe('Integration', () => { it('NODE_PATH', async () => { const doc = await initDOM('node-path'); - expect( - doc.getElementById('feature-node-path').childElementCount - ).to.equal(4); + expect(doc.getElementById('feature-node-path').childElementCount).toBe(4); doc.defaultView.close(); }); @@ -54,12 +51,12 @@ describe('Integration', () => { process.env.NODE_ENV === 'development' ? '' : 'http://www.example.org/spa'; - expect(doc.getElementById('feature-public-url').textContent).to.equal( + expect(doc.getElementById('feature-public-url').textContent).toBe( `${prefix}.` ); expect( doc.querySelector('head link[rel="shortcut icon"]').getAttribute('href') - ).to.equal(`${prefix}/favicon.ico`); + ).toBe(`${prefix}/favicon.ico`); doc.defaultView.close(); }); @@ -68,25 +65,25 @@ describe('Integration', () => { expect( doc.getElementById('feature-shell-env-variables').textContent - ).to.equal('fromtheshell.'); + ).toBe('fromtheshell.'); doc.defaultView.close(); }); it('expand .env variables', async () => { const doc = await initDOM('expand-env-variables'); - expect(doc.getElementById('feature-expand-env-1').textContent).to.equal( + expect(doc.getElementById('feature-expand-env-1').textContent).toBe( 'basic' ); - expect(doc.getElementById('feature-expand-env-2').textContent).to.equal( + expect(doc.getElementById('feature-expand-env-2').textContent).toBe( 'basic' ); - expect(doc.getElementById('feature-expand-env-3').textContent).to.equal( + expect(doc.getElementById('feature-expand-env-3').textContent).toBe( 'basic' ); expect( doc.getElementById('feature-expand-env-existing').textContent - ).to.equal('fromtheshell'); + ).toBe('fromtheshell'); doc.defaultView.close(); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js b/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js index 0ed5a940891..e807888d397 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js @@ -7,9 +7,8 @@ const fs = require('fs'); const http = require('http'); -const jsdom = require('jsdom'); +const jsdom = require('jsdom/lib/old-api.js'); const path = require('path'); -const { expect } = require('chai'); let getMarkup; export let resourceLoader; @@ -50,7 +49,7 @@ if (process.env.E2E_FILE) { it.only('can run jsdom (at least one of "E2E_FILE" or "E2E_URL" environment variables must be provided)', () => { expect( new Error("This isn't the error you are looking for.") - ).to.be.undefined(); + ).toBeUndefined(); }); } diff --git a/packages/react-scripts/fixtures/kitchensink/integration/syntax.test.js b/packages/react-scripts/fixtures/kitchensink/integration/syntax.test.js index 9e34b669d6e..54920726fa5 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/syntax.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/syntax.test.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import { expect } from 'chai'; import initDOM from './initDOM'; describe('Integration', () => { @@ -15,25 +14,25 @@ describe('Integration', () => { expect( doc.getElementById('feature-array-destructuring').childElementCount - ).to.equal(4); + ).toBe(4); doc.defaultView.close(); }); it('array spread', async () => { const doc = await initDOM('array-spread'); - expect( - doc.getElementById('feature-array-spread').childElementCount - ).to.equal(4); + expect(doc.getElementById('feature-array-spread').childElementCount).toBe( + 4 + ); doc.defaultView.close(); }); it('async/await', async () => { const doc = await initDOM('async-await'); - expect( - doc.getElementById('feature-async-await').childElementCount - ).to.equal(4); + expect(doc.getElementById('feature-async-await').childElementCount).toBe( + 4 + ); doc.defaultView.close(); }); @@ -42,7 +41,7 @@ describe('Integration', () => { expect( doc.getElementById('feature-class-properties').childElementCount - ).to.equal(4); + ).toBe(4); doc.defaultView.close(); }); @@ -51,7 +50,7 @@ describe('Integration', () => { expect( doc.getElementById('feature-computed-properties').childElementCount - ).to.equal(4); + ).toBe(4); doc.defaultView.close(); }); @@ -60,7 +59,7 @@ describe('Integration', () => { expect( doc.getElementById('feature-custom-interpolation').childElementCount - ).to.equal(4); + ).toBe(4); doc.defaultView.close(); }); @@ -69,7 +68,7 @@ describe('Integration', () => { expect( doc.getElementById('feature-default-parameters').childElementCount - ).to.equal(4); + ).toBe(4); doc.defaultView.close(); }); @@ -78,16 +77,16 @@ describe('Integration', () => { expect( doc.getElementById('feature-destructuring-and-await').childElementCount - ).to.equal(4); + ).toBe(4); doc.defaultView.close(); }); it('generators', async () => { const doc = await initDOM('generators'); - expect( - doc.getElementById('feature-generators').childElementCount - ).to.equal(4); + expect(doc.getElementById('feature-generators').childElementCount).toBe( + 4 + ); doc.defaultView.close(); }); @@ -96,7 +95,7 @@ describe('Integration', () => { expect( doc.getElementById('feature-object-destructuring').childElementCount - ).to.equal(4); + ).toBe(4); doc.defaultView.close(); }); @@ -105,16 +104,14 @@ describe('Integration', () => { expect( doc.getElementById('feature-object-spread').childElementCount - ).to.equal(4); + ).toBe(4); doc.defaultView.close(); }); it('promises', async () => { const doc = await initDOM('promises'); - expect(doc.getElementById('feature-promises').childElementCount).to.equal( - 4 - ); + expect(doc.getElementById('feature-promises').childElementCount).toBe(4); doc.defaultView.close(); }); @@ -123,7 +120,7 @@ describe('Integration', () => { expect( doc.getElementById('feature-rest-and-default').childElementCount - ).to.equal(4); + ).toBe(4); doc.defaultView.close(); }); @@ -132,7 +129,7 @@ describe('Integration', () => { expect( doc.getElementById('feature-rest-parameters').childElementCount - ).to.equal(4); + ).toBe(4); doc.defaultView.close(); }); @@ -141,7 +138,7 @@ describe('Integration', () => { expect( doc.getElementById('feature-template-interpolation').childElementCount - ).to.equal(4); + ).toBe(4); doc.defaultView.close(); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index 4aca73603dd..ebd830dfaaa 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import { expect } from 'chai'; import initDOM, { resourceLoader } from './initDOM'; import url from 'url'; @@ -20,14 +19,14 @@ const matchCSS = (doc, regexes) => { } resourceLoader({ url: url.parse(href) }, (_, textContent) => { for (const regex of regexes) { - expect(textContent).to.match(regex); + expect(textContent).toMatch(regex); } }); } else { for (let i = 0; i < regexes.length; ++i) { expect( doc.getElementsByTagName('style')[i].textContent.replace(/\s/g, '') - ).to.match(regexes[i]); + ).toMatch(regexes[i]); } } }; @@ -87,7 +86,7 @@ describe('Integration', () => { const children = doc.getElementById('graphql-inclusion').children; // .graphql - expect(children[0].textContent.replace(/\s/g, '')).to.equal( + expect(children[0].textContent.replace(/\s/g, '')).toBe( '{"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","variableDefinitions":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"test"},"value":{"kind":"StringValue","value":"test","block":false}}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"test"},"arguments":[],"directives":[]}]}}]}}],"loc":{"start":0,"end":40,"source":{"body":"{\\ntest(test:\\"test\\"){\\ntest\\n}\\n}\\n","name":"GraphQLrequest","locationOffset":{"line":1,"column":1}}}}' ); doc.defaultView.close(); @@ -96,7 +95,7 @@ describe('Integration', () => { it('image inclusion', async () => { const doc = await initDOM('image-inclusion'); - expect(doc.getElementById('feature-image-inclusion').src).to.match( + expect(doc.getElementById('feature-image-inclusion').src).toMatch( /^data:image\/jpeg;base64.+==$/ ); doc.defaultView.close(); @@ -105,7 +104,7 @@ describe('Integration', () => { it('no ext inclusion', async () => { const doc = await initDOM('no-ext-inclusion'); - expect(doc.getElementById('feature-no-ext-inclusion').href).to.match( + expect(doc.getElementById('feature-no-ext-inclusion').href).toMatch( /\/static\/media\/aFileWithoutExt\.[a-f0-9]{8}\.bin$/ ); doc.defaultView.close(); @@ -114,7 +113,7 @@ describe('Integration', () => { it('json inclusion', async () => { const doc = await initDOM('json-inclusion'); - expect(doc.getElementById('feature-json-inclusion').textContent).to.equal( + expect(doc.getElementById('feature-json-inclusion').textContent).toBe( 'This is an abstract.' ); doc.defaultView.close(); @@ -123,7 +122,7 @@ describe('Integration', () => { it('linked modules', async () => { const doc = await initDOM('linked-modules'); - expect(doc.getElementById('feature-linked-modules').textContent).to.equal( + expect(doc.getElementById('feature-linked-modules').textContent).toBe( '2.0.0' ); doc.defaultView.close(); @@ -131,7 +130,7 @@ describe('Integration', () => { it('svg inclusion', async () => { const doc = await initDOM('svg-inclusion'); - expect(doc.getElementById('feature-svg-inclusion').src).to.match( + expect(doc.getElementById('feature-svg-inclusion').src).toMatch( /\/static\/media\/logo\..+\.svg$/ ); doc.defaultView.close(); @@ -140,9 +139,7 @@ describe('Integration', () => { it('svg component', async () => { const doc = await initDOM('svg-component'); - expect(doc.getElementById('feature-svg-component').textContent).to.equal( - '' - ); + expect(doc.getElementById('feature-svg-component').textContent).toBe(''); doc.defaultView.close(); }); @@ -155,7 +152,7 @@ describe('Integration', () => { it('unknown ext inclusion', async () => { const doc = await initDOM('unknown-ext-inclusion'); - expect(doc.getElementById('feature-unknown-ext-inclusion').href).to.match( + expect(doc.getElementById('feature-unknown-ext-inclusion').href).toMatch( /\/static\/media\/aFileWithExt\.[a-f0-9]{8}\.unknown$/ ); doc.defaultView.close(); diff --git a/packages/react-scripts/fixtures/kitchensink/jest.integration.config.js b/packages/react-scripts/fixtures/kitchensink/jest.integration.config.js new file mode 100644 index 00000000000..fc778892493 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/jest.integration.config.js @@ -0,0 +1,4 @@ +module.exports = { + testEnvironment: 'node', + testMatch: ['**/integration/*.test.js'], +}; diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/scss-styles.scss b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/scss-styles.scss index 8aac77fbf6e..5a764ed2022 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/scss-styles.scss +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/assets/scss-styles.scss @@ -1,4 +1,12 @@ -@import "~bootstrap/scss/bootstrap"; +@import "~bootstrap/scss/functions"; +@import "~bootstrap/scss/variables"; +@import "~bootstrap/scss/mixins"; + +@import "~bootstrap/scss/reboot"; +@import "~bootstrap/scss/type"; +@import "~bootstrap/scss/images"; +@import "~bootstrap/scss/code"; +@import "~bootstrap/scss/grid"; #feature-scss-inclusion { background: ghostwhite; diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 490eb5f5666..47f3b417d17 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -1475,7 +1475,7 @@ import App from './App'; it('renders welcome message', () => { const wrapper = shallow(); const welcome =

Welcome to React

; - // expect(wrapper.contains(welcome)).to.equal(true); + // expect(wrapper.contains(welcome)).toBe(true); expect(wrapper.contains(welcome)).toEqual(true); }); ``` diff --git a/tasks/e2e-kitchensink-eject.sh b/tasks/e2e-kitchensink-eject.sh index ef7a511dc23..41ea1ab0d10 100755 --- a/tasks/e2e-kitchensink-eject.sh +++ b/tasks/e2e-kitchensink-eject.sh @@ -145,7 +145,7 @@ REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \ CI=true \ NODE_PATH=src \ NODE_ENV=test \ - yarn test --no-cache --testPathPattern=src + yarn test --no-cache --runInBand --testPathPattern=src # Test "development" environment tmp_server_log=`mktemp` @@ -159,7 +159,7 @@ E2E_URL="http://localhost:3002" \ CI=true NODE_PATH=src \ NODE_ENV=development \ BABEL_ENV=test \ - node_modules/.bin/mocha --timeout 30000 --compilers js:@babel/register --require @babel/polyfill integration/*.test.js + node_modules/.bin/jest --no-cache --runInBand --config='jest.integration.config.js' # Test "production" environment E2E_FILE=./build/index.html \ @@ -168,7 +168,7 @@ E2E_FILE=./build/index.html \ BABEL_ENV=test \ NODE_PATH=src \ PUBLIC_URL=http://www.example.org/spa/ \ - node_modules/.bin/mocha --timeout 30000 --compilers js:@babel/register --require @babel/polyfill integration/*.test.js + node_modules/.bin/jest --no-cache --runInBand --config='jest.integration.config.js' # Cleanup cleanup diff --git a/tasks/e2e-kitchensink.sh b/tasks/e2e-kitchensink.sh index c6011997cf8..a4cb3438f26 100755 --- a/tasks/e2e-kitchensink.sh +++ b/tasks/e2e-kitchensink.sh @@ -131,11 +131,12 @@ exists build/*.html exists build/static/js/main.*.js # Unit tests +# https://facebook.github.io/jest/docs/en/troubleshooting.html#tests-are-extremely-slow-on-docker-and-or-continuous-integration-ci-server REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \ CI=true \ NODE_PATH=src \ NODE_ENV=test \ - yarn test --no-cache --testPathPattern=src + yarn test --no-cache --runInBand --testPathPattern=src # Prepare "development" environment tmp_server_log=`mktemp` @@ -155,7 +156,7 @@ E2E_URL="http://localhost:3001" \ CI=true NODE_PATH=src \ NODE_ENV=development \ BABEL_ENV=test \ - node_modules/.bin/mocha --timeout 30000 --compilers js:@babel/register --require @babel/polyfill integration/*.test.js + node_modules/.bin/jest --no-cache --runInBand --config='jest.integration.config.js' # Test "production" environment E2E_FILE=./build/index.html \ CI=true \ @@ -163,11 +164,7 @@ E2E_FILE=./build/index.html \ NODE_ENV=production \ BABEL_ENV=test \ PUBLIC_URL=http://www.example.org/spa/ \ - node_modules/.bin/mocha --timeout 30000 --compilers js:@babel/register --require @babel/polyfill integration/*.test.js - -# Remove the config we just created for Mocha -# TODO: this is very hacky and we should find some other solution -rm .babelrc + node_modules/.bin/jest --no-cache --runInBand --config='jest.integration.config.js' # Cleanup cleanup