devtools/e2e: add setup for running e2e in CI
A setup is added using docker-compose, which allows us to run e2e tests
locally and in CI.
As of this CL, e2e/basic.test.ts can be run locally using
`./e2e/docker/run.sh e2e/basic.test.ts`.
Change-Id: Ief17c51ed7ab7de9cc8c535a7061f18d75763ecd
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/326649
Trust: Julie Qiu <julie@golang.org>
Run-TryBot: Julie Qiu <julie@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
diff --git a/doc/frontend.md b/doc/frontend.md
index 591d2b0..7b96971 100644
--- a/doc/frontend.md
+++ b/doc/frontend.md
@@ -55,39 +55,18 @@
list of comma-separated strings each representing a path of a module to load
into memory.
-### Testing
+### End-to-End (E2E) Tests
-In addition to tests inside internal/frontend and internal/testing/integration,
-pages on pkg.go.dev may have accessibility tree and image snapshot tests. These
-tests will create diffs for inspection on failure. Timeouts and diff thresholds
-are configurable for image snapshots if adjustments are needed to prevent test
-flakiness. See the
+In addition to tests written in Go inside internal/frontend and
+internal/testing/integration, pages on pkg.go.dev may have accessibility tree
+and image snapshot tests. These tests will create diffs for inspection on
+failure. Timeouts and diff thresholds are configurable for image snapshots if
+adjustments are needed to prevent test flakiness. See the
[API](https://github.com/americanexpress/jest-image-snapshot#%EF%B8%8F-api) for
jest image snapshots for more information.
-The e2e tests require that npm and docker are installed on your machine.
-
-First run headless chrome
-
- docker run --rm -e "CONNECTION_TIMEOUT=-1" -p 3000:3000 browserless/chrome:1.46-chrome-stable
-
-Then run the tests
-
- BASE_URL=https://pkg.go.dev npm run e2e
-
-#### Writing E2E Tests
-
-Tests are written in the Jest framework using Puppeteer to drive a headless
-instance of Chrome.
-
-Familiarize yourself with the
-[Page](https://pptr.dev/#?product=Puppeteer&version=v5.5.0&show=api-class-page)
-class from the Puppeteer documenation. You'll find methods on this class that
-let you to interact with the page.
-
-Most tests will follow a similar structure but for details on the Jest
-framework and the various hooks and assertions see the
-[API](https://jestjs.io/docs/en/api).
+These tests are in the [e2e/ directory](../e2e). For details, see
+[e2e/README.md](../e2e/README.md).
## Static Assets
diff --git a/e2e/README.md b/e2e/README.md
new file mode 100644
index 0000000..9d56185
--- /dev/null
+++ b/e2e/README.md
@@ -0,0 +1,50 @@
+# End-to-End (E2E) Tests
+
+This directory contains end-to-end tests for pages on pkg.go.dev.
+
+## Running E2E Tests
+
+In order to run the tests, run this command from the root of the repository:
+
+```
+$ ./e2e/docker/run.sh
+```
+
+`./e2e/docker/run.sh` sets up a series of docker containers that run a postgres
+database, frontend, and headless chrome, and runs the e2e tests using headless
+chrome.
+
+Alternatively, you can run the tests against a website that is already running.
+
+First run headless chrome:
+
+ docker run --rm -e "CONNECTION_TIMEOUT=-1" -p 3000:3000 browserless/chrome:1.46-chrome-stable
+
+Then run the tests from the root of pkgsite:
+
+ ./all.bash npx jest [files]
+
+`PKGSITE_URL` can https://pkg.go.dev, or http://localhost:8080 if you have a
+local instance for the frontend running.
+
+### Understanding Test Failures
+
+If the tests failure, diffs will be created that show the cause of the failure.
+Timeouts and diff thresholds are configurable for image snapshots if
+adjustments are needed to prevent test flakiness. See the
+[API](https://github.com/americanexpress/jest-image-snapshot#%EF%B8%8F-api) for
+jest image snapshots for more information.
+
+### Writing E2E Tests
+
+Tests are written in the Jest framework using Puppeteer to drive a headless
+instance of Chrome.
+
+Familiarize yourself with the
+[Page](https://pptr.dev/#?product=Puppeteer&version=v5.5.0&show=api-class-page)
+class from the Puppeteer documenation. You'll find methods on this class that
+let you to interact with the page.
+
+Most tests will follow a similar structure but for details on the Jest
+framework and the various hooks and assertions see the
+[API](https://jestjs.io/docs/en/api).
diff --git a/e2e/docker/Dockerfile.frontend b/e2e/docker/Dockerfile.frontend
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/e2e/docker/Dockerfile.frontend
diff --git a/e2e/docker/docker-compose.yaml b/e2e/docker/docker-compose.yaml
new file mode 100644
index 0000000..9918d71
--- /dev/null
+++ b/e2e/docker/docker-compose.yaml
@@ -0,0 +1,65 @@
+# Copyright 2021 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+version: '3'
+services:
+ chrome:
+ image: browserless/chrome:1.46-chrome-stable
+ depends_on:
+ - frontend
+ ports:
+ - 3000:3000
+ environment:
+ - CONNECTION_TIMEOUT=120000
+ frontend:
+ build:
+ context: ../../
+ dockerfile: e2e/docker/Dockerfile.frontend
+ command: ./frontend -host=0.0.0.0:8080
+ depends_on:
+ - migrate
+ environment:
+ - GO_DISCOVERY_DATABASE_USER=postgres
+ - GO_DISCOVERY_DATABASE_PASSWORD=postgres
+ - GO_DISCOVERY_DATABASE_HOST=db
+ - GO_DISCOVERY_DATABASE_NAME=discovery_e2e_test
+ - PORT=8080
+ image: pkgsite_frontend
+ ports:
+ - 8080:8080
+ migrate:
+ depends_on:
+ - wait_for_db
+ image: migrate/migrate:v4.14.1
+ volumes:
+ - ../../migrations:/pkgsite/migrations
+ command:
+ [
+ '-path',
+ '/pkgsite/migrations',
+ '-database',
+ 'postgres://postgres:postgres@db:5432/discovery_e2e_test?sslmode=disable',
+ 'up',
+ ]
+ # wait_for_db is used to delay migrations until the database is ready for connections.
+ wait_for_db:
+ image: ubuntu:14.04
+ depends_on:
+ - db
+ command: >
+ /bin/bash -c "
+ while ! nc -z db 5432;
+ do
+ echo sleeping;
+ sleep 1;
+ done;
+ echo connected!;
+ "
+ db:
+ image: postgres:11.12
+ environment:
+ - POSTGRES_PASSWORD=postgres
+ - POSTGRES_USER=postgres
+ - POSTGRES_DB=discovery_e2e_test
+ ports:
+ - 5428:5432
diff --git a/e2e/docker/run.sh b/e2e/docker/run.sh
new file mode 100755
index 0000000..ddfc82c
--- /dev/null
+++ b/e2e/docker/run.sh
@@ -0,0 +1,54 @@
+#!/usr/bin/env bash
+
+# Copyright 2021 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+outfile="/tmp/e2e-chrome-$$.log"
+start_browser() {
+ # trap "kill 0" EXIT # kill the browser process on exit
+
+ docker-compose -f e2e/docker/docker-compose.yaml up -d chrome >& $outfile &
+ echo "Starting browser, output at $outfile"
+ sleep 30
+
+ # Wait for the browser to start up.
+ while ! curl -s http://localhost:3000 > /dev/null; do
+ sleep 1
+ done
+ echo "Browser is up."
+}
+
+main() {
+ start_browser
+
+ local files="e2e"
+ for arg in "$@"; do
+ if [[ $arg == e2e/* ]];then
+ files=""
+ fi
+ done
+
+ # Find the repo root.
+ script_dir=""
+ pkgsite_dir=""
+ if [[ "$OSTYPE" == "darwin"* ]]; then
+ # readlink doesn't work on Mac. Replace with greadlink.
+ script_dir=$(dirname "$(greadlink -f "$0")")
+ pkgsite_dir=$(greadlink -f "${script_dir}/../..")
+ else
+ script_dir=$(dirname "$(readlink -f "$0")")
+ pkgsite_dir=$(readlink -f "${script_dir}/../..")
+ fi
+
+ cd "${pkgsite_dir}"
+ GO_DISCOVERY_E2E_BASE_URL="http://frontend:8080"
+ (./devtools/ci/nodejs.sh npx jest $files $@)
+ echo "Done!"
+
+ echo "----- Contents of $outfile -----"
+ cat $outfile
+ docker-compose -f e2e/docker/docker-compose.yaml stop
+}
+
+main $@