add selenium doc and prepare script
We have no documentation in Confluence or this repo for running Selenium tests natively. This commit adds a doc for that. We're also migrating the "prepare" script from the qa_tools repo to this one. Test Plan: - follow the instructions in doc/testing_with_selenium.md to verify it's accurate - run script/canvas_update to verify it still works - follow the setup instructions in script/prepare/README.md and verify it works Change-Id: I11d63e60dc1faa8be1dfacfc9bebfcbea55c31f1 Reviewed-on: https://gerrit.instructure.com/167300 Tested-by: Jenkins Reviewed-by: David Tan <dtan@instructure.com> QA-Review: David Tan <dtan@instructure.com> Product-Review: Michael Hargiss <mhargiss@instructure.com>
This commit is contained in:
parent
f119cfd489
commit
3cfbdf31ac
|
@ -0,0 +1,90 @@
|
|||
# Testing with Selenium
|
||||
|
||||
You may run the Selenium tests either natively or in docker.
|
||||
|
||||
## Running Selenium Tests Natively (Mac)
|
||||
|
||||
We're making a few assumptions here:
|
||||
- you're using an Apple computer
|
||||
- you've already installed Homebrew
|
||||
- you've already installed Postgres (postgresapp.com is an excellent option),
|
||||
and Postgres is running on your computer
|
||||
- you've already installed Node.js
|
||||
|
||||
0. Install `yarn` if you haven't already:
|
||||
|
||||
```sh
|
||||
brew install yarn
|
||||
```
|
||||
|
||||
If you find you need an older version of yarn, follow these instructions to
|
||||
install the older version and switch to it:
|
||||
|
||||
[https://stackoverflow.com/a/52525732/3038677](https://stackoverflow.com/a/52525732/3038677)
|
||||
|
||||
1. Follow the instructions in `script/prepare/README.md` to setup the `prepare`
|
||||
script.
|
||||
|
||||
You'll use the `prepare` script later to automate installing and updating Canvas
|
||||
on your computer.
|
||||
|
||||
Note: some features of `prepare` only work if you have access to Instructure's
|
||||
Gerrit host. See the README for details.
|
||||
|
||||
2. Install a web browser driver on your computer for the browser you wish to run
|
||||
the tests in. Homebrew is the easiest way to go:
|
||||
|
||||
```sh
|
||||
brew install chromedriver # necessary for running tests in Chrome
|
||||
brew install geckodriver # necessary for running tests in Firefox
|
||||
```
|
||||
|
||||
Now let's get Canvas ready to run the tests.
|
||||
|
||||
3. Copy the Selenium and database configuration files:
|
||||
|
||||
```sh
|
||||
cp config/selenium.yml.example config/selenium.yml
|
||||
cp config/database.yml.example config/database.yml
|
||||
```
|
||||
|
||||
4. Use `prepare` to install Canvas plugins and dependencies, create databases,
|
||||
run database migrations, etc:
|
||||
|
||||
```sh
|
||||
prepare
|
||||
```
|
||||
|
||||
You might encounter problems with some Ruby dependencies. The ["Dependency
|
||||
Installation" section](https://github.com/instructure/canvas-lms/wiki/Quick-Start#dependency-installation)
|
||||
in the public Canvas LMS Github wiki has some useful tips.
|
||||
|
||||
4.a. Optional. Run delayed jobs in the foreground (not all Selenium tests need
|
||||
this but some do):
|
||||
|
||||
```sh
|
||||
script/delayed_job run
|
||||
```
|
||||
|
||||
or run it in the background:
|
||||
|
||||
```sh
|
||||
script/delayed_job run &
|
||||
```
|
||||
|
||||
5. Run the Selenium tests:
|
||||
|
||||
```sh
|
||||
bundle exec rspec spec/selenium
|
||||
```
|
||||
|
||||
or run a specific Selenium test:
|
||||
|
||||
```sh
|
||||
bundle exec rspec spec/selenium/accounts_spec.rb:36
|
||||
```
|
||||
|
||||
## Running Selenium Tests in Docker
|
||||
|
||||
See the [Selenium section](https://github.com/instructure/canvas-lms/blob/master/doc/docker/developing_with_docker.md#selenium)
|
||||
of the `doc/docker/developing_with_docker.md` instructions.
|
|
@ -1,5 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
source script/common.sh
|
||||
|
||||
LOG="$(pwd)/log/canvas_update.log"
|
||||
|
||||
# TODO: improve usage / help
|
||||
function usage {
|
||||
echo "usage: canvas_update [-qhv] [-n phase]"
|
||||
|
@ -10,104 +14,6 @@ function bad_usage {
|
|||
exit 1
|
||||
}
|
||||
|
||||
function echo_console_and_log {
|
||||
echo "$1"
|
||||
echo "$1" >>"$LOG"
|
||||
}
|
||||
|
||||
function is_git_dir {
|
||||
git rev-parse --is-inside-git-dir >/dev/null 2>&1 && [ -d .git ]
|
||||
return $?
|
||||
}
|
||||
|
||||
function is_canvas_root {
|
||||
CANVAS_IN_README=$(head -1 README.md 2>/dev/null | grep 'Canvas LMS')
|
||||
[[ "$CANVAS_IN_README" != "" ]] && is_git_dir
|
||||
return $?
|
||||
}
|
||||
|
||||
function ensure_in_canvas_root_directory {
|
||||
if ! is_canvas_root; then
|
||||
echo "Please run from a Canvas root directory"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
function intro_message {
|
||||
echo "Bringing Canvas up to date ..."
|
||||
echo " Log file is $LOG"
|
||||
|
||||
echo >>"$LOG"
|
||||
echo "-----------------------------" >>"$LOG"
|
||||
echo "Canvas Update ($(date)):" >>"$LOG"
|
||||
echo "-----------------------------" >>"$LOG"
|
||||
}
|
||||
|
||||
function update_plugin {
|
||||
(
|
||||
cd "$1"
|
||||
if is_git_dir; then
|
||||
echo_console_and_log " Updating plugin $1 ..."
|
||||
( git checkout master >>"$LOG" 2>&1 && \
|
||||
git pull --rebase >>"$LOG" 2>&1 ) || \
|
||||
( echo " failed to pull plugin (see $LOG)"; kill -INT $$ )
|
||||
fi
|
||||
)
|
||||
}
|
||||
|
||||
function update_plugins {
|
||||
# Loop through each plugin dir, and if it's a git repo, update it
|
||||
# This needs to be done first so that db:migrate can pull in any plugin-
|
||||
# precipitated changes to the database.
|
||||
for dir in {gems,vendor}; do
|
||||
if [ -d "$dir/plugins" ]; then
|
||||
for plugin in $dir/plugins/*; do update_plugin "$plugin"; done
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function rebase_canvas {
|
||||
echo_console_and_log " Pulling Canvas code ..."
|
||||
( git checkout master >>"$LOG" 2>&1 && git pull --rebase >>"$LOG" 2>&1 ) || \
|
||||
( echo " failed to pull Canvas (see $LOG)"; kill -INT $$ )
|
||||
}
|
||||
|
||||
function bundle_install_with_check {
|
||||
echo_console_and_log " Checking your gems (bundle check) ..."
|
||||
if bundle check >>"$LOG" 2>&1 ; then
|
||||
echo_console_and_log " Gems are up to date, no need to bundle install ..."
|
||||
else
|
||||
bundle_install
|
||||
fi
|
||||
}
|
||||
|
||||
function bundle_install {
|
||||
echo_console_and_log " Installing gems (bundle install) ..."
|
||||
rm Gemfile.lock* >/dev/null 2>&1
|
||||
bundle install >>"$LOG" 2>&1 || \
|
||||
( echo " failed to bundle install (see $LOG)"; kill -INT $$ )
|
||||
}
|
||||
|
||||
function rake_db_migrate_dev_and_test {
|
||||
echo_console_and_log " Migrating DB ..."
|
||||
RAILS_ENV=development bundle exec rake db:migrate >>"$LOG" 2>&1 || \
|
||||
( echo " failed to migrate db (development) (see $LOG)"; kill -INT $$ )
|
||||
RAILS_ENV=test bundle exec rake db:migrate >>"$LOG" 2>&1 || \
|
||||
( echo " failed to migrate db (test) (see $LOG)"; kill -INT $$ )
|
||||
}
|
||||
|
||||
function yarn_install {
|
||||
echo_console_and_log " Installing node packages ..."
|
||||
yarn install >>"$LOG" 2>&1 || \
|
||||
( echo " failed to install node packages (see $LOG)"; kill -INT $$ )
|
||||
}
|
||||
|
||||
function compile_assets {
|
||||
echo_console_and_log " compiling assets ..."
|
||||
bundle exec rake 'canvas:compile_assets_dev' >>"$LOG" 2>&1 || \
|
||||
( echo " failed to generate JS (see $LOG)"; kill -INT $$ )
|
||||
}
|
||||
|
||||
# TODO: moar tips plz
|
||||
function tips {
|
||||
echo "Tips:"
|
||||
|
@ -117,16 +23,17 @@ function tips {
|
|||
|
||||
function update_canvas {
|
||||
ensure_in_canvas_root_directory
|
||||
intro_message
|
||||
intro_message "Canvas Update"
|
||||
|
||||
if [[ -z "$SKIP_CODE" ]] ; then
|
||||
update_plugins
|
||||
checkout_master_canvas
|
||||
rebase_canvas
|
||||
fi
|
||||
|
||||
if [[ -z "$SKIP_DEPS" ]] ; then
|
||||
bundle_install_with_check
|
||||
yarn_install
|
||||
install_node_packages
|
||||
fi
|
||||
|
||||
if [[ -z "$SKIP_DATA" ]] ; then
|
||||
|
@ -144,8 +51,6 @@ function update_canvas {
|
|||
fi
|
||||
}
|
||||
|
||||
LOG="$(pwd)/log/canvas_update.log"
|
||||
|
||||
# default options
|
||||
PERFORM_UPDATE=true
|
||||
QUICK_MODE=false
|
||||
|
@ -184,6 +89,7 @@ do
|
|||
esac
|
||||
done
|
||||
|
||||
if $PERFORM_UPDATE; then
|
||||
if [ "$PERFORM_UPDATE" == "true" ]; then
|
||||
trap print_results INT TERM EXIT
|
||||
update_canvas
|
||||
fi
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
#!/bin/bash
|
||||
|
||||
# This file contains commonly used BASH functions for scripting in canvas-lms,
|
||||
# particularly script/canvas_update and script/prepare/prepare . As such,
|
||||
# *be careful* when you modify these functions as doing so will impact multiple
|
||||
# scripts that likely aren't used or tested in continuous integration builds.
|
||||
|
||||
function echo_console_and_log {
|
||||
echo "$1"
|
||||
echo "$1" >>"$LOG"
|
||||
}
|
||||
|
||||
function print_results {
|
||||
exit_code=$?
|
||||
set +e
|
||||
|
||||
if [ "${exit_code}" == "0" ]; then
|
||||
echo ""
|
||||
echo_console_and_log " \o/ Success!"
|
||||
else
|
||||
echo ""
|
||||
echo_console_and_log " /o\ Something went wrong. Check ${LOG} for details."
|
||||
fi
|
||||
|
||||
exit ${exit_code}
|
||||
}
|
||||
|
||||
function ensure_in_canvas_root_directory {
|
||||
if ! is_canvas_root; then
|
||||
echo "Please run from a Canvas root directory"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
function is_canvas_root {
|
||||
CANVAS_IN_README=$(head -1 README.md 2>/dev/null | grep 'Canvas LMS')
|
||||
[[ "$CANVAS_IN_README" != "" ]] && is_git_dir
|
||||
return $?
|
||||
}
|
||||
|
||||
function is_git_dir {
|
||||
git rev-parse --is-inside-git-dir >/dev/null 2>&1 && [ -d .git ]
|
||||
return $?
|
||||
}
|
||||
|
||||
# Parameter: the name of the script calling this function
|
||||
function intro_message {
|
||||
script_name="$1"
|
||||
echo "Bringing Canvas up to date ..."
|
||||
echo " Log file is $LOG"
|
||||
|
||||
echo >>"$LOG"
|
||||
echo "-----------------------------" >>"$LOG"
|
||||
echo "$1 ($(date)):" >>"$LOG"
|
||||
echo "-----------------------------" >>"$LOG"
|
||||
}
|
||||
|
||||
function update_plugin {
|
||||
(
|
||||
cd "$1"
|
||||
if is_git_dir; then
|
||||
echo_console_and_log " Updating plugin $1 ..."
|
||||
git checkout master >>"$LOG" 2>&1
|
||||
git pull --rebase >>"$LOG" 2>&1
|
||||
fi
|
||||
)
|
||||
}
|
||||
|
||||
function update_plugins {
|
||||
# Loop through each plugin dir, and if it's a git repo, update it
|
||||
# This needs to be done first so that db:migrate can pull in any plugin-
|
||||
# precipitated changes to the database.
|
||||
for dir in {gems,vendor}; do
|
||||
if [ -d "$dir/plugins" ]; then
|
||||
for plugin in $dir/plugins/*; do update_plugin "$plugin"; done
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function checkout_master_canvas {
|
||||
echo_console_and_log " Checking out canvas-lms master ..."
|
||||
git checkout master >>"$LOG" 2>&1
|
||||
}
|
||||
|
||||
function rebase_canvas {
|
||||
echo_console_and_log " Rebasing canvas-lms on HEAD ..."
|
||||
git pull --rebase >>"$LOG" 2>&1
|
||||
}
|
||||
|
||||
function bundle_install {
|
||||
echo_console_and_log " Installing gems (bundle install) ..."
|
||||
rm Gemfile.lock* >/dev/null 2>&1
|
||||
bundle install >>"$LOG" 2>&1
|
||||
}
|
||||
|
||||
function bundle_install_with_check {
|
||||
echo_console_and_log " Checking your gems (bundle check) ..."
|
||||
if bundle check >>"$LOG" 2>&1 ; then
|
||||
echo_console_and_log " Gems are up to date, no need to bundle install ..."
|
||||
else
|
||||
bundle_install
|
||||
fi
|
||||
}
|
||||
|
||||
function rake_db_migrate_dev_and_test {
|
||||
echo_console_and_log " Migrating development DB ..."
|
||||
RAILS_ENV=development bundle exec rake db:migrate >>"$LOG" 2>&1
|
||||
|
||||
echo_console_and_log " Migrating test DB ..."
|
||||
RAILS_ENV=test bundle exec rake db:migrate >>"$LOG" 2>&1
|
||||
}
|
||||
|
||||
function install_node_packages {
|
||||
echo_console_and_log " Installing Node packages ..."
|
||||
bundle exec rake js:yarn_install >>"$LOG" 2>&1
|
||||
}
|
||||
|
||||
function compile_assets {
|
||||
echo_console_and_log " Compiling assets (css and js only, no docs or styleguide) ..."
|
||||
bundle exec rake canvas:compile_assets_dev >>"$LOG" 2>&1
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
# prepare
|
||||
|
||||
There are numerous tasks to execute after checking out a Canvas patchset...
|
||||
compile assets, migrate database changes, update plugins, etc. Forgetting to do
|
||||
any one of these may bork your testing, possibly even produce false positives!
|
||||
|
||||
Sometimes all you need is the latest master branch of canvas-lms, but you can't
|
||||
quite recall all the database migration and asset compilation tasks.
|
||||
|
||||
`prepare` takes care of all that for you.
|
||||
|
||||
## What does it do exactly?
|
||||
|
||||
`prepare` will:
|
||||
|
||||
1. Make sure you're in a canvas root directory
|
||||
2. Pull the code changes (either from master or from the patchset you've specified)
|
||||
3. Update Canvas plugins
|
||||
4. Check if your Canvas gem dependencies need updating
|
||||
* If they do, it will install them for you
|
||||
5. Migrate any database changes to your development db
|
||||
6. Migrate any database changes to your test db
|
||||
7. Install Canvas javascript dependencies if they aren't already installed
|
||||
8. Compile CSS and Javascript
|
||||
9. Make you happy :smiley:
|
||||
|
||||
It can also nuke your Javascript dependencies, force re-install them, and more.
|
||||
See the full feature list below.
|
||||
|
||||
## Setup
|
||||
|
||||
Add a symlink to `prepare` in your /usr/local/bin/ directory, like so:
|
||||
|
||||
```bash
|
||||
$ cd canvas-lms/script/prepare/
|
||||
$ ln -s $(pwd)/prepare /usr/local/bin/prepare
|
||||
```
|
||||
|
||||
You're all set!
|
||||
|
||||
## How do I use it?
|
||||
|
||||
This works just like Portals. To checkout a specific patchset, copy its unique
|
||||
ID from gerrit. Then execute:
|
||||
|
||||
```bash
|
||||
$ prepare <commit_id>
|
||||
```
|
||||
|
||||
For example:
|
||||
```bash
|
||||
$ prepare 89/12345/67
|
||||
```
|
||||
|
||||
Or, if you just want to checkout master, do this:
|
||||
```bash
|
||||
$ git checkout master
|
||||
$ prepare
|
||||
```
|
||||
|
||||
## What else can it do for me?
|
||||
|
||||
Let's say you've branched off master and committed code changes. Now you want to
|
||||
test your changes against the latest Canvas code base on master before you push
|
||||
your code for review.
|
||||
|
||||
You can easily `git pull --rebase` (provided you've already done
|
||||
`git branch --set-upstream-to=origin/master`), but what if there have been
|
||||
database, gem, or css changes since you branched?
|
||||
|
||||
You can update all those manually. Or you can let `prepare` do it for you.
|
||||
|
||||
Simply:
|
||||
```bash
|
||||
$ prepare
|
||||
```
|
||||
|
||||
It will `git pull --rebase`, then update your database, compile css, etc.
|
||||
(Again, see the "What does it do exactly?" section above for details.)
|
||||
|
||||
NOTE: `prepare` won't execute `git branch --set-upstream-to=origin/master` for
|
||||
you. It assumes you've already set your branch's upstream to the desired remote
|
||||
branch.
|
||||
|
||||
## Features
|
||||
|
||||
Current and planned:
|
||||
|
||||
- [x] Keeps a log of processes and any errors
|
||||
- [x] Updates your Canvas codebase, including plugins, gems, and node packages
|
||||
- [x] Performs database migrations on both development and test databases
|
||||
- [x] Compiles assets (css and javascript)
|
||||
- [x] Starts or restarts `powder` if you have it installed and linked to Canvas
|
||||
- [x] Supports `git checkout`
|
||||
- [x] Supports updating your current branch off master
|
||||
- [x] Supports nuking your Canvas node_modules, i.e. `rm -rf node_modules && npm install`
|
||||
- [x] Supports a fresh installation of Javascript dependencies (useful for new Canvas setups)
|
||||
- [ ] Supports `git cherry-pick`
|
||||
- [ ] Supports a "quick" option, i.e. skipping asset compilation entirely
|
||||
|
||||
## Code Credit
|
||||
|
||||
Much of this code is borrowed from [one of Canvas' update scripts](https://github.com/instructure/canvas-lms/blob/stable/script/canvas_update).
|
||||
I simply added a couple features and repurposed it for Canvas QA folks who are
|
||||
likely accustomed to the Portals checkout flow.
|
|
@ -0,0 +1,124 @@
|
|||
#!/bin/bash
|
||||
|
||||
source script/common.sh
|
||||
|
||||
# Set this manually if your computer's username doesn't match your gerrit username
|
||||
gerrit_username=$USER
|
||||
LOG="$(pwd)/log/prepare.log"
|
||||
|
||||
function usage() {
|
||||
echo "usage: prepare [ [-hin] [-p PATCHSET_ID] ]
|
||||
|
||||
prepare prepares Canvas to run natively on your computer.
|
||||
|
||||
Running prepare without any options will rebase on the current HEAD,
|
||||
update plugins, install or update Ruby and Javascript dependencies,
|
||||
create both dev and test databases if necessary, run database migrations,
|
||||
and finally compile CSS and Javascript. If you use powder then it will also
|
||||
restart powder for you.
|
||||
|
||||
The optional -i flag will install all javascript dependencies.
|
||||
|
||||
The optional -n flag will nuke all javascript dependencies, then install
|
||||
them.
|
||||
|
||||
The optional -p PATCHSET_ID will checkout the Gerrit patchset instead of
|
||||
rebasing on HEAD (the default prepare behavior)."
|
||||
}
|
||||
|
||||
function pull_patchset_from_gerrit() {
|
||||
echo_console_and_log " Pulling Canvas patchset $1 ..."
|
||||
git fetch ssh://$gerrit_username@gerrit.instructure.com:29418/canvas-lms refs/changes/$1 >>"$LOG" 2>&1 && git checkout FETCH_HEAD >>"$LOG" 2>&1
|
||||
}
|
||||
|
||||
function db_create_dev_and_test() {
|
||||
echo_console_and_log " Creating development DB if it doesn't already exist ..."
|
||||
createdb canvas_development >>"$LOG" 2>&1
|
||||
|
||||
echo_console_and_log " Creating test DB if it doesn't already exist ..."
|
||||
createdb canvas_test >>"$LOG" 2>&1
|
||||
}
|
||||
|
||||
function nuke_node_modules() {
|
||||
echo_console_and_log " Removing node_modules and gems/**/node_modules ..."
|
||||
rm -rf node_modules && rm -rf gems/**/node_modules >>"$LOG" 2>&1
|
||||
}
|
||||
|
||||
function restart_powder() {
|
||||
echo " Checking if powder is being used in this repo ..."
|
||||
if [ -f .powder ] ; then
|
||||
echo " Checking if pow is running ..."
|
||||
if ps aux | grep pow | grep -v grep > /dev/null ; then
|
||||
echo_console_and_log " Restarting powder ..."
|
||||
powder restart >>"$LOG" 2>&1
|
||||
fi
|
||||
else
|
||||
echo " ... nope."
|
||||
fi
|
||||
}
|
||||
|
||||
function prepare() {
|
||||
ensure_in_canvas_root_directory
|
||||
intro_message "Prepare"
|
||||
|
||||
if [ "$1" == "" ]; then
|
||||
rebase_canvas
|
||||
else
|
||||
pull_patchset_from_gerrit "$1"
|
||||
fi
|
||||
|
||||
update_plugins
|
||||
bundle_install_with_check
|
||||
db_create_dev_and_test
|
||||
rake_db_migrate_dev_and_test
|
||||
|
||||
if [ "$NUKE_NODE_MODULES" == "true" ]; then
|
||||
nuke_node_modules
|
||||
fi
|
||||
|
||||
if [ "$INSTALL_NODE_PACKAGES" == "true" ] || [ ! -d node_modules ]; then
|
||||
install_node_packages
|
||||
fi
|
||||
|
||||
compile_assets
|
||||
restart_powder
|
||||
}
|
||||
|
||||
# default options
|
||||
PERFORM_UPDATE=true
|
||||
INSTALL_NODE_PACKAGES=false
|
||||
NUKE_NODE_MODULES=false
|
||||
|
||||
# parse options
|
||||
# http://www.tldp.org/LDP/abs/html/internal.html#EX33
|
||||
while getopts ":hin" Option
|
||||
do
|
||||
case $Option in
|
||||
h )
|
||||
PERFORM_UPDATE=false
|
||||
usage;;
|
||||
i )
|
||||
PERFORM_UPDATE=true
|
||||
INSTALL_NODE_PACKAGES=true;;
|
||||
n )
|
||||
PERFORM_UPDATE=true
|
||||
INSTALL_NODE_PACKAGES=true
|
||||
NUKE_NODE_MODULES=true;;
|
||||
* )
|
||||
PERFORM_UPDATE=false
|
||||
echo "Sorry, that's not a valid option!"
|
||||
usage;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$PERFORM_UPDATE" == "true" ]; then
|
||||
trap print_results INT TERM EXIT
|
||||
|
||||
patchset_id="$1"
|
||||
|
||||
if [ "$patchset_id" == "-i" ] || [ "$patchset_id" == "-n" ]; then
|
||||
patchset_id=""
|
||||
fi
|
||||
|
||||
prepare "$patchset_id"
|
||||
fi
|
Loading…
Reference in New Issue