@@ -26,9 +26,6 @@ public class RemoteWebDriverAdvice {
2626 // ThreadLocal re-entrance guard to prevent multiple enhancement calls in the same thread
2727 private static final ThreadLocal <Boolean > isEnhancing = ThreadLocal .withInitial (() -> false );
2828
29- // Flag to warn only once about missing tunnel (avoid spam in parallel execution)
30- private static volatile boolean warnedAboutMissingTunnel = false ;
31-
3229 // Session-thread manager for validating thread affinity
3330 private static final SessionThreadManager sessionThreadManager = SessionThreadManager .getInstance ();
3431
@@ -228,26 +225,64 @@ public static void enhanceCapabilities(MutableCapabilities capabilities) {
228225 }
229226
230227 if (tunnelInCapabilities ) {
231- // Tunnel is enabled - check if it's running and add tunnel name
228+ // Tunnel is enabled - ensure it's running and wait for it to be ready
232229 try {
233230 com .lambdatest .selenium .tunnel .TunnelManager tunnelManager =
234231 com .lambdatest .selenium .tunnel .TunnelManager .getInstance ();
235232
236- if (tunnelManager .isTunnelRunning ()) {
237- String tunnelName = tunnelManager .getTunnelName ();
238- if (tunnelName != null && !tunnelName .trim ().isEmpty ()) {
239- ltOptions .put ("tunnelName" , tunnelName );
240- }
241- } else {
242- // Tunnel configured but not running - warn once
243- if (!warnedAboutMissingTunnel ) {
244- warnedAboutMissingTunnel = true ;
245- System .err .println ("[LambdaTest SDK] WARNING: tunnel=true in YAML but no tunnel is running." );
246- System .err .println ("[LambdaTest SDK] Tests will continue without tunnel. This may cause connection issues for local resources." );
233+ // Synchronize to ensure only one thread starts the tunnel
234+ synchronized (RemoteWebDriverAdvice .class ) {
235+ if (!tunnelManager .isTunnelRunning ()) {
236+ // Tunnel is not running - start it automatically
237+ System .out .println ("[LambdaTest SDK] Tunnel is enabled but not running. Starting tunnel automatically..." );
238+
239+ try {
240+ // Reuse config variable from outer scope
241+ String username = config .getUsername ();
242+ String accessKey = config .getAccessKey ();
243+
244+ // Get tunnel name from config if available
245+ String tunnelName = null ;
246+ if (ltOptions .containsKey ("tunnelName" )) {
247+ Object tunnelNameObj = ltOptions .get ("tunnelName" );
248+ if (tunnelNameObj != null ) {
249+ tunnelName = tunnelNameObj .toString ();
250+ }
251+ }
252+
253+ // Start tunnel and wait for it to be ready
254+ // startTunnel() internally waits up to 90 seconds for tunnel to be ready
255+ tunnelManager .startTunnel (username , accessKey , tunnelName );
256+
257+ System .out .println ("[LambdaTest SDK] Tunnel started successfully and ready for use." );
258+ } catch (com .lambdatest .selenium .tunnel .TunnelManager .TunnelException e ) {
259+ System .err .println ("[LambdaTest SDK] ERROR: Failed to start tunnel: " + e .getMessage ());
260+ System .err .println ("[LambdaTest SDK] Tests will fail without tunnel. Please start tunnel manually or fix configuration." );
261+ throw new RuntimeException ("Tunnel startup failed: " + e .getMessage (), e );
262+ } catch (Exception e ) {
263+ System .err .println ("[LambdaTest SDK] ERROR: Unexpected error starting tunnel: " + e .getMessage ());
264+ e .printStackTrace ();
265+ throw new RuntimeException ("Tunnel startup failed: " + e .getMessage (), e );
266+ }
247267 }
248268 }
269+
270+ // Verify tunnel is running (should be true if startTunnel() returned successfully,
271+ // or if another thread already started it)
272+ if (!tunnelManager .isTunnelRunning ()) {
273+ throw new RuntimeException ("Tunnel is not running. This should not happen if startTunnel() completed successfully." );
274+ }
275+
276+ // Add tunnel name to capabilities
277+ String tunnelName = tunnelManager .getTunnelName ();
278+ if (tunnelName != null && !tunnelName .trim ().isEmpty ()) {
279+ ltOptions .put ("tunnelName" , tunnelName );
280+ }
281+
249282 } catch (Exception e ) {
250- System .err .println ("[LambdaTest SDK] Warning: Error checking tunnel status: " + e .getMessage ());
283+ System .err .println ("[LambdaTest SDK] ERROR: Tunnel handling failed: " + e .getMessage ());
284+ e .printStackTrace ();
285+ throw new RuntimeException ("Tunnel setup failed: " + e .getMessage (), e );
251286 }
252287 }
253288 }
0 commit comments