Add some more sophisticated scouting tests

This patch adds a test that validates actually submitting a match.

Signed-off-by: Philipp Schrader <philipp.schrader@gmail.com>
Change-Id: I3fb1063b5ec89aa843d0bb96f71c3bbfd2601122
diff --git a/scouting/scouting_test.ts b/scouting/scouting_test.ts
index c63251b..43423c1 100644
--- a/scouting/scouting_test.ts
+++ b/scouting/scouting_test.ts
@@ -1,11 +1,14 @@
 import {browser, by, element, protractor} from 'protractor';
 
+const EC = protractor.ExpectedConditions;
+
 // Loads the page (or reloads it) and deals with the "Are you sure you want to
 // leave this page" popup.
 async function loadPage() {
   await disableAlerts();
   await browser.navigate().refresh();
   expect((await browser.getTitle())).toEqual('FRC971 Scouting Application');
+  await disableAlerts();
 }
 
 // Disables alert popups. They are extremely tedious to deal with in
@@ -13,7 +16,7 @@
 // an invisible checkbox that's off-screen.
 async function disableAlerts() {
   await browser.executeAsyncScript(function (callback) {
-    const block_alerts = document.getElementById('block_alerts') as HTMLInputElement;
+    let block_alerts = document.getElementById('block_alerts') as HTMLInputElement;
     block_alerts.checked = true;
     callback();
   });
@@ -24,6 +27,12 @@
   return element(by.css('.header')).getText();
 }
 
+// Returns the currently displayed progress message on the screen. This only
+// exists on screens where the web page interacts with the web server.
+function getProgressMessage() {
+  return element(by.css('.progress_message')).getText();
+}
+
 // Returns the currently displayed error message on the screen. This only
 // exists on screens where the web page interacts with the web server.
 function getErrorMessage() {
@@ -43,23 +52,62 @@
       .toEqual(`${fieldName}: ${expectedValue}`);
 }
 
+// Sets a text field to the specified value.
+function setTextboxByIdTo(id: string, value: string) {
+  // Just sending "value" to the input fields is insufficient. We need to
+  // overwrite the text that is there. If we didn't hit CTRL-A to select all
+  // the text, we'd be appending to whatever is there already.
+  return element(by.id(id)).sendKeys(
+        protractor.Key.CONTROL, 'a', protractor.Key.NULL,
+        value);
+}
+
 describe('The scouting web page', () => {
   beforeAll(async () => {
     await browser.get(browser.baseUrl);
     expect((await browser.getTitle())).toEqual('FRC971 Scouting Application');
     await disableAlerts();
+
+    // Import the match list before running any tests. Ideally this should be
+    // run in beforeEach(), but it's not worth doing that at this time. Our
+    // tests are basic enough not to require this.
+    await element(by.cssContainingText('.nav-link', 'Import Match List')).click();
+    expect(await getHeadingText()).toEqual('Import Match List');
+    await setTextboxByIdTo('year', '2016');
+    await setTextboxByIdTo('event_code', 'nytr');
+    await element(by.buttonText('Import')).click();
+
+    await browser.wait(EC.textToBePresentInElement(
+        element(by.css('.progress_message')), 'Successfully imported match list.'));
   });
 
+  it('should: error on unknown match.', async () => {
+    await loadPage();
+
+    // Pick a match that doesn't exist in the 2016nytr match list.
+    await setTextboxByIdTo('match_number', '3');
+    await setTextboxByIdTo('team_number', '971');
+
+    // Click Next until we get to the submit screen.
+    for (let i = 0; i < 5; i++) {
+      await element(by.buttonText('Next')).click();
+    }
+    expect(await getHeadingText()).toEqual('Review and Submit');
+
+    // Attempt to submit and validate the error.
+    await element(by.buttonText('Submit')).click();
+    expect(await getErrorMessage()).toContain(
+        'Failed to find team 971 in match 3 in the schedule.');
+  });
+
+
   it('should: review and submit correct data.', async () => {
     await loadPage();
 
+    // Submit scouting data for a random team that attended 2016nytr.
     expect(await getHeadingText()).toEqual('Team Selection');
-    // Just sending "971" to the input fields is insufficient. We need to
-    // overwrite the text that is there. If we didn't hit CTRL-A to select all
-    // the text, we'd be appending to whatever is there already.
-    await element(by.id('team_number')).sendKeys(
-        protractor.Key.CONTROL, 'a', protractor.Key.NULL,
-        '971');
+    await setTextboxByIdTo('match_number', '2');
+    await setTextboxByIdTo('team_number', '5254');
     await element(by.buttonText('Next')).click();
 
     expect(await getHeadingText()).toEqual('Auto');
@@ -81,8 +129,8 @@
     expect(await getErrorMessage()).toEqual('');
 
     // Validate Team Selection.
-    await expectReviewFieldToBe('Match number', '1');
-    await expectReviewFieldToBe('Team number', '971');
+    await expectReviewFieldToBe('Match number', '2');
+    await expectReviewFieldToBe('Team number', '5254');
 
     // Validate Auto.
     await expectNthReviewFieldToBe('Upper Shots Made', 0, '0');
@@ -105,9 +153,11 @@
     await expectReviewFieldToBe('Battery died', 'false');
     await expectReviewFieldToBe('Broke (mechanically)', 'true');
 
-    // TODO(phil): Submit data and make sure it made its way to the database
-    // correctly. Right now the /requests/submit/data_scouting endpoint is not
-    // implemented.
+    await element(by.buttonText('Submit')).click();
+    await browser.wait(EC.textToBePresentInElement(
+        element(by.css('.header')), 'Home'));
+
+    // TODO(phil): Make sure the data made its way to the database correctly.
   });
 
   it('should: load all images successfully.', async () => {