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 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
65 changes: 46 additions & 19 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 @@ -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,30 @@ class FixtureBuilder {
return this;
}

withRampsSelectedRegion(region = null) {
const defaultRegion = {
currencies: ['/currencies/fiat/xcd'],
emoji: '🇱🇨',
id: '/regions/lc',
name: 'Saint Lucia',
support: { buy: true, sell: true, recurringBuy: true },
unsupported: false,
recommended: false,
detected: false,
};

// Use the provided region or fallback to the default
this.fixture.state.fiatOrders.selectedRegionAgg = region ?? defaultRegion;
return this;
}
withRampsSelectedPaymentMethod() {
const paymentType = '/payments/debit-credit-card';

// Use the provided region or fallback to the default
this.fixture.state.fiatOrders.selectedPaymentMethodAgg = paymentType;
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 +845,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 +884,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 +937,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 +1018,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();
6 changes: 5 additions & 1 deletion e2e/resources/blacklistURLs.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
".*phishing-detection.cx.metamask.io/.*",
".*eth.llamarpc.com/.*",
".*token-api.metaswap.codefi.network/.*",
".*gas.api.cx.metamask.io/networks/*"
".*gas.api.cx.metamask.io/networks/.*",
".*clients3.google.com/generate_204.*",
".*pulse.walletconnect.org/batch.*",
".*accounts.api.cx.metamask.io/v2/accounts/.*",
".*exp.host/--/api/v2/development-sessions/.*"
]
}
2 changes: 1 addition & 1 deletion e2e/specs/networks/add-custom-rpc.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { CustomNetworks } from '../../resources/networks.e2e';

const fixtureServer = new FixtureServer();

describe(SmokeCore('Custom RPC Tests'), () => {
describe('Custom RPC Tests', () => {
beforeAll(async () => {
await TestHelpers.reverseServerPort();
const fixture = new FixtureBuilder().build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
'use strict';
import TestHelpers from '../../helpers';

import { loginToApp } from '../../viewHelper';
import { withFixtures } from '../../fixtures/fixture-helper';
import { SmokeCore } from '../../tags';
import FixtureBuilder from '../../fixtures/fixture-builder';

import SellGetStartedView from '../../pages/Ramps/SellGetStartedView';
import BuyGetStartedView from '../../pages/Ramps/BuyGetStartedView';

import Assertions from '../../utils/Assertions';
import NetworkAddedBottomSheet from '../../pages/Network/NetworkAddedBottomSheet';
import NetworkApprovalBottomSheet from '../../pages/Network/NetworkApprovalBottomSheet';
import NetworkEducationModal from '../../pages/Network/NetworkEducationModal';

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

beforeEach(async () => {
jest.setTimeout(150000);
});

it('should deep link to onramp on Base network', async () => {
const BuyDeepLink =
'metamask://buy?chainId=8453&address=0x833589fcd6edb6e08f4c7c32d4f71b54bda02913&amount=12';

await withFixtures(
{
fixture: new FixtureBuilder().withRampsSelectedRegion().build(),
restartDevice: true,
},
async () => {
await loginToApp();
await device.sendToHome();
await device.launchApp({
url: BuyDeepLink,
});

await Assertions.checkIfVisible(
await SellGetStartedView.getStartedButton,
);

await BuyGetStartedView.tapGetStartedButton();

await Assertions.checkIfVisible(NetworkApprovalBottomSheet.container);
await NetworkApprovalBottomSheet.tapApproveButton();
await NetworkAddedBottomSheet.tapSwitchToNetwork();
await Assertions.checkIfVisible(NetworkEducationModal.container);
await NetworkEducationModal.tapGotItButton();
await Assertions.checkIfTextIsDisplayed('USD Coin');
},
);
});
});
55 changes: 55 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,55 @@
'use strict';
import TestHelpers from '../../helpers';

import { loginToApp } from '../../viewHelper';
import { withFixtures } from '../../fixtures/fixture-helper';
import { SmokeCore } from '../../tags';
import FixtureBuilder from '../../fixtures/fixture-builder';

import SellGetStartedView from '../../pages/Ramps/SellGetStartedView';
import BuyGetStartedView from '../../pages/Ramps/BuyGetStartedView';

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

describe(SmokeCore('Buy Crypto Deeplinks'), () => {
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(
{
fixture: new FixtureBuilder()
.withRampsSelectedPaymentMethod()
.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);
await BuildQuoteView.tapDefaultToken('Ethereum');

await TokenSelectBottomSheet.tapTokenByName('DAI');
await Assertions.checkIfTextIsDisplayed('Dai Stablecoin');
await Assertions.checkIfTextIsDisplayed('$275');
},
);
});
});
89 changes: 89 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,89 @@
'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 NetworkApprovalBottomSheet from '../../pages/Network/NetworkApprovalBottomSheet';
import NetworkAddedBottomSheet from '../../pages/Network/NetworkAddedBottomSheet';
import NetworkEducationModal from '../../pages/Network/NetworkEducationModal';

describe(SmokeCore('Sell Crypto Deeplinks'), () => {
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';
const franceRegion = {
currencies: ['/currencies/fiat/eur'],
emoji: '🇫🇷',
id: '/regions/fr',
name: 'France',
support: { buy: true, sell: true, recurringBuy: true },
unsupported: false,
recommended: false,
detected: false,
};
await withFixtures(
{
fixture: new FixtureBuilder()
.withRampsSelectedRegion(franceRegion)
.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=56';

await withFixtures(
{
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 NetworkApprovalBottomSheet.tapApproveButton();
await NetworkAddedBottomSheet.tapSwitchToNetwork();
await Assertions.checkIfVisible(NetworkEducationModal.container);
await NetworkEducationModal.tapGotItButton();
},
);
});
});
Loading