Skip to content

Commit

Permalink
test: implement e2e for DCC (#199)
Browse files Browse the repository at this point in the history
* test: implement e2e test for dcc

* test: delete unused code in DCC e2e test

* test: add condition when reading file in app config of dcc e2e test

* test: remove comment in issue DCC e2e test

* test: change name of delete file in e2e test

* test: update test title in issueDCC e2e test
  • Loading branch information
ldhyen99 authored Jan 21, 2025
1 parent b0f7d71 commit 9ce7bb8
Show file tree
Hide file tree
Showing 8 changed files with 2,494 additions and 2,661 deletions.
3,577 changes: 1,785 additions & 1,792 deletions app-config.e2e.json

Large diffs are not rendered by default.

15 changes: 13 additions & 2 deletions cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default defineConfig({
openMode: 0, // No retries in interactive mode
},
defaultCommandTimeout: 4000,
defaultBrowser: "chrome",
defaultBrowser: 'chrome',
setupNodeEvents(on) {
on('task', {
writeToFile({ fileName, data }: { fileName: string; data: any }) {
Expand All @@ -33,7 +33,18 @@ export default defineConfig({
} catch (error: any) {
throw error;
}
}
},
deleteFileCredentialE2E(fileName: string) {
const filePath = path.resolve('cypress/fixtures/credentials-e2e', fileName);
return new Promise((resolve, reject) => {
fs.unlink(filePath, (err) => {
if (err) {
return reject(err);
}
resolve(null);
});
});
},
});
},
},
Expand Down
10 changes: 10 additions & 0 deletions cypress/e2e/issue_workflow_test/DCC/credentials.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"credentials": [
{
"type": "digitalConformityCredential",
"version": "v0.5.0",
"dataPath": "../../cypress/fixtures/credentials-e2e/DigitalConformityCredential_instance-v0.5.0.json",
"url": ""
}
]
}
123 changes: 123 additions & 0 deletions cypress/e2e/issue_workflow_test/DCC/issueDCC.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
describe('Issue DCC end-to-end testing flow', () => {
beforeEach(() => {
// Load app config JSON
cy.fixture('app-config.json').then((data) => {
Cypress.env('AppConfig', data);
});
});

it('should access the right app config data', () => {
const AppConfig = Cypress.env('AppConfig');
expect(AppConfig?.name).to.not.be.null;
expect(AppConfig?.name).to.not.be.undefined;
});

it('should visit the homepage, navigate to "Generate DCC" through "General features", handle API calls, and show success message', () => {
const AppConfig = Cypress.env('AppConfig');
cy.visit('/');

cy.contains('a', 'General features').should('be.visible').and('not.be.disabled').click();

cy.url().should('include', '/general-features');
const feature = AppConfig.generalFeatures[0]?.features.find(
(feature: { name: string }) => feature.name === 'Generate DCC',
);

const shemaDCC = feature?.components[0].props?.schema?.url ?? '';
const appService = feature?.services[0]?.parameters[0] ?? {};
cy.intercept('GET', shemaDCC).as('getConformityCredential');

cy.contains('a', 'Generate DCC')
.should('be.visible')
.and('not.be.disabled')
.click();

cy.wait('@getConformityCredential', { timeout: 20000 }).then((interception) => {
expect(interception?.response?.statusCode).to.eq(200);
});

const API_ENDPOINT = {
ISSUE_BITSTRING_STATUS_LIST: '/agent/issueBitstringStatusList',
VCKit_URL: appService?.vckit?.vckitAPIUrl + '/credentials/issue',
STORAGE_URL: appService?.storage?.url,
IDR_URL: appService?.dlr?.dlrAPIUrl + appService?.dlr?.linkRegisterPath,
};
cy.intercept('POST', API_ENDPOINT.ISSUE_BITSTRING_STATUS_LIST).as('issueBitStringStatusList');
cy.intercept('POST', API_ENDPOINT.VCKit_URL).as('issueCredentials');
cy.intercept('POST', API_ENDPOINT.STORAGE_URL).as('storeVC');
cy.intercept('POST', API_ENDPOINT.IDR_URL).as('linkResolverRegister');

cy.contains('button', 'Submit').should('be.visible').and('not.be.disabled').click();

// await API create credential status
cy.wait('@issueBitStringStatusList').then((interception) => {
expect(interception?.response?.statusCode).to.eq(200);
cy.log('Completed: issueBitstringStatusList');
});

// await API issue VC
cy.wait('@issueCredentials').then((interception) => {
const credential = interception.request.body.credential;
cy.log('interception: request: ', JSON.stringify(credential));
expect(interception?.response?.statusCode).to.eq(201);
// Write the credential to a file
cy.task('writeToFile', { fileName: 'DigitalConformityCredential_instance-v0.5.0.json', data: credential });
cy.log('Completed: issueCredentials and written to file');
});

// await API storage VC
cy.wait('@storeVC').then((interception) => {
expect(interception?.response?.statusCode).to.eq(201);
cy.log('Completed: storeVC');

// Extract the URI from the response
const { uri, hash } = interception?.response?.body;
expect(uri).to.not.be.undefined;
expect(hash).to.not.be.undefined;
cy.request('GET', uri).then((response) => {
expect(response.status).to.eq(200);
});
});

// await API register link
cy.wait('@linkResolverRegister').then((interception) => {
expect(interception?.response?.statusCode).to.eq(201);
cy.log('Completed: linkResolverRegister');
});

// Verify toast appears, using react-toastify
cy.get('.Toastify__toast').should('be.visible').and('contain', 'Action Successful');
});

it('Verify linkType', () => {
const checkLinkTypeURL = 'http://localhost:3000/gs1/01/09359502000034';
cy.request('GET', checkLinkTypeURL).then((response) => {
expect(response.status).to.eq(200);
});
});

it('Runs testing UNTP V0.5.0', () => {
cy.task('runShellScript', { scriptPath: './cypress/e2e/issue_workflow_test/DCC/test-untp-dcc-scripts.sh' }).then(
(output: any) => {
const cleanedOutput = output.replace(/\x1b\[[0-9;]*m/g, '');
cy.log('Shell Script Output:', cleanedOutput);
// Expect the output to include success message
expect(cleanedOutput).to.include('Script completed successfully!');
expect(cleanedOutput).to.include('Testing Credential: digitalConformityCredential');
expect(cleanedOutput).to.include('Result: PASS');
},
);

// Define the path to the JSON file you want to delete
const filePath = 'DigitalConformityCredential_instance-v0.5.0.json';

// Call the task to delete the file
cy.task('deleteFileCredentialE2E', filePath).then((result) => {
if (result) {
cy.log('File deleted successfully');
} else {
cy.log('File not found or could not be deleted');
}
});
});
});
44 changes: 44 additions & 0 deletions cypress/e2e/issue_workflow_test/DCC/test-untp-dcc-scripts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/bash

echo "Current working directory: $(pwd)"
# Set variables
SOURCE_FILE="cypress/e2e/issue_workflow_test/DCC/credentials.json"
DEST_FOLDER="packages/untp-test-suite"

# Verify paths
if [ ! -f "$SOURCE_FILE" ]; then
echo "Source file not found: $SOURCE_FILE"
exit 1
fi

if [ ! -d "$DEST_FOLDER" ]; then
echo "Destination folder not found: $DEST_FOLDER"
exit 1
fi

# Copy the JSON file to the new folder
cp "$SOURCE_FILE" "$DEST_FOLDER" || { echo "Failed to copy $SOURCE_FILE to $DEST_FOLDER"; exit 1; }
# Navigate to the new folder
cd "$DEST_FOLDER" || { echo "Failed to navigate to folder: $DEST_FOLDER"; exit 1; }

# Run yarn build
if ! command -v yarn &> /dev/null; then
echo "yarn is not installed. Please install it before running the script."
exit 1
fi

yarn run build || { echo "Build failed"; exit 1; }

# Run npm install globally
if ! command -v npm &> /dev/null; then
echo "npm is not installed. Please install it before running the script."
exit 1
fi

npm install -g . || { echo "Global npm install failed"; exit 1; }

# Run untp script
yarn run untp test || { echo "untp script failed"; exit 1; }

echo "Script completed successfully!"
# End of script
12 changes: 12 additions & 0 deletions cypress/e2e/issue_workflow_test/DPP/issueDPP.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,17 @@ describe('Issue DPP end-to-end testing flow', () => {
expect(cleanedOutput).to.include('Result: PASS');
},
);

// Define the path to the JSON file you want to delete
const filePath = 'DigitalProductPassport_instance-v0.5.0.json';

// Call the task to delete the file
cy.task('deleteFileCredentialE2E', filePath).then((result) => {
if (result) {
cy.log('File deleted successfully');
} else {
cy.log('File not found or could not be deleted');
}
});
});
});
Loading

0 comments on commit 9ce7bb8

Please sign in to comment.