mirror of
https://github.com/encounter/engine.git
synced 2026-07-10 03:18:43 -07:00
[web] Run engine tests on Safari locally by launching safari installed on MacOS (#14555)
* Launch safari browser * Adding safari tests to supported browsers * changing the directrory for redirect file. This works without opening a permision pop-up. Note: there is no headless mode in safari * addressing reviewer comments
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
# For more information on test and runner configurations:
|
||||
#
|
||||
# * https://github.com/dart-lang/test/blob/master/pkgs/test/doc/configuration.md#platforms
|
||||
|
||||
platforms:
|
||||
- safari
|
||||
- vm
|
||||
@@ -48,6 +48,7 @@ abstract class PlatformBinding {
|
||||
String getChromeExecutablePath(io.Directory versionDir);
|
||||
String getFirefoxExecutablePath(io.Directory versionDir);
|
||||
String getFirefoxLatestVersionUrl();
|
||||
String getSafariSystemExecutablePath();
|
||||
}
|
||||
|
||||
const String _kBaseDownloadUrl =
|
||||
@@ -79,6 +80,10 @@ class _LinuxBinding implements PlatformBinding {
|
||||
@override
|
||||
String getFirefoxLatestVersionUrl() =>
|
||||
'https://download.mozilla.org/?product=firefox-latest&os=linux64&lang=en-US';
|
||||
|
||||
@override
|
||||
String getSafariSystemExecutablePath() =>
|
||||
throw UnsupportedError('Safari is not supported on Linux');
|
||||
}
|
||||
|
||||
class _MacBinding implements PlatformBinding {
|
||||
@@ -112,6 +117,10 @@ class _MacBinding implements PlatformBinding {
|
||||
@override
|
||||
String getFirefoxLatestVersionUrl() =>
|
||||
'https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US';
|
||||
|
||||
@override
|
||||
String getSafariSystemExecutablePath() =>
|
||||
'/Applications/Safari.app/Contents/MacOS/Safari';
|
||||
}
|
||||
|
||||
class BrowserInstallation {
|
||||
|
||||
@@ -15,7 +15,7 @@ import 'environment.dart';
|
||||
class FirefoxArgParser extends BrowserArgParser {
|
||||
static final FirefoxArgParser _singletonInstance = FirefoxArgParser._();
|
||||
|
||||
/// The [ChromeArgParser] singleton.
|
||||
/// The [FirefoxArgParser] singleton.
|
||||
static FirefoxArgParser get instance => _singletonInstance;
|
||||
|
||||
String _version;
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
// Copyright 2013 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 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'environment.dart';
|
||||
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:pedantic/pedantic.dart';
|
||||
|
||||
import 'package:test_core/src/util/io.dart'; // ignore: implementation_imports
|
||||
|
||||
import 'browser.dart';
|
||||
import 'safari_installation.dart';
|
||||
import 'common.dart';
|
||||
|
||||
/// A class for running an instance of Safari.
|
||||
///
|
||||
/// Most of the communication with the browser is expected to happen via HTTP,
|
||||
/// so this exposes a bare-bones API. The browser starts as soon as the class is
|
||||
/// constructed, and is killed when [close] is called.
|
||||
///
|
||||
/// Any errors starting or running the process are reported through [onExit].
|
||||
class Safari extends Browser {
|
||||
@override
|
||||
final name = 'Safari';
|
||||
|
||||
static String version;
|
||||
|
||||
/// Starts a new instance of Safari open to the given [url], which may be a
|
||||
/// [Uri] or a [String].
|
||||
factory Safari(Uri url, {bool debug = false}) {
|
||||
version = SafariArgParser.instance.version;
|
||||
|
||||
assert(version != null);
|
||||
return Safari._(() async {
|
||||
// TODO(nurhan): Configure info log for LUCI.
|
||||
final BrowserInstallation installation = await getOrInstallSafari(
|
||||
version,
|
||||
infoLog: DevNull(),
|
||||
);
|
||||
|
||||
// Safari will only open files (not general URLs) via the command-line
|
||||
// API, so we create a dummy file to redirect it to the page we actually
|
||||
// want it to load.
|
||||
final Directory redirectDir = Directory(
|
||||
path.join(environment.webUiDartToolDir.path),
|
||||
);
|
||||
final redirect = path.join(redirectDir.path, 'redirect.html');
|
||||
File(redirect).writeAsStringSync(
|
||||
'<script>location = ' + jsonEncode(url.toString()) + '</script>');
|
||||
|
||||
var process =
|
||||
await Process.start(installation.executable, [redirect] /* args */);
|
||||
|
||||
unawaited(process.exitCode
|
||||
.then((_) => File(redirect).deleteSync(recursive: true)));
|
||||
|
||||
return process;
|
||||
});
|
||||
}
|
||||
|
||||
Safari._(Future<Process> startBrowser()) : super(startBrowser);
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
// Copyright 2013 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 'dart:io' as io;
|
||||
|
||||
import 'package:args/args.dart';
|
||||
|
||||
import 'common.dart';
|
||||
|
||||
class SafariArgParser extends BrowserArgParser {
|
||||
static final SafariArgParser _singletonInstance = SafariArgParser._();
|
||||
|
||||
/// The [SafariArgParser] singleton.
|
||||
static SafariArgParser get instance => _singletonInstance;
|
||||
|
||||
String _version;
|
||||
|
||||
SafariArgParser._();
|
||||
|
||||
@override
|
||||
void populateOptions(ArgParser argParser) {
|
||||
argParser
|
||||
..addOption(
|
||||
'safari-version',
|
||||
defaultsTo: 'system',
|
||||
help: 'The Safari version to use while running tests. The Safari '
|
||||
'browser installed on the system is used as the only option now.'
|
||||
'Soon we will add support for using different versions using the '
|
||||
'tech previews.',
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void parseOptions(ArgResults argResults) {
|
||||
_version = argResults['safari-version'];
|
||||
assert(_version == 'system');
|
||||
}
|
||||
|
||||
@override
|
||||
String get version => _version;
|
||||
}
|
||||
|
||||
/// Returns the installation of Safari.
|
||||
///
|
||||
/// Currently uses the Safari version installed on the operating system.
|
||||
///
|
||||
/// Latest Safari version for Catalina, Mojave, High Siera is 13.
|
||||
///
|
||||
/// Latest Safari version for Sierra is 12.
|
||||
// TODO(nurhan): user latest version to download and install the latest
|
||||
// technology preview.
|
||||
Future<BrowserInstallation> getOrInstallSafari(
|
||||
String requestedVersion, {
|
||||
StringSink infoLog,
|
||||
}) async {
|
||||
|
||||
// These tests are aimed to run only on MacOs machines local or on LUCI.
|
||||
if (!io.Platform.isMacOS) {
|
||||
throw UnimplementedError('Safari on ${io.Platform.operatingSystem} is'
|
||||
' not supported. Safari is only supported on MacOS.');
|
||||
}
|
||||
|
||||
infoLog ??= io.stdout;
|
||||
|
||||
if (requestedVersion == 'system') {
|
||||
// Since Safari is included in MacOS, always assume there will be one on the
|
||||
// system.
|
||||
infoLog.writeln('Using the system version that is already installed.');
|
||||
return BrowserInstallation(
|
||||
version: 'system',
|
||||
executable: PlatformBinding.instance.getSafariSystemExecutablePath(),
|
||||
);
|
||||
} else {
|
||||
infoLog.writeln('Unsupported version $requestedVersion.');
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,9 @@ import 'chrome_installer.dart';
|
||||
import 'common.dart';
|
||||
import 'environment.dart';
|
||||
import 'firefox.dart';
|
||||
import 'firefox_installer.dart'; // ignore: implementation_imports
|
||||
import 'firefox_installer.dart';
|
||||
import 'safari.dart';
|
||||
import 'safari_installation.dart';
|
||||
|
||||
/// Utilities for browsers, that tests are supported.
|
||||
///
|
||||
@@ -22,18 +24,20 @@ import 'firefox_installer.dart'; // ignore: implementation_imports
|
||||
/// One should also implement [BrowserArgParser] and add it to the [argParsers].
|
||||
class SupportedBrowsers {
|
||||
final List<BrowserArgParser> argParsers =
|
||||
List.of([ChromeArgParser.instance, FirefoxArgParser.instance]);
|
||||
List.of([ChromeArgParser.instance, FirefoxArgParser.instance, SafariArgParser.instance]);
|
||||
|
||||
final List<String> supportedBrowserNames = ['chrome', 'firefox'];
|
||||
final List<String> supportedBrowserNames = ['chrome', 'firefox', 'safari'];
|
||||
|
||||
final Map<String, Runtime> supportedBrowsersToRuntimes = {
|
||||
'chrome': Runtime.chrome,
|
||||
'firefox': Runtime.firefox
|
||||
'firefox': Runtime.firefox,
|
||||
'safari': Runtime.safari,
|
||||
};
|
||||
|
||||
final Map<String, String> browserToConfiguration = {
|
||||
'chrome': '--configuration=${environment.webUiRootDir.path}/dart_test_chrome.yaml',
|
||||
'firefox': '--configuration=${environment.webUiRootDir.path}/dart_test_firefox.yaml',
|
||||
'safari': '--configuration=${environment.webUiRootDir.path}/dart_test_safari.yaml',
|
||||
};
|
||||
|
||||
static final SupportedBrowsers _singletonInstance = SupportedBrowsers._();
|
||||
@@ -48,6 +52,8 @@ class SupportedBrowsers {
|
||||
return Chrome(url, debug: debug);
|
||||
} else if (runtime == Runtime.firefox) {
|
||||
return Firefox(url, debug: debug);
|
||||
} else if (runtime == Runtime.safari) {
|
||||
return Safari(url, debug: debug);
|
||||
} else {
|
||||
throw new UnsupportedError('The browser type not supported in tests');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user