diff --git a/.github/workflows/ui-smoketest.yml b/.github/workflows/ui-smoketest.yml
index 4fd43f546..34af264f6 100644
--- a/.github/workflows/ui-smoketest.yml
+++ b/.github/workflows/ui-smoketest.yml
@@ -26,7 +26,6 @@ permissions:
contents: read # This is required for actions/checkout
jobs:
-
cypress-run-chrome:
runs-on: ubuntu-22.04
environment: ${{ github.event.inputs.environment }}
@@ -51,8 +50,23 @@ jobs:
env:
CYPRESS_BASE_URL: 'https://${{ github.event.inputs.sandbox }}.access-request-fulfilment.patient-deductions.nhs.uk'
CYPRESS_grepTags: 'smoke'
+ CYPRESS_WORKSPACE: ${{ github.event.inputs.sandbox }}
CYPRESS_USERNAME: ${{ secrets.CYPRESS_USERNAME }}
CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }}
+ CYPRESS_OUTPUT_VIDEO: true
+
+ - uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: cypress-screenshots
+ path: /home/runner/work/national-document-repository/national-document-repository/app/cypress/screenshots
+ if-no-files-found: ignore
+ - uses: actions/upload-artifact@v4
+ if: failure()
+ with:
+ name: cypress-videos
+ path: /home/runner/work/national-document-repository/national-document-repository/app/cypress/videos
+ if-no-files-found: ignore
cypress-run-firefox:
runs-on: ubuntu-22.04
@@ -64,6 +78,13 @@ jobs:
repository: 'nhsconnect/national-document-repository'
ref: ${{ github.event.inputs.build_branch}}
+ - name: Configure AWS Credentials
+ uses: aws-actions/configure-aws-credentials@v2
+ with:
+ role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }}
+ role-skip-session-tagging: true
+ aws-region: ${{ vars.AWS_REGION }}
+
- name: Cypress install
run: |
npm install --legacy-peer-deps
@@ -78,8 +99,10 @@ jobs:
env:
CYPRESS_BASE_URL: 'https://${{ github.event.inputs.sandbox }}.access-request-fulfilment.patient-deductions.nhs.uk'
CYPRESS_grepTags: 'smoke'
+ CYPRESS_WORKSPACE: ${{ github.event.inputs.sandbox }}
CYPRESS_USERNAME: ${{ secrets.CYPRESS_USERNAME }}
CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }}
+ CYPRESS_OUTPUT_VIDEO: false
cypress-run-edge:
runs-on: ubuntu-22.04
@@ -105,5 +128,7 @@ jobs:
env:
CYPRESS_BASE_URL: 'https://${{ github.event.inputs.sandbox }}.access-request-fulfilment.patient-deductions.nhs.uk'
CYPRESS_grepTags: 'smoke'
+ CYPRESS_WORKSPACE: ${{ github.event.inputs.sandbox }}
CYPRESS_USERNAME: ${{ secrets.CYPRESS_USERNAME }}
CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }}
+ CYPRESS_OUTPUT_VIDEO: false
diff --git a/app/.env.template b/app/.env.template
index 40d33ddb0..d44b03365 100644
--- a/app/.env.template
+++ b/app/.env.template
@@ -7,6 +7,12 @@ REACT_APP_IMAGE_VERSION="%IMAGE_VERSION%"
CONTAINER_PORT=xx # Port number within the container. Needed for building the docker image
HOST_PORT=xxxx # Port number that the docker-compose localhost exposes. Only need this if we run docker-compose
PORT=xxxx # Port number of the localhost dev server when we run `make start`
+
+# Cypress Smoke Testing
CYPRESS_BASE_URL=http://localhost:xxxx # Use the port number same as above PORT
CYPRESS_USERNAME=xxxx # For Cypress CIS2 Login during smoke tests
CYPRESS_PASSWORD=xxxx # For Cypress CIS2 Login during smoke tests
+CYPRESS_WORKSPACE=local # Helps find the correct patient data relative to the workspace
+AWS_ACCESS_KEY_ID=xxxx # If workspace is a sandbox, data is seeded with these credentials
+AWS_SECRET_ACCESS_KEY=xxxx # If workspace is a sandbox, data is seeded with these credentials
+AWS_SESSION_TOKEN=xxxx # If workspace is a sandbox, data is seeded with these credentials
diff --git a/app/cypress.config.ts b/app/cypress.config.ts
index 6d8c37e00..c6ac7b536 100644
--- a/app/cypress.config.ts
+++ b/app/cypress.config.ts
@@ -14,6 +14,11 @@ export default defineConfig({
env: {
USERNAME: process.env.CYPRESS_USERNAME,
PASSWORD: process.env.CYPRESS_PASSWORD,
+ WORKSPACE: process.env.CYPRESS_WORKSPACE ?? 'local',
+ AWS_ACCESS_KEY_ID: process.env.AWS_ACCESS_KEY_ID,
+ AWS_SECRET_ACCESS_KEY: process.env.AWS_SECRET_ACCESS_KEY,
+ AWS_REGION: process.env.AWS_REGION,
+ AWS_SESSION_TOKEN: process.env.AWS_SESSION_TOKEN,
},
component: {
devServer: {
@@ -28,4 +33,6 @@ export default defineConfig({
html: false,
json: true,
},
+ video: process.env.CYPRESS_OUTPUT_VIDEO ? true : false,
+ videoCompression: 15,
});
diff --git a/app/cypress/e2e/0-ndr-core-tests/homepage.cy.js b/app/cypress/e2e/0-ndr-core-tests/homepage.cy.js
index 5f5bac141..88803fecd 100644
--- a/app/cypress/e2e/0-ndr-core-tests/homepage.cy.js
+++ b/app/cypress/e2e/0-ndr-core-tests/homepage.cy.js
@@ -12,6 +12,25 @@ describe('Home Page', () => {
cy.url().should('eq', baseUrl + homeUrl);
});
+ it('displays correct page title on home page', { tags: 'regression' }, () => {
+ cy.get('.app-homepage-content h1').should(
+ 'have.text',
+ 'Access and store digital GP records',
+ );
+ });
+
+ it('displays start now button on home page', { tags: 'regression' }, () => {
+ cy.get('.nhsuk-button').should('have.text', 'Start now');
+ });
+
+ it('displays service banner', { tags: 'regression' }, () => {
+ cy.get('.govuk-phase-banner__content__tag').should('have.text', 'New Service');
+ cy.get('.govuk-phase-banner__text').should(
+ 'have.text',
+ 'Your feedback will help us to improve this service.',
+ );
+ });
+
context('Login tests', () => {
it(
'should display patient search page with navigation after user log in from homepage',
@@ -42,37 +61,44 @@ describe('Home Page', () => {
});
context('Logout tests', () => {
- // TODO: Align with smoke logout test
it(
'should display home page with no navigation after user log out',
{ tags: 'regression' },
() => {
- cy.get('header').should('have.length', 1);
+ cy.get('header').should('exist');
- cy.get('.nhsuk-logo__background').should('have.length', 1);
- cy.get('.nhsuk-header__transactional-service-name').should('have.length', 1);
+ cy.get('.nhsuk-logo__background').should('exist');
+ cy.get('.nhsuk-header__transactional-service-name').should('exist');
cy.get('.nhsuk-header__transactional-service-name')
.children()
.should('have.length', 1);
+ cy.get('.nhsuk-header__transactional-service-name--link').should('exist');
cy.get('.nhsuk-header__transactional-service-name--link').should(
'have.text',
'Access and store digital GP records',
);
+ cy.get('.nhsuk-header__navigation').should('not.exist');
+ cy.get('.nhsuk-header__navigation-list').should('not.exist');
- cy.get('.nhsuk-header__navigation').should('have.length', 0);
- cy.get('.nhsuk-header__navigation-list').should('have.length', 0);
- },
- );
+ cy.login(Roles.GP_CLINICAL);
+
+ cy.url().should('eq', baseUrl + searchUrl);
+ cy.get('.nhsuk-header__navigation').should('exist');
+ cy.get('.nhsuk-header__navigation-list').should('exist');
- it('displays correct page title on home page', { tags: 'regression' }, () => {
- cy.get('.app-homepage-content h1').should(
- 'have.text',
- 'Access and store digital GP records',
- );
- });
+ cy.intercept('GET', '/Auth/Logout', {
+ statusCode: 200,
+ }).as('logout');
- it('displays start now button on home page', { tags: 'regression' }, () => {
- cy.get('.nhsuk-button').should('have.text', 'Start now');
- });
+ cy.getByTestId('logout-btn').should('exist');
+ cy.getByTestId('logout-btn').click();
+
+ cy.wait('@logout');
+ cy.url({ timeout: 10000 }).should('contain', baseUrl + homeUrl);
+
+ cy.get('.nhsuk-header__navigation').should('not.exist');
+ cy.get('.nhsuk-header__navigation-list').should('not.exist');
+ },
+ );
});
});
diff --git a/app/cypress/e2e/0-ndr-core-tests/pcse_user_workflows/patient_search_and_verify_workflow.cy.js b/app/cypress/e2e/0-ndr-core-tests/pcse_user_workflows/patient_search_and_verify_workflow.cy.js
index 6f1f1c790..6fd10fdc5 100644
--- a/app/cypress/e2e/0-ndr-core-tests/pcse_user_workflows/patient_search_and_verify_workflow.cy.js
+++ b/app/cypress/e2e/0-ndr-core-tests/pcse_user_workflows/patient_search_and_verify_workflow.cy.js
@@ -4,12 +4,11 @@ describe('PCSE Workflow: patient search and verify', () => {
// env vars
const baseUrl = Cypress.config('baseUrl');
const homeUrl = '/';
- const testPatient = '9000000009';
const patient = {
birthDate: '1970-01-01',
familyName: 'Default Surname',
givenName: ['Default Given Name'],
- nhsNumber: testPatient,
+ nhsNumber: '9000000009',
postalCode: 'AA1 1AA',
superseded: false,
restricted: false,
@@ -19,37 +18,11 @@ describe('PCSE Workflow: patient search and verify', () => {
cy.visit(homeUrl);
});
- it(
- 'It redirects to the patient download screen when patient search successfully by a PCSE user',
- { tags: 'regression' },
- () => {
- cy.intercept('GET', '/SearchPatient*', {
- statusCode: 200,
- body: patient,
- }).as('search');
-
- cy.login(Roles.PCSE);
- cy.get('#nhs-number-input').click();
- cy.get('#nhs-number-input').type(testPatient);
-
- cy.get('#search-submit').click();
- cy.wait('@search');
-
- cy.url().should('include', 'result');
- cy.url().should('eq', baseUrl + '/search/patient/result');
- cy.get('#gp-message').should('not.exist');
-
- cy.get('#verify-submit').click();
-
- cy.url().should('include', 'results');
- cy.url().should('eq', baseUrl + '/search/results');
- },
- );
-
it(
'It shows the download documents page when download patient is verified by a PCSE user',
{ tags: 'regression' },
() => {
+ const testPatient = '9000000009';
cy.login(Roles.PCSE);
cy.intercept('GET', '/SearchPatient*', {
statusCode: 200,
@@ -66,31 +39,11 @@ describe('PCSE Workflow: patient search and verify', () => {
},
);
- it(
- 'It searches for a valid patient successfully when the user enters a known nhs number by a PCSE user',
- { tags: 'regression' },
- () => {
- cy.intercept('GET', '/SearchPatient*', {
- statusCode: 200,
- body: patient,
- }).as('search');
-
- cy.login(Roles.PCSE);
- cy.get('#nhs-number-input').click();
- cy.get('#nhs-number-input').type(testPatient);
-
- cy.get('#search-submit').click();
- cy.wait('@search');
-
- cy.url().should('include', 'result');
- cy.url().should('eq', baseUrl + '/search/patient/result');
- },
- );
-
it(
'It searches for a valid patient successfully when the user enters a known nhs number with spaces by a PCSE user',
{ tags: 'regression' },
() => {
+ const testPatient = '900 000 0009';
cy.intercept('GET', '/SearchPatient*', {
statusCode: 200,
body: {
@@ -114,6 +67,7 @@ describe('PCSE Workflow: patient search and verify', () => {
'It searches for a valid patient successfully when the user enters a known nhs number with dashes by a PCSE user',
{ tags: 'regression' },
() => {
+ const testPatient = '900-000-0009';
cy.intercept('GET', '/SearchPatient*', {
statusCode: 200,
body: {
diff --git a/app/cypress/e2e/1-ndr-smoke-tests/gp_user_workflows/patient_search_and_verify_workflow.cy.js b/app/cypress/e2e/1-ndr-smoke-tests/gp_user_workflows/patient_search_and_verify_workflow.cy.js
new file mode 100644
index 000000000..ef982f42c
--- /dev/null
+++ b/app/cypress/e2e/1-ndr-smoke-tests/gp_user_workflows/patient_search_and_verify_workflow.cy.js
@@ -0,0 +1,33 @@
+import { Roles, roleName } from '../../../support/roles';
+
+describe('GP Workflow: Patient search and verify', () => {
+ // env vars
+ const baseUrl = Cypress.config('baseUrl');
+ const gpRoles = [Roles.GP_ADMIN, Roles.GP_CLINICAL];
+
+ const workspace = Cypress.env('WORKSPACE');
+ const activePatient = workspace === 'ndr-dev' ? '9730153817' : '9000000002';
+
+ gpRoles.forEach((role) => {
+ it(
+ `[Smoke] Shows the Lloyd george view page when upload patient is verified and active as a ${roleName(
+ role,
+ )} `,
+ { tags: 'smoke' },
+ () => {
+ cy.smokeLogin(role);
+ cy.get('#nhs-number-input').click();
+ cy.get('#nhs-number-input').type(activePatient);
+ cy.get('#search-submit').click();
+
+ cy.url({ timeout: 10000 }).should('eq', baseUrl + '/search/upload/result');
+ cy.get('#verify-submit').click();
+
+ cy.url({ timeout: 10000 }).should(
+ 'eq',
+ baseUrl + '/search/patient/lloyd-george-record',
+ );
+ },
+ );
+ });
+});
diff --git a/app/cypress/e2e/1-ndr-smoke-tests/homepage.cy.js b/app/cypress/e2e/1-ndr-smoke-tests/homepage.cy.js
index 96691d02b..207198e86 100644
--- a/app/cypress/e2e/1-ndr-smoke-tests/homepage.cy.js
+++ b/app/cypress/e2e/1-ndr-smoke-tests/homepage.cy.js
@@ -13,30 +13,68 @@ describe('Home Page', () => {
cy.url().should('eq', baseUrl + homeUrl);
});
- it(
- '[Smoke] should display patient search page with navigation after user log in from homepage',
- { tags: 'smoke' },
- () => {
- cy.get('header').should('exist');
-
- cy.get('.nhsuk-logo__background').should('exist');
- cy.get('.nhsuk-header__transactional-service-name').should('exist');
- cy.get('.nhsuk-header__transactional-service-name').children().should('have.length', 1);
- cy.get('.nhsuk-header__transactional-service-name--link').should('exist');
- cy.get('.nhsuk-header__transactional-service-name--link').should(
- 'have.text',
- 'Access and store digital GP records',
- );
- cy.get('.nhsuk-header__navigation').should('not.exist');
- cy.get('.nhsuk-header__navigation-list').should('not.exist');
-
- cy.smokeLogin(Roles.GP_CLINICAL);
-
- cy.url().should('eq', baseUrl + searchUrl);
- cy.get('.nhsuk-header__navigation').should('exist');
- cy.get('.nhsuk-header__navigation-list').should('exist');
- },
-
- //TODO: Add logout test
- );
+ context('Login tests', () => {
+ it(
+ '[Smoke] should display patient search page with navigation after user log in from homepage',
+ { tags: 'smoke' },
+ () => {
+ cy.get('header').should('exist');
+
+ cy.get('.nhsuk-logo__background').should('exist');
+ cy.get('.nhsuk-header__transactional-service-name').should('exist');
+ cy.get('.nhsuk-header__transactional-service-name')
+ .children()
+ .should('have.length', 1);
+ cy.get('.nhsuk-header__transactional-service-name--link').should('exist');
+ cy.get('.nhsuk-header__transactional-service-name--link').should(
+ 'have.text',
+ 'Access and store digital GP records',
+ );
+ cy.get('.nhsuk-header__navigation').should('not.exist');
+ cy.get('.nhsuk-header__navigation-list').should('not.exist');
+
+ cy.smokeLogin(Roles.GP_CLINICAL);
+
+ cy.url().should('eq', baseUrl + searchUrl);
+ cy.get('.nhsuk-header__navigation').should('exist');
+ cy.get('.nhsuk-header__navigation-list').should('exist');
+ },
+ );
+ });
+
+ context('Logout tests', () => {
+ it(
+ '[Smoke] should display home page with no navigation after user log out',
+ { tags: 'smoke' },
+ () => {
+ cy.get('header').should('exist');
+
+ cy.get('.nhsuk-logo__background').should('exist');
+ cy.get('.nhsuk-header__transactional-service-name').should('exist');
+ cy.get('.nhsuk-header__transactional-service-name')
+ .children()
+ .should('have.length', 1);
+ cy.get('.nhsuk-header__transactional-service-name--link').should('exist');
+ cy.get('.nhsuk-header__transactional-service-name--link').should(
+ 'have.text',
+ 'Access and store digital GP records',
+ );
+ cy.get('.nhsuk-header__navigation').should('not.exist');
+ cy.get('.nhsuk-header__navigation-list').should('not.exist');
+
+ cy.smokeLogin(Roles.GP_CLINICAL);
+
+ cy.url().should('eq', baseUrl + searchUrl);
+ cy.get('.nhsuk-header__navigation').should('exist');
+ cy.get('.nhsuk-header__navigation-list').should('exist');
+
+ cy.getByTestId('logout-btn').should('exist');
+ cy.getByTestId('logout-btn').click();
+ cy.url({ timeout: 10000 }).should('eq', baseUrl + homeUrl);
+
+ cy.get('.nhsuk-header__navigation').should('not.exist');
+ cy.get('.nhsuk-header__navigation-list').should('not.exist');
+ },
+ );
+ });
});
diff --git a/app/cypress/support/aws.commands.ts b/app/cypress/support/aws.commands.ts
index 9184316ff..3b80ac47b 100644
--- a/app/cypress/support/aws.commands.ts
+++ b/app/cypress/support/aws.commands.ts
@@ -2,34 +2,60 @@
import AWS from './aws.config';
-Cypress.Commands.add('addFileToS3', (bucketName, fileName, fileContent) => {
- const s3 = new AWS.S3();
+Cypress.Commands.add(
+ 'addFileToS3',
+ (bucketName: string, fileName: string, fileContent: AWS.S3.Body) => {
+ const s3 = new AWS.S3();
- const params: AWS.S3.Types.PutObjectRequest = {
- Bucket: bucketName,
- Key: fileName,
- Body: fileContent,
- };
+ const params: AWS.S3.Types.PutObjectRequest = {
+ Bucket: bucketName,
+ Key: fileName,
+ Body: fileContent,
+ };
- s3.upload(params, (err, data) => {
- if (err) {
- console.error('Error uploading file to S3:', err);
- } else {
- console.log('File uploaded successfully to S3:', data.Location);
- }
- });
-});
+ return cy.wrap(
+ new Cypress.Promise((resolve, reject) => {
+ s3.upload(params, (err, data) => {
+ if (err) {
+ const message = 'Error uploading file to S3:' + err;
+ console.error(message);
+ reject(message);
+ } else {
+ console.log('File uploaded successfully to S3:', data.Location);
+ resolve(data);
+ }
+ });
+ }),
+ );
+ },
+);
-Cypress.Commands.add('addItemToDynamoDb', (tableName, item) => {
- const dynamoDB = new AWS.DynamoDB();
+Cypress.Commands.add(
+ 'addItemToDynamoDb',
+ (tableName: string, item: AWS.DynamoDB.PutItemInputAttributeMap) => {
+ const dynamoDB = new AWS.DynamoDB();
- const params = {
- TableName: tableName,
- Item: AWS.DynamoDB.Converter.marshall(item),
- };
+ const params: AWS.DynamoDB.PutItemInput = {
+ TableName: tableName,
+ Item: AWS.DynamoDB.Converter.marshall(item),
+ };
- return cy.wrap(dynamoDB.putItem(params).promise(), { timeout: 10000 });
-});
+ return cy.wrap(
+ new Cypress.Promise((resolve, reject) => {
+ dynamoDB.putItem(params, (err, data) => {
+ if (err) {
+ const message = 'Error uploading to Dynamo:' + tableName;
+ console.error(message);
+ reject(message);
+ } else {
+ console.log('Upload to Dynamo success:', tableName);
+ resolve(data);
+ }
+ });
+ }),
+ );
+ },
+);
Cypress.Commands.add('deleteFileFromS3', (bucketName: string, fileName: string) => {
const s3 = new AWS.S3();
@@ -39,9 +65,20 @@ Cypress.Commands.add('deleteFileFromS3', (bucketName: string, fileName: string)
Key: fileName,
};
- return cy.wrap(s3.deleteObject(params).promise(), { timeout: 10000 }).then(() => {
- console.log('File deleted successfully from S3:', fileName);
- });
+ return cy.wrap(
+ new Cypress.Promise((resolve, reject) => {
+ s3.deleteObject(params, (err, data) => {
+ if (err) {
+ const message = 'Error uploading to S3:' + bucketName;
+ console.error(message);
+ reject(message);
+ } else {
+ console.log('Upload to S3 success:', bucketName);
+ resolve(data);
+ }
+ });
+ }),
+ );
});
Cypress.Commands.add('deleteItemFromDynamoDb', (tableName: string, itemId: string) => {
@@ -54,7 +91,18 @@ Cypress.Commands.add('deleteItemFromDynamoDb', (tableName: string, itemId: strin
},
};
- return cy.wrap(dynamoDB.deleteItem(params).promise(), { timeout: 10000 }).then(() => {
- console.log('Item deleted successfully from DynamoDB:', itemId);
- });
+ return cy.wrap(
+ new Cypress.Promise((resolve, reject) => {
+ dynamoDB.deleteItem(params, (err, data) => {
+ if (err) {
+ const message = 'Error uploading to Dynamo:' + tableName;
+ console.error(message);
+ reject(message);
+ } else {
+ console.log('Upload to Dynamo success:', tableName);
+ resolve(data);
+ }
+ });
+ }),
+ );
});
diff --git a/app/cypress/support/aws.config.ts b/app/cypress/support/aws.config.ts
index 225a34dde..1ec6ca0fe 100644
--- a/app/cypress/support/aws.config.ts
+++ b/app/cypress/support/aws.config.ts
@@ -2,10 +2,10 @@ import AWS from 'aws-sdk';
// need to get from env vars
AWS.config.update({
- accessKeyId: '',
- secretAccessKey: '',
- region: '',
- sessionToken: '',
+ accessKeyId: Cypress.env('AWS_accessKeyId'),
+ secretAccessKey: Cypress.env('AWS_secretAccessKey'),
+ region: Cypress.env('AWS_region'),
+ sessionToken: Cypress.env('AWS_sessionToken'),
});
export default AWS;
diff --git a/app/cypress/support/commands.ts b/app/cypress/support/commands.ts
deleted file mode 100644
index 780b9dcbf..000000000
--- a/app/cypress/support/commands.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-///
-const registerCypressGrep = require('@cypress/grep');
-registerCypressGrep();
-// ***********************************************
-// This example commands.ts shows you how to
-// create various custom commands and overwrite
-// existing commands.
-//
-// For more comprehensive examples of custom
-// commands please read more here:
-// https://on.cypress.io/custom-commands
-// ***********************************************
-//
-//
-// -- This is a parent command --
-// Cypress.Commands.add('login', (email, password) => { ... })
-//
-//
-// -- This is a child command --
-// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
-//
-//
-// -- This is a dual command --
-// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
-//
-//
-// -- This will overwrite an existing command --
-// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
-//
-// declare global {
-// namespace Cypress {
-// interface Chainable {
-// login(email: string, password: string): Chainable
-// drag(subject: string, options?: Partial): Chainable
-// dismiss(subject: string, options?: Partial): Chainable
-// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
-// }
-// }
-// }
diff --git a/app/cypress/support/e2e.ts b/app/cypress/support/e2e.ts
index 2f552eb4b..5f186e92e 100644
--- a/app/cypress/support/e2e.ts
+++ b/app/cypress/support/e2e.ts
@@ -1,23 +1,9 @@
-///
-// ***********************************************************
-// This example support/e2e.ts is processed and
-// loaded automatically before your test files.
-//
-// This is a great place to put global configuration and
-// behavior that modifies Cypress.
-//
-// You can change the location of this file or turn off
-// automatically serving support files with the
-// 'supportFile' configuration option.
-//
-// You can read more here:
-// https://on.cypress.io/configuration
-// ***********************************************************
-
-import './commands';
-import './aws.commands';
+import { DynamoDB, S3 } from 'aws-sdk';
import { Roles, roleIds, roleList } from './roles';
-
+import Bluebird from 'cypress/types/bluebird';
+///
+const registerCypressGrep = require('@cypress/grep');
+registerCypressGrep();
Cypress.Commands.add('getByTestId', (selector, ...args) => {
return cy.get(`[data-testid=${selector}]`, ...args);
@@ -91,49 +77,59 @@ declare global {
* @param {string} value - The value of the data-testid attribute of the target DOM element.
* @return {HTMLElement} - Target DOM element.
*/
- getByTestId(value: string);
+ getByTestId(value: string): Chainable>;
/**
* Mock user login by intercepting the {baseUrl}/auth-callback request
* @param {Roles} role - The user role to login with. Must be an enum of Roles
*/
- login(role: Roles);
+ login(role: Roles): Chainable;
/**
* Real user login via CIS2 and redirect back to {baseUrl}/auth-callback.
* @param {Roles} role - The user role to login with. Must be an enum of Roles
*/
- smokeLogin(role: Roles);
+ smokeLogin(role: Roles): Chainable;
/**
* Add file to s3 bucket
* @param {string} bucketName - Name of the target S3 bucket
* @param {string} fileName - Filepath of the file to upload
* @param {string} fileContent - Content of the file to upload
+ * @return {Promise} - S3 response for s3.upload
*/
addFileToS3(
bucketName: string,
fileName: string,
- fileContent: string,
- ): Chainable;
+ fileContent: S3.Body,
+ ): Chainable>;
/**
* Add dynamoDB entry
* @param {string} tableName - Name of the target dynamoDB table
* @param {{ [key: string]: any; }} item - dynamoDB item to upload
+ * @return {Promise} - Dynamo response for dynamoDB.putItem
*/
addItemToDynamoDb(
tableName: string,
- item: { [key: string]: string },
- ): Chainable;
+ item: DynamoDB.PutItemInputAttributeMap,
+ ): Chainable>;
/**
* Delete file from S3 bucket
* @param {string} bucketName - Name of the target S3 bucket
* @param {string} fileName - Filepath of the file to delete
+ * @return {Promise} - S3 response for s3.deleteObject
*/
- deleteFileFromS3(bucketName: string, fileName: string): Chainable;
+ deleteFileFromS3(
+ bucketName: string,
+ fileName: string,
+ ): Chainable>;
/**
* Delete item from DynamoDB table
* @param {string} tableName - Name of the target DynamoDB table
* @param {string} itemId - ID of the item to delete
+ * @return {Promise} - Dynamo response for dynamoDB.deleteItem
*/
- deleteItemFromDynamoDb(tableName: string, itemId: string): Chainable;
+ deleteItemFromDynamoDb(
+ tableName: string,
+ itemId: string,
+ ): Chainable>;
}
}
}
diff --git a/app/package-lock.json b/app/package-lock.json
index 5a3fe060f..5328dbf09 100644
--- a/app/package-lock.json
+++ b/app/package-lock.json
@@ -13,7 +13,6 @@
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.5.0",
- "cross-env": "^7.0.3",
"dotenv": "^16.3.1",
"eslint-plugin-legacy-decorators": "^1.0.0",
"fake-progress": "^1.0.4",
@@ -11694,23 +11693,6 @@
"node": ">=10"
}
},
- "node_modules/cross-env": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
- "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
- "dependencies": {
- "cross-spawn": "^7.0.1"
- },
- "bin": {
- "cross-env": "src/bin/cross-env.js",
- "cross-env-shell": "src/bin/cross-env-shell.js"
- },
- "engines": {
- "node": ">=10.14",
- "npm": ">=6",
- "yarn": ">=1"
- }
- },
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
diff --git a/app/package.json b/app/package.json
index 97b533d8b..c6ed4e556 100644
--- a/app/package.json
+++ b/app/package.json
@@ -25,6 +25,7 @@
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
+ "aws-sdk": "^2.1510.0",
"axios": "^1.5.0",
"dotenv": "^16.3.1",
"eslint-plugin-legacy-decorators": "^1.0.0",
@@ -47,7 +48,6 @@
"web-vitals": "^2.1.4"
},
"devDependencies": {
- "aws-sdk": "^2.1510.0",
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@storybook/addon-essentials": "^7.4.0",
"@storybook/addon-interactions": "^7.4.0",
diff --git a/lambdas/services/bulk_upload_service.py b/lambdas/services/bulk_upload_service.py
index edc632d41..82a628367 100644
--- a/lambdas/services/bulk_upload_service.py
+++ b/lambdas/services/bulk_upload_service.py
@@ -56,7 +56,7 @@ def process_message_queue(self, records: list):
"All remaining messages in this batch will be returned to sqs queue to retry later."
)
- all_unprocessed_message = records[index - 1:]
+ all_unprocessed_message = records[index - 1 :]
for unprocessed_message in all_unprocessed_message:
self.sqs_repository.put_sqs_message_back_to_queue(
unprocessed_message