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: Add ramps URL scheme deeplinking e2e #12747

Merged
merged 20 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
61 changes: 41 additions & 20 deletions e2e/fixtures/fixture-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { merge } from 'lodash';
import { CustomNetworks, PopularNetworksList } from '../resources/networks.e2e';
import { CHAIN_IDS } from '@metamask/transaction-controller';

export const DEFAULT_FIXTURE_ACCOUNT = '0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3';
export const DEFAULT_FIXTURE_ACCOUNT =
'0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3';

const DAPP_URL = 'localhost';

Expand Down Expand Up @@ -447,7 +448,7 @@ class FixtureBuilder {
whitelist: [],
tabs: [
{
url: 'https://portfolio.metamask.io/explore?MetaMaskEntry=mobile/',
url: 'https://metamask.github.io/test-dapp/',
cortisiko marked this conversation as resolved.
Show resolved Hide resolved
id: 1692550481062,
},
],
Expand Down Expand Up @@ -627,6 +628,7 @@ class FixtureBuilder {
selectedRegionAgg: null,
selectedPaymentMethodAgg: null,
getStartedAgg: false,
getStartedSell: false,
authenticationUrls: [],
activationKeys: [],
},
Expand Down Expand Up @@ -696,8 +698,9 @@ class FixtureBuilder {
const { providerConfig } = data;

// Generate a unique key for the new network client ID
const newNetworkClientId = `networkClientId${Object.keys(networkController.networkConfigurationsByChainId).length + 1
}`;
const newNetworkClientId = `networkClientId${
Object.keys(networkController.networkConfigurationsByChainId).length + 1
}`;

// Define the network configuration
const networkConfig = {
Expand Down Expand Up @@ -776,6 +779,24 @@ class FixtureBuilder {
return this;
}

withRampsSelectedRegion() {
cortisiko marked this conversation as resolved.
Show resolved Hide resolved
const regionAgg = {
currencies: ['/currencies/fiat/xcd'],
emoji: '🇱🇨',
id: '/regions/lc',
name: 'Saint Lucia',
support: { buy: true, sell: true, recurringBuy: true },
unsupported: false,
recommended: false,
detected: false,
selectedPaymentMethodAgg: '/payments/debit-credit-card',
cortisiko marked this conversation as resolved.
Show resolved Hide resolved
};

this.fixture.state.fiatOrders.selectedRegionAgg = regionAgg;

return this;
}

/**
* Adds chain switching permission for specific chains.
* @param {string[]} chainIds - Array of chain IDs to permit (defaults to ['0x1']), other nexts like linea mainnet 0xe708
Expand Down Expand Up @@ -818,9 +839,10 @@ class FixtureBuilder {
const fixtures = this.fixture.state.engine.backgroundState;

// Generate a unique key for the new network client ID
const newNetworkClientId = `networkClientId${Object.keys(fixtures.NetworkController.networkConfigurationsByChainId)
.length + 1
}`;
const newNetworkClientId = `networkClientId${
Object.keys(fixtures.NetworkController.networkConfigurationsByChainId)
.length + 1
}`;

// Define the Ganache network configuration
const ganacheNetworkConfig = {
Expand Down Expand Up @@ -856,9 +878,10 @@ class FixtureBuilder {
const sepoliaConfig = CustomNetworks.Sepolia.providerConfig;

// Generate a unique key for the new network client ID
const newNetworkClientId = `networkClientId${Object.keys(fixtures.NetworkController.networkConfigurationsByChainId)
.length + 1
}`;
const newNetworkClientId = `networkClientId${
cortisiko marked this conversation as resolved.
Show resolved Hide resolved
Object.keys(fixtures.NetworkController.networkConfigurationsByChainId)
.length + 1
}`;

// Define the Sepolia network configuration
const sepoliaNetworkConfig = {
Expand Down Expand Up @@ -908,8 +931,9 @@ class FixtureBuilder {
} = network.providerConfig;

// Generate a unique key for the new network client ID
const newNetworkClientId = `networkClientId${Object.keys(networkConfigurationsByChainId).length + 1
}`;
const newNetworkClientId = `networkClientId${
cortisiko marked this conversation as resolved.
Show resolved Hide resolved
Object.keys(networkConfigurationsByChainId).length + 1
}`;

// Define the network configuration
const networkConfig = {
Expand Down Expand Up @@ -988,19 +1012,16 @@ class FixtureBuilder {
allTokens: {
[CHAIN_IDS.MAINNET]: {
[DEFAULT_FIXTURE_ACCOUNT]: tokens,
}
}
},
},
});
return this;
}

withIncomingTransactionPreferences(incomingTransactionPreferences) {
merge(
this.fixture.state.engine.backgroundState.PreferencesController,
{
showIncomingTransactions: incomingTransactionPreferences,
},
);
merge(this.fixture.state.engine.backgroundState.PreferencesController, {
cortisiko marked this conversation as resolved.
Show resolved Hide resolved
showIncomingTransactions: incomingTransactionPreferences,
});
return this;
}

Expand Down
4 changes: 4 additions & 0 deletions e2e/pages/Ramps/BuildQuoteView.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ class BuildQuoteView {
async tapCancelButton() {
await Gestures.waitAndTap(this.cancelButton);
}
async tapDefaultToken(token) {
cortisiko marked this conversation as resolved.
Show resolved Hide resolved
const tokenName = await Matchers.getElementByText(token);
await Gestures.waitAndTap(tokenName);
}
}

export default new BuildQuoteView();
12 changes: 12 additions & 0 deletions e2e/pages/Ramps/TokenSelectBottomSheet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Matchers from '../../utils/Matchers';
cortisiko marked this conversation as resolved.
Show resolved Hide resolved
import Gestures from '../../utils/Gestures';

class TokenSelectBottomSheet {
async tapTokenByName(token) {
const tokenName = await Matchers.getElementByText(token);

await Gestures.waitAndTap(tokenName);
}
}

export default new TokenSelectBottomSheet();
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { mockEvents } from '../../api-mocking/mock-config/mock-events';
import Assertions from '../../utils/Assertions';
import { SmokeConfirmations } from '../../tags';

describe(SmokeConfirmations('Security Alert API - Send flow'), () => {
describe('Security Alert API - Send flow', () => {
cortisiko marked this conversation as resolved.
Show resolved Hide resolved
const BENIGN_ADDRESS_MOCK = '0x50587E46C5B96a3F6f9792922EC647F13E6EFAE4';

beforeAll(async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { mockEvents } from '../../../api-mocking/mock-config/mock-events';
import ConfirmationView from '../../../pages/Confirmation/ConfirmationView';
import { SmokeConfirmations } from '../../../tags';

describe(SmokeConfirmations('Security Alert API - Signature'), () => {
describe('Security Alert API - Signature', () => {
cortisiko marked this conversation as resolved.
Show resolved Hide resolved
beforeAll(async () => {
jest.setTimeout(2500000);
await TestHelpers.reverseServerPort();
Expand Down
96 changes: 96 additions & 0 deletions e2e/specs/ramps/deeplink-to-buy-flow.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
'use strict';
import { loginToApp } from '../../viewHelper';

import FixtureBuilder from '../../fixtures/fixture-builder';
import { withFixtures } from '../../fixtures/fixture-helper';

import TestHelpers from '../../helpers';
import SellGetStartedView from '../../pages/Ramps/SellGetStartedView';
import { SmokeCore } from '../../tags';
import BuyGetStartedView from '../../pages/Ramps/BuyGetStartedView';

import BuildQuoteView from '../../pages/Ramps/BuildQuoteView';
import Assertions from '../../utils/Assertions';

describe(SmokeCore('Buy Crypto'), () => {
beforeAll(async () => {
await TestHelpers.reverseServerPort();
});

beforeEach(async () => {
jest.setTimeout(150000);
});
it('should deep link to onramp ETH', async () => {
const buyLink = 'metamask://buy?chainId=1&amount=275';

await withFixtures(
{
dapp: true,
fixture: new FixtureBuilder()
.withPopularNetworks()
.withRampsSelectedRegion()
.build(),
restartDevice: true,
},
async () => {
await loginToApp();
await device.sendToHome();
await device.launchApp({
url: buyLink,
});
await Assertions.checkIfVisible(
await SellGetStartedView.getStartedButton,
);

await BuyGetStartedView.tapGetStartedButton();
await Assertions.checkIfVisible(BuildQuoteView.getQuotesButton);

/* Uncomment this once the bug:
"when I update the token after deep linking"
is updated

// await BuildQuoteView.tapDefaultToken();
// await TokenSelectBottomSheet.tapTokenByName('LINK');
// await Assertions.checkIfTextIsDisplayed('LINK');
*/
// await Assertions.checkIfTextIsDisplayed('XCD');
await Assertions.checkIfTextIsDisplayed('$275');
},
);
});

