From 4a52f28cffcedf32cca1638a1fbd370072dd9185 Mon Sep 17 00:00:00 2001 From: mildred Date: Thu, 28 Mar 2024 20:22:36 +0100 Subject: [PATCH] Adding request issuance for all types of credentials --- README.md | 38 ++-- src/constants/constants.ts | 2 + src/constants/credential_fields.ts | 2 +- src/data_stores/credentials_data_store.ts | 182 ++++++++++-------- src/page-objects/US_AddIdentityPage.ts | 88 +++++++++ src/page-objects/US_CredentialRequestPage.ts | 105 ++++++++++ src/page-objects/US_IdentitiesPage.ts | 52 +++++ src/page-objects/US_ViewCredentialPage.ts | 29 ++- src/page-objects/US_ViewMyCredentialsPage.ts | 29 ++- src/steps.ts | 115 +++++++++-- src/utils.ts | 8 +- tests/01-AD-leftmenuNavigation.spec.ts | 30 ++- tests/02-AD-manageUsers.spec.ts | 35 ---- ...COMM-EnabledAndIssueFVC_Credential.spec.ts | 85 ++++---- ...-COMM-EnabledAndIssueMC_Credential.spec.ts | 89 +++++---- tests/06-COMM-EnabledAndIssueNGO_FED.spec.ts | 86 ++++----- ...-COMM-EnabledAndIssueCC_Credential.spec.ts | 92 ++++----- ...OMM-EnabledAndIssue_EOC_Credential.spec.ts | 89 +++++---- tests/events_messages.json | 35 ---- vc_excel/federation-membership.xlsx | Bin 13831 -> 13831 bytes 20 files changed, 759 insertions(+), 432 deletions(-) create mode 100644 src/page-objects/US_AddIdentityPage.ts create mode 100644 src/page-objects/US_CredentialRequestPage.ts create mode 100644 src/page-objects/US_IdentitiesPage.ts delete mode 100644 tests/events_messages.json diff --git a/README.md b/README.md index d66d05a..ac20a0a 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,6 @@ for the final product. To get started with the IdHub testing project, you need to have the following prerequisites installed on your system: - **Node.js**: Ensure you have Node.js version 14 or later installed. You can check your version by running `node -v` in your terminal. If you need to install or update Node.js, visit the [official Node.js website](https://nodejs.org/). -- **TypeScript**: The project is written in TypeScript. You should have TypeScript version 4.0 or later. You can install it globally using npm by running `npm install -g typescript`. -- **Playwright**: Playwright is the tool used for end-to-end testing. You can install it by running `npm install playwright`. ### Installation @@ -51,10 +49,9 @@ To clone the repository and install the project dependencies, follow these steps 1. Open your terminal or command prompt. 2. Navigate to the directory where you want to clone the project. -3. Run `git clone https://github.com/idHub_testing.git` to clone the repository. +3. Run `git clone https://gitea.pangea.org/trustchain-oc1-orchestral/IdHub_E2E_testing.git` to clone the repository. 4. Navigate into the project directory using `cd idHub_testing`. -5. Install the project dependencies: -- Installing global dependencies: `npm install -g playwright` +5. Installing playwright using `npm install -g playwright` - Installing project dependencies: `npm install` - Setting up environment variables: [TODO] @@ -73,7 +70,7 @@ This command runs the test suite using Playwright, executing all tests defined i ### Writing Tests: When writing new tests, it's important to follow the established test structure. Here's a brief guide: - **Test Files**: Place your test files in the `tests` directory, following the naming convention `test-name.spec.ts`. -- **Page Objects**: Use the Page Object Model (POM) pattern for organizing your tests. Each page in your application should have a corresponding Page Object file, e.g., `COMM_loginPage.ts`, `AD_ViewUsersPage.ts`, `US_ViewMyCredentialsPage.ts` (prefix 'AD_' for a page in the admin interface, prefix 'US_' for a page in the user interface, prefix 'COMM_' for common pages). The page objects are stored in the directory `src/page-objects`. +- **Page Objects**: Use the Page Object Model (POM) pattern for organizing your tests. Each page in your application should have a corresponding Page Object file, The page objects are stored in the directory `src/page-objects`. - **Step Definitions**: Define reusable steps within the `steps.ts` This helps in maintaining the tests and promotes code reuse. The `steps.ts` is stored in the `src` directory. An example of a simple test might look like this: @@ -115,19 +112,32 @@ The 'loginAs' function in `steps.ts` use the 'LoginPage' page object, wher ## Project Directory Structure -### src directory -- **constants directory:**: Describe.... -- **data_stores directory**: Describe... -- **interfaces directory**: Describe -- **page-objects directory**: Describe -- **steps.ts**: Describe -- **utils.ts**: Describe +### src/constants directory + +The **constants.ts** file defines a collection of constants used for various purposes within a project, including file paths, JSON schema names and URLs, Excel file names for testing, schema names and types as they appear in the Idhub Admin interface, user alert messages, status types, and membership types. These constants are likely used across the project for consistent references to file paths, schema identifiers, and other configuration details, ensuring that changes to these values only need to be made in one place. + +The **credentials_fields.ts** file is designed to store and manage constant values related to the fields or properties of the diferent types of credentials defined in the pilots. + +### src/data_stores directory + +The **credential_data_store.ts** file serves as a data store for different types of credentials, each represented as an array of objects. This structure is particularly useful for testing or simulating a database of credentials without the need for a backend service. Each type of credential, such as FinancialVulnerabilityCredential_data, MembershipCard_data, FederationMembership_data, CourseCredential_data, and EOperatorClaim_data, is populated with example data. The file also includes a section for undefined credential data (CREDENTIAL_TYPE_DATASTORE_UNDEFINED), as mock data for handle cases where credential data is not available. + +The **users_data_store.ts** file contains simulated user data for testing purposes. + +### src/interfaces directory + +The **credential_interfaces.ts** file defines the interfaces that represent the structure of different types of credentials. Each interface specifies the fields that a credential object must have, along with the type of each field. + +### src/page-objects directory +Here there are the Page Objects files corresponding to each tested page in the application. e.g., `COMM_loginPage.ts`, `AD_ViewUsersPage.ts`, `US_ViewMyCredentialsPage.ts` (prefix 'AD_' for a page in the admin interface, prefix 'US_' for a page in the user interface, prefix 'COMM_' for common pages). + +### src/steps.ts file contains reusable steps within that helps to maintain the tests and promotes code reuse. ### tests directory The tests directory is where all test files are stored. These test files contain the actual tests that Playwright will execute to validate the functionality of the application. The configuration for the tests directory and other related settings are defined in the Playwright configuration file, typically named playwright.config.ts. ### vc_excel directory -describe +A set of excel data files for each type of credentials, used to test the data file import functionality to enable credentials. ## Pipeline integration diff --git a/src/constants/constants.ts b/src/constants/constants.ts index 0281e7c..f818a8e 100644 --- a/src/constants/constants.ts +++ b/src/constants/constants.ts @@ -87,6 +87,8 @@ export const ALERT_FILE_TO_IMPORT_WITH_REQUIRED_COLUMS_EMPTY_EOC = "line 3: 'leg export const ALERT_USER_CREATED_SUCESSFULLY_MESSAGE = 'The account was created successfully' export const ERROR_INCORRECT_EMAIL_PASSWORD = 'Please enter a correct Email address and password. Note that both fields may be case-sensitive.' +export const ENABLED_ST = "Enabled" +export const ISSUED_ST = "Issued" //Memberships export const MEMBERSHIP_TYPES = [ diff --git a/src/constants/credential_fields.ts b/src/constants/credential_fields.ts index 55fcf7c..17ad725 100644 --- a/src/constants/credential_fields.ts +++ b/src/constants/credential_fields.ts @@ -13,7 +13,7 @@ export const CREDENTIAL_TYPES_FIELDS_LIST = { 'financialVulnerabilityScore', 'amountCoveredByOtherAids', 'connectivityOptionList', - 'assessmentDate' + 'assessmentDate', ] as string[], "MembershipCard": [ diff --git a/src/data_stores/credentials_data_store.ts b/src/data_stores/credentials_data_store.ts index 20a3ddd..00c5b6c 100644 --- a/src/data_stores/credentials_data_store.ts +++ b/src/data_stores/credentials_data_store.ts @@ -22,13 +22,12 @@ CREDENTIAL_TYPES_DATA_STORE.FinancialVulnerabilityCredential_data = [{ financialVulnerabilityScore: '4', amountCoveredByOtherAids: '0', connectivityOptionList: 'Fibra', - assessmentDate: '2024-01-01' + assessmentDate: '2024-01-01', }, { firstName: 'Ludwing Van', lastName: 'Beethoven', email: 'user2@example.org', - phoneNumber: 'undefined', identityDocType: 'DNI', identityNumber: '76677667Q', streetAddress: 'C/ Fontanals', @@ -36,8 +35,7 @@ CREDENTIAL_TYPES_DATA_STORE.FinancialVulnerabilityCredential_data = [{ socialWorkerSurname: 'Ruíz', financialVulnerabilityScore: '6', amountCoveredByOtherAids: '30', - connectivityOptionList: 'undefined', - assessmentDate: '2024-01-03' + assessmentDate: '2024-01-03', }, { firstName: 'Franz', @@ -52,7 +50,7 @@ CREDENTIAL_TYPES_DATA_STORE.FinancialVulnerabilityCredential_data = [{ financialVulnerabilityScore: '8', amountCoveredByOtherAids: '10', connectivityOptionList: 'Fibra', - assessmentDate: '2023-10-04' + assessmentDate: '2023-10-04', }, { firstName: 'Barbara', @@ -67,7 +65,7 @@ CREDENTIAL_TYPES_DATA_STORE.FinancialVulnerabilityCredential_data = [{ financialVulnerabilityScore: '9', amountCoveredByOtherAids: '0', connectivityOptionList: 'Fibra', - assessmentDate: '2024-01-04' + assessmentDate: '2024-01-04', } ]; @@ -86,7 +84,7 @@ CREDENTIAL_TYPES_DATA_STORE.MembershipCard_data = [ firstName: "Wolfgang Amadeus", lastName: "Mozart", role: "Conductor", - email: "user1@example.org" + email: "user1@example.org", }, { organisation: "Pangea", @@ -99,7 +97,7 @@ CREDENTIAL_TYPES_DATA_STORE.MembershipCard_data = [ firstName: "Ludwing Van", lastName: "Beethoven", role: "Composer", - email: "user2@example.org" + email: "user2@example.org", }, { organisation: "Pangea", @@ -113,7 +111,7 @@ CREDENTIAL_TYPES_DATA_STORE.MembershipCard_data = [ firstName: "Franz", lastName: "Schubert", role: "Chamber musician", - email: "user3@example.org" + email: "user3@example.org", }, { organisation: "Pangea", @@ -127,7 +125,7 @@ CREDENTIAL_TYPES_DATA_STORE.MembershipCard_data = [ firstName: "Barbara", lastName: "Strozzi", role: "Composer and Singer", - email: "user4@example.org" + email: "user4@example.org", }, { organisation: "Pangea", @@ -141,7 +139,7 @@ CREDENTIAL_TYPES_DATA_STORE.MembershipCard_data = [ firstName: "Clara", lastName: "Schumann", role: "Composer and Pianist", - email: "user5@example.org" + email: "user5@example.org", } ]; @@ -238,7 +236,7 @@ CREDENTIAL_TYPES_DATA_STORE.CourseCredential_data = [ courseFramework: "European Qualifications Framework (EQF) Level 6", courseCredits: "5", dateOfAssessment: "2020-12-20", - evidenceAssessment: "final exam" + evidenceAssessment: "final exam", }, { firstName: "Ludwing Van", @@ -257,7 +255,7 @@ CREDENTIAL_TYPES_DATA_STORE.CourseCredential_data = [ courseLevel: "Undergraduate", courseCredits: "7", dateOfAssessment: "2020-12-20", - evidenceAssessment: "presence" + evidenceAssessment: "presence", }, { firstName: "Barbara", @@ -276,7 +274,7 @@ CREDENTIAL_TYPES_DATA_STORE.CourseCredential_data = [ courseFramework: "Classical music", courseCredits: "10", dateOfAssessment: "2020-12-20", - evidenceAssessment: "presence" + evidenceAssessment: "presence", } ]; @@ -317,90 +315,104 @@ export const CREDENTIAL_TYPE_DATASTORE_UNDEFINED = { CourseCredential_data_undefined: {} as Record, EOperatorClaim_data_undefined: {} as Record - //TODO añadir otros tipos de credenciales } CREDENTIAL_TYPE_DATASTORE_UNDEFINED.FinancialVulnerabilityCredential_data_undefined = { - firstName: 'undefined_data', - lastName: 'undefined_data', - email: 'undefined_data', - phoneNumber: 'undefined_data', - identityDocType: 'undefined_data', - identityNumber: 'undefined_data', - streetAddress: 'undefined_data', - socialWorkerName: 'undefined_data', - socialWorkerSurname: 'undefined_data', - financialVulnerabilityScore: 'undefined_data', - amountCoveredByOtherAids: 'undefined_data', - connectivityOptionList: 'undefined_data', - assessmentDate: 'undefined_data' + credentialSubject: { + firstName: 'undefined_data', + lastName: 'undefined_data', + email: 'undefined_data', + phoneNumber: 'undefined_data', + identityDocType: 'undefined_data', + identityNumber: 'undefined_data', + streetAddress: 'undefined_data', + socialWorkerName: 'undefined_data', + socialWorkerSurname: 'undefined_data', + financialVulnerabilityScore: 'undefined_data', + amountCoveredByOtherAids: 'undefined_data', + connectivityOptionList: 'undefined_data', + assessmentDate: 'undefined_data' + }, + status: 'undefined_data' } CREDENTIAL_TYPE_DATASTORE_UNDEFINED.MembershipCard_data_undefined = { - organisation: 'undefined_data', - membershipType: 'undefined_data', - membershipId: 'undefined_data', - affiliatedSince: 'undefined_data', - affiliatedUntil: 'undefined_data', - typeOfPerson: 'undefined_data', - identityDocType: 'undefined_data', - identityNumber: 'undefined_data', - firstName: 'undefined_data', - lastName: 'undefined_data', - role: 'undefined_data', - email: 'undefined_data' + credentialSubject: { + organisation: 'undefined_data', + membershipType: 'undefined_data', + membershipId: 'undefined_data', + affiliatedSince: 'undefined_data', + affiliatedUntil: 'undefined_data', + typeOfPerson: 'undefined_data', + identityDocType: 'undefined_data', + identityNumber: 'undefined_data', + firstName: 'undefined_data', + lastName: 'undefined_data', + role: 'undefined_data', + email: 'undefined_data', + }, + status: 'undefined_data' } + CREDENTIAL_TYPE_DATASTORE_UNDEFINED.FederationMembership_data_undefined = { - federation: 'undefined_data', - legalName: 'undefined_data', - shortName: 'undefined_data', - registrationIdentifier: 'undefined_data', - publicRegistry: 'undefined_data', - streetAddress: 'undefined_data', - postCode: 'undefined_data', - city: 'undefined_data', - taxReference: 'undefined_data', - membershipType: 'undefined_data', - membershipStatus: 'undefined_data', - membershipId: 'undefined_data', - membershipSince: 'undefined_data', - email: 'undefined_data', - phone: 'undefined_data', - website: 'undefined_data', - evidence: 'undefined_data', - certificationDate: 'undefined_data' + credentialSubject: { + federation: 'undefined_data', + legalName: 'undefined_data', + shortName: 'undefined_data', + registrationIdentifier: 'undefined_data', + publicRegistry: 'undefined_data', + streetAddress: 'undefined_data', + postCode: 'undefined_data', + city: 'undefined_data', + taxReference: 'undefined_data', + membershipType: 'undefined_data', + membershipStatus: 'undefined_data', + membershipId: 'undefined_data', + membershipSince: 'undefined_data', + email: 'undefined_data', + phone: 'undefined_data', + website: 'undefined_data', + evidence: 'undefined_data', + certificationDate: 'undefined_data', + }, + status: 'undefined_data' } CREDENTIAL_TYPE_DATASTORE_UNDEFINED.CourseCredential_data_undefined = { - firstName: 'undefined_data', - lastName: 'undefined_data', - email: 'undefined_data', - personalIdentifier: 'undefined_data', - issuedDate: 'undefined_data', - modeOfInstruction: 'undefined_data', - courseDuration: 'undefined_data', - courseDays: 'undefined_data', - courseName: 'undefined_data', - courseDescription: 'undefined_data', - gradingScheme: 'undefined_data', - scoreAwarded: 'undefined_data', - qualificationAwarded: 'undefined_data', - courseLevel: 'undefined_data', - courseFramework: 'undefined_data', - courseCredits: 'undefined_data', - dateOfAssessment: 'undefined_data', - evidenceAssessment: 'undefined_data', + credentialSubject: { + firstName: 'undefined_data', + lastName: 'undefined_data', + email: 'undefined_data', + personalIdentifier: 'undefined_data', + issuedDate: 'undefined_data', + modeOfInstruction: 'undefined_data', + courseDuration: 'undefined_data', + courseDays: 'undefined_data', + courseName: 'undefined_data', + courseDescription: 'undefined_data', + gradingScheme: 'undefined_data', + scoreAwarded: 'undefined_data', + qualificationAwarded: 'undefined_data', + courseLevel: 'undefined_data', + courseFramework: 'undefined_data', + courseCredits: 'undefined_data', + dateOfAssessment: 'undefined_data', + evidenceAssessment: 'undefined_data', + }, + status: 'undefined_data' } CREDENTIAL_TYPE_DATASTORE_UNDEFINED.EOperatorClaim_data_undefined = { - legalName: 'undefined_data', - role: 'undefined_data', - email: 'undefined_data', - accreditedBy: 'undefined_data', - operatorNumber: 'undefined_data', - limitJurisdiction: 'undefined_data', - accreditedFor: 'undefined_data' -} - + credentialSubject: { + legalName: 'undefined_data', + role: 'undefined_data', + email: 'undefined_data', + accreditedBy: 'undefined_data', + operatorNumber: 'undefined_data', + limitJurisdiction: 'undefined_data', + accreditedFor: 'undefined_data', + }, + status: 'undefined_data' +} \ No newline at end of file diff --git a/src/page-objects/US_AddIdentityPage.ts b/src/page-objects/US_AddIdentityPage.ts new file mode 100644 index 0000000..53308bf --- /dev/null +++ b/src/page-objects/US_AddIdentityPage.ts @@ -0,0 +1,88 @@ +import { Page, Locator, expect } from "@playwright/test" + +export class AddIdentityPage { + readonly page: Page + readonly primaryTitle: Locator + readonly secondaryTitle: Locator + readonly label: Locator + readonly dropdownType: Locator + readonly saveButton: Locator + readonly cancelButton: Locator + + public constructor(page: Page) { + this.page = page; + this.primaryTitle = this.page.getByRole('heading', { name: 'My wallet' }) + this.secondaryTitle = this.page.getByRole('heading', { name: ' Add a new Identity (DID)' }) + this.label = this.page.getByPlaceholder('Label') + this.dropdownType = this.page.getByLabel('Type') + this.saveButton = this.page.getByRole('button', { name: 'Save' }) + this.cancelButton = this.page.getByRole('link', { name: 'Cancel' }) + + } + + async getPrimaryTitle() { + try { + return await this.primaryTitle.innerText(); + } catch (error) { + console.error("Failed to get primary title:", error); + throw error; + } + } + + async getSecondaryTitle() { + try { + return await this.secondaryTitle.innerText(); + } catch (error) { + console.error("Failed to get secondary title:", error); + throw error; + } + } + + async getDropdownType() { + try { + return this.dropdownType; + } catch (error) { + console.error("Failed to get dropdown DID Type value:", error); + throw error; + } + } + + async getLabel() { + try { + return this.label; + } catch (error) { + console.error("Failed to get Label value:", error); + throw error; + } + } + + + async getSaveButton() { + try { + return this.saveButton; + } catch (error) { + console.error("Failed to get the 'Save' button:", error); + throw error; + } + } + + async getCancelButton() { + try { + return this.cancelButton; + } catch (error) { + console.error("Failed to get the 'Cancel' button:", error); + throw error; + } + } + async addDid(label: string, didType: string) { + try { + (await this.getLabel()).fill(label); + (await this.getDropdownType()).selectOption({ label: didType }); + (await this.getSaveButton()).click(); + } catch (error) { + console.error("Failed adding new did: ", error); + throw error; + } + } + +} \ No newline at end of file diff --git a/src/page-objects/US_CredentialRequestPage.ts b/src/page-objects/US_CredentialRequestPage.ts new file mode 100644 index 0000000..4616837 --- /dev/null +++ b/src/page-objects/US_CredentialRequestPage.ts @@ -0,0 +1,105 @@ +import { Page, Locator, expect } from "@playwright/test" + +export class CredentialRequestPage { + readonly page: Page + readonly primaryTitle: Locator + readonly secondaryTitle: Locator + readonly drowdownDid: Locator + readonly dropdownCredential: Locator + readonly requestButton: Locator + readonly cancelButton: Locator + + public constructor(page: Page) { + this.page = page; + this.primaryTitle = this.page.getByRole('heading', { name: 'My wallet' }) + this.secondaryTitle = this.page.getByRole('heading', { name: ' Credential Request' }) + this.drowdownDid = this.page.getByLabel('Did') + this.dropdownCredential = this.page.getByLabel('Credential') + this.requestButton = this.page.getByRole('button', { name: 'Request' }) + this.cancelButton = this.page.getByRole('link', { name: 'Cancel' }) + + } + + async getPrimaryTitle() { + try { + return await this.primaryTitle.innerText(); + } catch (error) { + console.error("Failed to get primary title:", error); + throw error; + } + } + + async getSecondaryTitle() { + try { + return await this.secondaryTitle.innerText(); + } catch (error) { + console.error("Failed to get secondary title:", error); + throw error; + } + } + + async getDropdownDid() { + try { + return this.drowdownDid; + } catch (error) { + console.error("Failed to get dropdown DID value:", error); + throw error; + } + } + async getDropdownCredential() { + try { + return this.dropdownCredential; + } catch (error) { + console.error("Failed to get dropdown Credential value:", error); + throw error; + } + } + + async getRequestButton() { + try { + return this.requestButton; + } catch (error) { + console.error("Failed to get the 'Request' button:", error); + throw error; + } + } + + async getCancelButton() { + try { + return this.cancelButton; + } catch (error) { + console.error("Failed to get the 'Cancel' button:", error); + throw error; + } + } + async clickRequestButton() { + try { + (await this.getRequestButton()).click(); + } catch (error) { + console.error("Failed to click request button: ", error); + throw error; + } + } + + async clickCancelButton() { + try { + (await this.getCancelButton()).click(); + } catch (error) { + console.error("Failed to click cancel did: ", error); + throw error; + } + } + + async requestCredential(did: string, credential: string) { + try { + console.log("DId", did); + (await this.getDropdownDid()).selectOption({ label: did }); + (await this.getDropdownCredential()).selectOption({ label: credential }); + (await this.clickRequestButton()); + } catch (error) { + console.error("Failed to request a credential: ", error); + throw error; + } + } + +} \ No newline at end of file diff --git a/src/page-objects/US_IdentitiesPage.ts b/src/page-objects/US_IdentitiesPage.ts new file mode 100644 index 0000000..d2d037e --- /dev/null +++ b/src/page-objects/US_IdentitiesPage.ts @@ -0,0 +1,52 @@ +import { Page, Locator } from "@playwright/test" + +export class IdentitiesPage { + + readonly page: Page + readonly primaryTitle: Locator + readonly secondaryTitle: Locator + readonly addIdentityButton: Locator + + constructor(page: Page) { + this.page = page; + this.primaryTitle = page.getByRole('heading', { name: 'My wallet' }); + this.secondaryTitle = page.getByRole('heading', { name: ' Identities (DIDs)' }); + this.addIdentityButton = page.getByRole('link', { name: 'Add Identity ' }); + } + async getPrimaryTitle() { + try { + return await this.primaryTitle.innerText(); + } catch (error) { + console.error("Failed to get primary title:", error); + throw error; + } + } + + async getSecondaryTitle() { + try { + return await this.secondaryTitle.innerText(); + } catch (error) { + console.error("Failed to get primary title:", error); + throw error; + } + } + + async getAddIdentityButton() { + try { + return this.addIdentityButton; + } catch (error) { + console.error("Failed to get Add Identity button:", error); + throw error; + } + } + + async clickAddIdentityButton() { + try { + return (await this.getAddIdentityButton()).click(); + } catch (error) { + console.error("Failed to get click credential button:", error); + throw error; + } + } + +} diff --git a/src/page-objects/US_ViewCredentialPage.ts b/src/page-objects/US_ViewCredentialPage.ts index 168624f..6c371a6 100644 --- a/src/page-objects/US_ViewCredentialPage.ts +++ b/src/page-objects/US_ViewCredentialPage.ts @@ -6,11 +6,13 @@ export class ViewCredentialPage { readonly page: Page readonly primaryTitle: Locator readonly secondaryTitle: Locator + readonly requestCredentialButton: Locator constructor(page: Page) { this.page = page; this.primaryTitle = page.getByRole('heading', { name: 'My wallet' }); - this.secondaryTitle = page.getByRole('heading', { name: ' Credential' }); + this.requestCredentialButton = page.getByRole('link', { name: 'Request credential' }); + } async getPrimaryTitle() { try { @@ -21,20 +23,32 @@ export class ViewCredentialPage { } } - async getSecondaryTitle() { + async getRequestCredentialButton() { try { - return await this.secondaryTitle.innerText(); + return this.requestCredentialButton; } catch (error) { - console.error("Failed to get secondary title:", error); + console.error("Failed to get request credential button:", error); throw error; } } + async clickRequestCredentialButton() { + try { + return (await this.getRequestCredentialButton()).click(); + } catch (error) { + console.error("Failed to get click credential button:", error); + throw error; + } + } + + async buildACredentialFromInputValues(credentialType: string) { try { const elementsWithLabel = await this.page.locator('.col-3 strong').all(); const elementsWithValue = await this.page.locator('.col.bg-light.text-secondary').all(); + + let credential = initialize_with_undefined_values(credentialType); let labels: string[] = []; @@ -48,17 +62,20 @@ export class ViewCredentialPage { if (value != null && label != null && label != 'Id' && label != "Issuance date" && label != "Status") { labels.push(label); values.push(value); + } else { + if (label === "Status"){ + credential.status = value; + } } } - credential = setCredentialValues(labels, values, credentialType); + credential.credentialSubject = setCredentialValues(labels, values, credentialType); return credential; } catch (error) { console.error("Failed to build the credential from input values:", error); throw error; } - }//end function diff --git a/src/page-objects/US_ViewMyCredentialsPage.ts b/src/page-objects/US_ViewMyCredentialsPage.ts index fbd049e..69aefc7 100644 --- a/src/page-objects/US_ViewMyCredentialsPage.ts +++ b/src/page-objects/US_ViewMyCredentialsPage.ts @@ -1,4 +1,5 @@ import { Page, Locator } from "@playwright/test" +import { ISSUED_ST } from "../constants/constants" export class ViewMyCredentialsPage { @@ -87,9 +88,7 @@ export class ViewMyCredentialsPage { (await this.getIssuedOnTitle()).click(); } - async gotoViewEnabledCredentialPage(type: string) { - - let status = 'Enabled'; + async gotoViewCredentialPage(type: string, status: string) { // Locator for all rows const rowLocator = this.page.locator('tr'); @@ -97,23 +96,19 @@ export class ViewMyCredentialsPage { const typeFilteredRows = rowLocator.filter({ hasText: type }); // Rows with the fourth column having the specified status - const statusFilteredRows = typeFilteredRows.filter({ hasText: status }); - - // only the rows matching both criteria - // Check if the row exists - if (await statusFilteredRows.count() > 0) { - // Click to view the credential - await statusFilteredRows.first().locator('i.bi.bi-eye').click(); - } else { - console.log(`No row found with type '${type}' and status '${status}'.`); + //const statusFilteredRows = typeFilteredRows.filter({ hasText: status }); + // Manually filter rows based on the fourth column's text content + let statusFilteredRows = []; + for (const row of await typeFilteredRows.all()) { + const fourthColumnText = await row.locator('td:nth-child(4)').textContent(); + if (fourthColumnText === status) { + await row.locator('i.bi.bi-eye').click(); + break; + } } - } - async enabledCredentialExistInMyCredentials(type: string): Promise { - - let status = 'Enabled'; - + async credentialExistInMyCredentials(type: string, status: string): Promise { // Locator for all rows const rowLocator = this.page.locator('tr'); diff --git a/src/steps.ts b/src/steps.ts index 774da39..a0ad1a3 100644 --- a/src/steps.ts +++ b/src/steps.ts @@ -1,9 +1,9 @@ import { expect, Page } from '@playwright/test' -import { appendRandomNumberToFilename, copyFile, deleteFile } from './utils' +import { appendRandomNumberToInput, copyFile, deleteFile } from './utils' import { CREDENTIAL_TYPE_DATASTORE_UNDEFINED, CREDENTIAL_TYPES_DATA_STORE } from './data_stores/credentials_data_store' -import { CREDENTIAL_TYPES_FIELDS_LIST} from './constants/credential_fields' +import { CREDENTIAL_TYPES_FIELDS_LIST } from './constants/credential_fields' import { LogInPage } from './page-objects/COMM_LoginPage' import { ADMIN_EMAIL, ADMIN_K, ENCRYPTION_KEY, USER_K } from './constants/env_constants' import { LeftMenuAdminPage } from './page-objects/AD_LeftMenuAdminPage' @@ -18,8 +18,12 @@ import { User } from './interfaces/User' import { EncryptionKeyPage } from './page-objects/AD_EncryptionKeyPage' import { DataProtectionPage } from './page-objects/COMM_DataProtectionPage' import { ImportDataPage } from './page-objects/AD_ImportDataPage' -import { PATH_FILES_TO_IMPORT } from './constants/constants' +import { ENABLED_ST, ISSUED_ST, PATH_FILES_TO_IMPORT } from './constants/constants' import { fail } from 'assert' +import { ViewCredentialPage } from './page-objects/US_ViewCredentialPage' +import { AddIdentityPage } from './page-objects/US_AddIdentityPage' +import { IdentitiesPage } from './page-objects/US_IdentitiesPage' +import { CredentialRequestPage } from './page-objects/US_CredentialRequestPage' export async function loginAsAdmin(page: Page, url: string) { @@ -37,7 +41,7 @@ export async function loginAsAdmin(page: Page, url: string) { //code to set Encription Key await encryptionKeyPage.enterKey(ENCRYPTION_KEY); await encryptionKeyPage.clickSaveButton(); - + await expect(page).toHaveTitle('Data protection – IdHub'); currentTitle = await page.title(); } @@ -141,6 +145,18 @@ export async function clickMyCredentialsOnLeftMenu(page: Page) { } } +export async function clickIdentitiesOnLeftMenu(page: Page) { + try { + const leftMenuPage = new LeftMenuUserPage(page); + const identitiesLink = await leftMenuPage.getIdentitiesLink(); + await identitiesLink.click() + return { identitiesLink } + } catch (error) { + console.error(`Failed to access Identities option on left menu: `); + throw error; + } +} + export async function clickManageRolesOnLeftMenu(page: Page) { try { const leftMenuPage = new LeftMenuAdminPage(page); @@ -213,6 +229,18 @@ export async function clickViewCredentialsOnLeftMenu(page: Page) { } } +export async function clickViewOrganizationWalletOnLeftMenu(page: Page) { + try { + const leftMenuPage = new LeftMenuAdminPage(page); + const viewOrganisationalWalletLink = await leftMenuPage.getOrganisationalWalletLink(); + await viewOrganisationalWalletLink.click() + return { viewOrganisationalWalletLink } + } catch (error) { + console.error(`Failed to access Organisational wallet on left menu: `); + throw error; + } +} + export async function clickViewSchemaOnLeftMenu(page: Page, templateName: string) { try { const templatesPage = new TemplatesPage(page) @@ -240,19 +268,20 @@ export async function gotoBasicInfoPageOfTheUser(page: Page, user: User) { await viewUsersPage.gotoUserInformationPage(user) } -export async function gotoViewEnabledCredential(page: Page, credentialType: string) { +export async function gotoViewCredential(page: Page, credentialType: string, status: string) { const myCredentialsPage = new ViewMyCredentialsPage(page) //Access the specific enabled credential that is expected to be in the user wallet! const { myCredentialsLink } = await clickMyCredentialsOnLeftMenu(page); try { - expect(await myCredentialsPage.enabledCredentialExistInMyCredentials(credentialType)).toBeTruthy(); + expect(await myCredentialsPage.credentialExistInMyCredentials(credentialType, status)).toBeTruthy(); } catch (error) { console.error('Failed accessing the enabled credential of type ${credentialType}', error); } - await myCredentialsPage.gotoViewEnabledCredentialPage(credentialType); + await myCredentialsPage.gotoViewCredentialPage(credentialType, status); } + export async function checkIfTheInformationIsValid(page: Page, user: User) { const userPersonalInformationPage = new UserPersonalInformationPage(page) @@ -264,9 +293,8 @@ export async function checkIfTheInformationIsValid(page: Page, user: User) { } -export function expectedCredentialSubjectForUser(email: string, credentialType: string){ +export function expectedCredentialSubjectForUser(email: string, credentialType: string) { -//export function expectedCredentialSubjectForUser(email: string, credentialType: string): FinancialVulnerabilityCredential_fields | MembershipCard_fields | NGOFederationMembership_fields | undefined { try { const testingDataForCredential = CREDENTIAL_TYPES_DATA_STORE[credentialType + '_data']; @@ -300,7 +328,7 @@ export async function checkFileName(page: Page, fileName: string): Promise { } } -export function appendRandomNumberToFilename(filename: string) { +export function appendRandomNumberToInput(input: string) { // Generate a random number between 100 and 999 const randomNumber = Math.floor(Math.random() * (999 - 100 + 1)) + 100; // Extract the extension from the filename - const extensionIndex = filename.lastIndexOf('.'); - const extension = extensionIndex !== -1 ? filename.slice(extensionIndex) : ''; + const extensionIndex = input.lastIndexOf('.'); + const extension = extensionIndex !== -1 ? input.slice(extensionIndex) : ''; // Remove the extension from the original filename - const basename = extensionIndex !== -1 ? filename.slice(0, extensionIndex) : filename; + const basename = extensionIndex !== -1 ? input.slice(0, extensionIndex) : input; // Append the random number and the extension to form the new filename return `${basename}${randomNumber}${extension}`; diff --git a/tests/01-AD-leftmenuNavigation.spec.ts b/tests/01-AD-leftmenuNavigation.spec.ts index 8acb557..15e5aa6 100644 --- a/tests/01-AD-leftmenuNavigation.spec.ts +++ b/tests/01-AD-leftmenuNavigation.spec.ts @@ -4,7 +4,7 @@ import { ViewUsersPage } from '../src/page-objects/AD_ViewUsersPage'; import { BasicUserInfoSectionPage } from '../src/page-objects/AD_BasicUserInfoSectionInPage'; import { ViewRolesPage } from '../src/page-objects/AD_ViewRolesPage'; import { ViewServicesPage } from '../src/page-objects/AD_ViewServicesPage'; -import { clickAddUserOnLeftMenu, clickDashboardOnLeftMenu, clickManageRolesOnLeftMenu, clickManageServicesOnLeftMenu, clickViewUsersOnLeftMenu, loginAsAdmin } from '../src/steps'; +import { clickAddUserOnLeftMenu, clickDashboardOnLeftMenu, clickManageRolesOnLeftMenu, clickManageServicesOnLeftMenu, clickViewCredentialsOnLeftMenu, clickViewOrganizationWalletOnLeftMenu, clickViewUsersOnLeftMenu, loginAsAdmin } from '../src/steps'; import { URL_IDHUB } from '../src/constants/env_constants'; /** @@ -43,7 +43,7 @@ test.describe('Leftside Menu navigation test', () => { }) test('LEFTMENU -> Roles and Services', async ({ page }) => { - + //Navigate to "Roles" const leftMenu = new LeftMenuAdminPage(page); (await leftMenu.getRolesLink()).click(); @@ -51,7 +51,7 @@ test.describe('Leftside Menu navigation test', () => { //Navigate to "Manage roles" await clickManageRolesOnLeftMenu(page); await expect(page).toHaveTitle('Access control management – IdHub'); - + //Check titles const viewRolesPage = new ViewRolesPage(page); expect(await viewRolesPage.getPrimaryTitle()).toEqual("Access control management"); @@ -70,13 +70,31 @@ test.describe('Leftside Menu navigation test', () => { //TODO: credentials, templates.... - test.skip('LEFTMENU -> Credentials', async ({ page }) => { + test('LEFTMENU -> Credentials', async ({ page }) => { + const leftMenu = new LeftMenuAdminPage(page); + (await leftMenu.getCredentialsLink()).click(); + + //Navigate to "View Credentials" + await clickViewCredentialsOnLeftMenu(page); + await expect(page).toHaveTitle('Credential management – IdHub'); + + //Navigate to "Organization's wallet" + await clickViewOrganizationWalletOnLeftMenu(page); + }) - test.skip('LEFTMENU -> Templates', async ({ page }) => { + test('LEFTMENU -> Templates', async ({ page }) => { + //Navigate to "Templates" + const leftMenu = new LeftMenuAdminPage(page); + (await leftMenu.getTemplatesLink()).click(); + await expect(page).toHaveTitle('Template management – IdHub'); }) - test.skip('LEFTMENU -> Data', async ({ page }) => { + test('LEFTMENU -> Data', async ({ page }) => { + //Navigate to "Data" + const leftMenu = new LeftMenuAdminPage(page); + (await leftMenu.getDataLink()).click(); + await expect(page).toHaveTitle('Data file management – IdHub'); }) }) \ No newline at end of file diff --git a/tests/02-AD-manageUsers.spec.ts b/tests/02-AD-manageUsers.spec.ts index e5a7143..09785eb 100644 --- a/tests/02-AD-manageUsers.spec.ts +++ b/tests/02-AD-manageUsers.spec.ts @@ -81,41 +81,6 @@ test.describe('USER Section Tests', () => { await basicInfoPage.updateUserBasicInfo(user.firstName, user.lastName, user.email, true); }); - - /** - * Create a list of random users - * ADD the USER (basic info) to the idhub - * Validate infomation after addition - */ - - test.skip('USERS -> Add user: Add random users with basic data', async ({ page }) => { - - const randomUsers = createUsersRandomList(6) - - // Initialize pages - const basicInfoPage = new BasicUserInfoSectionPage(page); - const membershipPage = new AddMembershipPage(page); - - // Navigate to the Add User page - const { addUserLink } = await clickAddUserOnLeftMenu(page); - - // Add the list of users - for (let user of randomUsers) { - await basicInfoPage.addUserBasicInfo(user.firstName, user.lastName, user.email, false); - expect(await membershipPage.alertUserCreationMessageIsValid()).toBeTruthy(); - await membershipPage.addUserMembership(user.membershipType, user.startDate, user.endDate); - await addUserLink.click(); - } - - // Check if the users are visible in 'View users' panel - const viewUsersPage = new ViewUsersPage(page); - const { viewUsersLink } = await clickViewUsersOnLeftMenu(page); - for (let user of randomUsers) { - expect(await viewUsersPage.userExists(user.email)).toBeTruthy(); - await viewUsersLink.click(); - } - - }); /** * ADD a user (basic information) and validate it after addition diff --git a/tests/04-COMM-EnabledAndIssueFVC_Credential.spec.ts b/tests/04-COMM-EnabledAndIssueFVC_Credential.spec.ts index f96c873..d6e7cde 100644 --- a/tests/04-COMM-EnabledAndIssueFVC_Credential.spec.ts +++ b/tests/04-COMM-EnabledAndIssueFVC_Credential.spec.ts @@ -1,14 +1,13 @@ -import { test, expect} from '@playwright/test' -import { loginAsAdmin, loginAsUser, gotoViewEnabledCredential, expectedCredentialSubjectForUser, testImportDataFile_SadPath, testImportDataFile_HappyPath } from '../src/steps'; -import { ViewCredentialPage } from '../src/page-objects/US_ViewCredentialPage.js' -import { URL_IDHUB, USER1_EMAIL } from '../src/constants/env_constants'; +import { test } from '@playwright/test'; +import { loginAsAdmin, loginAsUser, testImportDataFile_SadPath, testImportDataFile_HappyPath, test_ViewAndCheckEnabledCredentialbyUser, test_RequestAndCheckIssuedCredentialByUser } from '../src/steps'; +import { URL_IDHUB, USER1_EMAIL, USER2_EMAIL, USER3_EMAIL } from '../src/constants/env_constants'; import { ALERT_FILE_TO_IMPORT_IS_EMPTY, ALERT_FILE_TO_IMPORT_WITHOUT_REQUIRED_COLUMS, ALERT_FILE_TO_IMPORT_WITH_ALIEN_COLUMS, ALERT_FILE_TO_IMPORT_WITH_REQUIRED_COLUMS_EMPTY, FILE_TO_IMPORT_FVC, FILE_TO_IMPORT_FVC_EMPTY, FILE_TO_IMPORT_FVC_WITHOUT_REQUIRED_COLUMNS, FILE_TO_IMPORT_FVC_WITH_ALIEN_COLUMNS, FILE_TO_IMPORT_FVC_WITH_REQUIRED_EMPTY, JSON_SCHEMA_FVC, SCHEMA_FVC, SCHEMA_TYPE_FVC } from '../src/constants/constants'; /** -* Checking Admin Data Section: view the lists of files imported, import data, ... +* Testing Admin->Data Section functionality with the Financial Vulnerability Credential (FVC) */ -test.describe('ADMIN-> DATA Section Tests - Testing with Financial Vulnerability Credential', () => { +test.describe('ADMIN-> DATA -> Import FVC excel files', () => { test.beforeEach(async ({ page }) => { await loginAsAdmin(page, URL_IDHUB); @@ -20,11 +19,12 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Financial Vulnerability }) /** * Load an excel file - Happy Path - * Expected behavior: the file is loaded, the message:"The file was imported successfully!" is displayed, - * and the file appears in the imported files view. + * Expected behavior: + * - the file is loaded, the message: "The file was imported successfully!" is displayed. + * - the file appears in the imported files view. */ - test('DATA -> Import data file - Happy path - Financial Vulnerability Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import FVC excel file - Happy Path', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_FVC; const jsonSchema = JSON_SCHEMA_FVC; @@ -34,13 +34,13 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Financial Vulnerability }); - /** - * Load an excel file - Sad Path: - * Try to load a well-formatted excel file but without data. - * Expected behavior: The error message: "The file you try to import is empty" - */ + /** + * Load an excel file - Sad Path: + * Try to load a well-formatted excel file but without data. + * Expected behavior: The error message: "The file you try to import is empty" + */ - test('DATA -> Import data file - Sad path (file well formatted but empty) - Financial Vulnerability Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import FVC excel file - Sad path (file well formatted but empty)', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_FVC_EMPTY; const jsonSchema = JSON_SCHEMA_FVC; @@ -56,8 +56,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Financial Vulnerability * Try to load a bad formatted file, without required data. */ - test('DATA -> Import data file - Sad path (bad formatted file, without required columns) - Financial Vulnerability Credential ', async ({ page }) => { - + test('ADMIN-> DATA -> Import FVC excel file - Sad path (bad formatted file, without required columns)', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_FVC_WITHOUT_REQUIRED_COLUMNS; const jsonSchema = JSON_SCHEMA_FVC; const schema = SCHEMA_FVC; @@ -73,7 +72,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Financial Vulnerability * Expected behavior: The error message: "line 2: Additional properties are not allowed ('alien1', 'alien2' were unexpected)" */ - test('DATA -> Import data file - Sad path (bad formatted file, with alien columns) - Financial Vulnerability Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import FVC excel file - Sad path (bad formatted file, with alien columns)', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_FVC_WITH_ALIEN_COLUMNS; const jsonSchema = JSON_SCHEMA_FVC; const schema = SCHEMA_FVC; @@ -89,7 +88,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Financial Vulnerability * Expected behavior: The error message: "line 3: 'firstName' is a required property" */ - test('DATA -> Import data file - Sad path (file with required columns present but empty) - Financial Vulnerability Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import FVC excel file - Sad path (file with required columns present but empty)', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_FVC_WITH_REQUIRED_EMPTY; const jsonSchema = JSON_SCHEMA_FVC; @@ -102,11 +101,8 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Financial Vulnerability }) //end describe -test.describe('USER -> Credentials Section Tests - testing with USER1_EMAIL AND FINANCIAL VULNERABILITY CRED', () => { +test.describe('USER -> My Credentials - enable and issue credentials', () => { - test.beforeEach(async ({ page }) => { - await loginAsUser(page, USER1_EMAIL, URL_IDHUB); - }) test.afterEach(async ({ page }) => { await page.click('.logout'); await page.close(); @@ -114,24 +110,39 @@ test.describe('USER -> Credentials Section Tests - testing with USER1_EMAIL AND }) /** - * PRE-CONDITIONS: the admin has enabled a credential of type 'Financial Vulnerabitity' for USER1_EMAIL - * This is true, if the before test (DATA -> Import data- HAPPY PATH has been passed sucessfully) + * PRE-CONDITIONS: the admin has enabled sucessfully a credential in the previous test (DATA -> Import data- HAPPY PATH has been passed sucessfully) * SUMMARY: - * - Check if the user1 can visualize the credentials that has been enabled in "My Credentials" - * - Check the fields displayed when user click "View" Credential + * - Check if the user can visualize the credentials that has been enabled in "My Credentials" + * - Check that the fields displayed in "View" Credential are the expected ones */ - test('USER Credentials -> My Credentials -> View enabled Financial Vulnerability Credential', async ({ page }) => { - // View the Financial Vulnerabilty Credential in status 'Enabled' for the user - await gotoViewEnabledCredential(page, SCHEMA_TYPE_FVC); - const enabledCredentialView = new ViewCredentialPage(page); - //Check that required fields exist and have a valid value in the current enabled credential - - //Get the credential subject values of the credential visualized on the screen and compare to the model - let actualCredential = await enabledCredentialView.buildACredentialFromInputValues(SCHEMA_TYPE_FVC); - let expectedCredential = await expectedCredentialSubjectForUser(USER1_EMAIL, SCHEMA_TYPE_FVC); - expect(actualCredential).toEqual(expectedCredential); + test('USER -> My Credentials -> View FVC enabled Credential for user1', async ({ page }) => { + + let schemaType = SCHEMA_TYPE_FVC; + let user = USER1_EMAIL; + + await loginAsUser(page, user, URL_IDHUB); + await test_ViewAndCheckEnabledCredentialbyUser(page, schemaType, user); }); + test('USER -> My Credentials -> View FVC enabled Credential for user2', async ({ page }) => { + let schemaType = SCHEMA_TYPE_FVC; + let user = USER2_EMAIL; + + await loginAsUser(page, user, URL_IDHUB); + await test_ViewAndCheckEnabledCredentialbyUser(page, schemaType, user); + + }); + + test('USER -> My Credentials -> Request the issuance of a FVC for user3', async ({ page }) => { + + let schemaType = SCHEMA_TYPE_FVC; + let user = USER3_EMAIL; + + await loginAsUser(page, user, URL_IDHUB); + + await test_RequestAndCheckIssuedCredentialByUser(page, schemaType, user); + + }); }) diff --git a/tests/05-COMM-EnabledAndIssueMC_Credential.spec.ts b/tests/05-COMM-EnabledAndIssueMC_Credential.spec.ts index 0d36894..c2e4e83 100644 --- a/tests/05-COMM-EnabledAndIssueMC_Credential.spec.ts +++ b/tests/05-COMM-EnabledAndIssueMC_Credential.spec.ts @@ -1,14 +1,13 @@ -import { test, expect } from '@playwright/test' -import { ViewCredentialPage } from '../src/page-objects/US_ViewCredentialPage.js' -import { URL_IDHUB, USER1_EMAIL, USER2_EMAIL } from '../src/constants/env_constants'; -import { ALERT_FILE_TO_IMPORT_IS_EMPTY, ALERT_FILE_TO_IMPORT_WITHOUT_REQUIRED_COLUMS_MC, ALERT_FILE_TO_IMPORT_WITH_ALIEN_COLUMS, ALERT_FILE_TO_IMPORT_WITH_REQUIRED_COLUMS_EMPTY, FILE_TO_IMPORT_MC, FILE_TO_IMPORT_MC_2, FILE_TO_IMPORT_MC_EMPTY, FILE_TO_IMPORT_MC_WITHOUT_REQUIRED_COLUMNS, FILE_TO_IMPORT_MC_WITH_ALIEN_COLUMNS, FILE_TO_IMPORT_MC_WITH_REQUIRED_EMPTY, JSON_SCHEMA_MC, SCHEMA_MC, SCHEMA_TYPE_MC } from '../src/constants/constants'; -import { expectedCredentialSubjectForUser, gotoViewEnabledCredential, loginAsAdmin, loginAsUser, testImportDataFile_HappyPath, testImportDataFile_SadPath } from '../src/steps.js'; +import { test} from '@playwright/test' +import { URL_IDHUB, USER1_EMAIL, USER2_EMAIL, USER3_EMAIL } from '../src/constants/env_constants'; +import { ALERT_FILE_TO_IMPORT_IS_EMPTY, ALERT_FILE_TO_IMPORT_WITHOUT_REQUIRED_COLUMS_MC, ALERT_FILE_TO_IMPORT_WITH_ALIEN_COLUMS, ALERT_FILE_TO_IMPORT_WITH_REQUIRED_COLUMS_EMPTY, ENABLED_ST, FILE_TO_IMPORT_MC, FILE_TO_IMPORT_MC_2, FILE_TO_IMPORT_MC_EMPTY, FILE_TO_IMPORT_MC_WITHOUT_REQUIRED_COLUMNS, FILE_TO_IMPORT_MC_WITH_ALIEN_COLUMNS, FILE_TO_IMPORT_MC_WITH_REQUIRED_EMPTY, ISSUED_ST, JSON_SCHEMA_MC, SCHEMA_MC, SCHEMA_TYPE_MC } from '../src/constants/constants'; +import { loginAsAdmin, loginAsUser, testImportDataFile_HappyPath, testImportDataFile_SadPath, test_RequestAndCheckIssuedCredentialByUser, test_ViewAndCheckEnabledCredentialbyUser } from '../src/steps.js'; /** -* Checking data section: view the lists of files imported, import data, delete... +* Testing Admin->Data Section functionality with the Membership Credential (MC) */ -test.describe('ADMIN-> DATA Section Tests - Testing with Membership Credential', () => { +test.describe('ADMIN-> DATA -> Import MC excel files', () => { test.beforeEach(async ({ page }) => { await loginAsAdmin(page, URL_IDHUB); @@ -19,12 +18,13 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Membership Credential', }) /** - * Load of an excel file - Happy Path: - * Expected behavior: the file is loaded, the message:"The file was imported successfully!" is displayed, - * and the file appears in the imported files view. + * Load an excel file - Happy Path + * Expected behavior: + * - the file is loaded, the message: "The file was imported successfully!" is displayed. + * - the file appears in the imported files view. */ - test('DATA -> Import data file - Happy path - Membership Card Credential - membership_card.xlsx ', async ({ page }) => { + test('ADMIN-> DATA -> Import MC excel file - Happy Path', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_MC; const jsonSchema = JSON_SCHEMA_MC; @@ -40,7 +40,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Membership Credential', * Expected behavior: The error message: "The file you try to import is empty" */ - test('DATA -> Import data file - Sad path (file well formatted but empty) - Membership Card Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import MC excel file - Sad path (file well formatted but empty', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_MC_EMPTY; const jsonSchema = JSON_SCHEMA_MC; @@ -51,7 +51,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Membership Credential', }); - test('DATA -> Import data file - Sad path (bad formatted file, without required columns) - Membership Card Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import MC excel file - Sad path (bad formatted file, without required columns', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_MC_WITHOUT_REQUIRED_COLUMNS; const jsonSchema = JSON_SCHEMA_MC; @@ -62,7 +62,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Membership Credential', }); - test('DATA -> Import data file - Sad path (bad formatted file, with alien columns) - Membership Card Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import MC excel file - Sad path (bad formatted file, with alien columns)', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_MC_WITH_ALIEN_COLUMNS; const jsonSchema = JSON_SCHEMA_MC; @@ -73,7 +73,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Membership Credential', }); - test('DATA -> Import data file - Sad path (file with required columns present but empty) - Membership Card Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import MC excel file - Sad path (file with required columns present but empty)', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_MC_WITH_REQUIRED_EMPTY; const jsonSchema = JSON_SCHEMA_MC; @@ -86,7 +86,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Membership Credential', }) -test.describe('USER -> Credentials Section Tests - testing with USER1_EMAIL AND Membership Card Credential', () => { +test.describe('USER -> My Credentials - enable and issue credentials', () => { test.afterEach(async ({ page }) => { await page.click('.logout'); @@ -94,36 +94,41 @@ test.describe('USER -> Credentials Section Tests - testing with USER1_EMAIL AND }) /** - * PRE-CONDITIONS: the admin has enabled a credential of type 'Membership Card' for USER1_EMAIL - * This is true, if the before test (DATA -> Import data- HAPPY PATH has been passed sucessfully) + * PRE-CONDITIONS: the admin has enabled sucessfully a credential in the previous test (DATA -> Import data- HAPPY PATH has been passed sucessfully) * SUMMARY: - * - Check if the user1 can visualize the credentials that has been enabled in "My Credentials" - * - Check the fields displayed when user click "View" Credential + * - Check if the user can visualize the credentials that has been enabled in "My Credentials" + * - Check that the fields displayed in "View" Credential are the expected ones */ - test('USER Credentials -> My Credentials -> View enabled Membership Card - for user1@example.org', async ({ page }) => { - // View the Membership Card Credential in status 'Enabled' for the user - await loginAsUser(page, USER1_EMAIL, URL_IDHUB); - await gotoViewEnabledCredential(page, SCHEMA_TYPE_MC); - const enabledCredentialView = new ViewCredentialPage(page); - //Check that required fields exist and have a valid value in the current enabled credential - //Get the credential subject values of the credential visualized in the screen and compare to the model - let actualCredential = await enabledCredentialView.buildACredentialFromInputValues(SCHEMA_TYPE_MC); - let expectedCredential = await expectedCredentialSubjectForUser(USER1_EMAIL, SCHEMA_TYPE_MC); - expect(actualCredential).toEqual(expectedCredential); + test('USER -> My Credentials -> View MC enabled Credential for user1', async ({ page }) => { + + let schemaType = SCHEMA_TYPE_MC; + let user = USER1_EMAIL; + + await loginAsUser(page, user, URL_IDHUB); + await test_ViewAndCheckEnabledCredentialbyUser(page, schemaType, user); + }); - test('USER Credentials -> My Credentials -> View enabled Membership Card - for user2@example.org', async ({ page }) => { - // View the Membership Card Credential in status 'Enabled' for the user - await loginAsUser(page, USER2_EMAIL, URL_IDHUB); - await gotoViewEnabledCredential(page, SCHEMA_TYPE_MC); - const enabledCredentialView = new ViewCredentialPage(page); - //Check that required fields exist and have a valid value in the current enabled credential - - //Get the credential subject values of the credential visualized in the screen and compare to the model - let actualCredential = await enabledCredentialView.buildACredentialFromInputValues(SCHEMA_TYPE_MC); - let expectedCredential = await expectedCredentialSubjectForUser(USER2_EMAIL, SCHEMA_TYPE_MC); - expect(actualCredential).toEqual(expectedCredential); + test('USER -> My Credentials -> View MC enabled Credential for user3', async ({ page }) => { + + let schemaType = SCHEMA_TYPE_MC; + let user = USER3_EMAIL; + + await loginAsUser(page, user, URL_IDHUB); + await test_ViewAndCheckEnabledCredentialbyUser(page, schemaType, user); + }); -}) + + test('USER -> My Credentials -> Request the issuance of a MC for user3', async ({ page }) => { + + let schemaType = SCHEMA_TYPE_MC; + let user = USER3_EMAIL; + + await loginAsUser(page, user, URL_IDHUB); + + await test_RequestAndCheckIssuedCredentialByUser(page, schemaType, user); + + }); +}) diff --git a/tests/06-COMM-EnabledAndIssueNGO_FED.spec.ts b/tests/06-COMM-EnabledAndIssueNGO_FED.spec.ts index b92c03b..5eb1773 100644 --- a/tests/06-COMM-EnabledAndIssueNGO_FED.spec.ts +++ b/tests/06-COMM-EnabledAndIssueNGO_FED.spec.ts @@ -1,14 +1,13 @@ -import { test, expect } from '@playwright/test' -import { loginAsAdmin, loginAsUser, gotoViewEnabledCredential, expectedCredentialSubjectForUser, testImportDataFile_HappyPath, testImportDataFile_SadPath } from '../src/steps'; -import { ViewCredentialPage } from '../src/page-objects/US_ViewCredentialPage.js' -import { URL_IDHUB, USER1_EMAIL, USER2_EMAIL } from '../src/constants/env_constants'; +import { test} from '@playwright/test' +import { loginAsAdmin, loginAsUser, testImportDataFile_HappyPath, testImportDataFile_SadPath, test_RequestAndCheckIssuedCredentialByUser, test_ViewAndCheckEnabledCredentialbyUser } from '../src/steps'; +import { URL_IDHUB, USER1_EMAIL, USER2_EMAIL, USER3_EMAIL } from '../src/constants/env_constants'; import { ALERT_FILE_TO_IMPORT_IS_EMPTY, ALERT_FILE_TO_IMPORT_WITHOUT_REQUIRED_COLUMS_NGO_FM, ALERT_FILE_TO_IMPORT_WITH_ALIEN_COLUMS, ALERT_FILE_TO_IMPORT_WITH_REQUIRED_COLUMS_EMPTY_NGO_FM, FILE_TO_IMPORT_NGO_FM, FILE_TO_IMPORT_NGO_FM_EMPTY, FILE_TO_IMPORT_NGO_FM_WITHOUT_REQUIRED_COLUMNS, FILE_TO_IMPORT_NGO_FM_WITH_ALIEN_COLUMNS, FILE_TO_IMPORT_NGO_FM_WITH_REQUIRED_EMPTY, JSON_SCHEMA_NGO_FM, SCHEMA_NGO_FM, SCHEMA_TYPE_NGO_FM } from '../src/constants/constants'; /** -* Checking data section: view the lists of files imported, import data, delete... +* Testing Admin->Data Section functionality with the NGO Federation Membership Credential (NGO_FM) */ -test.describe('ADMIN-> DATA Section Tests - Testing with NGO Federation Membership', () => { +test.describe('ADMIN-> DATA -> Import NGO_FM excel files', () => { test.beforeEach(async ({ page }) => { await loginAsAdmin(page, URL_IDHUB); @@ -20,12 +19,13 @@ test.describe('ADMIN-> DATA Section Tests - Testing with NGO Federation Membersh /** - * Load an excel file - Happy Path - * Expected behavior: the file is loaded, the message:"The file was imported successfully!" is displayed, - * and the file appears in the imported files view. - */ + * Load an excel file - Happy Path + * Expected behavior: + * - the file is loaded, the message: "The file was imported successfully!" is displayed. + * - the file appears in the imported files view. + */ - test('DATA -> Import data file - Happy path - NGO Federation Membership Credential - federation-membership.xlsx ', async ({ page }) => { + test('DATA -> ADMIN-> DATA -> Import NGO_FM excel file - Happy Path', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_NGO_FM; const jsonSchema = JSON_SCHEMA_NGO_FM; @@ -42,7 +42,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with NGO Federation Membersh * Expected behavior: The error message: "The file you try to import is empty" */ - test('DATA -> Import data file - Sad path (file well formatted but empty) - NGO Federation Membership Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import NGO_FM excel file - Sad path (file well formatted but empty', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_NGO_FM_EMPTY; const jsonSchema = JSON_SCHEMA_NGO_FM; @@ -53,7 +53,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with NGO Federation Membersh }); - test('DATA -> Import data file - Sad path (file bad formatted, without required columns) - NGO Federation Membership Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import NGO excel file - Sad path (bad formatted file, without required columns', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_NGO_FM_WITHOUT_REQUIRED_COLUMNS; const jsonSchema = JSON_SCHEMA_NGO_FM; @@ -64,7 +64,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with NGO Federation Membersh }); - test('DATA -> Import data file - Sad path (file bad formatted, with alien columns) - NGO Federation Membership Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import NGO_FM excel file - Sad path (bad formatted file, with alien columns)', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_NGO_FM_WITH_ALIEN_COLUMNS; const jsonSchema = JSON_SCHEMA_NGO_FM; @@ -75,7 +75,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with NGO Federation Membersh }); - test('DATA -> Import data file - Sad path (file with required columns present but empty) - NGO Federation Membership Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import NGO_FM excel file - Sad path (file with required columns present but empty)', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_NGO_FM_WITH_REQUIRED_EMPTY; const jsonSchema = JSON_SCHEMA_NGO_FM; @@ -88,7 +88,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with NGO Federation Membersh }) //end describe -test.describe('USER -> Credentials Section Tests - testing with USER1_EMAIL AND NGO Federation Membership Credential', () => { +test.describe('USER -> My Credentials - enable and issue credentials', () => { test.afterEach(async ({ page }) => { //este se ejecutará despues de cada test await page.click('.logout'); @@ -96,38 +96,38 @@ test.describe('USER -> Credentials Section Tests - testing with USER1_EMAIL AND }) /** - * PRE-CONDITIONS: the admin has enabled a credential of type 'NGO Federation Membership' for USER1_EMAIL - * This is true, if the before test (DATA -> Import data- HAPPY PATH has been passed sucessfully) + * PRE-CONDITIONS: the admin has enabled sucessfully a credential in the previous test (DATA -> Import data- HAPPY PATH has been passed sucessfully) * SUMMARY: - * - Check if the user1 can visualize the credentials that has been enabled in "My Credentials" - * - Check the fields displayed when user click "View" Credential + * - Check if the user can visualize the credentials that has been enabled in "My Credentials" + * - Check that the fields displayed in "View" Credential are the expected ones */ - test('USER Credentials -> My Credentials -> View enabled NGO Federation Membership Credential - for user1@example.org', async ({ page }) => { - // View the NGO Federation Membership Credential in status 'Enabled' for the user - await loginAsUser(page, USER1_EMAIL, URL_IDHUB); - await gotoViewEnabledCredential(page, SCHEMA_TYPE_NGO_FM); - const enabledCredentialView = new ViewCredentialPage(page); - //Check that required fields exist and have a valid value in the current enabled credential - - //Get the credential subject values of the credential visualized in the screen and compare to the model - let actualCredential = await enabledCredentialView.buildACredentialFromInputValues(SCHEMA_TYPE_NGO_FM); - let expectedCredential = await expectedCredentialSubjectForUser(USER1_EMAIL, SCHEMA_TYPE_NGO_FM); - expect(actualCredential).toEqual(expectedCredential); + test('USER -> My Credentials -> View NGO_FM enabled Credential for user1', async ({ page }) => { + let schemaType = SCHEMA_TYPE_NGO_FM; + let user = USER1_EMAIL; + + await loginAsUser(page, user, URL_IDHUB); + await test_ViewAndCheckEnabledCredentialbyUser(page, schemaType, user); + }); - test('USER Credentials -> My Credentials -> View enabled NGO Federation Membership Credential - for user2@example.org', async ({ page }) => { - // View the NGO Federation Membership Credential in status 'Enabled' for the user - await loginAsUser(page, USER2_EMAIL, URL_IDHUB); - await gotoViewEnabledCredential(page, SCHEMA_TYPE_NGO_FM); - const enabledCredentialView = new ViewCredentialPage(page); - //Check that required fields exist and have a valid value in the current enabled credential - - //Get the credential subject values of the credential visualized in the screen and compare to the model - let actualCredential = await enabledCredentialView.buildACredentialFromInputValues(SCHEMA_TYPE_NGO_FM); - let expectedCredential = await expectedCredentialSubjectForUser(USER2_EMAIL, SCHEMA_TYPE_NGO_FM); - expect(actualCredential).toEqual(expectedCredential); + test('USER -> My Credentials -> View NGO_FM enabled Credential for user2', async ({ page }) => { + let schemaType = SCHEMA_TYPE_NGO_FM; + let user = USER2_EMAIL; + + await loginAsUser(page, user, URL_IDHUB); + await test_ViewAndCheckEnabledCredentialbyUser(page, schemaType, user); + }); + test('USER -> My Credentials -> Request the issuance of a NGO_FM for user3', async ({ page }) => { + + let schemaType = SCHEMA_NGO_FM; + let user = USER3_EMAIL; + + await loginAsUser(page, user, URL_IDHUB); + + await test_RequestAndCheckIssuedCredentialByUser(page, schemaType, user); + + }); }) - diff --git a/tests/07-COMM-EnabledAndIssueCC_Credential.spec.ts b/tests/07-COMM-EnabledAndIssueCC_Credential.spec.ts index 2e73544..1c09b2d 100644 --- a/tests/07-COMM-EnabledAndIssueCC_Credential.spec.ts +++ b/tests/07-COMM-EnabledAndIssueCC_Credential.spec.ts @@ -1,14 +1,13 @@ -import { test, expect } from '@playwright/test' -import { loginAsAdmin, loginAsUser, gotoViewEnabledCredential, expectedCredentialSubjectForUser, testImportDataFile_HappyPath, testImportDataFile_SadPath } from '../src/steps'; -import { ViewCredentialPage } from '../src/page-objects/US_ViewCredentialPage.js' -import { URL_IDHUB, USER1_EMAIL, USER2_EMAIL } from '../src/constants/env_constants'; +import { test} from '@playwright/test' +import { loginAsAdmin, loginAsUser,testImportDataFile_HappyPath, testImportDataFile_SadPath, test_RequestAndCheckIssuedCredentialByUser, test_ViewAndCheckEnabledCredentialbyUser } from '../src/steps'; +import { URL_IDHUB, USER1_EMAIL, USER2_EMAIL, USER3_EMAIL } from '../src/constants/env_constants'; import { ALERT_FILE_TO_IMPORT_IS_EMPTY, ALERT_FILE_TO_IMPORT_WITHOUT_REQUIRED_COLUMS_CC, ALERT_FILE_TO_IMPORT_WITH_ALIEN_COLUMS, ALERT_FILE_TO_IMPORT_WITH_REQUIRED_COLUMS_EMPTY, FILE_TO_IMPORT_CC, FILE_TO_IMPORT_CC_EMPTY, FILE_TO_IMPORT_CC_WITHOUT_REQUIRED_COLUMNS, FILE_TO_IMPORT_CC_WITH_ALIEN_COLUMNS, FILE_TO_IMPORT_CC_WITH_REQUIRED_EMPTY, JSON_SCHEMA_CC, SCHEMA_CC, SCHEMA_TYPE_CC } from '../src/constants/constants'; /** -* Checking data section: view the lists of files imported, import data, delete... +* Testing Admin->Data Section functionality with the NGO Course Credential (CC) */ -test.describe('ADMIN-> DATA Section Tests - Testing with Course Credential', () => { +test.describe('ADMIN-> DATA -> Import CC excel files', () => { test.beforeEach(async ({ page }) => { await loginAsAdmin(page, URL_IDHUB); @@ -18,13 +17,14 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Course Credential', () await page.close(); }) - /** - * Load of an excel file - Happy Path: - * Expected behavior: the file is loaded, the message:"The file was imported successfully!" is displayed, - * and the file appears in the imported files view. - */ + /** + * Load an excel file - Happy Path + * Expected behavior: + * - the file is loaded, the message: "The file was imported successfully!" is displayed. + * - the file appears in the imported files view. + */ - test('DATA -> Import data file - Happy path - Course Credential - course-credential.xlsx ', async ({ page }) => { + test('ADMIN-> DATA -> Import CC excel file - Happy Path', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_CC; const jsonSchema = JSON_SCHEMA_CC; @@ -40,7 +40,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Course Credential', () * Expected behavior: The error message: "The file you try to import is empty" */ - test('DATA -> Import data file - Sad path (file well formatted but empty) - Course Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import CC excel file - Sad path (file well formatted but empty', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_CC_EMPTY; const jsonSchema = JSON_SCHEMA_CC; @@ -51,7 +51,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Course Credential', () }); - test('DATA -> Import data file - Sad path (bad formatted file, without required columns) - Course Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import CC excel file - Sad path (bad formatted file, without required columns', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_CC_WITHOUT_REQUIRED_COLUMNS; const jsonSchema = JSON_SCHEMA_CC; @@ -62,7 +62,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Course Credential', () }); - test('DATA -> Import data file - Sad path (bad formatted file, with alien columns) - Course Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import CC excel file - Sad path (bad formatted file, with alien columns)', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_CC_WITH_ALIEN_COLUMNS; @@ -75,7 +75,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Course Credential', () }); - test('DATA -> Import data file - Sad path (file with required columns present but empty) - Course Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import CC excel file - Sad path (file with required columns present but empty)', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_CC_WITH_REQUIRED_EMPTY; const jsonSchema = JSON_SCHEMA_CC; @@ -88,46 +88,46 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Course Credential', () }) -test.describe('USER -> Credentials Section Tests - testing with USER1_EMAIL AND Course Credential', () => { +test.describe('USER -> My Credentials - enable and issue credentials', () => { - test.afterEach(async ({ page }) => { + test.afterEach(async ({ page }) => { await page.click('.logout'); await page.close(); }) /** - * PRE-CONDITIONS: the admin has enabled a credential of type 'Course' for USER1_EMAIL - * This is true, if the before test (DATA -> Import data- HAPPY PATH has been passed sucessfully) + * PRE-CONDITIONS: the admin has enabled sucessfully a credential in the previous test (DATA -> Import data- HAPPY PATH has been passed sucessfully) * SUMMARY: - * - Check if the user1 can visualize the credentials that has been enabled in "My Credentials" - * - Check the fields displayed when user click "View" Credential + * - Check if the user can visualize the credentials that has been enabled in "My Credentials" + * - Check that the fields displayed in "View" Credential are the expected ones */ - - test('USER Credentials -> My Credentials -> View enabled Course Credential - for user1@example.org', async ({ page }) => { - // View the Course Credential in status 'Enabled' for the user - await loginAsUser(page, USER1_EMAIL, URL_IDHUB); - await gotoViewEnabledCredential(page, SCHEMA_TYPE_CC); - const enabledCredentialView = new ViewCredentialPage(page); - //Check that required fields exist and have a valid value in the current enabled credential - - //Get the credential subject values of the credential visualized in the screen and compare to the model - let actualCredential = await enabledCredentialView.buildACredentialFromInputValues(SCHEMA_TYPE_CC); - let expectedCredential = await expectedCredentialSubjectForUser(USER1_EMAIL, SCHEMA_TYPE_CC); - expect(actualCredential).toEqual(expectedCredential); + + test('USER -> My Credentials -> View CC enabled Credential for user1', async ({ page }) => { + let schemaType = SCHEMA_TYPE_CC; + let user = USER1_EMAIL; + + await loginAsUser(page, user, URL_IDHUB); + await test_ViewAndCheckEnabledCredentialbyUser(page, schemaType, user); + }); - test('USER Credentials -> My Credentials -> View enabled Course Credential - for user2@example.org', async ({ page }) => { - // View the Course Credential in status 'Enabled' for the user - await loginAsUser(page, USER2_EMAIL, URL_IDHUB); - await gotoViewEnabledCredential(page, SCHEMA_TYPE_CC); - const enabledCredentialView = new ViewCredentialPage(page); - //Check that required fields exist and have a valid value in the current enabled credential - - //Get the credential subject values of the credential visualized in the screen and compare to the model - let actualCredential = await enabledCredentialView.buildACredentialFromInputValues(SCHEMA_TYPE_CC); - let expectedCredential = await expectedCredentialSubjectForUser(USER2_EMAIL, SCHEMA_TYPE_CC); - expect(actualCredential).toEqual(expectedCredential); + test('USER -> My Credentials -> View CC enabled Credential for user2', async ({ page }) => { + let schemaType = SCHEMA_TYPE_CC; + let user = USER2_EMAIL; + + await loginAsUser(page, user, URL_IDHUB); + await test_ViewAndCheckEnabledCredentialbyUser(page, schemaType, user); + }); -}) + test('USER -> My Credentials -> Request the issuance of a CC for user3', async ({ page }) => { + + let schemaType = SCHEMA_CC; + let user = USER3_EMAIL; + + await loginAsUser(page, user, URL_IDHUB); + await test_RequestAndCheckIssuedCredentialByUser(page, schemaType, user); + + }); +}) \ No newline at end of file diff --git a/tests/08-COMM-EnabledAndIssue_EOC_Credential.spec.ts b/tests/08-COMM-EnabledAndIssue_EOC_Credential.spec.ts index eaf7bfe..bb28dd8 100644 --- a/tests/08-COMM-EnabledAndIssue_EOC_Credential.spec.ts +++ b/tests/08-COMM-EnabledAndIssue_EOC_Credential.spec.ts @@ -1,14 +1,13 @@ -import { test, expect } from '@playwright/test' -import { loginAsAdmin, loginAsUser, gotoViewEnabledCredential, expectedCredentialSubjectForUser, testImportDataFile_HappyPath, testImportDataFile_SadPath } from '../src/steps'; -import { ViewCredentialPage } from '../src/page-objects/US_ViewCredentialPage.js' -import { URL_IDHUB, USER1_EMAIL, USER2_EMAIL } from '../src/constants/env_constants'; -import { ALERT_FILE_TO_IMPORT_IS_EMPTY, ALERT_FILE_TO_IMPORT_WITHOUT_REQUIRED_COLUMS_EOC, ALERT_FILE_TO_IMPORT_WITH_ALIEN_COLUMS, ALERT_FILE_TO_IMPORT_WITH_REQUIRED_COLUMS_EMPTY_EOC, FILE_TO_IMPORT_EOC, FILE_TO_IMPORT_EOC_EMPTY, FILE_TO_IMPORT_EOC_WITHOUT_REQUIRED_COLUMNS, FILE_TO_IMPORT_EOC_WITH_ALIEN_COLUMNS, FILE_TO_IMPORT_EOC_WITH_REQUIRED_EMPTY, JSON_SCHEMA_EOC, SCHEMA_EOC, SCHEMA_TYPE_EOC } from '../src/constants/constants'; +import { test} from '@playwright/test' +import { loginAsAdmin, loginAsUser, testImportDataFile_HappyPath, testImportDataFile_SadPath, test_RequestAndCheckIssuedCredentialByUser, test_ViewAndCheckEnabledCredentialbyUser } from '../src/steps'; +import { URL_IDHUB, USER1_EMAIL, USER2_EMAIL, USER3_EMAIL } from '../src/constants/env_constants'; +import { ALERT_FILE_TO_IMPORT_IS_EMPTY, ALERT_FILE_TO_IMPORT_WITHOUT_REQUIRED_COLUMS_EOC, ALERT_FILE_TO_IMPORT_WITH_ALIEN_COLUMS, ALERT_FILE_TO_IMPORT_WITH_REQUIRED_COLUMS_EMPTY_EOC,FILE_TO_IMPORT_EOC, FILE_TO_IMPORT_EOC_EMPTY, FILE_TO_IMPORT_EOC_WITHOUT_REQUIRED_COLUMNS, FILE_TO_IMPORT_EOC_WITH_ALIEN_COLUMNS, FILE_TO_IMPORT_EOC_WITH_REQUIRED_EMPTY, JSON_SCHEMA_EOC, SCHEMA_EOC, SCHEMA_TYPE_EOC } from '../src/constants/constants'; /** -* Checking data section: view the lists of files imported, import data, delete... +* Testing Admin->Data Section functionality with the E-Operator Claim Credential (EOP) */ -test.describe('ADMIN-> DATA Section Tests - Testing with E-Operator Claim Credential', () => { +test.describe('ADMIN-> DATA -> Import EOP excel files', () => { test.beforeEach(async ({ page }) => { await loginAsAdmin(page, URL_IDHUB); @@ -18,14 +17,14 @@ test.describe('ADMIN-> DATA Section Tests - Testing with E-Operator Claim Creden await page.close(); }) - - /** + /** * Load an excel file - Happy Path - * Expected behavior: the file is loaded, the message:"The file was imported successfully!" is displayed, - * and the file appears in the imported files view. + * Expected behavior: + * - the file is loaded, the message: "The file was imported successfully!" is displayed. + * - the file appears in the imported files view. */ - test('DATA -> Import data file - Happy path - E-Operator Claim Credential - e-operator-claim.xlsx ', async ({ page }) => { + test('ADMIN-> DATA -> Import EOC excel file - Happy Path', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_EOC; const jsonSchema = JSON_SCHEMA_EOC; @@ -40,7 +39,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with E-Operator Claim Creden * Expected behavior: The error message: "The file you try to import is empty" */ - test('DATA -> Import data file - Sad path (file well formatted but empty) - E-Operator Claim Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import EOC excel file - Sad path (file well formatted but empty', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_EOC_EMPTY; const jsonSchema = JSON_SCHEMA_EOC; @@ -56,7 +55,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with E-Operator Claim Creden * Try to load a bad formatted file, without required data. */ - test('DATA -> Import data file - Sad path (bad formatted file, without required columns) - E-Operator Claim Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import EOC excel file - Sad path (bad formatted file, without required columns', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_EOC_WITHOUT_REQUIRED_COLUMNS; const jsonSchema = JSON_SCHEMA_EOC; @@ -67,7 +66,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with E-Operator Claim Creden }); - test('DATA -> Import data file - Sad path (file bad formatted, with alien columns) - E-Operator Claim Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import EOC excel file - Sad path (bad formatted file, with alien columns)', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_EOC_WITH_ALIEN_COLUMNS; const jsonSchema = JSON_SCHEMA_EOC; @@ -78,7 +77,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with E-Operator Claim Creden }); - test('DATA -> Import data file - Sad path (file with required columns present but empty) - E-Operator Claim Credential ', async ({ page }) => { + test('ADMIN-> DATA -> Import EOC excel file - Sad path (file with required columns present but empty)', async ({ page }) => { const fileToImport = FILE_TO_IMPORT_EOC_WITH_REQUIRED_EMPTY; const jsonSchema = JSON_SCHEMA_EOC; @@ -91,46 +90,46 @@ test.describe('ADMIN-> DATA Section Tests - Testing with E-Operator Claim Creden }) -test.describe('USER -> Credentials Section Tests - testing with USER1_EMAIL AND E-Operator Claim Credential', () => { +test.describe('USER -> My Credentials - enable and issue credentials', () => { test.afterEach(async ({ page }) => { //este se ejecutará despues de cada test await page.click('.logout'); await page.close(); }) - /** - * PRE-CONDITIONS: the admin has enabled a credential of type 'E-Operator Claim' for USER1_EMAIL - * This is true, if the before test (DATA -> Import data- HAPPY PATH has been passed sucessfully) + /** + * PRE-CONDITIONS: the admin has enabled sucessfully a credential in the previous test (DATA -> Import data- HAPPY PATH has been passed sucessfully) * SUMMARY: - * - Check if the user1 can visualize the credentials that has been enabled in "My Credentials" - * - Check the fields displayed when user click "View" Credential + * - Check if the user can visualize the credentials that has been enabled in "My Credentials" + * - Check that the fields displayed in "View" Credential are the expected ones */ - test('USER Credentials -> My Credentials -> View enabled E-Operator Claim Credential - for user1@example.org' , async ({ page }) => { - // View the E-Operator Claim Credential in status 'Enabled' for the user - await loginAsUser(page, USER1_EMAIL, URL_IDHUB); - await gotoViewEnabledCredential(page, SCHEMA_TYPE_EOC); - const enabledCredentialView = new ViewCredentialPage(page); - //Check that required fields exist and have a valid value in the current enabled credential - - //Get the credential subject values of the credential visualized in the screen and compare to the model - let actualCredential = await enabledCredentialView.buildACredentialFromInputValues(SCHEMA_TYPE_EOC); - let expectedCredential = await expectedCredentialSubjectForUser(USER1_EMAIL, SCHEMA_TYPE_EOC); - expect(actualCredential).toEqual(expectedCredential); + test('USER -> My Credentials -> View EOC enabled Credential for user1', async ({ page }) => { + let schemaType = SCHEMA_TYPE_EOC; + let user = USER1_EMAIL; + + await loginAsUser(page, user, URL_IDHUB); + await test_ViewAndCheckEnabledCredentialbyUser(page, schemaType, user); + }); - test('USER Credentials -> My Credentials -> View enabled E-Operator Claim Credential - for user2@example.org' , async ({ page }) => { - // View the E-Operator Claim Credential in status 'Enabled' for the user - await loginAsUser(page, USER2_EMAIL, URL_IDHUB); - await gotoViewEnabledCredential(page, SCHEMA_TYPE_EOC); - const enabledCredentialView = new ViewCredentialPage(page); - //Check that required fields exist and have a valid value in the current enabled credential - - //Get the credential subject values of the credential visualized in the screen and compare to the model - let actualCredential = await enabledCredentialView.buildACredentialFromInputValues(SCHEMA_TYPE_EOC); - let expectedCredential = await expectedCredentialSubjectForUser(USER2_EMAIL, SCHEMA_TYPE_EOC); - expect(actualCredential).toEqual(expectedCredential); + test('USER -> My Credentials -> View EOC enabled Credential for user2', async ({ page }) => { + let schemaType = SCHEMA_TYPE_EOC; + let user = USER2_EMAIL; + + await loginAsUser(page, user, URL_IDHUB); + await test_ViewAndCheckEnabledCredentialbyUser(page, schemaType, user); + }); -}) + test('USER -> My Credentials -> Request the issuance of a EOC for user3', async ({ page }) => { + + let schemaType = SCHEMA_EOC; + let user = USER3_EMAIL; + + await loginAsUser(page, user, URL_IDHUB); + await test_RequestAndCheckIssuedCredentialByUser(page, schemaType, user); + + }); +}) \ No newline at end of file diff --git a/tests/events_messages.json b/tests/events_messages.json deleted file mode 100644 index 5dee06d..0000000 --- a/tests/events_messages.json +++ /dev/null @@ -1,35 +0,0 @@ -[ - { - "id": "EV_USR_REGISTERED", - "text": "The user {email} was registered: name: {name}, last name: {lastname}", - "admin": "true", - "user": "no" - }, - { - "id": "EV_USR_WELCOME", - "text": "Welcome. You has been registered: name: {name}, last name: {lastname}", - "admin": "no", - "user": "true" - }, - - { - "id": "EV_DATA_FILE_IMPORTED_BY_ADMIN", - "text": "A new file was imported by admin: File:{name} Date:{dd/mm/yyyy}", - "admin": "true", - "user": "no" - }, - - { - "id": "EV_CREDENTIAL_ENABLED", - "text": "The credential of type '{type} was enabled for user {email}", - "admin": "true", - "user": "no" - }, - { - "id": "EV_CREDENTIAL_CAN_BE_REQUESTED", - "text": "The credential of type '{type} was enabled for user {email}", - "admin": "no", - "user": "yes" - } - - ] \ No newline at end of file diff --git a/vc_excel/federation-membership.xlsx b/vc_excel/federation-membership.xlsx index 4d6ffa916c7520c9a0f314bde514bcad9339debc..2e2cd2ec482dbdc0609efd371c4434b658eae3df 100644 GIT binary patch delta 3373 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 A>Hq)$ delta 3367 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