1// Copyright 2017 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5import 'dart:async'; 6 7import 'package:meta/meta.dart'; 8import 'package:test_api/backend.dart'; 9import 'package:test_core/src/executable.dart' as test; // ignore: implementation_imports 10import 'package:test_core/src/runner/hack_register_platform.dart' as hack; // ignore: implementation_imports 11 12import '../artifacts.dart'; 13import '../base/common.dart'; 14import '../base/file_system.dart'; 15import '../base/io.dart'; 16import '../base/process_manager.dart'; 17import '../base/terminal.dart'; 18import '../dart/package_map.dart'; 19import '../globals.dart'; 20import '../project.dart'; 21import '../web/compile.dart'; 22import 'flutter_platform.dart' as loader; 23import 'flutter_web_platform.dart'; 24import 'watcher.dart'; 25 26/// Runs tests using package:test and the Flutter engine. 27Future<int> runTests( 28 List<String> testFiles, { 29 Directory workDir, 30 List<String> names = const <String>[], 31 List<String> plainNames = const <String>[], 32 bool enableObservatory = false, 33 bool startPaused = false, 34 bool disableServiceAuthCodes = false, 35 bool ipv6 = false, 36 bool machine = false, 37 String precompiledDillPath, 38 Map<String, String> precompiledDillFiles, 39 bool trackWidgetCreation = false, 40 bool updateGoldens = false, 41 TestWatcher watcher, 42 @required int concurrency, 43 bool buildTestAssets = false, 44 FlutterProject flutterProject, 45 String icudtlPath, 46 Directory coverageDirectory, 47 bool web = false, 48}) async { 49 // Compute the command-line arguments for package:test. 50 final List<String> testArgs = <String>[ 51 if (!terminal.supportsColor) 52 '--no-color', 53 if (machine) 54 ...<String>['-r', 'json'] 55 else 56 ...<String>['-r', 'compact'], 57 '--concurrency=$concurrency', 58 for (String name in names) 59 ...<String>['--name', name], 60 for (String plainName in plainNames) 61 ...<String>['--plain-name', plainName], 62 ]; 63 if (web) { 64 final String tempBuildDir = fs.systemTempDirectory 65 .createTempSync('_flutter_test') 66 .absolute 67 .uri 68 .toFilePath(); 69 final bool result = await webCompilationProxy.initialize( 70 projectDirectory: flutterProject.directory, 71 testOutputDir: tempBuildDir, 72 ); 73 if (!result) { 74 throwToolExit('Failed to compile tests'); 75 } 76 testArgs 77 ..add('--platform=chrome') 78 ..add('--precompiled=$tempBuildDir') 79 ..add('--') 80 ..addAll(testFiles); 81 hack.registerPlatformPlugin( 82 <Runtime>[Runtime.chrome], 83 () { 84 return FlutterWebPlatform.start(flutterProject.directory.path); 85 } 86 ); 87 await test.main(testArgs); 88 return exitCode; 89 } 90 91 testArgs 92 ..add('--') 93 ..addAll(testFiles); 94 95 // Configure package:test to use the Flutter engine for child processes. 96 final String shellPath = artifacts.getArtifactPath(Artifact.flutterTester); 97 if (!processManager.canRun(shellPath)) 98 throwToolExit('Cannot find Flutter shell at $shellPath'); 99 100 final InternetAddressType serverType = 101 ipv6 ? InternetAddressType.IPv6 : InternetAddressType.IPv4; 102 103 final loader.FlutterPlatform platform = loader.installHook( 104 shellPath: shellPath, 105 watcher: watcher, 106 enableObservatory: enableObservatory, 107 machine: machine, 108 startPaused: startPaused, 109 disableServiceAuthCodes: disableServiceAuthCodes, 110 serverType: serverType, 111 precompiledDillPath: precompiledDillPath, 112 precompiledDillFiles: precompiledDillFiles, 113 trackWidgetCreation: trackWidgetCreation, 114 updateGoldens: updateGoldens, 115 buildTestAssets: buildTestAssets, 116 projectRootDirectory: fs.currentDirectory.uri, 117 flutterProject: flutterProject, 118 icudtlPath: icudtlPath, 119 ); 120 121 // Make the global packages path absolute. 122 // (Makes sure it still works after we change the current directory.) 123 PackageMap.globalPackagesPath = 124 fs.path.normalize(fs.path.absolute(PackageMap.globalPackagesPath)); 125 126 // Call package:test's main method in the appropriate directory. 127 final Directory saved = fs.currentDirectory; 128 try { 129 if (workDir != null) { 130 printTrace('switching to directory $workDir to run tests'); 131 fs.currentDirectory = workDir; 132 } 133 134 printTrace('running test package with arguments: $testArgs'); 135 await test.main(testArgs); 136 137 // test.main() sets dart:io's exitCode global. 138 printTrace('test package returned with exit code $exitCode'); 139 140 return exitCode; 141 } finally { 142 fs.currentDirectory = saved; 143 await platform.close(); 144 } 145} 146