resident_web_runner_cold_test.dart 6.86 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5 6 7 8
// 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:dwds/dwds.dart';
import 'package:flutter_tools/src/base/common.dart';
9
import 'package:flutter_tools/src/base/logger.dart';
10
import 'package:flutter_tools/src/base/terminal.dart';
11
import 'package:flutter_tools/src/build_info.dart';
12
import 'package:flutter_tools/src/build_system/build_system.dart';
13
import 'package:flutter_tools/src/device.dart';
14
import 'package:flutter_tools/src/globals.dart' as globals;
15 16
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/resident_runner.dart';
17
import 'package:flutter_tools/src/build_runner/resident_web_runner.dart';
18
import 'package:flutter_tools/src/web/chrome.dart';
19
import 'package:flutter_tools/src/build_runner/devfs_web.dart';
20
import 'package:flutter_tools/src/web/web_device.dart';
21
import 'package:mockito/mockito.dart';
22
import 'package:platform/platform.dart';
23
import 'package:vm_service/vm_service.dart';
24
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
25 26 27 28 29 30 31

import '../src/common.dart';
import '../src/testbed.dart';

void main() {
  Testbed testbed;
  ResidentWebRunner residentWebRunner;
32
  MockFlutterDevice mockFlutterDevice;
33 34
  MockWebDevFS mockWebDevFS;
  MockBuildSystem mockBuildSystem;
35 36

  setUp(() {
37 38
    mockWebDevFS = MockWebDevFS();
    mockBuildSystem = MockBuildSystem();
39
    final MockWebDevice mockWebDevice = MockWebDevice();
40 41
    mockFlutterDevice = MockFlutterDevice();
    when(mockFlutterDevice.device).thenReturn(mockWebDevice);
42 43 44 45 46
    when(mockFlutterDevice.devFS).thenReturn(mockWebDevFS);
    when(mockWebDevFS.sources).thenReturn(<Uri>[]);
    when(mockBuildSystem.build(any, any)).thenAnswer((Invocation invocation) async {
      return BuildResult(success: true);
    });
47 48
    testbed = Testbed(
      setup: () {
49
        residentWebRunner = residentWebRunner = DwdsWebRunnerFactory().createWebRunner(
50
          mockFlutterDevice,
51 52 53
          flutterProject: FlutterProject.current(),
          debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
          ipv6: true,
54
          stayResident: true,
55
          dartDefines: const <String>[],
56
          urlTunneller: null,
57
        ) as ResidentWebRunner;
58
      },
59
    );
60 61
  });

62
  void _setupMocks() {
63
    globals.fs.file('.packages').writeAsStringSync('\n');
64 65 66
    globals.fs.file('pubspec.yaml').createSync();
    globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
    globals.fs.file(globals.fs.path.join('web', 'index.html')).createSync(recursive: true);
67 68 69 70
  }

  test('Can successfully run and connect without vmservice', () => testbed.run(() async {
    _setupMocks();
71
    final DelegateLogger delegateLogger = globals.logger as DelegateLogger;
72 73
    final MockStatus mockStatus = MockStatus();
    delegateLogger.status = mockStatus;
74 75 76 77 78 79 80
    final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    final DebugConnectionInfo debugConnectionInfo = await connectionInfoCompleter.future;

    expect(debugConnectionInfo.wsUri, null);
81 82
    verify(mockStatus.stop()).called(1);
  }, overrides: <Type, Generator>{
83
    BuildSystem: () => mockBuildSystem,
84 85 86 87 88 89 90
    Logger: () => DelegateLogger(BufferLogger(
      terminal: AnsiTerminal(
        stdio: null,
        platform: const LocalPlatform(),
      ),
      outputPreferences: OutputPreferences.test(),
    )),
91 92 93 94 95
  }));

  test('Can full restart after attaching', () => testbed.run(() async {
    _setupMocks();
    final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
96
    unawaited(residentWebRunner.run(
97 98 99 100 101 102
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;
    final OperationResult result = await residentWebRunner.restart(fullRestart: true);

    expect(result.code, 0);
103 104
  }, overrides: <Type, Generator>{
    BuildSystem: () => mockBuildSystem,
105 106 107 108 109
  }));

  test('Fails on compilation errors in hot restart', () => testbed.run(() async {
    _setupMocks();
    final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
110
    unawaited(residentWebRunner.run(
111 112 113
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;
114 115
    when(mockBuildSystem.build(any, any)).thenAnswer((Invocation invocation) async {
      return BuildResult(success: false);
116 117 118 119 120
    });
    final OperationResult result = await residentWebRunner.restart(fullRestart: true);

    expect(result.code, 1);
    expect(result.message, contains('Failed to recompile application.'));
121 122
  }, overrides: <Type, Generator>{
    BuildSystem: () => mockBuildSystem,
123 124
  }));

125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
  test('Correctly performs a full refresh on attached chrome device.', () => testbed.run(() async {
    _setupMocks();
    final MockChromeDevice chromeDevice = MockChromeDevice();
    final MockChrome chrome = MockChrome();
    final MockChromeConnection mockChromeConnection = MockChromeConnection();
    final MockChromeTab mockChromeTab = MockChromeTab();
    final MockWipConnection mockWipConnection = MockWipConnection();
    when(mockChromeConnection.getTab(any)).thenAnswer((Invocation invocation) async {
      return mockChromeTab;
    });
    when(mockChromeTab.connect()).thenAnswer((Invocation invocation) async {
      return mockWipConnection;
    });
    when(chrome.chromeConnection).thenReturn(mockChromeConnection);
    launchChromeInstance(chrome);
    when(mockFlutterDevice.device).thenReturn(chromeDevice);
    final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
    unawaited(residentWebRunner.run(
      connectionInfoCompleter: connectionInfoCompleter,
    ));
    await connectionInfoCompleter.future;
    final OperationResult result = await residentWebRunner.restart(fullRestart: true);

    expect(result.code, 0);
    verify(mockWipConnection.sendCommand('Page.reload', <String, Object>{
      'ignoreCache': true,
    })).called(1);
152 153
  }, overrides: <Type, Generator>{
    BuildSystem: () => mockBuildSystem,
154 155
  }));

156 157
}

158
class MockWebDevFS extends Mock implements WebDevFS {}
159 160 161
class MockWebDevice extends Mock implements Device {}
class MockDebugConnection extends Mock implements DebugConnection {}
class MockVmService extends Mock implements VmService {}
162
class MockStatus extends Mock implements Status {}
163
class MockFlutterDevice extends Mock implements FlutterDevice {}
164 165 166 167 168
class MockChromeDevice extends Mock implements ChromeDevice {}
class MockChrome extends Mock implements Chrome {}
class MockChromeConnection extends Mock implements ChromeConnection {}
class MockChromeTab extends Mock implements ChromeTab {}
class MockWipConnection extends Mock implements WipConnection {}
169
class MockBuildSystem extends Mock implements BuildSystem {}