Skip to content

Commit 0323573

Browse files
committed
Auto-dismiss ANR dialog during element waits
CI emulator occasionally raises a system "isn't responding" dialog (e.g. on Quickstep/launcher) under CPU pressure, which sits on top of the app and blocks every element lookup until dismissed, causing element-wait timeouts even though the underlying screen rendered fine.
1 parent 6642059 commit 0323573

1 file changed

Lines changed: 31 additions & 3 deletions

File tree

test/helpers/waiters.js

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
const { TIMEOUTS, SELECTORS, TEST_DATA } = require('./constants');
22
const { takeScreenshot } = require('./screenshot');
33

4+
const ANR_WAIT_BTN = 'android:id/aerr_wait';
5+
6+
/**
7+
* Dismiss the system "isn't responding" (ANR) dialog if present, by tapping "Wait".
8+
* The emulator can raise this on the launcher/app under CPU pressure, and it sits on
9+
* top of the app blocking every element lookup until dismissed.
10+
* @param {WebdriverIO.Browser} driver - WebDriver instance
11+
* @returns {Promise<boolean>} whether the dialog was found and dismissed
12+
*/
13+
async function dismissAnrDialogIfPresent(driver) {
14+
const waitBtn = await driver.$(`id=${ANR_WAIT_BTN}`);
15+
if (!(await waitBtn.isDisplayed().catch(() => false))) {
16+
return false;
17+
}
18+
console.log('⚠ ANR dialog detected, tapping "Wait"');
19+
await waitBtn.click().catch(() => {});
20+
return true;
21+
}
22+
423
/**
524
* Wait for an element to be displayed
625
* @param {WebdriverIO.Browser} driver - WebDriver instance
@@ -10,7 +29,16 @@ const { takeScreenshot } = require('./screenshot');
1029
*/
1130
async function waitForElement(driver, selector, timeout = TIMEOUTS.ELEMENT_DISPLAY) {
1231
const element = await driver.$(selector);
13-
await element.waitForDisplayed({ timeout });
32+
await driver.waitUntil(
33+
async () => {
34+
if (await element.isDisplayed().catch(() => false)) {
35+
return true;
36+
}
37+
await dismissAnrDialogIfPresent(driver);
38+
return false;
39+
},
40+
{ timeout, interval: 1000, timeoutMsg: `element ("${selector}") still not displayed after ${timeout}ms` }
41+
);
1442
return element;
1543
}
1644

@@ -55,8 +83,7 @@ async function enterPasscode(driver, passcode, keyboardSelector = '~keyboardNumb
5583
for (let i = 0; i < passcode.length; i++) {
5684
const digit = passcode[i];
5785
const selector = `${keyboardSelector}${digit}`;
58-
const button = await driver.$(selector);
59-
await button.waitForDisplayed({ timeout: TIMEOUTS.ELEMENT_DISPLAY });
86+
const button = await waitForElement(driver, selector, TIMEOUTS.ELEMENT_DISPLAY);
6087
await button.click();
6188
await driver.pause(TIMEOUTS.KEYPRESS_DELAY);
6289
console.log(`✓ Entered digit ${i + 1}/${passcode.length}`);
@@ -92,4 +119,5 @@ module.exports = {
92119
waitForTransition,
93120
enterPasscode,
94121
unlockWallet,
122+
dismissAnrDialogIfPresent,
95123
};

0 commit comments

Comments
 (0)