it('should deep link to onramp on popular network', async () => {
const unaddedNetworkBuyDeepLink =
'metamask://buy?chainId=1&address=0xc00e94cb662c3520282e6f5717214004a7f26888&amount=270';
// 'metamask://buy?chainId=8453&amount=4';
await withFixtures(
{
dapp: true,
fixture: new FixtureBuilder()
.withPopularNetworks()
.withRampsSelectedRegion()
.build(),
restartDevice: true,
},
async () => {
await loginToApp();
await device.sendToHome();
await device.launchApp({
url: unaddedNetworkBuyDeepLink,
});
await Assertions.checkIfVisible(
await SellGetStartedView.getStartedButton,
);

await BuyGetStartedView.tapGetStartedButton();
await Assertions.checkIfVisible(BuildQuoteView.getQuotesButton);

// await NetworkEducationModal.tapGotItButton();

await Assertions.checkIfTextIsDisplayed('$270');

// await Assertions.checkIfTextIsDisplayed('Brett');
},
);
});
});
81 changes: 81 additions & 0 deletions e2e/specs/ramps/deeplink-to-sell-flow.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
'use strict';
import { loginToApp } from '../../viewHelper';

import FixtureBuilder from '../../fixtures/fixture-builder';
import { withFixtures } from '../../fixtures/fixture-helper';

