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

test: [POM] Migrate onboarding infura call privacy e2e tests #28079

Open
wants to merge 22 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
0816233
Add advanced-functionality.spec.ts for privacy settings tests
devin-ai-integration[bot] Oct 18, 2024
d1c4685
onboardinh class page
chloeYue Oct 22, 2024
eb0537c
Migrate onboarding tests to TypeScript and implement POM pattern
devin-ai-integration[bot] Oct 22, 2024
a30228f
Remove original JavaScript onboarding spec file
devin-ai-integration[bot] Oct 22, 2024
ec7c920
Convert onboarding.spec.js to TypeScript
devin-ai-integration[bot] Oct 23, 2024
6185a86
correctios
chloeYue Oct 23, 2024
6a2c7ec
Merge branch 'pom-migrate-onboarding' of https://github.com/MetaMask/…
chloeYue Oct 23, 2024
2a4570c
reduce flakiness
chloeYue Oct 23, 2024
035dd7a
reduce flakiness
chloeYue Oct 23, 2024
4991266
Merge branch 'develop' into pom-migrate-onboarding
chloeYue Oct 23, 2024
3796379
fix lint
chloeYue Oct 23, 2024
572695d
add more log message
chloeYue Oct 23, 2024
4b19769
chore: convert privacy test files to typescript and update page objec…
devin-ai-integration[bot] Oct 24, 2024
9938c20
chore: revert changes in configuration files to match master branch
devin-ai-integration[bot] Oct 24, 2024
a05d4c4
chore: revert configuration files to match develop branch
devin-ai-integration[bot] Oct 24, 2024
768df2f
Merge branch 'develop' into chloe-migrate-onboarding
chloeYue Oct 24, 2024
f36bdad
chore: remove migrated JavaScript test files
devin-ai-integration[bot] Oct 24, 2024
4d6ef70
Merge branch 'chloe-migrate-onboarding' of https://github.com/MetaMas…
devin-ai-integration[bot] Oct 24, 2024
bb4a0ff
remove unnecessary funtions
chloeYue Oct 24, 2024
00b6ad6
Merge branch 'chloe-migrate-onboarding' of https://github.com/MetaMas…
chloeYue Oct 24, 2024
adbd30e
fix
chloeYue Oct 24, 2024
390d5be
fix
chloeYue Oct 24, 2024
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
41 changes: 0 additions & 41 deletions test/e2e/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -630,45 +630,6 @@ const completeCreateNewWalletOnboardingFlow = async (driver, password) => {
await onboardingPinExtension(driver);
};

const importWrongSRPOnboardingFlow = async (driver, seedPhrase) => {
// agree to terms of use
await driver.clickElement('[data-testid="onboarding-terms-checkbox"]');

// welcome
await driver.clickElement('[data-testid="onboarding-import-wallet"]');

// metrics
await driver.clickElement('[data-testid="metametrics-no-thanks"]');

// import with recovery phrase
await driver.pasteIntoField(
'[data-testid="import-srp__srp-word-0"]',
seedPhrase,
);

const warningText = 'Invalid Secret Recovery Phrase';
const warnings = await driver.findElements('.import-srp__banner-alert-text');
const warning = warnings[1];

assert.equal(await warning.getText(), warningText);
};

const selectDropdownByNum = async (elements, index) => {
await elements[index].click();
};

const testSRPDropdownIterations = async (options, driver, iterations) => {
for (let i = 0; i < iterations; i++) {
await selectDropdownByNum(options, i);
await new Promise((resolve) => setTimeout(resolve, 1000));

const formFields = await driver.findElements('.import-srp__srp-word-label');
const expectedNumFields = 12 + i * 3;
const actualNumFields = formFields.length;
assert.equal(actualNumFields, expectedNumFields);
}
};

