From a0efbbfe8d5f5a8e41cd779c618392af81277d85 Mon Sep 17 00:00:00 2001 From: seaona <54408225+seaona@users.noreply.github.com> Date: Tue, 28 May 2024 15:38:34 +0200 Subject: [PATCH] fix: flaky test `onboarding @no-mmi doesn't make any network requests to infura before onboarding is completed/test-failure-screenshot.png` and `onboarding @no-mmi Clicks create a new wallet, accepts a secure password, reveals the Secret Recovery Phrase, confirm SRP/test-failure-screenshot.png` (#24813) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** This PR fixes more onboarding flakiness `onboarding @no-mmi doesn't make any network requests to infura before onboarding is completed/test-failure-screenshot.pn` and `onboarding @no-mmi Clicks create a new wallet, accepts a secure password, reveals the Secret Recovery Phrase, confirm SRP/test-failure-screenshot.png` . The error is originated when we try to click an element which is in stale state `StaleElementReferenceError: stale element reference: stale element not found in the current frame`. This is a race condition originated in the `clickElement` method, in the following way: 1. we try to find the clickable element 2. the element is refreshed in between 3. right after, we try to click the element from 1 --> this results in the element being stale, as the element we are trying to click is an old instance (1) instead of (2) ![Screenshot from 2024-05-28 14-43-54](https://github.com/MetaMask/metamask-extension/assets/54408225/da3a9fdc-28e3-4207-a843-65b9a333916d) Extra note: this race condition is surfaced in the Onboarding tests mostly (I've only seen it fail there, so far), since I suspect that the the actions we perform there, all refresh the same react component for onboarding, giving a window for this casuistic to happen - Circle ci job failures: https://app.circleci.com/pipelines/github/MetaMask/metamask-extension/83037/workflows/b435d63d-e50c-4dcd-af7d-4f6e0856ab6c/jobs/2967823/artifacts - Circle ci logs: ![Screenshot from 2024-05-28 14-37-47](https://github.com/MetaMask/metamask-extension/assets/54408225/e2b5e859-601b-4f45-a6c0-5141b1fa63e8) [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/24813?quickstart=1) ## **Related issues** Fixes: https://github.com/MetaMask/metamask-extension/issues/24602 (remaining items) ## **Manual testing steps** 1. Check ci or run onboarding tests multiple times (though I've never been able to repro this locally) ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Coding Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.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. --- test/e2e/webdriver/driver.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/test/e2e/webdriver/driver.js b/test/e2e/webdriver/driver.js index 198eb19f54a4..e4c8966b669b 100644 --- a/test/e2e/webdriver/driver.js +++ b/test/e2e/webdriver/driver.js @@ -396,9 +396,23 @@ class Driver { return elements.map((element) => wrapElementWithAPI(element, this)); } - async clickElement(rawLocator) { - const element = await this.findClickableElement(rawLocator); - await element.click(); + async clickElement(rawLocator, retries = 3) { + for (let attempt = 0; attempt < retries; attempt++) { + try { + const element = await this.findClickableElement(rawLocator); + await element.click(); + return; + } catch (error) { + if ( + error.name === 'StaleElementReferenceError' && + attempt < retries - 1 + ) { + await this.driver.delay(1000); + } else { + throw error; + } + } + } } /**