diff --git a/dwds/lib/dwds.dart b/dwds/lib/dwds.dart index 35a483c3b..c6af4af66 100644 --- a/dwds/lib/dwds.dart +++ b/dwds/lib/dwds.dart @@ -3,9 +3,12 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'package:build_daemon/data/build_status.dart'; +import 'package:dwds/src/debugging/webkit_debugger.dart'; import 'package:dwds/src/utilities/shared.dart'; +import 'package:http/http.dart' as http; import 'package:logging/logging.dart'; import 'package:meta/meta.dart'; import 'package:shelf/shelf.dart'; @@ -13,6 +16,7 @@ import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; import 'src/connections/app_connection.dart'; import 'src/connections/debug_connection.dart'; +import 'src/debugging/sources.dart'; import 'src/handlers/asset_handler.dart'; import 'src/handlers/dev_handler.dart'; import 'src/handlers/injected_handler.dart'; @@ -125,3 +129,34 @@ class Dwds { ); } } + +class Coverage { + LogWriter _logWriter; + Sources _sources; + + Coverage(this._logWriter, this._sources); + + Future start() async { + return await _sources.startPreciseCoverage(); + } + + Future collect() { + return _sources.takePreciseCoverage(); + } + + static Future init(LogWriter logWriter, String chromeUrl, int assetServerPort, String target, String applicationHost, int applicationPort) async { + final assetHandler = AssetHandler(assetServerPort, target, applicationHost, applicationPort); + + // set up debugger connection + final response = await http.get(chromeUrl + '/json'); + final url = jsonDecode(response.body)[0]['webSocketDebuggerUrl'] as String; + + final wipConnection = await WipConnection.connect(url); + final wipDebugger = WipDebugger(wipConnection); + final remoteDebugger = WebkitDebugger(wipDebugger); + + final sources = Sources(assetHandler, remoteDebugger, logWriter); + + return Coverage(logWriter, sources); + } +} diff --git a/dwds/lib/src/debugging/sources.dart b/dwds/lib/src/debugging/sources.dart index 02b4ccb65..bf4f2440b 100644 --- a/dwds/lib/src/debugging/sources.dart +++ b/dwds/lib/src/debugging/sources.dart @@ -39,6 +39,9 @@ class Sources { /// Paths to black box in the Chrome debugger. final _pathsToBlackBox = {'/packages/stack_trace/'}; + /// Determines whether or not we've already enabled the profile + bool _profilerEnabled = false; + /// Use `_readAssetOrNull` instead of using this directly, as it handles /// logging unsuccessful responses. final AssetHandler _assetHandler; @@ -127,6 +130,26 @@ class Sources { return tokenPosTable; } + Future startProfiler() async { + if (_profilerEnabled) { + return; + } + _profilerEnabled = true; + await _remoteDebugger.sendCommand('Profiler.enable'); + } + + Future startPreciseCoverage() async { + await startProfiler(); + await _remoteDebugger.sendCommand('Profiler.startPreciseCoverage'); + } + + Future takePreciseCoverage() async { + await startProfiler(); + final rawCoverage = await _remoteDebugger.sendCommand('Profiler.takePreciseCoverage'); + final jsCoverage = rawCoverage.result; + print('JS Coverage: $jsCoverage'); + } + void _clearCacheFor(WipScript script) { var serverPaths = _sourceToServerPaths[script.url] ?? {}; for (var serverPath in serverPaths) {