waitForNetworkIdle method
Waits for the network to be idle
Implementation
Future<bool> waitForNetworkIdle({
int timeoutMillis = 30000,
int idleTimeMs = 500,
}) async {
_checkDisposed();
if (_controller == null) {
throw ScrapingException.validation(
'Browser not initialized',
isRetryable: false,
);
}
try {
// Inject a script to track network requests
await _controller!.evaluateJavascript(
source: """
window._networkRequests = 0;
window._originalFetch = window.fetch;
window._originalXHR = window.XMLHttpRequest.prototype.open;
window.fetch = function() {
window._networkRequests++;
return window._originalFetch.apply(this, arguments).finally(() => {
window._networkRequests--;
});
};
window.XMLHttpRequest.prototype.open = function() {
window._networkRequests++;
this.addEventListener('loadend', () => {
window._networkRequests--;
});
return window._originalXHR.apply(this, arguments);
};
""",
);
// Wait for network to be idle
final startTime = DateTime.now();
while (DateTime.now().difference(startTime).inMilliseconds <
timeoutMillis) {
final requests = await _controller!.evaluateJavascript(
source: "window._networkRequests",
);
if (requests is int && requests == 0) {
// Wait for the idle time to make sure no new requests start
await Future.delayed(Duration(milliseconds: idleTimeMs));
// Check again
final requestsAfterIdle = await _controller!.evaluateJavascript(
source: "window._networkRequests",
);
if (requestsAfterIdle is int && requestsAfterIdle == 0) {
return true;
}
}
await Future.delayed(const Duration(milliseconds: 100));
}
// Timeout reached
return false;
} catch (e) {
_log('Error waiting for network idle: $e', isError: true);
return false;
}
}