From c2d045a2c3dfb75a97e500fe03d4e762683f063b Mon Sep 17 00:00:00 2001 From: solvd Date: Mon, 11 Mar 2024 13:00:41 -0300 Subject: [PATCH 1/5] #556 and #897 fix for device first session --- lib/units/api/controllers/devices.js | 10 +-- lib/units/ios-device/plugins/wda/WdaClient.js | 84 +++++++++++-------- 2 files changed, 49 insertions(+), 45 deletions(-) diff --git a/lib/units/api/controllers/devices.js b/lib/units/api/controllers/devices.js index 1e57f81b..366ca7d6 100755 --- a/lib/units/api/controllers/devices.js +++ b/lib/units/api/controllers/devices.js @@ -306,19 +306,11 @@ function getDeviceType (req, res) { var serial = req.swagger.params.serial.value dbapi.getDeviceType(serial) .then(response => { - if (!response) { - return res.status(404).json({ - success: false, - description: 'Device not found' - }) - } return res.status(200).json(response) }) .catch(function(err) { log.info('Failed to get device type: ', err.stack) - res.status(500).json({ - success: false - }) + return res.status(200).json({deviceType: null}) }) } diff --git a/lib/units/ios-device/plugins/wda/WdaClient.js b/lib/units/ios-device/plugins/wda/WdaClient.js index bc93ffdb..6b09dd7e 100644 --- a/lib/units/ios-device/plugins/wda/WdaClient.js +++ b/lib/units/ios-device/plugins/wda/WdaClient.js @@ -34,32 +34,37 @@ module.exports = syrup.serial() isRotating: false, deviceType: null, - getDeviceType: function() { - const setDeviceTypeInDB = () => { - this.handleRequest({ - method: 'GET', - uri: `${this.baseUrl}/wda/device/info`, - json: true - }).then((deviceInfo) => { - log.info('Setting device type value: ' + deviceInfo.value.model) - this.deviceType = deviceInfo.value.model - - return push.send([ - wireutil.global, - wireutil.envelope(new wire.DeviceTypeMessage( - options.serial, - deviceInfo.value.model - )) - ]) - }) - } + setDeviceTypeInDB: function() { + this.handleRequest({ + method: 'GET', + uri: `${this.baseUrl}/wda/device/info`, + json: true + }).then((deviceInfo) => { + log.info('Storing device type value: ' + deviceInfo.value.model) + this.deviceType = deviceInfo.value.model + + return push.send([ + wireutil.global, + wireutil.envelope(new wire.DeviceTypeMessage( + options.serial, + deviceInfo.value.model + )) + ]) + }) + }, + getDeviceType: function(onFirstSession) { return this.handleRequest({ method: 'GET', uri: `${options.storageUrl}api/v1/devices/${options.serial}/type`, }).then((response) => { let deviceType = JSON.parse(response).deviceType + + if (onFirstSession && !deviceType) { + return null + } + if (!deviceType) { - return setDeviceTypeInDB() + return this.setDeviceTypeInDB() } log.info('Reusing device type value: ', deviceType) @@ -93,7 +98,7 @@ module.exports = syrup.serial() log.info(`reusing existing wda session: ${this.sessionId}`) this.setStatus(3) - this.getDeviceType().then((response) => { + this.getDeviceType(false).then((response) => { if (this.deviceType !== 'Apple TV') { this.getOrientation() } @@ -124,7 +129,7 @@ module.exports = syrup.serial() // #284 send info about battery to STF db log.info(`sessionId: ${this.sessionId}`) - this.getDeviceType().then((response) => { + this.getDeviceType(false).then((response) => { // Prevent Apple TV disconnection if (this.deviceType !== 'Apple TV') { this.getOrientation() @@ -485,10 +490,8 @@ module.exports = syrup.serial() }) } }, - size: function() { - log.info('getting device window size...') - - const setSizeInDB = () => this.handleRequest({ + setSizeInDB: function() { + return this.handleRequest({ method: 'GET', uri: `${this.baseUrl}/session/${this.sessionId}/window/size`, }).then((firstSessionSize) => { @@ -522,6 +525,9 @@ module.exports = syrup.serial() return this.deviceSize }) }) + }, + size: function() { + log.info('getting device window size...') // #556: Get device size from RethinkDB return this.handleRequest({ @@ -530,10 +536,9 @@ module.exports = syrup.serial() }) .then((windowSizeResponse) => { let { height: dbHeight, width: dbWidth, scale: dbScale } = JSON.parse(windowSizeResponse); - // First device session: if (!dbHeight || !dbWidth || !dbScale) { - setSizeInDB() + return this.setSizeInDB() } else { // Reuse DB values: log.info('Reusing device size/scale') @@ -597,7 +602,6 @@ module.exports = syrup.serial() }) }, getOrientation: function() { - return this.handleRequest({ method: 'GET', uri: `${this.baseUrl}/session/${this.sessionId}/orientation`, @@ -737,7 +741,11 @@ module.exports = syrup.serial() return resolve(response) }) .catch(err => { - let errMes = err.error.value.message ? err.error.value.message : '' + let errMes = '' + + if (err.error.value.message) { + errMes = err.error.value.message + } // #762 & #864: Skip lock/unlock error messages if (errMes.includes('Timed out while waiting until the screen gets locked') || errMes.includes('unlocked')) { @@ -767,9 +775,11 @@ module.exports = syrup.serial() * WDA MJPEG connection is stable enough to be track status wda server itself. * As only connection is closed or error detected we have to restart STF */ - function connectToWdaMjpeg() { + function connectToWdaMjpeg(options) { console.log('connecting to WdaMjpeg') - socket.connect(options.connectPort, options.wdaHost) + socket.connect(options.connectPort, options.wdaHost, () => { + console.log(`Connected to WdaMjpeg ${options.wdaHost}:${options.connectPort}`) + }) // #410: Use status 6 (preparing) on WDA startup push.send([ @@ -779,10 +789,13 @@ module.exports = syrup.serial() 6 )) ]) - } - function wdaMjpegConnectEventHandler() { - console.log(`Connected to WdaMjpeg ${options.wdaHost}:${options.connectPort}`) + WdaClient.getDeviceType(true).then((response) => { + if (response === null) { + log.info('First session started') + return WdaClient.startSession() + } + }) } async function wdaMjpegCloseEventHandler(hadError) { @@ -799,7 +812,6 @@ module.exports = syrup.serial() ]) } - socket.on('connect', wdaMjpegConnectEventHandler) socket.on('close', wdaMjpegCloseEventHandler) connectToWdaMjpeg(options) From fc6e22a6ba99a485cbd04b9a925d191c97b22094 Mon Sep 17 00:00:00 2001 From: vdelendik Date: Tue, 12 Mar 2024 15:52:39 +0300 Subject: [PATCH 2/5] #556: fixed device type detection on startup --- lib/units/ios-device/plugins/wda/WdaClient.js | 82 +++++++++---------- .../components/stf/screen/screen-directive.js | 6 +- 2 files changed, 41 insertions(+), 47 deletions(-) diff --git a/lib/units/ios-device/plugins/wda/WdaClient.js b/lib/units/ios-device/plugins/wda/WdaClient.js index 6b09dd7e..7b69905c 100644 --- a/lib/units/ios-device/plugins/wda/WdaClient.js +++ b/lib/units/ios-device/plugins/wda/WdaClient.js @@ -17,7 +17,7 @@ module.exports = syrup.serial() .define((options, notifier, push) => { const log = logger.createLogger('wdaClient') log.info("WdaClient.js initializing...") - + const socket = new net.Socket() const WdaClient = { baseUrl: iosutil.getUri(options.wdaHost, options.wdaPort), @@ -35,6 +35,7 @@ module.exports = syrup.serial() deviceType: null, setDeviceTypeInDB: function() { + log.info('111'); this.handleRequest({ method: 'GET', uri: `${this.baseUrl}/wda/device/info`, @@ -52,25 +53,28 @@ module.exports = syrup.serial() ]) }) }, - getDeviceType: function(onFirstSession) { + getDeviceType: function() { + if (this.deviceType != null) { + return this.deviceType + } + + log.info('222'); return this.handleRequest({ method: 'GET', uri: `${options.storageUrl}api/v1/devices/${options.serial}/type`, }).then((response) => { let deviceType = JSON.parse(response).deviceType - if (onFirstSession && !deviceType) { - return null - } - if (!deviceType) { return this.setDeviceTypeInDB() } log.info('Reusing device type value: ', deviceType) this.deviceType = deviceType - })}, + }) + }, startSession: function() { + log.info('333'); log.info('verifying wda session status...') const params = { @@ -98,15 +102,12 @@ module.exports = syrup.serial() log.info(`reusing existing wda session: ${this.sessionId}`) this.setStatus(3) - this.getDeviceType(false).then((response) => { - if (this.deviceType !== 'Apple TV') { + if (this.deviceType !== 'Apple TV') { this.getOrientation() - } - - this.setVersion(sessionResponse) - - return this.size() - }) + } + + this.setVersion(sessionResponse) + return this.size() } log.info('starting wda session...') @@ -129,17 +130,12 @@ module.exports = syrup.serial() // #284 send info about battery to STF db log.info(`sessionId: ${this.sessionId}`) - this.getDeviceType(false).then((response) => { - // Prevent Apple TV disconnection - if (this.deviceType !== 'Apple TV') { - this.getOrientation() - this.batteryIosEvent() - } - - this.setStatus(3) - - return this.size() - }) + if (this.deviceType !== 'Apple TV') { + this.getOrientation() + this.batteryIosEvent() + } + this.setStatus(3) + return this.size() }) .catch((err) => { log.error('"startSession" No valid response from web driver!', err) @@ -162,7 +158,6 @@ module.exports = syrup.serial() method: 'DELETE', uri: `${this.baseUrl}/session/${currentSessionId}` }) - }, setStatus: function(status) { push.send([ @@ -217,9 +212,9 @@ module.exports = syrup.serial() if (this.deviceType !== 'Apple TV') { return this.handleRequest(requestParams) - } + } - // Apple TV keys + // Apple TV keys switch (true) { case value === '\v': @@ -320,7 +315,7 @@ module.exports = syrup.serial() id: 'finger1', parameters: {pointerType: 'touch'}, actions: [ - {type: 'pointerMove', duration: 0, x: scale.fromX, y: scale.fromY}, + {type: 'pointerMove', duration: 0, x: scale.fromX, y: scale.fromY}, {type: 'pointerMove', duration: scale.duration * 1000, x: scale.toX, y: (scale.fromY < scale.toY) ? scale.toY - (scale.toY / 4) : (scale.fromY - scale.toY >= 50 ? scale.toY + (scale.toY / 4) : scale.toY)}, {type: 'pointerUp'}, ], @@ -333,7 +328,7 @@ module.exports = syrup.serial() } let swipeOperation = () => { - if (!this.isSwiping) { + if (!this.isSwiping) { this.isSwiping = true this.handleRequest({ method: 'POST', @@ -346,7 +341,7 @@ module.exports = syrup.serial() }) } } - + return swipeOperation() }, touchUp: function() { @@ -381,7 +376,7 @@ module.exports = syrup.serial() body, json: true, }) - // else if (deviceType === 'Watch_OS') {...} + // else if (deviceType === 'Watch_OS') {...} } else { // Avoid crash, wait until width/height values are available if (x >= 0 && y >= 0) { @@ -429,7 +424,7 @@ module.exports = syrup.serial() body: {name: "select"}, json: true, }) - break; + break; } } } @@ -494,7 +489,7 @@ module.exports = syrup.serial() return this.handleRequest({ method: 'GET', uri: `${this.baseUrl}/session/${this.sessionId}/window/size`, - }).then((firstSessionSize) => { + }).then((firstSessionSize) => { this.deviceSize = JSON.parse(firstSessionSize).value let {height, width} = this.deviceSize @@ -527,6 +522,9 @@ module.exports = syrup.serial() }) }, size: function() { + if (this.deviceSize != null) { + return this.deviceSize + } log.info('getting device window size...') // #556: Get device size from RethinkDB @@ -544,7 +542,7 @@ module.exports = syrup.serial() log.info('Reusing device size/scale') // Set device size based on orientation, default is PORTRAIT if (this.orientation === 'PORTRAIT' || !this.orientation) { - this.deviceSize = { height: dbHeight /= dbScale, width: dbWidth /= dbScale } + this.deviceSize = { height: dbHeight /= dbScale, width: dbWidth /= dbScale } } else if (this.orientation === 'LANDSCAPE') { this.deviceSize = { height: dbWidth /= dbScale, width: dbHeight /= dbScale } } else if (this.deviceType === 'Apple TV') { @@ -688,7 +686,7 @@ module.exports = syrup.serial() json: true }) }, - switchCharset: function() { + switchCharset: function() { this.upperCase = !this.upperCase log.info(this.upperCase) @@ -761,7 +759,7 @@ module.exports = syrup.serial() if (errMes.includes('Session does not exist')) { return this.startSession() } - + // #409: capture wda/appium crash asap and exit with status 1 from stf //notifier.setDeviceTemporaryUnavialable(err) notifier.setDeviceAbsent(err) @@ -790,12 +788,8 @@ module.exports = syrup.serial() )) ]) - WdaClient.getDeviceType(true).then((response) => { - if (response === null) { - log.info('First session started') - return WdaClient.startSession() - } - }) + //TODO: handle negative case when device type not detected. Seems lifecycle.fatal(err) is ok. + WdaClient.getDeviceType() } async function wdaMjpegCloseEventHandler(hadError) { diff --git a/res/app/components/stf/screen/screen-directive.js b/res/app/components/stf/screen/screen-directive.js index 1dd2884b..4a46c0d1 100755 --- a/res/app/components/stf/screen/screen-directive.js +++ b/res/app/components/stf/screen/screen-directive.js @@ -26,9 +26,9 @@ module.exports = function DeviceScreenDirective( }, link: function($scope, $element) { // eslint-disable-next-line prefer-destructuring - if ($scope.device.ios && $scope.device.present && (!$scope.device.display.width || !$scope.device.display.height)) { - return Promise.delay(1000).then(() => window.location.reload()) - } + //if ($scope.device.ios && $scope.device.present && (!$scope.device.display.width || !$scope.device.display.height)) { + // return Promise.delay(1000).then(() => window.location.reload()) + //} const element = $element[0] const URL = window.URL || window.webkitURL const BLANK_IMG = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' From 8f5d855388860a037cd689d783c7ebbf4fee9dbc Mon Sep 17 00:00:00 2001 From: vdelendik Date: Tue, 12 Mar 2024 15:53:48 +0300 Subject: [PATCH 3/5] removed debug ingo log messages --- lib/units/ios-device/plugins/wda/WdaClient.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/units/ios-device/plugins/wda/WdaClient.js b/lib/units/ios-device/plugins/wda/WdaClient.js index 7b69905c..9bc9d2b5 100644 --- a/lib/units/ios-device/plugins/wda/WdaClient.js +++ b/lib/units/ios-device/plugins/wda/WdaClient.js @@ -35,7 +35,6 @@ module.exports = syrup.serial() deviceType: null, setDeviceTypeInDB: function() { - log.info('111'); this.handleRequest({ method: 'GET', uri: `${this.baseUrl}/wda/device/info`, @@ -58,7 +57,6 @@ module.exports = syrup.serial() return this.deviceType } - log.info('222'); return this.handleRequest({ method: 'GET', uri: `${options.storageUrl}api/v1/devices/${options.serial}/type`, @@ -74,7 +72,6 @@ module.exports = syrup.serial() }) }, startSession: function() { - log.info('333'); log.info('verifying wda session status...') const params = { From 9f3c88e9faf61fca3346457b7a114f287cb56a9c Mon Sep 17 00:00:00 2001 From: vdelendik Date: Tue, 12 Mar 2024 16:08:34 +0300 Subject: [PATCH 4/5] minor changes to stf to polish for release --- lib/units/ios-device/plugins/wda/WdaClient.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/units/ios-device/plugins/wda/WdaClient.js b/lib/units/ios-device/plugins/wda/WdaClient.js index 9bc9d2b5..ea6fcc92 100644 --- a/lib/units/ios-device/plugins/wda/WdaClient.js +++ b/lib/units/ios-device/plugins/wda/WdaClient.js @@ -742,12 +742,12 @@ module.exports = syrup.serial() errMes = err.error.value.message } - // #762 & #864: Skip lock/unlock error messages + // #762 & #864: Skip lock/unlock error messages if (errMes.includes('Timed out while waiting until the screen gets locked') || errMes.includes('unlocked')) { return } - // #765: Skip rotation error message + // #765: Skip rotation error message if (errMes.includes('Unable To Rotate Device')) { return log.info('The current application does not support rotation') } @@ -787,6 +787,11 @@ module.exports = syrup.serial() //TODO: handle negative case when device type not detected. Seems lifecycle.fatal(err) is ok. WdaClient.getDeviceType() + + //TODO: start session, init size/scale and stop session asap. Improve size getting info from db only + //WdaClient.startSession() + //WdaClient.setSizeInDB() + //WdaClient.stopSession() } async function wdaMjpegCloseEventHandler(hadError) { From 1a99f9386e8343a7314ec0a0b3b9f5dc17264924 Mon Sep 17 00:00:00 2001 From: vdelendik Date: Tue, 12 Mar 2024 16:09:54 +0300 Subject: [PATCH 5/5] removed useless code --- res/app/components/stf/screen/screen-directive.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/res/app/components/stf/screen/screen-directive.js b/res/app/components/stf/screen/screen-directive.js index 4a46c0d1..3142e360 100755 --- a/res/app/components/stf/screen/screen-directive.js +++ b/res/app/components/stf/screen/screen-directive.js @@ -26,9 +26,6 @@ module.exports = function DeviceScreenDirective( }, link: function($scope, $element) { // eslint-disable-next-line prefer-destructuring - //if ($scope.device.ios && $scope.device.present && (!$scope.device.display.width || !$scope.device.display.height)) { - // return Promise.delay(1000).then(() => window.location.reload()) - //} const element = $element[0] const URL = window.URL || window.webkitURL const BLANK_IMG = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='