import { Application } from "../../automation" ; import * as assert from "assert" ; import * as cp from "child_process" ; import { SmokeTestsConstants } from "./helpers/smokeTestsConstants" ; import { vscodeManager } from "./main" ; import { sleep } from "./helpers/utilities" ; import { SmokeTestLogger } from "./helpers/smokeTestLogger" ; import { TestRunArguments } from "./helpers/testConfigProcessor" ; import TestProject from "./helpers/testProject" ; import AutomationHelper from "./helpers/AutomationHelper" ; const RNmacOSDebugConfigName = "Debug macOS" ; const RNmacOSHermesDebugConfigName = "Debug macOS Hermes - Experimental" ; const RNmacOSsetBreakpointOnLine = 1 ; const RNmacOSHermesSetBreakpointOnLine = 15 ; const debugMacOSTestTime = SmokeTestsConstants . macOSTestTimeout ; export function startDebugMacOSTests ( macosProject , macosHermesProject , testParameters ) { describe ( "Debugging macOS" , ( ) => { let app ; let currentMacOSAppName = "" ; let automationHelper ; async function initApp ( workspaceOrFolder , sessionName ? , locale ? ) { app = await vscodeManager . runVSCode ( workspaceOrFolder , sessionName , locale ) ; automationHelper = new AutomationHelper ( app ) ; return app ; } async function disposeAll ( ) { SmokeTestLogger . info ( "Dispose all ..." ) ; if ( app ) { SmokeTestLogger . info ( "Stopping React Native packager ..." ) ; await automationHelper . runCommandWithRetry ( SmokeTestsConstants . stopPackagerCommand ) ; await sleep ( 3000 ) ; SmokeTestLogger . info ( "Stopping application ..." ) ; await app . stop ( ) ; } terminateMacOSapp ( currentMacOSAppName ) ; } afterEach ( disposeAll ) ; function terminateMacOSapp ( appName ) { SmokeTestLogger . info ( `*** Searching for ${ appName } macOS application process` ) ; const searchForMacOSappProcessCommand = `ps -ax | grep ${ appName }` ; const searchResults = cp . execSync ( searchForMacOSappProcessCommand ) . toString ( ) ; SmokeTestLogger . info ( `*** Searching for ${ appName } macOS application process: results ${ JSON . stringify ( searchResults ) }` ) ; if ( searchResults ) { const processIdRgx = /(^\d*)\s\?\?/g ; const processData = searchResults . split ( "\n" ) . find ( str => str . includes ( `${ appName }.app` ) ) ; if ( processData ) { const match = processIdRgx . exec ( processData ) ; if ( match && match [ 1 ] ) { SmokeTestLogger . info ( `*** Terminating ${ appName } macOS application process with PID ${ match [ 1 ] }` ) ; const terminateMacOSappProcessCommand = `kill ${ match [ 1 ] }` ; cp . execSync ( terminateMacOSappProcessCommand ) ; } } } } async function macOSApplicationTest ( testname , project , isHermesProject = false ) { app = await initApp ( project . workspaceDirectory , testname ) ; await automationHelper . openFileWithRetry ( project . projectEntryPointFile ) ; await app . workbench . editors . scrollTop ( ) ; SmokeTestLogger . info ( `${ testname }: App.js file is opened` ) ; let debugConfigName ; let setBreakpointOnLine ; if ( isHermesProject ) { debugConfigName = RNmacOSHermesDebugConfigName ; setBreakpointOnLine = RNmacOSHermesSetBreakpointOnLine ; } else { debugConfigName = RNmacOSDebugConfigName ; setBreakpointOnLine = RNmacOSsetBreakpointOnLine ; } await app . workbench . debug . setBreakpointOnLine ( setBreakpointOnLine ) ; SmokeTestLogger . info ( `${ testname }: Breakpoint is set on line ${ setBreakpointOnLine }` ) ; SmokeTestLogger . info ( `${ testname }: Chosen debug configuration: ${ debugConfigName }` ) ; SmokeTestLogger . info ( `${ testname }: Starting debugging` ) ; await automationHelper . runDebugScenarioWithRetry ( debugConfigName ) ; await app . workbench . debug . waitForDebuggingToStart ( ) ; SmokeTestLogger . info ( `${ testname }: Debugging started` ) ; await automationHelper . waitForStackFrameWithRetry ( sf => sf . name === project . projectEntryPointFile && sf . lineNumber === setBreakpointOnLine , `looking for App.js and line ${ setBreakpointOnLine }` ) ; SmokeTestLogger . info ( `${ testname }: Stack frame found` ) ; await app . workbench . debug . stepOver ( ) ; await sleep ( SmokeTestsConstants . debugConsoleSearchTimeout ) ; SmokeTestLogger . info ( `${ testname }: Searching for "Test output from debuggee" string in console` ) ; await automationHelper . runCommandWithRetry ( "Debug: Focus on Debug Console View" ) ; const found = await automationHelper . waitForOutputWithRetry ( "Test output from debuggee" ) ; assert . notStrictEqual ( found , false , '"Test output from debuggee" string is missing in debug console' ) ; SmokeTestLogger . success ( `${ testname }: "Test output from debuggee" string is found` ) ; await automationHelper . disconnectFromDebuggerWithRetry ( ) ; SmokeTestLogger . info ( `${ testname }: Debugging is stopped` ) ; } if ( process . platform === "darwin" && testParameters . RunMacOSTests ) { it ( "RN macOS app Debug test" , async function ( ) { this . timeout ( debugMacOSTestTime ) ; currentMacOSAppName = SmokeTestsConstants . RNmacOSAppName ; await macOSApplicationTest ( "RN macOS app Debug test" , macosProject ) ; } ) ; if ( ! testParameters . SkipUnstableTests ) { it ( "RN macOS Hermes app Debug test" , async function ( ) { this . timeout ( debugMacOSTestTime ) ; currentMacOSAppName = SmokeTestsConstants . RNmacOSHermesAppName ; await macOSApplicationTest ( "RN macOS Hermes app Debug test" , macosHermesProject , true ) ; } ) ; } } } ) ; }