| // 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' show json; |
| import 'dart:io'; |
| |
| import 'package:path/path.dart' as pathlib; |
| import 'package:test_api/src/backend/runtime.dart'; |
| |
| import 'browser.dart'; |
| import 'utils.dart'; |
| |
| /// Provides an environment for the desktop variant of Safari running on macOS. |
| class SafariMacOsEnvironment implements BrowserEnvironment { |
| @override |
| Browser launchBrowserInstance(Uri url, {bool debug = false}) { |
| return SafariMacOs(url); |
| } |
| |
| @override |
| Runtime get packageTestRuntime => Runtime.safari; |
| |
| @override |
| Future<void> prepare() async { |
| // Nothing extra to prepare for desktop Safari. |
| } |
| |
| // We do not yet support screenshots on desktop Safari. |
| @override |
| ScreenshotManager? getScreenshotManager() => null; |
| |
| @override |
| String get packageTestConfigurationYamlFile => 'dart_test_safari.yaml'; |
| } |
| |
| /// Runs an instance of Safari for macOS (i.e. desktop 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 SafariMacOs extends Browser { |
| @override |
| final String name = 'Safari macOS'; |
| |
| /// Starts a new instance of Safari open to the given [url]. |
| factory SafariMacOs(Uri url) { |
| return SafariMacOs._(() async { |
| // This hack to programmatically launch a test in Safari is borrowed from |
| // Karma: https://github.com/karma-runner/karma-safari-launcher/issues/29 |
| // |
| // The issue is that opening an HTML file directly causes Safari to pop up |
| // a UI prompt to confirm the opening of a file. However, files under |
| // Library/Containers/com.apple.Safari/Data are exempt from this pop up. |
| // We create a "trampoline" file in this directory. The trampoline |
| // redirects the browser to the test URL in a <script>. |
| final String homePath = Platform.environment['HOME']!; |
| final Directory safariDataDirectory = Directory(pathlib.join( |
| homePath, |
| 'Library/Containers/com.apple.Safari/Data', |
| )); |
| final Directory trampolineDirectory = await safariDataDirectory.createTemp('web-engine-test-trampoline-'); |
| |
| // Clean up trampoline files/directories before exiting felt. |
| cleanupCallbacks.add(() async { |
| if (trampolineDirectory.existsSync()) { |
| trampolineDirectory.delete(recursive: true); |
| } |
| }); |
| |
| final File trampoline = File( |
| pathlib.join(trampolineDirectory.path, 'trampoline.html'), |
| ); |
| await trampoline.writeAsString(''' |
| <script> |
| location = ${json.encode(url.toString())}; |
| </script> |
| '''); |
| |
| final Process process = await Process.start( |
| '/Applications/Safari.app/Contents/MacOS/Safari', |
| <String>[trampoline.path], |
| ); |
| |
| return process; |
| }); |
| } |
| |
| SafariMacOs._(Future<Process> Function() startBrowser) : super(startBrowser); |
| } |