const openSRPRevealQuiz = async (driver) => {
// navigate settings to reveal SRP
await driver.clickElement('[data-testid="account-options-menu-button"]');
Expand Down Expand Up @@ -1291,8 +1252,6 @@ module.exports = {
closeSRPReveal,
tapAndHoldToRevealSRP,
createDownloadFolder,
importWrongSRPOnboardingFlow,
testSRPDropdownIterations,
openDapp,
openDappConnectionsPage,
createDappTransaction,
Expand Down
38 changes: 21 additions & 17 deletions test/e2e/page-objects/flows/onboarding.flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,52 @@ import StartOnboardingPage from '../pages/onboarding/start-onboarding-page';
import SecureWalletPage from '../pages/onboarding/secure-wallet-page';
import OnboardingCompletePage from '../pages/onboarding/onboarding-complete-page';

export const importSRPOnboardingFlow = async (driver: Driver) => {
console.log('start import srp onboarding flow ');
export const createNewWalletOnboardingFlow = async (driver: Driver) => {
console.log('start creat new wallet onboarding flow ');
await driver.navigate();
const startOnboardingPage = new StartOnboardingPage(driver);
await startOnboardingPage.check_pageIsLoaded();
await startOnboardingPage.checkTermsCheckbox();
await startOnboardingPage.clickImportWalletButton();
await startOnboardingPage.clickCreateWalletButton();

const onboardingMetricsPage = new OnboardingMetricsPage(driver);
await onboardingMetricsPage.check_pageIsLoaded();
await onboardingMetricsPage.clickNoThanksButton();

const onboardingSrpPage = new OnboardingSrpPage(driver);
await onboardingSrpPage.check_pageIsLoaded();
await onboardingSrpPage.fillSrp();
await onboardingSrpPage.clickConfirmButton();

const onboardingPasswordPage = new OnboardingPasswordPage(driver);
await onboardingPasswordPage.check_pageIsLoaded();
await onboardingPasswordPage.createImportedWalletPassword();
await onboardingPasswordPage.createWalletPassword();

const secureWalletPage = new SecureWalletPage(driver);
await secureWalletPage.check_pageIsLoaded();
await secureWalletPage.revealAndConfirmSRP();
};

export const completeCreateNewWalletOnboardingFlow = async (driver: Driver) => {
console.log('start to complete create new wallet onboarding flow ');
export const importSRPOnboardingFlow = async (driver: Driver) => {
console.log('start import srp onboarding flow ');
await driver.navigate();
const startOnboardingPage = new StartOnboardingPage(driver);
await startOnboardingPage.check_pageIsLoaded();
await startOnboardingPage.checkTermsCheckbox();
await startOnboardingPage.clickCreateWalletButton();
await startOnboardingPage.clickImportWalletButton();

const onboardingMetricsPage = new OnboardingMetricsPage(driver);
await onboardingMetricsPage.check_pageIsLoaded();
await onboardingMetricsPage.clickNoThanksButton();

const onboardingSrpPage = new OnboardingSrpPage(driver);
await onboardingSrpPage.check_pageIsLoaded();
await onboardingSrpPage.fillSrp();
await onboardingSrpPage.clickConfirmButton();

const onboardingPasswordPage = new OnboardingPasswordPage(driver);
await onboardingPasswordPage.check_pageIsLoaded();
await onboardingPasswordPage.createWalletPassword();

const secureWalletPage = new SecureWalletPage(driver);
await secureWalletPage.check_pageIsLoaded();
await secureWalletPage.revealAndConfirmSRP();
await onboardingPasswordPage.createImportedWalletPassword();
};

export const completeCreateNewWalletOnboardingFlow = async (driver: Driver) => {
console.log('start to complete create new wallet onboarding flow ');
await createNewWalletOnboardingFlow(driver);
const onboardingCompletePage = new OnboardingCompletePage(driver);
await onboardingCompletePage.check_pageIsLoaded();
await onboardingCompletePage.check_congratulationsMessageIsDisplayed();
Expand Down
23 changes: 12 additions & 11 deletions test/e2e/page-objects/pages/header-navbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,31 +43,32 @@ class HeaderNavbar {
}

async lockMetaMask(): Promise<void> {
await this.driver.clickElement(this.accountOptionMenu);
// fix race condition with mmi build
if (process.env.MMI) {
await this.driver.waitForSelector(this.mmiPortfolioButton);
}
await this.openAccounOptionMenu();
await this.driver.clickElement(this.lockMetaMaskButton);
}

async openAccountMenu(): Promise<void> {
await this.driver.clickElement(this.accountMenuButton);
}

async openAccounOptionMenu(): Promise<void> {
console.log('Open account options menu');
await this.driver.clickElement(this.accountOptionMenu);
// fix race condition with mmi build
if (process.env.MMI) {
await this.driver.waitForSelector(this.mmiPortfolioButton);
}
}

async openSnapListPage(): Promise<void> {
console.log('Open account snap page');
await this.driver.clickElement(this.accountOptionMenu);
await this.openAccounOptionMenu();
await this.driver.clickElement(this.accountSnapButton);
}

async openSettingsPage(): Promise<void> {
console.log('Open settings page');
await this.driver.clickElement(this.accountOptionMenu);
// fix race condition with mmi build
if (process.env.MMI) {
await this.driver.waitForSelector(this.mmiPortfolioButton);
}
await this.openAccounOptionMenu();
await this.driver.clickElement(this.settingsButton);
}

Expand Down
11 changes: 8 additions & 3 deletions test/e2e/tests/privacy/account-tracker-api-usage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { MockedEndpoint } from 'mockttp';
import FixtureBuilder from '../../fixture-builder';
import {
defaultGanacheOptions,
unlockWallet,
veryLargeDelayMs,
withFixtures,
} from '../../helpers';
import { Mockttp } from '../../mock-e2e';
import HomePage from '../../page-objects/pages/homepage';
import { loginWithoutBalanceValidation } from '../../page-objects/flows/login.flow';

async function mockInfura(mockServer: Mockttp): Promise<MockedEndpoint[]> {
const blockNumber = { value: 0 };
Expand Down Expand Up @@ -122,7 +123,9 @@ describe('Account Tracker API Usage', function () {
)} request has been made to infura before opening the UI`,
);

await unlockWallet(driver);
await loginWithoutBalanceValidation(driver);
const homepage = new HomePage(driver);
await homepage.check_pageIsLoaded();
await driver.delay(veryLargeDelayMs);

allInfuraJsonRpcRequests = await getAllInfuraJsonRpcRequests(
Expand Down Expand Up @@ -158,7 +161,9 @@ describe('Account Tracker API Usage', function () {
testSpecificMock: mockInfura,
},
async ({ driver, mockedEndpoint }) => {
await unlockWallet(driver);
await loginWithoutBalanceValidation(driver);
const homepage = new HomePage(driver);
await homepage.check_pageIsLoaded();
await driver.delay(veryLargeDelayMs);
const initialInfuraJsonRpcRequests = await getAllInfuraJsonRpcRequests(
mockedEndpoint,
Expand Down
188 changes: 188 additions & 0 deletions test/e2e/tests/privacy/onboarding-infura-call-privacy.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import assert from 'assert';
import { Mockttp, MockedEndpoint } from 'mockttp';
import { withFixtures, regularDelayMs } from '../../helpers';
import FixtureBuilder from '../../fixture-builder';
import HomePage from '../../page-objects/pages/homepage';
import OnboardingCompletePage from '../../page-objects/pages/onboarding/onboarding-complete-page';
import {
importSRPOnboardingFlow,
createNewWalletOnboardingFlow,
} from '../../page-objects/flows/onboarding.flow';

// Mock function implementation for Infura requests
async function mockInfura(mockServer: Mockttp): Promise<MockedEndpoint[]> {
const infuraUrl =
'https://mainnet.infura.io/v3/00000000000000000000000000000000';
const sampleAddress = '1111111111111111111111111111111111111111';
return [
await mockServer
.forPost(infuraUrl)
.withJsonBodyIncluding({ method: 'eth_blockNumber' })
.thenCallback(() => {
return {
statusCode: 200,
json: {
jsonrpc: '2.0',
id: '1111111111111111',
result: '0x1',
},
};
}),
await mockServer
.forPost(infuraUrl)
.withJsonBodyIncluding({ method: 'eth_getBalance' })
.thenCallback(() => {
return {
statusCode: 200,
json: {
jsonrpc: '2.0',
id: '1111111111111111',
result: '0x0',
},
};
}),
await mockServer
.forPost(infuraUrl)
.withJsonBodyIncluding({ method: 'eth_getBlockByNumber' })
.thenCallback(() => {
return {
statusCode: 200,
json: {
jsonrpc: '2.0',
id: '1111111111111111',
result: {},
},
};
}),
await mockServer
.forPost(infuraUrl)
.withJsonBodyIncluding({ method: 'eth_call' })
.thenCallback(() => {
return {
statusCode: 200,
json: {
jsonrpc: '2.0',
id: '1111111111111111',
result: `0x000000000000000000000000${sampleAddress}`,
},
};
}),
await mockServer
.forPost(infuraUrl)
.withJsonBodyIncluding({ method: 'net_version' })
.thenCallback(() => {
return {
statusCode: 200,
json: { id: 8262367391254633, jsonrpc: '2.0', result: '1337' },
};
}),
];
}

describe('MetaMask onboarding @no-mmi', function () {
it("doesn't make any network requests to infura before create new wallet onboarding is completed", async function () {
await withFixtures(
{
fixtures: new FixtureBuilder({ onboarding: true })
.withNetworkControllerOnMainnet()
.build(),
title: this.test?.fullTitle(),
testSpecificMock: mockInfura,
},
async ({ driver, mockedEndpoint: mockedEndpoints }) => {
await createNewWalletOnboardingFlow(driver);

// Check no requests are made before completing creat new wallet onboarding
// Intended delay to ensure we cover at least 1 polling loop of time for the network request
await driver.delay(regularDelayMs);
for (const mockedEndpoint of mockedEndpoints) {
const isPending = await mockedEndpoint.isPending();
assert.equal(
isPending,
true,
`${mockedEndpoint} mock should still be pending before onboarding`,
);
const requests = await mockedEndpoint.getSeenRequests();
assert.equal(
requests.length,
0,
`${mockedEndpoint} should make no requests before onboarding`,
);
}

// complete create new wallet onboarding
const onboardingCompletePage = new OnboardingCompletePage(driver);
await onboardingCompletePage.check_pageIsLoaded();
await onboardingCompletePage.completeOnboarding();
const homePage = new HomePage(driver);
await homePage.check_pageIsLoaded();
await homePage.check_expectedBalanceIsDisplayed();

// network requests happen here
for (const mockedEndpoint of mockedEndpoints) {
await driver.wait(async () => {
const isPending = await mockedEndpoint.isPending();
return isPending === false;
}, driver.timeout);

const requests = await mockedEndpoint.getSeenRequests();
assert.equal(
requests.length > 0,
true,
`${mockedEndpoint} should make requests after onboarding`,
);
}
},
);
});

it("doesn't make any network requests to infura before onboarding by import is completed", async function () {
await withFixtures(
{
fixtures: new FixtureBuilder({ onboarding: true })
.withNetworkControllerOnMainnet()
.build(),
title: this.test?.fullTitle(),
testSpecificMock: mockInfura,
},
async ({ driver, mockedEndpoint: mockedEndpoints }) => {
await importSRPOnboardingFlow(driver);

// Check no requests before completing onboarding
// Intended delay to ensure we cover at least 1 polling loop of time for the network request
await driver.delay(regularDelayMs);
for (const mockedEndpoint of mockedEndpoints) {
const requests = await mockedEndpoint.getSeenRequests();
assert.equal(
requests.length,
0,
`${mockedEndpoint} should make no requests before import wallet onboarding complete`,
);
}

// complete import wallet onboarding
const onboardingCompletePage = new OnboardingCompletePage(driver);
await onboardingCompletePage.check_pageIsLoaded();
await onboardingCompletePage.completeOnboarding();
const homePage = new HomePage(driver);
await homePage.check_pageIsLoaded();
await homePage.check_expectedBalanceIsDisplayed();

// requests happen here
for (const mockedEndpoint of mockedEndpoints) {
await driver.wait(async () => {
const isPending = await mockedEndpoint.isPending();
return isPending === false;
}, driver.timeout);

const requests = await mockedEndpoint.getSeenRequests();
assert.equal(
requests.length > 0,
true,
`${mockedEndpoint} should make requests after onboarding`,
);
}
},
);
});
});
Loading