@@ -2,33 +2,6 @@ import { BasePlugin } from '@appium/base-plugin';
22import { logger } from '@appium/support' ;
33import { loadConfig } from './src/config/loader.js' ;
44import { createApiClient , GadsApiClient } from './src/api/client.js' ;
5- import { classify } from './src/utils/classifier.js' ;
6- import { handleArgs } from './src/utils/commandArgsHandler.js' ;
7- import { takeBeforeScreenshot , takeAfterScreenshot } from './src/utils/screenshots.js' ;
8-
9- /**
10- * This function redacts sensitive data from logs like when typing text
11- * @param {* } payload the log payload
12- * @returns
13- */
14- function redact ( payload ) {
15- const KEYS = new Set ( [ 'text' , 'value' ] ) ;
16- const seen = new WeakSet ( ) ;
17- const walk = ( v ) => {
18- if ( v && typeof v === 'object' ) {
19- if ( seen . has ( v ) ) return v ;
20- seen . add ( v ) ;
21- if ( Array . isArray ( v ) ) return v . map ( walk ) ;
22- const out = { } ;
23- for ( const [ k , val ] of Object . entries ( v ) ) {
24- out [ k ] = KEYS . has ( k ) ? '[REDACTED]' : walk ( val ) ;
25- }
26- return out ;
27- }
28- return v ;
29- } ;
30- return walk ( payload ) ;
31- }
325
336// Plugin constants
347const NAME = 'GADS' ;
@@ -45,16 +18,6 @@ class GadsAppium extends BasePlugin {
4518 static apiClient = null ;
4619 // Static property to hold the current Appium session ID
4720 static currentSessionId = "" ;
48- // Static property to hold the current driver
49- static activeDriver = null ;
50-
51- // Static properties for the action logs we send to GADS
52- static actionLogSequence = 0 ; // Unique step counter per session so we can properly order logs
53- static actionLogTenant = '' ; // The tenant of the user creating the session for report filtering and access
54- static actionLogBuildId = '' ; // The ID of the current build run - comes from session capabilities
55- static actionLogTestName = '' ; // The name of the current test - comes from session capabilities
56- static actionLogPlatformName = '' ; // Name of the platform where tests are executed - Android, iOS, Tizen, etc
57- static actionLogDeviceName = '' ; // The name of the device on which the current session runs - comes from GADS in session capabilities
5821
5922 // New endpoints on the Appium server from the plugin itself
6023 static newMethodMap = {
@@ -63,17 +26,6 @@ class GadsAppium extends BasePlugin {
6326 } ,
6427 } ;
6528
66-
67- // Clear the action log data on session end or whatever
68- async clearActionLogData ( ) {
69- GadsAppium . actionLogSequence = 0 ;
70- GadsAppium . actionLogTenant = '' ;
71- GadsAppium . actionLogBuildId = '' ;
72- GadsAppium . actionLogTestName = '' ;
73- GadsAppium . actionLogPlatformName = '' ;
74- GadsAppium . actionLogDeviceName = '' ;
75- }
76-
7729 /**
7830 * updateServer
7931 *
@@ -157,48 +109,13 @@ class GadsAppium extends BasePlugin {
157109 // Call through to the driver’s createSession
158110 const createSessionResult = await driver . createSession ?. ( jsonwpCaps , reqCaps , w3cCapabilities )
159111
160- // Store the active driver in case we need it for something
161- GadsAppium . activeDriver = driver
162-
163112 // Extract the sessionId
164113 const sessionId = createSessionResult ?. value ?. [ 0 ]
165114 if ( sessionId ) {
166115 GadsAppium . currentSessionId = sessionId ;
167116 await GadsAppium . apiClient . addSession ( GadsAppium . currentSessionId )
168117 }
169118
170- // Get the test run build ID from capabilities
171- const buildId = w3cCapabilities ?. alwaysMatch ?. [ 'gads:buildId' ]
172- if ( buildId ) {
173- // Store the build ID for the report logs
174- GadsAppium . actionLogBuildId = buildId
175- log . info ( `GADS: Build ID set to: ${ buildId } ` )
176- } else {
177- // If we don't have a build ID we preventively clear the static action log data
178- // So we don't save logs
179- this . clearActionLogData ( )
180- }
181-
182- // On a new session reset the action log sequence number
183- GadsAppium . actionLogSequence = 0
184- // Get the additional capabilities for extending the log information
185- const tenant = w3cCapabilities ?. alwaysMatch ?. [ 'gads:tenant' ]
186- if ( tenant ) {
187- GadsAppium . actionLogTenant = tenant
188- }
189- const testName = w3cCapabilities ?. alwaysMatch ?. [ 'gads:testName' ]
190- if ( testName ) {
191- GadsAppium . actionLogTestName = testName
192- }
193- const platformName = w3cCapabilities ?. alwaysMatch ?. [ 'platformName' ]
194- if ( platformName ) {
195- GadsAppium . actionLogPlatformName = platformName
196- }
197- const deviceName = w3cCapabilities ?. alwaysMatch ?. [ 'gads:deviceName' ]
198- if ( deviceName ) {
199- GadsAppium . actionLogDeviceName = deviceName
200- }
201-
202119 return createSessionResult
203120 }
204121
@@ -212,15 +129,10 @@ class GadsAppium extends BasePlugin {
212129 * @param {string } sessionId The sessionId to delete
213130 */
214131 async deleteSession ( next , driver , sessionId ) {
215- // Clear all action log properties
216- this . clearActionLogData ( )
217-
218132 // If we’re deleting the active session, clear it from the properties
219133 if ( GadsAppium . currentSessionId === sessionId ) {
220134 GadsAppium . currentSessionId = ''
221135 }
222- // Reset the active driver object
223- GadsAppium . activeDriver = null ;
224136
225137 // Call through to the driver's deleteSession
226138 const deleteSessionResult = await driver . deleteSession ?. ( sessionId )
@@ -240,115 +152,7 @@ class GadsAppium extends BasePlugin {
240152 * @returns
241153 */
242154 async handle ( next , driver , commandName , ...args ) {
243- // Do not handle the commands below at all, directly call through to next()
244- if ( [ 'createSession' , 'deleteSession' , 'getSessions' ] . includes ( commandName ) ) {
245- return await next ( )
246- }
247-
248- // Get the command start timestamp
249- const commandStartTS = Date . now ( )
250- let result , error ;
251-
252- // Take screenshot BEFORE command execution for specific commands
253- const hasBeforeScreenshot = takeBeforeScreenshot ( GadsAppium , commandName , GadsAppium . apiClient )
254-
255- // Execute the command, saving result and/or error
256- if ( commandName === 'execute' && args ?. [ 0 ] && typeof args [ 0 ] === 'string' && args [ 0 ] . includes ( 'gads:testResult' ) ) {
257- // Skip calling next() for test result commands to avoid unimplemented execute
258- result = { value : 'Test result processed' }
259- } else {
260- try {
261- result = await next ( )
262- } catch ( e ) {
263- error = e
264- }
265- }
266-
267- try {
268- const cfg = GadsAppium . cfg || this . cfg
269- if ( cfg ?. providerUrl && cfg ?. udid ) {
270- // Classify the command turning the Appium command name into a human-readable report-friendly command name
271- const info = classify ( commandName , args )
272-
273- // We log actions only if command was classified and `gads:buildId` capability is provided
274- if ( info && GadsAppium . actionLogBuildId ) {
275- // Increment the sequence number on each command we log
276- GadsAppium . actionLogSequence += 1
277-
278- // Parse element locator data for findElement/findElements commands
279- let findElementUsing = null ;
280- let findElementSelector = null ;
281- if ( commandName === 'findElement' || commandName === 'findElements' ) {
282- findElementUsing = args ?. [ 0 ]
283- findElementSelector = args ?. [ 1 ]
284- }
285-
286- // Parse specific commands arguments into human readable output
287- const commandAdditionalInfo = handleArgs ( commandName , args )
288-
289- // Check if this is a test result execute command
290- let testStatus = null ;
291- let testMessage = null ;
292- if ( commandName === 'execute' && args ?. [ 0 ] && typeof args [ 0 ] === 'string' && args [ 0 ] . includes ( 'gads:testResult' ) ) {
293- const scriptArgs = args ?. [ 1 ] ;
294- const testResult = Array . isArray ( scriptArgs ) ? scriptArgs [ 0 ] : scriptArgs ;
295- if ( testResult && typeof testResult === 'object' ) {
296- testStatus = testResult . status || 'unknown' ;
297- testMessage = testResult . message || testResult . error || '' ;
298- }
299- }
300-
301- // Take screenshot for any failed command
302- let hasAfterScreenshot = false
303- if ( error ) {
304- hasAfterScreenshot = takeAfterScreenshot ( GadsAppium , commandName , GadsAppium . apiClient )
305- }
306-
307- // Build the body of the log we send to GADS
308- const body = {
309- timestamp : commandStartTS , // Start time of the command
310- session_id : GadsAppium . currentSessionId || null , // Appium current session id
311- udid : cfg . udid , // Target device UDID
312- action : info . action , // Use "Test Result" for test result logs
313- command : commandName , // Actual Appium command name
314- duration_ms : Date . now ( ) - commandStartTS , // Time taken to execute the command
315- success : ! error , // Is the command successful or not
316- error : error ? String ( error . message || error ) : null , // Error string if any
317- sequence_number : GadsAppium . actionLogSequence , // Log sequence number for proper logs ordering
318- tenant : GadsAppium . actionLogTenant , // Test execution target tenant name from GADS - `gads:tenant`
319- build_id : GadsAppium . actionLogBuildId , // Test execution build identifier - `gads:buildId`
320- test_name : GadsAppium . actionLogTestName , // Name of target test if any - `gads:testName`
321- locator_using : findElementUsing , // Type of target element locator for findElement/findElements
322- locator_value : findElementSelector , // Value of the target element locator for findElement/findElements
323- device_name : GadsAppium . actionLogDeviceName , // Target device name from GADS
324- platform_name : GadsAppium . actionLogPlatformName , // Target test platform name - iOS/Android/Tizen/WebOS
325- additional_info : commandAdditionalInfo , // Use test message for test result logs
326- has_screenshot : hasBeforeScreenshot , // Whether a screenshot was taken before the command
327- has_screenshot_after : hasAfterScreenshot , // Whether a screenshot was taken after the command
328- }
329-
330- // Add test result fields only if they have values (to avoid empty fields in mongo)
331- if ( testStatus ) {
332- body . test_status = testStatus
333- body . action = 'Test Result'
334- }
335- if ( testMessage ) {
336- body . test_message = testMessage ;
337- body . additional_info = testMessage
338- }
339-
340- // Send the log to GADS
341- await GadsAppium . apiClient . sendSessionLog ( body )
342- }
343-
344- }
345- } catch ( e ) {
346- log . error ( `Something failed - ${ e } ` )
347- }
348-
349- // Keep the usual Appium handling - throw error or return result
350- if ( error ) throw error
351- return result
155+ return await next ( )
352156 }
353157
354158 /**
@@ -362,10 +166,8 @@ class GadsAppium extends BasePlugin {
362166 async onUnexpectedShutdown ( driver , cause ) {
363167 log . warn ( `GADS: Session ${ GadsAppium . currentSessionId } crashed unexpectedly` )
364168
365- // Clear the session id, active driver and the static action log properties
169+ // Clear the session id and the static action log properties
366170 GadsAppium . currentSessionId = ""
367- GadsAppium . activeDriver = null
368- this . clearActionLogData ( )
369171
370172 // Notify GADS the driver crashed by clearing the session on GADS side
371173 await GadsAppium . apiClient . removeSession ( )
0 commit comments