mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Bumps the Dart version to 3.8 across the repo (excluding engine/src/flutter/third_party) and applies formatting updates from Dart 3.8. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
161 lines
6.0 KiB
Dart
161 lines
6.0 KiB
Dart
// Copyright 2014 The Flutter 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:async';
|
|
|
|
import '../common.dart';
|
|
|
|
/// The web implementation of [CallbackManager].
|
|
///
|
|
/// See also:
|
|
///
|
|
/// * `_callback_io.dart`, which has the dart:io implementation
|
|
CallbackManager get callbackManager => _singletonWebDriverCommandManager;
|
|
|
|
/// WebDriverCommandManager singleton.
|
|
final _WebCallbackManager _singletonWebDriverCommandManager = _WebCallbackManager();
|
|
|
|
/// Manages communication between `integration_tests` and the `driver_tests`.
|
|
///
|
|
/// Along with responding to callbacks from the driver side this calls enables
|
|
/// usage of Web Driver commands by sending [WebDriverCommand]s to driver side.
|
|
///
|
|
/// Tests can execute an Web Driver commands such as `screenshot` using browsers'
|
|
/// WebDriver APIs.
|
|
///
|
|
/// See: https://www.w3.org/TR/webdriver/
|
|
class _WebCallbackManager implements CallbackManager {
|
|
/// App side tests will put the command requests from WebDriver to this pipe.
|
|
Completer<WebDriverCommand> _webDriverCommandPipe = Completer<WebDriverCommand>();
|
|
|
|
/// Updated when WebDriver completes the request by the test method.
|
|
///
|
|
/// For example, a test method will ask for a screenshot by calling
|
|
/// `takeScreenshot`. When this screenshot is taken [_driverCommandComplete]
|
|
/// will complete.
|
|
Completer<bool> _driverCommandComplete = Completer<bool>();
|
|
|
|
/// Takes screenshot using WebDriver screenshot command.
|
|
///
|
|
/// Only works on Web when tests are run via `flutter driver` command.
|
|
///
|
|
/// See: https://www.w3.org/TR/webdriver/#screen-capture.
|
|
@override
|
|
Future<Map<String, dynamic>> takeScreenshot(
|
|
String screenshotName, [
|
|
Map<String, Object?>? args,
|
|
]) async {
|
|
await _sendWebDriverCommand(WebDriverCommand.screenshot(screenshotName, args));
|
|
return <String, dynamic>{
|
|
'screenshotName': screenshotName,
|
|
// Flutter Web doesn't provide the bytes.
|
|
'bytes': <int>[],
|
|
};
|
|
}
|
|
|
|
@override
|
|
Future<void> convertFlutterSurfaceToImage() async {
|
|
// Noop on Web.
|
|
}
|
|
|
|
Future<void> _sendWebDriverCommand(WebDriverCommand command) async {
|
|
try {
|
|
_webDriverCommandPipe.complete(command);
|
|
final bool awaitCommand = await _driverCommandComplete.future;
|
|
if (!awaitCommand) {
|
|
throw Exception(
|
|
'Web Driver Command ${command.type} failed while waiting for '
|
|
'driver side',
|
|
);
|
|
}
|
|
} catch (exception) {
|
|
throw Exception('Web Driver Command failed: ${command.type} with exception $exception');
|
|
} finally {
|
|
// Reset the completer.
|
|
_driverCommandComplete = Completer<bool>();
|
|
}
|
|
}
|
|
|
|
/// The callback function to response the driver side input.
|
|
///
|
|
/// Provides a handshake mechanism for executing [WebDriverCommand]s on the
|
|
/// driver side.
|
|
@override
|
|
Future<Map<String, dynamic>> callback(
|
|
Map<String, String> params,
|
|
IntegrationTestResults testRunner,
|
|
) async {
|
|
final String command = params['command']!;
|
|
Map<String, String> response;
|
|
switch (command) {
|
|
case 'request_data':
|
|
return params['message'] == null
|
|
? _requestData(testRunner)
|
|
: _requestDataWithMessage(params['message']!, testRunner);
|
|
case 'get_health':
|
|
response = <String, String>{'status': 'ok'};
|
|
default:
|
|
throw UnimplementedError('$command is not implemented');
|
|
}
|
|
return <String, dynamic>{'isError': false, 'response': response};
|
|
}
|
|
|
|
Future<Map<String, dynamic>> _requestDataWithMessage(
|
|
String extraMessage,
|
|
IntegrationTestResults testRunner,
|
|
) async {
|
|
Map<String, String> response;
|
|
// Driver side tests' status is added as an extra message.
|
|
final DriverTestMessage message = DriverTestMessage.fromString(extraMessage);
|
|
// If driver side tests are pending send the first command in the
|
|
// `commandPipe` to the tests.
|
|
if (message.isPending) {
|
|
final WebDriverCommand command = await _webDriverCommandPipe.future;
|
|
switch (command.type) {
|
|
case WebDriverCommandType.screenshot:
|
|
final Map<String, dynamic> data = Map<String, dynamic>.from(command.values);
|
|
data.addAll(WebDriverCommand.typeToMap(WebDriverCommandType.screenshot));
|
|
response = <String, String>{'message': Response.webDriverCommand(data: data).toJson()};
|
|
case WebDriverCommandType.noop:
|
|
final Map<String, dynamic> data = <String, dynamic>{};
|
|
data.addAll(WebDriverCommand.typeToMap(WebDriverCommandType.noop));
|
|
response = <String, String>{'message': Response.webDriverCommand(data: data).toJson()};
|
|
case WebDriverCommandType.ack:
|
|
throw UnimplementedError('${command.type} is not implemented');
|
|
}
|
|
} else {
|
|
final Map<String, dynamic> data = <String, dynamic>{};
|
|
data.addAll(WebDriverCommand.typeToMap(WebDriverCommandType.ack));
|
|
response = <String, String>{'message': Response.webDriverCommand(data: data).toJson()};
|
|
_driverCommandComplete.complete(message.isSuccess);
|
|
_webDriverCommandPipe = Completer<WebDriverCommand>();
|
|
}
|
|
return <String, dynamic>{'isError': false, 'response': response};
|
|
}
|
|
|
|
Future<Map<String, dynamic>> _requestData(IntegrationTestResults testRunner) async {
|
|
final bool allTestsPassed = await testRunner.allTestsPassed.future;
|
|
final Map<String, String> response = <String, String>{
|
|
'message': allTestsPassed
|
|
? Response.allTestsPassed(data: testRunner.reportData).toJson()
|
|
: Response.someTestsFailed(
|
|
testRunner.failureMethodsDetails,
|
|
data: testRunner.reportData,
|
|
).toJson(),
|
|
};
|
|
return <String, dynamic>{'isError': false, 'response': response};
|
|
}
|
|
|
|
@override
|
|
void cleanup() {
|
|
if (!_webDriverCommandPipe.isCompleted) {
|
|
_webDriverCommandPipe.complete(Future<WebDriverCommand>.value(WebDriverCommand.noop()));
|
|
}
|
|
|
|
if (!_driverCommandComplete.isCompleted) {
|
|
_driverCommandComplete.complete(Future<bool>.value(false));
|
|
}
|
|
}
|
|
}
|