Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New automation tests #1080

Draft
wants to merge 5 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@
"import/no-named-as-default": 0,
"import/export": 1
}
}
}
33 changes: 31 additions & 2 deletions e2e-tests/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Page } from '@playwright/test';
import path from 'path';

export const vaultPassword = '3hQqzYn4C7Y8rEZTVEZb';
export const newPassword = 'this is new password';
export const twentyFourWordsSecretPhrase =
'hold matrix spider subway bottom jazz charge fire lawn valley stay coil moral hospital dream cycle multiply december agree huge major tower devote old';
export const twelveWordsSecretPhrase =
Expand All @@ -20,7 +22,8 @@ export const torusSecretKeyHex =
export const ACCOUNT_NAMES = {
defaultFirstAccountName: 'Account 1',
defaultSecondAccountName: 'Account 2',
createdAccountName: 'New account 1',
createdAccountName: 'First New Account',
createdAccountName2: 'Second New account ',
importedPemAccountName: 'Imported pem account',
renamedAccountName: 'Renamed account',
importedCerAccountName: 'Imported cer account',
Expand Down Expand Up @@ -109,7 +112,33 @@ export const NEW_VALIDATOR_FOR_STAKE = {
export const URLS = {
rpc: 'https://node.testnet.cspr.cloud/rpc'
};

export function createLocators(page: Page) {
return {
accountSwitcher: page.getByTestId('connection-status-modal'),
firstAccount: page.locator(
"span[type='bodySemiBold'].sc-iOeugr.hnMrar.sc-iJbNxu.bAimRi"
),
CSPRtotalBalance: page.locator('span[type="CSPRBold"]'),
liquidBalance: page.locator(
'#layout-content-container > div > div.sc-gGvHcT.LEYqH > div > div.sc-hLBbgP.sc-kDvujY.bxIaNA.czrHSx > div.sc-hLBbgP.sc-kDvujY.nnmro.czrHSx > div.sc-hLBbgP.sc-kDvujY.sc-fmixVB.eJhjZ.czrHSx.jIbqvc > div:nth-child(1) > div > span.sc-iOeugr.fFyyCL'
),
delegatedBalance: page.locator(
'//*[@id="layout-content-container"]/div/div[1]/div/div[2]/div[2]/div[2]/div[2]/div/span[1]'
),
undelegatingBalance: page.locator(
'//*[@id="layout-content-container"]/div/div[1]/div/div[2]/div[2]/div[2]/div[3]/div/span[1]'
),
totalBalanceUSD: page.locator(
'//span[@type="captionRegular" and @color="contentSecondary"]'
),
threeDotsMenu: page.locator(
"//*[contains(@class, 'sc-eJDSGI') and contains(@class, 'bMCuLR')]"
)
};
}
export function accountSettingLocator(accountName: string) {
return `xpath=//div[contains(@class, 'sc-hLBbgP') and contains(@class, 'fYMUrO')]//span[text()='${accountName}']/ancestor::div[contains(@class, 'sc-hLBbgP')]/following-sibling::div[@data-testid='popover-children-container']`;
}
export const RPC_RESPONSE = {
success: {
status: 200,
Expand Down
220 changes: 214 additions & 6 deletions e2e-tests/fixtures.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import {
test as base,
chromium,
type BrowserContext,
Page
Page,
test as base,
chromium
} from '@playwright/test';
import path from 'path';
import { PipelineOptions } from 'stream';

import {
DEFAULT_FIRST_ACCOUNT,
DEFAULT_SECOND_ACCOUNT,
PLAYGROUND_URL,
RPC_RESPONSE,
URLS,
newPassword,
vaultPassword
} from './constants';

Expand Down Expand Up @@ -212,6 +217,14 @@ export const popup = test.extend<{
createAccount: (newAccountName: string) => Promise<void>;
connectAccounts: () => Promise<void>;
addContact: () => Promise<void>;
providePassword: (popupPage?: Page) => Promise<void>;
passwordTimeout: (popupPage?: Page) => Promise<void>;
changePassword: (popupPage?: Page) => Promise<void>;
provideNewPassword: (popupPage?: Page) => Promise<void>;
unlockVaultNewPassword: (popupPage?: Page) => Promise<void>;
passwordDontMatch: (popupPage?: Page) => Promise<void>;
sendCsprTokens: (popupPage?: Page) => Promise<void>;
unlockValutForSigning: (popupPage?: Page) => Promise<void>;
}>({
popupPage: async ({ extensionId, page }, use) => {
await page.goto(`chrome-extension://${extensionId}/popup.html`);
Expand All @@ -225,10 +238,131 @@ export const popup = test.extend<{
.getByPlaceholder('Password', { exact: true })
.fill(vaultPassword);
await currentPage.getByRole('button', { name: 'Unlock wallet' }).click();
await page.waitForLoadState('networkidle');
await new Promise(r => setTimeout(r, 5000));
await page.waitForSelector('text=Total balance', {
state: 'visible',
timeout: 30000
});
};

await use(unlockVault);
},
unlockValutForSigning: async ({ page }, use) => {
const unlockValutForSigning = async (popupPage?: Page) => {
const currentPage = popupPage || page;

await currentPage
.getByPlaceholder('Password', { exact: true })
.fill(vaultPassword);
await currentPage.getByRole('button', { name: 'Unlock wallet' }).click();
};

await use(unlockValutForSigning);
},
sendCsprTokens: async ({ page }, use) => {
const sendCsprTokens = async (popupPage?: Page) => {
const currentPage = popupPage || page;
await currentPage.route(URLS.rpc, route =>
route.fulfill(RPC_RESPONSE.success)
);

await new Promise(r => setTimeout(r, 5000));

await currentPage.getByText('Send').click();

await popupExpect(
currentPage.getByRole('heading', { name: 'Select token and account' })
).toBeVisible();

await currentPage.getByRole('button', { name: 'Next' }).click();

await popupExpect(
currentPage.getByRole('heading', { name: 'Specify recipient' })
).toBeVisible();

await popupExpect(
currentPage.getByRole('button', { name: 'Next' })
).toBeDisabled();

await currentPage
.getByPlaceholder('Public key or name', { exact: true })
.fill(DEFAULT_SECOND_ACCOUNT.publicKey);

await popupExpect(
currentPage.getByText(DEFAULT_SECOND_ACCOUNT.mediumTruncatedPublicKey, {
exact: true
})
).toBeVisible();

await currentPage
.getByText(DEFAULT_SECOND_ACCOUNT.mediumTruncatedPublicKey, {
exact: true
})
.click();

await currentPage.getByRole('button', { name: 'Next' }).click();

await popupExpect(
currentPage.getByRole('heading', { name: 'Enter amount' })
).toBeVisible();

await currentPage.getByRole('button', { name: 'Next' }).click();

await popupExpect(
currentPage.getByRole('heading', { name: 'Confirm sending' })
).toBeVisible();

await popupExpect(
currentPage.getByText(DEFAULT_SECOND_ACCOUNT.publicKey)
).toBeVisible();

await popupExpect(
currentPage.getByRole('button', { name: 'Confirm send' })
).toBeDisabled();

// Scroll to the bottom
await currentPage.evaluate(() => {
const container = document.querySelector('#ms-container');

container?.scrollTo(0, 1000);
});

await popupExpect(
currentPage.getByRole('button', { name: 'Confirm send' })
).not.toBeDisabled();

await currentPage.getByRole('button', { name: 'Confirm send' }).click();
await currentPage.waitForLoadState('networkidle');
await popupExpect(
currentPage.getByRole('heading', {
name: 'You submitted a transaction'
})
).toBeVisible();

await currentPage.getByRole('button', { name: 'Done' }).click();

popupExpect(
currentPage.getByRole('heading', {
name: 'Are you enjoying Casper Wallet so far?'
})
).toBeVisible();
};
await use(sendCsprTokens);
},

unlockVaultNewPassword: async ({ page }, use) => {
const unlockVaultNewPassword = async (popupPage?: Page) => {
const currentPage = popupPage || page;

await currentPage
.getByPlaceholder('Password', { exact: true })
.fill(newPassword);
await currentPage.getByRole('button', { name: 'Unlock wallet' }).click();
};

await use(unlockVaultNewPassword);
},
lockVault: async ({ page }, use) => {
const lockVault = async () => {
await page.getByTestId('menu-open-icon').click();
Expand All @@ -250,7 +384,7 @@ export const popup = test.extend<{

await use(createAccount);
},
connectAccounts: async ({ page, unlockVault, context }, use) => {
connectAccounts: async ({ page, unlockValutForSigning, context }, use) => {
const connectAccounts = async () => {
await page.goto(PLAYGROUND_URL);

Expand All @@ -259,7 +393,7 @@ export const popup = test.extend<{
page.getByRole('button', { name: 'Connect', exact: true }).click()
]);

await unlockVault(connectAccountPage);
await unlockValutForSigning(connectAccountPage);

await connectAccountPage.getByText('select all', { exact: true }).click();

Expand Down Expand Up @@ -291,7 +425,81 @@ export const popup = test.extend<{
};

await use(addContact);
},

providePassword: async ({ page }, use) => {
const providePassword = async (popupPage?: Page) => {
const currentPage = popupPage || page;

await currentPage
.getByPlaceholder('Password', { exact: true })
.fill(vaultPassword);
await currentPage.getByRole('button', { name: 'Continue' }).click();
};

await use(providePassword);
},
provideNewPassword: async ({ page }, use) => {
const provideNewPassword = async (popupPage?: Page) => {
const currentPage = popupPage || page;

await currentPage
.getByPlaceholder('Password', { exact: true })
.fill(newPassword);
await currentPage.getByRole('button', { name: 'Continue' }).click();
};

await use(provideNewPassword);
},
changePassword: async ({ page }, use) => {
const changePassword = async (popupPage?: Page) => {
const currentPage = popupPage || page;

await currentPage
.getByPlaceholder('Password', { exact: true })
.fill(newPassword);
await currentPage.getByPlaceholder('Confirm password').fill(newPassword);

await currentPage.getByRole('button', { name: 'Continue' }).click();

await page.waitForTimeout(2000);
};

await use(changePassword);
},
passwordDontMatch: async ({ page }, use) => {
const changePassword = async (popupPage?: Page) => {
const currentPage = popupPage || page;

await currentPage
.getByPlaceholder('Password', { exact: true })
.fill(newPassword);
await currentPage
.getByPlaceholder('Confirm password')
.fill(vaultPassword);

await currentPage.getByRole('button', { name: 'Continue' }).click();

await page.waitForTimeout(2000);
};

await use(changePassword);
},

passwordTimeout: async ({ page }, use) => {
const passwordTimeout = async (popupPage?: Page) => {
const currentPage = popupPage || page;

await currentPage
.getByPlaceholder('Password', { exact: true })
.fill('wrong password');

for (let i = 0; i < 5; i++) {
await currentPage.getByRole('button', { name: 'Continue' }).click();
}
};

await use(passwordTimeout);
}
});

export const popupExpect = popup.expect;
14 changes: 13 additions & 1 deletion e2e-tests/onboarding-flow/confirm-secret-phrase-flow.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { onboardingExpect, onboarding } from '../fixtures';
import { DEFAULT_FIRST_ACCOUNT } from '../constants';
import { onboarding, onboardingExpect } from '../fixtures';

onboarding.describe('Onboarding UI: confirm secret phrase flow', () => {
onboarding(
Expand Down Expand Up @@ -30,6 +30,18 @@ onboarding.describe('Onboarding UI: confirm secret phrase flow', () => {
await onboardingExpect(
page.getByText(DEFAULT_FIRST_ACCOUNT.accountName)
).toBeVisible();
//Fresh account should have empty balances, no nft or deploy history
await onboardingExpect(page.getByText('NFTs')).toBeVisible();

await page.getByText('NFTs').click();

await onboardingExpect(
await page.getByText('No NFT tokens')
).toBeVisible();

await page.getByText('Deploys').click();

await onboardingExpect(await page.getByText('No activity')).toBeVisible();
}
);

Expand Down
Loading
Loading