forked from HHS/Head-Start-TTADP
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Activity Report Stepper cucumber tests (#53)
* Test drive cucumber * Test drive cucumber * Test drive cucumber * Test drive cucumber * Test drive cucumber * Test drive cucumber * Test drive cucumber * Test drive cucumber * Test drive cucumber * Test drive cucumber * Test drive cucumber * Test drive cucumber * Test drive cucumber * Test drive cucumber * Consolidated steps * Enable cucumber testing by env * Enable cucumber testing by env * Enable cucumber testing by env * Enable cucumber testing by env * Enable cucumber testing by env * Enable cucumber testing by env * Enable cucumber testing by env * Enable cucumber testing by env * Enable cucumber testing by env * Enable cucumber testing by env * Enable cucumber testing by env * Enable cucumber testing by env * Debug config.yml * Debug cucumber start * Debug cucumber start * Debug cucumber start * Debug cucumber start * Debug cucumber start * Debug cucumber start * Debug cucumber start * Debug cucumber start * Debug cucumber start * Add tests for the activity report stepper * Add auth bypass * Remove debugging stmt * Add env variables to cucumber job * Set redirect variable for cucumber * Set redirect variable for cucumber * Add screenshots, add tests * Add ADR for BDD testing * Update Readme * Adjust the ADR; remove dead code * Add a prod env check
- Loading branch information
1 parent
729df05
commit 2448e9d
Showing
15 changed files
with
1,573 additions
and
1,115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
Feature: Activity Report Stepper | ||
|
||
Scenario: Activity Summary | ||
Given I am logged in | ||
And I am on the activity reports page | ||
Then I see the Stepper | ||
And the first step is the Activity Summary | ||
Scenario: Navigation buttons | ||
Given I am logged in | ||
And I am on the activity reports page | ||
Then I see two navigation buttons | ||
And the "Previous" button is disabled | ||
When I click the "Next" button | ||
Then the "Previous" button is no longer disabled | ||
Scenario: Progress | ||
Given I am logged in | ||
And I am on the activity reports page | ||
When I click the "Next" button | ||
Then I moved past the "Activity Summary" step | ||
And I am on the "Participants" step | ||
When I click the "Next" button again | ||
Then the "Participants" step is still current, but I am on page 2 | ||
And I have not advanced to the "Goals & Objectives" step yet | ||
When I click the "Previous" button | ||
Then the "Participants" step is still current, but I am on page 1 | ||
When I click the "Previous" button again | ||
Then I am no longer on the "Participants" step | ||
And I am on the "Activity Summary" step |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
Feature: TTA Smarthub Home Page | ||
|
||
Scenario: Welcome page is displayed | ||
Given I am logged in | ||
And I am on the Smart Hub home page | ||
Then I see "Welcome to the TTA Smart Hub" message | ||
And I see "Activity Reports" link | ||
# Scenario: Login is redirected to HSES | ||
# Given the home page of tta-smarthub | ||
# When pressing login | ||
# Then we should see "Head Start Enterprise System" page |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
const { | ||
Given, When, Then, | ||
} = require('@cucumber/cucumber'); | ||
const assertTrue = require('assert'); | ||
const assert = require('assert'); | ||
const select = require('puppeteer-select'); | ||
const scope = require('../support/scope'); | ||
|
||
Given('I am on the activity reports page', async () => { | ||
const page = scope.context.currentPage; | ||
const selector = 'a[href$="activity-reports"]'; | ||
await Promise.all([ | ||
page.waitForNavigation(), | ||
page.click(selector), | ||
]); | ||
await page.screenshot({ path: 'reports/givenOnTheActivityReports.png' }); | ||
}); | ||
|
||
Then('I see the Stepper', async () => { | ||
const page = scope.context.currentPage; | ||
const selector = '[aria-label="progress"]'; | ||
|
||
const value = await page.$eval(selector, (el) => el.textContent); | ||
|
||
assertTrue(value); | ||
assertTrue(value.startsWith('Activity Summary')); | ||
}); | ||
|
||
Then('the first step is the Activity Summary', async () => { | ||
const page = scope.context.currentPage; | ||
const selector = '[aria-label="progress"] ol li span[aria-current="true"]'; | ||
|
||
const value = await page.$eval(selector, (el) => el.textContent); | ||
|
||
assert.equal(value, 'Activity Summary'); | ||
}); | ||
|
||
Then('I see two navigation buttons', async () => { | ||
const page = scope.context.currentPage; | ||
|
||
const buttonOne = await select(page).getElement('button:contains("Previous")'); | ||
const buttonTwo = await select(page).getElement('button:contains("Next")'); | ||
|
||
assertTrue(buttonOne); | ||
assertTrue(buttonTwo); | ||
|
||
let value = await page.evaluate((el) => el.textContent, buttonOne); | ||
assert.equal(value, 'Previous'); | ||
|
||
value = await page.evaluate((el) => el.textContent, buttonTwo); | ||
assert.equal(value, 'Next'); | ||
}); | ||
|
||
Then('the {string} button is disabled', async (string) => { | ||
const page = scope.context.currentPage; | ||
const buttonOneSelector = 'button[disabled]'; | ||
|
||
const buttonPrevious = await page.$(buttonOneSelector); | ||
|
||
assertTrue(buttonPrevious); | ||
|
||
const value = await page.evaluate((el) => el.textContent, buttonPrevious); | ||
assert.equal(value, string); | ||
}); | ||
|
||
When('I click the {string} button', async (string) => { | ||
const page = scope.context.currentPage; | ||
const buttonTwo = await select(page).getElement(`button:contains(${string})`); | ||
await buttonTwo.click(); | ||
}); | ||
|
||
Then('the {string} button is no longer disabled', async (string) => { | ||
const page = scope.context.currentPage; | ||
const buttonOneSelector = 'button[disabled]'; | ||
|
||
const buttonPrevious = await page.$(buttonOneSelector); | ||
|
||
const value = await page.evaluate((el) => el, buttonPrevious); | ||
assert.equal(value, null); | ||
}); | ||
|
||
Then('I moved past the {string} step', async (string) => { | ||
const page = scope.context.currentPage; | ||
assert.equal(string, 'Activity Summary'); | ||
const selector = `[data-testid="${string}"] > [aria-current="false"]`; | ||
|
||
const value = await page.$eval(selector, (el) => el.textContent); | ||
|
||
assertTrue(value); | ||
assertTrue(value.startsWith(string)); | ||
}); | ||
|
||
Then('I am on the {string} step', async (string) => { | ||
const page = scope.context.currentPage; | ||
const selector = `[data-testid="${string}"] > [aria-current="true"]`; | ||
|
||
const value = await page.$eval(selector, (el) => el.textContent); | ||
|
||
assertTrue(value); | ||
assert.equal(value, string); | ||
}); | ||
|
||
When('I click the {string} button again', async (string) => { | ||
const page = scope.context.currentPage; | ||
const buttonTwo = await select(page).getElement(`button:contains(${string})`); | ||
await buttonTwo.click(); | ||
}); | ||
|
||
Then('the {string} step is still current, but I am on page 2', async (string) => { | ||
const page = scope.context.currentPage; | ||
assert.equal(string, 'Participants'); | ||
const selector = '[data-testid="form"] > h1'; | ||
|
||
const value = await page.$eval(selector, (el) => el.textContent); | ||
|
||
assertTrue(value); | ||
assert.equal(value, `${string} - Page 2`); | ||
}); | ||
|
||
Then('I have not advanced to the {string} step yet', async (string) => { | ||
const page = scope.context.currentPage; | ||
assert.equal(string, 'Goals & Objectives'); | ||
const selector = `[data-testid="${string}"] > [aria-current="false"]`; | ||
|
||
const value = await page.$eval(selector, (el) => el.textContent); | ||
|
||
assertTrue(value); | ||
assertTrue(value.startsWith(string)); | ||
await page.screenshot({ path: 'reports/notOnGoalsYet.png' }); | ||
}); | ||
|
||
Then('the {string} step is still current, but I am on page 1', async (string) => { | ||
const page = scope.context.currentPage; | ||
assert.equal(string, 'Participants'); | ||
const selector = '[data-testid="form"] > h1'; | ||
|
||
const value = await page.$eval(selector, (el) => el.textContent); | ||
|
||
assertTrue(value); | ||
assert.equal(value, `${string} - Page 1`); | ||
}); | ||
|
||
Then('I am no longer on the {string} step', async (string) => { | ||
const page = scope.context.currentPage; | ||
assert.equal(string, 'Participants'); | ||
const selector = `[data-testid="${string}"] > [aria-current="false"]`; | ||
|
||
const value = await page.$eval(selector, (el) => el.textContent); | ||
|
||
assertTrue(value); | ||
assertTrue(value.startsWith(string)); | ||
}); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
require('dotenv').config(); | ||
const { | ||
Given, Then, | ||
} = require('@cucumber/cucumber'); | ||
const assertTrue = require('assert'); | ||
const assert = require('assert'); | ||
const scope = require('../support/scope'); | ||
|
||
Given('I am logged in', async () => { | ||
if (!scope.browser) { | ||
const width = 1024; | ||
const height = 1600; | ||
|
||
scope.browser = await scope.driver.launch({ | ||
defaultViewport: { width, height }, | ||
headless: true, | ||
// slowMo: 250, // can be used in conjunction with headless: false to slow down the browser | ||
}); | ||
} | ||
scope.context.currentPage = await scope.browser.newPage(); | ||
const page = scope.context.currentPage; | ||
|
||
const domain = process.env.TTA_SMART_HUB_URI.split('//')[1]; | ||
|
||
const cookies = [{ | ||
name: 'CUCUMBER_USER', | ||
value: `${process.env.CUCUMBER_USER}`, | ||
domain, | ||
path: '/', | ||
httpOnly: true, | ||
secure: false, | ||
session: true, | ||
sameSite: 'Strict', | ||
}]; | ||
|
||
await page.setCookie(...cookies); | ||
|
||
const loginLinkSelector = 'a[href$="api/login"]'; | ||
// const homeLinkSelector = 'a[href$="/"]'; | ||
const activityReportsSelector = 'a[href$="activity-reports"]'; | ||
|
||
await page.goto(scope.uri); | ||
await page.waitForSelector('em'); // Page title | ||
const name = await page.$eval('em', (el) => el.innerText); | ||
|
||
assert.equal(name, 'TTA Smart Hub'); | ||
// Check if actually logged in. If not login | ||
const result = await page.$(loginLinkSelector); | ||
|
||
if (result) { | ||
await page.click(loginLinkSelector); | ||
await page.waitForSelector(activityReportsSelector); // Activity Reports link | ||
await page.screenshot({ path: 'reports/givenLoggedIn.png' }); | ||
} | ||
}); | ||
|
||
Given('I am on the Smart Hub home page', async () => { | ||
await scope.context.currentPage.waitForSelector('h1'); | ||
}); | ||
|
||
Then('I see {string} message', async (string) => { | ||
const page = scope.context.currentPage; | ||
const value = await page.$eval('h1', (el) => el.textContent); | ||
|
||
assertTrue(value.includes(string)); | ||
}); | ||
|
||
Then('I see {string} link', async (string) => { | ||
const page = scope.context.currentPage; | ||
const selector = 'a[href$="activity-reports"]'; | ||
|
||
await page.waitForSelector(selector); | ||
const value = await page.$eval(selector, (el) => el.textContent); | ||
|
||
assert.equal(value, string); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# 10. BDD testing | ||
|
||
Date: 2020-10-25 | ||
|
||
## Status | ||
|
||
Pending | ||
|
||
## Context | ||
|
||
Behavior-driven development (BDD) allows for a broader team to collaborate on software development. The business stakeholders have insight into how well the software meets the requirements. Through automated tests they have a way to validate the functionality in a user friendly way. Cucumber or in our case cucumber-js is a top tool to provide a friendly language for all team members. To implement cucumber-js, additional tools are needed to provide a way to run automated browser tests. Here, Puppeteer as well as selenium webdriver both of which are popular tools to enable browser automation were evalueated. | ||
|
||
## Decision | ||
|
||
To go along with cucumber-js Puppeteer was selected. Puppeteer offers more control over Chromium based browsers, very fast, headless by default, run mode, and it can take screenshots of the pages, both in an image and PDF formats. Additionally, it measures rendering and load times by Chrome Performance Analysis tool and it is easier to set up than selenium webdriver. The drawback to using Puppeteer is it's lack of full cross-browser support, which is offered by the selenium webdriver, since Puppeteer is specialized for Chromium. | ||
|
||
## Consequences | ||
|
||
Investing time into enabling BDD with cucumber-js will have a positive impact on collaboration with the business stakeholders and provide a way to validate application's functionality. This was viewed as a worthwile investment considering that schedules might be affected. By using Puppeteer with cucumber-js we will have a solution that is fast and easier to set up with a limitation of not providing a full cross-browser support (Microsoft Edge, which is a default on Windows 10, is based on Chromium). Since the browsers to support include Chrome and IE this poses somewhat of a limitation, however the bulk of the benefits from using BDD comes from validating the application's behavior against the requirements. |
Oops, something went wrong.