Skip to content

Commit

Permalink
Update to match features in CHA accp. test project (#17)
Browse files Browse the repository at this point in the history
We recently added the project [SROC Charging Module API tests](https://github.com/DEFRA/sroc-charging-module-api-tests) to our suite of tools. It is also Cypress based and will be used to test the [Charging Module API](https://github.com/DEFRA/sroc-charging-module-api) going forward.

We started with this project as a base and then made the necessary amendments to allow us to test an API. Along the way, we also made a few other improvements. This change is about bringing those improvements back into this project and keeping the 2 consistent to make it easier to switch between them.

The keys changes are

- use `*.env` files for all customer configuration and store them in an `/environments` folder
- add the ability to generate a test report to make it easier to share results with other stakeholders
- adding CI support to the project
  • Loading branch information
Cruikshanks authored Oct 5, 2021
1 parent 6b86212 commit 25a7ce3
Show file tree
Hide file tree
Showing 27 changed files with 10,184 additions and 1,367 deletions.
10 changes: 0 additions & 10 deletions .env.example

This file was deleted.

62 changes: 62 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: CI

on: push

jobs:
build:
# You must use a Linux environment when using service containers or container jobs
runs-on: ubuntu-latest

steps:
# Downloads a copy of the code in your repository before running CI tests
- name: Checkout repository
uses: actions/checkout@v2

# Check for 'temporary' tags i.e. tags often used when working on a feature/scenario but which we don't want
# appearing in the final commit to main
#
# Reworking of https://stackoverflow.com/a/21788642/6117745
- name: Temporary tag check
run: |
! grep -r --include="*.feature" "@wip\|@focus" cypress/integration/
# Our projects use .nvmrc files to specify the node version to use. We can read and then output it as the result
# this step. Subsequent steps can then access the value
- name: Read Node version
run: echo "##[set-output name=NVMRC;]$(cat .nvmrc)"
# Give the step an ID to make it easier to refer to
id: nvm

# Gets the version to use by referring to the previous step
- name: Install Node
uses: actions/[email protected]
with:
node-version: "${{ steps.nvm.outputs.NVMRC }}"

# Speeds up workflows by reading the node modules from cache. Obviously you need to run it at least once, and the
# cache will be updated should the package-lock.json file change
- name: Cache Node modules
uses: actions/cache@v2
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.OS }}-node-
${{ runner.OS }}-
# Performs a clean installation of all dependencies in the `package.json` file
# For more information, see https://docs.npmjs.com/cli/ci.html
- name: Install dependencies
run: npm ci

# Run linting first. No point running the tests if there is a linting issue
- name: Run lint check
run: |
npm run lint
# We don't have unit tests in this project. We also can't access the service as its hidden behind a VPN. Instead
# we run a special CI test to confirm we haven't broken being able to run the project
- name: Run unit tests
run: |
npm run cy:run:ci
20 changes: 15 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,19 @@ cypress/videos/
# Screenshots generated by Cypress
cypress/screenshots/

# Downloads generated by Cypress
cypress/downloads/

