Skip to content

Commit

Permalink
test: deprecate gestures in helpers.js file (#13059)
Browse files Browse the repository at this point in the history
<!--
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**

The helpers.js file was a bit of a dumping ground for all test actions:
Selecting elements, asserting elements, and using utility methods like
delays, deep linking, launching the app, and interacting with elements.
We did some work last year to separate the various types of logic.

Locating elements - `Matchers.js`
Interacting with elements - `Guestures.js`
Asserting elements - `Assertions.js`

They all live in the e2e/utils folder. 

This PR aims to remove and deprecate all test actions within the
helper's file. Once this PR is merged, we can avoid engineers using
anti-patterns within the e2e framework. The next step is to extract all
logic from the testHelpers and place them in the appropriate utility
class.


## **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.
  • Loading branch information
cortisiko authored Jan 23, 2025
1 parent d6b3348 commit cb4ff03
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 52 deletions.
137 changes: 120 additions & 17 deletions e2e/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import Utilities from './utils/Utilities';
import { resolveConfig } from 'detox/internals';

export default class TestHelpers {
/**
* @deprecated Use Guestures Class to accomplish this.
*/
static async waitAndTap(elementId, timeout, index) {
await waitFor(element(by.id(elementId)))
.toBeVisible()
Expand All @@ -18,87 +21,124 @@ export default class TestHelpers {
.atIndex(index || 0)
.tap();
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static async waitAndTapText(text, timeout) {
await waitFor(element(by.text(text)))
.toBeVisible()
.withTimeout(timeout || 8000);

return element(by.text(text)).tap();
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static tap(elementId) {
return element(by.id(elementId)).tap();
}
/**
* @deprecated Use Guestures Class to accomplish this.
*/
static tapByDescendentTestID(parentElement, ChildElement) {
return element(
by.id(parentElement).withDescendant(by.id(ChildElement)),
).tap();
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static tapByText(text, index) {
return element(by.text(text))
.atIndex(index || 0)
.tap();
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static doubleTapByText(text, index) {
return element(by.text(text))
.atIndex(index || 0)
.multiTap(2);
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static tapAtPoint(elementId, point) {
return element(by.id(elementId)).tap(point);
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static tapItemAtIndex(elementID, index) {
return element(by.id(elementID))
.atIndex(index || 0)
.tap();
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static tapItemAtIndexByLabel(elementID, index) {
return element(by.label(elementID, index))
.atIndex(index || 0)
.tap();
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static async typeText(elementId, text) {
await TestHelpers.tap(elementId);
return element(by.id(elementId)).typeText(text);
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static async typeNumbers(elementId, text, submitLabel) {
await element(by.id(elementId)).replaceText(text.replace('\n', ''));
return element(by.label(submitLabel)).atIndex(0).tap();
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static async typeTextAndHideKeyboard(elementId, text) {
if (device.getPlatform() === 'android') {
await TestHelpers.clearField(elementId);
}
await TestHelpers.typeText(elementId, text + '\n');
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static async clearField(elementId) {
return element(by.id(elementId)).replaceText('');
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static async tapAndLongPress(elementId) {
await TestHelpers.tap(elementId);
return element(by.id(elementId)).longPress(2000);
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static async tapAndLongPressAtIndex(elementId, index) {
return element(by.id(elementId))
.atIndex(index || 0)
.longPress(2000);
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static async replaceTextInField(elementId, text) {
return element(by.id(elementId)).replaceText(text);
}
/**
* @deprecated Use Guestures Class to accomplish this.
*/

static tapAlertWithButton(text, index) {
if (device.getPlatform() === 'android') {
Expand All @@ -109,6 +149,10 @@ export default class TestHelpers {

return element(by.label(text)).atIndex(0).tap();
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static async waitAndTapByLabel(text, timeout, index) {
await waitFor(element(by.label(text)))
.toBeVisible()
Expand All @@ -118,12 +162,16 @@ export default class TestHelpers {
.atIndex(index || 0)
.tap();
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static async tapWebviewElement(elementId) {
// this method only words on android: https://wix.github.io/Detox/docs/api/webviews/
return web.element(by.web.id(elementId)).tap();
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static async swipe(elementId, direction, speed, percentage, xStart, yStart) {
await element(by.id(elementId)).swipe(
direction,
Expand All @@ -133,18 +181,30 @@ export default class TestHelpers {
yStart,
);
}
/**
* @deprecated Use Guestures Class to accomplish this.
*/
static async swipeByLabel(elementId, direction, speed, percentage) {
await element(by.label(elementId)).swipe(direction, speed, percentage);
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static async swipeByText(text, direction, speed, percentage) {
await element(by.text(text)).atIndex(0).swipe(direction, speed, percentage);
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static async scrollTo(scrollViewId, edge) {
await element(by.id(scrollViewId)).scrollTo(edge);
}

/**
* @deprecated Use Guestures Class to accomplish this.
*/
static async scrollUpTo(elementId, distance, direction) {
await element(by.id(elementId)).scroll(distance, direction);
}
Expand All @@ -161,22 +221,34 @@ export default class TestHelpers {
});
}

/**
* @deprecated Use Assertion Class to accomplish this.
*/
static async checkIfVisible(elementId) {
return await waitFor(element(by.id(elementId)))
.toBeVisible()
.withTimeout(15000);
}

/**
* @deprecated Use Assertion Class to accomplish this.
*/
static async checkIfNotVisible(elementId) {
return await waitFor(element(by.id(elementId)))
.not.toBeVisible()
.withTimeout(10000);
}

/**
* @deprecated Use Assertion Class to accomplish this.
*/
static async checkIfElementWithTextIsNotVisible(text) {
return await expect(element(by.text(text)).atIndex(0)).not.toBeVisible();
}

/**
* @deprecated Use Assertion Class to accomplish this.
*/
static async checkIfElementNotToHaveText(elementId, text) {
await waitFor(element(by.id(elementId)))
.toBeVisible()
Expand All @@ -185,13 +257,19 @@ export default class TestHelpers {
return expect(element(by.id(elementId))).not.toHaveText(text);
}

/**
* @deprecated Use Assertion Class to accomplish this.
*/
static async checkIfExists(elementId) {
await waitFor(element(by.id(elementId)))
.toBeVisible()
.withTimeout(10000);
return expect(element(by.id(elementId))).toExist();
}

/**
* @deprecated Use Assertion Class to accomplish this.
*/
static async checkIfHasText(elementId, text) {
await waitFor(element(by.id(elementId)))
.toBeVisible()
Expand All @@ -200,25 +278,41 @@ export default class TestHelpers {
return expect(element(by.id(elementId))).toHaveText(text);
}

/**
* @deprecated Use Assertion Class to accomplish this.
*/
static async checkIfElementWithTextIsVisible(text, index) {
return await waitFor(element(by.text(text)).atIndex(index || 0))
.toBeVisible()
.withTimeout(10000);
}

/**
* @deprecated Use Assertion Class to accomplish this.
*/
static async checkIfElementByTextIsVisible(text, timeout = 25000) {
return await waitFor(element(by.text(text)))
.toBeVisible()
.withTimeout(timeout);
}

/**
* @deprecated Use Assertion Class to accomplish this.
*/
static async checkIfElementHasString(elementID, text) {
return expect(element(by.id(elementID))).toString(text);
}

/**
* @deprecated Use Assertion Class to accomplish this.
*/
static checkIfToggleIsOn(elementID) {
return expect(element(by.id(elementID))).toHaveToggleValue(true);
}

/**
* @deprecated Use Assertion Class to accomplish this.
*/
static checkIfToggleIsOff(elementID) {
return expect(element(by.id(elementID))).toHaveToggleValue(false);
}
Expand All @@ -240,6 +334,9 @@ export default class TestHelpers {
});
} // Detox has no waits for webview elements visibility. Here is the custom one.

/**
* @deprecated Use Assertion Class to accomplish this.
*/
static async waitForWebElementToBeVisibleById(elementId, timeout = 15000) {
const start = Date.now();
while (Date.now() - start < timeout) {
Expand All @@ -253,6 +350,9 @@ export default class TestHelpers {
}
throw new Error('Element with ' + elementId + ' not found');
}
/**
* @deprecated Use Assertion Class to accomplish this.
*/

static async retry(maxAttempts, testLogic) {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
Expand Down Expand Up @@ -293,7 +393,9 @@ export default class TestHelpers {
}

static async launchAppForDebugBuild(platform, launchOptions) {
const deepLinkUrl = this.getDeepLinkUrl(this.getDevLauncherPackagerUrl(platform));
const deepLinkUrl = this.getDeepLinkUrl(
this.getDevLauncherPackagerUrl(platform),
);

if (platform === 'ios') {
await device.launchApp(launchOptions);
Expand All @@ -304,15 +406,16 @@ export default class TestHelpers {

return device.launchApp({
url: deepLinkUrl,
...launchOptions
...launchOptions,
});
}

static getDeepLinkUrl(url) {
return `expo-metamask://expo-development-client/?url=${encodeURIComponent(url)}`;
return `expo-metamask://expo-development-client/?url=${encodeURIComponent(
url,
)}`;
}


static getDevLauncherPackagerUrl(platform) {
return `http://localhost:8081/index.bundle?platform=${platform}&dev=true&minify=false&disableOnboarding=1`;
}
Expand Down
4 changes: 3 additions & 1 deletion e2e/pages/Transactions/ActivitiesView.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ class ActivitiesView {
const element = this.swapActivityTitle(sourceToken, destinationToken);
await Gestures.waitAndTap(element);
}

async tapConfirmedTransaction() {
await Gestures.waitAndTap(this.confirmedLabel);
}
async swipeDown() {
await Gestures.swipe(this.container, 'down', 'slow', 0.5);
}
Expand Down
14 changes: 11 additions & 3 deletions e2e/pages/wallet/EditAccountNameView.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,24 @@ import { EditAccountNameSelectorIDs } from '../../selectors/wallet/EditAccountNa

class EditAccountNameView {
get saveButton() {
return Matchers.getElementByID(EditAccountNameSelectorIDs.EDIT_ACCOUNT_NAME_SAVE);
return Matchers.getElementByID(
EditAccountNameSelectorIDs.EDIT_ACCOUNT_NAME_SAVE,
);
}

get accountNameInput() {
return Matchers.getElementByID(EditAccountNameSelectorIDs.ACCOUNT_NAME_INPUT);
return Matchers.getElementByID(
EditAccountNameSelectorIDs.ACCOUNT_NAME_INPUT,
);
}

async tapSave() {
await Gestures.waitAndTap(this.saveButton);
}

async updateAccountName(accountName) {
await Gestures.clearField(EditAccountNameView.accountNameInput);
await Gestures.typeTextAndHideKeyboard(this.accountNameInput, accountName);
}
}

export default new EditAccountNameView();
Loading

0 comments on commit cb4ff03

Please sign in to comment.