Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lib/web_ui/dart_test_safari.yaml
Original file line number Diff line number Diff line change
@@ -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
9 changes: 9 additions & 0 deletions lib/web_ui/dev/common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ abstract class PlatformBinding {
String getChromeExecutablePath(io.Directory versionDir);
String getFirefoxExecutablePath(io.Directory versionDir);
String getFirefoxLatestVersionUrl();
String getSafariSystemExecutablePath();
}

const String _kBaseDownloadUrl =
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/dev/firefox_installer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
67 changes: 67 additions & 0 deletions lib/web_ui/dev/safari.dart
Original file line number Diff line number Diff line change
@@ -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);
}
79 changes: 79 additions & 0 deletions lib/web_ui/dev/safari_installation.dart
Original file line number Diff line number Diff line change
@@ -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();
}
}
14 changes: 10 additions & 4 deletions lib/web_ui/dev/supported_browsers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand All @@ -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._();
Expand All @@ -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');
}
Expand Down