From 5bff696f803a7714d402eb2e4747a223c6639fbd Mon Sep 17 00:00:00 2001 From: Joe Haddad Date: Wed, 3 Oct 2018 00:41:14 -0400 Subject: [PATCH] Add browser test for graphql --- .../__snapshots__/index.test.js.snap | 5 ++ .../browser/graphql-with-mjs/index.test.js | 56 +++++++++++++++++ .../graphql-with-mjs/package.json | 3 +- .../graphql-with-mjs/public/index.html | 0 fixtures/browser/graphql-with-mjs/src/App.js | 63 +++++++++++++++++++ .../graphql-with-mjs/src/index.js | 0 fixtures/browser/jest.config.js | 7 +++ fixtures/browser/setupBrowserTests.js | 9 +++ fixtures/smoke/graphql-with-mjs/index.test.js | 17 ----- fixtures/smoke/graphql-with-mjs/src/App.js | 20 ------ fixtures/utils.js | 32 ++++++++++ package.json | 1 + tasks/e2e-behavior.sh | 3 + 13 files changed, 178 insertions(+), 38 deletions(-) create mode 100644 fixtures/browser/graphql-with-mjs/__snapshots__/index.test.js.snap create mode 100644 fixtures/browser/graphql-with-mjs/index.test.js rename fixtures/{smoke => browser}/graphql-with-mjs/package.json (73%) rename fixtures/{smoke => browser}/graphql-with-mjs/public/index.html (100%) create mode 100644 fixtures/browser/graphql-with-mjs/src/App.js rename fixtures/{smoke => browser}/graphql-with-mjs/src/index.js (100%) create mode 100644 fixtures/browser/jest.config.js create mode 100644 fixtures/browser/setupBrowserTests.js delete mode 100644 fixtures/smoke/graphql-with-mjs/index.test.js delete mode 100644 fixtures/smoke/graphql-with-mjs/src/App.js diff --git a/fixtures/browser/graphql-with-mjs/__snapshots__/index.test.js.snap b/fixtures/browser/graphql-with-mjs/__snapshots__/index.test.js.snap new file mode 100644 index 00000000000..5e56b8d629b --- /dev/null +++ b/fixtures/browser/graphql-with-mjs/__snapshots__/index.test.js.snap @@ -0,0 +1,5 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`graphql with mjs entrypoint correctly bundles files in development 1`] = `"Pikachu"`; + +exports[`graphql with mjs entrypoint correctly bundles files in production 1`] = `"Pikachu"`; diff --git a/fixtures/browser/graphql-with-mjs/index.test.js b/fixtures/browser/graphql-with-mjs/index.test.js new file mode 100644 index 00000000000..6149ed88c32 --- /dev/null +++ b/fixtures/browser/graphql-with-mjs/index.test.js @@ -0,0 +1,56 @@ +const { + bootstrap, + startDevelopmentServer, + startProductionServer, +} = require('../../utils'); +const puppeteer = require('puppeteer'); + +beforeEach(async () => { + await bootstrap({ directory: global.testDirectory, template: __dirname }); + global.appDevPort = await startDevelopmentServer({ + directory: global.testDirectory, + }); + global.appProdPort = await startProductionServer({ + directory: global.testDirectory, + }); + // Wait for serve to boot up + await new Promise(resolve => setTimeout(resolve, 1000)); +}); + +// https://github.com/facebook/create-react-app/issues/5234 +// https://github.com/facebook/create-react-app/pull/5258 +describe('graphql with mjs entrypoint', () => { + it('correctly bundles files in development', async () => { + const browser = await puppeteer.launch({ headless: true }); + try { + const page = await browser.newPage(); + await page.goto(`http://localhost:${global.appDevPort}/`); + await page.waitForSelector('.Pokemon-Name-Data'); + const output = await page.evaluate(() => { + return Array.from( + document.getElementsByClassName('Pokemon-Name-Data') + ).pop().innerHTML; + }); + expect(output).toMatchSnapshot(); + } finally { + browser.close(); + } + }); + + it('correctly bundles files in production', async () => { + const browser = await puppeteer.launch({ headless: true }); + try { + const page = await browser.newPage(); + await page.goto(`http://localhost:${global.appProdPort}/`); + await page.waitForSelector('.Pokemon-Name-Data'); + const output = await page.evaluate(() => { + return Array.from( + document.getElementsByClassName('Pokemon-Name-Data') + ).pop().innerHTML; + }); + expect(output).toMatchSnapshot(); + } finally { + browser.close(); + } + }); +}); diff --git a/fixtures/smoke/graphql-with-mjs/package.json b/fixtures/browser/graphql-with-mjs/package.json similarity index 73% rename from fixtures/smoke/graphql-with-mjs/package.json rename to fixtures/browser/graphql-with-mjs/package.json index c97e6b8d013..ad9cf3d89d7 100644 --- a/fixtures/smoke/graphql-with-mjs/package.json +++ b/fixtures/browser/graphql-with-mjs/package.json @@ -4,6 +4,7 @@ "graphql": "14.0.2", "react-apollo": "2.2.1", "react": "latest", - "react-dom": "latest" + "react-dom": "latest", + "serve": "10.0.2" } } diff --git a/fixtures/smoke/graphql-with-mjs/public/index.html b/fixtures/browser/graphql-with-mjs/public/index.html similarity index 100% rename from fixtures/smoke/graphql-with-mjs/public/index.html rename to fixtures/browser/graphql-with-mjs/public/index.html diff --git a/fixtures/browser/graphql-with-mjs/src/App.js b/fixtures/browser/graphql-with-mjs/src/App.js new file mode 100644 index 00000000000..39fabb94545 --- /dev/null +++ b/fixtures/browser/graphql-with-mjs/src/App.js @@ -0,0 +1,63 @@ +import React, { Component } from 'react'; +import ApolloClient, { gql } from 'apollo-boost'; +import { ApolloProvider, Query } from 'react-apollo'; + +const GET_PIKA = gql` + { + pokemon(name: "Pikachu") { + name + } + } +`; + +const client = new ApolloClient({ + uri: 'https://graphql-pokemon.now.sh/graphql', +}); + +class Pokemon extends Component { + render() { + const { name } = this.props.pokemon; + return ( +

+ Pokemon name: {name} +

+ ); + } +} + +class Data extends Component { + state = {}; + componentDidCatch() { + this.setState({ hasError: true }); + } + render() { + const { hasError } = this.state; + return hasError ? ( +
Error :(
+ ) : ( + + {({ loading, error, data }) => { + if (loading) { + return
Loading...
; + } + if (error) { + return
Error :(
; + } + return ; + }} +
+ ); + } +} + +class App extends Component { + render() { + return ( + + + + ); + } +} + +export default App; diff --git a/fixtures/smoke/graphql-with-mjs/src/index.js b/fixtures/browser/graphql-with-mjs/src/index.js similarity index 100% rename from fixtures/smoke/graphql-with-mjs/src/index.js rename to fixtures/browser/graphql-with-mjs/src/index.js diff --git a/fixtures/browser/jest.config.js b/fixtures/browser/jest.config.js new file mode 100644 index 00000000000..e3ab37e7923 --- /dev/null +++ b/fixtures/browser/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + testEnvironment: 'node', + testMatch: ['**/*.test.js'], + testPathIgnorePatterns: ['/src/', 'node_modules'], + setupTestFrameworkScriptFile: './setupBrowserTests.js', + forceExit: true, +}; diff --git a/fixtures/browser/setupBrowserTests.js b/fixtures/browser/setupBrowserTests.js new file mode 100644 index 00000000000..9bbc3ffb675 --- /dev/null +++ b/fixtures/browser/setupBrowserTests.js @@ -0,0 +1,9 @@ +const fs = require('fs-extra'); +const tempy = require('tempy'); +beforeEach(() => { + global.testDirectory = tempy.directory(); + jest.setTimeout(1000 * 60 * 5); +}); +afterEach(() => { + fs.removeSync(global.testDirectory); +}); diff --git a/fixtures/smoke/graphql-with-mjs/index.test.js b/fixtures/smoke/graphql-with-mjs/index.test.js deleted file mode 100644 index 1f1d2bd078a..00000000000 --- a/fixtures/smoke/graphql-with-mjs/index.test.js +++ /dev/null @@ -1,17 +0,0 @@ -const { - bootstrap, - isSuccessfulDevelopment, - isSuccessfulProduction, -} = require('../../utils'); -beforeEach(async () => { - await bootstrap({ directory: global.testDirectory, template: __dirname }); -}); - -describe('graphql with mjs entrypoint', () => { - it('builds in development', async () => { - await isSuccessfulDevelopment({ directory: global.testDirectory }); - }); - it('builds in production', async () => { - await isSuccessfulProduction({ directory: global.testDirectory }); - }); -}); diff --git a/fixtures/smoke/graphql-with-mjs/src/App.js b/fixtures/smoke/graphql-with-mjs/src/App.js deleted file mode 100644 index 1ba9891424a..00000000000 --- a/fixtures/smoke/graphql-with-mjs/src/App.js +++ /dev/null @@ -1,20 +0,0 @@ -import React, { Component } from 'react'; - -import ApolloClient from 'apollo-boost'; -import { ApolloProvider } from 'react-apollo'; - -const client = new ApolloClient({ - uri: '/whatever', -}); - -class App extends Component { - render() { - return ( - -
- - ); - } -} - -export default App; diff --git a/fixtures/utils.js b/fixtures/utils.js index bde092f6e3e..0c08a32746f 100644 --- a/fixtures/utils.js +++ b/fixtures/utils.js @@ -135,6 +135,36 @@ async function getOutputProduction({ directory, env = {} }) { } } +async function startDevelopmentServer({ directory, env = {} }) { + const port = await getPort(); + execa('./node_modules/.bin/react-scripts', ['start'], { + cwd: directory, + env: Object.assign( + {}, + { + BROWSER: 'none', + PORT: port, + CI: 'false', + FORCE_COLOR: '0', + }, + env + ), + }); + return port; +} + +async function startProductionServer({ directory, env = {} }) { + const port = await getPort(); + await execa('./node_modules/.bin/react-scripts', ['build'], { + cwd: directory, + env: Object.assign({}, { CI: 'false' }, env), + }); + execa('./node_modules/.bin/serve', ['-s', 'build', '-p', port], { + cwd: directory, + }); + return port; +} + module.exports = { bootstrap, isSuccessfulDevelopment, @@ -142,4 +172,6 @@ module.exports = { isSuccessfulTest, getOutputDevelopment, getOutputProduction, + startDevelopmentServer, + startProductionServer, }; diff --git a/package.json b/package.json index 96d63b4f224..c077728b316 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "meow": "^5.0.0", "multimatch": "^2.1.0", "prettier": "1.14.3", + "puppeteer": "^1.8.0", "strip-ansi": "^4.0.0", "svg-term-cli": "^2.1.1", "tempy": "^0.2.1" diff --git a/tasks/e2e-behavior.sh b/tasks/e2e-behavior.sh index 4a48b423b35..f4ed77659ad 100755 --- a/tasks/e2e-behavior.sh +++ b/tasks/e2e-behavior.sh @@ -95,6 +95,9 @@ git clean -df # Now that we have published them, run all tests as if they were released. # ****************************************************************************** +# Browser tests +CI=true ./node_modules/.bin/jest --config fixtures/browser/jest.config.js + # Smoke tests CI=true ./node_modules/.bin/jest --config fixtures/smoke/jest.config.js