diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..15567f4 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,12 @@ +language: generic + +services: + - docker + +install: + - curl -fsSL get.docksal.io | sh + - fin version + - fin sysinfo + +script: + - make && make test diff --git a/Dockerfile b/Dockerfile index eef5c72..62c5c25 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,26 +1,23 @@ -FROM mhart/alpine-node:6.10.0 +FROM node:8.5.0-alpine +ENV \ + PHANTOMJS_VERSION=2.1.1 \ + CASPERJS_VERSION=1.1.4 \ + SLIMERJS_VERSION=0.10.3 \ + BACKSTOPJS_VERSION=3.0.25 \ + # Workaround to fix phantomjs-prebuilt installation errors + # See https://github.com/Medium/phantomjs/issues/707 + NPM_CONFIG_UNSAFE_PERM=true + +# Base packages RUN apk add --no-cache \ bash \ - coreutils \ curl \ - git \ python \ - dbus \ - firefox-esr \ - fontconfig \ - ttf-freefont \ - xvfb + # Use GNU grep to avoid compatibility issues (busybox grep uses -r vs -R) + grep -# xvfb wrapper -COPY xvfb-run /usr/bin/xvfb-run - -ENV PHANTOMJS_VERSION 2.1.1 -ENV CASPERJS_VERSION 1.1.4 -ENV SLIMERJS_VERSION 0.10.3 -ENV BACKSTOPJS_VERSION 2.6.9 - -# Installing dependencies from archives - not only this allows us to control versions, +# Installing dependencies from archives - not only this allows us to control versions, # but the resulting image size is 130MB+ less (!) compared to an npm install (440MB vs 575MB). RUN \ mkdir -p /opt && \ @@ -55,6 +52,28 @@ RUN \ echo "Installing BackstopJS v${BACKSTOPJS_VERSION}..." && \ npm install -g backstopjs@${BACKSTOPJS_VERSION} +ENV \ + CHROMIUM_VERSION=61.0 \ + FIREFOX_VERSION=52.3 \ + CHROME_PATH=/usr/bin/chromium-browser + +# Chrome (from edge) +RUN apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/main --repository http://dl-cdn.alpinelinux.org/alpine/edge/community \ + "chromium>${CHROMIUM_VERSION}" + +# Firefox (from edge) +RUN apk add --no-cache \ + "firefox-esr>${FIREFOX_VERSION}" + +# SlimerJS dependencies +RUN \ + apk add --no-cache \ + dbus \ + xvfb + +# xvfb wrapper +COPY xvfb-run /usr/bin/xvfb-run + WORKDIR /src ENTRYPOINT ["backstop"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..bf789f0 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +-include env_make + +VERSION ?= 3 + +REPO = docksal/backstopjs +NAME = docksal-backstopjs-$(VERSION) + +.PHONY: build test push shell run start stop logs clean release + +build: + fin docker build -t $(REPO):$(VERSION) . + +test: + IMAGE=$(REPO):$(VERSION) NAME=$(NAME) tests/test.bats + +shell: + fin docker run --rm --name $(NAME) -it $(PORTS) $(VOLUMES) $(ENV) --entrypoint=bash $(REPO):$(VERSION) + +clean: + fin docker rm -f $(NAME) || true + +default: build diff --git a/README.md b/README.md index 614ce94..76cdc6f 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,21 @@ A self-contained Docker image to run [BackstopJS](https://github.com/garris/BackstopJS) with no external dependencies. +[Visual Regression Testing with BackstopJS in a Docker container](https://blog.docksal.io/visual-regression-testing-with-backstopjs-in-a-docker-container-dfd1b9ae8582) + Features: -- [BackstopJS 2.x](https://github.com/garris/BackstopJS) -- [PhantomJS](http://phantomjs.org/), -- [SlimerJS](https://slimerjs.org/) (with Firefox ESR), +- [BackstopJS 3.x](https://github.com/garris/BackstopJS) +- [PhantomJS](http://phantomjs.org/) +- [SlimerJS](https://slimerjs.org/) (with Firefox ESR) - [CasperJS](http://casperjs.org/) +- Chromium + + +## Versions + +- `docksal/backstopjs:2` - BackstopJS 2.x (legacy) +- `docksal/backstopjs` (`docksal/backstopjs:3`) - BackstopJS 3 with Chrome Headless support ## Usage @@ -17,7 +26,7 @@ Working directory is expected to be mounted at `/src` in the container. ``` $ docker run --rm -v $(pwd):/src docksal/backstopjs --version -BackstopJS 2.0.2 +BackstopJS v3.0.25 ``` You can also add a shell alias (in `.bashrc`, `.zshrc`, etc.) for convenience. @@ -30,26 +39,27 @@ Restart your shell or open a new one, then ``` $ backstopjs --version -BackstopJS 2.0.2 +BackstopJS v3.0.25 ``` ## Sample test ``` -docker run --rm -v $(pwd):/src docksal/backstopjs genConfig +docker run --rm -v $(pwd):/src docksal/backstopjs init docker run --rm -v $(pwd):/src docksal/backstopjs reference docker run --rm -v $(pwd):/src docksal/backstopjs test ``` -## PhantomJS/SlimerJS +## Browser engines -By default BackstopJS is using PhantomJS to take screenshots. -You can also use SlimerJS/Firefox by setting `"engine": "slimerjs"` -in the [configuration file](tests/backstop/backstop-example.json). +By default BackstopJS is using Headless Chrome to take screenshots. -Both SlimerJS and Firefox ESR (extended support release) are installed in the container. +You can also use PhantomJS or SlimerJS/Firefox by setting `"engine": "phantomjs"` or `"engine": "slimerjs"` respectively +in `backstop.json`. + +Chrome, PhantomJS, SlimerJS and Firefox ESR (extended support release) are pre-installed in the container. ## Limitations @@ -57,11 +67,14 @@ Both SlimerJS and Firefox ESR (extended support release) are installed in the co `backstop openReport` is not (yet) supported. You will need a running webserver to view HTML reports generated by BackstopJS. -When running SlimerJS, the user you are running the container as must have a home directory in order for Slimer to start properly. You can work around this by setting the HOME variable. Ex: +When running SlimerJS, the user you are running the container as must have a home directory in order for Slimer +to start properly. You can work around this by setting the `HOME` variable: + ``` docker run --rm --user 1000 -e HOME=/tmp/home docksal/backstopjs test ``` + ## Debugging The following command will start a bash session in the container. diff --git a/tests/test.bats b/tests/test.bats new file mode 100755 index 0000000..46448b2 --- /dev/null +++ b/tests/test.bats @@ -0,0 +1,79 @@ +#!/usr/bin/env bats + +PHANTOMJS_VERSION=2.1.1 +CASPERJS_VERSION=1.1.4 +SLIMERJS_VERSION=0.10.3 +BACKSTOPJS_VERSION=3.0.25 +CHROMIUM_VERSION=61.0 +FIREFOX_VERSION=52.3 + +# Debugging +teardown() { + echo + # TODO: figure out how to deal with this (output from previous run commands showing up along with the error message) + echo "Note: ignore the lines between \"...failed\" above and here" + echo + echo "Status: $status" + echo "Output:" + echo "================================================================" + echo "$output" + echo "================================================================" +} + +# Global skip +# Uncomment below, then comment skip in the test you want to debug. When done, reverse. +#SKIP=1 + +@test "Check PhantomJS" { + [[ $SKIP == 1 ]] && skip + + ### Tests ### + + run fin docker run --name ${NAME} --rm --entrypoint="" ${IMAGE} phantomjs --version + echo "$output" | grep -F ${PHANTOMJS_VERSION} +} + +@test "Check SlimerJS" { + [[ $SKIP == 1 ]] && skip + + ### Tests ### + + run fin docker run --name ${NAME} --rm --entrypoint="" ${IMAGE} slimerjs --version + echo "$output" | grep -F ${SLIMERJS_VERSION} +} + +@test "Check CasperJS" { + [[ $SKIP == 1 ]] && skip + + ### Tests ### + + run fin docker run --name ${NAME} --rm --entrypoint="" ${IMAGE} casperjs --version + echo "$output" | grep -F ${CASPERJS_VERSION} +} + +@test "Check BackstopJS" { + [[ $SKIP == 1 ]] && skip + + ### Tests ### + + run fin docker run --name ${NAME} --rm --entrypoint="" ${IMAGE} backstop --version + echo "$output" | grep -F ${BACKSTOPJS_VERSION} +} + +@test "Check Chrome" { + [[ $SKIP == 1 ]] && skip + + ### Tests ### + + run fin docker run --name ${NAME} --rm --entrypoint="" ${IMAGE} chromium-browser --version + echo "$output" | grep -F ${CHROMIUM_VERSION} +} + +@test "Check Firefox" { + [[ $SKIP == 1 ]] && skip + + ### Tests ### + + run fin docker run --name ${NAME} --rm --entrypoint="" ${IMAGE} firefox --version + echo "$output" | grep ${FIREFOX_VERSION} +}