e2e-simple.sh 11.8 KB
Newer Older
1
#!/bin/bash
Christopher Chedeau's avatar
Christopher Chedeau committed
2
# Copyright (c) 2015-present, Facebook, Inc.
Joe Haddad's avatar
Joe Haddad committed
3
4
5
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
Christopher Chedeau's avatar
Christopher Chedeau committed
6

7
8
9
10
11
# ******************************************************************************
# This is an end-to-end test intended to run on CI.
# You can also run it locally but it's slow.
# ******************************************************************************

Dan Abramov's avatar
Dan Abramov committed
12
# Start in tasks/ even if run from root directory
Christopher Chedeau's avatar
Christopher Chedeau committed
13
14
cd "$(dirname "$0")"

15
16
17
18
19
# CLI and app temporary locations
# http://unix.stackexchange.com/a/84980
temp_cli_path=`mktemp -d 2>/dev/null || mktemp -d -t 'temp_cli_path'`
temp_app_path=`mktemp -d 2>/dev/null || mktemp -d -t 'temp_app_path'`

20
21
function cleanup {
  echo 'Cleaning up.'
22
  cd "$root_path"
Dan Abramov's avatar
Dan Abramov committed
23
  # Uncomment when snapshot testing is enabled by default:
Ville Immonen's avatar
Ville Immonen committed
24
  # rm ./packages/react-scripts/template/src/__snapshots__/App.test.js.snap
25
  rm -rf "$temp_cli_path" $temp_app_path
26
27
}

Dan Abramov's avatar
Dan Abramov committed
28
# Error messages are redirected to stderr
29
function handle_error {
Dan Abramov's avatar
Dan Abramov committed
30
  echo "$(basename $0): ERROR! An error was encountered executing line $1." 1>&2;
Dan Abramov's avatar
Dan Abramov committed
31
  cleanup
32
  echo 'Exiting with error.' 1>&2;
33
34
35
36
37
  exit 1
}

function handle_exit {
  cleanup
38
  echo 'Exiting without error.' 1>&2;
39
40
41
  exit
}

42
function create_react_app {
43
  node "$temp_cli_path"/node_modules/create-react-app/index.js "$@"
44
45
}

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
function install_package {
  local pkg=$(basename $1)

  # Clean target (for safety)
  rm -rf node_modules/$pkg/
  rm -rf node_modules/**/$pkg/

  # Copy package into node_modules/ ignoring installed deps
  # rsync -a ${1%/} node_modules/ --exclude node_modules
  cp -R ${1%/} node_modules/
  rm -rf node_modules/$pkg/node_modules/

  # Install `dependencies`
  cd node_modules/$pkg/
  if [ "$USE_YARN" = "yes" ]
  then
    yarn install --production
  else
    npm install --only=production
  fi
  # Remove our packages to ensure side-by-side versions are used (which we link)
  rm -rf node_modules/{babel-preset-react-app,eslint-config-react-app,react-dev-utils,react-error-overlay,react-scripts}
  cd ../..
}

71
72
73
74
75
76
77
# Check for the existence of one or more files.
function exists {
  for f in $*; do
    test -e "$f"
  done
}

78
79
80
81
82
# Exit the script with a helpful error message when any error is encountered
trap 'set +x; handle_error $LINENO $BASH_COMMAND' ERR

# Cleanup before exit on any termination signal
trap 'set +x; handle_exit' SIGQUIT SIGTERM SIGINT SIGKILL SIGHUP
Christopher Chedeau's avatar
Christopher Chedeau committed
83
84
85
86

# Echo every command being executed
set -x

Dan Abramov's avatar
Dan Abramov committed
87
# Go to root
Christopher Chedeau's avatar
Christopher Chedeau committed
88
cd ..
Dan Abramov's avatar
Dan Abramov committed
89
root_path=$PWD
90

91
92
93
94
95
96
# Clear cache to avoid issues with incorrect packages being used
if hash yarnpkg 2>/dev/null
then
  # AppVeyor uses an old version of yarn.
  # Once updated to 0.24.3 or above, the workaround can be removed
  # and replaced with `yarnpkg cache clean`
