Skip to content

Commit

Permalink
test(extension): e2e - add e2e tests for sending ada/assets from DApp
Browse files Browse the repository at this point in the history
  • Loading branch information
ljagiela committed Jun 5, 2023
1 parent d93b12c commit aa6b86a
Show file tree
Hide file tree
Showing 22 changed files with 561 additions and 95 deletions.
Expand Up @@ -12,11 +12,19 @@ export const DappTransactionSuccess = (): React.ReactElement => {
<div data-testid="dapp-sign-tx-success" className={styles.noWalletContainer}>
<div className={styles.noWalletContent}>
<Image data-testid="dapp-sign-tx-success-image" preview={false} width={112} src={Success} />
<div className={styles.heading}>{t('browserView.transaction.success.youCanSafelyCloseThisPanel')}</div>
<div className={styles.description}>{t('core.dappTransaction.signedSuccessfully')}</div>
<div data-testid="dapp-sign-tx-success-heading" className={styles.heading}>
{t('browserView.transaction.success.youCanSafelyCloseThisPanel')}
</div>
<div data-testid="dapp-sign-tx-success-description" className={styles.description}>
{t('core.dappTransaction.signedSuccessfully')}
</div>
</div>
<div className={styles.footer}>
<Button data-test-id="window-close-btn" className={styles.footerBtn} onClick={() => window.close()}>
<Button
data-testid="dapp-sign-tx-success-close-button"
className={styles.footerBtn}
onClick={() => window.close()}
>
{t('general.button.close')}
</Button>
</div>
Expand Down
Expand Up @@ -68,7 +68,7 @@ export const SignTransaction = (): React.ReactElement => {
<Layout title={undefined}>
<div className={styles.passwordContainer}>
<Spin spinning={isLoading}>
<h5 className={styles.message}>
<h5 className={styles.message} data-testid="sign-transaction-description">
{t('browserView.transaction.send.enterWalletPasswordToConfirmTransaction')}
</h5>
<Password
Expand All @@ -81,10 +81,20 @@ export const SignTransaction = (): React.ReactElement => {
</Spin>
</div>
<div className={styles.actions}>
<Button onClick={onConfirm} disabled={confirmIsDisabled} className={styles.actionBtn}>
<Button
onClick={onConfirm}
disabled={confirmIsDisabled}
className={styles.actionBtn}
data-testid="sign-transaction-confirm"
>
{t('dapp.confirm.btn.confirm')}
</Button>
<Button onClick={setPreviousView} color="secondary" className={styles.actionBtn}>
<Button
onClick={setPreviousView}
color="secondary"
className={styles.actionBtn}
data-testid="sign-transaction-cancel"
>
{t('dapp.confirm.btn.cancel')}
</Button>
</div>
Expand Down
Expand Up @@ -49,33 +49,43 @@ export const DappTransaction = ({
</div>
)}
{errorMessage && <ErrorPane error={errorMessage} className={styles.error} />}
<div className={styles.details}>
<div data-testid="dapp-transaction-container" className={styles.details}>
<div className={styles.header}>
<div className={styles.title}>{translations.transaction}</div>
<div className={styles.type}>{type}</div>
<div data-testid="dapp-transaction-title" className={styles.title}>
{translations.transaction}
</div>
<div data-testid="dapp-transaction-type" className={styles.type}>
{type}
</div>
</div>
{outputs.map((output) => (
<div className={styles.body} key={output.recipient}>
<div className={styles.detail}>
<div className={styles.title}>{translations.amount}</div>
<div data-testid="dapp-transaction-amount-title" className={styles.title}>
{translations.amount}
</div>
<div className={styles.value}>
<div className={styles.bold}>{output.coins.toString()} ADA</div>
<div data-testid="dapp-transaction-amount-value" className={styles.bold}>
{output.coins.toString()} ADA
</div>
{outputs.length === 1 && (
<div className={styles.sub}>
<div data-testid="dapp-transaction-amount-fee" className={styles.sub}>
{translations.fee}: {fee.toString()} ADA
</div>
)}
{output.assets &&
output.assets.map((asset) => (
<div className={styles.bold} key={asset.name.toString()}>
<div data-testid="dapp-transaction-asset" className={styles.bold} key={asset.name.toString()}>
{asset.amount} {asset.ticker || asset.name}
</div>
))}
</div>
</div>
<div className={styles.detail}>
<div className={styles.title}>{translations.recipient}</div>
<div className={styles.value}>
<div data-testid="dapp-transaction-recipient-title" className={styles.title}>
{translations.recipient}
</div>
<div data-testid="dapp-transaction-recipient-address" className={styles.value}>
<Ellipsis className={styles.rightAligned} text={output.recipient} ellipsisInTheMiddle />
</div>
</div>
Expand Down
126 changes: 112 additions & 14 deletions packages/e2e-tests/src/assert/dAppConnectorAssert.ts
Expand Up @@ -4,27 +4,48 @@ import AuthorizeDAppPage from '../elements/dappConnector/authorizeDAppPage';
import AuthorizedDAppsPage from '../elements/dappConnector/authorizedDAppsPage';
import AuthorizeDAppModal from '../elements/dappConnector/authorizeDAppModal';
import ExampleDAppPage from '../elements/dappConnector/testDAppPage';

export type ExpectedAuthorizedDAppDetails = {
import ConfirmTransactionPage from '../elements/dappConnector/confirmTransactionPage';
import CommonDappPageElements from '../elements/dappConnector/commonDappPageElements';
import SignTransactionPage from '../elements/dappConnector/signTransactionPage';
import DAppTransactionAllDonePage from '../elements/dappConnector/dAppTransactionAllDonePage';
import { Logger } from '../support/logger';
import testContext from '../utils/testContext';

export type ExpectedDAppDetails = {
hasLogo: boolean;
name: string;
url: string;
};

export type ExpectedTransactionData = {
typeOfTransaction: string;
amountADA: string;
amountAsset?: string;
recipientAddress: string;
};

class DAppConnectorAssert {
async assertSeeAuthorizeDAppPage(expectedDappName: string, expectedDappUrl: string) {
await AuthorizeDAppPage.headerLogo.waitForDisplayed();
await AuthorizeDAppPage.betaPill.waitForDisplayed();
await expect(await AuthorizeDAppPage.betaPill.getText()).to.equal(await t('core.dapp.beta'));
async assertSeeHeader() {
const commonDappPageElements = new CommonDappPageElements();
await commonDappPageElements.headerLogo.waitForDisplayed();
await commonDappPageElements.betaPill.waitForDisplayed();
await expect(await commonDappPageElements.betaPill.getText()).to.equal(await t('core.dapp.beta'));
}

await AuthorizeDAppPage.pageTitle.waitForDisplayed();
await expect(await AuthorizeDAppPage.pageTitle.getText()).to.equal(await t('dapp.connect.header'));
async assertSeeTitleAndDappDetails(expectedTitleKey: string, expectedDappDetails: ExpectedDAppDetails) {
const commonDappPageElements = new CommonDappPageElements();
await commonDappPageElements.pageTitle.waitForDisplayed();
await expect(await commonDappPageElements.pageTitle.getText()).to.equal(await t(expectedTitleKey));
await commonDappPageElements.dAppLogo.waitForDisplayed({ reverse: !expectedDappDetails.hasLogo });
await commonDappPageElements.dAppName.waitForDisplayed();
await expect(await commonDappPageElements.dAppName.getText()).to.equal(expectedDappDetails.name);
await commonDappPageElements.dAppUrl.waitForDisplayed();
await expect(await commonDappPageElements.dAppUrl.getText()).to.equal(expectedDappDetails.url);
}

await AuthorizeDAppPage.dAppLogo.waitForDisplayed();
await AuthorizeDAppPage.dAppName.waitForDisplayed();
await expect(await AuthorizeDAppPage.dAppName.getText()).to.equal(expectedDappName);
await AuthorizeDAppPage.dAppUrl.waitForDisplayed();
await expect(await AuthorizeDAppPage.dAppUrl.getText()).to.equal(expectedDappUrl);
async assertSeeAuthorizeDAppPage(expectedDappDetails: ExpectedDAppDetails) {
await this.assertSeeHeader();
await this.assertSeeTitleAndDappDetails('dapp.connect.header', expectedDappDetails);

await AuthorizeDAppPage.banner.container.waitForDisplayed();
await AuthorizeDAppPage.banner.icon.waitForDisplayed();
Expand Down Expand Up @@ -112,7 +133,7 @@ class DAppConnectorAssert {
expect(await AuthorizedDAppsPage.dAppContainers.length).to.equal(0);
}

async assertSeeAuthorizedDAppsOnTheList(expectedDApps: ExpectedAuthorizedDAppDetails[]) {
async assertSeeAuthorizedDAppsOnTheList(expectedDApps: ExpectedDAppDetails[]) {
expect(await AuthorizedDAppsPage.dAppContainers.length).to.equal(expectedDApps.length);
for (const [i, expectedDapp] of expectedDApps.entries()) {
await AuthorizedDAppsPage.dAppLogos[i].waitForDisplayed({ reverse: !expectedDApps[i].hasLogo });
Expand All @@ -121,6 +142,83 @@ class DAppConnectorAssert {
await AuthorizedDAppsPage.dAppRemoveButtons[i].waitForDisplayed();
}
}

async assertSeeConfirmTransactionPage(
expectedDApp: ExpectedDAppDetails,
expectedTransactionData: ExpectedTransactionData
) {
await this.assertSeeHeader();
await this.assertSeeTitleAndDappDetails('dapp.confirm.header', expectedDApp);
await ConfirmTransactionPage.transactionTypeTitle.waitForDisplayed();
await expect(await ConfirmTransactionPage.transactionTypeTitle.getText()).to.equal(
await t('dapp.confirm.details.header')
);
await ConfirmTransactionPage.transactionType.waitForDisplayed();
await expect(await ConfirmTransactionPage.transactionType.getText()).to.equal(
expectedTransactionData.typeOfTransaction
);

await ConfirmTransactionPage.transactionAmountTitle.waitForDisplayed();
await expect(await ConfirmTransactionPage.transactionAmountTitle.getText()).to.equal(
await t('dapp.confirm.details.amount')
);

await ConfirmTransactionPage.transactionAmountValue.waitForDisplayed();
await expect(await ConfirmTransactionPage.transactionAmountValue.getText()).to.equal(
expectedTransactionData.amountADA
);

await ConfirmTransactionPage.transactionAmountFee.waitForDisplayed();

if (expectedTransactionData.amountAsset && expectedTransactionData.amountAsset !== '0') {
await ConfirmTransactionPage.transactionAmountAsset.waitForDisplayed();
await expect(await ConfirmTransactionPage.transactionAmountAsset.getText()).to.equal(
expectedTransactionData.amountAsset
);
}

await ConfirmTransactionPage.transactionRecipientTitle.waitForDisplayed();
await expect(await ConfirmTransactionPage.transactionRecipientTitle.getText()).to.equal(
await t('dapp.confirm.details.recepient')
);
await expect(await ConfirmTransactionPage.transactionRecipientAddress.getText()).to.contain(
expectedTransactionData.recipientAddress.slice(-10)
);

await ConfirmTransactionPage.confirmButton.waitForDisplayed();
await expect(await ConfirmTransactionPage.confirmButton.getText()).to.equal(await t('dapp.confirm.btn.confirm'));

await ConfirmTransactionPage.cancelButton.waitForDisplayed();
await expect(await ConfirmTransactionPage.cancelButton.getText()).to.equal(await t('dapp.confirm.btn.cancel'));
}

async assertSeeSignTransactionPage() {
await this.assertSeeHeader();
await SignTransactionPage.passwordInput.container.waitForDisplayed();
await SignTransactionPage.confirmButton.waitForDisplayed();
await expect(await SignTransactionPage.confirmButton.getText()).to.equal(await t('dapp.confirm.btn.confirm'));
await SignTransactionPage.cancelButton.waitForDisplayed();
await expect(await SignTransactionPage.cancelButton.getText()).to.equal(await t('dapp.confirm.btn.cancel'));
}

async assertSeeAllDonePage() {
await this.assertSeeHeader();
await DAppTransactionAllDonePage.image.waitForDisplayed();

await DAppTransactionAllDonePage.heading.waitForDisplayed();
await expect(await DAppTransactionAllDonePage.heading.getText()).to.equal(
await t('browserView.transaction.success.youCanSafelyCloseThisPanel')
);

await DAppTransactionAllDonePage.description.waitForDisplayed();
await expect(await DAppTransactionAllDonePage.description.getText()).to.equal(await t('core.dappTransaction.signedSuccessfully'));

Check failure on line 214 in packages/e2e-tests/src/assert/dAppConnectorAssert.ts

View workflow job for this annotation

GitHub Actions / Build & Test

Replace `await·t('core.dappTransaction.signedSuccessfully')` with `⏎······await·t('core.dappTransaction.signedSuccessfully')⏎····`

await DAppTransactionAllDonePage.closeButton.waitForDisplayed();
await expect(await DAppTransactionAllDonePage.closeButton.getText()).to.equal(await t('general.button.close'));

Logger.log('saving tx hash: null'); // TODO save proper hash once it's added to the all done page
testContext.save('txHashValue', false);
}
}

export default new DAppConnectorAssert();
24 changes: 23 additions & 1 deletion packages/e2e-tests/src/assert/tokensPageAssert.ts
Expand Up @@ -142,7 +142,12 @@ class TokensPageAssert {
}
}

async assertSeeValueSubtracted(tokenName: string, subtractedAmount: string, fee: string, mode: 'extended' | 'popup') {
async assertSeeValueSubtractedAda(
tokenName: string,
subtractedAmount: string,
fee: string,
mode: 'extended' | 'popup'
) {
const tokensPage = new TokensPage();
const expectedValue =
Number.parseFloat(await testContext.load(`${Asset.getByName(tokenName).ticker}tokenBalance`)) -
Expand All @@ -163,6 +168,23 @@ class TokensPageAssert {
);
}

async assertSeeValueSubtractedAsset(tokenName: string, subtractedAmount: string, mode: 'extended' | 'popup') {
const tokensPage = new TokensPage();
const expectedValue =
Number.parseFloat(await testContext.load(`${Asset.getByName(tokenName).ticker}tokenBalance`)) -
Number.parseFloat(subtractedAmount);
const expectedValueRounded = Number.parseFloat(expectedValue.toFixed(2));
Logger.log(`waiting for token: ${tokenName} with value: ${expectedValueRounded}`);
await browser.waitUntil(
async () => (await tokensPage.getTokenTableItemValueByName(tokenName, mode)) === expectedValueRounded,
{
timeout: 30_000,
interval: 3000,
timeoutMsg: `failed while waiting for ${tokenName} value update`
}
);
}

async assertSeeCoinGeckoCredits(shouldSee: boolean) {
const tokensPage = new TokensPage();
await tokensPage.coinGeckoCredits.waitForDisplayed({ reverse: !shouldSee });
Expand Down
4 changes: 2 additions & 2 deletions packages/e2e-tests/src/assert/transactionDetailsAssert.ts
Expand Up @@ -5,7 +5,7 @@ import webTester from '../actor/webTester';
import { expect } from 'chai';
import testContext from '../utils/testContext';

type ExpectedTransactionDetails = {
export type ExpectedTransactionDetails = {
transactionDescription: string;
hash?: string;
transactionData?: transactionData[];
Expand Down Expand Up @@ -40,7 +40,7 @@ class TransactionsDetailsAssert {
);
if (expectedTransactionDetails.hash) {
await expect(await transactionsDetails.transactionDetailsHash.getText()).to.equal(
expectedTransactionDetails.hash
String(expectedTransactionDetails.hash)
);
}
await expect(
Expand Down
33 changes: 2 additions & 31 deletions packages/e2e-tests/src/elements/dappConnector/authorizeDAppPage.ts
Expand Up @@ -2,43 +2,14 @@
import Banner from '../banner';
import { ChainablePromiseElement } from 'webdriverio';
import { ChainablePromiseArray } from 'webdriverio/build/types';
import CommonDappPageElements from './commonDappPageElements';

class AuthorizeDAppPage {
private HEADER_LOGO = '[data-testid="header-logo"]';
private BETA_PILL = '[data-testid="beta-pill"]';
private PAGE_TITLE = '[data-testid="layout-title"]';
private DAPP_LOGO = '[data-testid="dapp-info-logo"]';
private DAPP_NAME = '[data-testid="dapp-info-name"]';
private DAPP_URL = '[data-testid="dapp-info-url"]';
class AuthorizeDAppPage extends CommonDappPageElements {
private PERMISSIONS_TITLE = '[data-testid="authorize-dapp-title"]';
private PERMISSIONS_LIST = '[data-testid="authorize-dapp-permissions"]';
private AUTHORIZE_BUTTON = '[data-testid="connect-authorize-button"]';
private CANCEL_BUTTON = '[data-testid="connect-cancel-button"]';

get headerLogo(): ChainablePromiseElement<WebdriverIO.Element> {
return $(this.HEADER_LOGO);
}

get betaPill(): ChainablePromiseElement<WebdriverIO.Element> {
return $(this.BETA_PILL);
}

get pageTitle(): ChainablePromiseElement<WebdriverIO.Element> {
return $(this.PAGE_TITLE);
}

get dAppLogo(): ChainablePromiseElement<WebdriverIO.Element> {
return $(this.DAPP_LOGO);
}

get dAppName(): ChainablePromiseElement<WebdriverIO.Element> {
return $(this.DAPP_NAME);
}

get dAppUrl(): ChainablePromiseElement<WebdriverIO.Element> {
return $(this.DAPP_URL);
}

get banner(): typeof Banner {
return Banner;
}
Expand Down

0 comments on commit aa6b86a

Please sign in to comment.