From 0ac98ecc06a083e98123f3f47069d4d1072ad373 Mon Sep 17 00:00:00 2001 From: Wim Selles Date: Sun, 19 Sep 2021 10:48:22 +0200 Subject: [PATCH] fix hybrid element position determination (#1906) * fix: fix hybrid element position determination when switched to the webview of a hybrid app the elements on the screenshot were not aligned with the expected position. This will fix that by determining the position of the first webview on in the hybrid app * Fix review comment * fix: fix after review comment --- app/main/appium-method-handler.js | 25 +++++++++++++++++++++---- app/renderer/actions/Session.js | 22 ++++++++++------------ 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/app/main/appium-method-handler.js b/app/main/appium-method-handler.js index d326e7a2e..8cbbb5298 100644 --- a/app/main/appium-method-handler.js +++ b/app/main/appium-method-handler.js @@ -191,7 +191,7 @@ export default class AppiumMethodHandler { async _getContextsSourceAndScreenshot () { let contexts, contextsError, currentContext, currentContextError, platformName, - source, sourceError, screenshot, screenshotError, statBarHeight, windowSize, windowSizeError; + source, sourceError, screenshot, screenshotError, statBarHeight, windowSize, windowSizeError, webViewPosition; if (!await this._hasContextsCommand()) { currentContext = null; @@ -232,6 +232,17 @@ export default class AppiumMethodHandler { } if (currentContext !== NATIVE_APP) { + const isAndroid = _.toLower(platformName) === 'android'; + try { + // Get the webview offset + const el = await this.driver.elementOrNull( + isAndroid ? 'xpath' : '-ios class chain', + isAndroid ? '//android.webkit.WebView' : '**/XCUIElementTypeWebView' + ); + if (el) { + webViewPosition = await this.driver.getLocation(el.value); + } + } catch (ign) {} await this.driver.context(currentContext); } // End of note @@ -242,9 +253,15 @@ export default class AppiumMethodHandler { */ try { if (currentContext !== NATIVE_APP) { - const webviewStatusAddressBarHeight = await this.driver.execute(getWebviewStatusAddressBarHeight, [{platformName, statBarHeight}]); - - await this.driver.execute(setHtmlElementAttributes, [{platformName, webviewStatusAddressBarHeight}]); + // Fallback if the webview position can't be determined, + // then do it based on the web context + if (!webViewPosition) { + webViewPosition = { + x: 0, + y: await this.driver.execute(getWebviewStatusAddressBarHeight, [{platformName, statBarHeight}]), + }; + } + await this.driver.execute(setHtmlElementAttributes, [{platformName, webviewStatusAddressBarHeight: webViewPosition.y}]); } } catch (ign) {} } diff --git a/app/renderer/actions/Session.js b/app/renderer/actions/Session.js index 532340c08..f8c08fa64 100644 --- a/app/renderer/actions/Session.js +++ b/app/renderer/actions/Session.js @@ -802,29 +802,27 @@ export function setVisibleProviders () { * @param {object} caps */ function addCustomCaps (caps) { - const {browserName = '', platformName = ''} = caps; - const safariCustomCaps = { - // Add the includeSafariInWebviews for future HTML detection - includeSafariInWebviews: true, - }; - const chromeCustomCaps = { + const {platformName = ''} = caps; + const androidCustomCaps = { + // @TODO: remove when this is defaulted in the newest Appium 1.8.x release + ensureWebviewsHavePages: true, // Make sure the screenshot is taken of the whole screen when the ChromeDriver is used + // for or Chrome, or for Hybrid apps nativeWebScreenshot: true, // Set the ChromeDriver to w3c:false because all internal calls are still JSONWP calls chromeOptions: { 'w3c': false, }, }; - const androidCustomCaps = { - // @TODO: remove when this is defaulted in the newest Appium 1.8.x release - ensureWebviewsHavePages: true, + const iosCustomCaps = { + // Always add the includeSafariInWebviews for future HTML detection + // This will ensure that if you use AD to switch between App and browser + // that it can detect Safari as a webview + includeSafariInWebviews: true, }; - const iosCustomCaps = {}; return { ...caps, - ...(browserName.toLowerCase() === 'safari' ? safariCustomCaps : {}), - ...(browserName.toLowerCase() === 'chrome' ? chromeCustomCaps : {}), ...(platformName.toLowerCase() === 'android' ? androidCustomCaps : {}), ...(platformName.toLowerCase() === 'ios' ? iosCustomCaps : {}), };