Skip to content

Commit

Permalink
Merge branch 'master' into clickable
Browse files Browse the repository at this point in the history
  • Loading branch information
CoderDake authored Jun 30, 2023
2 parents 136037b + 6658554 commit b49eac8
Show file tree
Hide file tree
Showing 15 changed files with 443 additions and 106 deletions.
55 changes: 36 additions & 19 deletions packages/devtools_app/integration_test/run_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:io';

import 'test_infra/run/_chrome_driver.dart';
import 'test_infra/run/_in_file_args.dart';
import 'test_infra/run/run_test.dart';

Expand All @@ -18,26 +19,42 @@ const _testSuffix = '_test.dart';
const _offlineIndicator = 'integration_test/test/offline';

void main(List<String> args) async {
final testRunnerArgs = TestRunnerArgs(args, verifyValidTarget: false);
if (testRunnerArgs.testTarget != null) {
// TODO(kenz): add support for specifying a directory as the target instead
// of a single file.
await _runTest(testRunnerArgs);
} else {
// Run all tests since a target test was not provided.
final testDirectory = Directory(_testDirectory);
final testFiles = testDirectory
.listSync(recursive: true)
.where((testFile) => testFile.path.endsWith(_testSuffix));

for (final testFile in testFiles) {
final testTarget = testFile.path;
final newArgsWithTarget = TestRunnerArgs([
...args,
'--${TestRunnerArgs.testTargetArg}=$testTarget',
]);
await _runTest(newArgsWithTarget);
Exception? exception;
final chromedriver = ChromeDriver();

try {
// Start chrome driver before running the flutter integration test.
await chromedriver.start();

final testRunnerArgs = TestRunnerArgs(args, verifyValidTarget: false);
if (testRunnerArgs.testTarget != null) {
// TODO(kenz): add support for specifying a directory as the target instead
// of a single file.
await _runTest(testRunnerArgs);
} else {
// Run all tests since a target test was not provided.
final testDirectory = Directory(_testDirectory);
final testFiles = testDirectory
.listSync(recursive: true)
.where((testFile) => testFile.path.endsWith(_testSuffix));

for (final testFile in testFiles) {
final testTarget = testFile.path;
final newArgsWithTarget = TestRunnerArgs([
...args,
'--${TestRunnerArgs.testTargetArg}=$testTarget',
]);
await _runTest(newArgsWithTarget);
}
}
} on Exception catch (e) {
exception = e;
} finally {
await chromedriver.stop();
}

if (exception != null) {
throw exception;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2023 The Chromium 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:io';

import '_io_utils.dart';
import '_utils.dart';

class ChromeDriver with IOMixin {
late final Process _process;

// TODO(kenz): add error messaging if the chromedriver executable is not
// found. We can also consider using web installers directly in this script:
// https://github.com/flutter/flutter/wiki/Running-Flutter-Driver-tests-with-Web#web-installers-repo.
Future<void> start() async {
try {
debugLog('starting the chromedriver process');
_process = await Process.start(
'chromedriver',
[
'--port=4444',
],
);
listenToProcessOutput(_process, printTag: 'ChromeDriver');
} catch (e) {
// ignore: avoid-throw-in-catch-block, by design
throw Exception('Error starting chromedriver: $e');
}
}

Future<void> stop() async {
await cancelAllStreamSubscriptions();
debugLog('killing the chromedriver process');
_process.kill();
}
}
13 changes: 13 additions & 0 deletions packages/devtools_app/integration_test/test_infra/run/_utils.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2023 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// ignore_for_file: avoid_print

bool debugTestScript = false;

void debugLog(String log) {
if (debugTestScript) {
print(log);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ import 'package:collection/collection.dart';
import '_in_file_args.dart';
import '_io_utils.dart';
import '_test_app_driver.dart';

bool _debugTestScript = false;
import '_utils.dart';

/// Runs one test.
///
Expand Down Expand Up @@ -48,16 +47,6 @@ Future<void> runFlutterIntegrationTest(
}
}

// TODO(kenz): do we need to start chromedriver in headless mode?
// Start chrome driver before running the flutter integration test.
final chromedriver = ChromeDriver();
try {
await chromedriver.start();
} catch (e) {
// ignore: avoid-throw-in-catch-block, by design
throw Exception('Error starting chromedriver: $e');
}

// Run the flutter integration test.
final testRunner = TestRunner();
Exception? exception;
Expand All @@ -75,45 +64,19 @@ Future<void> runFlutterIntegrationTest(
exception = e;
} finally {
if (testApp != null) {
_debugLog('killing the test app');
debugLog('killing the test app');
await testApp.stop();
}

_debugLog('cancelling stream subscriptions');
debugLog('cancelling stream subscriptions');
await testRunner.cancelAllStreamSubscriptions();
await chromedriver.cancelAllStreamSubscriptions();

_debugLog('killing the chromedriver process');
chromedriver.kill();
}

if (exception != null) {
throw exception;
}
}

class ChromeDriver with IOMixin {
late final Process _process;

// TODO(kenz): add error messaging if the chromedriver executable is not
// found. We can also consider using web installers directly in this script:
// https://github.com/flutter/flutter/wiki/Running-Flutter-Driver-tests-with-Web#web-installers-repo.
Future<void> start() async {
_debugLog('starting the chromedriver process');
_process = await Process.start(
'chromedriver',
[
'--port=4444',
],
);
listenToProcessOutput(_process, printTag: 'ChromeDriver');
}

void kill() {
_process.kill();
}
}

class TestRunner with IOMixin {
static const _beginExceptionMarker = 'EXCEPTION CAUGHT';
static const _endExceptionMarker = '═════════════════════════';
Expand All @@ -130,7 +93,7 @@ class TestRunner with IOMixin {
Map<String, Object> testAppArguments = const <String, Object>{},
}) async {
Future<void> runTest({required int attemptNumber}) async {
_debugLog('starting the flutter drive process');
debugLog('starting the flutter drive process');
final process = await Process.start(
'flutter',
[
Expand Down Expand Up @@ -210,9 +173,9 @@ class TestRunner with IOMixin {
timeout,
]);

_debugLog('attempting to kill the flutter drive process');
debugLog('attempting to kill the flutter drive process');
process.kill();
_debugLog('flutter drive process has exited');
debugLog('flutter drive process has exited');

// Ignore exception handling and retries if the tests passed. This is to
// avoid bugs with the test runner where the test can fail after the test
Expand All @@ -224,7 +187,7 @@ class TestRunner with IOMixin {
'Integration test timed out on try #$attemptNumber: $testTarget',
);
} else {
_debugLog(
debugLog(
'Integration test timed out on try #$attemptNumber. Retrying '
'$testTarget now.',
);
Expand Down Expand Up @@ -276,12 +239,6 @@ class _TestResult {
}
}

void _debugLog(String log) {
if (_debugTestScript) {
print(log);
}
}

class TestRunnerArgs {
TestRunnerArgs(List<String> args, {bool verifyValidTarget = true}) {
final argParser = _buildArgParser();
Expand Down
2 changes: 1 addition & 1 deletion packages/devtools_app/lib/devtools.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
// the constant declaration `const String version =`.
// If you change the declaration you must also modify the regex in
// tools/update_version.dart.
const String version = '2.25.0';
const String version = '2.26.0-dev.0';
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,23 @@ import 'network_model.dart';
import 'network_screen.dart';
import 'network_service.dart';

/// Different types of Network Response which can be used to visualise response
/// on Response tab
enum NetworkResponseViewType {
auto,
text,
json;

@override
String toString() {
return switch (this) {
NetworkResponseViewType.json => 'Json',
NetworkResponseViewType.text => 'Text',
_ => 'Auto',
};
}
}

class NetworkController extends DisposableController
with
SearchControllerMixin<NetworkRequest>,
Expand Down Expand Up @@ -50,6 +67,22 @@ class NetworkController extends DisposableController

final _requests = ValueNotifier<NetworkRequests>(NetworkRequests());

/// Notifies that current response type has been changed
ValueListenable<NetworkResponseViewType> get currentResponseViewType =>
_currentResponseViewType;

final _currentResponseViewType =
ValueNotifier<NetworkResponseViewType>(NetworkResponseViewType.auto);

/// Change current response type
set setResponseViewType(NetworkResponseViewType type) =>
_currentResponseViewType.value = type;

/// Reset drop down to initial state when current network request is changed
void resetDropDown() {
_currentResponseViewType.value = NetworkResponseViewType.auto;
}

final selectedRequest = ValueNotifier<NetworkRequest?>(null);
late CurrentNetworkRequests _currentNetworkRequests;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,26 @@ class NetworkRequestInspector extends StatelessWidget {
(
tab: _buildTab(
tabName: NetworkRequestInspector._responseTabTitle,
trailing: HttpViewTrailingCopyButton(
data,
(data) => data.responseBody,
trailing: Row(
children: [
HttpResponseTrailingDropDown(
data,
currentResponseViewType:
controller.currentResponseViewType,
onChanged: (value) =>
controller.setResponseViewType = value,
),
HttpViewTrailingCopyButton(
data,
(data) => data.responseBody,
),
],
),
),
tabView: HttpResponseView(data),
tabView: HttpResponseView(
data,
currentResponseViewType: controller.currentResponseViewType,
),
),
if (data.hasCookies)
(
Expand Down
Loading

0 comments on commit b49eac8

Please sign in to comment.