From 665d380f81dcc30ec923a89551b1f9e37cb4a604 Mon Sep 17 00:00:00 2001 From: Angjie Li <56002538+angjieli@users.noreply.github.com> Date: Mon, 9 Mar 2020 13:01:07 -0700 Subject: [PATCH] Add Android Chrome support to Flutter Web Driver. (#51677) * Support Android Chrome for Flutter Web Driver. --- .../lib/src/driver/web_driver.dart | 19 +++--- .../flutter_tools/lib/src/commands/drive.dart | 60 +++++++++++++------ .../commands.shard/hermetic/drive_test.dart | 13 ++++ 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/packages/flutter_driver/lib/src/driver/web_driver.dart b/packages/flutter_driver/lib/src/driver/web_driver.dart index 88a859eb89b..9b21690ec2b 100644 --- a/packages/flutter_driver/lib/src/driver/web_driver.dart +++ b/packages/flutter_driver/lib/src/driver/web_driver.dart @@ -20,10 +20,8 @@ import 'timeline.dart'; /// An implementation of the Flutter Driver using the WebDriver. /// /// Example of how to test WebFlutterDriver: -/// 1. Have Selenium server (https://bit.ly/2TlkRyu) and WebDriver binary (https://chromedriver.chromium.org/downloads) downloaded and placed under the same folder -/// 2. Launch WebDriver Server: java -jar selenium-server-standalone-3.141.59.jar -/// 3. Launch Flutter Web application: flutter run -v -d chrome --target=test_driver/scroll_perf_web.dart -/// 4. Run test script: flutter drive --target=test_driver/scroll_perf_web.dart -v --use-existing-app=/application address/ +/// 1. Launch WebDriver binary: ./chromedriver --port=4444 +/// 2. Run test script: flutter drive --target=test_driver/scroll_perf_web.dart -d web-server --release class WebFlutterDriver extends FlutterDriver { /// Creates a driver that uses a connection provided by the given /// [_connection]. @@ -47,7 +45,7 @@ class WebFlutterDriver extends FlutterDriver { /// [hostUrl] which would fallback to environment variable VM_SERVICE_URL. /// Driver also depends on environment variables DRIVER_SESSION_ID, /// BROWSER_SUPPORTS_TIMELINE, DRIVER_SESSION_URI, DRIVER_SESSION_SPEC - /// and DRIVER_SESSION_CAPABILITIES for configurations. + /// and ANDROID_CHROME_ON_EMULATOR for configurations. static Future connectWeb( {String hostUrl, Duration timeout}) async { hostUrl ??= Platform.environment['VM_SERVICE_URL']; @@ -56,7 +54,7 @@ class WebFlutterDriver extends FlutterDriver { 'session-id': Platform.environment['DRIVER_SESSION_ID'], 'session-uri': Platform.environment['DRIVER_SESSION_URI'], 'session-spec': Platform.environment['DRIVER_SESSION_SPEC'], - 'session-capabilities': Platform.environment['DRIVER_SESSION_CAPABILITIES'], + 'android-chrome-on-emulator': Platform.environment['ANDROID_CHROME_ON_EMULATOR'] == 'true', }; final FlutterWebConnection connection = await FlutterWebConnection.connect (hostUrl, settings, timeout: timeout); @@ -183,7 +181,7 @@ class FlutterWebConnection { _supportsTimelineAction = value; } - /// Starts WebDriver with the given [capabilities] and + /// Starts WebDriver with the given [settings] and /// establishes the connection to Flutter Web application. static Future connect( String url, @@ -195,6 +193,13 @@ class FlutterWebConnection { settings['session-id'].toString(), uri: Uri.parse(settings['session-uri'].toString()), spec: _convertToSpec(settings['session-spec'].toString().toLowerCase())); + if (settings['android-chrome-on-emulator'] == true) { + final Uri localUri = Uri.parse(url); + // Converts to Android Emulator Uri. + // Hardcode the host to 10.0.2.2 based on + // https://developer.android.com/studio/run/emulator-networking + url = Uri(scheme: localUri.scheme, host: '10.0.2.2', port:localUri.port).toString(); + } await driver.get(url); await waitUntilExtensionInstalled(driver, timeout); diff --git a/packages/flutter_tools/lib/src/commands/drive.dart b/packages/flutter_tools/lib/src/commands/drive.dart index 84c14c9bd90..afbb4fe744c 100644 --- a/packages/flutter_tools/lib/src/commands/drive.dart +++ b/packages/flutter_tools/lib/src/commands/drive.dart @@ -14,7 +14,6 @@ import '../base/file_system.dart'; import '../base/process.dart'; import '../build_info.dart'; import '../cache.dart'; -import '../convert.dart'; import '../dart/package_map.dart'; import '../dart/sdk.dart'; import '../device.dart'; @@ -92,6 +91,7 @@ class DriveCommand extends RunCommandBase { 'Following browsers are supported: \n' 'Chrome, Firefox, Safari (macOS and iOS) and Edge. Defaults to Chrome.', allowed: [ + 'android-chrome', 'chrome', 'edge', 'firefox', @@ -104,7 +104,11 @@ class DriveCommand extends RunCommandBase { help: 'The dimension of browser when running Flutter Web test. \n' 'This will affect screenshot and all offset-related actions. \n' 'By default. it is set to 1600,1024 (1600 by 1024).', - ); + ) + ..addFlag('android-emulator', + defaultsTo: true, + help: 'Whether to perform Flutter Driver testing on Android Emulator.' + 'Works only if \'browser-name\' is set to \'android-chrome\''); } @override @@ -187,7 +191,15 @@ class DriveCommand extends RunCommandBase { target: targetFile, flutterProject: flutterProject, ipv6: ipv6, - debuggingOptions: DebuggingOptions.enabled(buildInfo), + debuggingOptions: getBuildInfo().isRelease ? + DebuggingOptions.disabled( + getBuildInfo(), + port: stringArg('web-port') + ) + : DebuggingOptions.enabled( + getBuildInfo(), + port: stringArg('web-port') + ), stayResident: false, urlTunneller: null, ); @@ -243,25 +255,27 @@ class DriveCommand extends RunCommandBase { ); } + final bool isAndroidChrome = browser == Browser.androidChrome; + final bool useEmulator = argResults['android-emulator'] as bool; // set window size - final List dimensions = argResults['browser-dimension'].split(',') as List; - assert(dimensions.length == 2); - int x, y; - try { - x = int.parse(dimensions[0]); - y = int.parse(dimensions[1]); - } on FormatException catch (ex) { - throwToolExit(''' + // for android chrome, skip such action + if (!isAndroidChrome) { + final List dimensions = argResults['browser-dimension'].split( + ',') as List; + assert(dimensions.length == 2); + int x, y; + try { + x = int.parse(dimensions[0]); + y = int.parse(dimensions[1]); + } on FormatException catch (ex) { + throwToolExit(''' Dimension provided to --browser-dimension is invalid: $ex '''); - } - final async_io.Window window = await driver.window; - try { + } + final async_io.Window window = await driver.window; await window.setLocation(const math.Point(0, 0)); await window.setSize(math.Rectangle(0, 0, x, y)); - } on Exception { - // Error might be thrown in some browsers. } // add driver info to environment variables @@ -269,9 +283,9 @@ $ex 'DRIVER_SESSION_ID': driver.id, 'DRIVER_SESSION_URI': driver.uri.toString(), 'DRIVER_SESSION_SPEC': driver.spec.toString(), - 'DRIVER_SESSION_CAPABILITIES': jsonEncode(driver.capabilities), 'SUPPORT_TIMELINE_ACTION': (browser == Browser.chrome).toString(), 'FLUTTER_WEB_TEST': 'true', + 'ANDROID_CHROME_ON_EMULATOR': (isAndroidChrome && useEmulator).toString(), }); } @@ -489,6 +503,8 @@ Future _stopApp(DriveCommand command) async { /// A list of supported browsers @visibleForTesting enum Browser { + /// Chrome on Android: https://developer.chrome.com/multidevice/android/overview + androidChrome, /// Chrome: https://www.google.com/chrome/ chrome, /// Edge: https://www.microsoft.com/en-us/windows/microsoft-edge @@ -504,6 +520,7 @@ enum Browser { /// Converts [browserName] string to [Browser] Browser _browserNameToEnum(String browserName){ switch (browserName) { + case 'android-chrome': return Browser.androidChrome; case 'chrome': return Browser.chrome; case 'edge': return Browser.edge; case 'firefox': return Browser.firefox; @@ -592,6 +609,15 @@ Map getDesiredCapabilities(Browser browser, bool headless) { 'browserName': 'safari', 'safari:useSimulator': true }; + case Browser.androidChrome: + return { + 'browserName': 'chrome', + 'platformName': 'android', + 'goog:chromeOptions': { + 'androidPackage': 'com.android.chrome', + 'args': ['--disable-fullscreen'] + }, + }; default: throw UnsupportedError('Browser $browser not supported.'); } diff --git a/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart index d48130f3353..2e04041488f 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart @@ -713,6 +713,19 @@ void main() { expect(getDesiredCapabilities(Browser.iosSafari, false), expected); }); + + test('android chrome', () { + final Map expected = { + 'browserName': 'chrome', + 'platformName': 'android', + 'goog:chromeOptions': { + 'androidPackage': 'com.android.chrome', + 'args': ['--disable-fullscreen'] + }, + }; + + expect(getDesiredCapabilities(Browser.androidChrome, false), expected); + }); }); }