@@ -1774,6 +1774,13 @@ class CdpDriver implements AppDriver {
17741774
17751775 Future <Map <String , dynamic >> _call (String method,
17761776 [Map <String , dynamic >? params]) async {
1777+ // If disconnected but reconnecting, wait up to 30s for reconnection
1778+ if ((_ws == null || ! _connected) && _reconnecting) {
1779+ for (int i = 0 ; i < 60 ; i++ ) {
1780+ await Future .delayed (const Duration (milliseconds: 500 ));
1781+ if (_connected && _ws != null ) break ;
1782+ }
1783+ }
17771784 if (_ws == null || ! _connected) {
17781785 throw Exception ('Not connected via CDP' );
17791786 }
@@ -2057,9 +2064,56 @@ function _dqAll(sel, root) {
20572064 }
20582065 }
20592066
2067+ /// Whether auto-reconnect is in progress.
2068+ bool _reconnecting = false ;
2069+
2070+ /// Max auto-reconnect attempts.
2071+ static const int _maxReconnectAttempts = 5 ;
2072+
20602073 void _onDisconnect () {
20612074 _connected = false ;
20622075 _failAllPending ('Connection lost' );
2076+ // Trigger auto-reconnect (non-blocking)
2077+ _autoReconnect ();
2078+ }
2079+
2080+ /// Auto-reconnect to CDP when connection drops (e.g. CfT restart).
2081+ Future <void > _autoReconnect () async {
2082+ if (_reconnecting) return ;
2083+ _reconnecting = true ;
2084+ try {
2085+ for (int attempt = 1 ; attempt <= _maxReconnectAttempts; attempt++ ) {
2086+ // Exponential backoff: 1s, 2s, 4s, 8s, 16s
2087+ await Future .delayed (Duration (seconds: 1 << (attempt - 1 )));
2088+ try {
2089+ final wsUrl = await _discoverTarget ();
2090+ if (wsUrl == null ) continue ;
2091+
2092+ _ws = await WebSocket .connect (wsUrl)
2093+ .timeout (const Duration (seconds: 10 ));
2094+ _connected = true ;
2095+
2096+ _ws! .listen (
2097+ _onMessage,
2098+ onDone: _onDisconnect,
2099+ onError: (_) => _onDisconnect (),
2100+ cancelOnError: false ,
2101+ );
2102+
2103+ // Re-enable required CDP domains
2104+ await Future .wait ([
2105+ _call ('Page.enable' ),
2106+ _call ('DOM.enable' ),
2107+ _call ('Runtime.enable' ),
2108+ ]);
2109+ return ; // Success
2110+ } catch (_) {
2111+ // Retry
2112+ }
2113+ }
2114+ } finally {
2115+ _reconnecting = false ;
2116+ }
20632117 }
20642118
20652119 void _failAllPending (String reason) {
0 commit comments