# Test output generated by cypress-cucumber-preprocessor
cypress/reports/json/*.json

# Merged test output and report generated by cucumber-html-reporter
cypress/reports/html/*.html
cypress/reports/html/*.json

# Dotenv https://github.com/motdotla/dotenv
# Ignore the .env file as this may contain actual credentials. The .env.example
# file gets committed which acts as documentation on what environment
# variables will need to be set up
.env
.env.local
# Ignore our .env files as they contain actual credentials. The .example.env file gets committed to act as documentation
# on what environment variables need to be set up. The .ci.env is to support our automated CI build
/environments/*
!/environments/.ci.env
!/environments/.example.env
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
14
26 changes: 19 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,21 @@ npm install

## Configuration

> Important! Do not store credentials such as passwords in the config files
> Important! Do not add environment files to source control
We have 5 environments where the TCM could be running; local, development, test, pre-production, and production.
We have 5 environments where the CHA could be running; local, development, test, pre-production, and production.

Each has its own config file stored in `config/`. Any configuration shared across the environments is stored in `cypress.json`. But these can be overidden in the environment config file.
Each has its own config file stored in `environments/`. Any configuration shared across the environments is stored in `cypress.json`. But this can be overidden in the environment config files.

### Dotenv
### Environment files

Via the [Cypress dotenv](https://github.com/morficus/cypress-dotenv) plugin you can store environment variables in a local `.env` file.
The config or 'environment' files hold environment variables which are key-value pairs; _name of the thing_ and the _value of the thing_. For example, `CYPRESS_PASSWORD=password12345`.

Things like credentials, which we don't want stored in the project, we'll pass in as environment variables. Dotenv and the `.env` file saves you having to add them to your session.
Depending on the environment selected the [Cypress dotenv](https://github.com/morficus/cypress-dotenv) plugin will read in the values and make them available via [Cypress.env()](https://docs.cypress.io/api/cypress-api/env) in the tests.

Checkout `.env.example` for an example of the file you'll need to create to run the project.
Using these `.env` files allows us to store both config and credentials that change across environments in one place but it is important they are *_never_* committed to source control.

Checkout [environments/.env.example](/environments/.env.example) for an example of the file you'll need to create for each environment.

## Execution

Expand Down Expand Up @@ -94,6 +96,16 @@ Another preference of the team is to use the [Page object pattern](https://marti

Pages live in `cypress/pages`.

## Reporting

Built into the project is the ability to generate a HTML report of your last test run.

<img src="docs/report.png" width="400" alt="Screenshot of html report" />

Each time you use `cy:open` or `cy:run` the project will automatically delete the previous test results and generate new ones based on what tests are run.

If you then call `npm run report` the project will generate a HTML report based on the test results. You can access the report at `cypress/reports/html/report.html`.

## Contributing to this project

If you have an idea you'd like to contribute please log an issue.
Expand Down
3 changes: 0 additions & 3 deletions config/dev.json

This file was deleted.

3 changes: 0 additions & 3 deletions config/local.json

This file was deleted.

3 changes: 0 additions & 3 deletions config/pre.json

This file was deleted.

3 changes: 0 additions & 3 deletions config/tst.json

This file was deleted.

1 change: 0 additions & 1 deletion cypress.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
},
"testFiles": "**/*.feature",
"video": false,
"baseUrl": "http://localhost:3000",
"users": {
"system": {
"email": "[email protected]",
Expand Down
11 changes: 11 additions & 0 deletions cypress/integration/ci.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@ci
Feature: Continuous integration check of the project
As a contributor to this project
I want to know a change I made hasn't broken it (though it may have failing tests)
So that we have a reliable base on which to build our acceptance tests

Scenario: Check project will run
Given a cucumber that is 30 cm long
When I cut it in halves
Then I have two cucumbers
And both are 15 cm long
27 changes: 27 additions & 0 deletions cypress/integration/ci/ci_steps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Given, When, Then, And } from 'cypress-cucumber-preprocessor/steps'

Given('a cucumber that is {int} cm long', (length) => {
cy.wrap({ color: 'green', size: length }).as('cucumber')
})

When('I cut it in halves', () => {
cy.get('@cucumber').then((cucumber) => {
cy.wrap(
[{ color: 'green', size: cucumber.size / 2 }, { color: 'green', size: cucumber.size / 2 }]
).as('choppedCucumbers')
})
})

Then('I have two cucumbers', () => {
cy.get('@choppedCucumbers').then((choppedCucumbers) => {
expect(choppedCucumbers).to.have.lengthOf(2)
})
})

And('both are {int} cm long', (length) => {
cy.get('@choppedCucumbers').then((choppedCucumbers) => {
choppedCucumbers.forEach((cucumber) => {
expect(cucumber.size).to.equal(length)
})
})
})
2 changes: 1 addition & 1 deletion cypress/integration/common/general.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Then } from 'cypress-cucumber-preprocessor/steps'

Then(`I see {string} in the main heading`, (title) => {
Then('I see {string} in the main heading', (title) => {
cy.get('h1').contains(title)
})
24 changes: 12 additions & 12 deletions cypress/integration/export_data/export_data.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { Before, When, Then, And } from 'cypress-cucumber-preprocessor/steps'
import { When, Then, And } from 'cypress-cucumber-preprocessor/steps'
import ExportDataPage from '../../pages/export_data_page'
import TransactionsPage from '../../pages/transactions_page'

When('I select the {string} regime', (regime) => {
TransactionsPage.regimeMenu().click()
TransactionsPage.regimeMenuItem(regime).click()
})
TransactionsPage.regimeMenu().click()
TransactionsPage.regimeMenuItem(regime).click()
})