97
  # Issues:
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  #    https://github.com/yarnpkg/yarn/issues/2591
  #    https://github.com/appveyor/ci/issues/1576
  #    https://github.com/facebookincubator/create-react-app/pull/2400
  # When removing workaround, you may run into
  #    https://github.com/facebookincubator/create-react-app/issues/2030
  case "$(uname -s)" in
    *CYGWIN*|MSYS*|MINGW*) yarn=yarn.cmd;;
    *) yarn=yarnpkg;;
  esac
  $yarn cache clean
fi

if hash npm 2>/dev/null
then
112
  # npm 5 is too buggy right now
Dan Abramov's avatar
Dan Abramov committed
113
  if [ $(npm -v | head -c 1) -eq 5 ]; then
114
    npm i -g npm@^4.x
Dan Abramov's avatar
Dan Abramov committed
115
  fi;
116
  npm cache clean || npm cache verify
117
118
fi

119
# Prevent bootstrap, we only want top-level dependencies
120
cp package.json package.json.bak
121
grep -v "postinstall" package.json > temp && mv temp package.json
122
123
124
npm install
mv package.json.bak package.json

Joe Haddad's avatar
Joe Haddad committed
125
126
127
128
129
# We need to install create-react-app deps to test it
cd "$root_path"/packages/create-react-app
npm install
cd "$root_path"

130
131
132
133
134
# If the node version is < 6, the script should just give an error.
nodeVersion=`node --version | cut -d v -f2`
nodeMajor=`echo $nodeVersion | cut -d. -f1`
nodeMinor=`echo $nodeVersion | cut -d. -f2`
if [[ nodeMajor -lt 6 ]]
135
136
137
then
  cd $temp_app_path
  err_output=`node "$root_path"/packages/create-react-app/index.js test-node-version 2>&1 > /dev/null || echo ''`
Dan Abramov's avatar
Dan Abramov committed
138
  [[ $err_output =~ You\ are\ running\ Node ]] && exit 0 || exit 1
139
140
fi

Ville Immonen's avatar
Ville Immonen committed
141
142
143
if [ "$USE_YARN" = "yes" ]
then
  # Install Yarn so that the test can use it to install packages.
Dan Abramov's avatar
Dan Abramov committed
144
  npm install -g yarn
145
  yarn cache clean
Ville Immonen's avatar
Ville Immonen committed
146
147
fi

148
149
150
# We removed the postinstall, so do it manually here
node bootstrap.js

Dan Abramov's avatar
Dan Abramov committed
151
# Lint own code
152
153
154
155
156
157
158
159
160
161
./node_modules/.bin/eslint --max-warnings 0 packages/babel-preset-react-app/
./node_modules/.bin/eslint --max-warnings 0 packages/create-react-app/
./node_modules/.bin/eslint --max-warnings 0 packages/eslint-config-react-app/
./node_modules/.bin/eslint --max-warnings 0 packages/react-dev-utils/
./node_modules/.bin/eslint --max-warnings 0 packages/react-scripts/
cd packages/react-error-overlay/
./node_modules/.bin/eslint --max-warnings 0 src/
npm test
npm run build:prod
cd ../..
162
163
164
cd packages/react-dev-utils/
npm test
cd ../..
165

Dan Abramov's avatar
Dan Abramov committed
166
167
168
169
170
# ******************************************************************************
# First, test the create-react-app development environment.
# This does not affect our users but makes sure we can develop it.
# ******************************************************************************

