From f096a2f66e0fe8677afb02c051e614b647ddaf6f Mon Sep 17 00:00:00 2001 From: Kirill Zyusko Date: Fri, 27 Dec 2024 15:43:52 +0100 Subject: [PATCH] e2e: faster selection test (#747) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 📜 Description Improve speed of `scrollUpUntilElementIsBarelyVisible` + reduce its flakiness. ## 💡 Motivation and Context Before execution of this method was ~14s. Now it's 7s. Also a new version reduces flakiness. The approach is quite simple - knowing keyboard height, device screen height and element position we can easily calculate the necessary distance for scroll to place element straight above the keyboard. Using this approach we don't need to use infinite for-loop and we can scroll only one time 😎 It's not possible to get keyboard height using Detox, so I calculated these values myself (we kind of making a process of adding a new device a little bit more complicated, but e2e tests become more reliable, so I think it's okay to have these changes). ## 📢 Changelog ### E2E - added `keyboardHeight` property to device preferences; - use math calculations to get a scroll distance until element is almost hidden by keyboard; ## 🤔 How Has This Been Tested? Tested manually and CI. ## 📸 Screenshots (if appropriate): image ## 📝 Checklist - [x] CI successfully passed - [x] I added new mocks and corresponding unit-tests if library API was changed --- e2e/kit/helpers/actions/index.ts | 37 +++++++++++++----------- e2e/kit/helpers/env/devicePreferences.ts | 7 +++++ 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/e2e/kit/helpers/actions/index.ts b/e2e/kit/helpers/actions/index.ts index ac7cf2ea7..499584162 100644 --- a/e2e/kit/helpers/actions/index.ts +++ b/e2e/kit/helpers/actions/index.ts @@ -1,5 +1,4 @@ import colors from "colors/safe"; -import { expect } from "detox"; import { waitForElementById } from "../awaitable"; import { getDevicePreference } from "../env/devicePreferences"; @@ -129,26 +128,30 @@ export const scrollDownUntilElementIsVisible = async ( .scroll(100, "down", NaN, 0.5); }; +type Frame = { + x: number; + y: number; + width: number; + height: number; +}; + export const scrollUpUntilElementIsBarelyVisible = async ( scrollViewId: string, elementId: string, + threshold = 10, ): Promise => { - for (;;) { - await element(by.id(scrollViewId)).scroll(50, "up", 0.01, 0.5); - - try { - // verify that we can interact with element - if (device.getPlatform() === "ios") { - await expect(element(by.id(elementId))).toBeVisible(); - } else { - // on Android visible is always true - await element(by.id(elementId)).tap({ x: 0, y: 25 }); - } - } catch (e) { - await element(by.id(scrollViewId)).scroll(35, "down", 0.01, 0.5); - break; - } - } + const preference = getDevicePreference(); + const { frame } = (await element(by.id(elementId)).getAttributes()) as { + frame: Frame; + }; + const distance = + preference.height - + preference.keyboard - + frame.y - + frame.height - + threshold; + + await element(by.id(scrollViewId)).scroll(distance, "up", 0.01, 0.5); }; export const closeKeyboard = async (textInputId: string) => { diff --git a/e2e/kit/helpers/env/devicePreferences.ts b/e2e/kit/helpers/env/devicePreferences.ts index c9310b180..4f702148b 100644 --- a/e2e/kit/helpers/env/devicePreferences.ts +++ b/e2e/kit/helpers/env/devicePreferences.ts @@ -2,37 +2,44 @@ import parseDeviceName from "../../utils/parseDeviceName"; type Preference = { emojiButtonCoordinates?: { x: number; y: number }; + keyboard: number; width: number; height: number; }; const DEVICE_PREFERENCES: Record = { "e2e_emulator_28": { + keyboard: 980, emojiButtonCoordinates: undefined, width: 1080, height: 1920, }, "e2e_emulator_31": { + keyboard: 900, emojiButtonCoordinates: { x: 324, y: 1704 }, width: 1080, height: 1920, }, "iPhone 16 Pro": { + keyboard: 291, emojiButtonCoordinates: { x: 40, y: 830 }, width: 393, height: 852, }, "iPhone 15 Pro": { + keyboard: 291, emojiButtonCoordinates: { x: 40, y: 830 }, width: 393, height: 852, }, "iPhone 14 Pro": { + keyboard: 291, emojiButtonCoordinates: { x: 40, y: 830 }, width: 393, height: 852, }, "iPhone 13 Pro": { + keyboard: 286, emojiButtonCoordinates: { x: 40, y: 830 }, width: 390, height: 844,