mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[web] use a different method for launching desktop safari (flutter/engine#27567)
This commit is contained in:
parent
b6dbaa079a
commit
e2e4ee5df9
@ -1,63 +0,0 @@
|
||||
// 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:convert';
|
||||
|
||||
import 'utils.dart';
|
||||
|
||||
class MacOSInfo {
|
||||
/// Print information collected from the operating system.
|
||||
///
|
||||
/// Built in tools such as `system_profiler` and `defaults` are utilized.
|
||||
Future<void> printInformation() async {
|
||||
await _printSafariApplications();
|
||||
await _printSafariDefaults();
|
||||
await _printUserLimits();
|
||||
}
|
||||
|
||||
/// Print information on applications in the system that contains string
|
||||
/// `Safari`.
|
||||
Future<void> _printSafariApplications() async {
|
||||
final ProcessManager systemProfiler = await startProcess(
|
||||
'system_profiler',
|
||||
<String>['SPApplicationsDataType', '-json'],
|
||||
evalOutput: true,
|
||||
);
|
||||
final String systemProfileJson = await systemProfiler.evalStdout();
|
||||
|
||||
final Map<String, dynamic> json =
|
||||
jsonDecode(systemProfileJson) as Map<String, dynamic>;
|
||||
final List<dynamic> systemProfile = json.values.first as List<dynamic>;
|
||||
for (int i = 0; i < systemProfile.length; i++) {
|
||||
final Map<String, dynamic> application =
|
||||
systemProfile[i] as Map<String, dynamic>;
|
||||
final String applicationName = application['_name'] as String;
|
||||
if (applicationName.contains('Safari')) {
|
||||
print('application: $applicationName '
|
||||
'fullInfo: ${application.toString()}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Print all the defaults in the system related to Safari.
|
||||
Future<void> _printSafariDefaults() async {
|
||||
final ProcessManager defaults = await startProcess(
|
||||
'/usr/bin/defaults',
|
||||
<String>['find', 'Safari'],
|
||||
evalOutput: true,
|
||||
);
|
||||
print('Safari related defaults:\n ${await defaults.evalStdout()}');
|
||||
}
|
||||
|
||||
/// Print user limits (file and process).
|
||||
Future<void> _printUserLimits() async {
|
||||
ProcessManager ulimit = await startProcess('ulimit', <String>['-n'], evalOutput: true);
|
||||
final String fileLimit = await ulimit.evalStdout();
|
||||
print('MacOS file limit: $fileLimit');
|
||||
|
||||
ulimit = await startProcess('ulimit', <String>['-u'], evalOutput: true);
|
||||
final String processLimit = await ulimit.evalStdout();
|
||||
print('MacOS process limit: $processLimit');
|
||||
}
|
||||
}
|
||||
@ -3,13 +3,14 @@
|
||||
// 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 'common.dart';
|
||||
import 'safari_installation.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
/// Provides an environment for the desktop variant of Safari running on macOS.
|
||||
class SafariMacOsEnvironment implements BrowserEnvironment {
|
||||
@ -45,34 +46,44 @@ class SafariMacOs extends Browser {
|
||||
@override
|
||||
final String name = 'Safari macOS';
|
||||
|
||||
/// Starts a new instance of Safari open to the given [url], which may be a
|
||||
/// [Uri].
|
||||
/// Starts a new instance of Safari open to the given [url].
|
||||
factory SafariMacOs(Uri url) {
|
||||
final String version = SafariArgParser.instance.version;
|
||||
return SafariMacOs._(() async {
|
||||
// TODO(nurhan): Configure info log for LUCI.
|
||||
final BrowserInstallation installation = await getOrInstallSafari(
|
||||
version,
|
||||
infoLog: DevNull(),
|
||||
);
|
||||
// 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-');
|
||||
|
||||
// In the macOS Catalina opening Safari browser with a file brings
|
||||
// a popup which halts the test.
|
||||
// The following list of arguments needs to be provided to the `open`
|
||||
// command to open Safari for a given URL. In summary, `open` tool opens
|
||||
// a new Safari browser (even if one is already open), opens it with no
|
||||
// persistent state and wait until it opens.
|
||||
// The details copied from `man open` on macOS.
|
||||
// TODO(nurhan): https://github.com/flutter/flutter/issues/50809
|
||||
final Process process = await Process.start(installation.executable, <String>[
|
||||
// These are flags for `open` command line tool.
|
||||
'-F', // Open a fresh Safari with no persistent state.
|
||||
'-W', // Wait until the Safari opens.
|
||||
'-n', // Open a new instance of the Safari even another one is open.
|
||||
'-b', // Specifies the bundle identifier for the application to use.
|
||||
'com.apple.Safari', // Bundle identifier for Safari.
|
||||
'${url.toString()}'
|
||||
]);
|
||||
// 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;
|
||||
});
|
||||
|
||||
@ -39,7 +39,6 @@ import 'environment.dart';
|
||||
import 'exceptions.dart';
|
||||
import 'firefox.dart';
|
||||
import 'firefox_installer.dart';
|
||||
import 'macos_info.dart';
|
||||
import 'safari_installation.dart';
|
||||
import 'safari_ios.dart';
|
||||
import 'safari_macos.dart';
|
||||
@ -180,14 +179,8 @@ class TestCommand extends Command<bool> with ArgUtils<bool> {
|
||||
}
|
||||
GeneralTestsArgumentParser.instance.parseOptions(argResults!);
|
||||
|
||||
/// Collect information on the bot.
|
||||
if (isSafariOnMacOS && isLuci) {
|
||||
final MacOSInfo macOsInfo = new MacOSInfo();
|
||||
await macOsInfo.printInformation();
|
||||
}
|
||||
|
||||
final Pipeline testPipeline = Pipeline(steps: <PipelineStep>[
|
||||
ClearTerminalScreenStep(),
|
||||
if (isWatchMode) ClearTerminalScreenStep(),
|
||||
TestRunnerStep(this),
|
||||
]);
|
||||
await testPipeline.run();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user