Adding request issuance for all types of credentials
This commit is contained in:
parent
657c7c962a
commit
4a52f28cff
38
README.md
38
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<User>' 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
|
||||
|
|
|
@ -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 = [
|
||||
|
|
|
@ -13,7 +13,7 @@ export const CREDENTIAL_TYPES_FIELDS_LIST = {
|
|||
'financialVulnerabilityScore',
|
||||
'amountCoveredByOtherAids',
|
||||
'connectivityOptionList',
|
||||
'assessmentDate'
|
||||
'assessmentDate',
|
||||
] as string[],
|
||||
|
||||
"MembershipCard": [
|
||||
|
|
|
@ -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,11 +315,11 @@ export const CREDENTIAL_TYPE_DATASTORE_UNDEFINED = {
|
|||
CourseCredential_data_undefined: {} as Record<string, any>,
|
||||
EOperatorClaim_data_undefined: {} as Record<string, any>
|
||||
|
||||
//TODO añadir otros tipos de credenciales
|
||||
}
|
||||
|
||||
|
||||
CREDENTIAL_TYPE_DATASTORE_UNDEFINED.FinancialVulnerabilityCredential_data_undefined = {
|
||||
credentialSubject: {
|
||||
firstName: 'undefined_data',
|
||||
lastName: 'undefined_data',
|
||||
email: 'undefined_data',
|
||||
|
@ -335,9 +333,12 @@ CREDENTIAL_TYPE_DATASTORE_UNDEFINED.FinancialVulnerabilityCredential_data_undefi
|
|||
amountCoveredByOtherAids: 'undefined_data',
|
||||
connectivityOptionList: 'undefined_data',
|
||||
assessmentDate: 'undefined_data'
|
||||
},
|
||||
status: 'undefined_data'
|
||||
}
|
||||
|
||||
CREDENTIAL_TYPE_DATASTORE_UNDEFINED.MembershipCard_data_undefined = {
|
||||
credentialSubject: {
|
||||
organisation: 'undefined_data',
|
||||
membershipType: 'undefined_data',
|
||||
membershipId: 'undefined_data',
|
||||
|
@ -349,10 +350,14 @@ CREDENTIAL_TYPE_DATASTORE_UNDEFINED.MembershipCard_data_undefined = {
|
|||
firstName: 'undefined_data',
|
||||
lastName: 'undefined_data',
|
||||
role: 'undefined_data',
|
||||
email: 'undefined_data'
|
||||
email: 'undefined_data',
|
||||
},
|
||||
status: 'undefined_data'
|
||||
}
|
||||
|
||||
|
||||
CREDENTIAL_TYPE_DATASTORE_UNDEFINED.FederationMembership_data_undefined = {
|
||||
credentialSubject: {
|
||||
federation: 'undefined_data',
|
||||
legalName: 'undefined_data',
|
||||
shortName: 'undefined_data',
|
||||
|
@ -370,10 +375,13 @@ CREDENTIAL_TYPE_DATASTORE_UNDEFINED.FederationMembership_data_undefined = {
|
|||
phone: 'undefined_data',
|
||||
website: 'undefined_data',
|
||||
evidence: 'undefined_data',
|
||||
certificationDate: 'undefined_data'
|
||||
certificationDate: 'undefined_data',
|
||||
},
|
||||
status: 'undefined_data'
|
||||
}
|
||||
|
||||
CREDENTIAL_TYPE_DATASTORE_UNDEFINED.CourseCredential_data_undefined = {
|
||||
credentialSubject: {
|
||||
firstName: 'undefined_data',
|
||||
lastName: 'undefined_data',
|
||||
email: 'undefined_data',
|
||||
|
@ -392,15 +400,19 @@ CREDENTIAL_TYPE_DATASTORE_UNDEFINED.CourseCredential_data_undefined = {
|
|||
courseCredits: 'undefined_data',
|
||||
dateOfAssessment: 'undefined_data',
|
||||
evidenceAssessment: 'undefined_data',
|
||||
},
|
||||
status: 'undefined_data'
|
||||
}
|
||||
|
||||
CREDENTIAL_TYPE_DATASTORE_UNDEFINED.EOperatorClaim_data_undefined = {
|
||||
credentialSubject: {
|
||||
legalName: 'undefined_data',
|
||||
role: 'undefined_data',
|
||||
email: 'undefined_data',
|
||||
accreditedBy: 'undefined_data',
|
||||
operatorNumber: 'undefined_data',
|
||||
limitJurisdiction: 'undefined_data',
|
||||
accreditedFor: 'undefined_data'
|
||||
accreditedFor: 'undefined_data',
|
||||
},
|
||||
status: 'undefined_data'
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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<boolean> {
|
||||
|
||||
let status = 'Enabled';
|
||||
|
||||
async credentialExistInMyCredentials(type: string, status: string): Promise<boolean> {
|
||||
// Locator for all rows
|
||||
const rowLocator = this.page.locator('tr');
|
||||
|
||||
|
|
97
src/steps.ts
97
src/steps.ts
|
@ -1,6 +1,6 @@
|
|||
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'
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
||||
|
@ -266,7 +295,6 @@ export async function checkIfTheInformationIsValid(page: Page, user: User) {
|
|||
|
||||
export function expectedCredentialSubjectForUser(email: string, credentialType: string) {
|
||||
|
||||
//export function expectedCredentialSubjectForUser<T extends FinancialVulnerabilityCredential_fields, MembershipCard_fields, NGOFederationMembership_fields>(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<strin
|
|||
const viewImportedDataPage = new ViewImportedDataPage(page);
|
||||
let fileInTheList = await viewImportedDataPage.fileIsAvailableInView(fileName);
|
||||
if (fileInTheList) {
|
||||
let newName = appendRandomNumberToFilename(fileName);
|
||||
let newName = appendRandomNumberToInput(fileName);
|
||||
//rename the file
|
||||
copyFile(fileName, newName);
|
||||
return newName;
|
||||
|
@ -455,3 +483,58 @@ export async function testImportDataFile_SadPath(page: Page, fileToImport: strin
|
|||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
export async function test_ViewAndCheckEnabledCredentialbyUser(page: Page, schemaType: string, user: string) {
|
||||
|
||||
const enabledCredentialView = new ViewCredentialPage(page);
|
||||
|
||||
// View the credential in status 'Enabled'
|
||||
await gotoViewCredential(page, schemaType, ENABLED_ST);
|
||||
|
||||
//Get the credential subject values of the credential visualized on the screen and compare to the model
|
||||
|
||||
let metaCredential = await enabledCredentialView.buildACredentialFromInputValues(schemaType);
|
||||
let actualCredential = metaCredential.credentialSubject;
|
||||
let status = metaCredential.status;
|
||||
let expectedCredential = await expectedCredentialSubjectForUser(user, schemaType);
|
||||
expect(actualCredential).toEqual(expectedCredential);
|
||||
expect(status).toEqual(ENABLED_ST);
|
||||
}
|
||||
|
||||
export async function test_RequestAndCheckIssuedCredentialByUser(page: Page, schemaType: string, user: string) {
|
||||
|
||||
const identitiesPage = new IdentitiesPage(page);
|
||||
const addIdentityPage = new AddIdentityPage(page);
|
||||
const credentialView = new ViewCredentialPage(page);
|
||||
const credentialRequestPage = new CredentialRequestPage(page);
|
||||
|
||||
await clickIdentitiesOnLeftMenu(page);
|
||||
|
||||
//Add a new identity
|
||||
await identitiesPage.clickAddIdentityButton();
|
||||
let did = appendRandomNumberToInput('did');
|
||||
await addIdentityPage.addDid(did, 'Web');
|
||||
|
||||
|
||||
// View the Financial Vulnerabilty Credential in status 'Enabled' for the user
|
||||
await gotoViewCredential(page, schemaType, ENABLED_ST);
|
||||
|
||||
// Request the credential
|
||||
await credentialView.clickRequestCredentialButton();
|
||||
await credentialRequestPage.requestCredential(did, schemaType);
|
||||
await clickMyCredentialsOnLeftMenu(page);
|
||||
|
||||
|
||||
await gotoViewCredential(page, schemaType, ISSUED_ST);
|
||||
|
||||
|
||||
//Get the credential subject values of the credential visualized on the screen and compare to the model
|
||||
let metaCredential = await credentialView.buildACredentialFromInputValues(schemaType);
|
||||
let actualCredential = metaCredential.credentialSubject;
|
||||
let status = metaCredential.status;
|
||||
let expectedCredential = await expectedCredentialSubjectForUser(user, schemaType);
|
||||
|
||||
expect(actualCredential).toEqual(expectedCredential);
|
||||
expect(status).toEqual(ISSUED_ST);
|
||||
|
||||
}
|
|
@ -106,16 +106,16 @@ export async function deleteFile(fileName: string): Promise<void> {
|
|||
}
|
||||
}
|
||||
|
||||
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}`;
|
||||
|
|
|
@ -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';
|
||||
|
||||
/**
|
||||
|
@ -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');
|
||||
})
|
||||
|
||||
})
|
|
@ -82,41 +82,6 @@ test.describe('USER Section Tests', () => {
|
|||
|
||||
});
|
||||
|
||||
/**
|
||||
* 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
|
||||
* UPDATE their basic information and validate it after modification
|
||||
|
|
|
@ -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;
|
||||
|
@ -40,7 +40,7 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Financial Vulnerability
|
|||
* 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
|
||||
test('USER -> My Credentials -> View FVC enabled Credential for user1', async ({ page }) => {
|
||||
|
||||
//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);
|
||||
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);
|
||||
|
||||
});
|
||||
})
|
||||
|
|
|
@ -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
|
||||
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);
|
||||
|
||||
//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);
|
||||
});
|
||||
})
|
||||
|
|
|
@ -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);
|
||||
|
@ -21,11 +20,12 @@ 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.
|
||||
* 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
|
||||
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);
|
||||
|
||||
//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 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
|
||||
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);
|
||||
|
||||
//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 -> 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);
|
||||
|
||||
});
|
||||
})
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
@ -19,12 +18,13 @@ test.describe('ADMIN-> DATA Section Tests - Testing with Course 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 - 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,7 +88,7 @@ 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 }) => {
|
||||
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 '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
|
||||
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);
|
||||
|
||||
//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 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
|
||||
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);
|
||||
|
||||
//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 -> 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);
|
||||
|
||||
});
|
||||
})
|
||||
|
||||
|
|
|
@ -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_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,7 +90,7 @@ 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');
|
||||
|
@ -99,38 +98,38 @@ test.describe('USER -> Credentials Section Tests - testing with USER1_EMAIL AND
|
|||
})
|
||||
|
||||
/**
|
||||
* 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
|
||||
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);
|
||||
|
||||
//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 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
|
||||
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);
|
||||
|
||||
//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 -> 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);
|
||||
|
||||
});
|
||||
})
|
||||
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
||||
]
|
Binary file not shown.
Reference in New Issue