Skip to content

Commit 60361c2

Browse files
feat: migrates browser related POMs to typescript and the new framework (#17420)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** - Adds an extra type in one of the assertion class helper - Migrates to the new withFixtures helper ### 🚀 Generic stats: - 27 Page object files migrated to ts - 23 selectors migrated to ts <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.
1 parent 2737a7d commit 60361c2

21 files changed

+458
-377
lines changed
Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
11
/* eslint-disable import/no-commonjs */
22
require('@babel/register');
3-
require('ts-node/register');
3+
4+
// Configure ts-node with options that will properly handle .d.ts files
5+
require('ts-node').register({
6+
transpileOnly: true,
7+
compilerOptions: {
8+
module: 'commonjs',
9+
target: 'es2017',
10+
allowJs: true,
11+
esModuleInterop: true,
12+
skipLibCheck: true,
13+
},
14+
files: true,
15+
});
16+
417
require('./json-rpc-coverage.js');

e2e/framework/Assertions.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ export default class Assertions {
1111
* Assert element is visible with auto-retry
1212
*/
1313
static async expectElementToBeVisible(
14-
detoxElement: DetoxElement | WebElement | DetoxMatcher,
14+
detoxElement:
15+
| DetoxElement
16+
| WebElement
17+
| DetoxMatcher
18+
| IndexableNativeElement,
1519
options: AssertionOptions = {},
1620
): Promise<void> {
1721
const {
@@ -43,7 +47,11 @@ export default class Assertions {
4347
* Assert element is not visible with auto-retry
4448
*/
4549
static async expectElementToNotBeVisible(
46-
detoxElement: DetoxElement | WebElement,
50+
detoxElement:
51+
| DetoxElement
52+
| WebElement
53+
| DetoxMatcher
54+
| IndexableNativeElement,
4755
options: AssertionOptions = {},
4856
): Promise<void> {
4957
const {

e2e/framework/fixtures/FixtureBuilder.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
PopularNetworksList,
1616
} from '../../resources/networks.e2e';
1717
import { BackupAndSyncSettings } from '../types';
18+
import { logger } from '../logger';
1819

1920
export const DEFAULT_FIXTURE_ACCOUNT =
2021
'0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3';
@@ -816,19 +817,42 @@ class FixtureBuilder {
816817
};
817818
}
818819

820+
withPermissionControllerConnectedToTestDapp() {
821+
return this.withPermissionControllerConnectedToMultipleTestDapps();
822+
}
823+
819824
/**
820825
* Connects the PermissionController to a test dapp with specific accounts permissions and origins.
826+
* For the time being, you're only able to connect 2 dapps because one will have the origin as
827+
* localhost and the other dapp will have the specific device equivalent localhost.
828+
* We could hardcoded the state but then Wallet behavior would be incorrectly checked.
821829
* @param {Object[]} additionalPermissions - Additional permissions to merge for each test dapp instance. They should be passed in the correct order
822830
* @returns {FixtureBuilder} - The FixtureBuilder instance for method chaining.
823831
*/
824832
withPermissionControllerConnectedToMultipleTestDapps(
825833
additionalPermissions: Record<string, unknown>[] = [{}],
826834
) {
835+
if (additionalPermissions.length > 2) {
836+
logger.error(
837+
'You can only connect 2 dapps at a time since permissions are given based on the origin.',
838+
);
839+
throw new Error(
840+
'You can only connect 2 dapps at a time since permissions are given based on the origin.',
841+
);
842+
}
827843
let allPermissions = {};
828-
for (const permission of additionalPermissions) {
844+
for (let i = 0; i < additionalPermissions.length; i++) {
845+
// This needs to be escalated as permissions are given based on the origin and it's impossible to have distinct
846+
// permissions for the same origin.
847+
if (i === 0) {
848+
additionalPermissions[i].origin = DAPP_URL;
849+
} else {
850+
additionalPermissions[i].origin =
851+
device.getPlatform() === 'android' ? '10.0.2.2' : '127.0.0.1';
852+
}
829853
const testDappPermissions = this.createPermissionControllerConfig(
830-
permission,
831-
device.getPlatform() === 'android' ? '10.0.2.2' : '127.0.0.1',
854+
additionalPermissions[i],
855+
additionalPermissions[i].origin as string,
832856
);
833857
allPermissions = merge(allPermissions, testDappPermissions);
834858
}

e2e/pages/Browser/AddBookmarkView.js renamed to e2e/pages/Browser/AddBookmarkView.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
import { AddBookmarkViewSelectorsIDs } from '../../selectors/Browser/AddBookmarkView.selectors';
2-
import Gestures from '../../utils/Gestures';
3-
import Matchers from '../../utils/Matchers';
2+
import Gestures from '../../framework/Gestures';
3+
import Matchers from '../../framework/Matchers';
44

55
class AddFavoritesView {
6-
get container() {
6+
get container(): DetoxElement {
77
return Matchers.getElementByID(AddBookmarkViewSelectorsIDs.CONTAINER);
88
}
99

10-
get addBookmarkButton() {
10+
get addBookmarkButton(): DetoxElement {
1111
return device.getPlatform() === 'ios'
1212
? Matchers.getElementByID(AddBookmarkViewSelectorsIDs.CONFIRM_BUTTON)
1313
: Matchers.getElementByLabel(AddBookmarkViewSelectorsIDs.CONFIRM_BUTTON);
1414
}
1515

16-
async tapAddBookmarksButton() {
17-
await Gestures.waitAndTap(this.addBookmarkButton);
16+
async tapAddBookmarksButton(): Promise<void> {
17+
await Gestures.waitAndTap(this.addBookmarkButton, {
18+
elemDescription: 'Tap on the add bookmark button',
19+
});
1820
}
1921
}
2022

e2e/pages/Browser/BrowserView.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,10 @@ class Browser {
218218
await device.enableSynchronization(); // re-enabling synchronization
219219
}
220220

221+
/**
222+
* @deprecated - please migrate to the new Framework
223+
* @returns {Promise<void>}
224+
*/
221225
async waitForBrowserPageToLoad(): Promise<void> {
222226
await TestHelpers.delay(5000);
223227
}

e2e/pages/Browser/ConnectBottomSheet.js

Lines changed: 0 additions & 80 deletions
This file was deleted.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import {
2+
ConnectAccountBottomSheetSelectorsIDs,
3+
ConnectAccountBottomSheetSelectorsText,
4+
} from '../../selectors/Browser/ConnectAccountBottomSheet.selectors';
5+
import Matchers from '../../framework/Matchers';
6+
import Gestures from '../../framework/Gestures';
7+
import { CommonSelectorsIDs } from '../../selectors/Common.selectors';
8+
9+
class ConnectBottomSheet {
10+
get container(): DetoxElement {
11+
return Matchers.getElementByID(
12+
ConnectAccountBottomSheetSelectorsIDs.CONTAINER,
13+
);
14+
}
15+
get connectButton(): DetoxElement {
16+
return device.getPlatform() === 'android'
17+
? Matchers.getElementByLabel(CommonSelectorsIDs.CONNECT_BUTTON)
18+
: Matchers.getElementByID(CommonSelectorsIDs.CONNECT_BUTTON);
19+
}
20+
21+
get connectAccountsButton(): DetoxElement {
22+
return Matchers.getElementByText(
23+
ConnectAccountBottomSheetSelectorsText.CONNECT_ACCOUNTS,
24+
);
25+
}
26+
27+
get importButton(): DetoxElement {
28+
return Matchers.getElementByText(
29+
ConnectAccountBottomSheetSelectorsText.IMPORT_ACCOUNT,
30+
);
31+
}
32+
33+
get selectAllButton(): DetoxElement {
34+
return Matchers.getElementByText(
35+
ConnectAccountBottomSheetSelectorsText.SELECT_ALL,
36+
);
37+
}
38+
39+
get selectMultiButton(): DetoxElement {
40+
return Matchers.getElementByID(
41+
ConnectAccountBottomSheetSelectorsIDs.SELECT_MULTI_BUTTON,
42+
);
43+
}
44+
45+
get cancelButton(): DetoxElement {
46+
return Matchers.getElementByID(
47+
ConnectAccountBottomSheetSelectorsIDs.CANCEL_BUTTON,
48+
);
49+
}
50+
51+
async tapCancelButton(): Promise<void> {
52+
await Gestures.waitAndTap(this.cancelButton, {
53+
elemDescription: 'Tap on the cancel button',
54+
});
55+
}
56+
57+
async tapConnectButton(): Promise<void> {
58+
await Gestures.waitAndTap(this.connectButton, {
59+
elemDescription: 'Tap on the connect button',
60+
});
61+
}
62+
63+
async tapConnectMultipleAccountsButton(): Promise<void> {
64+
await Gestures.waitAndTap(this.connectAccountsButton, {
65+
elemDescription: 'Tap on the connect multiple accounts button',
66+
});
67+
}
68+
69+
async tapImportAccountOrHWButton(): Promise<void> {
70+
await Gestures.waitAndTap(this.importButton, {
71+
elemDescription: 'Tap on the import account or hardware wallet button',
72+
});
73+
}
74+
75+
async tapSelectAllButton(): Promise<void> {
76+
await Gestures.waitAndTap(this.selectAllButton, {
77+
elemDescription: 'Tap on the select all button',
78+
});
79+
}
80+
81+
async tapAccountConnectMultiSelectButton(): Promise<void> {
82+
await Gestures.waitAndTap(this.selectMultiButton, {
83+
elemDescription: 'Tap on the account connect multi select button',
84+
});
85+
}
86+
87+
async scrollToBottomOfModal(): Promise<void> {
88+
await Gestures.swipe(this.container, 'down', {
89+
speed: 'slow',
90+
elemDescription: 'Scroll to the bottom of the modal',
91+
});
92+
}
93+
}
94+
95+
export default new ConnectBottomSheet();

0 commit comments

Comments
 (0)