@@ -2,21 +2,22 @@ import _ from 'lodash';
22
33import { SAVED_CLIENT_FRAMEWORK , SET_SAVED_GESTURES } from '../../shared/setting-defs.js' ;
44import { POINTER_TYPES } from '../constants/gestures.js' ;
5- import { APP_MODE , NATIVE_APP } from '../constants/session-inspector.js' ;
5+ import { APP_MODE , NATIVE_APP , UNKNOWN_ERROR } from '../constants/session-inspector.js' ;
66import i18n from '../i18next.js' ;
77import InspectorDriver from '../lib/appium/inspector-driver.js' ;
88import { CLIENT_FRAMEWORK_MAP } from '../lib/client-frameworks/map.js' ;
99import { getSetting , setSetting } from '../polyfills.js' ;
1010import { readTextFromUploadedFiles } from '../utils/file-handling.js' ;
1111import { getOptimalXPath , getSuggestedLocators } from '../utils/locator-generation.js' ;
1212import { log } from '../utils/logger.js' ;
13+ import { notification } from '../utils/notification.js' ;
1314import {
1415 findDOMNodeByPath ,
1516 findJSONElementByPath ,
1617 xmlToDOM ,
1718 xmlToJSON ,
1819} from '../utils/source-parsing.js' ;
19- import { showError } from './SessionBuilder.js' ;
20+ import { newSession , showError } from './SessionBuilder.js' ;
2021
2122export const SET_SESSION_DETAILS = 'SET_SESSION_DETAILS' ;
2223export const SET_SOURCE_AND_SCREENSHOT = 'SET_SOURCE_AND_SCREENSHOT' ;
@@ -117,6 +118,7 @@ export const TOGGLE_SHOW_ATTRIBUTES = 'TOGGLE_SHOW_ATTRIBUTES';
117118export const TOGGLE_REFRESHING_STATE = 'TOGGLE_REFRESHING_STATE' ;
118119
119120export const SET_GESTURE_UPLOAD_ERROR = 'SET_GESTURE_UPLOAD_ERROR' ;
121+ export const SET_AUTO_SESSION_RESTART = 'SET_AUTO_SESSION_RESTART' ;
120122
121123const KEEP_ALIVE_PING_INTERVAL = 20 * 1000 ;
122124const NO_NEW_COMMAND_LIMIT = 24 * 60 * 60 * 1000 ; // Set timeout to 24 hours
@@ -272,65 +274,90 @@ export function applyClientMethod(params) {
272274 params . methodName !== 'getPageSource' &&
273275 params . methodName !== 'gesture' &&
274276 getState ( ) . inspector . isRecording ;
275- try {
276- dispatch ( { type : METHOD_CALL_REQUESTED } ) ;
277- const callAction = callClientMethod ( params ) ;
278- const {
277+ dispatch ( { type : METHOD_CALL_REQUESTED } ) ;
278+ const callAction = callClientMethod ( params ) ;
279+ const {
280+ contexts,
281+ contextsError,
282+ commandRes,
283+ currentContext,
284+ currentContextError,
285+ source,
286+ screenshot,
287+ windowSize,
288+ sourceError,
289+ screenshotError,
290+ windowSizeError,
291+ variableName,
292+ variableIndex,
293+ strategy,
294+ selector,
295+ } = await callAction ( dispatch , getState ) ;
296+
297+ // TODO: Implement recorder code for gestures
298+ if ( isRecording ) {
299+ // Add 'findAndAssign' line of code. Don't do it for arrays though. Arrays already have 'find' expression
300+ if ( strategy && selector && ! variableIndex && variableIndex !== 0 ) {
301+ const findAction = findAndAssign ( strategy , selector , variableName , false ) ;
302+ findAction ( dispatch , getState ) ;
303+ }
304+
305+ // now record the actual action
306+ let args = [ variableName , variableIndex ] ;
307+ args = args . concat ( params . args || [ ] ) ;
308+ dispatch ( { type : RECORD_ACTION , action : params . methodName , params : args } ) ;
309+ }
310+ dispatch ( { type : METHOD_CALL_DONE } ) ;
311+
312+ if ( source ) {
313+ dispatch ( {
314+ type : SET_SOURCE_AND_SCREENSHOT ,
279315 contexts,
280- contextsError,
281- commandRes,
282316 currentContext,
283- currentContextError ,
284- source,
317+ sourceJSON : xmlToJSON ( source ) ,
318+ sourceXML : source ,
285319 screenshot,
286320 windowSize,
321+ contextsError,
322+ currentContextError,
287323 sourceError,
288324 screenshotError,
289325 windowSizeError,
290- variableName,
291- variableIndex,
292- strategy,
293- selector,
294- } = await callAction ( dispatch , getState ) ;
295-
296- // TODO: Implement recorder code for gestures
297- if ( isRecording ) {
298- // Add 'findAndAssign' line of code. Don't do it for arrays though. Arrays already have 'find' expression
299- if ( strategy && selector && ! variableIndex && variableIndex !== 0 ) {
300- const findAction = findAndAssign ( strategy , selector , variableName , false ) ;
301- findAction ( dispatch , getState ) ;
302- }
303-
304- // now record the actual action
305- let args = [ variableName , variableIndex ] ;
306- args = args . concat ( params . args || [ ] ) ;
307- dispatch ( { type : RECORD_ACTION , action : params . methodName , params : args } ) ;
308- }
309- dispatch ( { type : METHOD_CALL_DONE } ) ;
326+ } ) ;
327+ }
328+ window . dispatchEvent ( new Event ( 'resize' ) ) ;
329+ return commandRes ;
330+ } ;
331+ }
310332
311- if ( source ) {
312- dispatch ( {
313- type : SET_SOURCE_AND_SCREENSHOT ,
314- contexts,
315- currentContext,
316- sourceJSON : xmlToJSON ( source ) ,
317- sourceXML : source ,
318- screenshot,
319- windowSize,
320- contextsError,
321- currentContextError,
322- sourceError,
323- screenshotError,
324- windowSizeError,
325- } ) ;
326- }
327- window . dispatchEvent ( new Event ( 'resize' ) ) ;
328- return commandRes ;
329- } catch ( error ) {
330- log . error ( error ) ;
333+ export function restartSession ( error , params ) {
334+ return async ( dispatch , getState ) => {
335+ if ( error ?. name !== UNKNOWN_ERROR ) {
331336 showError ( error , { methodName : params . methodName , secs : 10 } ) ;
332- dispatch ( { type : METHOD_CALL_DONE } ) ;
337+ return dispatch ( { type : METHOD_CALL_DONE } ) ;
333338 }
339+ showError ( error , { methodName : params . methodName , secs : 3 } ) ;
340+ notification . info ( {
341+ message : i18n . t ( 'RestartSessionMessage' ) ,
342+ duration : 3 ,
343+ } ) ;
344+ const quitSes = quitSession ( 'Window closed' ) ;
345+ const newSes = newSession ( getState ( ) . builder . caps ) ;
346+ const getPageSrc = applyClientMethod ( { methodName : 'getPageSource' , ignoreResult : true } ) ;
347+ const storeSessionSet = storeSessionSettings ( ) ;
348+ const getSavedClientFrame = getSavedClientFramework ( ) ;
349+ const runKeepAliveLp = runKeepAliveLoop ( ) ;
350+ const setSesTime = setSessionTime ( Date . now ( ) ) ;
351+
352+ await quitSes ( dispatch , getState ) ;
353+ await newSes ( dispatch , getState ) ;
354+ await getPageSrc ( dispatch , getState ) ;
355+ await storeSessionSet ( dispatch , getState ) ;
356+ await getSavedClientFrame ( dispatch ) ;
357+ runKeepAliveLp ( dispatch , getState ) ;
358+ setSesTime ( dispatch ) ;
359+ dispatch ( { type : SET_AUTO_SESSION_RESTART , autoSessionRestart : true } ) ;
360+ dispatch ( { type : METHOD_CALL_DONE } ) ;
334361 } ;
335362}
336363
@@ -878,9 +905,11 @@ export function keepSessionAlive() {
878905
879906export function callClientMethod ( params ) {
880907 return async ( dispatch , getState ) => {
881- const { driver, appMode, isUsingMjpegMode, isSourceRefreshOn} = getState ( ) . inspector ;
908+ const { driver, appMode, isUsingMjpegMode, isSourceRefreshOn, autoSessionRestart} =
909+ getState ( ) . inspector ;
882910 const { methodName, ignoreResult = true } = params ;
883911 params . appMode = appMode ;
912+ params . autoSessionRestart = autoSessionRestart ;
884913
885914 // don't retrieve screenshot if we're already using the mjpeg stream
886915 if ( isUsingMjpegMode ) {
@@ -893,28 +922,38 @@ export function callClientMethod(params) {
893922
894923 log . info ( `Calling client method with params:` ) ;
895924 log . info ( params ) ;
896- const action = keepSessionAlive ( ) ;
897- action ( dispatch , getState ) ;
898- const inspectorDriver = InspectorDriver . instance ( driver ) ;
899- const res = await inspectorDriver . run ( params ) ;
900- let { commandRes} = res ;
901-
902- // Ignore empty objects
903- if ( _ . isObject ( res ) && _ . isEmpty ( res ) ) {
904- commandRes = null ;
905- }
925+ try {
926+ const action = keepSessionAlive ( ) ;
927+ action ( dispatch , getState ) ;
928+ const inspectorDriver = InspectorDriver . instance ( driver ) ;
929+ const res = await inspectorDriver . run ( params ) ;
930+ let { commandRes} = res ;
931+
932+ // Ignore empty objects
933+ if ( _ . isObject ( res ) && _ . isEmpty ( res ) ) {
934+ commandRes = null ;
935+ }
906936
907- if ( ! ignoreResult ) {
908- // if the user is running actions manually, we want to show the full response with the
909- // ability to scroll etc...
910- const result = JSON . stringify ( commandRes , null , ' ' ) ;
911- const truncatedResult = _ . truncate ( result , { length : 2000 } ) ;
912- log . info ( `Result of client command was:` ) ;
913- log . info ( truncatedResult ) ;
914- setVisibleCommandResult ( result , methodName ) ( dispatch ) ;
937+ if ( ! ignoreResult ) {
938+ // if the user is running actions manually, we want to show the full response with the
939+ // ability to scroll etc...
940+ const result = JSON . stringify ( commandRes , null , ' ' ) ;
941+ const truncatedResult = _ . truncate ( result , { length : 2000 } ) ;
942+ log . info ( `Result of client command was:` ) ;
943+ log . info ( truncatedResult ) ;
944+ setVisibleCommandResult ( result , methodName ) ( dispatch ) ;
945+ }
946+ res . elementId = res . id ;
947+ return res ;
948+ } catch ( error ) {
949+ log . error ( error ) ;
950+ if ( getState ( ) . inspector . autoSessionRestart ) {
951+ const restartSes = restartSession ( error , params ) ;
952+ return await restartSes ( dispatch , getState ) ;
953+ }
954+ showError ( error , { methodName : params . methodName , secs : 10 } ) ;
955+ dispatch ( { type : METHOD_CALL_DONE } ) ;
915956 }
916- res . elementId = res . id ;
917- return res ;
918957 } ;
919958}
920959
@@ -1096,3 +1135,10 @@ export function toggleShowAttributes() {
10961135 dispatch ( { type : TOGGLE_SHOW_ATTRIBUTES } ) ;
10971136 } ;
10981137}
1138+
1139+ export function toggleAutoSessionRestart ( ) {
1140+ return ( dispatch , getState ) => {
1141+ const autoSessionRestart = ! getState ( ) . inspector . autoSessionRestart ;
1142+ dispatch ( { type : SET_AUTO_SESSION_RESTART , autoSessionRestart} ) ;
1143+ } ;
1144+ }
0 commit comments