Skip to content

Commit

Permalink
Cypress Testing on CI (#9478)
Browse files Browse the repository at this point in the history
* Travis running cypress (#9411)

* updating dependencies to use custom fork of cypress-metamask

* add script and options for running cypress tests

* add wait-on package for scripting cypress runs

* travis docs indicate that bionic will start xvfb by adding it as a service

* add migration step

* another attempt at including cypress tests

* redirect webserver logs to /dev/null

* bad idea to move stdout to dev/null

* add NETWORK_NAME to travis env file

* update runserver command to go to background

* updating existing cypress tests to run on ci

* update docker-compose file: use default accounts for ganache

* add set -x to get more visibility into cypress command args

* update call to cypress run to see if travis will recognize flags

* try running cypress directly from node_modules

* remove set -x now that arguments are making their way to cypress

* Cypress testing/add connection metamask wallet test (#9429)

* updating dependencies to use custom fork of cypress-metamask

* add script and options for running cypress tests

* redirect webserver logs to /dev/null

* update docker-compose file: use default accounts for ganache

* test running connect site with metamask on ci

* attempt at passing in env from config

* add ganache-cli to dev dependencies

* updated script call

* moving where NETWORK_NAME is defined

* build please

* moving network_name again

* remove network_name

* add superuser creation to script

* take two at creating a superuser

* third times a charm - create superuser

* try loading user data from fixtures

* scroll metamask button into view

* add cypress settings to gain access to screenshots/videos

* no longer need the scrolling command

* add updated cypress-run to red-squirrel

* create make target and documentation for running cypress tests
  • Loading branch information
ksolo authored Sep 17, 2021
1 parent e990dc4 commit 29e8f78
Show file tree
Hide file tree
Showing 17 changed files with 5,109 additions and 548 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,7 @@ src/
_build/
**/.vs
**/dist/*

# cypress artifacts
cypress/videos
cypress/screenshots
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ services:
- docker
- postgresql
- redis
- xvfb

addons:
chrome: stable

cache:
npm: false
Expand Down Expand Up @@ -48,6 +52,8 @@ jobs:
- npm run stylelint
- (cd app; python3 ./manage.py collectstatic --noinput --disable-collectfast)
- pytest -p no:ethereum -p no:warnings
# Run cypress tests
- bin/ci/cypress-run
# Generate Markdown documentation and static docs page.
- pydocmd build
env:
Expand Down
17 changes: 15 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ ENV DEBIAN_FRONTEND=noninteractive

ARG PACKAGES="libpq-dev libxml2 libxslt1-dev libfreetype6 libjpeg-dev libmaxminddb-dev bash git tar gzip inkscape libmagic-dev"
ARG BUILD_DEPS="gcc g++ curl postgresql libxml2-dev libxslt-dev libfreetype6 libffi-dev libjpeg-dev autoconf automake libtool make dos2unix libvips libvips-dev"
WORKDIR /code
ARG CHROME_DEPS="fonts-liberation libasound2 libatk-bridge2.0-0 libatk1.0-0 libatspi2.0-0 libcairo2 libcups2 libcurl3-gnutls libdrm2 libexpat1 libgbm1 libglib2.0-0 libnspr4 libgtk-3-0 libpango-1.0-0 libx11-6 libxcb1 libxcomposite1 libxdamage1 libxext6 libxfixes3 libxkbcommon0 libxrandr2 libxshmfence1 xdg-utils"
ARG CYPRESS_DEPS="libgtk2.0-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libxtst6 xauth xvfb"

# Inkscape
RUN apt-get update
Expand All @@ -19,13 +20,24 @@ RUN apt-get install -y $PACKAGES
RUN apt-get update
RUN apt-get install -y $BUILD_DEPS

RUN apt-get install -y wget
# Install google chrome for cypress testing
WORKDIR /usr/src
RUN apt-get update && apt-get install -y wget
RUN wget "https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb"
RUN apt-get install -y $CHROME_DEPS
RUN dpkg -i google-chrome-stable_current_amd64.deb

# Install cypress dependencies
RUN apt-get install -y $CYPRESS_DEPS

RUN apt-get install -y libsodium-dev

RUN add-apt-repository universe
RUN apt-get update
RUN apt-get install -y python3-pip

WORKDIR /code

COPY dist/* ./

# GeoIP2 Data Files
Expand Down Expand Up @@ -58,6 +70,7 @@ RUN apt-get install -y yarn
RUN yarn global add n
RUN n stable

EXPOSE 9222
ENTRYPOINT ["/usr/local/bin/dumb-init", "--"]
CMD ["bash", "/bin/docker-command.bash"]

Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ logs: ## Print and actively tail the docker compose logs.
cypress: ## Open cypress testing UI
@npx cypress open

cypress-local: ## Run the cypress tests locally - the application MUST already be running for these to pass
@source "./app/app/.env"
@npx cypress install
@npx cypress run --headed --browser chrome

pytest: ## Run pytest (Backend)
@docker-compose exec -e PYTHONPATH=/code/app/ -e DJANGO_SETTINGS_MODULE="app.settings" web pytest -p no:ethereum

Expand Down
6 changes: 6 additions & 0 deletions app/app/local.env
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,9 @@ PREMAILER_CACHE_MAXSIZE=4096

GTC_DIST_API_URL=
GTC_DIST_KEY=

# CYPRESS METAMASK VARIABLES
NETWORK_NAME=localhost
SECRET_WORDS=
PASSWORD=
CYPRESS_REMOTE_DEBUGGING_PORT=9222
36 changes: 36 additions & 0 deletions bin/ci/cypress-run
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#! /bin/bash
set -eou pipefail

# start ganache and send to background
# using published ganache mnemonic - known globally and not a secret
export SECRET_WORDS="chief loud snack trend chief net field husband vote message decide replace"
node_modules/.bin/ganache-cli -m "${SECRET_WORDS}" -h 0.0.0.0 &

# build assets
mkdir -p app/assets/{static,media}
export STATICFILES_DIRS="${TRAVIS_BUILD_DIR}/app/assets/"
python3 app/manage.py bundle
yarn run build

python3 app/manage.py collectstatic --noinput --disable-collectfast

# set up database
python3 app/manage.py migrate
python3 app/manage.py loaddata "${TRAVIS_BUILD_DIR}/app/app/fixtures/users.json"
python3 app/manage.py loaddata "${TRAVIS_BUILD_DIR}/app/app/fixtures/profiles.json"

# run app server
python3 app/manage.py runserver 0.0.0.0:8000 &

# set required env vars and run cypress tests
export NETWORK_NAME=localhost
export PASSWORD="g1tc01nc0" # used in readme for root user account
export CYPRESS_REMOTE_DEBUGGING_PORT=9222
export VERBOSE=1
node_modules/.bin/cypress install
node_modules/.bin/wait-on http://0.0.0.0:8000
node_modules/.bin/cypress run \
--browser chrome \
--headed \
--record \
--key 23c824d9-b9eb-4aea-88fd-d0bb06a9eb51
1 change: 1 addition & 0 deletions bin/docker-command.bash
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ then
then
yarn run build
else
yarn cypress install
yarn run webpack &
fi
fi
Expand Down
6 changes: 5 additions & 1 deletion cypress.json
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
{}
{
"chromeWebSecurity": true,
"baseUrl": "http://localhost:8000",
"projectId": "e7rv3w"
}
24 changes: 24 additions & 0 deletions cypress/integration/connect-wallet/test_connect_with_metamask.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
describe('connect wallet: metamask', () => {
before(() => {
cy.setupMetamask();
cy.changeMetamaskNetwork('localhost');
});

after(() => {
cy.disconnectMetamaskWallet();
cy.clearWindows();
});

it('pulls address from metamask accounts', () => {
cy.impersonateUser();

cy.get('#navbarDropdownWallet').as('wallet').click();
cy.contains('Connect Wallet').click();
cy.contains('MetaMask').click();

cy.acceptMetamaskAccess();

cy.get('@wallet').click();
cy.get('#wallet-btn').should('contain.text', 'Change Wallet');
});
});
14 changes: 0 additions & 14 deletions cypress/integration/test_visit.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,12 @@ describe('Visit Tests', function() {
it('Visits the Kudos Marketplace', function() {
cy.visit('http://localhost:8000/kudos/marketplace');
});
/*
it('Visits the Kudos Sender', function() {
cy.visit('http://localhost:8000/kudos/send');
cy.url().should('contain', 'github.com');
});
*/
it('Visits the Labs Page', function() {
cy.visit('http://localhost:8000/explorer');
});
it('Visits the About Page', function() {
cy.visit('http://localhost:8000/about');
});
it('Visits the Mission Page', function() {
cy.visit('http://localhost:8000/mission');
});
/*
it('Visits the Results Page', function() {
cy.visit('http://localhost:8000/results');
});
*/
it('Visits the Activity Page', function() {
cy.visit('http://localhost:8000/activity');
});
Expand Down
1 change: 1 addition & 0 deletions cypress/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
require('cypress-metamask/plugins')(on);
};
81 changes: 81 additions & 0 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,84 @@
//
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })

