resident_web_runner_cold_test.dart 6.98 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/dart/pub.dart';
14
import 'package:flutter_tools/src/device.dart';
15
import 'package:flutter_tools/src/globals.dart' as globals;
16 17
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/resident_runner.dart';
18
import 'package:flutter_tools/src/build_runner/resident_web_runner.dart';
19
import 'package:flutter_tools/src/web/chrome.dart';
20
import 'package:flutter_tools/src/build_runner/devfs_web.dart';
21
import 'package:flutter_tools/src/web/web_device.dart';
22
import 'package:mockito/mockito.dart';
23
import 'package:platform/platform.dart';
24
import 'package:vm_service/vm_service.dart';
25
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
26 27 28 29 30 31 32

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

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

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

64
  void _setupMocks() {
65
    globals.fs.file('.packages').writeAsStringSync('\n');
66 67 68
    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);
69 70 71 72
  }

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

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

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

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

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

    expect(result.code, 1);
    expect(result.message, contains('Failed to recompile application.'));
123 124
  }, overrides: <Type, Generator>{
    BuildSystem: () => mockBuildSystem,
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 152 153
  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);
154 155
  }, overrides: <Type, Generator>{
    BuildSystem: () => mockBuildSystem,
156 157
  }));

158 159
}

160
class MockWebDevFS extends Mock implements WebDevFS {}
161 162 163
class MockWebDevice extends Mock implements Device {}
class MockDebugConnection extends Mock implements DebugConnection {}
class MockVmService extends Mock implements VmService {}
164
class MockStatus extends Mock implements Status {}
165
class MockFlutterDevice extends Mock implements FlutterDevice {}
166 167 168 169 170
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 {}
171
class MockBuildSystem extends Mock implements BuildSystem {}
172
class MockPub extends Mock implements Pub {}