Initial commit adding integration tests. (#1557)
* Initial commit adding integration tests. * Fix test name. * Adding package-lock. * Some updates. * More updates. * Extend page comparison max to 9.99% * Removed node assert statement. * Updated baseline images and tests. * Added docs, fixed docker configuration file. * Updates. * Update docker compose. * Fix json error. * Add comment to Dockerfile. * Comment to trigger CI. * Moved dependencies to allow for docker image build. * Add restore command. * Fix restore command. * Change docker image. * Add checkout command. * Add java. * Add node version install. * Trying machine executor. * Fix typo.: * Remove old docker command. * EVERYTHING IN ONE SHELL. * Trying nvm. * Fix typo. * Fix node version... * Fix typo. * More node stuff. * Updates to docker compose. * Add chown to circleci config. * Fix docker login error. * Change exec command user. * Add screenshots for debugging. * Try fixing js command. * Try fixing js command again. * Change screenshot path * Add mkdir for error shots. * Trying something for postgres. * Updates. * Fix lint error. * Try fixing errorshots. * Updates before rebase. * Updated baseline for new homepage. * Remove baseline image save. * Trying a change for errorshots. * Update test.
This commit is contained in:
Родитель
d252cc2a29
Коммит
b19eff6d4a
|
@ -49,6 +49,28 @@ jobs:
|
||||||
name: Test Code
|
name: Test Code
|
||||||
command: docker run blurts-server npm run lint
|
command: docker run blurts-server npm run lint
|
||||||
|
|
||||||
|
integration-test:
|
||||||
|
machine:
|
||||||
|
image: ubuntu-1604:201903-01
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
name: Build and run tests.
|
||||||
|
command: |
|
||||||
|
export NVM_DIR="/opt/circleci/.nvm"
|
||||||
|
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||||
|
nvm use 10
|
||||||
|
node -v
|
||||||
|
cp .env-dist .env
|
||||||
|
npm install
|
||||||
|
npm install --only=dev
|
||||||
|
sudo chown -R $USER:$USER .
|
||||||
|
mkdir ./tests/integration/errorShots
|
||||||
|
docker-compose -f tests/integration/docker-compose.yml up --build -d
|
||||||
|
docker-compose -f tests/integration/docker-compose.yml exec --user root firefox npm run test:integration
|
||||||
|
- store_artifacts:
|
||||||
|
path: ./tests/integration/errorShots/
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
docker:
|
docker:
|
||||||
- image: docker:18.02.0-ce
|
- image: docker:18.02.0-ce
|
||||||
|
@ -98,7 +120,6 @@ workflows:
|
||||||
filters:
|
filters:
|
||||||
tags:
|
tags:
|
||||||
only: /.*/
|
only: /.*/
|
||||||
|
|
||||||
- deploy:
|
- deploy:
|
||||||
requires:
|
requires:
|
||||||
- build
|
- build
|
||||||
|
@ -111,3 +132,7 @@ workflows:
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
only: master
|
only: master
|
||||||
|
- integration-test:
|
||||||
|
requires:
|
||||||
|
- build
|
||||||
|
|
||||||
|
|
|
@ -41,19 +41,20 @@ BASKET_NEWSLETTER=mozilla-and-you
|
||||||
# leave FXA_ENABLED empty to disable FXA
|
# leave FXA_ENABLED empty to disable FXA
|
||||||
FXA_ENABLED=
|
FXA_ENABLED=
|
||||||
FXA_SETTINGS_URL="https://stable.dev.lcip.org/settings"
|
FXA_SETTINGS_URL="https://stable.dev.lcip.org/settings"
|
||||||
OAUTH_CLIENT_ID=cb1bef9d06bb9bc9
|
OAUTH_CLIENT_ID=edd29a80019d61a1
|
||||||
OAUTH_CLIENT_SECRET=f5fb99de6e0af18ab17e013ac1d439903179a97a1c510fc10bc3bd50bbce089b
|
OAUTH_CLIENT_SECRET=a80feaad77c847275d39ac989ee12a873ef6b54cbc184128f86f2afecdf003b5
|
||||||
OAUTH_AUTHORIZATION_URI="https://oauth-stable.dev.lcip.org/v1/authorization"
|
OAUTH_AUTHORIZATION_URI="https://oauth-stable.dev.lcip.org/v1/authorization"
|
||||||
OAUTH_PROFILE_URI="https://stable.dev.lcip.org/profile/v1/profile"
|
OAUTH_PROFILE_URI="https://stable.dev.lcip.org/profile/v1/profile"
|
||||||
OAUTH_TOKEN_URI="https://oauth-stable.dev.lcip.org/v1/token"
|
OAUTH_TOKEN_URI="https://oauth-stable.dev.lcip.org/v1/token"
|
||||||
|
|
||||||
# HIBP API for breach data
|
# HIBP API for breach data
|
||||||
HIBP_API_ROOT="https://stage.haveibeenpwned.com/api/v2/"
|
|
||||||
# How many seconds to wait before refreshing upstream breach data from HIBP
|
# How many seconds to wait before refreshing upstream breach data from HIBP
|
||||||
HIBP_RELOAD_BREACHES_TIMER=600
|
HIBP_RELOAD_BREACHES_TIMER=600
|
||||||
# HIBP API for range search and subscription
|
# HIBP API for range search and subscription
|
||||||
HIBP_KANON_API_ROOT="https://api.haveibeenpwned.com"
|
HIBP_KANON_API_ROOT="https://api.haveibeenpwned.com"
|
||||||
HIBP_KANON_API_TOKEN=""
|
HIBP_KANON_API_TOKEN=
|
||||||
|
HIBP_API_ROOT="https://haveibeenpwned.com/api/v2"
|
||||||
|
HIBP_API_TOKEN=
|
||||||
# How many milliseconds to wait before retrying an HIBP request
|
# How many milliseconds to wait before retrying an HIBP request
|
||||||
HIBP_THROTTLE_DELAY=2000
|
HIBP_THROTTLE_DELAY=2000
|
||||||
# Max number of times to try an HIBP request before throwing error
|
# Max number of times to try an HIBP request before throwing error
|
||||||
|
|
12
.eslintrc.js
12
.eslintrc.js
|
@ -35,7 +35,17 @@ module.exports = {
|
||||||
],
|
],
|
||||||
env: {
|
env: {
|
||||||
jest: true,
|
jest: true,
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
'tests/integration/**/*.js',
|
||||||
|
],
|
||||||
|
globals: {
|
||||||
|
"$": "readonly",
|
||||||
|
"$$": "readonly",
|
||||||
|
"browser": "readonly",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
|
|
|
@ -12,7 +12,7 @@ USER app
|
||||||
COPY package.json package.json
|
COPY package.json package.json
|
||||||
COPY package-lock.json package-lock.json
|
COPY package-lock.json package-lock.json
|
||||||
|
|
||||||
RUN npm install && rm -rf ~app/.npm /tmp/*
|
RUN npm install --production && rm -rf ~app/.npm /tmp/*
|
||||||
|
|
||||||
COPY --chown=app:app . /app
|
COPY --chown=app:app . /app
|
||||||
|
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
23
package.json
23
package.json
|
@ -10,9 +10,12 @@
|
||||||
"@sentry/node": "^4.2.3",
|
"@sentry/node": "^4.2.3",
|
||||||
"arg": "^2.0.0",
|
"arg": "^2.0.0",
|
||||||
"basic-auth": "^2.0.0",
|
"basic-auth": "^2.0.0",
|
||||||
|
"babel-minify": "^0.4.3",
|
||||||
"body-parser": "^1.18.3",
|
"body-parser": "^1.18.3",
|
||||||
|
"clean-css-cli": "^4.2.1",
|
||||||
"client-oauth2": "^4.2.1",
|
"client-oauth2": "^4.2.1",
|
||||||
"client-sessions": "^0.8.0",
|
"client-sessions": "^0.8.0",
|
||||||
|
"concat": "^1.0.3",
|
||||||
"cpr": "^3.0.1",
|
"cpr": "^3.0.1",
|
||||||
"csurf": "^1.9.0",
|
"csurf": "^1.9.0",
|
||||||
"dotenv": "^5.0.1",
|
"dotenv": "^5.0.1",
|
||||||
|
@ -33,14 +36,22 @@
|
||||||
"mozlog": "^2.2.0",
|
"mozlog": "^2.2.0",
|
||||||
"nodemailer": "^4.6.4",
|
"nodemailer": "^4.6.4",
|
||||||
"nodemailer-express-handlebars": "^3.0.0",
|
"nodemailer-express-handlebars": "^3.0.0",
|
||||||
|
"npm-run-all": "^4.1.5",
|
||||||
"pg": "^7.4.3",
|
"pg": "^7.4.3",
|
||||||
"sns-validator": "^0.3.4",
|
"sns-validator": "^0.3.4",
|
||||||
"uuid": "^3.2.1"
|
"uuid": "^3.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-minify": "^0.4.3",
|
"@wdio/cli": "^5.18.6",
|
||||||
|
"@wdio/dot-reporter": "^5.18.6",
|
||||||
|
"@wdio/firefox-profile-service": "^5.16.11",
|
||||||
|
"@wdio/local-runner": "^5.18.6",
|
||||||
|
"@wdio/mocha-framework": "^5.18.6",
|
||||||
|
"@wdio/selenium-standalone-service": "^5.16.10",
|
||||||
|
"@wdio/spec-reporter": "^5.18.6",
|
||||||
|
"@wdio/sync": "^5.18.5",
|
||||||
|
"chai": "^4.2.0",
|
||||||
"clean-css-cli": "^4.2.1",
|
"clean-css-cli": "^4.2.1",
|
||||||
"concat": "^1.0.3",
|
|
||||||
"coveralls": "^3.0.1",
|
"coveralls": "^3.0.1",
|
||||||
"eslint": "^4.18.1",
|
"eslint": "^4.18.1",
|
||||||
"eslint-plugin-node": "^6.0.1",
|
"eslint-plugin-node": "^6.0.1",
|
||||||
|
@ -51,12 +62,13 @@
|
||||||
"node-mocks-http": "^1.7.0",
|
"node-mocks-http": "^1.7.0",
|
||||||
"nodemon": "^1.18.7",
|
"nodemon": "^1.18.7",
|
||||||
"npm-audit-ci-wrapper": "^2.4.3",
|
"npm-audit-ci-wrapper": "^2.4.3",
|
||||||
"npm-run-all": "^4.1.5",
|
|
||||||
"onchange": "^6.1.0",
|
"onchange": "^6.1.0",
|
||||||
"postcss-cli": "^6.1.2",
|
"postcss-cli": "^6.1.2",
|
||||||
"stylelint": "^9.10.1",
|
"stylelint": "^9.10.1",
|
||||||
"stylelint-config-standard": "^18.2.0",
|
"stylelint-config-standard": "^18.2.0",
|
||||||
"uglify-js": "^3.4.9"
|
"uglify-js": "^3.4.9",
|
||||||
|
"wdio-docker-service": "^2.2.0",
|
||||||
|
"wdio-image-comparison-service": "^1.9.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "10"
|
"node": "10"
|
||||||
|
@ -116,6 +128,9 @@
|
||||||
"test:db:migrate": "NODE_ENV=tests knex migrate:latest --knexfile db/knexfile.js --env tests",
|
"test:db:migrate": "NODE_ENV=tests knex migrate:latest --knexfile db/knexfile.js --env tests",
|
||||||
"test:tests": "NODE_ENV=tests HIBP_THROTTLE_DELAY=1000 HIBP_THROTTLE_MAX_TRIES=3 jest --runInBand --coverage tests/",
|
"test:tests": "NODE_ENV=tests HIBP_THROTTLE_DELAY=1000 HIBP_THROTTLE_MAX_TRIES=3 jest --runInBand --coverage tests/",
|
||||||
"test:coveralls": "cat ./coverage/lcov.info | coveralls",
|
"test:coveralls": "cat ./coverage/lcov.info | coveralls",
|
||||||
|
"test:integration": "wdio tests/integration/wdio.conf.js",
|
||||||
|
"test:integration-headless": "MOZ_HEADLESS=1 wdio tests/integration/wdio.conf.js",
|
||||||
|
"test:integration-docker": "MOZ_HEADLESS=1 wdio tests/integration/wdio.docker.js",
|
||||||
"test": "run-s test:db:migrate test:tests test:coveralls"
|
"test": "run-s test:db:migrate test:tests test:coveralls"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Use this script to test if a given TCP host/port are available
|
||||||
|
|
||||||
|
WAITFORIT_cmdname=${0##*/}
|
||||||
|
|
||||||
|
echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
|
||||||
|
|
||||||
|
usage()
|
||||||
|
{
|
||||||
|
cat << USAGE >&2
|
||||||
|
Usage:
|
||||||
|
$WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
|
||||||
|
-h HOST | --host=HOST Host or IP under test
|
||||||
|
-p PORT | --port=PORT TCP port under test
|
||||||
|
Alternatively, you specify the host and port as host:port
|
||||||
|
-s | --strict Only execute subcommand if the test succeeds
|
||||||
|
-q | --quiet Don't output any status messages
|
||||||
|
-t TIMEOUT | --timeout=TIMEOUT
|
||||||
|
Timeout in seconds, zero for no timeout
|
||||||
|
-- COMMAND ARGS Execute command with args after the test finishes
|
||||||
|
USAGE
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for()
|
||||||
|
{
|
||||||
|
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
|
||||||
|
echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
|
||||||
|
else
|
||||||
|
echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
|
||||||
|
fi
|
||||||
|
WAITFORIT_start_ts=$(date +%s)
|
||||||
|
while :
|
||||||
|
do
|
||||||
|
if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
|
||||||
|
nc -z $WAITFORIT_HOST $WAITFORIT_PORT
|
||||||
|
WAITFORIT_result=$?
|
||||||
|
else
|
||||||
|
(echo > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
|
||||||
|
WAITFORIT_result=$?
|
||||||
|
fi
|
||||||
|
if [[ $WAITFORIT_result -eq 0 ]]; then
|
||||||
|
WAITFORIT_end_ts=$(date +%s)
|
||||||
|
echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
return $WAITFORIT_result
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_wrapper()
|
||||||
|
{
|
||||||
|
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
|
||||||
|
if [[ $WAITFORIT_QUIET -eq 1 ]]; then
|
||||||
|
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
|
||||||
|
else
|
||||||
|
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
|
||||||
|
fi
|
||||||
|
WAITFORIT_PID=$!
|
||||||
|
trap "kill -INT -$WAITFORIT_PID" INT
|
||||||
|
wait $WAITFORIT_PID
|
||||||
|
WAITFORIT_RESULT=$?
|
||||||
|
if [[ $WAITFORIT_RESULT -ne 0 ]]; then
|
||||||
|
echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
|
||||||
|
fi
|
||||||
|
return $WAITFORIT_RESULT
|
||||||
|
}
|
||||||
|
|
||||||
|
# process arguments
|
||||||
|
while [[ $# -gt 0 ]]
|
||||||
|
do
|
||||||
|
case "$1" in
|
||||||
|
*:* )
|
||||||
|
WAITFORIT_hostport=(${1//:/ })
|
||||||
|
WAITFORIT_HOST=${WAITFORIT_hostport[0]}
|
||||||
|
WAITFORIT_PORT=${WAITFORIT_hostport[1]}
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
--child)
|
||||||
|
WAITFORIT_CHILD=1
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
-q | --quiet)
|
||||||
|
WAITFORIT_QUIET=1
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
-s | --strict)
|
||||||
|
WAITFORIT_STRICT=1
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
-h)
|
||||||
|
WAITFORIT_HOST="$2"
|
||||||
|
if [[ $WAITFORIT_HOST == "" ]]; then break; fi
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--host=*)
|
||||||
|
WAITFORIT_HOST="${1#*=}"
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
-p)
|
||||||
|
WAITFORIT_PORT="$2"
|
||||||
|
if [[ $WAITFORIT_PORT == "" ]]; then break; fi
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--port=*)
|
||||||
|
WAITFORIT_PORT="${1#*=}"
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
-t)
|
||||||
|
WAITFORIT_TIMEOUT="$2"
|
||||||
|
if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--timeout=*)
|
||||||
|
WAITFORIT_TIMEOUT="${1#*=}"
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
WAITFORIT_CLI=("$@")
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
--help)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echoerr "Unknown argument: $1"
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
|
||||||
|
echoerr "Error: you need to provide a host and port to test."
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
|
||||||
|
WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
|
||||||
|
WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
|
||||||
|
WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
|
||||||
|
|
||||||
|
# Check to see if timeout is from busybox?
|
||||||
|
WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
|
||||||
|
WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
|
||||||
|
|
||||||
|
WAITFORIT_BUSYTIMEFLAG=""
|
||||||
|
if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
|
||||||
|
WAITFORIT_ISBUSY=1
|
||||||
|
# Check if busybox timeout uses -t flag
|
||||||
|
# (recent Alpine versions don't support -t anymore)
|
||||||
|
if timeout &>/dev/stdout | grep -q -e '-t '; then
|
||||||
|
WAITFORIT_BUSYTIMEFLAG="-t"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
WAITFORIT_ISBUSY=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $WAITFORIT_CHILD -gt 0 ]]; then
|
||||||
|
wait_for
|
||||||
|
WAITFORIT_RESULT=$?
|
||||||
|
exit $WAITFORIT_RESULT
|
||||||
|
else
|
||||||
|
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
|
||||||
|
wait_for_wrapper
|
||||||
|
WAITFORIT_RESULT=$?
|
||||||
|
else
|
||||||
|
wait_for
|
||||||
|
WAITFORIT_RESULT=$?
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $WAITFORIT_CLI != "" ]]; then
|
||||||
|
if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
|
||||||
|
echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
|
||||||
|
exit $WAITFORIT_RESULT
|
||||||
|
fi
|
||||||
|
exec "${WAITFORIT_CLI[@]}"
|
||||||
|
else
|
||||||
|
exit $WAITFORIT_RESULT
|
||||||
|
fi
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Build app for integration tests
|
||||||
|
FROM node:10
|
||||||
|
|
||||||
|
RUN useradd -d /app -u 1001 -g 1000 app
|
||||||
|
|
||||||
|
RUN npm update -g
|
||||||
|
RUN rm -rf /tmp/*
|
||||||
|
|
||||||
|
# RUN apk add --no-cache bash
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN chown app /app
|
||||||
|
|
||||||
|
USER app
|
||||||
|
|
||||||
|
COPY package.json package.json
|
||||||
|
COPY package-lock.json package-lock.json
|
||||||
|
|
||||||
|
RUN npm install && rm -rf ~app/.npm /tmp/*
|
||||||
|
|
||||||
|
COPY --chown=app:root . /app
|
||||||
|
|
||||||
|
RUN npm run build:all
|
||||||
|
|
||||||
|
CMD NODE_ICU_DATA=./node_modules/full-icu node server.js
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Firefox Monitor Integration tests
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
- Docker
|
||||||
|
- Docker-Compose
|
||||||
|
- [geckodriver]
|
||||||
|
- [npm]
|
||||||
|
- [nodejs]
|
||||||
|
|
||||||
|
## Firefox Setup
|
||||||
|
|
||||||
|
Make sure Firefox is in your system path if you want to watch the tests run inside your browser.
|
||||||
|
|
||||||
|
1. Follow setup instructions [here](https://github.com/mozilla/blurts-server#install).
|
||||||
|
2. Set appropriate ENV variables, HIBP_API_TOKEN, HIBP_KANON_API_TOKEN, MAILINATOR_PASSWORD
|
||||||
|
2. Build and start the containers: ```docker-compose -f tests/integration/docker-compose.yml up --build -d```.
|
||||||
|
3. Run the tests: ```npm run test:integration```.
|
||||||
|
They can also be run headlessly: ```npm run test:integration-headless```, and inside docker: ```npm run test:integration-docker```.
|
||||||
|
|
||||||
|
[geckodriver]: https://github.com/mozilla/geckodriver/releases
|
||||||
|
[npm]: https://docs.npmjs.com/
|
||||||
|
[nodejs]: https://nodejs.org/en/
|
|
@ -0,0 +1,55 @@
|
||||||
|
# Integration test docker-compose
|
||||||
|
version: "3.7"
|
||||||
|
services:
|
||||||
|
server:
|
||||||
|
build:
|
||||||
|
context: ../..
|
||||||
|
dockerfile: tests/integration/Dockerfile.integration-test.yml
|
||||||
|
ports:
|
||||||
|
- ${PORT}:${PORT}
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
environment:
|
||||||
|
- HIBP_KANON_API_TOKEN
|
||||||
|
- HIBP_API_TOKEN
|
||||||
|
- FXA_ENABLED=1
|
||||||
|
- LOGOS_ORIGIN=null
|
||||||
|
- BREACH_RESOLUTION_ENABLED=false
|
||||||
|
- MONITOR_FXA_PASSWORD
|
||||||
|
- DATABASE_URL=postgres://postgres@postgres:5432/blurts
|
||||||
|
links:
|
||||||
|
- postgres
|
||||||
|
postgres:
|
||||||
|
image: postgres
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=postgres
|
||||||
|
- POSTGRES_DB=blurts
|
||||||
|
- POSTGRES_HOST_AUTH_METHOD=trust
|
||||||
|
expose:
|
||||||
|
- "5432"
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
migration:
|
||||||
|
image: integration_server:latest
|
||||||
|
command: bash -c "chmod +x ./scripts/wait-for-it.sh && ./scripts/wait-for-it.sh postgres:5432 -- npm run db:migrate"
|
||||||
|
environment:
|
||||||
|
- DATABASE_URL=postgres://postgres@postgres:5432/blurts
|
||||||
|
links:
|
||||||
|
- postgres
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
firefox:
|
||||||
|
image: b4handjr/selenium-firefox:python3-latest
|
||||||
|
env_file: ../../.env
|
||||||
|
environment:
|
||||||
|
- MOZ_HEADLESS=1
|
||||||
|
- MONITOR_FXA_PASSWORD
|
||||||
|
volumes:
|
||||||
|
- ../../:/code
|
||||||
|
expose:
|
||||||
|
- "4444"
|
||||||
|
ports:
|
||||||
|
- "5900:5900"
|
||||||
|
shm_size: 2g
|
||||||
|
network_mode: host
|
|
@ -0,0 +1,21 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
class UserDashboardPage {
|
||||||
|
|
||||||
|
waitForPageToLoad() {
|
||||||
|
$("#dashboard").waitForExist(5000);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
get addEmailBox() { return $("#email-add"); }
|
||||||
|
get verificationLink() { return $("#email-add-submit"); }
|
||||||
|
manageEmailAddresses() {
|
||||||
|
const UserPreferencesPage = require("./userPreferences.page");
|
||||||
|
|
||||||
|
$(".manage-emails").waitForExist(5000);
|
||||||
|
$(".manage-emails").click();
|
||||||
|
return UserPreferencesPage.waitForPageToLoad();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = new UserDashboardPage();
|
|
@ -0,0 +1,29 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
class HomePage {
|
||||||
|
/* Represents the Home page */
|
||||||
|
|
||||||
|
waitForPageToLoad() {
|
||||||
|
this.monitorLogo.waitForExist(5000);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
get monitorLogo() { return $(".fx-monitor-logotype"); }
|
||||||
|
get breachCard() { return new BreachCard(); }
|
||||||
|
get breachEmailAddress() { return $("#scan-email"); }
|
||||||
|
get checkBreachesButton() {
|
||||||
|
$(".input-group-button > input:nth-child(1)").click();
|
||||||
|
const ScanResultsPage = require("./scanResults.page");
|
||||||
|
|
||||||
|
return ScanResultsPage.waitForPageToLoad();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BreachCard {
|
||||||
|
/* Represents the Breach card region */
|
||||||
|
|
||||||
|
get latestBreachCard() { return $(".latest-breach"); }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = new HomePage();
|
|
@ -0,0 +1,19 @@
|
||||||
|
/* global $$ */
|
||||||
|
/* global $ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
class ScanResultsPage {
|
||||||
|
|
||||||
|
waitForPageToLoad() {
|
||||||
|
$(".scan-results").waitForExist(5000);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
get numberOfBreaches() {
|
||||||
|
return $(".headline > span:nth-child(1)").getText();
|
||||||
|
}
|
||||||
|
get breachCards() { return $$(".breach-card"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = new ScanResultsPage();
|
|
@ -0,0 +1,13 @@
|
||||||
|
/* global $ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
class UserPreferencesPage {
|
||||||
|
|
||||||
|
waitForPageToLoad() {
|
||||||
|
$(".preferences").waitForExist(5000);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = new UserPreferencesPage();
|
|
@ -0,0 +1,9 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
class NavBar {
|
||||||
|
/* Represents the navbar */
|
||||||
|
|
||||||
|
get signIn() { return $("#sign-in-btn"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = new NavBar();
|
Двоичные данные
tests/integration/tests/Visual_Baseline/desktop_firefox/Breaches_Page-1920x1080.png
Normal file
Двоичные данные
tests/integration/tests/Visual_Baseline/desktop_firefox/Breaches_Page-1920x1080.png
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 173 KiB |
Двоичные данные
tests/integration/tests/Visual_Baseline/desktop_firefox/Breaches_Page-headless-1920x1080.png
Normal file
Двоичные данные
tests/integration/tests/Visual_Baseline/desktop_firefox/Breaches_Page-headless-1920x1080.png
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 99 KiB |
Двоичные данные
tests/integration/tests/Visual_Baseline/desktop_firefox/Home_Page-1920x1080.png
Normal file
Двоичные данные
tests/integration/tests/Visual_Baseline/desktop_firefox/Home_Page-1920x1080.png
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 695 KiB |
Двоичные данные
tests/integration/tests/Visual_Baseline/desktop_firefox/Home_Page-headless-1920x1080.png
Normal file
Двоичные данные
tests/integration/tests/Visual_Baseline/desktop_firefox/Home_Page-headless-1920x1080.png
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 414 KiB |
Двоичные данные
tests/integration/tests/Visual_Baseline/desktop_firefox/SecurityTips_Page-1920x1080.png
Normal file
Двоичные данные
tests/integration/tests/Visual_Baseline/desktop_firefox/SecurityTips_Page-1920x1080.png
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 5.2 MiB |
Двоичные данные
tests/integration/tests/Visual_Baseline/desktop_firefox/SecurityTips_Page-headless-1920x1080.png
Normal file
Двоичные данные
tests/integration/tests/Visual_Baseline/desktop_firefox/SecurityTips_Page-headless-1920x1080.png
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 3.0 MiB |
|
@ -0,0 +1,17 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
describe("Firefox Monitor Breaches Page", function() {
|
||||||
|
this.retries(2);
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
browser.url("/breaches");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should look like normal", function() {
|
||||||
|
expect(browser.checkFullPageScreen("Breaches_Page", {
|
||||||
|
hideElements: [
|
||||||
|
$$(".breach-info-wrapper"),
|
||||||
|
],
|
||||||
|
})).to.be.within(0, 9.99);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,81 @@
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const HomePage = require("../pages/desktop/home.page");
|
||||||
|
const NavBar = require("../regions/navbar.region");
|
||||||
|
const UserDashboardPage = require("../pages/desktop/dashboard.page");
|
||||||
|
|
||||||
|
describe("Firefox Monitor homepage", function() {
|
||||||
|
/* this.retries(2); */
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
browser.url("/");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should load the latest breach card", function() {
|
||||||
|
const homePage = HomePage;
|
||||||
|
|
||||||
|
homePage.waitForPageToLoad();
|
||||||
|
expect(homePage.breachCard.latestBreachCard.isDisplayed()).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should look like normal", function() {
|
||||||
|
expect(browser.checkFullPageScreen("Home_Page", {
|
||||||
|
hideElements: [
|
||||||
|
$$(".breach-info-wrapper"),
|
||||||
|
],
|
||||||
|
})).to.be.within(0, 9.99);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should load correct number of breaches from an email input", function() {
|
||||||
|
const homePage = HomePage;
|
||||||
|
|
||||||
|
homePage.waitForPageToLoad();
|
||||||
|
homePage.breachEmailAddress.setValue(global.primaryEmail);
|
||||||
|
const scanResults = homePage.checkBreachesButton;
|
||||||
|
expect(scanResults.breachCards.length)
|
||||||
|
.to
|
||||||
|
.equal(Number(scanResults.numberOfBreaches));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should allow secondary email to be added", function() {
|
||||||
|
const homePage = HomePage;
|
||||||
|
const navBar = NavBar;
|
||||||
|
|
||||||
|
homePage.waitForPageToLoad();
|
||||||
|
navBar.signIn.click();
|
||||||
|
// FxA login
|
||||||
|
// Check if fxa email is needed, if error, just continue
|
||||||
|
try {
|
||||||
|
$(".email").waitForExist(5000);
|
||||||
|
$(".email").click();
|
||||||
|
$(".email").setValue(global.primaryEmail);
|
||||||
|
$("#submit-btn").click();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
// FxA password login
|
||||||
|
$("#password").waitForExist(5000);
|
||||||
|
$("#password").click();
|
||||||
|
$("#password").setValue(global.monitorFxaPassword);
|
||||||
|
$("#submit-btn").click();
|
||||||
|
|
||||||
|
// Begin navigiation in monitor
|
||||||
|
const dashboard = UserDashboardPage.waitForPageToLoad();
|
||||||
|
dashboard.addEmailBox.setValue(global.secondaryEmail);
|
||||||
|
dashboard.verificationLink.click();
|
||||||
|
// Wait for dashboard to reload
|
||||||
|
try {
|
||||||
|
dashboard.waitForPageToLoad();
|
||||||
|
dashboard.manageEmailAddresses();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
const email = $$(".e-address")[1];
|
||||||
|
// Check email
|
||||||
|
expect(email.getText()).to.equal(global.secondaryEmail);
|
||||||
|
$(".remove-email-submit").click();
|
||||||
|
browser.refresh();
|
||||||
|
expect(email.getText()).to.equal(global.primaryEmail);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,13 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
describe("Firefox Monitor Security Tips Page", function() {
|
||||||
|
this.retries(2);
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
browser.url("/security-tips");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should look like normal", function() {
|
||||||
|
expect(browser.checkFullPageScreen("SecurityTips_Page", {})).to.be.within(0, 5);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
This file is used to create a baseline image for a webpage.
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
describe("Firefox Monitor homepage", function() {
|
||||||
|
this.retries(2);
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
browser.url("/");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should look like normal", function() {
|
||||||
|
browser.saveFullPageScreen("Home_Page", {
|
||||||
|
hideElements: [
|
||||||
|
$$(".breach-info-wrapper"),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
expect(browser.checkFullPageScreen("Home_Page", {
|
||||||
|
hideElements: [
|
||||||
|
$$(".breach-info-wrapper"),
|
||||||
|
],
|
||||||
|
})).to.equal(0);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,278 @@
|
||||||
|
/* eslint-disable no-process-env */
|
||||||
|
/* eslint-disable no-undef */
|
||||||
|
/* eslint-disable strict */
|
||||||
|
|
||||||
|
const { join } = require("path");
|
||||||
|
require("dotenv").config();
|
||||||
|
|
||||||
|
exports.config = {
|
||||||
|
//
|
||||||
|
// ====================
|
||||||
|
// Runner Configuration
|
||||||
|
// ====================
|
||||||
|
//
|
||||||
|
// WebdriverIO allows it to run your tests in arbitrary locations (e.g. locally or
|
||||||
|
// on a remote machine).
|
||||||
|
runner: "local",
|
||||||
|
//
|
||||||
|
// Override default path ('/wd/hub') for chromedriver service.
|
||||||
|
// path: '/wd/hub',
|
||||||
|
//
|
||||||
|
// ==================
|
||||||
|
// Specify Test Files
|
||||||
|
// ==================
|
||||||
|
// Define which test specs should run. The pattern is relative to the directory
|
||||||
|
// from which `wdio` was called. Notice that, if you are calling `wdio` from an
|
||||||
|
// NPM script (see https://docs.npmjs.com/cli/run-script) then the current working
|
||||||
|
// directory is where your package.json resides, so `wdio` will be called from there.
|
||||||
|
//
|
||||||
|
specs: [
|
||||||
|
"./tests/integration/tests/**/test-*-page.js",
|
||||||
|
],
|
||||||
|
// Patterns to exclude.
|
||||||
|
exclude: [
|
||||||
|
// 'path/to/excluded/files'
|
||||||
|
],
|
||||||
|
//
|
||||||
|
// ============
|
||||||
|
// Capabilities
|
||||||
|
// ============
|
||||||
|
// Define your capabilities here. WebdriverIO can run multiple capabilities at the same
|
||||||
|
// time. Depending on the number of capabilities, WebdriverIO launches several test
|
||||||
|
// sessions. Within your capabilities you can overwrite the spec and exclude options in
|
||||||
|
// order to group specific specs to a specific capability.
|
||||||
|
//
|
||||||
|
// First, you can define how many instances should be started at the same time. Let's
|
||||||
|
// say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have
|
||||||
|
// set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec
|
||||||
|
// files and you set maxInstances to 10, all spec files will get tested at the same time
|
||||||
|
// and 30 processes will get spawned. The property handles how many capabilities
|
||||||
|
// from the same test should run tests.
|
||||||
|
//
|
||||||
|
maxInstances: 1,
|
||||||
|
//
|
||||||
|
// If you have trouble getting all important capabilities together, check out the
|
||||||
|
// Sauce Labs platform configurator - a great tool to configure your capabilities:
|
||||||
|
// https://docs.saucelabs.com/reference/platforms-configurator
|
||||||
|
//
|
||||||
|
capabilities: [{
|
||||||
|
browserName: "firefox",
|
||||||
|
"moz:firefoxOptions": {
|
||||||
|
log: { level: "trace" },
|
||||||
|
prefs: {},
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
//
|
||||||
|
// ===================
|
||||||
|
// Test Configurations
|
||||||
|
// ===================
|
||||||
|
// Define all options that are relevant for the WebdriverIO instance here
|
||||||
|
//
|
||||||
|
// Level of logging verbosity: trace | debug | info | warn | error | silent
|
||||||
|
logLevel: "error",
|
||||||
|
//
|
||||||
|
// Set specific log levels per logger
|
||||||
|
// loggers:
|
||||||
|
// - webdriver, webdriverio
|
||||||
|
// - @wdio/applitools-service, @wdio/browserstack-service, @wdio/devtools-service, @wdio/sauce-service
|
||||||
|
// - @wdio/mocha-framework, @wdio/jasmine-framework
|
||||||
|
// - @wdio/local-runner, @wdio/lambda-runner
|
||||||
|
// - @wdio/sumologic-reporter
|
||||||
|
// - @wdio/cli, @wdio/config, @wdio/sync, @wdio/utils
|
||||||
|
// Level of logging verbosity: trace | debug | info | warn | error | silent
|
||||||
|
// logLevels: {
|
||||||
|
// webdriver: 'info',
|
||||||
|
// '@wdio/applitools-service': 'info'
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
// If you only want to run your tests until a specific amount of tests have failed use
|
||||||
|
// bail (default is 0 - don't bail, run all tests).
|
||||||
|
bail: 0,
|
||||||
|
//
|
||||||
|
// Set a base URL in order to shorten url command calls. If your `url` parameter starts
|
||||||
|
// with `/`, the base url gets prepended, not including the path portion of your baseUrl.
|
||||||
|
// If your `url` parameter starts without a scheme or `/` (like `some/path`), the base url
|
||||||
|
// gets prepended directly.
|
||||||
|
baseUrl: process.env.SERVER_URL,
|
||||||
|
//
|
||||||
|
// Default timeout for all waitFor* commands.
|
||||||
|
waitforTimeout: 10000,
|
||||||
|
//
|
||||||
|
// Default timeout in milliseconds for request
|
||||||
|
// if browser driver or grid doesn't send response
|
||||||
|
connectionRetryTimeout: 90000,
|
||||||
|
//
|
||||||
|
// Default request retries count
|
||||||
|
connectionRetryCount: 3,
|
||||||
|
//
|
||||||
|
// Test runner services
|
||||||
|
// Services take over a specific job you don't want to take care of. They enhance
|
||||||
|
// your test setup with almost no effort. Unlike plugins, they don't add new
|
||||||
|
// commands. Instead, they hook themselves up into the test process.
|
||||||
|
services: [
|
||||||
|
"firefox-profile", "selenium-standalone", ["image-comparison", {
|
||||||
|
baselineFolder: join(process.cwd(), "./tests/integration/tests/Visual_Baseline/"),
|
||||||
|
formatImageName: process.env.MOZ_HEADLESS ? "{tag}-headless-{width}x{height}" : "{tag}-{width}x{height}",
|
||||||
|
screenshotPath: join(process.cwd(), ".tmp/"),
|
||||||
|
savePerInstance: true,
|
||||||
|
// autoSaveBaseline: true,
|
||||||
|
}],
|
||||||
|
],
|
||||||
|
|
||||||
|
// Framework you want to run your specs with.
|
||||||
|
// The following are supported: Mocha, Jasmine, and Cucumber
|
||||||
|
// see also: https://webdriver.io/docs/frameworks.html
|
||||||
|
//
|
||||||
|
// Make sure you have the wdio adapter package for the specific framework installed
|
||||||
|
// before running any tests.
|
||||||
|
framework: "mocha",
|
||||||
|
//
|
||||||
|
// The number of times to retry the entire specfile when it fails as a whole
|
||||||
|
// specFileRetries: 1,
|
||||||
|
//
|
||||||
|
// Test reporter for stdout.
|
||||||
|
// The only one supported by default is 'dot'
|
||||||
|
// see also: https://webdriver.io/docs/dot-reporter.html
|
||||||
|
reporters: ["dot", "spec"],
|
||||||
|
|
||||||
|
//
|
||||||
|
// Options to be passed to Mocha.
|
||||||
|
// See the full list at http://mochajs.org/
|
||||||
|
mochaOpts: {
|
||||||
|
ui: "bdd",
|
||||||
|
timeout: 120000,
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// =====
|
||||||
|
// Hooks
|
||||||
|
// =====
|
||||||
|
// WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance
|
||||||
|
// it and to build services around it. You can either apply a single function or an array of
|
||||||
|
// methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got
|
||||||
|
// resolved to continue.
|
||||||
|
/**
|
||||||
|
* Gets executed once before all workers get launched.
|
||||||
|
* @param {Object} config wdio configuration object
|
||||||
|
* @param {Array.<Object>} capabilities list of capabilities details
|
||||||
|
*/
|
||||||
|
// onPrepare: function (config, capabilities) {
|
||||||
|
// },
|
||||||
|
/**
|
||||||
|
* Gets executed just before initialising the webdriver session and test framework. It allows you
|
||||||
|
* to manipulate configurations depending on the capability or spec.
|
||||||
|
* @param {Object} config wdio configuration object
|
||||||
|
* @param {Array.<Object>} capabilities list of capabilities details
|
||||||
|
* @param {Array.<String>} specs List of spec file paths that are to be run
|
||||||
|
*/
|
||||||
|
//beforeSession: function (config, capabilities, specs) {
|
||||||
|
//},
|
||||||
|
/**
|
||||||
|
* Gets executed before test execution begins. At this point you can access to all global
|
||||||
|
* variables like `browser`. It is the perfect place to define custom commands.
|
||||||
|
* @param {Array.<Object>} capabilities list of capabilities details
|
||||||
|
* @param {Array.<String>} specs List of spec file paths that are to be run
|
||||||
|
*/
|
||||||
|
before: function (capabilities, specs) {
|
||||||
|
const chai = require("chai");
|
||||||
|
|
||||||
|
global.expect = chai.expect;
|
||||||
|
chai.Should();
|
||||||
|
|
||||||
|
global.primaryEmail = "test@mailinator.com";
|
||||||
|
global.secondaryEmail = "test" + Math.random() + "@mailinator.com";
|
||||||
|
global.monitorFxaPassword = process.env.MONITOR_FXA_PASSWORD || "a_secure_password ;)";
|
||||||
|
browser.setWindowSize(1920, 1080);
|
||||||
|
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Runs before a WebdriverIO command gets executed.
|
||||||
|
* @param {String} commandName hook command name
|
||||||
|
* @param {Array} args arguments that command would receive
|
||||||
|
*/
|
||||||
|
// beforeCommand: function (commandName, args) {
|
||||||
|
// },
|
||||||
|
/**
|
||||||
|
* Hook that gets executed before the suite starts
|
||||||
|
* @param {Object} suite suite details
|
||||||
|
*/
|
||||||
|
// beforeSuite: function (suite) {
|
||||||
|
// },
|
||||||
|
/**
|
||||||
|
* Function to be executed before a test (in Mocha/Jasmine) starts.
|
||||||
|
*/
|
||||||
|
// beforeTest: function (test, context) {
|
||||||
|
// },
|
||||||
|
/**
|
||||||
|
* Hook that gets executed _before_ a hook within the suite starts (e.g. runs before calling
|
||||||
|
* beforeEach in Mocha)
|
||||||
|
*/
|
||||||
|
// beforeHook: function (test, context) {
|
||||||
|
// },
|
||||||
|
/**
|
||||||
|
* Hook that gets executed _after_ a hook within the suite starts (e.g. runs after calling
|
||||||
|
* afterEach in Mocha)
|
||||||
|
*/
|
||||||
|
// afterHook: function (test, context, { error, result, duration, passed, retries }) {
|
||||||
|
// },
|
||||||
|
/**
|
||||||
|
* Function to be executed after a test (in Mocha/Jasmine).
|
||||||
|
*/
|
||||||
|
afterTest: function(test, context, { error, result, duration, passed, retries }) {
|
||||||
|
/* Take screenshots for debugging on circleci */
|
||||||
|
if ("CIRCLECI" in process.env) {
|
||||||
|
const path = join(process.cwd(), "./tests/integration/errorShots/error-"+Date.now()+".png");
|
||||||
|
browser.saveScreenshot(path);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook that gets executed after the suite has ended
|
||||||
|
* @param {Object} suite suite details
|
||||||
|
*/
|
||||||
|
// afterSuite: function (suite) {
|
||||||
|
// },
|
||||||
|
/**
|
||||||
|
* Runs after a WebdriverIO command gets executed
|
||||||
|
* @param {String} commandName hook command name
|
||||||
|
* @param {Array} args arguments that command would receive
|
||||||
|
* @param {Number} result 0 - command success, 1 - command error
|
||||||
|
* @param {Object} error error object if any
|
||||||
|
*/
|
||||||
|
// afterCommand: function (commandName, args, result, error) {
|
||||||
|
// },
|
||||||
|
/**
|
||||||
|
* Gets executed after all tests are done. You still have access to all global variables from
|
||||||
|
* the test.
|
||||||
|
* @param {Number} result 0 - test pass, 1 - test fail
|
||||||
|
* @param {Array.<Object>} capabilities list of capabilities details
|
||||||
|
* @param {Array.<String>} specs List of spec file paths that ran
|
||||||
|
*/
|
||||||
|
// after: function (result, capabilities, specs) {
|
||||||
|
// },
|
||||||
|
/**
|
||||||
|
* Gets executed right after terminating the webdriver session.
|
||||||
|
* @param {Object} config wdio configuration object
|
||||||
|
* @param {Array.<Object>} capabilities list of capabilities details
|
||||||
|
* @param {Array.<String>} specs List of spec file paths that ran
|
||||||
|
*/
|
||||||
|
// afterSession: function (config, capabilities, specs) {
|
||||||
|
// },
|
||||||
|
/**
|
||||||
|
* Gets executed after all workers got shut down and the process is about to exit. An error
|
||||||
|
* thrown in the onComplete hook will result in the test run failing.
|
||||||
|
* @param {Object} exitCode 0 - success, 1 - fail
|
||||||
|
* @param {Object} config wdio configuration object
|
||||||
|
* @param {Array.<Object>} capabilities list of capabilities details
|
||||||
|
* @param {<Object>} results object containing test results
|
||||||
|
*/
|
||||||
|
// onComplete: function(exitCode, config, capabilities, results) {
|
||||||
|
// },
|
||||||
|
/**
|
||||||
|
* Gets executed when a refresh happens.
|
||||||
|
* @param {String} oldSessionId session ID of the old session
|
||||||
|
* @param {String} newSessionId session ID of the new session
|
||||||
|
*/
|
||||||
|
//onReload: function(oldSessionId, newSessionId) {
|
||||||
|
//}
|
||||||
|
};
|
|
@ -0,0 +1,37 @@
|
||||||
|
/* eslint-disable no-process-env */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const common = require("./wdio.conf.js");
|
||||||
|
const { join } = require("path");
|
||||||
|
|
||||||
|
exports.config = Object.assign({}, common.config, {
|
||||||
|
baseUrl: "http://localhost:6060",
|
||||||
|
maxInstances: 3,
|
||||||
|
services: ["docker", "firefox-profile", "selenium-standalone", ["image-comparison", {
|
||||||
|
baselineFolder: join(process.cwd(), "./tests/integration/tests/Visual_Baseline/"),
|
||||||
|
formatImageName: process.env.MOZ_HEADLESS ? "{tag}-headless-{width}x{height}" : "{tag}-{width}x{height}",
|
||||||
|
screenshotPath: join(process.cwd(), ".tmp/"),
|
||||||
|
savePerInstance: true,
|
||||||
|
}]],
|
||||||
|
dockerOptions: {
|
||||||
|
image: "selenium/standalone-firefox",
|
||||||
|
healthCheck: {
|
||||||
|
url: "http://localhost:4444",
|
||||||
|
maxRetries: 3,
|
||||||
|
inspectInterval: 1000,
|
||||||
|
startDelay: 2000,
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
e: ["MOZ_HEADLESS=1",
|
||||||
|
"MONITOR_FXA_PASSWORD=${MONITOR_FXA_PASSWORD}",
|
||||||
|
"HIBP_KANON_API_TOKEN=${HIBP_KANON_API_TOKEN}",
|
||||||
|
"HIBP_API_TOKEN=${HIBP_API_TOKEN}",
|
||||||
|
],
|
||||||
|
p: ["4444:4444", "5900:5900"],
|
||||||
|
v: "/dev/shm:/dev/shm",
|
||||||
|
shmSize: "2g",
|
||||||
|
network: "host",
|
||||||
|
},
|
||||||
|
dockerLogs: "docker-logs/",
|
||||||
|
},
|
||||||
|
});
|
Загрузка…
Ссылка в новой задаче