🤖 : "My name is Trillian! I'll be your guide to Galaxy E2E Alpha!"
🤖 : "This repo contains end-to-end test suites for the Edvisor.io web-client"
The directory structure models that of the web client. Each directory contains tests for one application, and corresponds to the same named directory in the web-client repo.
Reminder: Search for keyword 'SPECIAL' for tests that may need .skips
added or
removed.
Tests that can be run only one time per database reset should be unskipped in master
branch.
(being updated)
For a high level overview of the code, move on to the next section.
-
If new code is on remote,
git pull
from the web-client repo. -
Otherwise go straight to api-server repo (remember client is symlinked) and run
./bin/edvisor build -s client
.
-
mysql -u root
-
Update with Stripe token to stop Stripe errors.
-
Make sure the database is running. If not,
mysql.server start
. -
Then go into
.env
inapi-server
repo and make sure database is local. -
Then reset the database by running
./bin/edvisor full-reset
An overview of how things are structured
- Use the present tense ("Add feature" not "Added feature")
- Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
- Limit the first line to 72 characters or less
- Consider starting the commit message with an applicable emoji:
- ✨
:sparkles:
when adding a new feature - 🎨
:art:
when improving the format/structure of the code - 🚀
:rocket:
when improving performance - 📝
:memo:
when writing docs - 🐛
:bug:
when fixing a bug - 🔥
:fire:
when removing code or files - 💚
:green_heart:
when fixing the CI build - ✅
:white_check_mark:
when adding tests - 🔒
:lock:
when dealing with security - ⬆️
:arrow_up:
when upgrading dependencies - ⬇️
:arrow_down:
when downgrading dependencies - 👕
:shirt:
when removing linter warnings
- ✨
Branches are divided simply as master
, PROJ-\d\d\d\d
, and sprint-name
.
The branch name reflects the test suites' compatibility with the corresponding
web-client
and api-server
. For example, master
tests should work with the
master
branch of web-client
and api-server
. weedle
tests should work with
weedle
sprint branch of web-client
and api-server
.
New tests and fixes should go in the branch they're compatible with. Any other new feature,
such as updates to shell scripts, should go into a PROJ
branch branched off
the merge-base of the branches they affect.
Both PROJ-\d\d\d\d
and sprint-name
branch off of master and are rebased back
onto it.
All JavaScript must adhere to JavaScript Standard Style.
- Prefer the object spread operator (
{...anotherObj}
) toObject.assign()
- Inline
export
s with expressions whenever possible// Use this: export default class ClassName { } // Instead of: class ClassName { } export default ClassName
Where it all begins. The .conf
file helps set the stage for your tests.
Suites let you organize your tests. In our tests, those suites that start with
a
such as aSettings
, refer to the Settings functionality of the Agency app.
Those that start with s
such as sSettings
are for the Settings functionality
of the School app.
🤖 : "Patterns are beautiful weaves of code"
If it's for a page, such as the Student Profile page, then the filename will be
studentProfile.pageObject.js
If it's for a part of a page, such as an Area/Modal etc, then the filename will
be addStudentModal.pageObject.js
Each app or sub-app has a pageObject file of its very own. Only the root
pageObject file imports
from any other pageObject file that it may need. This
is to minimize the chaos of pageObjects endlessly importing from others. You
can see which pageObjects an app test suite is dependent on by looking at only
the imports
in the root pageObject file.
🤖 : "Moar patterns 😍"
The before()
and beforeEach
functions contain logic that the tests are
dependent on but are not being tested. The logic being tested will always
be inside an it('should be put in here if being tested')
.
Here you'll find naming patterns for the variables and prototypal methods we're using.
🤖 : "✨ Magical conventions help keep your sanity."
We use prototypal methods to do actions on the page. Method names are:
verb + detail about the element + element type. For example, a method for
clicking on a button called 'Change' will be called clickChangeButton
.
When there are more buttons called 'Change' on the same page, we'll add
contextual details. If the button changes a student's pipeline, we'll call the
method that clicks it clickChangePipelineButton()
. If there is more than one
button that fits this pattern, the order can be included. For example,
clickChangePipelineFirstButton()
Initialized variables that correspond to elements on a page follow a similar pattern. They just omit the leading verb, because they don't "do" things. The button being clicked in the example above can be initialized as "changePipelineButton".
Functions prefixed with 'testNeeds' (e.g. testNeedsDuplicatePipeline
) means
that it isn't meant to represent human behaviour. Rather that it's needed by a
test. So such functions may take shortcuts, such as navigating to a
specific page in the app by url instead of clicking to it as a user is likely to.
(Undergoing changes) The word 'relative' is used in a name when the element is only available in a given context. For example, 'changePipelineStatusRelativeOption' is an option that only appears when a dropdown is present.
/shared/pages/
contains pageObject files belonging to pages that do not
possess specs files of their own.
Static methods in widgets.js
interact with the page. pageObject files provide
a layer of abstraction and so spec files don't directly invoke static widget
methods. Instead, spec files may invoke pageObject prototypal methods which
in turn call static widget methods.
Filenames may make more sense in context of the complete filepath.
The styleguide linked below is rather good.
In addition to the web-client-e2e, you'll need other repos.
- Clone api-server and web-client
Then, in both repos:
-
Run
npm install
-
Run
git submodule init
-
Run
git submodule update
-
Copy the sample env into the env with
cp .env.sample .env
-
You'll need to
brew install git-lfs
. Thengit lfs install
.
- Navigate to the web-client repo and run
./bin/edvisor build -s client
.
-
Run
npm install -g gulp
. Navigate to the api-server repo. -
Symlink client directory to the /client folder in api-server
-
Run
gulp build
-
Reset the database by running
./bin/edvisor full-reset
-
Run
gulp
if you'd prefernodemon
running + want to see errors. Otherwise rungulp start
Ok, setup is done!
-
Install Protractor for the project using
npm install
. This will install all dependencies for theweb-client-e2e
project. -
webdriver-manager will be installed with the above. Now run
./node_modules/protractor/bin/webdriver-manager update
. This is for Selenium.
-
Are you using DirectConnect or Selenium? If Selenium: Protractor may start a standalone Selenium server. Otherwise if you have Protractor installed global from before, run
webdriver-manager start
. Doesn’t matter where from. Terminal will stay running. Check that conf.js points to this Selenium server. If DirectConnect, check that directConnect: 'true' inconf.js
. -
Are you running it against localhost (is gulp is running from
api-server
directory)? You'll need a database. We use MariaDB. Runmysql.server start
, one time. Will need to rerun when machine is restarted. FYI,mysql.server stop
andmysql.server restart
. -
Are you running it against on the localhost? If so, run
gulp
from api-server repo. Will keep running in terminal.
Navigate to the directory containing the conf.js of your desired test. Run test with protractor protractor.conf.js
.
protractor protractor.conf.js
will run all tests.
- Options are: invoices, partners, quotes, settings, students - this runs all tests involving each suite
protractor protractor.conf.js --suite agency
change 'agency' to whatever app you want to test
protractor protractor.conf.js --specs agency/student_profile_spec.js
🤖 : "I've found these pages very very helpful. Maybe you should check them out. ✨"
Protractor styleguide 🤖 : "This one has good links at the end of README.md"
Protractor timeouts (many errors from here 💩)
Did you know how many ways you'll need to run this for reliable results? This will help 😁