Max's avatar
Max committed
171
172
173
# Test local build command
npm run build
# Check for expected output
174
175
176
177
178
exists build/*.html
exists build/static/js/*.js
exists build/static/css/*.css
exists build/static/media/*.svg
exists build/favicon.ico
Max's avatar
Max committed
179

180
181
# Run tests with CI flag
CI=true npm test
Dan Abramov's avatar
Dan Abramov committed
182
# Uncomment when snapshot testing is enabled by default:
183
# exists template/src/__snapshots__/App.test.js.snap
Dan Abramov's avatar
Dan Abramov committed
184
185
186

# Test local start command
npm start -- --smoke-test
Christoph Pojer's avatar
Christoph Pojer committed
187

Dan Abramov's avatar
Dan Abramov committed
188
189
190
191
# ******************************************************************************
# Next, pack react-scripts and create-react-app so we can verify they work.
# ******************************************************************************

Dan Abramov's avatar
Dan Abramov committed
192
# Pack CLI
193
cd "$root_path"/packages/create-react-app
Christopher Chedeau's avatar
Christopher Chedeau committed
194
195
cli_path=$PWD/`npm pack`

Dan Abramov's avatar
Dan Abramov committed
196
# Go to react-scripts
197
cd "$root_path"/packages/react-scripts
Ville Immonen's avatar
Ville Immonen committed
198

199
200
201
202
203
# Save package.json because we're going to touch it
cp package.json package.json.orig

# Replace own dependencies (those in the `packages` dir) with the local paths
# of those packages.
204
node "$root_path"/tasks/replace-own-deps.js
Ville Immonen's avatar
Ville Immonen committed
205

Dan Abramov's avatar
Dan Abramov committed
206
# Finally, pack react-scripts
207
scripts_path="$root_path"/packages/react-scripts/`npm pack`
Dan Abramov's avatar
Dan Abramov committed
208

209
210
211
212
# Restore package.json
rm package.json
mv package.json.orig package.json

Dan Abramov's avatar
Dan Abramov committed
213
214
215
216
# ******************************************************************************
# Now that we have packed them, create a clean app folder and install them.
# ******************************************************************************

Dan Abramov's avatar
Dan Abramov committed
217
# Install the CLI in a temporary location
218
cd "$temp_cli_path"
219
220
221
222
223
224

# Initialize package.json before installing the CLI because npm will not install
# the CLI properly in the temporary location if it is missing.
npm init --yes

# Now we can install the CLI from the local package.
225
npm install "$cli_path"
Christopher Chedeau's avatar
Christopher Chedeau committed
226
227
228

# Install the app in a temporary location
cd $temp_app_path
229
create_react_app --scripts-version="$scripts_path" test-app
Dan Abramov's avatar
Dan Abramov committed
230
231
232
233
234
235

# ******************************************************************************
# Now that we used create-react-app to create an app depending on react-scripts,
# let's make sure all npm scripts are in the working state.
# ******************************************************************************

236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
function verify_env_url {
  # Backup package.json because we're going to make it dirty
  cp package.json package.json.orig

  # Test default behavior
  grep -F -R --exclude=*.map "\"/static/" build/ -q; test $? -eq 0 || exit 1

  # Test relative path build
  awk -v n=2 -v s="  \"homepage\": \".\"," 'NR == n {print s} {print}' package.json > tmp && mv tmp package.json

  npm run build
  # Disabled until this can be tested
  # grep -F -R --exclude=*.map "../../static/" build/ -q; test $? -eq 0 || exit 1
  grep -F -R --exclude=*.map "\"./static/" build/ -q; test $? -eq 0 || exit 1
  grep -F -R --exclude=*.map "\"/static/" build/ -q; test $? -eq 1 || exit 1

  PUBLIC_URL="/anabsolute" npm run build
  grep -F -R --exclude=*.map "/anabsolute/static/" build/ -q; test $? -eq 0 || exit 1
  grep -F -R --exclude=*.map "\"/static/" build/ -q; test $? -eq 1 || exit 1

  # Test absolute path build
  sed "2s/.*/  \"homepage\": \"\/testingpath\",/" package.json > tmp && mv tmp package.json

  npm run build
  grep -F -R --exclude=*.map "/testingpath/static/" build/ -q; test $? -eq 0 || exit 1
  grep -F -R --exclude=*.map "\"/static/" build/ -q; test $? -eq 1 || exit 1

  PUBLIC_URL="https://www.example.net/overridetest" npm run build
  grep -F -R --exclude=*.map "https://www.example.net/overridetest/static/" build/ -q; test $? -eq 0 || exit 1
  grep -F -R --exclude=*.map "\"/static/" build/ -q; test $? -eq 1 || exit 1
  grep -F -R --exclude=*.map "testingpath/static" build/ -q; test $? -eq 1 || exit 1

  # Test absolute url build
  sed "2s/.*/  \"homepage\": \"https:\/\/www.example.net\/testingpath\",/" package.json > tmp && mv tmp package.json

  npm run build
  grep -F -R --exclude=*.map "/testingpath/static/" build/ -q; test $? -eq 0 || exit 1
  grep -F -R --exclude=*.map "\"/static/" build/ -q; test $? -eq 1 || exit 1

  PUBLIC_URL="https://www.example.net/overridetest" npm run build
  grep -F -R --exclude=*.map "https://www.example.net/overridetest/static/" build/ -q; test $? -eq 0 || exit 1
  grep -F -R --exclude=*.map "\"/static/" build/ -q; test $? -eq 1 || exit 1
  grep -F -R --exclude=*.map "testingpath/static" build/ -q; test $? -eq 1 || exit 1

  # Restore package.json
  rm package.json
  mv package.json.orig package.json
}

