Skip to content
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
6 changes: 3 additions & 3 deletions e2e/api-specs/ConfirmationsRejectionRule.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { device } from 'detox';
import { addToQueue } from './helpers';
import paramsToObj from '@open-rpc/test-coverage/build/utils/params-to-obj';
import TestHelpers from '../helpers';
import Matchers from '../utils/Matchers';
import Gestures from '../utils/Gestures';
import Matchers from '../framework/Matchers';
import Gestures from '../framework/Gestures';
import ConnectBottomSheet from '../pages/Browser/ConnectBottomSheet';
import AssetWatchBottomSheet from '../pages/Transactions/AssetWatchBottomSheet';
import SpamFilterModal from '../pages/Browser/SpamFilterModal';
Expand All @@ -14,7 +14,7 @@ import ConnectedAccountsModal from '../pages/Browser/ConnectedAccountsModal';
// eslint-disable-next-line import/no-nodejs-modules
import fs from 'fs';

import Assertions from '../utils/Assertions';
import Assertions from '../framework/Assertions';
import PermissionSummaryBottomSheet from '../pages/Browser/PermissionSummaryBottomSheet';

const getBase64FromPath = async (path) => {
Expand Down
52 changes: 0 additions & 52 deletions e2e/framework/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,57 +89,5 @@ module.exports = {
],
},
},
{
files: ['**/e2e/pages/**/*.{js,ts}'],
rules: {
'no-restricted-imports': [
'error',
{
paths: [
{
name: '../utils/Gestures',
message:
'Do not import Gestures from e2e/utils/. Use e2e/framework/index.ts instead.',
},
{
name: '../utils/Gestures.js',
message:
'Do not import Gestures from e2e/utils/. Use e2e/framework/index.ts instead.',
},
{
name: '../utils/Assertions',
message:
'Do not import Assertions from e2e/utils/. Use e2e/framework/index.ts instead.',
},
{
name: '../utils/Assertions.js',
message:
'Do not import Assertions from e2e/utils/. Use e2e/framework/index.ts instead.',
},
{
name: '../utils/Utilities',
message:
'Do not import Utilities from e2e/utils/. Use e2e/framework/index.ts instead.',
},
{
name: '../utils/Utilities.js',
message:
'Do not import Utilities from e2e/utils/. Use e2e/framework/index.ts instead.',
},
{
name: '../utils/Matchers',
message:
'Do not import Matchers from e2e/utils/. Use e2e/framework/index.ts instead.',
},
{
name: '../utils/Matchers.js',
message:
'Do not import Matchers from e2e/utils/. Use e2e/framework/index.ts instead.',
},
],
},
],
},
},
],
};
12 changes: 12 additions & 0 deletions e2e/framework/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ export const DEFAULT_SOLANA_TEST_DAPP_PATH = path.join(
'dist',
);

/**
* The schemes for the E2E deep links.
* @enum {string}
* @example
* {
* E2EDeeplinkSchemes.PERPS,
* }
*/
export enum E2EDeeplinkSchemes {
PERPS = 'e2e://perps/',
}

/**
* The variants of the dapp to load for test.
* @enum {string}
Expand Down
26 changes: 18 additions & 8 deletions e2e/framework/DeepLink.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
/*
* Cross-platform deep link opener for Detox tests.
*/
import { createLogger } from './logger';
import { E2EDeeplinkSchemes } from './Constants';

// Import device from Detox types to avoid shadowing warnings
// eslint-disable-next-line @typescript-eslint/no-explicit-any
declare const device: any; // eslint-disable-line @typescript-eslint/no-explicit-any
const logger = createLogger({
name: 'E2E - DeepLink',
});

