mirror of
https://github.com/dart-lang/sdk
synced 2024-10-07 09:11:55 +00:00
Revert "Revert "Make Safari tests more robust.""
This reverts commit b9cdd0e1b2
.
This change should now work, because the buildbot recipes use the
renamed flag --reset-browser-configuration.
BUG=
R=ahe@google.com
Review URL: https://codereview.chromium.org/2070513002 .
This commit is contained in:
parent
b9cdd0e1b2
commit
f76236db74
|
@ -3296,7 +3296,6 @@ LayoutTests/fast/animation/request-animation-frame-within-callback_t01: Skip # T
|
|||
LayoutTests/fast/backgrounds/background-repeat-computed-style_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/backgrounds/repeat/parsing-background-repeat_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/borders/border-image-width-numbers-computed-style_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/borders/border-radius-child_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/canvas/2d.fillText.gradient_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.gradient_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.negative_t01: RuntimeError # Please triage this failure
|
||||
|
@ -3420,7 +3419,6 @@ LayoutTests/fast/css/aspect-ratio-parsing-tests_t01: RuntimeError # Please triag
|
|||
LayoutTests/fast/css/background-serialize_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/css/border-image-style-length_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/css/computed-offset-with-zoom_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/css/content/content-none_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/css/content/content-normal_t01: RuntimeError # Please triage this failure
|
||||
|
@ -3548,7 +3546,6 @@ LayoutTests/fast/dom/HTMLDialogElement/synthetic-click-inert_t01: RuntimeError #
|
|||
LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-relative_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-static_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/HTMLDocument/active-element-gets-unforcusable_t01: Skip # Times out. Please triage this failure
|
||||
LayoutTests/fast/dom/HTMLDocument/set-focus-on-valid-element_t01: RuntimeError, Timeout # Please triage this failure
|
||||
LayoutTests/fast/dom/HTMLElement/insertAdjacentHTML-errors_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/HTMLElement/set-inner-outer-optimization_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/HTMLElement/spellcheck_t01: RuntimeError # Please triage this failure
|
||||
|
@ -3910,7 +3907,6 @@ LayoutTests/fast/multicol/hit-test-above-or-below_t01: RuntimeError # Please tri
|
|||
LayoutTests/fast/multicol/hit-test-end-of-column-with-line-height_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/multicol/hit-test-end-of-column_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/multicol/hit-test-float_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/multicol/hit-test-gap-between-pages-flipped_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/multicol/newmulticol/balance-images_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/multicol/orphans-relayout_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: RuntimeError # Please triage this failure
|
||||
|
@ -3957,7 +3953,6 @@ LayoutTests/fast/storage/storage-disallowed-in-data-url_t01: RuntimeError # Plea
|
|||
LayoutTests/fast/sub-pixel/cssom-subpixel-precision_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/sub-pixel/shadows-computed-style_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/svg/tabindex-focus_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/svg/whitespace-angle_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/svg/whitespace-integer_t01: RuntimeError # Please triage this failure
|
||||
|
@ -4427,8 +4422,43 @@ WebPlatformTest/webstorage/event_local_key_t01: RuntimeError # Please triage thi
|
|||
WebPlatformTest/webstorage/event_session_key_t01: RuntimeError # Please triage this failure
|
||||
WebPlatformTest/webstorage/event_session_storagearea_t01: Pass, RuntimeError # Fails on 7.1. Please triage this failure
|
||||
WebPlatformTest/webstorage/event_session_url_t01: Skip # Times out. Please triage this failure
|
||||
WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Makes the following test time out.
|
||||
WebPlatformTest/webstorage/storage_session_setitem_quotaexceedederr_t01: Skip # Times out. Please triage this failure
|
||||
|
||||
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: Skip
|
||||
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: Skip
|
||||
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: Skip
|
||||
LayoutTests/fast/dom/HTMLDocument/set-focus-on-valid-element_t01: Skip
|
||||
|
||||
LayoutTests/fast/canvas/webgl/context-lost_t01: Skip
|
||||
|
||||
LayoutTests/fast/canvas/canvas-strokePath-gradient-shadow_t01: RuntimeError # Fails 10 out of 10.
|
||||
LayoutTests/fast/canvas/canvas-strokeRect-gradient-shadow_t01: RuntimeError # Fails 10 out of 10.
|
||||
LayoutTests/fast/css/css-selector-text_t01: RuntimeError # Fails 10 out of 10.
|
||||
LayoutTests/fast/css/ex-unit-with-no-x-height_t01: RuntimeError # Fails 10 out of 10.
|
||||
LayoutTests/fast/css/font-property-priority_t01: RuntimeError # Fails 10 out of 10.
|
||||
LayoutTests/fast/css/inherited-properties-rare-text_t01: RuntimeError # Fails 10 out of 10.
|
||||
LayoutTests/fast/css/invalid-not-with-simple-selector-sequence_t01: RuntimeError # Fails 10 out of 10.
|
||||
LayoutTests/fast/css/parsing-font-variant-ligatures_t01: RuntimeError # Fails 10 out of 10.
|
||||
LayoutTests/fast/css/pseudo-valid-unapplied_t01: RuntimeError # Fails 10 out of 10.
|
||||
LayoutTests/fast/dom/HTMLLinkElement/resolve-url-on-insertion_t01: RuntimeError # Fails 10 out of 10.
|
||||
LayoutTests/fast/dom/css-selectorText_t01: RuntimeError # Fails 10 out of 10.
|
||||
LayoutTests/fast/forms/datalist/datalist-child-validation_t01: RuntimeError # Fails 10 out of 10.
|
||||
LayoutTests/fast/overflow/scrollbar-restored_t01: RuntimeError # Fails 10 out of 10.
|
||||
LibTest/html/Element/isContentEditable_A01_t01: RuntimeError # Fails 10 out of 10.
|
||||
LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # Fails 10 out of 10.
|
||||
LibTest/html/IFrameElement/isContentEditable_A01_t01: RuntimeError, Pass # Fails 19 out of 20.
|
||||
|
||||
LayoutTests/fast/flexbox/repaint-scrollbar_t01: Pass, RuntimeError # Fails 2 out of 10.
|
||||
LibTest/html/Element/getBoundingClientRect_A01_t02: Pass, RuntimeError # Fails 3 out of 10.
|
||||
LayoutTests/fast/css/focus-display-block-inline_t01: Pass, RuntimeError # Fails 5 out of 10.
|
||||
LayoutTests/fast/css/pseudo-any_t01: Pass, RuntimeError # Fails 4 out of 10.
|
||||
LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: Pass, RuntimeError # Fails 8 out of 10.
|
||||
LayoutTests/fast/forms/autofocus-input-css-style-change_t01: Pass, RuntimeError # Fails 7 out of 10.
|
||||
LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-onblur-setvalue-onfocusremoved_t01: Pass, RuntimeError # Fails 6 out of 10.
|
||||
|
||||
LayoutTests/fast/canvas/webgl/glsl-conformance_t01: Skip # Times out 1 out of 20.
|
||||
|
||||
[ $compiler == dart2js && $runtime == safarimobilesim ]
|
||||
LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
|
||||
|
|
|
@ -292,13 +292,15 @@ input_element_test/supported_date: Fail
|
|||
input_element_test/supported_datetime-local: Fail
|
||||
touchevent_test/supported: Fail # Safari does not support TouchEvents
|
||||
notification_test/constructors: Fail # Safari doesn't let us access the fields of the Notification to verify them.
|
||||
|
||||
[ $runtime == safari ]
|
||||
indexeddb_1_test/functional: Skip # Times out. Issue 21433
|
||||
indexeddb_2_test: RuntimeError # Issue 21433
|
||||
indexeddb_4_test: RuntimeError # Issue 21433
|
||||
indexeddb_5_test: RuntimeError # Issue 21433
|
||||
|
||||
|
||||
js_test/JsArray: RuntimeError # Fails 10 out of 10.
|
||||
indexeddb_3_test: Skip # Times out 1 out of 10.
|
||||
|
||||
[ $runtime == opera ]
|
||||
blob_constructor_test: Fail
|
||||
canvas_test: Fail
|
||||
|
|
|
@ -202,7 +202,7 @@ def TestStep(name, mode, system, compiler, runtime, targets, flags, arch):
|
|||
else:
|
||||
cmd.extend(['--progress=buildbot', '-v'])
|
||||
|
||||
cmd.append('--clear_browser_cache')
|
||||
cmd.append('--reset-browser-configuration')
|
||||
|
||||
global IsFirstTestStepCall
|
||||
if IsFirstTestStepCall:
|
||||
|
|
27
tools/safari_factory_reset.py
Executable file
27
tools/safari_factory_reset.py
Executable file
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env python
|
||||
# Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
||||
# for details. All rights reserved. Use of this source code is governed by a
|
||||
# BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import os
|
||||
import string
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import utils
|
||||
|
||||
|
||||
def Main():
|
||||
args = sys.argv[1:]
|
||||
tools_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
dart_script_name = os.path.join(
|
||||
tools_dir, 'testing', 'dart', 'reset_safari.dart');
|
||||
command = [utils.CheckedInSdkExecutable(),
|
||||
'--checked', dart_script_name] + args
|
||||
exit_code = subprocess.call(command)
|
||||
utils.DiagnoseExitCode(exit_code, command)
|
||||
return exit_code
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(Main())
|
|
@ -14,6 +14,9 @@ import 'http_server.dart';
|
|||
import 'path.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
import 'reset_safari.dart' show
|
||||
killAndResetSafari;
|
||||
|
||||
class BrowserOutput {
|
||||
final StringBuffer stdout = new StringBuffer();
|
||||
final StringBuffer stderr = new StringBuffer();
|
||||
|
@ -53,10 +56,10 @@ abstract class Browser {
|
|||
String id;
|
||||
|
||||
/**
|
||||
* Delete the browser specific caches on startup.
|
||||
* Reset the browser to a known configuration on start-up.
|
||||
* Browser specific implementations are free to ignore this.
|
||||
*/
|
||||
static bool deleteCache = false;
|
||||
static bool resetBrowserConfiguration = false;
|
||||
|
||||
/** Print everything (stdout, stderr, usageLog) whenever we add to it */
|
||||
bool debugPrint = false;
|
||||
|
@ -105,6 +108,15 @@ abstract class Browser {
|
|||
'ie10'
|
||||
];
|
||||
|
||||
/// If [browserName] doesn't support Window.open, we use iframes instead.
|
||||
static bool requiresIframe(String browserName) {
|
||||
return !BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName);
|
||||
}
|
||||
|
||||
static bool requiresFocus(String browserName) {
|
||||
return browserName == "safari";
|
||||
}
|
||||
|
||||
// TODO(kustermann): add standard support for chrome on android
|
||||
static bool supportedBrowser(String name) {
|
||||
return SUPPORTED_BROWSERS.contains(name);
|
||||
|
@ -269,6 +281,13 @@ abstract class Browser {
|
|||
|
||||
/** Starts the browser loading the given url */
|
||||
Future<bool> start(String url);
|
||||
|
||||
/// Called when the driver page is requested, that is, when the browser first
|
||||
/// contacts the test server. At this time, it's safe to assume that the
|
||||
/// browser process has started and opened its first window.
|
||||
///
|
||||
/// This is used by [Safari] to ensure the browser window has focus.
|
||||
Future<Null> onDriverPageRequested() => new Future<Null>.value();
|
||||
}
|
||||
|
||||
class Safari extends Browser {
|
||||
|
@ -278,62 +297,48 @@ class Safari extends Browser {
|
|||
static const String versionFile =
|
||||
"/Applications/Safari.app/Contents/version.plist";
|
||||
|
||||
/**
|
||||
* Directories where safari stores state. We delete these if the deleteCache
|
||||
* is set
|
||||
*/
|
||||
static const List<String> CACHE_DIRECTORIES = const [
|
||||
"Library/Caches/com.apple.Safari",
|
||||
"Library/Safari",
|
||||
"Library/Saved Application State/com.apple.Safari.savedState",
|
||||
"Library/Caches/Metadata/Safari"
|
||||
];
|
||||
static const String safariBundleLocation = "/Applications/Safari.app/";
|
||||
|
||||
Future<bool> allowPopUps() {
|
||||
var command = "defaults";
|
||||
var args = [
|
||||
"write",
|
||||
"com.apple.safari",
|
||||
"com.apple.Safari.ContentPageGroupIdentifier."
|
||||
"WebKit2JavaScriptCanOpenWindowsAutomatically",
|
||||
"1"
|
||||
];
|
||||
return Process.run(command, args).then((result) {
|
||||
if (result.exitCode != 0) {
|
||||
_logEvent("Could not disable pop-up blocking for safari");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
Future<bool> deleteIfExists(Iterator<String> paths) {
|
||||
if (!paths.moveNext()) return new Future.value(true);
|
||||
Directory directory = new Directory(paths.current);
|
||||
return directory.exists().then((exists) {
|
||||
if (exists) {
|
||||
_logEvent("Deleting ${paths.current}");
|
||||
return directory
|
||||
.delete(recursive: true)
|
||||
.then((_) => deleteIfExists(paths))
|
||||
.catchError((error) {
|
||||
_logEvent("Failure trying to delete ${paths.current}: $error");
|
||||
return false;
|
||||
});
|
||||
} else {
|
||||
_logEvent("${paths.current} is not present");
|
||||
return deleteIfExists(paths);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Clears the cache if the static deleteCache flag is set.
|
||||
// Clears the cache if the static resetBrowserConfiguration flag is set.
|
||||
// Returns false if the command to actually clear the cache did not complete.
|
||||
Future<bool> clearCache() {
|
||||
if (!Browser.deleteCache) return new Future.value(true);
|
||||
var home = Platform.environment['HOME'];
|
||||
Iterator iterator = CACHE_DIRECTORIES.map((s) => "$home/$s").iterator;
|
||||
return deleteIfExists(iterator);
|
||||
Future<bool> resetConfiguration() async {
|
||||
if (!Browser.resetBrowserConfiguration) return true;
|
||||
|
||||
Completer completer = new Completer();
|
||||
handleUncaughtError(error, StackTrace stackTrace) {
|
||||
if (!completer.isCompleted) {
|
||||
completer.completeError(error, stackTrace);
|
||||
} else {
|
||||
throw new AsyncError(error, stackTrace);
|
||||
}
|
||||
}
|
||||
Zone parent = Zone.current;
|
||||
ZoneSpecification specification = new ZoneSpecification(
|
||||
print: (Zone self, ZoneDelegate delegate, Zone zone, String line) {
|
||||
delegate.run(parent, () {
|
||||
_logEvent(line);
|
||||
});
|
||||
});
|
||||
Future zoneWrapper() {
|
||||
Uri safariUri = Uri.base.resolve(safariBundleLocation);
|
||||
return new Future(() => killAndResetSafari(bundle: safariUri))
|
||||
.then(completer.complete);
|
||||
}
|
||||
|
||||
// We run killAndResetSafari in a Zone as opposed to running an external
|
||||
// process. The Zone allows us to collect its output, and protect the rest
|
||||
// of the test infrastructure against errors in it.
|
||||
runZoned(
|
||||
zoneWrapper, zoneSpecification: specification,
|
||||
onError: handleUncaughtError);
|
||||
|
||||
try {
|
||||
await completer.future;
|
||||
return true;
|
||||
} catch (error, st) {
|
||||
_logEvent("Unable to reset Safari: $error$st");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> getVersion() {
|
||||
|
@ -369,42 +374,58 @@ class Safari extends Browser {
|
|||
});
|
||||
}
|
||||
|
||||
void _createLaunchHTML(var path, var url) {
|
||||
Future<Null> _createLaunchHTML(var path, var url) async {
|
||||
var file = new File("${path}/launch.html");
|
||||
var randomFile = file.openSync(mode: FileMode.WRITE);
|
||||
var randomFile = await file.open(mode: FileMode.WRITE);
|
||||
var content = '<script language="JavaScript">location = "$url"</script>';
|
||||
randomFile.writeStringSync(content);
|
||||
randomFile.close();
|
||||
await randomFile.writeString(content);
|
||||
await randomFile.close();
|
||||
}
|
||||
|
||||
Future<bool> start(String url) {
|
||||
Future<bool> start(String url) async {
|
||||
_logEvent("Starting Safari browser on: $url");
|
||||
return allowPopUps().then((success) {
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
return clearCache().then((cleared) {
|
||||
if (!cleared) {
|
||||
_logEvent("Could not clear cache");
|
||||
return false;
|
||||
}
|
||||
// Get the version and log that.
|
||||
return getVersion().then((version) {
|
||||
_logEvent("Got version: $version");
|
||||
return Directory.systemTemp.createTemp().then((userDir) {
|
||||
_cleanup = () {
|
||||
userDir.deleteSync(recursive: true);
|
||||
};
|
||||
_createLaunchHTML(userDir.path, url);
|
||||
var args = ["${userDir.path}/launch.html"];
|
||||
return startBrowserProcess(_binary, args);
|
||||
});
|
||||
}).catchError((error) {
|
||||
_logEvent("Running $_binary --version failed with $error");
|
||||
return false;
|
||||
});
|
||||
});
|
||||
});
|
||||
if (!await resetConfiguration()) {
|
||||
_logEvent("Could not clear cache");
|
||||
return false;
|
||||
}
|
||||
String version;
|
||||
try {
|
||||
version = await getVersion();
|
||||
} catch (error) {
|
||||
_logEvent("Running $_binary --version failed with $error");
|
||||
return false;
|
||||
}
|
||||
_logEvent("Got version: $version");
|
||||
Directory userDir;
|
||||
try {
|
||||
userDir = await Directory.systemTemp.createTemp();
|
||||
} catch (error) {
|
||||
_logEvent("Error creating temporary directory: $error");
|
||||
return false;
|
||||
}
|
||||
_cleanup = () {
|
||||
userDir.deleteSync(recursive: true);
|
||||
};
|
||||
try {
|
||||
await _createLaunchHTML(userDir.path, url);
|
||||
} catch (error) {
|
||||
_logEvent("Error creating launch HTML: $error");
|
||||
return false;
|
||||
}
|
||||
var args = [
|
||||
"-d", "-i", "-m", "-s", "-u", _binary,
|
||||
"${userDir.path}/launch.html"];
|
||||
try {
|
||||
return startBrowserProcess("/usr/bin/caffeinate", args);
|
||||
} catch (error) {
|
||||
_logEvent("Error starting browser process: $error");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Null> onDriverPageRequested() async {
|
||||
await Process.run("/usr/bin/osascript",
|
||||
['-e', 'tell application "Safari" to activate']);
|
||||
}
|
||||
|
||||
String toString() => "Safari";
|
||||
|
@ -477,16 +498,16 @@ class Chrome extends Browser {
|
|||
class SafariMobileSimulator extends Safari {
|
||||
/**
|
||||
* Directories where safari simulator stores state. We delete these if the
|
||||
* deleteCache is set
|
||||
* resetBrowserConfiguration is set
|
||||
*/
|
||||
static const List<String> CACHE_DIRECTORIES = const [
|
||||
"Library/Application Support/iPhone Simulator/7.1/Applications"
|
||||
];
|
||||
|
||||
// Clears the cache if the static deleteCache flag is set.
|
||||
// Clears the cache if the static resetBrowserConfiguration flag is set.
|
||||
// Returns false if the command to actually clear the cache did not complete.
|
||||
Future<bool> clearCache() {
|
||||
if (!Browser.deleteCache) return new Future.value(true);
|
||||
Future<bool> resetConfiguration() {
|
||||
if (!Browser.resetBrowserConfiguration) return new Future.value(true);
|
||||
var home = Platform.environment['HOME'];
|
||||
Iterator iterator = CACHE_DIRECTORIES.map((s) => "$home/$s").iterator;
|
||||
return deleteIfExists(iterator);
|
||||
|
@ -494,7 +515,7 @@ class SafariMobileSimulator extends Safari {
|
|||
|
||||
Future<bool> start(String url) {
|
||||
_logEvent("Starting safari mobile simulator browser on: $url");
|
||||
return clearCache().then((success) {
|
||||
return resetConfiguration().then((success) {
|
||||
if (!success) {
|
||||
_logEvent("Could not clear cache, exiting");
|
||||
return false;
|
||||
|
@ -561,9 +582,10 @@ class IE extends Browser {
|
|||
});
|
||||
}
|
||||
|
||||
// Clears the recovery cache if the static deleteCache flag is set.
|
||||
Future<bool> clearCache() {
|
||||
if (!Browser.deleteCache) return new Future.value(true);
|
||||
// Clears the recovery cache if the static resetBrowserConfiguration flag is
|
||||
// set.
|
||||
Future<bool> resetConfiguration() {
|
||||
if (!Browser.resetBrowserConfiguration) return new Future.value(true);
|
||||
var localAppData = Platform.environment['LOCALAPPDATA'];
|
||||
|
||||
Directory dir = new Directory("$localAppData\\Microsoft\\"
|
||||
|
@ -578,7 +600,7 @@ class IE extends Browser {
|
|||
|
||||
Future<bool> start(String url) {
|
||||
_logEvent("Starting ie browser on: $url");
|
||||
return clearCache().then((_) => getVersion()).then((version) {
|
||||
return resetConfiguration().then((_) => getVersion()).then((version) {
|
||||
_logEvent("Got version: $version");
|
||||
return startBrowserProcess(_binary, [url]);
|
||||
});
|
||||
|
@ -876,12 +898,12 @@ class BrowserTestRunner {
|
|||
static const Duration MIN_NONEMPTY_QUEUE_TIME = const Duration(seconds: 1);
|
||||
|
||||
final Map configuration;
|
||||
BrowserTestingServer testingServer;
|
||||
final BrowserTestingServer testingServer;
|
||||
|
||||
final String localIp;
|
||||
String browserName;
|
||||
int maxNumBrowsers;
|
||||
bool checkedMode;
|
||||
final String browserName;
|
||||
final int maxNumBrowsers;
|
||||
final bool checkedMode;
|
||||
int numBrowsers = 0;
|
||||
// Used to send back logs from the browser (start, stop etc)
|
||||
Function logger;
|
||||
|
@ -928,27 +950,23 @@ class BrowserTestRunner {
|
|||
if (_currentStartingBrowserId == id) _currentStartingBrowserId = null;
|
||||
}
|
||||
|
||||
// If [browserName] doesn't support opening new windows, we use new iframes
|
||||
// instead.
|
||||
bool get useIframe =>
|
||||
!Browser.BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName);
|
||||
|
||||
/// The optional testingServer parameter allows callers to pass in
|
||||
/// a testing server with different behavior than the default
|
||||
/// BrowserTestServer. The url handlers of the testingServer are
|
||||
/// overwritten, so an existing handler can't be shared between instances.
|
||||
BrowserTestRunner(
|
||||
this.configuration, this.localIp, this.browserName, this.maxNumBrowsers,
|
||||
{BrowserTestingServer this.testingServer}) {
|
||||
checkedMode = configuration['checked'];
|
||||
if (browserName == 'ff') browserName = 'firefox';
|
||||
Map configuration,
|
||||
String localIp,
|
||||
String browserName,
|
||||
this.maxNumBrowsers)
|
||||
: configuration = configuration,
|
||||
localIp = localIp,
|
||||
browserName = (browserName == 'ff') ? 'firefox' : browserName,
|
||||
checkedMode = configuration['checked'],
|
||||
testingServer = new BrowserTestingServer(
|
||||
configuration, localIp,
|
||||
Browser.requiresIframe(browserName),
|
||||
Browser.requiresFocus(browserName)) {
|
||||
testingServer.testRunner = this;
|
||||
}
|
||||
|
||||
Future start() async {
|
||||
if (testingServer == null) {
|
||||
testingServer =
|
||||
new BrowserTestingServer(configuration, localIp, useIframe);
|
||||
}
|
||||
await testingServer.start();
|
||||
testingServer
|
||||
..testDoneCallBack = handleResults
|
||||
|
@ -1285,6 +1303,9 @@ class BrowserTestingServer {
|
|||
/// test
|
||||
|
||||
final String localIp;
|
||||
final bool useIframe;
|
||||
final bool requiresFocus;
|
||||
BrowserTestRunner testRunner;
|
||||
|
||||
static const String driverPath = "/driver";
|
||||
static const String nextTestPath = "/next_test";
|
||||
|
@ -1297,14 +1318,14 @@ class BrowserTestingServer {
|
|||
var testCount = 0;
|
||||
var errorReportingServer;
|
||||
bool underTermination = false;
|
||||
bool useIframe = false;
|
||||
|
||||
Function testDoneCallBack;
|
||||
Function testStatusUpdateCallBack;
|
||||
Function testStartedCallBack;
|
||||
Function nextTestCallBack;
|
||||
|
||||
BrowserTestingServer(this.configuration, this.localIp, this.useIframe);
|
||||
BrowserTestingServer(
|
||||
this.configuration, this.localIp, this.useIframe, this.requiresFocus);
|
||||
|
||||
Future start() {
|
||||
var test_driver_error_port = configuration['test_driver_error_port'];
|
||||
|
@ -1366,29 +1387,41 @@ class BrowserTestingServer {
|
|||
handleStarted(request, browserId(request, startedPath), testId(request));
|
||||
});
|
||||
|
||||
makeSendPageHandler(String prefix) => (HttpRequest request) {
|
||||
noCache(request);
|
||||
var textResponse = "";
|
||||
if (prefix == driverPath) {
|
||||
textResponse = getDriverPage(browserId(request, prefix));
|
||||
request.response.headers.set('Content-Type', 'text/html');
|
||||
}
|
||||
if (prefix == nextTestPath) {
|
||||
textResponse = getNextTest(browserId(request, prefix));
|
||||
request.response.headers.set('Content-Type', 'text/plain');
|
||||
}
|
||||
request.response.write(textResponse);
|
||||
request.listen((_) {}, onDone: request.response.close);
|
||||
request.response.done.catchError((error) {
|
||||
if (!underTermination) {
|
||||
print("URI ${request.uri}");
|
||||
print("Textresponse $textResponse");
|
||||
throw "Error returning content to browser: $error";
|
||||
}
|
||||
void sendPageHandler(HttpRequest request) {
|
||||
// Do NOT make this method async. We need to call catchError below
|
||||
// synchronously to avoid unhandled asynchronous errors.
|
||||
noCache(request);
|
||||
Future<String> textResponse;
|
||||
if (request.uri.path.startsWith(driverPath)) {
|
||||
textResponse = getDriverPage(browserId(request, driverPath));
|
||||
request.response.headers.set('Content-Type', 'text/html');
|
||||
} else if (request.uri.path.startsWith(nextTestPath)) {
|
||||
textResponse = new Future<String>.value(
|
||||
getNextTest(browserId(request, nextTestPath)));
|
||||
request.response.headers.set('Content-Type', 'text/plain');
|
||||
} else {
|
||||
textResponse = new Future<String>.value("");
|
||||
}
|
||||
request.response.done.catchError((error) {
|
||||
if (!underTermination) {
|
||||
return textResponse.then((String text) {
|
||||
print("URI ${request.uri}");
|
||||
print("textResponse $textResponse");
|
||||
throw "Error returning content to browser: $error";
|
||||
});
|
||||
};
|
||||
server.addHandler(driverPath, makeSendPageHandler(driverPath));
|
||||
server.addHandler(nextTestPath, makeSendPageHandler(nextTestPath));
|
||||
}
|
||||
});
|
||||
textResponse.then((String text) async {
|
||||
request.response.write(text);
|
||||
await request.listen(null).asFuture();
|
||||
// Ignoring the returned closure as it returns the 'done' future
|
||||
// which alread has catchError installed above.
|
||||
request.response.close();
|
||||
});
|
||||
}
|
||||
|
||||
server.addHandler(driverPath, sendPageHandler);
|
||||
server.addHandler(nextTestPath, sendPageHandler);
|
||||
}
|
||||
|
||||
void handleReport(HttpRequest request, String browserId, var testId,
|
||||
|
@ -1447,33 +1480,34 @@ class BrowserTestingServer {
|
|||
return "http://$localIp:$port/driver/$browserId";
|
||||
}
|
||||
|
||||
String getDriverPage(String browserId) {
|
||||
Future<String> getDriverPage(String browserId) async {
|
||||
await testRunner.browserStatus[browserId].browser.onDriverPageRequested();
|
||||
var errorReportingUrl =
|
||||
"http://$localIp:${errorReportingServer.port}/$browserId";
|
||||
String driverContent = """
|
||||
<!DOCTYPE html><html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
.box {
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
.controller.box {
|
||||
height: 75px;
|
||||
top: 0;
|
||||
}
|
||||
.test.box {
|
||||
top: 75px;
|
||||
bottom: 0;
|
||||
}
|
||||
</style>
|
||||
<title>Driving page</title>
|
||||
<style>
|
||||
.big-notice {
|
||||
background-color: red;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: xx-large;
|
||||
text-align: center;
|
||||
}
|
||||
.controller.box {
|
||||
white-space: nowrap;
|
||||
overflow: scroll;
|
||||
height: 6em;
|
||||
}
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
body div {
|
||||
padding-top: 10px;
|
||||
}
|
||||
</style>
|
||||
<script type='text/javascript'>
|
||||
var STATUS_UPDATE_INTERVAL = 10000;
|
||||
|
||||
|
@ -1603,7 +1637,8 @@ class BrowserTestingServer {
|
|||
embedded_iframe_div.removeChild(embedded_iframe);
|
||||
embedded_iframe = document.createElement('iframe');
|
||||
embedded_iframe.id = "embedded_iframe";
|
||||
embedded_iframe.style="width:100%;height:100%";
|
||||
embedded_iframe.width='800px';
|
||||
embedded_iframe.height='600px';
|
||||
embedded_iframe_div.appendChild(embedded_iframe);
|
||||
embedded_iframe.src = url;
|
||||
} else {
|
||||
|
@ -1775,13 +1810,26 @@ class BrowserTestingServer {
|
|||
</script>
|
||||
</head>
|
||||
<body onload="startTesting()">
|
||||
|
||||
<div class='big-notice'>
|
||||
Please keep this window in focus at all times.
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Some browsers, Safari, in particular, may pause JavaScript when not
|
||||
visible to conserve power consumption and CPU resources. In addition,
|
||||
some tests of focus events will not work correctly if this window doesn't
|
||||
have focus. It's also advisable to close any other programs that may open
|
||||
modal dialogs, for example, Chrome with Calendar open.
|
||||
</div>
|
||||
|
||||
<div class="controller box">
|
||||
Dart test driver, number of tests: <span id="number"></span><br>
|
||||
Currently executing: <span id="currently_executing"></span><br>
|
||||
Unhandled error: <span id="unhandled_error"></span>
|
||||
</div>
|
||||
<div id="embedded_iframe_div" class="test box">
|
||||
<iframe style="width:100%;height:100%;" id="embedded_iframe"></iframe>
|
||||
<iframe id="embedded_iframe"></iframe>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
227
tools/testing/dart/reset_safari.dart
Normal file
227
tools/testing/dart/reset_safari.dart
Normal file
|
@ -0,0 +1,227 @@
|
|||
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
|
||||
/// Helper program for killing and resetting all Safari settings to a known
|
||||
/// state that works well for testing dart2js output in Safari.
|
||||
///
|
||||
/// Warning: this will delete all your Safari settings and bookmarks.
|
||||
library testing.reset_safari;
|
||||
|
||||
import 'dart:async' show
|
||||
Future,
|
||||
Timer;
|
||||
|
||||
import 'dart:io' show
|
||||
Directory,
|
||||
File,
|
||||
Platform,
|
||||
Process,
|
||||
ProcessResult;
|
||||
|
||||
const String defaultSafariBundleLocation = "/Applications/Safari.app/";
|
||||
|
||||
const String relativeSafariLocation = "Contents/MacOS/Safari";
|
||||
|
||||
const String lsofLocation = "/usr/sbin/lsof";
|
||||
|
||||
const String killLocation = "/bin/kill";
|
||||
|
||||
const String pkillLocation = "/usr/bin/pkill";
|
||||
|
||||
const String safari = "com.apple.Safari";
|
||||
|
||||
const String defaultsLocation = "/usr/bin/defaults";
|
||||
|
||||
final List<String> safariSettings = <String>[
|
||||
"Library/Caches/$safari",
|
||||
"Library/Safari",
|
||||
"Library/Saved Application State/$safari.savedState",
|
||||
"Library/Caches/Metadata/Safari",
|
||||
"Library/Preferences/$safari.plist",
|
||||
];
|
||||
|
||||
const Duration defaultPollDelay = const Duration(milliseconds: 1);
|
||||
|
||||
final String cpgi = "$safari.ContentPageGroupIdentifier";
|
||||
|
||||
final String knownSafariPreference = '''
|
||||
{
|
||||
DefaultBrowserPromptingState2 = 2;
|
||||
StartPageViewControllerMode = 0;
|
||||
TestDriveOriginBrowser = 1;
|
||||
TestDriveUserDecision = 2;
|
||||
TestDriveState = 3;
|
||||
AlwaysRestoreSessionAtLaunch = 0;
|
||||
NewTabBehavior = 1;
|
||||
NewWindowBehavior = 1;
|
||||
LastSafariVersionWithWelcomePage = "9.0";
|
||||
OpenNewTabsInFront = 0;
|
||||
TabCreationPolicy = 0;
|
||||
|
||||
IncludeDevelopMenu = 1;
|
||||
WebKitDeveloperExtrasEnabledPreferenceKey = 1;
|
||||
"$cpgi.WebKit2DeveloperExtrasEnabled" = 1;
|
||||
|
||||
AutoFillCreditCardData = 0;
|
||||
AutoFillMiscellaneousForms = 0;
|
||||
AutoFillPasswords = 0;
|
||||
|
||||
SuppressSearchSuggestions = 1;
|
||||
|
||||
PreloadTopHit = 0;
|
||||
ShowFavoritesUnderSmartSearchField = 0;
|
||||
WebsiteSpecificSearchEnabled = 0;
|
||||
|
||||
WarnAboutFraudulentWebsites = 0;
|
||||
|
||||
|
||||
WebKitJavaScriptEnabled = 1;
|
||||
"$cpgi.WebKit2JavaScriptEnabled" = 1;
|
||||
|
||||
WebKitJavaScriptCanOpenWindowsAutomatically = 1;
|
||||
"$cpgi.WebKit2JavaScriptCanOpenWindowsAutomatically" = 1;
|
||||
|
||||
"$cpgi.WebKit2WebGLEnabled" = 1;
|
||||
WebGLDefaultLoadPolicy = WebGLPolicyAllowNoSecurityRestrictions;
|
||||
|
||||
"$cpgi.WebKit2PluginsEnabled" = 0;
|
||||
|
||||
BlockStoragePolicy = 1;
|
||||
WebKitStorageBlockingPolicy = 0;
|
||||
"$cpgi.WebKit2StorageBlockingPolicy" = 0;
|
||||
|
||||
|
||||
SafariGeolocationPermissionPolicy = 0;
|
||||
|
||||
CanPromptForPushNotifications = 0;
|
||||
|
||||
InstallExtensionUpdatesAutomatically = 0;
|
||||
|
||||
ShowFullURLInSmartSearchField = 1;
|
||||
|
||||
"$cpgi.WebKit2PlugInSnapshottingEnabled" = 0;
|
||||
}
|
||||
''';
|
||||
|
||||
Future<Null> get pollDelay => new Future.delayed(defaultPollDelay);
|
||||
|
||||
String signalArgument(
|
||||
String defaultSignal,
|
||||
{bool force: false,
|
||||
bool testOnly: false}) {
|
||||
if (force && testOnly) {
|
||||
throw new ArgumentError("[force] and [testOnly] can't both be true.");
|
||||
}
|
||||
if (force) return "-KILL";
|
||||
if (testOnly) return "-0";
|
||||
return defaultSignal;
|
||||
}
|
||||
|
||||
Future<int> kill(
|
||||
List<String> pids,
|
||||
{bool force: false,
|
||||
bool testOnly: false}) async {
|
||||
List<String> arguments =
|
||||
<String>[signalArgument("-TERM", force: force, testOnly: testOnly)]
|
||||
..addAll(pids);
|
||||
ProcessResult result = await Process.run(killLocation, arguments);
|
||||
return result.exitCode;
|
||||
}
|
||||
|
||||
Future<int> pkill(
|
||||
String pattern,
|
||||
{bool force: false,
|
||||
bool testOnly: false}) async {
|
||||
List<String> arguments = <String>[
|
||||
signalArgument("-HUP", force: force, testOnly: testOnly),
|
||||
pattern];
|
||||
ProcessResult result = await Process.run(pkillLocation, arguments);
|
||||
return result.exitCode;
|
||||
}
|
||||
|
||||
Uri validatedBundleName(Uri bundle) {
|
||||
if (bundle == null) return Uri.base.resolve(defaultSafariBundleLocation);
|
||||
if (!bundle.path.endsWith("/")) {
|
||||
throw new ArgumentError(
|
||||
"Bundle ('$bundle') must end with a slash ('/').");
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
|
||||
Future<Null> killSafari({Uri bundle}) async {
|
||||
bundle = validatedBundleName(bundle);
|
||||
Uri safariBinary = bundle.resolve(relativeSafariLocation);
|
||||
ProcessResult result = await Process.run(
|
||||
lsofLocation, ["-t", safariBinary.toFilePath()]);
|
||||
if (result.exitCode == 0) {
|
||||
String stdout = result.stdout;
|
||||
List<String> pids = new List<String>.from(
|
||||
stdout.split("\n").where((String line) => !line.isEmpty));
|
||||
Timer timer = new Timer(const Duration(seconds: 10), () {
|
||||
print("Kill -9 Safari $pids");
|
||||
kill(pids, force: true);
|
||||
});
|
||||
int exitCode = await kill(pids);
|
||||
while (exitCode == 0) {
|
||||
await pollDelay;
|
||||
print("Polling Safari $pids");
|
||||
exitCode = await kill(pids, testOnly: true);
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
Timer timer = new Timer(const Duration(seconds: 10), () {
|
||||
print("Kill -9 $safari");
|
||||
pkill(safari, force: true);
|
||||
});
|
||||
int exitCode = await pkill(safari);
|
||||
while (exitCode == 0) {
|
||||
await pollDelay;
|
||||
print("Polling $safari");
|
||||
exitCode = await pkill(safari, testOnly: true);
|
||||
}
|
||||
timer.cancel();
|
||||
}
|
||||
|
||||
Future<Null> deleteIfExists(Uri uri) async {
|
||||
Directory directory = new Directory.fromUri(uri);
|
||||
if (await directory.exists()) {
|
||||
print("Deleting directory '$uri'.");
|
||||
await directory.delete(recursive: true);
|
||||
} else {
|
||||
File file = new File.fromUri(uri);
|
||||
if (await file.exists()) {
|
||||
print("Deleting file '$uri'.");
|
||||
await file.delete();
|
||||
} else {
|
||||
print("File '$uri' not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<Null> resetSafariSettings() async {
|
||||
String home = Platform.environment["HOME"];
|
||||
if (!home.endsWith("/")) {
|
||||
home = "$home/";
|
||||
}
|
||||
Uri homeDirectory = Uri.base.resolve(home);
|
||||
for (String setting in safariSettings) {
|
||||
await deleteIfExists(homeDirectory.resolve(setting));
|
||||
}
|
||||
ProcessResult result = await Process.run(
|
||||
defaultsLocation, <String>["write", safari, knownSafariPreference]);
|
||||
if (result.exitCode != 0) {
|
||||
throw "Unable to reset Safari settings: ${result.stdout}${result.stderr}";
|
||||
}
|
||||
}
|
||||
|
||||
Future<Null> killAndResetSafari({Uri bundle}) async {
|
||||
bundle = validatedBundleName(bundle);
|
||||
await killSafari(bundle: bundle);
|
||||
await resetSafariSettings();
|
||||
}
|
||||
|
||||
Future<Null> main() async {
|
||||
await killAndResetSafari();
|
||||
}
|
|
@ -69,7 +69,7 @@ Future testConfigurations(List<Map> configurations) async {
|
|||
var recordingPath = firstConf['record_to_file'];
|
||||
var recordingOutputPath = firstConf['replay_from_file'];
|
||||
|
||||
Browser.deleteCache = firstConf['clear_browser_cache'];
|
||||
Browser.resetBrowserConfiguration = firstConf['reset_browser_configuration'];
|
||||
|
||||
if (recordingPath != null && recordingOutputPath != null) {
|
||||
print("Fatal: Can't have the '--record_to_file' and '--replay_from_file'"
|
||||
|
|
|
@ -338,9 +338,11 @@ Note: currently only implemented for dart2js.''',
|
|||
false,
|
||||
type: 'bool'),
|
||||
new _TestOptionSpecification(
|
||||
'clear_browser_cache',
|
||||
'Browser specific clearing of caches(i.e., delete it).',
|
||||
['--clear_browser_cache'],
|
||||
'reset_browser_configuration',
|
||||
'Browser specific reset of configuration. '
|
||||
'WARNING: Using this option may remove your bookmarks and '
|
||||
'other settings.',
|
||||
['--reset-browser-configuration'],
|
||||
[],
|
||||
false,
|
||||
type: 'bool'),
|
||||
|
|
Loading…
Reference in a new issue