blob: 1cbbed65f2d2206bc09e5acc537e04ec54ff9502 [file] [log] [blame]
// 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 {
Browser launchBrowserInstance(Uri url, {bool debug = false}) {
return SafariMacOs(url);
Runtime get packageTestRuntime => Runtime.safari;
Future<void> prepare() async {
// Nothing extra to prepare for desktop Safari.
// We do not yet support screenshots on desktop Safari.
ScreenshotManager? getScreenshotManager() => null;
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 {
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:
// 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/ 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(
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('''
location = ${json.encode(url.toString())};
final Process process = await Process.start(
return process;
SafariMacOs._(Future<Process> Function() startBrowser) : super(startBrowser);