export async function openE2EUrl(url: string): Promise<void> {
// eslint-disable-next-line no-console
console.log(`[E2E] DeepLink open: ${url}`);
logger.debug(`Opening E2E DeepLink: ${url}`);
if (device.getPlatform() === 'ios' && device.openURL) {
await device.openURL({ url });
return;
Expand All @@ -17,9 +18,18 @@ export async function openE2EUrl(url: string): Promise<void> {
// On Android, our production manifest doesn't declare the custom "e2e" scheme.
// Reuse the already-declared "expo-metamask" scheme to transport the command.
// Mapping: e2e://perps/<path>?<query> -> expo-metamask://e2e/perps/<path>?<query>
const mappedUrl = url.startsWith('e2e://perps/')
? url.replace('e2e://perps/', 'expo-metamask://e2e/perps/')
: url;
let mappedUrl = url;
// Handle all E2EDeeplinkSchemes
for (const deeplinkScheme of Object.values(E2EDeeplinkSchemes)) {
if (url.startsWith(deeplinkScheme)) {
mappedUrl = url.replace(
deeplinkScheme,
`expo-metamask://${deeplinkScheme}`,
);
break;
}
}

if (device.openURL) {
await device.openURL({ url: mappedUrl });
return;
Expand Down
34 changes: 34 additions & 0 deletions e2e/framework/Gestures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,40 @@ export default class Gestures {
);
}

/**
* Type text into a web element within a webview using JavaScript injection.
* @param {Promise<Detox.IndexableWebElement>} element - The web element to type into.
* @param {string} text - The text to type.
*/
static async typeInWebElement(
elem: Promise<IndexableWebElement>,
text: string,
): Promise<void> {
try {
await (
await elem
).runScript(
(
el: {
focus: () => void;
value: string;
_valueTracker?: { setValue: (v: string) => void };
dispatchEvent: (event: { bubbles?: boolean }) => void;
},
value: string,
) => {
el.focus();
el.value = value;
el._valueTracker && el._valueTracker.setValue('');
el.dispatchEvent(new Event('input', { bubbles: true }));
},
[text],
);
} catch {
await this.typeText(elem, text);
}
}

/**
* Replace text in field with retry
* @returns A Promise that resolves when the text is successfully replaced
Expand Down
19 changes: 0 additions & 19 deletions e2e/framework/PerpsE2E.ts

This file was deleted.

2 changes: 1 addition & 1 deletion e2e/utils/SoftAssert.ts → e2e/framework/SoftAssert.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createLogger } from '../framework/logger';
import { createLogger } from './logger';

const logger = createLogger({
name: 'SoftAssert',
Expand Down
2 changes: 1 addition & 1 deletion e2e/framework/fixtures/FixtureHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
getLocalTestDappPort,
getMockServerPort,
} from './FixtureUtils';
import Utilities from '../../utils/Utilities';
import Utilities from '../../framework/Utilities';
import TestHelpers from '../../helpers';
import {
startMockServer,
Expand Down
2 changes: 1 addition & 1 deletion e2e/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
getMockServerPort,
getSecondTestDappPort,
} from './framework/fixtures/FixtureUtils';
import Utilities from './utils/Utilities';
import Utilities from './framework/Utilities';
import { resolveConfig } from 'detox/internals';
import { createLogger } from './framework/logger';

Expand Down
3 changes: 1 addition & 2 deletions e2e/init.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* eslint-env jest */
import { logger } from './framework';
import Utilities from './utils/Utilities';
import Utilities from './framework/Utilities';

/**
* Before all tests, modify the app launch arguments to include the blacklistURLs.
Expand Down
3 changes: 1 addition & 2 deletions e2e/pages/Browser/TestSnaps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import TestHelpers from '../../helpers';
import Assertions from '../../framework/Assertions';
import { IndexableWebElement } from 'detox/detox';
import Utilities from '../../framework/Utilities';
import LegacyGestures from '../../utils/Gestures';
import { ConfirmationFooterSelectorIDs } from '../../selectors/Confirmation/ConfirmationView.selectors';
import { waitForTestSnapsToLoad } from '../../viewHelper';
import { RetryOptions } from '../../framework';
Expand Down Expand Up @@ -315,7 +314,7 @@ class TestSnaps {
TestSnapInputSelectorWebIDS[locator],
) as Promise<IndexableWebElement>;
// New gestures currently don't support web elements
await LegacyGestures.typeInWebElement(webElement, message);
await Gestures.typeInWebElement(webElement, message);
}

async approveSignRequest() {
Expand Down
2 changes: 1 addition & 1 deletion e2e/specs/analytics/import-wallet.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
IDENTITY_TEAM_PASSWORD,
IDENTITY_TEAM_SEED_PHRASE,
} from '../identity/utils/constants';
import SoftAssert from '../../utils/SoftAssert';
import SoftAssert from '../../framework/SoftAssert';
import { withFixtures } from '../../framework/fixtures/FixtureHelper';
import FixtureBuilder from '../../framework/fixtures/FixtureBuilder';
import { Mockttp } from 'mockttp';
Expand Down
2 changes: 1 addition & 1 deletion e2e/specs/analytics/new-wallet.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { CreateNewWallet } from '../../viewHelper';
import TestHelpers from '../../helpers';
import Assertions from '../../framework/Assertions';
import { getEventsPayloads, onboardingEvents } from './helpers';
import SoftAssert from '../../utils/SoftAssert';
import SoftAssert from '../../framework/SoftAssert';
import { withFixtures } from '../../framework/fixtures/FixtureHelper';
import FixtureBuilder from '../../framework/fixtures/FixtureBuilder';

Expand Down
2 changes: 1 addition & 1 deletion e2e/specs/analytics/opt-out.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
getEventsPayloads,
onboardingEvents,
} from './helpers';
import SoftAssert from '../../utils/SoftAssert';
import SoftAssert from '../../framework/SoftAssert';

describe(
RegressionWalletPlatform(
Expand Down
2 changes: 1 addition & 1 deletion e2e/specs/card/card-button.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import FixtureBuilder from '../../framework/fixtures/FixtureBuilder';
import { testSpecificMock } from '../../api-mocking/mock-responses/cardholder-mocks';
import { EventPayload, getEventsPayloads } from '../analytics/helpers';
import CardHomeView from '../../pages/Card/CardHomeView';
import SoftAssert from '../../utils/SoftAssert';
import SoftAssert from '../../framework/SoftAssert';
import { CustomNetworks } from '../../resources/networks.e2e';

describe.skip(SmokeCard('Card NavBar Button'), () => {
Expand Down
2 changes: 1 addition & 1 deletion e2e/specs/card/card-home-add-funds.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import FixtureBuilder from '../../framework/fixtures/FixtureBuilder';
import { testSpecificMock } from '../../api-mocking/mock-responses/cardholder-mocks';
import { EventPayload, getEventsPayloads } from '../analytics/helpers';
import CardHomeView from '../../pages/Card/CardHomeView';
import SoftAssert from '../../utils/SoftAssert';
import SoftAssert from '../../framework/SoftAssert';
import { CustomNetworks } from '../../resources/networks.e2e';

describe.skip(SmokeCard('CardHome - Add Funds'), () => {
Expand Down
2 changes: 1 addition & 1 deletion e2e/specs/card/card-home-manage-card.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import FixtureBuilder from '../../framework/fixtures/FixtureBuilder';
import { testSpecificMock } from '../../api-mocking/mock-responses/cardholder-mocks';
import { EventPayload, getEventsPayloads } from '../analytics/helpers';
import CardHomeView from '../../pages/Card/CardHomeView';
import SoftAssert from '../../utils/SoftAssert';
import SoftAssert from '../../framework/SoftAssert';
import { CustomNetworks } from '../../resources/networks.e2e';

describe.skip(SmokeCard('CardHome - Manage Card'), () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
import TestDApp from '../../../pages/Browser/TestDApp';
import { DappVariants } from '../../../framework/Constants';
import { EventPayload, getEventsPayloads } from '../../analytics/helpers';
import SoftAssert from '../../../utils/SoftAssert';
import SoftAssert from '../../../framework/SoftAssert';
import { Mockttp } from 'mockttp';
import {
setupMockRequest,
Expand Down
2 changes: 1 addition & 1 deletion e2e/specs/multichain-accounts/delete-account.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
import AccountDetails from '../../pages/MultichainAccounts/AccountDetails';
import DeleteAccount from '../../pages/MultichainAccounts/DeleteAccount';
import Assertions from '../../framework/Assertions';
import Matchers from '../../utils/Matchers';
import Matchers from '../../framework/Matchers';
import WalletView from '../../pages/wallet/WalletView';
import TestHelpers from '../../helpers';
import AccountListBottomSheet from '../../pages/wallet/AccountListBottomSheet';
Expand Down
22 changes: 22 additions & 0 deletions e2e/specs/perps/helpers/perps-modifiers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { openE2EUrl } from '../../../framework/DeepLink';
import { E2EDeeplinkSchemes } from '../../../framework/Constants';

class PerpsE2EModifiers {
static async updateMarketPrice(symbol: string, price: string): Promise<void> {
await openE2EUrl(
`${E2EDeeplinkSchemes.PERPS}push-price?symbol=${encodeURIComponent(
symbol,
)}&price=${encodeURIComponent(price)}`,
);
}

static async triggerLiquidation(symbol: string): Promise<void> {
await openE2EUrl(
`${E2EDeeplinkSchemes.PERPS}force-liquidation?symbol=${encodeURIComponent(
symbol,
)}`,
);
}
}

export default PerpsE2EModifiers;
4 changes: 2 additions & 2 deletions e2e/specs/perps/perps-limit-long-fill.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import PerpsMarketListView from '../../pages/Perps/PerpsMarketListView';
import PerpsMarketDetailsView from '../../pages/Perps/PerpsMarketDetailsView';
import PerpsOrderView from '../../pages/Perps/PerpsOrderView';
import PerpsView from '../../pages/Perps/PerpsView';
import PerpsE2E from '../../framework/PerpsE2E';
import PerpsE2EModifiers from './helpers/perps-modifiers';

describe(RegressionTrade('Perps - ETH limit long fill'), () => {
it.skip('creates ETH limit long at -10%, shows open order, then fills after -15%', async () => {
Expand Down Expand Up @@ -63,7 +63,7 @@ describe(RegressionTrade('Perps - ETH limit long fill'), () => {

// Push the price -15% to ensure the order is executed
// Default ETH price in mock is 2500.00, -15% => 2125.00
await PerpsE2E.updateMarketPrice('ETH', '2125.00');
await PerpsE2EModifiers.updateMarketPrice('ETH', '2125.00');

// Navigate to ETH again to verify order is gone and position is present
await TabBarComponent.tapActions();
Expand Down
10 changes: 5 additions & 5 deletions e2e/specs/perps/perps-position-liquidation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { PERPS_ARBITRUM_MOCKS } from '../../api-mocking/mock-responses/perps-arb
import PerpsMarketDetailsView from '../../pages/Perps/PerpsMarketDetailsView';
import PerpsView from '../../pages/Perps/PerpsView';
import { createLogger, LogLevel } from '../../framework/logger';
import PerpsE2E from '../../framework/PerpsE2E';
import PerpsE2EModifiers from './helpers/perps-modifiers';
import Assertions from '../../framework/Assertions';
import Matchers from '../../framework/Matchers';
import { PerpsPositionsViewSelectorsIDs } from '../../selectors/Perps/Perps.selectors';
Expand Down Expand Up @@ -54,17 +54,17 @@ describe(RegressionTrade('Perps Position'), () => {
await PerpsView.tapBackButtonMarketList();

// add price change and liquidation -> not yet liquidated
await PerpsE2E.updateMarketPrice('BTC', '80000.00');
await PerpsE2E.triggerLiquidation('BTC');
await PerpsE2EModifiers.updateMarketPrice('BTC', '80000.00');
await PerpsE2EModifiers.triggerLiquidation('BTC');
logger.info('🔥 E2E Mock: Liquidation triggered. Not yet liquidated');

// Assertion 1: still have 2 positions (the default and the recently opened)
await PerpsView.ensurePerpsTabPositionVisible('BTC', 5, 'long', 0);
await PerpsView.ensurePerpsTabPositionVisible('BTC', 3, 'long', 1);

// add price change and force liquidation - BTC below 30k triggers default BTC liquidation
await PerpsE2E.updateMarketPrice('BTC', '30000.00');
await PerpsE2E.triggerLiquidation('BTC');
await PerpsE2EModifiers.updateMarketPrice('BTC', '30000.00');
await PerpsE2EModifiers.triggerLiquidation('BTC');
logger.info('🔥 E2E Mock: Liquidation triggered. Liquidated');

// Assertion 2: only BTC 3x is visible
Expand Down
Loading
Loading