[Note: This is a snapshot of the readme present in our private Git repo, posted for the sake of prospective web dev contractors. If you’re reading this past May 2019, expect that it is out of date.]
Project Overview
- Node.js app on the backend
- Uses Express web framework to define HTTP routes, serve content, etc.
- Uses Pug (formerly known as Jade) for templating: see
views/*.jade
- app.js is our “
main()
”… it’s just set-up stuff auth/
handles login and registrationcontrollers/
houses all the back-end controllers; this is where the magic happens. The top of each controller file defines the routes it handles (see, for example, calls toConnectionTools.defineGetRoute()
), so if you know the URL you’re interested in, you can find the controller responsible for it.utils/
contains (you guessed it) a handful of utility classes used throughout the controller code.
- Angular.js on the frontend—yes, the old “Angular.js” version 1.4.9, not the new hotness “Angular” version whatever-they’re-up-to-these-days… is it over 9,000?
public/js/
contains all the Angular controllerspublic/lib/
contains the JavaScript libraries we depend on; the most important of these is ui-grid, which powers the grid displays you see all across the site
- Cucumber.js for integration tests
test/features/
contains the.feature
description filestest/features/step_definitions
defines how those.feature
descriptions actually get implemented; these use WebDriverIO to do browser manipulation.test/features/support
performs setup and teardown of tests
- A bunch of Python scripts (in
scripts/
) that Tyler uses for, like, interacting with the live Gateway; aside fromtest_api.py
, this can probably be safely ignored
Running the app locally
- Install Node.js and NPM (instructions vary depending on your OS)
- On Mac, you can install Homebrew (if you don’t have it already), then just run
$ brew install node
- On Mac, you can install Homebrew (if you don’t have it already), then just run
$ cd <gateway directory>
$ npm install
—installs all the Node.js package dependencies$ npm install -g grunt
—gets you Grunt (which you’ll need for the next step), installed globally so you can use it from any location$ grunt build
—combines and “minifies” all our CSS and front-end JavaScript (everything in public/styles/ gets splatted into gateway-app.css, and everything in public/js/ gets splatted into gateway-app.js)- While you’re developing, you’ll want to leave
$ grunt watch
running instead, so that it will automatically recompile your JS/CSS as you change things.
- While you’re developing, you’ll want to leave
- Edit
.env
to un-comment theMAIL_TARGET
and set it to your email address. This will ensure that emails sent from the test environment go to you, rather than Tyler. $ node app.js
—Starts the server. If everything worked, the console output should have no errors, just a few “info” lines.- Visit http://localhost:5000 in your browser—you should see a home page that looks just like the live server’s.
Debugging the app from within PhpStorm
Tyler’s a big fan of the JetBrains IDEs, and PhpStorm has support for running Node.js apps in the debugger. The killer feature here is being able to set a breakpoint in the back-end app and be able to examine the app’s state live—no more console.log()
for you!
If you can already run the app from the terminal (per the above), here’s how you can set it up to run in PhpStorm’s debugger:
- Install PhpStorm (duh)—they have a free 30 day trial.
- Open the
gateway
directory in it. - Click the dropdown in the upper right of the window. This is the run configuration picker.
- Select “Edit Configurations.”
- In the window that appears, click the “+” button in the upper left, and choose Node.js from the dropdown list.
- Set the working directory to your Gateway directory, and the JavaScript file to
app.js
. The rest of the defaults should be fine. - Apply your changes.
- Click the “debug” button next to the run configuration picker. You should now be able to access the app at http://localhost:5000.
Building the front-end JavaScript and CSS
We use Grunt to minify and concatenate our Javascript & CSS files, so that users can make one HTTP request and get all of our resources (or at least all our resources that load on allpages), rather than making many requests for many small files.
Thus, if you only change a source file (a file like app.js
or xplane.css
), your changes won’t be reflected in your testing. Instead, you need to also run our Grunt task, like this:
- Install Grunt globally (obviously do this just once):
$ sudo npm install -g grunt
- Run the build task:
$ grunt build
Likewise, if you add a new Javascript/CSS file to be loaded on every page (we used to do this by adding a script
or style
tag to layout.jade
), you’ll want to instead add that file to the list of concatenated scripts, located in the concat
field of Gruntfile.js
. (Note that this is an ordered list!)
Running the Integration Tests
We use cucumber.js with Selenium ChromeDriver for integration testing/BDD. We also have a handful of Python tests (defined in scripts/test_api.py
) for testing the REST API.
First (one time only), you’ll need to set up your environment:
- Run
$ npm install
(you’ve probably already done this if you’ve run the app locally!) - Install a Selenium “driver” for your browser of choice (e.g., ChromeDriver). If you’re on Mac, this is available via Homebrew:
$ brew install chromedriver
- Manually make Selenium aware of the “driver” for your browser:
$ ./node_modules/selenium-standalone/bin/selenium-standalone install --config=selenium-config.js
- (Note that the argument to
selenium-standalone
here isinstall
, in contrast tostart
used below)
- (Note that the argument to
After you’ve gotten your environment set up, here’s what you need to do to run the tests day-to-day:
In three separate command line tabs, you’ll need to run these commands, respectively:
- Start the Selenium server, which is responsible for giving the testing suite access to a real browser, rather than a buggy mock of a browser:
$ ./node_modules/selenium-standalone/bin/selenium-standalone start --config=selenium-config.js
- Start a local instance of the webapp:
$ node app.js
- Run the tests:
$ make
- This runs the Cucumber tests first; only if those pass does it proceed to the REST API tests.
One note: We do not unit-test submitting airports from WED. If your changes touch the API, you should probably perform a manual test of WED before pushing your changes, just because the REST API tests don’t catch bugs in WED itself! (Tyler’s been bitten by this: once, when the Gateway server returned too long a text description of an error, WED would go into an infinite loop. Doh!)
Running the tests from PhpStorm like the cool kids
It’s not enough to be able to debug the app from within PhpStorm (per above)—we JavaScript hipsters also want to be able to debug our tests from the IDE. Here’s how to configure that in PhpStorm (assuming you can already run the tests via make
):
- Go to Edit Configurations again, as you did when you set up the Node.JS app itself.
- Click “+” and choose “Cucumber.js”.
- Set the “Feature file or directory” to gateway/test/features/
- Optionally set the Cucumber.js arguments to
--tags=@someTagHere
- Launch the app itself (either from PhpStorm or your terminal, doesn’t matter)
- Launch Selenium from your terminal
- Select the test target from the run configuration dropdown.
- Click the debug button.
TODO: Is there a good way to have Selenium get launched automagically from PhpStorm?
Running the standalone Python API tests
There are a suite of Python 3 tests designed to test the API features. These are normally run at the end of the Cucumber tests. However, using the steps below, they can be run on their own.
For the one-time setup of a Python 3 virtural environment:
$ cd <path/to/gateway>
$ virtualenv env -p python3
$ env/bin/pip3 install -r scripts/package_requirements.txt
Then, to run the tests:
$ cd <path/to/gateway>
$ env/bin/python3 scripts/test_api.py
Troubleshooting
“Why do I get a 404 File Not Found for gateway-app.min.js or gateway-app.min.js.map?”
You didn’t run the build task (see “Building the Javascript” above). We don’t commit the built version of the Javascript to the repo (in the same way you would never commit the compiled version of a C++ program).