Joe Haddad's avatar
Joe Haddad committed
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
function verify_module_scope {
  # Create stub json file
  echo "{}" >> sample.json

  # Save App.js, we're going to modify it
  cp src/App.js src/App.js.bak

  # Add an out of scope import
  echo "import sampleJson from '../sample'" | cat - src/App.js > src/App.js.temp && mv src/App.js.temp src/App.js

  # Make sure the build fails
  npm run build; test $? -eq 1 || exit 1
  # TODO: check for error message

  # Restore App.js
  rm src/App.js
  mv src/App.js.bak src/App.js
}

Dan Abramov's avatar
Dan Abramov committed
304
# Enter the app directory
Christopher Chedeau's avatar
Christopher Chedeau committed
305
306
307
308
cd test-app

# Test the build
npm run build
309
# Check for expected output
310
311
312
313
314
exists build/*.html
exists build/static/js/*.js
exists build/static/css/*.css
exists build/static/media/*.svg
exists build/favicon.ico
315

316
317
# Run tests with CI flag
CI=true npm test
Dan Abramov's avatar
Dan Abramov committed
318
# Uncomment when snapshot testing is enabled by default:
319
# exists src/__snapshots__/App.test.js.snap
Christoph Pojer's avatar
Christoph Pojer committed
320

Dan Abramov's avatar
Dan Abramov committed
321
322
323
# Test the server
npm start -- --smoke-test

324
325
326
# Test environment handling
verify_env_url

Joe Haddad's avatar
Joe Haddad committed
327
328
329
# Test reliance on webpack internals
verify_module_scope

Dan Abramov's avatar
Dan Abramov committed
330
331
332
333
# ******************************************************************************
# Finally, let's check that everything still works after ejecting.
# ******************************************************************************

Dan Abramov's avatar
Dan Abramov committed
334
# Eject...
Christopher Chedeau's avatar
Christopher Chedeau committed
335
336
echo yes | npm run eject

337
338
339
340
341
342
343
344
# Ensure Yarn is ran after eject; at the time of this commit, we don't run Yarn
# after ejecting. Soon, we may only skip Yarn on Windows. Let's try to remove
# this in the near future.
if hash yarnpkg 2>/dev/null
then
  yarnpkg install --check-files
fi

Dan Abramov's avatar
Dan Abramov committed
345
# ...but still link to the local packages
346
347
348
install_package "$root_path"/packages/babel-preset-react-app
install_package "$root_path"/packages/eslint-config-react-app
install_package "$root_path"/packages/react-dev-utils
Dan Abramov's avatar
Dan Abramov committed
349

Dan Abramov's avatar
Dan Abramov committed
350
351
# Test the build
npm run build
352
# Check for expected output
353
354
355
356
357
exists build/*.html
exists build/static/js/*.js
exists build/static/css/*.css
exists build/static/media/*.svg
exists build/favicon.ico
358

Dan Abramov's avatar
Dan Abramov committed
359
360
361
362
# Run tests, overring the watch option to disable it.
# `CI=true npm test` won't work here because `npm test` becomes just `jest`.
# We should either teach Jest to respect CI env variable, or make
# `scripts/test.js` survive ejection (right now it doesn't).
Dan Abramov's avatar
Dan Abramov committed
363
364
npm test -- --watch=no
# Uncomment when snapshot testing is enabled by default:
365
# exists src/__snapshots__/App.test.js.snap
Christoph Pojer's avatar
Christoph Pojer committed
366

Dan Abramov's avatar
Dan Abramov committed
367
368
369
# Test the server
npm start -- --smoke-test

370
371
# Test environment handling
verify_env_url
372

Joe Haddad's avatar
Joe Haddad committed
373
374
375
# Test reliance on webpack internals
verify_module_scope

Christopher Chedeau's avatar
Christopher Chedeau committed
376
# Cleanup
377
cleanup