From 803a85c54807c9dff2ec9759f969181aa4792309 Mon Sep 17 00:00:00 2001 From: Wim Selles Date: Sun, 5 Jul 2020 11:57:42 +0200 Subject: [PATCH] feat: add locator timings (#1448) * feat: add locator timings * chore: update code after feedback * chore: update code after feedback --- app/main/appium-method-handler.js | 6 ++++ app/renderer/actions/Inspector.js | 23 +++++++++++++ .../components/Inspector/Inspector.js | 32 +++++++++-------- .../components/Inspector/SelectedElement.js | 34 ++++++++++++++++--- app/renderer/reducers/Inspector.js | 21 +++++++++++- assets/locales/en/translation.json | 3 ++ 6 files changed, 99 insertions(+), 20 deletions(-) diff --git a/app/main/appium-method-handler.js b/app/main/appium-method-handler.js index cabdf583a..913289274 100644 --- a/app/main/appium-method-handler.js +++ b/app/main/appium-method-handler.js @@ -2,6 +2,7 @@ import Bluebird from 'bluebird'; import wd from 'wd'; import log from 'electron-log'; import _ from 'lodash'; +import { timing } from 'appium-support'; import { SCREENSHOT_INTERACTION_MODE } from '../renderer/components/Inspector/shared'; import {getWebviewStatusAddressBarHeight, parseSource, setHtmlElementAttributes} from './webviewHelpers'; @@ -64,7 +65,11 @@ export default class AppiumMethodHandler { } async fetchElement (strategy, selector) { + const timer = new timing.Timer().start(); let element = await this.driver.elementOrNull(strategy, selector); + const duration = timer.getDuration(); + const executionTime = Math.round(duration.asMilliSeconds); + if (element === null) { return {}; } @@ -84,6 +89,7 @@ export default class AppiumMethodHandler { strategy, selector, id, + executionTime, }; } diff --git a/app/renderer/actions/Inspector.js b/app/renderer/actions/Inspector.js index 5e03b7f19..3a5b1f1db 100644 --- a/app/renderer/actions/Inspector.js +++ b/app/renderer/actions/Inspector.js @@ -44,6 +44,8 @@ export const SET_LOCATOR_TEST_STRATEGY = 'SET_LOCATOR_TEST_STRATEGY'; export const SET_LOCATOR_TEST_VALUE = 'SET_LOCATOR_TEST_VALUE'; export const SEARCHING_FOR_ELEMENTS = 'SEARCHING_FOR_ELEMENTS'; export const SEARCHING_FOR_ELEMENTS_COMPLETED = 'SEARCHING_FOR_ELEMENTS_COMPLETED'; +export const GET_FIND_ELEMENTS_TIMES = 'GET_FIND_ELEMENTS_TIMES'; +export const GET_FIND_ELEMENTS_TIMES_COMPLETED = 'GET_FIND_ELEMENTS_TIMES_COMPLETED'; export const SET_LOCATOR_TEST_ELEMENT = 'SET_LOCATOR_TEST_ELEMENT'; export const CLEAR_SEARCH_RESULTS = 'CLEAR_SEARCH_RESULTS'; export const ADD_ASSIGNED_VAR_CACHE = 'ADD_ASSIGNED_VAR_CACHE'; @@ -367,6 +369,27 @@ export function searchForElement (strategy, selector) { }; } +/** + * Get all the find element times based on the find data source + */ +export function getFindElementsTimes (findDataSource) { + return async (dispatch) => { + dispatch({type: GET_FIND_ELEMENTS_TIMES}); + try { + const findElementsExecutionTimes = []; + for (const element of findDataSource) { + const {find, selector} = element; + const {executionTime} = await callClientMethod({strategy: find, selector}); + findElementsExecutionTimes.push({find, key: find, selector, time: executionTime}); + } + dispatch({type: GET_FIND_ELEMENTS_TIMES_COMPLETED, findElementsExecutionTimes}); + } catch (error) { + dispatch({type: GET_FIND_ELEMENTS_TIMES_COMPLETED}); + showError(error, 10); + } + }; +} + export function findAndAssign (strategy, selector, variableName, isArray) { return (dispatch, getState) => { const {assignedVarCache} = getState().inspector; diff --git a/app/renderer/components/Inspector/Inspector.js b/app/renderer/components/Inspector/Inspector.js index 309edd60c..793fcc79d 100644 --- a/app/renderer/components/Inspector/Inspector.js +++ b/app/renderer/components/Inspector/Inspector.js @@ -114,7 +114,7 @@ export default class Inspector extends Component { const {screenshot, screenshotError, selectedElement = {}, applyClientMethod, quitSession, isRecording, showRecord, startRecording, pauseRecording, showLocatorTestModal, - screenshotInteractionMode, + screenshotInteractionMode, isFindingElementsTimes, selectedInteractionMode, selectInteractionMode, showKeepAlivePrompt, keepSessionAlive, sourceXML, t} = this.props; const {path} = selectedElement; @@ -215,19 +215,21 @@ export default class Inspector extends Component { ; - return
- {controls} - {main} - keepSessionAlive()} - onCancel={() => quitSession()} - okText={t('Keep Session Running')} - cancelText={t('Quit Session')} - > -

{t('Your session is about to expire')}

-
-
; + return ( +
+ {controls} + {main} + keepSessionAlive()} + onCancel={() => quitSession()} + okText={t('Keep Session Running')} + cancelText={t('Quit Session')} + > +

{t('Your session is about to expire')}

+
+
+
); } } diff --git a/app/renderer/components/Inspector/SelectedElement.js b/app/renderer/components/Inspector/SelectedElement.js index 8f0ac22ed..f113ea09c 100644 --- a/app/renderer/components/Inspector/SelectedElement.js +++ b/app/renderer/components/Inspector/SelectedElement.js @@ -58,6 +58,9 @@ class SelectedElement extends Component { contexts, currentContext, setFieldValue, + getFindElementsTimes, + findElementsExecutionTimes, + isFindingElementsTimes, sendKeys, selectedElement, sendKeysModalVisible, @@ -69,6 +72,7 @@ class SelectedElement extends Component { t, } = this.props; const {attributes, xpath} = selectedElement; + const isDisabled = !elementId || isFindingElementsTimes; // Get the columns for the attributes table let attributeColumns = [{ @@ -106,13 +110,29 @@ class SelectedElement extends Component { dataIndex: 'selector', key: 'selector', render: selectedElementTableCell + }, { + title: t('Time'), + dataIndex: 'time', + key: 'time', + render: selectedElementTableCell }]; + const getTimeButton = ( + + ); + // Get the data for the strategies table let findDataSource = _.toPairs(getLocators(attributes, sourceXML)).map(([key, selector]) => ({ key, selector, find: key, + time: getTimeButton, })); // If XPath is the only provided data source, warn the user about it's brittleness @@ -127,9 +147,15 @@ class SelectedElement extends Component { key: 'xpath', find: 'xpath', selector: xpath, + time: getTimeButton, }); } + // Replace table data with table data that has the times + if (findElementsExecutionTimes.length > 0) { + findDataSource = findElementsExecutionTimes; + } + return
{elementInteractionsNotAvailable && @@ -140,7 +166,7 @@ class SelectedElement extends Component {