And('I proceed to view file download details', () => {
TransactionsPage.transactionMenu().click()
TransactionsPage.downloadTransactionDataMenuItem().click()
})
TransactionsPage.transactionMenu().click()
TransactionsPage.downloadTransactionDataMenuItem().click()
})

Then('I can view the Data Protection Notice', () => {
ExportDataPage.dataProtectionNotice().should('be.visible')
})
})

And('I can download transaction data', () => {
ExportDataPage.downloadBtn().should('have.attr', 'href', '/regimes/pas/data_export/download')
//DownloadTransactionFilePage.downloadBtn().click()
})
// DownloadTransactionFilePage.downloadBtn().click()
})
38 changes: 19 additions & 19 deletions cypress/integration/review_annual_billing/annual_billing_steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,33 @@ import { When, Then, And } from 'cypress-cucumber-preprocessor/steps'
import AnnualBillingPage from '../../pages/annual_billing_page'
import AnnualBillingFileDetailsPage from '../../pages/annual_billing_file_details_page'
import TransactionsPage from '../../pages/transactions_page'

When('I select the {string} regime', (regime) => {
TransactionsPage.regimeMenu().click()
TransactionsPage.regimeMenuItem(regime).click()
})
TransactionsPage.regimeMenu().click()
TransactionsPage.regimeMenuItem(regime).click()
})

And('I proceed to review Annual Billing details', () => {
TransactionsPage.annualBillingDataMenuItem().click()
TransactionsPage.reviewAnnualBillingDataMenuItem().click()
AnnualBillingPage.mainHeading().should('be.visible')
})
TransactionsPage.annualBillingDataMenuItem().click()
TransactionsPage.reviewAnnualBillingDataMenuItem().click()
AnnualBillingPage.mainHeading().should('be.visible')
})

Then('I can view a list of Annual Billing Data Files', () => {
AnnualBillingPage.dataFilesTable().should('be.visible')
})
AnnualBillingPage.dataFilesTable().should('be.visible')
})

And('I select an Annual Billing File to review', () => {
AnnualBillingPage.fileNameLink().click()
AnnualBillingFileDetailsPage.mainHeading().should('be.visible')
})
AnnualBillingPage.fileNameLink().click()
AnnualBillingFileDetailsPage.mainHeading().should('be.visible')
})

Then('I can view the details of the selected Annual Billing File', () => {
AnnualBillingFileDetailsPage.fileDetailsPanel().should('be.visible')
AnnualBillingFileDetailsPage.errorsHeading().should('be.visible')
})
AnnualBillingFileDetailsPage.fileDetailsPanel().should('be.visible')
AnnualBillingFileDetailsPage.errorsHeading().should('be.visible')
})

And('I can navigate back to Review Annual Billing', () => {
AnnualBillingFileDetailsPage.backBtn().click()
AnnualBillingPage.mainHeading().should('be.visible')
})
AnnualBillingFileDetailsPage.backBtn().click()
AnnualBillingPage.mainHeading().should('be.visible')
})
32 changes: 15 additions & 17 deletions cypress/pages/annual_billing_file_details_page.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
class AnnualBillingFileDetailsPage {

static mainHeading () {
return cy.get('h1')
}
static mainHeading () {
return cy.get('h1')
}

static errorsHeading () {
return cy.get('h2')
}

static fileDetailsPanel () {
return cy.get('.panel')
}
static errorsHeading () {
return cy.get('h2')
}

static backBtn () {
return cy.get('.btn.btn-secondary')
}

static fileDetailsPanel () {
return cy.get('.panel')
}

export default AnnualBillingFileDetailsPage

static backBtn () {
return cy.get('.btn.btn-secondary')
}
}

export default AnnualBillingFileDetailsPage
27 changes: 12 additions & 15 deletions cypress/pages/annual_billing_page.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
class AnnualBillingPage {

static mainHeading () {
return cy.get('h1')
}

static dataFilesTable () {
return cy.get('.table')
}
static mainHeading () {
return cy.get('h1')
}

static dataFilesTable () {
return cy.get('.table')
}

static fileNameLink () {
return cy.get('.table > tbody > tr > td > [href="/regimes/wml/annual_billing_data_files/48"]')
}

static fileNameLink () {
return cy.get('.table > tbody > tr > td > [href="/regimes/wml/annual_billing_data_files/48"]')
}
export default AnnualBillingPage
}

export default AnnualBillingPage
Loading

0 comments on commit 25a7ce3

Please sign in to comment.