From 627623b6035444f9037bb206d6a5af1622265ab7 Mon Sep 17 00:00:00 2001 From: Sudo Platform Engineering Date: Wed, 14 Jul 2021 06:59:25 +0000 Subject: [PATCH] Release 0.3.0 --- .gitignore | 1 + e2e/commonHelpers.ts | 252 ++++++++++-------- e2e/connectionHelpers.ts | 181 ++++++------- e2e/connections.test.ts | 135 ++++------ e2e/credentialDefinition.test.ts | 56 ++-- e2e/credentialDefinitionHelpers.ts | 46 ++-- e2e/credentialIssuance.test.ts | 52 ++-- e2e/credentialIssuanceHelpers.ts | 63 ++--- e2e/decentralizedIdentifiers.test.ts | 63 +++-- e2e/decentralizedIdentifiersHelpers.ts | 28 +- e2e/proofPresentation.test.ts | 51 ++-- e2e/proofPresentationHelpers.ts | 58 ++-- e2e/schemaDefinition.test.ts | 155 ++++++----- e2e/schemaDefinitionHelpers.ts | 139 +++++----- e2e/setup-tests.ts | 2 +- package.json | 13 +- src/components/Form/modal.tsx | 4 +- .../ConnectionsCard/AcceptInvitationForm.tsx | 10 +- .../ConnectionsCard/ConnectionsCard.spec.tsx | 6 +- .../ConnectionsCard/CreateInvitationForm.tsx | 4 +- yarn.lock | 8 +- 21 files changed, 682 insertions(+), 645 deletions(-) diff --git a/.gitignore b/.gitignore index df9398a..c01a7b6 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ .env.development.local .env.test.local .env.production.local +.e2e_test_success npm-debug.log* yarn-debug.log* diff --git a/e2e/commonHelpers.ts b/e2e/commonHelpers.ts index 832417d..81143fe 100644 --- a/e2e/commonHelpers.ts +++ b/e2e/commonHelpers.ts @@ -1,8 +1,33 @@ -import { By, until } from 'selenium-webdriver'; +import { By, Locator, until, WebElement } from 'selenium-webdriver'; import { driver } from './setup-tests'; export const commonWaitDefault = 20000; +/** + * Utility function to wait for a element to appear and be + * visible. Returns to element if found. + * + * @param {?number} wait an optional amount of time to use when waiting for + * elements to resolve when locating them. + * @return {WebElement} The now visible element. + */ +export async function e2eWaitElementVisible( + locator: Locator, + wait: number = commonWaitDefault, +): Promise { + try { + const element = await driver.wait( + until.elementIsVisible( + await driver.wait(until.elementLocated(locator), wait), + ), + wait, + ); + return element; + } catch (e) { + throw `Failed to find visible element ${locator}: ${e}`; + } +} + /** * Utility function to test navigation to a specified card * and verify presence. @@ -26,11 +51,7 @@ export async function e2eNavigateToCard( ): Promise { // Use the side nav to get to the correct panel for (let i = 0; i < route.length; i++) { - const element = await driver.wait( - until.elementLocated(By.linkText(route[i])), - wait, - ); - + const element = await e2eWaitElementVisible(By.linkText(route[i]), wait); await driver .actions({ bridge: true }) .pause(200) @@ -40,14 +61,14 @@ export async function e2eNavigateToCard( .perform(); } // Make sure the correct card is found - await driver.wait( - until.elementLocated(By.css(`#${cardIdPrefix} .ant-card-head-title`)), + await e2eWaitElementVisible( + By.css(`#${cardIdPrefix} .ant-card-head-title`), wait, ); expect( - await driver - .findElement(By.css(`#${cardIdPrefix} .ant-card-head-title`)) - .getText(), + await ( + await driver.findElement(By.css(`#${cardIdPrefix} .ant-card-head-title`)) + ).getText(), ).toBe(cardTitle); } @@ -68,27 +89,20 @@ export async function e2eHoverOverCardInfoIcon( ): Promise { { // Move mouse over info icon - const element = await driver.wait( - until.elementLocated(By.css(`#${cardIdPrefix}__popover-icon > svg`)), + const element = await e2eWaitElementVisible( + By.css(`#${cardIdPrefix}__popover-icon > svg`), wait, ); await driver.actions({ bridge: true }).move({ origin: element }).perform(); } // Make sure the pop up displays - await driver.wait( - until.elementLocated( - By.xpath(`//div[@id='${cardIdPrefix}__popover-dialog']/div[2]/p`), - ), + await e2eWaitElementVisible( + By.xpath(`//div[@id='${cardIdPrefix}__popover-dialog']/div[2]/p`), wait, ); + // Move mouse out of info icon - { - const element = await driver.wait( - until.elementLocated(By.css('body')), - wait, - ); - await driver.actions({ bridge: true }).move({ origin: element }).perform(); - } + await driver.actions({ bridge: true }).move({}).perform(); // Make sure the pop up goes away await driver.wait( until.elementIsNotVisible( @@ -114,11 +128,11 @@ export async function e2eCheckMessageDisplays( wait: number = commonWaitDefault, ): Promise { // Check that the expected message appears after the action. - const element = await driver.wait( - until.elementLocated(By.xpath(`//span[contains(.,'${message}')]`)), + const element = await e2eWaitElementVisible( + By.xpath(`//span[contains(.,'${message}')]`), wait, ); - await driver.wait(until.elementIsVisible(element), wait); + // Wait for message to dissapear to avoid artifact issues // with subsequent UI actions await driver.wait(until.stalenessOf(element), wait); @@ -142,21 +156,25 @@ export async function e2eInitiateThenCancelCardForm( cardFormId: string, wait: number = commonWaitDefault, ): Promise { - await driver - .wait( - until.elementLocated(By.css(`#${cardFormActivateButton} > span`)), + await ( + await e2eWaitElementVisible( + By.css(`#${cardFormActivateButton} > span`), wait, ) - .click(); + ).click(); + await e2eWaitElementVisible(By.id(cardFormId), wait); - await driver.wait( - until.elementIsVisible( - await driver.wait(until.elementLocated(By.id(cardFormId)), wait), - ), + const cancelBtn = await e2eWaitElementVisible( + By.css(`#${cardFormId}__cancel-btn > span`), wait, ); - - await driver.findElement(By.css(`#${cardFormId}__cancel-btn > span`)).click(); + await driver + .actions({ bridge: true }) + .pause(200) + .move({ origin: cancelBtn }) + .pause(200) + .click() + .perform(); await driver.wait( until.elementIsNotVisible( @@ -187,20 +205,18 @@ export async function e2eActivateTableRowDropdownAction( actionSelection: string, wait: number = commonWaitDefault, ): Promise { - await driver - .wait( - until.elementLocated( - By.xpath( - `//div[@id='${tableId}']//table/tbody/tr/td[contains(.,'${rowId}')]/..//button[contains(.,'${actionButtonLabel}')]`, - ), + await ( + await e2eWaitElementVisible( + By.xpath( + `//div[@id='${tableId}']//table/tbody/tr/td[contains(.,'${rowId}')]/..//button[contains(.,'${actionButtonLabel}')]`, ), wait, ) - .click(); + ).click(); { - const element = await driver.wait( - until.elementLocated(By.xpath(`//li[contains(.,'${actionSelection}')]`)), + const element = await e2eWaitElementVisible( + By.xpath(`//li[contains(.,'${actionSelection}')]`), wait, ); await driver.wait(until.elementIsEnabled(element), wait); @@ -252,12 +268,11 @@ export async function e2eExecuteTableRowDropdownAction( ); { - const element = await driver.wait( - until.elementLocated( - By.xpath(`//button[contains(.,'${dialogButtonId}')]/span`), - ), + const element = await e2eWaitElementVisible( + By.xpath(`//button[contains(.,'${dialogButtonId}')]/span`), wait, ); + await driver .actions({ bridge: true }) .pause(200) @@ -305,86 +320,62 @@ export async function e2eExecuteTableRowRemoveAction( expectedMessage: string, wait: number = commonWaitDefault, ): Promise { - await driver - .wait( - until.elementLocated( - By.xpath( - `//div[@id='${tableId}']//table/tbody/tr/td[contains(.,'${rowId}')]/..//button[contains(.,'${removeButtonLabel}')]`, - ), + await ( + await e2eWaitElementVisible( + By.xpath( + `//div[@id='${tableId}']//table/tbody/tr/td[contains(.,'${rowId}')]/..//button[contains(.,'${removeButtonLabel}')]`, ), wait, ) - .click(); + ).click(); // Check Remove dialog appears - await driver.wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated( - By.xpath(`//span[contains(.,'${confirmDialogTitle}')]`), - ), - wait, - ), - ), + let element = await e2eWaitElementVisible( + By.xpath(`//span[contains(.,'${confirmDialogTitle}')]`), wait, ); - let button = await driver.wait( - until.elementLocated( + // Cancel out to make sure that works + await ( + await e2eWaitElementVisible( By.xpath( `//span[contains(.,'${confirmDialogTitle}')]/ancestor::div[@class='ant-modal-body']//span[contains(.,'${cancelButtonLabel}')]`, ), - ), - wait, - ); - - await button.click(); + wait, + ) + ).click(); - // Check Remove dialog disappears - { - await new Promise((r) => setTimeout(r, 3000)); - const elements = await driver.findElements( - By.xpath(`//span[contains(.,'${confirmDialogTitle}')]`), - ); - expect(elements.length).toBeFalsy(); - } + // Wait for message to dissapear to avoid artifact issues + // with subsequent UI actions + await driver.wait(until.stalenessOf(element), wait); - // Now execute the remove - await driver - .wait( - until.elementLocated( - By.xpath( - `//div[@id='${tableId}']//table/tbody/tr/td[contains(.,'${rowId}')]/..//button[contains(.,'${removeButtonLabel}')]`, - ), + await ( + await e2eWaitElementVisible( + By.xpath( + `//div[@id='${tableId}']//table/tbody/tr/td[contains(.,'${rowId}')]/..//button[contains(.,'${removeButtonLabel}')]`, ), wait, ) - .click(); + ).click(); - await driver.wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated( - By.xpath(`//span[contains(.,'${confirmDialogTitle}')]`), - ), - wait, - ), - ), + element = await e2eWaitElementVisible( + By.xpath(`//span[contains(.,'${confirmDialogTitle}')]`), wait, ); - button = await driver.wait( - until.elementLocated( + await ( + await e2eWaitElementVisible( By.xpath( `//span[contains(.,'${confirmDialogTitle}')]/ancestor::div[@class='ant-modal-body']//span[contains(.,'${confirmButtonLabel}')]`, ), - ), - wait, - ); - - await button.click(); + wait, + ) + ).click(); await e2eCheckMessageDisplays(expectedMessage, wait); + // Wait for message to dissapear to avoid artifact issues + // with subsequent UI actions + await driver.wait(until.stalenessOf(element), wait); // Make sure it was deleted from the table { @@ -396,3 +387,54 @@ export async function e2eExecuteTableRowRemoveAction( expect(elements.length).toBeFalsy(); } } + +/** + * Utility function to cancel the TAA dialog and check it goes away. + * Expects the TAA dialog is being or about to be displayed. + * + * @param {?number} wait an optional amount of time to use when waiting for + * elements to resolve when locating them. + */ +export async function e2eCancelTAAForm( + wait: number = commonWaitDefault, +): Promise { + // Check that the TAA is displayed + const taa = await e2eWaitElementVisible( + By.xpath("//span[contains(.,'Transaction Authors Agreement (TAA)')]"), + wait, + ); + + // Cancel out + await ( + await e2eWaitElementVisible( + By.css('#ModalTAAAcceptance__cancel-btn > span'), + wait, + ) + ).click(); + await driver.wait(until.stalenessOf(taa), wait); +} + +/** + * Utility function to Accept the TAA dialog. + * Expects the TAA dialog is being or about to be displayed. + * + * @param {?number} wait an optional amount of time to use when waiting for + * elements to resolve when locating them. + */ +export async function e2eAcceptTAAForm( + wait: number = commonWaitDefault, +): Promise { + // Check that the TAA is displayed + await e2eWaitElementVisible( + By.xpath("//span[contains(.,'Transaction Authors Agreement (TAA)')]"), + wait, + ); + + // Accept the TAA + await ( + await e2eWaitElementVisible( + By.css('#ModalTAAAcceptance__accept-btn > span'), + wait, + ) + ).click(); +} diff --git a/e2e/connectionHelpers.ts b/e2e/connectionHelpers.ts index 15c4788..e0b0786 100644 --- a/e2e/connectionHelpers.ts +++ b/e2e/connectionHelpers.ts @@ -1,5 +1,5 @@ import { By, until } from 'selenium-webdriver'; -import { e2eNavigateToCard } from './commonHelpers'; +import { e2eNavigateToCard, e2eWaitElementVisible } from './commonHelpers'; import { driver } from './setup-tests'; export const dcWaitDefault = 20000; @@ -25,41 +25,37 @@ export async function e2eNavigateToConnectionsCard(): Promise { * invitation. */ export async function e2eCreateInvitation(alias: string): Promise { - e2eNavigateToConnectionsCard(); - await driver - .wait( - until.elementLocated(By.css('#ConnectionsCard__create-btn > span')), + await e2eNavigateToConnectionsCard(); + await ( + await e2eWaitElementVisible( + By.css('#ConnectionsCard__create-btn > span'), dcWaitDefault, ) - .click(); + ).click(); - await driver.wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated(By.id('CreateInvitationForm')), - dcWaitDefault, - ), - ), + await e2eWaitElementVisible(By.id('CreateInvitationForm'), dcWaitDefault); + + const aliasElement = await e2eWaitElementVisible( + By.id('CreateInvitationForm_alias'), dcWaitDefault, ); + await driver - .wait( - until.elementLocated(By.css('#CreateInvitationForm #myAlias')), - dcWaitDefault, - ) - .click(); - await driver - .wait( - until.elementLocated(By.css('#CreateInvitationForm #myAlias')), - dcWaitDefault, - ) - .sendKeys(alias); - await driver - .wait( - until.elementLocated(By.css('#CreateInvitationForm__submit-btn > span')), + .actions({ bridge: true }) + .pause(500) + .move({ origin: aliasElement }) + .pause(500) + .click() + .pause(500) + .sendKeys(alias) + .perform(); + + await ( + await e2eWaitElementVisible( + By.css('#CreateInvitationForm__submit-btn > span'), dcWaitDefault, ) - .click(); + ).click(); await driver.wait( until.elementIsNotVisible( @@ -73,43 +69,30 @@ export async function e2eCreateInvitation(alias: string): Promise { // Make sure the invitation is created and displayed in the // modal dialog - await driver.wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated( - By.xpath("//span[contains(.,'Invitation Details')]"), - ), - dcWaitDefault, - ), - ), + const invitation = await e2eWaitElementVisible( + By.xpath("//span[contains(.,'Invitation Details')]"), dcWaitDefault, ); // Get the invitation text to return. - const invitationText = await driver - .wait(until.elementLocated(By.xpath('//pre')), dcWaitDefault) - .getText(); + const invitationText = await ( + await driver.wait(until.elementLocated(By.xpath('//pre')), dcWaitDefault) + ).getText(); // Clear the confirm dialog - await driver - .wait( - until.elementLocated(By.xpath("//span[contains(.,'Ok')]")), + await ( + await e2eWaitElementVisible( + By.xpath("//span[contains(.,'Ok')]"), dcWaitDefault, ) - .click(); + ).click(); // Make sure the dialog dissapears - { - await new Promise((r) => setTimeout(r, 3000)); - const elements = await driver.findElements( - By.xpath("//span[contains(.,'Invitation Details')]"), - ); - expect(elements.length).toBeFalsy(); - } + await driver.wait(until.stalenessOf(invitation), dcWaitDefault); // Check the invitation appears in the list - await driver.wait( - until.elementLocated(By.xpath(`//td[contains(.,'${alias}')]`)), + await e2eWaitElementVisible( + By.xpath(`//td[contains(.,'${alias}')]`), dcWaitDefault, ); @@ -128,55 +111,55 @@ export async function e2eAcceptInvitation( alias: string, invitation: string, ): Promise { - e2eNavigateToConnectionsCard(); + await e2eNavigateToConnectionsCard(); // Input the invitation into the acceptance dialog - await driver - .wait( - until.elementIsEnabled( - await driver.wait( - until.elementLocated(By.css('#ConnectionsCard__accept-btn > span')), - dcWaitDefault, - ), - ), + await ( + await e2eWaitElementVisible( + By.css('#ConnectionsCard__accept-btn > span'), + dcWaitDefault, ) - .click(); + ).click(); - await driver.wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated(By.id('AcceptInvitationForm')), - dcWaitDefault, - ), - ), + await e2eWaitElementVisible(By.id('AcceptInvitationForm'), dcWaitDefault); + + const aliasElement = await e2eWaitElementVisible( + By.id('AcceptInvitationForm_alias'), dcWaitDefault, ); + + await driver.wait(until.elementIsEnabled(aliasElement), dcWaitDefault); await driver - .wait( - until.elementLocated(By.css('#AcceptInvitationForm #myAlias')), - dcWaitDefault, - ) - .click(); - await driver - .wait( - until.elementLocated(By.css('#AcceptInvitationForm #myAlias')), - dcWaitDefault, - ) - .sendKeys(alias); - await driver - .wait(until.elementLocated(By.id('invitation_input')), dcWaitDefault) - .click(); + .actions({ bridge: true }) + .pause(500) + .move({ origin: aliasElement }) + .pause(500) + .click() + .pause(500) + .sendKeys(alias) + .perform(); + + const textElement = await e2eWaitElementVisible( + By.id('AcceptInvitationForm_invitation'), + dcWaitDefault, + ); await driver - .wait(until.elementLocated(By.id('invitation_input')), dcWaitDefault) - .sendKeys(invitation); + .actions({ bridge: true }) + .pause(500) + .move({ origin: textElement }) + .pause(500) + .click() + .pause(500) + .sendKeys(invitation) + .perform(); // Accept invitation and make sure review dialog displayed - await driver - .wait( - until.elementLocated(By.css('#AcceptInvitationForm__submit-btn > span')), + await ( + await e2eWaitElementVisible( + By.css('#AcceptInvitationForm__submit-btn > span'), dcWaitDefault, ) - .click(); + ).click(); await driver.wait( until.elementIsNotVisible( @@ -188,24 +171,22 @@ export async function e2eAcceptInvitation( dcWaitDefault, ); - await driver.wait( - until.elementLocated(By.xpath("//span[contains(.,'Invitation Details')]")), + await e2eWaitElementVisible( + By.xpath("//span[contains(.,'Invitation Details')]"), dcWaitDefault, ); // Complete connection set up - await driver - .wait( - until.elementLocated( - By.css('.ant-modal-confirm-btns > .ant-btn-primary > span'), - ), + await ( + await e2eWaitElementVisible( + By.css('.ant-modal-confirm-btns > .ant-btn-primary > span'), dcWaitDefault, ) - .click(); + ).click(); // Check the invitation appears in the list - await driver.wait( - until.elementLocated(By.xpath(`//td[contains(.,'${alias}')]`)), + await e2eWaitElementVisible( + By.xpath(`//td[contains(.,'${alias}')]`), dcWaitDefault, ); } diff --git a/e2e/connections.test.ts b/e2e/connections.test.ts index d761614..2363d1f 100644 --- a/e2e/connections.test.ts +++ b/e2e/connections.test.ts @@ -3,6 +3,7 @@ import { e2eExecuteTableRowRemoveAction, e2eHoverOverCardInfoIcon, e2eInitiateThenCancelCardForm, + e2eWaitElementVisible, } from './commonHelpers'; import { e2eNavigateToConnectionsCard, @@ -32,26 +33,21 @@ describe('Connections', function () { it('DC-0011 Initiate invitation acceptance then cancel dialog', async function () { await e2eNavigateToConnectionsCard(); - await driver - .wait( - until.elementLocated(By.css('#ConnectionsCard__accept-btn > span')), + await ( + await e2eWaitElementVisible( + By.css('#ConnectionsCard__accept-btn > span'), dcWaitDefault, ) - .click(); + ).click(); - await driver.wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated(By.id('AcceptInvitationForm')), - dcWaitDefault, - ), - ), - dcWaitDefault, - ); + await e2eWaitElementVisible(By.id('AcceptInvitationForm'), dcWaitDefault); - await driver - .findElement(By.css('#AcceptInvitationForm__cancel-btn > span')) - .click(); + await ( + await e2eWaitElementVisible( + By.css('#AcceptInvitationForm__cancel-btn > span'), + dcWaitDefault, + ) + ).click(); await driver.wait( until.elementIsNotVisible( @@ -90,22 +86,14 @@ describe('Connections', function () { it('DC-0201 Attempt invalid create invitation without label', async function () { await e2eNavigateToConnectionsCard(); - await driver - .wait( - until.elementLocated(By.css('#ConnectionsCard__create-btn > span')), + await ( + await e2eWaitElementVisible( + By.css('#ConnectionsCard__create-btn > span'), dcWaitDefault, ) - .click(); + ).click(); - await driver.wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated(By.id('CreateInvitationForm')), - dcWaitDefault, - ), - ), - dcWaitDefault, - ); + await e2eWaitElementVisible(By.id('CreateInvitationForm'), dcWaitDefault); // Make sure error text field is not initially displayed { @@ -114,52 +102,42 @@ describe('Connections', function () { ); expect(elements.length).toBeFalsy(); } - await driver - .wait( - until.elementLocated( - By.css('#CreateInvitationForm__submit-btn > span'), - ), + + await ( + await e2eWaitElementVisible( + By.css('#CreateInvitationForm__submit-btn > span'), dcWaitDefault, ) - .click(); + ).click(); + // Check that error text field is displayed - const errorText = await driver - .wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated(By.css('.ant-form-item-explain > div')), - dcWaitDefault, - ), - ), + const errorText = await ( + await e2eWaitElementVisible( + By.css('.ant-form-item-explain > div'), dcWaitDefault, ) - .getText(); + ).getText(); expect(errorText).toContain('Please provide a label'); - await driver - .findElement(By.css('#CreateInvitationForm__cancel-btn > span')) - .click(); + await ( + await e2eWaitElementVisible( + By.css('#CreateInvitationForm__cancel-btn > span'), + dcWaitDefault, + ) + ).click(); }); it('DC-0202 Attempt invalid accept invitation without label', async function () { await e2eNavigateToConnectionsCard(); - await driver - .wait( - until.elementLocated(By.css('#ConnectionsCard__accept-btn > span')), + + await ( + await e2eWaitElementVisible( + By.css('#ConnectionsCard__accept-btn > span'), dcWaitDefault, ) - .click(); - - await driver.wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated(By.id('AcceptInvitationForm')), - dcWaitDefault, - ), - ), - dcWaitDefault, - ); + ).click(); + await e2eWaitElementVisible(By.id('AcceptInvitationForm'), dcWaitDefault); // Make sure error text field is not initially displayed { @@ -168,31 +146,28 @@ describe('Connections', function () { ); expect(elements.length).toBeFalsy(); } - await driver - .wait( - until.elementLocated( - By.css('#AcceptInvitationForm__submit-btn > span'), - ), + + await ( + await e2eWaitElementVisible( + By.css('#AcceptInvitationForm__submit-btn > span'), dcWaitDefault, ) - .click(); + ).click(); + // Check that error text field is displayed - const errorText = await driver - .wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated(By.css('.ant-form-item-explain > div')), - dcWaitDefault, - ), - ), + const errorText = await ( + await e2eWaitElementVisible( + By.css('.ant-form-item-explain > div'), dcWaitDefault, ) - .getText(); - + ).getText(); expect(errorText).toContain('Please provide a label'); - await driver - .findElement(By.css('#AcceptInvitationForm__cancel-btn > span')) - .click(); + await ( + await e2eWaitElementVisible( + By.css('#AcceptInvitationForm__cancel-btn > span'), + dcWaitDefault, + ) + ).click(); }); }); diff --git a/e2e/credentialDefinition.test.ts b/e2e/credentialDefinition.test.ts index 60752f5..4beec37 100644 --- a/e2e/credentialDefinition.test.ts +++ b/e2e/credentialDefinition.test.ts @@ -1,7 +1,8 @@ -import { By, until } from 'selenium-webdriver'; +import { By } from 'selenium-webdriver'; import { e2eHoverOverCardInfoIcon, e2eInitiateThenCancelCardForm, + e2eWaitElementVisible, } from './commonHelpers'; import { e2eCreateCredentialDefinition } from './credentialDefinitionHelpers'; import { @@ -45,42 +46,41 @@ describe('Credential Definition', function () { it('CD-0201 Attempt invalid create credential definition without name or schema', async function () { await e2eNavigateToCredentialDefinitionsCard(); - await driver - .wait( - until.elementLocated( - By.css('#CredentialDefinitionsCard__create-btn > span'), - ), + await ( + await e2eWaitElementVisible( + By.css('#CredentialDefinitionsCard__create-btn > span'), cdWaitDefault, ) - .click(); - await driver.wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated(By.id('CreateCredentialDefinitionForm')), - cdWaitDefault, - ), - ), + ).click(); + + await e2eWaitElementVisible( + By.id('CreateCredentialDefinitionForm'), cdWaitDefault, ); + // Try submit with no data and make sure the two mandatory fields present // an error. - await driver - .findElement(By.css('#CreateCredentialDefinitionForm__submit-btn > span')) - .click(); - await driver.wait( - until.elementLocated( - By.css('.ant-row:nth-child(2) .ant-form-item-explain'), - ), + await ( + await e2eWaitElementVisible( + By.css('#CreateCredentialDefinitionForm__submit-btn > span'), + cdWaitDefault, + ) + ).click(); + + await e2eWaitElementVisible( + By.css('.ant-row:nth-child(2) .ant-form-item-explain'), cdWaitDefault, ); - await driver.wait( - until.elementLocated( - By.css('.ant-row:nth-child(1) .ant-form-item-explain'), - ), + + await e2eWaitElementVisible( + By.css('.ant-row:nth-child(1) .ant-form-item-explain'), cdWaitDefault, ); - await driver - .findElement(By.css('#CreateCredentialDefinitionForm__cancel-btn > span')) - .click(); + + await ( + await driver.findElement( + By.css('#CreateCredentialDefinitionForm__cancel-btn > span'), + ) + ).click(); }); }); diff --git a/e2e/credentialDefinitionHelpers.ts b/e2e/credentialDefinitionHelpers.ts index e17fed6..1b1a6a2 100644 --- a/e2e/credentialDefinitionHelpers.ts +++ b/e2e/credentialDefinitionHelpers.ts @@ -1,5 +1,10 @@ import { By, until } from 'selenium-webdriver'; -import { e2eCheckMessageDisplays, e2eNavigateToCard } from './commonHelpers'; +import { + e2eAcceptTAAForm, + e2eCheckMessageDisplays, + e2eNavigateToCard, + e2eWaitElementVisible, +} from './commonHelpers'; import { driver } from './setup-tests'; export const cdWaitDefault = 40000; @@ -31,34 +36,39 @@ export async function e2eCreateCredentialDefinition( ): Promise { await e2eNavigateToCredentialDefinitionsCard(); - await driver - .findElement(By.css('#CredentialDefinitionsCard__create-btn > span')) - .click(); + await ( + await e2eWaitElementVisible( + By.css('#CredentialDefinitionsCard__create-btn > span'), + cdWaitDefault, + ) + ).click(); - await driver.wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated(By.id('CreateCredentialDefinitionForm')), - cdWaitDefault, - ), - ), + await e2eWaitElementVisible( + By.id('CreateCredentialDefinitionForm'), cdWaitDefault, ); - await driver.findElement(By.id('tag')).click(); - await driver.findElement(By.id('tag')).sendKeys(name); - await driver.findElement(By.id('schemaId')).click(); + await (await driver.findElement(By.id('tag'))).click(); + await (await driver.findElement(By.id('tag'))).sendKeys(name); + await (await driver.findElement(By.id('schemaId'))).click(); // Use the SchemaId from our created schema - await driver.findElement(By.id('schemaId')).sendKeys(schemaId); - await driver - .findElement(By.css('#CreateCredentialDefinitionForm__submit-btn > span')) - .click(); + await (await driver.findElement(By.id('schemaId'))).sendKeys(schemaId); + + await ( + await e2eWaitElementVisible( + By.css('#CreateCredentialDefinitionForm__submit-btn > span'), + cdWaitDefault, + ) + ).click(); + + await e2eAcceptTAAForm(cdWaitDefault); await e2eCheckMessageDisplays( 'Credential Definition Created!', cdWaitDefault, ); + // Verify the credential has been put into the table await driver.wait( until.elementLocated(By.xpath(`//td[contains(.,'${name}')]`)), cdWaitDefault, diff --git a/e2e/credentialIssuance.test.ts b/e2e/credentialIssuance.test.ts index a1a2d43..812440c 100644 --- a/e2e/credentialIssuance.test.ts +++ b/e2e/credentialIssuance.test.ts @@ -1,9 +1,10 @@ -import { By, until } from 'selenium-webdriver'; +import { By } from 'selenium-webdriver'; import { e2eExecuteTableRowDropdownAction, e2eExecuteTableRowRemoveAction, e2eHoverOverCardInfoIcon, e2eInitiateThenCancelCardForm, + e2eWaitElementVisible, } from './commonHelpers'; import { e2eAcceptInvitation, e2eCreateInvitation } from './connectionHelpers'; import { e2eCreateCredentialDefinition } from './credentialDefinitionHelpers'; @@ -172,47 +173,34 @@ describe('Credential Issuance', function () { it('CI-0201 Attempt invalid credential request without attributes', async function () { await e2eNavigateToRequestedCredentialsCard(); - await driver - .wait( - until.elementLocated(By.css('#CredentialRequestsCard__new-btn > span')), + await ( + await e2eWaitElementVisible( + By.css('#CredentialRequestsCard__new-btn > span'), ciWaitDefault, ) - .click(); - - await driver.wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated(By.id('ProposeCredentialForm')), - ciWaitDefault, - ), - ), - ciWaitDefault, - ); + ).click(); + await e2eWaitElementVisible(By.id('ProposeCredentialForm'), ciWaitDefault); // Submit and check error text is displayed - await driver - .wait( - until.elementLocated( - By.css('#ProposeCredentialForm__submit-btn > span'), - ), + await ( + await e2eWaitElementVisible( + By.css('#ProposeCredentialForm__submit-btn > span'), ciWaitDefault, ) - .click(); + ).click(); - await driver.wait( - until.elementLocated( - By.css('.ant-row:nth-child(1) .ant-form-item-explain'), - ), + await e2eWaitElementVisible( + By.css('.ant-row:nth-child(1) .ant-form-item-explain'), ciWaitDefault, ); - await driver.wait( - until.elementLocated( - By.css('.ant-row:nth-child(3) .ant-form-item-explain'), - ), + await e2eWaitElementVisible( + By.css('.ant-row:nth-child(3) .ant-form-item-explain'), ciWaitDefault, ); - await driver - .findElement(By.css('#ProposeCredentialForm__cancel-btn > span')) - .click(); + await ( + await driver.findElement( + By.css('#ProposeCredentialForm__cancel-btn > span'), + ) + ).click(); }); }); diff --git a/e2e/credentialIssuanceHelpers.ts b/e2e/credentialIssuanceHelpers.ts index 87ea82d..a606f18 100644 --- a/e2e/credentialIssuanceHelpers.ts +++ b/e2e/credentialIssuanceHelpers.ts @@ -78,12 +78,12 @@ export async function e2eEnterCredentialProposalDetails( attributes: { name: string; value: string }[], ): Promise { await e2eNavigateToRequestedCredentialsCard(); - await driver - .wait( + await ( + await driver.wait( until.elementLocated(By.css('#CredentialRequestsCard__new-btn > span')), ciWaitDefault, ) - .click(); + ).click(); await driver.wait( until.elementIsVisible( @@ -95,25 +95,28 @@ export async function e2eEnterCredentialProposalDetails( ciWaitDefault, ); - await driver - .wait(until.elementLocated(By.id('schemaId')), ciWaitDefault) - .click(); - await driver - .wait(until.elementLocated(By.id('schemaId')), ciWaitDefault) - .sendKeys(schemaId); - await driver - .wait(until.elementLocated(By.id('message')), ciWaitDefault) - .click(); - await driver - .wait(until.elementLocated(By.id('message')), ciWaitDefault) - .sendKeys(message); + await ( + await driver.wait(until.elementLocated(By.id('schemaId')), ciWaitDefault) + ).click(); - await driver - .wait( + await ( + await driver.wait(until.elementLocated(By.id('schemaId')), ciWaitDefault) + ).sendKeys(schemaId); + + await ( + await driver.wait(until.elementLocated(By.id('message')), ciWaitDefault) + ).click(); + + await ( + await driver.wait(until.elementLocated(By.id('message')), ciWaitDefault) + ).sendKeys(message); + + await ( + await driver.wait( until.elementLocated(By.xpath("//input[@id='DIDCommSelections']/../..")), ciWaitDefault, ) - .click(); + ).click(); { // Move mouse over selection @@ -136,18 +139,18 @@ export async function e2eEnterCredentialProposalDetails( } for (let i = 0; i < attributes.length; i++) { - await driver - .wait( + await ( + await driver.wait( until.elementLocated(By.id(`attribute_${attributes[i].name}`)), ciWaitDefault, ) - .click(); - await driver - .wait( + ).click(); + await ( + await driver.wait( until.elementLocated(By.id(`attribute_${attributes[i].name}`)), ciWaitDefault, ) - .sendKeys(attributes[i].value); + ).sendKeys(attributes[i].value); } } @@ -179,12 +182,12 @@ export async function e2eSendCredentialProposal( attributes, ); - await driver - .wait( + await ( + await driver.wait( until.elementLocated(By.css('#ProposeCredentialForm__submit-btn > span')), ciWaitDefault, ) - .click(); + ).click(); await driver.wait( until.elementIsNotVisible( @@ -210,14 +213,14 @@ export async function e2eSendCredentialProposal( // Get the thread id to use in looking up the // credential proposal in the issuer - const credentialThread = await driver - .wait( + const credentialThread = await ( + await driver.wait( until.elementLocated( By.xpath(`//td[contains(.,'${connectionAlias}')]/../td[2]`), ), ciWaitDefault, ) - .getText(); + ).getText(); return credentialThread; } diff --git a/e2e/decentralizedIdentifiers.test.ts b/e2e/decentralizedIdentifiers.test.ts index 125d60a..9d4fdb4 100644 --- a/e2e/decentralizedIdentifiers.test.ts +++ b/e2e/decentralizedIdentifiers.test.ts @@ -1,5 +1,11 @@ import { By, until } from 'selenium-webdriver'; -import { e2eHoverOverCardInfoIcon } from './commonHelpers'; +import { + e2eAcceptTAAForm, + e2eCancelTAAForm, + e2eCheckMessageDisplays, + e2eHoverOverCardInfoIcon, + e2eWaitElementVisible, +} from './commonHelpers'; import { createPrivateDID, didWaitDefault, @@ -20,22 +26,26 @@ describe('Decentralized Identifiers', function () { it('DI-0010 Initiate private did creation then cancel dialog', async function () { await e2eNavigateToDIDCard(); // Activate the create DID dialog button - await driver - .findElement(By.css('#DecentralizedIdentifiersCard__create-btn > span')) - .click(); + await ( + await e2eWaitElementVisible( + By.css('#DecentralizedIdentifiersCard__create-btn > span'), + didWaitDefault, + ) + ).click(); + // Make sure the dialog appears - await driver.wait( - until.elementIsVisible( - await driver.findElement(By.css('.ant-modal-confirm-title')), - ), + await e2eWaitElementVisible( + By.css('.ant-modal-confirm-title'), didWaitDefault, ); // Cancel create dialog - await driver - .findElement( + await ( + await e2eWaitElementVisible( By.css('#DecentralizedIdentifiersCard__create-cancel-btn > span'), + didWaitDefault, ) - .click(); + ).click(); + // Make sure the dialog dissapears await driver.wait( until.stalenessOf( @@ -53,21 +63,30 @@ describe('Decentralized Identifiers', function () { it('DI-0103 Write private DID to Ledger', async function () { // We make sure there is at least one writeable DID since we don't know what order tests will be run in await createPrivateDID(); - // Use the side nav to get to the DID tab - await driver - .wait( - until.elementLocated(By.linkText('Decentralized Identifiers')), + // Locate an unwritten DID row in the table and activate write to ledger dialog + await ( + await e2eWaitElementVisible( + By.xpath("//span[contains(.,'Write to Ledger')]"), didWaitDefault, ) - .click(); + ).click(); + + await e2eCancelTAAForm(didWaitDefault); + // Locate an unwritten DID row in the table and activate write to ledger dialog - await driver - .wait( - until.elementLocated(By.xpath("//span[contains(.,'Write to Ledger')]")), + await ( + await e2eWaitElementVisible( + By.xpath("//span[contains(.,'Write to Ledger')]"), didWaitDefault, ) - .click(); - // NOTE: Need a way to verify that the written row changes button to non-selectable - // and text to indicate written + ).click(); + + await e2eAcceptTAAForm(didWaitDefault); + + // Check we get a success message + await e2eCheckMessageDisplays( + 'Decentralized Identifier written to public ledger', + didWaitDefault, + ); }); }); diff --git a/e2e/decentralizedIdentifiersHelpers.ts b/e2e/decentralizedIdentifiersHelpers.ts index b6a04cf..346d68d 100644 --- a/e2e/decentralizedIdentifiersHelpers.ts +++ b/e2e/decentralizedIdentifiersHelpers.ts @@ -1,10 +1,10 @@ import { By, until } from 'selenium-webdriver'; -import { e2eNavigateToCard } from './commonHelpers'; +import { e2eNavigateToCard, e2eWaitElementVisible } from './commonHelpers'; import { driver } from './setup-tests'; export const didWaitDefault = 20000; -/** +/** * Utility function to navigate to the Decenteralized Identifiers card * and verify presence. */ @@ -23,20 +23,24 @@ export async function e2eNavigateToDIDCard(): Promise { export async function createPrivateDID(): Promise { await e2eNavigateToDIDCard(); // Activate the create DID dialog button - await driver - .findElement(By.css('#DecentralizedIdentifiersCard__create-btn > span')) - .click(); + await ( + await e2eWaitElementVisible( + By.css('#DecentralizedIdentifiersCard__create-btn > span'), + didWaitDefault, + ) + ).click(); // Make sure the dialog appears - await driver.wait( - until.elementIsVisible( - await driver.findElement(By.css('.ant-modal-confirm-title')), - ), + await e2eWaitElementVisible( + By.css('.ant-modal-confirm-title'), didWaitDefault, ); // Initiate the create - await driver - .findElement(By.css('#DecentralizedIdentifiersCard__create-ok-btn > span')) - .click(); + await ( + await e2eWaitElementVisible( + By.css('#DecentralizedIdentifiersCard__create-ok-btn > span'), + didWaitDefault, + ) + ).click(); // Make sure the dialog completes. // NOTE: Need mechanism to check table gets an extra DID await driver.wait( diff --git a/e2e/proofPresentation.test.ts b/e2e/proofPresentation.test.ts index d1a5de4..2c97bd0 100644 --- a/e2e/proofPresentation.test.ts +++ b/e2e/proofPresentation.test.ts @@ -1,9 +1,10 @@ -import { By, until } from 'selenium-webdriver'; +import { By } from 'selenium-webdriver'; import { e2eExecuteTableRowDropdownAction, e2eExecuteTableRowRemoveAction, e2eHoverOverCardInfoIcon, e2eInitiateThenCancelCardForm, + e2eWaitElementVisible, } from './commonHelpers'; import { e2eAcceptInvitation, e2eCreateInvitation } from './connectionHelpers'; import { e2eCreateCredentialDefinition } from './credentialDefinitionHelpers'; @@ -212,47 +213,35 @@ describe('Proof Presentation', function () { it('PP-0201 Attempt invalid proof request without attributes', async function () { await e2eNavigateToVerifierActiveProofRequestsCard(); - await driver - .wait( - until.elementLocated( - By.css('#ActiveProofRequestsCard__new-btn > span'), - ), + await ( + await e2eWaitElementVisible( + By.css('#ActiveProofRequestsCard__new-btn > span'), ppWaitDefault, ) - .click(); + ).click(); - await driver.wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated(By.id('RequestProofForm')), - ppWaitDefault, - ), - ), - ppWaitDefault, - ); + await e2eWaitElementVisible(By.id('RequestProofForm'), ppWaitDefault); // Submit and check error text is displayed - await driver - .wait( - until.elementLocated(By.css('#RequestProofForm__submit-btn > span')), + await ( + await e2eWaitElementVisible( + By.css('#RequestProofForm__submit-btn > span'), ppWaitDefault, ) - .click(); + ).click(); - await driver.wait( - until.elementLocated( - By.css('.ant-row:nth-child(1) .ant-form-item-explain'), - ), + await e2eWaitElementVisible( + By.css('.ant-row:nth-child(1) .ant-form-item-explain'), ppWaitDefault, ); - await driver.wait( - until.elementLocated( - By.css('.ant-row:nth-child(3) .ant-form-item-explain'), - ), + + await e2eWaitElementVisible( + By.css('.ant-row:nth-child(3) .ant-form-item-explain'), ppWaitDefault, ); - await driver - .findElement(By.css('#RequestProofForm__cancel-btn > span')) - .click(); + + await ( + await driver.findElement(By.css('#RequestProofForm__cancel-btn > span')) + ).click(); }); }); diff --git a/e2e/proofPresentationHelpers.ts b/e2e/proofPresentationHelpers.ts index a65117d..2d277cd 100644 --- a/e2e/proofPresentationHelpers.ts +++ b/e2e/proofPresentationHelpers.ts @@ -79,12 +79,12 @@ export async function e2eEnterProofRequestDetails( attributes: { name: string; toggleRequired: boolean }[], ): Promise { await e2eNavigateToVerifierActiveProofRequestsCard(); - await driver - .wait( + await ( + await driver.wait( until.elementLocated(By.css('#ActiveProofRequestsCard__new-btn > span')), ppWaitDefault, ) - .click(); + ).click(); await driver.wait( until.elementIsVisible( @@ -96,25 +96,25 @@ export async function e2eEnterProofRequestDetails( ppWaitDefault, ); - await driver - .wait(until.elementLocated(By.id('schemaId')), ppWaitDefault) - .click(); - await driver - .wait(until.elementLocated(By.id('schemaId')), ppWaitDefault) - .sendKeys(schemaId); - await driver - .wait(until.elementLocated(By.id('message')), ppWaitDefault) - .click(); - await driver - .wait(until.elementLocated(By.id('message')), ppWaitDefault) - .sendKeys(message); + await ( + await driver.wait(until.elementLocated(By.id('schemaId')), ppWaitDefault) + ).click(); + await ( + await driver.wait(until.elementLocated(By.id('schemaId')), ppWaitDefault) + ).sendKeys(schemaId); + await ( + await driver.wait(until.elementLocated(By.id('message')), ppWaitDefault) + ).click(); + await ( + await driver.wait(until.elementLocated(By.id('message')), ppWaitDefault) + ).sendKeys(message); - await driver - .wait( + await ( + await driver.wait( until.elementLocated(By.xpath("//input[@id='DIDCommSelections']/../..")), ppWaitDefault, ) - .click(); + ).click(); { // Move mouse over selection @@ -146,7 +146,7 @@ export async function e2eEnterProofRequestDetails( ), ppWaitDefault, ); - checkBox.click(); + await checkBox.click(); } } } @@ -178,12 +178,12 @@ export async function e2eSendProofRequest( attributes, ); - await driver - .wait( + await ( + await driver.wait( until.elementLocated(By.css('#RequestProofForm__submit-btn > span')), ppWaitDefault, ) - .click(); + ).click(); await driver.wait( until.elementIsNotVisible( @@ -207,14 +207,14 @@ export async function e2eSendProofRequest( // Get the thread id to use in looking up the // proof request in future actions - const proofRequestThread = await driver - .wait( + const proofRequestThread = await ( + await driver.wait( until.elementLocated( By.xpath(`//td[contains(.,'${connectionAlias}')]/../td[2]`), ), ppWaitDefault, ) - .getText(); + ).getText(); return proofRequestThread; } @@ -272,7 +272,7 @@ export async function e2eEnterProofPresentationDetails( } if (attributes[i].toggleReveal) { - checkBox.click(); + await checkBox.click(); } } } @@ -296,14 +296,14 @@ export async function e2eSendProofPresentation( ): Promise { await e2eEnterProofPresentationDetails(proofThreadId, attributes); - await driver - .wait( + await ( + await driver.wait( until.elementLocated( By.css('#PreparePresentationForm__submit-btn > span'), ), ppWaitDefault, ) - .click(); + ).click(); await driver.wait( until.elementIsNotVisible( diff --git a/e2e/schemaDefinition.test.ts b/e2e/schemaDefinition.test.ts index e17d6c0..1b5d190 100644 --- a/e2e/schemaDefinition.test.ts +++ b/e2e/schemaDefinition.test.ts @@ -2,6 +2,7 @@ import { By, until } from 'selenium-webdriver'; import { e2eHoverOverCardInfoIcon, e2eInitiateThenCancelCardForm, + e2eWaitElementVisible, } from './commonHelpers'; import { e2eCreateSchemaDefinition, @@ -52,22 +53,22 @@ describe('Schema Definition', function () { 'state', ]); - await driver - .wait(until.elementLocated(By.linkText('2')), sdWaitDefault) - .click(); + await ( + await e2eWaitElementVisible(By.linkText('2'), sdWaitDefault) + ).click(); + // Check that the overflow page has the expected attribute - await driver.wait( - until.elementLocated(By.xpath("//td[contains(.,'suburb')]")), + await e2eWaitElementVisible( + By.xpath("//td[contains(.,'suburb')]"), sdWaitDefault, ); - await driver - .wait( - until.elementLocated( - By.css('#CreateSchemaDefinitionForm__cancel-btn > span'), - ), + + await ( + await e2eWaitElementVisible( + By.css('#CreateSchemaDefinitionForm__cancel-btn > span'), sdWaitDefault, ) - .click(); + ).click(); }); it('SD-0104 Initiate valid basic schema with one attribute then delete attribute', async function () { @@ -75,48 +76,47 @@ describe('Schema Definition', function () { 'licenseNumber', ]); - await driver - .wait( - until.elementLocated(By.xpath("//button[contains(.,'Remove')]")), + await ( + await e2eWaitElementVisible( + By.xpath("//button[contains(.,'Remove')]"), sdWaitDefault, ) - .click(); + ).click(); + // Need a way to check that the attribute table is now empty - await driver - .wait( - until.elementLocated( - By.css('#CreateSchemaDefinitionForm__cancel-btn > span'), - ), + await ( + await e2eWaitElementVisible( + By.css('#CreateSchemaDefinitionForm__cancel-btn > span'), sdWaitDefault, ) - .click(); + ).click(); }); it('SD-0201 Attempt invalid create schema without name', async function () { await e2eNavigateToSchemaCard(); - await driver - .wait( - until.elementLocated( - By.css('#SchemaDefinitionsCard__create-btn > span'), - ), + await ( + await e2eWaitElementVisible( + By.css('#SchemaDefinitionsCard__create-btn > span'), sdWaitDefault, ) - .click(); - await driver.wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated(By.id('CreateSchemaDefinitionForm')), - sdWaitDefault, - ), - ), + ).click(); + + await e2eWaitElementVisible( + By.id('CreateSchemaDefinitionForm'), sdWaitDefault, ); - await driver - .wait(until.elementLocated(By.id('schemaVersion')), sdWaitDefault) - .click(); - await driver - .wait(until.elementLocated(By.id('schemaVersion')), sdWaitDefault) - .sendKeys('0.1'); + await ( + await driver.wait( + until.elementLocated(By.id('schemaVersion')), + sdWaitDefault, + ) + ).click(); + await ( + await driver.wait( + until.elementLocated(By.id('schemaVersion')), + sdWaitDefault, + ) + ).sendKeys('0.1'); // Make sure error text field is not initially displayed { const elements = await driver.findElements( @@ -124,36 +124,35 @@ describe('Schema Definition', function () { ); expect(elements.length).toBeFalsy(); } - await driver - .findElement(By.css('#CreateSchemaDefinitionForm__submit-btn > span')) - .click(); + await ( + await e2eWaitElementVisible( + By.css('#CreateSchemaDefinitionForm__submit-btn > span'), + sdWaitDefault, + ) + ).click(); // Check that error text field is displayed - await driver.wait( - until.elementLocated(By.css('.ant-form-item-explain > div')), - 10000, + await e2eWaitElementVisible( + By.css('.ant-form-item-explain > div'), + sdWaitDefault, ); - await driver - .findElement(By.css('#CreateSchemaDefinitionForm__cancel-btn > span')) - .click(); + + await ( + await driver.findElement( + By.css('#CreateSchemaDefinitionForm__cancel-btn > span'), + ) + ).click(); }); it('SD-0202 Input invalid schema version and check validation fails', async function () { await e2eNavigateToSchemaCard(); - await driver - .wait( - until.elementLocated( - By.css('#SchemaDefinitionsCard__create-btn > span'), - ), + await ( + await e2eWaitElementVisible( + By.css('#SchemaDefinitionsCard__create-btn > span'), sdWaitDefault, ) - .click(); - await driver.wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated(By.id('CreateSchemaDefinitionForm')), - sdWaitDefault, - ), - ), + ).click(); + await e2eWaitElementVisible( + By.id('CreateSchemaDefinitionForm'), sdWaitDefault, ); // Make sure error text field is not initially displayed @@ -163,19 +162,27 @@ describe('Schema Definition', function () { ); expect(elements.length).toBeFalsy(); } - await driver - .wait(until.elementLocated(By.id('schemaVersion')), sdWaitDefault) - .click(); - await driver - .wait(until.elementLocated(By.id('schemaVersion')), sdWaitDefault) - .sendKeys('x.1'); + await ( + await driver.wait( + until.elementLocated(By.id('schemaVersion')), + sdWaitDefault, + ) + ).click(); + await ( + await driver.wait( + until.elementLocated(By.id('schemaVersion')), + sdWaitDefault, + ) + ).sendKeys('x.1'); // Check that error text field is displayed - await driver.wait( - until.elementLocated(By.css('.ant-form-item-explain > div')), - 10000, + await e2eWaitElementVisible( + By.css('.ant-form-item-explain > div'), + sdWaitDefault, ); - await driver - .findElement(By.css('#CreateSchemaDefinitionForm__cancel-btn > span')) - .click(); + await ( + await driver.findElement( + By.css('#CreateSchemaDefinitionForm__cancel-btn > span'), + ) + ).click(); }); }); diff --git a/e2e/schemaDefinitionHelpers.ts b/e2e/schemaDefinitionHelpers.ts index 3891040..5d0de9f 100644 --- a/e2e/schemaDefinitionHelpers.ts +++ b/e2e/schemaDefinitionHelpers.ts @@ -1,5 +1,10 @@ import { By, Key, until } from 'selenium-webdriver'; -import { e2eCheckMessageDisplays, e2eNavigateToCard } from './commonHelpers'; +import { + e2eAcceptTAAForm, + e2eCheckMessageDisplays, + e2eNavigateToCard, + e2eWaitElementVisible, +} from './commonHelpers'; import { driver } from './setup-tests'; export const sdWaitDefault = 20000; @@ -28,17 +33,19 @@ export async function e2eGetSchemaId(name: string): Promise { await e2eNavigateToSchemaCard(); // Obtain the schema identifier to return - await driver - .wait( - until.elementLocated(By.xpath(`//td[contains(.,'${name}')]/../td[1]`)), + await ( + await e2eWaitElementVisible( + By.xpath(`//td[contains(.,'${name}')]/../td[1]`), sdWaitDefault, ) - .click(); - const schemaId = await driver - .findElement( + ).click(); + + const schemaId = await ( + await e2eWaitElementVisible( By.xpath("//h3[contains(.,'Schema Identifier')]/following-sibling::p"), + sdWaitDefault, ) - .getText(); + ).getText(); return schemaId; } @@ -62,44 +69,56 @@ export async function e2eEnterSchemaDefintionDetails( attributes: string[], ): Promise { await e2eNavigateToSchemaCard(); - await driver - .wait( - until.elementLocated(By.css('#SchemaDefinitionsCard__create-btn > span')), + await ( + await e2eWaitElementVisible( + By.css('#SchemaDefinitionsCard__create-btn > span'), sdWaitDefault, ) - .click(); - await driver.wait( - until.elementIsVisible( - await driver.wait( - until.elementLocated(By.id('CreateSchemaDefinitionForm')), - sdWaitDefault, - ), - ), + ).click(); + + await e2eWaitElementVisible( + By.id('CreateSchemaDefinitionForm'), sdWaitDefault, ); - await driver - .wait(until.elementLocated(By.id('schemaName')), sdWaitDefault) - .click(); - await driver - .wait(until.elementLocated(By.id('schemaName')), sdWaitDefault) - .sendKeys(name); - await driver - .wait(until.elementLocated(By.id('schemaVersion')), sdWaitDefault) - .click(); - await driver - .wait(until.elementLocated(By.id('schemaVersion')), sdWaitDefault) - .sendKeys(version); + + await ( + await driver.wait(until.elementLocated(By.id('schemaName')), sdWaitDefault) + ).click(); + await ( + await driver.wait(until.elementLocated(By.id('schemaName')), sdWaitDefault) + ).sendKeys(name); + await ( + await driver.wait( + until.elementLocated(By.id('schemaVersion')), + sdWaitDefault, + ) + ).click(); + await ( + await driver.wait( + until.elementLocated(By.id('schemaVersion')), + sdWaitDefault, + ) + ).sendKeys(version); for (let i = 0; i < attributes.length; i++) { - await driver - .wait(until.elementLocated(By.id('attributes')), sdWaitDefault) - .click(); - await driver - .wait(until.elementLocated(By.id('attributes')), sdWaitDefault) - .sendKeys(attributes[i]); - await driver - .wait(until.elementLocated(By.id('attributes')), sdWaitDefault) - .sendKeys(Key.ENTER); + await ( + await driver.wait( + until.elementLocated(By.id('attributes')), + sdWaitDefault, + ) + ).click(); + await ( + await driver.wait( + until.elementLocated(By.id('attributes')), + sdWaitDefault, + ) + ).sendKeys(attributes[i]); + await ( + await driver.wait( + until.elementLocated(By.id('attributes')), + sdWaitDefault, + ) + ).sendKeys(Key.ENTER); // Make sure the entry appears in the table before proceeding await driver.wait( until.elementLocated(By.xpath(`//td[contains(.,'${attributes[i]}')]`)), @@ -127,38 +146,32 @@ export async function e2eCreateSchemaDefinition( ): Promise { await e2eEnterSchemaDefintionDetails(name, version, attributes); - await driver - .wait( - until.elementLocated( - By.css('#CreateSchemaDefinitionForm__submit-btn > span'), - ), + await ( + await e2eWaitElementVisible( + By.css('#CreateSchemaDefinitionForm__submit-btn > span'), sdWaitDefault, ) - .click(); - await driver.wait( - until.elementIsNotVisible( - await driver.wait( - until.elementLocated(By.id('CreateSchemaDefinitionForm')), - sdWaitDefault, - ), - ), - sdWaitDefault, - ); + ).click(); + + await e2eAcceptTAAForm(sdWaitDefault); await e2eCheckMessageDisplays('Schema Definition Created!', sdWaitDefault); - // Obtain the schema identifier to return - await driver - .wait( - until.elementLocated(By.xpath(`//td[contains(.,'${name}')]/../td[1]`)), + // Obtain the schema identifier to return, which also ensures it was + // created and displayed. + await ( + await e2eWaitElementVisible( + By.xpath(`//td[contains(.,'${name}')]/../td[1]`), sdWaitDefault, ) - .click(); - const schemaId = await driver - .findElement( + ).click(); + + const schemaId = await ( + await e2eWaitElementVisible( By.xpath("//h3[contains(.,'Schema Identifier')]/following-sibling::p"), + sdWaitDefault, ) - .getText(); + ).getText(); return schemaId; } diff --git a/e2e/setup-tests.ts b/e2e/setup-tests.ts index 90f4d9c..5c3370b 100644 --- a/e2e/setup-tests.ts +++ b/e2e/setup-tests.ts @@ -29,7 +29,7 @@ afterEach(async () => { ); combineCoverage(coverageData); // Delay each test to be visible. - await new Promise((r) => setTimeout(r, 2000)); + await new Promise((r) => setTimeout(r, 1000)); }); beforeAll(async () => { diff --git a/package.json b/package.json index d682458..f8d76ad 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@sudoplatform-labs/sudo-di-cloud-agent-admin-console", "description": "Sudo Decentalized Identity Cloud Agent Admin Console Application", - "version": "0.2.5", + "version": "0.3.0", "author": "Anonyome Platform Team", "license": "Apache-2.0", "files": [ @@ -19,12 +19,12 @@ "build:ts-check": "yarn tsc --noEmit", "test:update-acapy-address": "./utils/update-acapy-address.sh -c ./build/acapy.json", "test:execute-e2e": "jest --runInBand -c jest.e2e.config.js", - "test:start-browser-server-debug": "./e2e/browser-server.sh start -i selenium/standalone-chrome-debug:3.141.59-20210128 -p 4445", - "test:start-browser-server": "./e2e/browser-server.sh start -i selenium/standalone-chrome:3.141.59-20210128 -p 4445", + "test:start-browser-server-debug": "./e2e/browser-server.sh start -i selenium/standalone-chrome-debug:3.141.59 -p 4445", + "test:start-browser-server": "./e2e/browser-server.sh start -i selenium/standalone-chrome:3.141.59 -p 4445", "test:stop-browser-server": "./e2e/browser-server.sh stop", "test:start-e2e-env": "yarn di-env start -s 7837E638F94B43B5AD22C97354B997F9 && yarn test:update-acapy-address && yarn test:start-browser-server-debug", "test:stop-e2e-env": "yarn test:stop-browser-server; yarn di-env down", - "test:run-e2e": " yarn test:start-e2e-env && yarn test:execute-e2e; yarn test:stop-e2e-env", + "test:run-e2e": "rm -rf .e2e_test_success && yarn test:start-e2e-env && yarn test:execute-e2e && touch .e2e_test_success; yarn test:stop-e2e-env", "test:unit": "yarn react-scripts test", "test:e2e": "yarn test:run-e2e", "test:all": "CI=true yarn test:unit && yarn test:e2e ", @@ -37,11 +37,12 @@ "coverage:unit-tests": "cd ./instrumented && CI=true yarn test:unit --coverage", "coverage:e2e-tests": "cd ./instrumented && yarn test:run-e2e", "coverage:all-tests": "yarn coverage:unit-tests; yarn coverage:copy-unit-test-coverage; yarn coverage:e2e-tests", - "coverage:report": "rm -rf ./.nyc_output && cp -R instrumented/.nyc_output ./ && nyc report --nycrc-path='./nyc.e2e.config.json'" + "coverage:report": "rm -rf ./.nyc_output && cp -R instrumented/.nyc_output ./ && nyc report --nycrc-path='./nyc.e2e.config.json'", + "coverage": "rm -rf ./instrumented; yarn coverage:build && yarn coverage:all-tests; yarn coverage:report" }, "dependencies": { "@ant-design/icons": "^4.0.5", - "@sudoplatform-labs/sudo-di-cloud-agent": "^0.2.5", + "@sudoplatform-labs/sudo-di-cloud-agent": "^0.3.0", "antd": "^4.5.4", "antd-mask-input": "^0.1.13", "color": "^3.1.2", diff --git a/src/components/Form/modal.tsx b/src/components/Form/modal.tsx index 59c68f7..816f22e 100644 --- a/src/components/Form/modal.tsx +++ b/src/components/Form/modal.tsx @@ -93,10 +93,10 @@ export async function modalTAAAcceptance( }); await onAccept(); }, - okButtonProps: { id: 'CreateSchemaDefinitionForm__taa-accept-btn' }, + okButtonProps: { id: 'ModalTAAAcceptance__accept-btn' }, onCancel: onCancel, cancelButtonProps: { - id: 'CreateSchemaDefinitionForm__taa-cancel-btn', + id: 'ModalTAAAcceptance__cancel-btn', }, }); } else { diff --git a/src/pages/Connections/ConnectionsCard/AcceptInvitationForm.tsx b/src/pages/Connections/ConnectionsCard/AcceptInvitationForm.tsx index 6c9283a..e526155 100644 --- a/src/pages/Connections/ConnectionsCard/AcceptInvitationForm.tsx +++ b/src/pages/Connections/ConnectionsCard/AcceptInvitationForm.tsx @@ -45,13 +45,13 @@ export const AcceptInvitationForm: React.FC = (props) => { // Base64 formated invitation and place it into // the correct ConnectionInvitationAcceptaParams.invitation // field. - const inviteParam = values.invitation.replace( + const inviteParam = values.AcceptInvitationForm_invitation.replace( /(http:\/\/.*)?\?c_i=/i, '', ); const inviteTxt = inviteParam ? atob(inviteParam) : ''; const acceptDetails: ConnectionAcceptParams = { - alias: values.myAlias, + alias: values.AcceptInvitationForm_alias, mode: ConnRecord.AcceptEnum.Auto, invitation: JSON.parse(inviteTxt), }; @@ -68,7 +68,7 @@ export const AcceptInvitationForm: React.FC = (props) => { onFinish={handleSubmit} layout="vertical"> = (props) => { = (props) => { message: 'Please provide the Invitation URL for the Connection.', }, ]}> -