• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 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';
6import 'dart:convert';
7import 'dart:io';
8
9import 'package:path/path.dart' as path;
10import 'package:vm_service_client/vm_service_client.dart';
11
12import 'package:flutter_devicelab/framework/adb.dart';
13import 'package:flutter_devicelab/framework/framework.dart';
14import 'package:flutter_devicelab/framework/utils.dart';
15
16void main() {
17  task(() async {
18    int vmServicePort;
19
20    final Device device = await devices.workingDevice;
21    await device.unlock();
22    final Directory appDir = dir(path.join(flutterDirectory.path, 'dev/integration_tests/ui'));
23    await inDirectory(appDir, () async {
24      final Completer<void> ready = Completer<void>();
25      bool ok;
26      print('run: starting...');
27      final Process run = await startProcess(
28        path.join(flutterDirectory.path, 'bin', 'flutter'),
29        <String>['run', '--verbose', '--disable-service-auth-codes', '-d', device.deviceId, 'lib/commands.dart'],
30      );
31      final StreamController<String> stdout = StreamController<String>.broadcast();
32      run.stdout
33        .transform<String>(utf8.decoder)
34        .transform<String>(const LineSplitter())
35        .listen((String line) {
36          print('run:stdout: $line');
37          stdout.add(line);
38          if (vmServicePort == null) {
39            vmServicePort = parseServicePort(line);
40            if (vmServicePort != null) {
41              print('service protocol connection available at port $vmServicePort');
42              print('run: ready!');
43              ready.complete();
44              ok ??= true;
45            }
46          }
47        });
48      run.stderr
49        .transform<String>(utf8.decoder)
50        .transform<String>(const LineSplitter())
51        .listen((String line) {
52          stderr.writeln('run:stderr: $line');
53        });
54      run.exitCode.then<void>((int exitCode) { ok = false; });
55      await Future.any<dynamic>(<Future<dynamic>>[ ready.future, run.exitCode ]);
56      if (!ok)
57        throw 'Failed to run test app.';
58
59      final VMServiceClient client = VMServiceClient.connect('ws://localhost:$vmServicePort/ws');
60
61      final DriveHelper driver = DriveHelper(vmServicePort);
62
63      await driver.drive('none');
64      print('test: pressing "p" to enable debugPaintSize...');
65      run.stdin.write('p');
66      await driver.drive('debug_paint');
67      print('test: pressing "p" again...');
68      run.stdin.write('p');
69      await driver.drive('none');
70      print('test: pressing "P" to enable performance overlay...');
71      run.stdin.write('P');
72      await driver.drive('performance_overlay');
73      print('test: pressing "P" again...');
74      run.stdin.write('P');
75      await driver.drive('none');
76      final Future<String> reloadStartingText =
77        stdout.stream.firstWhere((String line) => line.endsWith('] Initializing hot reload...'));
78      final Future<String> reloadEndingText =
79        stdout.stream.firstWhere((String line) => line.contains('] Reloaded ') && line.endsWith('ms.'));
80      print('test: pressing "r" to perform a hot reload...');
81      run.stdin.write('r');
82      await reloadStartingText;
83      await reloadEndingText;
84      await driver.drive('none');
85      final Future<String> restartStartingText =
86        stdout.stream.firstWhere((String line) => line.endsWith('Performing hot restart...'));
87      final Future<String> restartEndingText =
88        stdout.stream.firstWhere((String line) => line.contains('] Restarted application in '));
89      print('test: pressing "R" to perform a full reload...');
90      run.stdin.write('R');
91      await restartStartingText;
92      await restartEndingText;
93      await driver.drive('none');
94      run.stdin.write('q');
95      final int result = await run.exitCode;
96      if (result != 0)
97        throw 'Received unexpected exit code $result from run process.';
98      print('test: validating that the app has in fact closed...');
99      await client.done.timeout(const Duration(seconds: 5));
100    });
101    return TaskResult.success(null);
102  });
103}
104
105class DriveHelper {
106  DriveHelper(this.vmServicePort);
107
108  final int vmServicePort;
109
110  Future<void> drive(String name) async {
111    print('drive: running commands_$name check...');
112    final Process drive = await startProcess(
113      path.join(flutterDirectory.path, 'bin', 'flutter'),
114      <String>['drive', '--use-existing-app', 'http://127.0.0.1:$vmServicePort/', '--keep-app-running', '--driver', 'test_driver/commands_${name}_test.dart'],
115    );
116    drive.stdout
117        .transform<String>(utf8.decoder)
118        .transform<String>(const LineSplitter())
119        .listen((String line) {
120      print('drive:stdout: $line');
121    });
122    drive.stderr
123        .transform<String>(utf8.decoder)
124        .transform<String>(const LineSplitter())
125        .listen((String line) {
126      stderr.writeln('drive:stderr: $line');
127    });
128    final int result = await drive.exitCode;
129    if (result != 0)
130      throw 'Failed to drive test app (exit code $result).';
131    print('drive: finished commands_$name check successfully.');
132  }
133}
134