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