// authentication
Cypress.Commands.add('loginRootUser', () => {
const url = '_administrationlogin/';

cy.request({url, method: 'GET', log: true}).then((response) => {
const body = Cypress.$(response.body);
const csrfmiddlewaretoken = body.find('input[name=csrfmiddlewaretoken]').val();

cy.request({
url,
method: 'POST',
body: {
csrfmiddlewaretoken,
username: 'root',
password: 'gitcoinco'
},
form: true
});
});
});

Cypress.Commands.add('impersonateUser', () => {
cy.loginRootUser();
cy.visit('impersonate/4/');
});

Cypress.Commands.add('logout', () => {
cy.request('logout/?next=/');
});

// grants
Cypress.Commands.add('createGrantSubmission', (options = {}) => {
cy.logout();
cy.impersonateUser();

const url = 'grants/new/';

return cy.request(url)
.then((response) => {
const body = Cypress.$(response.body);
const csrfmiddlewaretoken = body.find('input[name=csrfmiddlewaretoken]').val();

return cy.request({
url,
method: 'POST',
body: {
csrfmiddlewaretoken,
grant_type: options.grant_type || 'media',
title: options.title || 'Test Grant Submission',
description: options.description || 'Describing grant submission',
description_rich: options.description_rich || "{'ops':[{'insert':'The mission of the grant is to...},{'insert':'\n'}]}'",
has_external_funding: options.has_exeternal_funding || 'no',
eth_payout_address: options.eth_payout_address || '0xB81C935D01e734b3D8bb233F5c4E1D72DBC30f6c',
handle1: options.handle1 || '@gitcoin',
handle2: options.handle2 || '@kbw',
region: options.region || 'north_america',
reference_url: options.reference_url || 'https://gitcoin.co',
github_project_url: options.github_project_url || 'https://github.com/gitcoinco/web',
'team_members[]': options.team_members || '',
'categories[]': options.categories || 4
},
form: true
});
});
});

