Use AngularStrap for navbar

https://mgcrea.github.io/angular-strap/

AngularStrap provides Angular directives for Bootstrap CSS to, for
example, mark the active navbar tab.

One alternative is "Angular directives for Boostrap" by the AngularUI
team, but that doesn't have a "Nav" directive, only "Tabs" which doesn't
support tabs inside the navbar with the tabs' content outside the
navbar.
"manual" and "automated" view boilerplate
Fix class names to get 2 column layout

"span6" was a bootstrap 2 thing; we're using bootstrap 3.
Remove "bootstrap-theme" css

It's an optional layer over the standard bootstrap css that adds some
3D/gradient effects. With the current trends moving towards flat design
let's not add gradients.
Use orange "united" theme from bootswatch

To match the orange design of the appliance.

TODO: Better color match (edit the bootswatch less/sass sources not the
css).

The theme is MIT licensed.
Navbar orange is lighter to match stb-tester appliance front panel

Generated with:

    git clone https://github.com/thomaspark/bootswatch.git
    cd bootswatch
    npm install
    (cd ~ && npm install grunt-cli)
    sed -i -e 's/^@brand-primary:.*/@brand-primary: #f77f00;/' \
           -e 's/^@link-color:.*/@link-color: #d70;/'
    ~/.npm/grunt-cli/0.1.13/package/bin/grunt swatch:united
    cp united/bootstrap.css ...
css fix: Remove 1px orange border left of logo in navbar

So that the hand of the stb-tester logo looks like it's coming out of
the edge of the window.

Note that we're merely shifting the margin left by 1px; bootstrap's
margin is -15px (to compensate for .container-fluid's padding).
Remove angular-seed's "app-version" directive

This isn't part of the Angular framework itself, but something added by
"angular-seed", which is an Angular app template. I thought it was a DRY
way of somehow taking the app version from package.json, but it turns
out that it's just to let you hardcode your app version in "version.js"
instead of in "index.html", and I don't need all those lines of code and
6 files just to do that.
Remove IE-specific stuff that came from angular-seed

We don't test on IE so might as well not pretend to support it.

I don't really understand what this did, but I don't see how it was
correct -- you'd get <html ng-app="myApp"> if you were using IE, but no
<html> element at all if you weren't!? The "ng-app" is fairly crucial to
Angular, I would have thought.

modernizr.js provides feature detection ("does this browser support
html5 feature xyz?") but it doesn't actually "modernize" the browser by
implementing the missing functionality; it provides a "Modernizr" object
that you can query ("if (Modernizr.video.web) ..."). There are no
references to "Modernizr" anywhere in the codebase, so I'm removing this
too.
Default route is "automated tests", not "manual control"

This is probably what you want to do most of the time: Kick off a test
run.
Consolidate routing configuration into app.js

I find this much clearer than the existing layout, which came from the
"angular seed" template. I see "app.js" as the part that glues all the
other components together. Hopefully the controllers will be quite
minimal, but if not I can always split them out into their own files
later.
Cleanup: Rename controllers from xCtrl -> xController

According to ng-book.com:

> It is considered a best-practice to name our controllers as
> [Name]Controller, rather than [Name]Ctrl.

This also matches the examples in the Angular documentation.[1]

Also, I don't need the more verbose "[function...]" syntax[2] since I
don't intend to minify this javascript file.

[1] https://docs.angularjs.org/guide/controller

[2] https://docs.angularjs.org/guide/di#inline-array-annotation
    vs. https://docs.angularjs.org/guide/di#implicit-annotation
Add README with description, license undecided, dev instructions
Show current branch (hardcoded to master) and sha (polled from back-end)

All the logic is in the controller; I'll eventually pull it out into an
angular Service or something.

I thought about putting the `$timeout(updateSha, 1000)` inside the
`finally` part of a `try...finally`, but there isn't actually much
that can go wrong; if `data` doesn't have a `sha` attribute then
`data.sha` is `undefined`, not an exception as in other languages.
Test that test-pack branch sha is displayed

This is an end-to-end test for the functionality added in the previous
commit.

You have to manually start the backend before you run the test with
`npm run protractor`. It will automatically launch an instance of
Chromium and control it via WebDriver.

Protractor is the end-to-end test runner installed by angular-seed,
and it's the test runner recommended in the Angular tutorial.[1]

If we need more flexibility in future[2] we might consider writing tests
in python using the Selenium (WebDriver) python bindings. I'm also
committing "notes.md" with what I've figured out so far to do that.
But at least this is testing the real javascript code in a real browser
against the real back-end service.

[1] https://docs.angularjs.org/tutorial/step_03#running-end-to-end-tests-with-protractor

[2] For example, test that the sha is updated in the Web UI when you
    push a new commit to the git repo -- that's not something I intend
    to script from the javascript test code.
Use $interval, not $timeout, to poll backend

To allow end-to-end testing with Protractor. See "Waiting for Page
Synchronization" at
https://github.com/angular/protractor/blob/fcd973b/docs/timeouts.md
Limit sha display to 7 digits

To keep the UI neater.
List available tests to run, in a multi-select box

Note that we only re-fetch the list of tests from the back-end if the
sha has changed, because for the back-end this can be relatively
expensive to generate (grepping all the source files in the test-pack
repo).

I had to use the Promise's `then` instead of `success` so that I could
chain more Promises.

Note that `ng-model="selectedTests"` means that in the Controller,
`$scope.selectedTests` will contain the selected values.
Tests select-box uses test name, not array index, as <option> value

Before:

    <select>
      <option value="0">tests/example_tests.py::test_1</option>
    </select>

After:

    <select>
      <option value="tests/example_tests.py::test_1"></option>
    </select>

This doesn't actually make any functional difference: In both cases, the
selections were preserved when the list of tests on the master branch
changes and the list of options is updated. According to [1] it has a
performance benefit though I admit I don't fully understand the
implications. Angular's own documentation of "track by"[2] is pretty
minimal.

[1] http://www.bennadel.com/blog/2556-using-track-by-with-ngrepeat-in-angularjs-1-2.htm
[2] https://docs.angularjs.org/api/ng/directive/select
Ignore stale responses from back-end

This addresses a hypothetical concern I have about the following race
condition:

1. Web UI thinks sha="a". Due to the regular polling, Web UI makes
   request #1 to the backend for current sha.

2. User selects a different branch from the drop-down list (this feature
   isn't currently implemented, but bear with me). Web UI sends request
   #2 (immediately) for the new branch's sha.

3. We get the response for request #2 (more quickly than the original
   request)! We update display the new sha & the new list of tests for
   the new branch.

4. Only now we receive the response for the original request #1. We
   update the display to show the original branch's sha & list of tests
   -- that is, the wrong data for the currently selected branch.

Maybe this can't actually happen, but I don't know.

A similar problem could (hypothetically) happen with the list of tests
when the branch stays the same but the sha changes:

1. The sha changes, ask for the new list of tests.
2. The sha changes again a second later, ask for the newer list of
   tests.
3. Response #2 arrives (this would require response #1 to take longer
   than a second, which is the polling interval between noticing sha
   changes; could that be possible if the test-pack git repo is
   extremely large?)
4. Response #1 arrives and sets the list of tests to the wrong tests.

Maybe a more generic approach would be to include a token or serial
number in each request to the back-end, have the back-end return it in
the response, and check that instead. Anyway I'm probably overthinking
this so I'll stop now, but I've made the change so I'll leave it in for
now.