Skip to content
This repository was archived by the owner on Aug 16, 2024. It is now read-only.

Commit af61071

Browse files
authored
Add behavior e2e tests (facebook#5146)
* Add new behavior e2e test script * Add output for transparency
1 parent 7644f73 commit af61071

File tree

7 files changed

+243
-6
lines changed

7 files changed

+243
-6
lines changed

.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ build
33
my-app*
44
packages/react-scripts/template
55
packages/react-scripts/fixtures
6+
fixtures/

.travis.yml

+8-6
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,25 @@ node_js:
77
cache:
88
yarn: true
99
directories:
10-
- .npm
10+
- .npm
1111
before_install:
1212
- curl -o- -L https://yarnpkg.com/install.sh | bash
1313
- export PATH="$HOME/.yarn/bin:$PATH"
1414
install: true
1515
script:
16-
- 'if [ $TEST_SUITE = "simple" ]; then tasks/e2e-simple.sh; fi'
17-
- 'if [ $TEST_SUITE = "installs" ]; then tasks/e2e-installs.sh; fi'
18-
- 'if [ $TEST_SUITE = "kitchensink" ]; then tasks/e2e-kitchensink.sh; fi'
19-
- 'if [ $TEST_SUITE = "kitchensink-eject" ]; then tasks/e2e-kitchensink-eject.sh; fi'
20-
- 'if [ $TEST_SUITE = "old-node" ]; then tasks/e2e-old-node.sh; fi'
16+
- 'if [ $TEST_SUITE = "simple" ]; then tasks/e2e-simple.sh; fi'
17+
- 'if [ $TEST_SUITE = "installs" ]; then tasks/e2e-installs.sh; fi'
18+
- 'if [ $TEST_SUITE = "kitchensink" ]; then tasks/e2e-kitchensink.sh; fi'
19+
- 'if [ $TEST_SUITE = "kitchensink-eject" ]; then tasks/e2e-kitchensink-eject.sh; fi'
20+
- 'if [ $TEST_SUITE = "old-node" ]; then tasks/e2e-old-node.sh; fi'
21+
- 'if [ $TEST_SUITE = "behavior" ]; then tasks/e2e-behavior.sh; fi'
2122
env:
2223
matrix:
2324
- TEST_SUITE=simple
2425
- TEST_SUITE=installs
2526
- TEST_SUITE=kitchensink
2627
- TEST_SUITE=kitchensink-eject
28+
- TEST_SUITE=behavior
2729
matrix:
2830
include:
2931
- node_js: 4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "builds-with-multiple-runtimes",
3+
"description": "Tests that a build succeeds with multiple runtime versions",
4+
"dependencies": {
5+
"dva": "2.4.0",
6+
"ky": "0.3.0"
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from 'react';
2+
import dva from 'dva';
3+
import createHistory from 'history/createHashHistory';
4+
import ky from 'ky';
5+
6+
const app = dva({ history: createHistory() });
7+
app.router(() => {
8+
ky.get('https://canihazip.com/s')
9+
.then(r => r.text())
10+
.then(console.log, console.error)
11+
.then(() => console.log('ok'));
12+
return <div>Test</div>;
13+
});
14+
app.start('#root');

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
"format": "prettier --trailing-comma es5 --single-quote --write 'packages/*/*.js' 'packages/*/!(node_modules)/**/*.js'"
1919
},
2020
"devDependencies": {
21+
"cross-spawn": "^6.0.5",
2122
"eslint": "5.6.0",
2223
"execa": "1.0.0",
24+
"fs-extra": "^7.0.0",
2325
"husky": "1.0.0-rc.15",
2426
"lerna": "2.9.1",
2527
"lerna-changelog": "^0.8.0",

tasks/e2e-behavior.sh

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#!/bin/bash
2+
# Copyright (c) 2015-present, Facebook, Inc.
3+
#
4+
# This source code is licensed under the MIT license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
# ******************************************************************************
8+
# This is an end-to-end kitchensink test intended to run on CI.
9+
# You can also run it locally but it's slow.
10+
# ******************************************************************************
11+
12+
# Start in tasks/ even if run from root directory
13+
cd "$(dirname "$0")"
14+
15+
# CLI, app, and test module temporary locations
16+
# http://unix.stackexchange.com/a/84980
17+
temp_app_path=`mktemp -d 2>/dev/null || mktemp -d -t 'temp_app_path'`
18+
temp_module_path=`mktemp -d 2>/dev/null || mktemp -d -t 'temp_module_path'`
19+
custom_registry_url=http://localhost:4873
20+
original_npm_registry_url=`npm get registry`
21+
original_yarn_registry_url=`yarn config get registry`
22+
23+
function cleanup {
24+
echo 'Cleaning up.'
25+
ps -ef | grep 'react-scripts' | grep -v grep | awk '{print $2}' | xargs kill -9
26+
cd "$root_path"
27+
npm set registry "$original_npm_registry_url"
28+
yarn config set registry "$original_yarn_registry_url"
29+
}
30+
31+
# Error messages are redirected to stderr
32+
function handle_error {
33+
echo "$(basename $0): ERROR! An error was encountered executing line $1." 1>&2;
34+
cleanup
35+
echo 'Exiting with error.' 1>&2;
36+
exit 1
37+
}
38+
39+
function handle_exit {
40+
cleanup
41+
echo 'Exiting without error.' 1>&2;
42+
exit
43+
}
44+
45+
# Check for the existence of one or more files.
46+
function exists {
47+
for f in $*; do
48+
test -e "$f"
49+
done
50+
}
51+
52+
# Exit the script with a helpful error message when any error is encountered
53+
trap 'set +x; handle_error $LINENO $BASH_COMMAND' ERR
54+
55+
# Cleanup before exit on any termination signal
56+
trap 'set +x; handle_exit' SIGQUIT SIGTERM SIGINT SIGKILL SIGHUP
57+
58+
# Echo every command being executed
59+
set -x
60+
61+
# Go to root
62+
cd ..
63+
root_path=$PWD
64+
65+
if hash npm 2>/dev/null
66+
then
67+
npm i -g npm@latest
68+
fi
69+
70+
# Bootstrap monorepo
71+
yarn
72+
73+
# ******************************************************************************
74+
# First, publish the monorepo.
75+
# ******************************************************************************
76+
77+
# Start local registry
78+
tmp_registry_log=`mktemp`
79+
nohup npx [email protected] -c tasks/verdaccio.yaml &>$tmp_registry_log &
80+
# Wait for `verdaccio` to boot
81+
grep -q 'http address' <(tail -f $tmp_registry_log)
82+
83+
# Set registry to local registry
84+
npm set registry "$custom_registry_url"
85+
yarn config set registry "$custom_registry_url"
86+
87+
# Login so we can publish packages
88+
(cd && npx [email protected] -u user -p password -e [email protected] -r "$custom_registry_url")
89+
90+
# Publish the monorepo
91+
git clean -df
92+
./tasks/publish.sh --yes --force-publish=* --skip-git --cd-version=prerelease --exact --npm-tag=latest
93+
94+
# ******************************************************************************
95+
# Now that we have published them, create a clean app folder and install them.
96+
# ******************************************************************************
97+
98+
# Install the app in a temporary location
99+
cd $temp_app_path
100+
npx create-react-app test-behavior
101+
102+
# ******************************************************************************
103+
# Now that we used create-react-app to create an app depending on react-scripts,
104+
# let's run through all of our behavior tests.
105+
# ******************************************************************************
106+
107+
# Enter the app directory
108+
cd "$temp_app_path/test-behavior"
109+
110+
node "$root_path"/tasks/test-behavior.js "$temp_app_path/test-behavior"
111+
112+
# Cleanup
113+
cleanup

tasks/test-behavior.js

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
'use strict';
2+
3+
const args = process.argv.slice(2);
4+
const fs = require('fs-extra');
5+
const path = require('path');
6+
const os = require('os');
7+
const spawn = require('cross-spawn');
8+
9+
const applicationPath = args.pop();
10+
const applicationPackageJson = path.resolve(applicationPath, 'package.json');
11+
const applicationSrc = path.resolve(applicationPath, 'src');
12+
const applicationModules = path.resolve(applicationPath, 'node_modules');
13+
14+
const fixturePath = path.resolve(__dirname, '..', 'fixtures', 'behavior');
15+
const fixtures = fs
16+
.readdirSync(fixturePath)
17+
.map(fixture => path.resolve(fixturePath, fixture))
18+
.filter(path => fs.lstatSync(path).isDirectory);
19+
20+
const packageContents = require(applicationPackageJson);
21+
22+
function install({ root }) {
23+
spawn.sync('yarnpkg', ['--cwd', root, 'install'], { cwd: root });
24+
}
25+
26+
function startApp({ root }) {
27+
const output = spawn
28+
.sync('yarnpkg', ['start', '--smoke-test'], { cwd: root })
29+
.output.join('');
30+
31+
if (!/Compiled successfully/.test(output)) {
32+
throw new Error(output);
33+
}
34+
35+
console.log('\t = application started: ', output);
36+
}
37+
38+
function buildApp({ root }) {
39+
const output = spawn
40+
.sync('yarnpkg', ['build'], { cwd: root })
41+
.output.join('');
42+
43+
if (!/Compiled successfully/.test(output)) {
44+
throw new Error(output);
45+
}
46+
47+
console.log('\t = application built: ', output);
48+
}
49+
50+
console.log(`=> checking ${fixtures.length} fixtures`);
51+
for (const fixture of fixtures) {
52+
const {
53+
name,
54+
description,
55+
dependencies,
56+
devDependencies,
57+
} = require(path.resolve(fixture, 'package.json'));
58+
console.log(`\t * checking fixture ${name}`);
59+
console.log(`\t ... this fixture: ${description}`);
60+
61+
fs.emptyDirSync(applicationSrc);
62+
fs.emptyDirSync(applicationModules);
63+
fs.copySync(path.resolve(fixture, 'src'), applicationSrc);
64+
65+
try {
66+
fs.writeJsonSync(
67+
applicationPackageJson,
68+
Object.assign({}, packageContents, {
69+
dependencies: Object.assign(
70+
{},
71+
packageContents.dependencies,
72+
dependencies
73+
),
74+
devDependencies: Object.assign(
75+
{},
76+
packageContents.devDependencies,
77+
devDependencies
78+
),
79+
}),
80+
{
81+
spaces: 2,
82+
EOL: os.EOL,
83+
}
84+
);
85+
install({ root: applicationPath });
86+
startApp({ root: applicationPath });
87+
buildApp({ root: applicationPath });
88+
} catch (e) {
89+
console.error(`\t ! failed on ${name}:`);
90+
throw e;
91+
} finally {
92+
fs.writeJsonSync(applicationPackageJson, packageContents, {
93+
spaces: 2,
94+
EOL: os.EOL,
95+
});
96+
}
97+
}

0 commit comments

Comments
 (0)