Cypress.Commands.add('approveGrant', (grantSlug) => {
cy.logout();
cy.loginRootUser();

const pk = grantSlug.match(/\/grants\/(\d*)\//)[1];
const changePath = `_administrationgrants/grant/${pk}/change/`;

cy.visit(changePath);
cy.get('[name=active]').check();
cy.get('[name=defer_clr_to]').select(pk);
cy.get('[name=_save]').click();

cy.logout();
});
2 changes: 2 additions & 0 deletions cypress/support/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

// Import commands.js using ES2015 syntax:
import './commands';
import 'cypress-metamask';

// Alternatively you can use CommonJS syntax:
// require('./commands')
Expand All @@ -24,3 +25,4 @@ Cypress.on('uncaught:exception', (err, runnable) => {
// failing the test
return false;
});

5 changes: 4 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ services:

web:
restart: unless-stopped
ipc: host
shm_size: '4gb'
environment:
- PYTHONUNBUFFERED=1
- PYTHONIOENCODING=utf8
Expand All @@ -63,6 +65,7 @@ services:
- "3030:3030"
- "8001:8001"
- "35729:35729"
- "9222:9222"
depends_on:
- db
stdin_open: true
Expand All @@ -79,7 +82,7 @@ services:
image: trufflesuite/ganache-cli
ports:
- "8545:8545"
command: '-a 1 --seed 2 --host 0.0.0.0 --mnemonic "${TEST_MNEMONIC}"'
command: '--host 0.0.0.0 --mnemonic "${TEST_MNEMONIC}"'
deploy:
replicas: 1
resources:
Expand Down
1 change: 1 addition & 0 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ To keep the style of the Javascript code consistent we have a basic linting conf
* 1 tab = 4 spaces for everything else
* Use `rem` for CSS when applicable
* Add relevant unit tests for all new Python logic and update existing tests to accommodate new logic. You can run tests via: `make pytest`
* Gitcoin uses Cypress for system tests. To run those locally you will first need to launch the application, and then use the `make cypress-local` target
* If you introduce new backend methods or classes, you must include docstrings that conform to PEP-257 and follow the existing patterns throughout the codebase. See `app/avatar/(models|views|utils).py` - If you introduce a new django module, like: `avatar` or `marketing`, you must update `pydocmd.yaml` to include relevant python modules from the newly introduced app.

### Step 4: Commit
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,19 @@
"babel-eslint": "^10.1.0",
"babel-loader": "^8.2.2",
"css-loader": "^5.2.4",
"cypress": "^3.4.1",
"cypress": "^8.3.1",
"eslint": "^7.14.0",
"file-loader": "^6.2.0",
"filemanager-webpack-plugin": "^4.0.0",
"ganache-cli": "^6.12.2",
"glob": "^7.1.6",
"sass": "^1.32.11",
"sass-loader": "^11.0.1",
"stylelint": "^9.10.1",
"stylelint-config-recommended": "^2.2.0",
"stylelint-scss": "^3.19.0",
"uglify-js": "^3.13.4",
"wait-on": "^6.0.0",
"webpack": "^5.36.0",
"webpack-cli": "^4.6.0",
"webpack-watched-glob-entries-plugin": "^2.1.9"
Expand All @@ -47,6 +49,7 @@
"@joeattardi/emoji-button": "^3.1.1",
"bootstrap": "4.6.0",
"bootstrap-vue": "2.18.0",
"cypress-metamask": "https://github.com/gitcoinco/cypress-metamask",
"daterangepicker": "3.0.5",
"dompurify": "^2.2.9",
"gsap": "3.6.0",
Expand Down
Loading

0 comments on commit 29e8f78

Please sign in to comment.