Skip to content

Commit

Permalink
Replace PhantomJS with headless Chrome in tests
Browse files Browse the repository at this point in the history
Update our test/CI environment to a modern browser which matches what
our users use and supports modern web APIs and ES language features.

 - Add a Dockerfile which defines an image that includes everything
   needed to run client tests and deployment steps. This image uses
   plain Alpine as the base rather than Debian as this makes it easier
   to update frequently (every 6 months) to get a current Chrome build.

 - Replace PhantomJS with Puppeteer for testing locally and on Travis.
   Jenkins uses Chromium packages from Alpine.
  • Loading branch information
robertknight committed Aug 15, 2019
1 parent 8988a96 commit d7f22bb
Show file tree
Hide file tree
Showing 6 changed files with 867 additions and 888 deletions.
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Exclude large local dirs from the Docker build context to make the image build
# faster.

.git/
build/
coverage/
node_modules/
20 changes: 20 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# nb. We use Alpine as a base image and then install Node + Yarn separately
# rather than using a Node base image because this enables automated tools to
# upgrade everything by simply updating the Alpine version.
#
# Alpine is updated every 6 months so all packages are pretty recent.
FROM alpine:3.10

RUN apk update && apk add --no-cache \
chromium \
git \
make \
nodejs \
yarn

# Do not download a Chrome build as part of installing the "puppeteer" package,
# it won't work in Alpine.
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true

# Enable test scripts to detect that they are running from the Docker image.
ENV RUNNING_IN_DOCKER true
12 changes: 10 additions & 2 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
node {
checkout scm

nodeEnv = docker.image("node:10-stretch")
workspace = pwd()

// Tag used when deploying to NPM.
Expand Down Expand Up @@ -57,9 +56,18 @@ node {
}
echo "Building and testing ${newPkgVersion}"

sh "docker build -t hypothesis-client-tests ."
nodeEnv = docker.image("hypothesis-client-tests")

stage('Setup') {
nodeEnv.inside("-e HOME=${workspace}") {
sh "yarn install"
}
}

stage('Test') {
nodeEnv.inside("-e HOME=${workspace}") {
sh 'make test'
sh "make checkformatting lint test"
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@
"karma": "^4.0.0",
"karma-browserify": "^6.0.0",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage-istanbul-reporter": "^2.0.4",
"karma-mocha": "^1.1.1",
"karma-mocha-reporter": "^2.0.4",
"karma-phantomjs-launcher": "^1.0.1",
"karma-sinon": "^1.0.5",
"katex": "^0.10.0",
"lodash.debounce": "^4.0.3",
Expand All @@ -90,6 +90,7 @@
"postcss-url": "^8.0.0",
"preact": "10.0.0-rc.1",
"prettier": "1.18.2",
"puppeteer": "^1.2.0",
"query-string": "^3.0.1",
"raf": "^3.1.0",
"raven-js": "^3.7.0",
Expand Down
33 changes: 32 additions & 1 deletion src/karma.config.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
/* global process */

'use strict';

/* global __dirname */

const path = require('path');
const envify = require('loose-envify/custom');

let chromeFlags = [];
process.env.CHROME_BIN = require('puppeteer').executablePath();

// On Travis and in Docker, the tests run as root, so the sandbox must be
// disabled.
if (process.env.TRAVIS || process.env.RUNNING_IN_DOCKER) {
chromeFlags.push('--no-sandbox');
}

if (process.env.RUNNING_IN_DOCKER) {
// Disable `/dev/shm` usage as this can cause Chrome to fail to load large
// HTML pages, such as the one Karma creates with all the tests loaded.
//
// See https://github.com/GoogleChrome/puppeteer/issues/1834 and
// https://github.com/karma-runner/karma-chrome-launcher/issues/198.
chromeFlags.push('--disable-dev-shm-usage');

// Use Chromium from Alpine packages. The one that Puppeteer downloads won't
// load in Alpine.
process.env.CHROME_BIN = 'chromium-browser';
}

module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
Expand Down Expand Up @@ -138,9 +162,16 @@ module.exports = function(config) {

// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['PhantomJS'],
browsers: ['ChromeHeadless_Custom'],
browserNoActivityTimeout: 20000, // Travis is slow...

customLaunchers: {
ChromeHeadless_Custom: {
base: 'ChromeHeadless',
flags: chromeFlags,
},
},

// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
Expand Down
Loading

0 comments on commit d7f22bb

Please sign in to comment.