import TestHelpers from '../../helpers';
import SellGetStartedView from '../../pages/Ramps/SellGetStartedView';
import { SmokeCore } from '../../tags';

import BuildQuoteView from '../../pages/Ramps/BuildQuoteView';
import Assertions from '../../utils/Assertions';
import NetworkListModal from '../../pages/Network/NetworkListModal';
import NetworkApprovalBottomSheet from '../../pages/Network/NetworkApprovalBottomSheet';
import NetworkAddedBottomSheet from '../../pages/Network/NetworkAddedBottomSheet';
import { PopularNetworksList } from '../../resources/networks.e2e';
import NetworkEducationModal from '../../pages/Network/NetworkEducationModal';
describe(SmokeCore('Buy Crypto'), () => {
beforeAll(async () => {
await TestHelpers.reverseServerPort();
});

beforeEach(async () => {
jest.setTimeout(150000);
});
it('should deep link to offramp ETH', async () => {
const sellDeepLinkURL =
'metamask://sell?chainId=1&address=0x0000000000000000000000000000000000000000&amount=50';
await withFixtures(
{
dapp: true,
fixture: new FixtureBuilder().withRampsSelectedRegion().build(),
restartDevice: true,
},
async () => {
await loginToApp();

await device.openURL({
url: sellDeepLinkURL,
});
await Assertions.checkIfVisible(
await SellGetStartedView.getStartedButton,
);

await SellGetStartedView.tapGetStartedButton();
await Assertions.checkIfVisible(BuildQuoteView.getQuotesButton);

await Assertions.checkIfTextIsDisplayed('50 ETH');
},
);
});
it('Should deep link to an unsupported network in the off-ramp flow', async () => {
const unsupportedNetworkSellDeepLink = 'metamask://sell?chainId=2';
await withFixtures(
{
dapp: true,
fixture: new FixtureBuilder().withRampsSelectedRegion().build(),
restartDevice: true,
},
async () => {
await loginToApp();

await device.openURL({
url: unsupportedNetworkSellDeepLink,
});
await Assertions.checkIfVisible(
await SellGetStartedView.getStartedButton,
);

await SellGetStartedView.tapGetStartedButton();
await NetworkListModal.changeNetworkTo(
PopularNetworksList.Avalanche.providerConfig.nickname,
);

await NetworkApprovalBottomSheet.tapApproveButton();
await NetworkAddedBottomSheet.tapSwitchToNetwork();
await NetworkEducationModal.tapGotItButton();
},
);
});
});
Loading