diff --git a/packages/flutter_tools/test/integration.shard/flutter_run_with_error_test.dart b/packages/flutter_tools/test/integration.shard/flutter_run_with_error_test.dart new file mode 100644 index 0000000000..3cf44ba88b --- /dev/null +++ b/packages/flutter_tools/test/integration.shard/flutter_run_with_error_test.dart @@ -0,0 +1,69 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:file/file.dart'; +import 'package:flutter_tools/src/base/file_system.dart'; + +import '../src/common.dart'; +import 'test_data/project_with_early_error.dart'; +import 'test_driver.dart'; +import 'test_utils.dart'; + +void main() { + Directory tempDir; + final ProjectWithEarlyError _project = ProjectWithEarlyError(); + const String _exceptionStart = '══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞══════════════════'; + FlutterRunTestDriver _flutter; + + setUp(() async { + tempDir = createResolvedTempDirectorySync('run_test.'); + await _project.setUpIn(tempDir); + _flutter = FlutterRunTestDriver(tempDir); + }); + + tearDown(() async { + await _flutter.stop(); + tryToDelete(tempDir); + }); + + test('flutter run reports an early error in an application', () async { + final StringBuffer stdout = StringBuffer(); + _flutter.stdout.listen(stdout.writeln); + + await _flutter.run(startPaused: true, withDebugger: true, structuredErrors: true); + await _flutter.resume(); + await _flutter.stop(); + + expect(stdout.toString(), contains(_exceptionStart)); + }); + + test('flutter run for web reports an early error in an application', () async { + final StringBuffer stdout = StringBuffer(); + + await _flutter.run(startPaused: true, withDebugger: true, structuredErrors: true, chrome: true); + await _flutter.resume(); + + final Completer completer = Completer(); + bool lineFound = false; + + await Future(() async { + _flutter.stdout.listen((String line) { + stdout.writeln(line); + if (line.startsWith('Another exception was thrown') && !lineFound) { + lineFound = true; + completer.complete(); + } + }); + await completer.future; + }).timeout(const Duration(seconds: 15), onTimeout: () { + // Complete anyway in case we don't see the 'Another exception' line. + completer.complete(); + }); + + expect(stdout.toString(), contains(_exceptionStart)); + await _flutter.stop(); + }, skip: 'Running in cirrus environment causes premature exit'); +} diff --git a/packages/flutter_tools/test/integration.shard/test_data/project_with_early_error.dart b/packages/flutter_tools/test/integration.shard/test_data/project_with_early_error.dart new file mode 100644 index 0000000000..dabc96f17b --- /dev/null +++ b/packages/flutter_tools/test/integration.shard/test_data/project_with_early_error.dart @@ -0,0 +1,41 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'project.dart'; + +class ProjectWithEarlyError extends Project { + + @override + final String pubspec = ''' + name: test + environment: + sdk: ">=2.0.0-dev.68.0 <3.0.0" + + dependencies: + flutter: + sdk: flutter + '''; + + @override + final String main = r''' + import 'dart:async'; + + import 'package:flutter/material.dart'; + + Future main() async { + while (true) { + runApp(new MyApp()); + await Future.delayed(const Duration(milliseconds: 50)); + } + } + + class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + throw FormatException(); + } + } + '''; + +} diff --git a/packages/flutter_tools/test/integration.shard/test_driver.dart b/packages/flutter_tools/test/integration.shard/test_driver.dart index 0ee0c67604..9d842bd2a0 100644 --- a/packages/flutter_tools/test/integration.shard/test_driver.dart +++ b/packages/flutter_tools/test/integration.shard/test_driver.dart @@ -437,6 +437,7 @@ class FlutterRunTestDriver extends FlutterTestDriver { bool startPaused = false, bool pauseOnExceptions = false, bool chrome = false, + bool structuredErrors = false, File pidFile, String script, }) async { @@ -451,6 +452,8 @@ class FlutterRunTestDriver extends FlutterTestDriver { ...['chrome', '--web-run-headless', '--web-enable-expression-evaluation'] else 'flutter-tester', + if (structuredErrors) + '--dart-define=flutter.inspector.structuredErrors=true', ], withDebugger: withDebugger, startPaused: startPaused,