introduce an optional 'onError' parameter (#92)
* introduce an optional parameter
* address typo
* add some test plumbing
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cebbe9b..1301a48 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 1.2.0
+
+- Introduce an optional `onError` parameter when setting up a [WipConnection].
+ This can be used to report errors from the underlying [WebSocket].
+
## 1.1.0
- Have `ChromeConnection.getTabs` return better exceptions where there's a
diff --git a/lib/webkit_inspection_protocol.dart b/lib/webkit_inspection_protocol.dart
index 6f5f7df..251cd1a 100644
--- a/lib/webkit_inspection_protocol.dart
+++ b/lib/webkit_inspection_protocol.dart
@@ -175,8 +175,14 @@
bool get isBackgroundPage => type == 'background_page';
- Future<WipConnection> connect() =>
- WipConnection.connect(webSocketDebuggerUrl);
+ /// Connect to the debug connection for this tab and return a [WipConnection].
+ ///
+ /// On errors from this stream, the [onError] handler is called with the error
+ /// object and possibly a stack trace. The [onError] callback must be of type
+ /// `void Function(Object error)` or `void Function(Object error, StackTrace)`.
+ Future<WipConnection> connect({Function? onError}) {
+ return WipConnection.connect(webSocketDebuggerUrl, onError: onError);
+ }
@override
String toString() => url;
@@ -216,23 +222,34 @@
final _closeController = StreamController<WipConnection>.broadcast();
final _notificationController = StreamController<WipEvent>.broadcast();
- static Future<WipConnection> connect(String url) {
+ /// Connect to the given url and return a [WipConnection].
+ ///
+ /// On errors from this stream, the [onError] handler is called with the error
+ /// object and possibly a stack trace. The [onError] callback must be of type
+ /// `void Function(Object error)` or `void Function(Object error, StackTrace)`.
+ static Future<WipConnection> connect(String url, {Function? onError}) {
return WebSocket.connect(url).then((socket) {
- return WipConnection._(url, socket);
+ return WipConnection._(url, socket, onError: onError);
});
}
- WipConnection._(this.url, this._ws) {
- _ws.listen((data) {
- var json = jsonDecode(data as String) as Map<String, dynamic>;
+ WipConnection._(this.url, this._ws, {Function? onError}) {
+ void onData(dynamic /*String|List<int>*/ data) {
_onReceive.add(data);
+ var json = jsonDecode(data as String) as Map<String, dynamic>;
if (json.containsKey('id')) {
_handleResponse(json);
} else {
_handleNotification(json);
}
- }, onDone: _handleClose);
+ }
+
+ _ws.listen(
+ onData,
+ onError: onError,
+ onDone: _handleClose,
+ );
}
Stream<WipConnection> get onClose => _closeController.stream;
@@ -244,8 +261,10 @@
@override
String toString() => url;
- Future<WipResponse> sendCommand(String method,
- [Map<String, dynamic>? params]) {
+ Future<WipResponse> sendCommand(
+ String method, [
+ Map<String, dynamic>? params,
+ ]) {
var completer = Completer<WipResponse>();
var json = {'id': _nextId++, 'method': method};
if (params != null) {
diff --git a/pubspec.yaml b/pubspec.yaml
index 2aa2801..abcacc0 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: webkit_inspection_protocol
-version: 1.1.0
+version: 1.2.0
description: >
A client for the Chrome DevTools Protocol (previously called the Webkit
Inspection Protocol).
@@ -13,7 +13,7 @@
dev_dependencies:
args: ^2.0.0
- lints: ^2.0.0
+ lints: '>=1.0.0 <3.0.0'
shelf_static: ^1.0.0
shelf_web_socket: ^1.0.0
shelf: ^1.0.0
diff --git a/test/test_setup.dart b/test/test_setup.dart
index 857e445..afd1d64 100644
--- a/test/test_setup.dart
+++ b/test/test_setup.dart
@@ -13,7 +13,7 @@
Future<WipConnection>? _wipConnection;
/// Returns a (cached) debugger connection to the first regular tab of
-/// the browser with remote debugger running at 'localhost:9222',
+/// the browser with remote debugger running at 'localhost:9222'.
Future<WipConnection> get wipConnection {
_wipConnection ??= () async {
var debugPort = await _startWebDriver(await _startChromeDriver());
@@ -27,6 +27,21 @@
return _wipConnection!;
}
+/// Returns a (cached) debugger connection to the first regular tab of
+/// the browser with remote debugger running at 'localhost:9222'.
+Future<WipConnection> createWipConnection({Function? onError}) {
+ _wipConnection ??= () async {
+ var debugPort = await _startWebDriver(await _startChromeDriver());
+ var chrome = ChromeConnection('localhost', debugPort);
+ var tab = (await chrome
+ .getTab((tab) => !tab.isBackgroundPage && !tab.isChromeExtension))!;
+ var connection = await tab.connect(onError: onError);
+ connection.onClose.listen((_) => _wipConnection = null);
+ return connection;
+ }();
+ return _wipConnection!;
+}
+
Process? _chromeDriver;
/// Starts ChromeDriver and returns the listening port.
@@ -61,18 +76,24 @@
var capabilities = Capabilities.chrome
..addAll({
Capabilities.chromeOptions: {
- 'args': ['remote-debugging-port=$debugPort', '--headless']
+ 'args': ['remote-debugging-port=$debugPort', '--headless'],
}
});
- await createDriver(
- spec: WebDriverSpec.JsonWire,
- desired: capabilities,
- uri: Uri.parse('http://127.0.0.1:$chromeDriverPort/wd/hub/'));
+ _webDriver = await createDriver(
+ spec: WebDriverSpec.JsonWire,
+ desired: capabilities,
+ uri: Uri.parse('http://127.0.0.1:$chromeDriverPort/wd/hub/'),
+ );
return debugPort;
}
+void killChromeDriver() {
+ _chromeDriver?.kill();
+ _chromeDriver = null;
+}
+
/// Returns a port that is probably, but not definitely, not in use.
///
/// This has a built-in race condition: another process may bind this port at
@@ -118,10 +139,12 @@
Future closeConnection() async {
if (_wipConnection != null) {
- await _webDriver?.quit(closeSession: true);
+ await _webDriver?.quit(closeSession: true).catchError((e) => null);
_webDriver = null;
+
_chromeDriver?.kill();
_chromeDriver = null;
+
_wipConnection = null;
}
}