let test = require('ava'),
    webdriver = require('selenium-webdriver'),
    By = webdriver.By,
    chalk = require('chalk')

// This gives us access to send Chrome commands.
require('chromedriver')

// Webdriver's promise manager only made sense before Node had async/await support.
// Now it's a deprecated legacy feature, so we should use the simpler native Node support instead.
webdriver.promise.USE_PROMISE_MANAGER = false

console.log(
    chalk.bold.cyan('These tests assume that you have just run ../insertSqlBaseData.sql on your SQLServer instance')
)

// We use the beforeEach hook to put helpers on t.context and set up test scaffolding.
test.beforeEach(t => {
    t.context.driver = new webdriver.Builder()
        .forBrowser('chrome')
        .build()

    // This method is a helper so we don't have to keep repeating the hostname.
    // Passing the authentication through the querystring is a hack so we can
    // pass the information along via window.fetch. 
    t.context.get = async pathname => 
        await t.context.driver.get(`http://localhost:3000${pathname}?user=erin&pass=erin`)

    // For debugging purposes.
    t.context.waitForever = async () => {
        console.log(chalk.red('Waiting forever so you can debug...'))
        await t.context.driver.wait(() => {})
    }

    t.context.$ = cssSelector => t.context.driver.findElement(By.css(cssSelector))
    t.context.$$ = cssSelector => t.context.driver.findElements(By.css(cssSelector))

    // This helper method is necessary because we don't know when React has finished rendering the page.
    // We will wait for it to be done, with a max timeout so the test does not hang if the rendering fails.
    let fiveSecondsMs = 5000
    t.context.waitUntilElementHasText = async (elem, expectedText) => 
        await t.context.driver.wait(async () => {
            let text = await elem.getText()
            return text === expectedText
        }, fiveSecondsMs, `Element did not have text '${expectedText}' within ${fiveSecondsMs} milliseconds`)
})

// Shut down the browser when we are done.
test.afterEach.always(async t => {
    if (t.context.driver) {
        await t.context.driver.quit()
    }
})

test('Home Page', async t => {
    // We can use t.plan() to indicate how many assertions we plan to make.
    // This provides safety in case there's a silent failure and the test
    // looks like it exited successfully, when in fact it just died. I've 
    // seen people get bit by that a done with frameworks like Mocha which
    // do not offer test planning.
    t.plan(5)

    await t.context.get('/')

    // Use a CSS selector to find an element that we care about on the page.
    let [$reportsPending, $draftReports, $orgReports, $upcomingEngagements] = await t.context.$$('.home-tile h1')

    // Wait until the element has the text we want, which means that React has finished loading.
    await t.context.waitUntilElementHasText($reportsPending, '0')

    // Make an assertion about what the element should say.
    t.is(await $reportsPending.getText(), '0')

    await t.context.waitUntilElementHasText($draftReports, '0')
    t.is(await $draftReports.getText(), '0')

    await t.context.waitUntilElementHasText($orgReports, '2')
    t.is(await $orgReports.getText(), '2')

    await t.context.waitUntilElementHasText($upcomingEngagements, '0')
    t.is(await $upcomingEngagements.getText(), '0')

    await t.context.$('.persistent-tour-launcher').click()
    let $hopscotchTitle = await t.context.$('.hopscotch-title')
    await t.context.waitUntilElementHasText($hopscotchTitle, 'Welcome')
    t.is(await $hopscotchTitle.getText(), 'Welcome')
})

@@ -2026,16 +2026,670 @@
 econds%60)
+%0A%0A    // A helper function to combine waiting for an element to have rendered and then asserting on its contents.%0A    t.context.assertElementText = async (t, elem, expectedText) =%3E %7B%0A        try %7B%0A            await t.context.waitUntilElementHasText(elem, expectedText)%0A        %7D catch (e) %7B%0A            // If we got a TimeoutError because the element did not have the text we expected, just swallow it here%0A            // and let the assertion on blow up instead. That will produce a clearer error message.%0A            if (e.name !== 'TimeoutError') %7B%0A                throw e%0A            %7D%0A        %7D%0A        t.is(await elem.getText(), expectedText)%0A    %7D
 %0A%7D)%0A%0A// 
@@ -3446,105 +3446,8 @@
 ')%0A%0A
-    // Wait until the element has the text we want, which means that React has finished loading.%0A
     
@@ -3466,129 +3466,28 @@
 ext.
-waitUntil
+assert
 Element
-Has
 Text(
-$reportsPending, '0')%0A%0A    // Make an assertion about what the element should say.%0A    t.is(awai
 t
+,
  $re
@@ -3498,34 +3498,23 @@
 sPending
-.getText()
 , '0')%0A
-%0A
     awai
@@ -3529,66 +3529,28 @@
 ext.
-waitUntil
+assert
 Element
-Has
 Text(
-$draftReports, '0')%0A    t.is(awai
 t
+,
  $dr
@@ -3559,34 +3559,23 @@
 tReports
-.getText()
 , '0')%0A
-%0A
     awai
@@ -3590,64 +3590,28 @@
 ext.
-waitUntil
+assert
 Element
-Has
 Text(
-$orgReports, '2')%0A    t.is(awai
 t
+,
  $or
@@ -3622,26 +3622,15 @@
 orts
-.getText()
 , '2')%0A
-%0A
     
@@ -3649,73 +3649,28 @@
 ext.
-waitUntil
+assert
 Element
-Has
 Text(
-$upcomingEngagements, '0')%0A    t.is(awai
 t
+,
  $up
@@ -3686,26 +3686,16 @@
 agements
-.getText()
 , '0')%0A%0A
@@ -3841,74 +3841,28 @@
 ext.
-waitUntil
+assert
 Element
-Has
 Text(
-$hopscotchTitle, 'Welcome')%0A    t.is(awai
 t
+,
  $ho
@@ -3873,26 +3873,16 @@
 tchTitle
-.getText()
 , 'Welco

refactor tests a bit