summaryrefslogtreecommitdiffstats
path: root/chrome/test
diff options
context:
space:
mode:
authorpatrick@chromium.org <patrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-12 01:08:42 +0000
committerpatrick@chromium.org <patrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-12 01:08:42 +0000
commit71a050a42cdb55b0a9b685b096297b97918312d2 (patch)
treefba7408b4d762a83db463c9101fb437daf3418a0 /chrome/test
parentc489b2702caeb985677c0d1ff2a7a1678bbb41a8 (diff)
downloadchromium_src-71a050a42cdb55b0a9b685b096297b97918312d2.zip
chromium_src-71a050a42cdb55b0a9b685b096297b97918312d2.tar.gz
chromium_src-71a050a42cdb55b0a9b685b096297b97918312d2.tar.bz2
- Add UI test for DOM checker.
- Modify DOM checker to work with the UI test framework. - Add expected failure list for DOM checker. Note that this only runs the tests over HTTP, not file:///. BUG=6274 Review URL: http://codereview.chromium.org/43029 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11505 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test')
-rw-r--r--chrome/test/data/dom_checker/README.chromium30
-rw-r--r--chrome/test/data/dom_checker/dom_checker.html108
-rw-r--r--chrome/test/data/dom_checker/dom_config.js6
-rw-r--r--chrome/test/data/dom_checker/dom_target_page.html8
-rw-r--r--chrome/test/data/dom_checker/expected_failures.txt4
-rw-r--r--chrome/test/data/dom_checker/extra_utils.js50
-rw-r--r--chrome/test/ui/dom_checker_uitest.cc156
-rw-r--r--chrome/test/ui/ui_tests.scons4
-rw-r--r--chrome/test/ui/ui_tests.vcproj8
9 files changed, 316 insertions, 58 deletions
diff --git a/chrome/test/data/dom_checker/README.chromium b/chrome/test/data/dom_checker/README.chromium
index 453dff91..75c672b 100644
--- a/chrome/test/data/dom_checker/README.chromium
+++ b/chrome/test/data/dom_checker/README.chromium
@@ -1,7 +1,23 @@
-This directory contains DOM checker, a tool to help automatically validate
-domain security policy enforcement. This tool will check cross-domain DOM
-accesses, JavaScript cookies, XMLHttpRequest calls, and more.
-
-DOM checker was written by Michal Zalewski and Filipe Almeida of Google.
-
-Version: 1.01
+This directory contains DOM checker, a tool to help automatically validate
+domain security policy enforcement. This tool will check cross-domain DOM
+accesses, JavaScript cookies, XMLHttpRequest calls, and more.
+
+DOM checker was written by Michal Zalewski and Filipe Almeida of Google.
+
+Version: 1.01
+
+Modifications:
+ - Modified dom_config.js to work with the test configuration setup.
+ - Added bookkeeping variables to dom_checker.html. These variables track the
+ total number of tests ran and the failed tests. This data is written to
+ cookies, which will be picked up by the test executable.
+ - Modified dom_checker.html to not complain when running the test on a
+ specified port other than the default port.
+ - Modified dom_checker.html to start the tests immediately on page load,
+ rather than waiting for the user to click on a button.
+ - Removed trailing whitespace in all files.
+ - Added extra_utils.js to contain extra utility functions needed to help with
+ automating the test. Included this file in dom_checker.html.
+ - Added expected_failures.txt to contain a list of expected failures. The
+ test is considered "passing" if there are no failures not in the expected
+ failure list.
diff --git a/chrome/test/data/dom_checker/dom_checker.html b/chrome/test/data/dom_checker/dom_checker.html
index 661d60e..2e02fd7 100644
--- a/chrome/test/data/dom_checker/dom_checker.html
+++ b/chrome/test/data/dom_checker/dom_checker.html
@@ -27,6 +27,7 @@
<title>DOM checker - browser domain context separation validator</title>
<script src="dom_config.js"></script>
+<script src="extra_utils.js"></script>
<script>
@@ -36,7 +37,7 @@ var running_local = false; // Running from file:///?
var bad = 0; // Number of failed tests
var now_running = 0; // Run-level nesting counter
-var target_page; // Target page location
+var target_page; // Target page location
var same_blank; // Same-domain blank page location
var blank_page; // Blank page location
@@ -73,10 +74,14 @@ var fail_cycles = 0; // IPC failure count
var output; // Output container.
+// Some added bookkeeping variables.
+var num_tests_total = 0;
+var tests_failed = [];
+
/* Send a reset command to IPC peer. */
function ipc_reset() {
- last_ipc = 'RESET';
+ last_ipc = 'RESET';
if (disable_ipc) return;
ipc_wait_count = 0;
@@ -89,7 +94,7 @@ function ipc_reset() {
/* Send evaluation request to IPC peer. */
function ipc_eval(expr) {
- last_ipc = 'EVAL(' + expr + ')';
+ last_ipc = 'EVAL(' + expr + ')';
if (disable_ipc) return;
ipc_wait_count = 0;
@@ -118,8 +123,8 @@ function ipc_changed() {
/* So, Opera is a bit naughty and won't let us do that. Oh well. */
- alert('Unable to get ipc_write frame hash in response to ' + last_ipc +
- ' (' + ipc_count + ') in state ' + ipc_state +
+ alert('Unable to get ipc_write frame hash in response to ' + last_ipc +
+ ' (' + ipc_count + ') in state ' + ipc_state +
'\nWARNING: Disabling side channel IPC, results may be less accurate!');
disable_ipc = true;
@@ -134,8 +139,8 @@ function ipc_changed() {
if (ipc_value == ipc_state) {
ipc_wait_count++;
- if (ipc_wait_count == 500)
- alert('Waited more than 500 cycles on IPC command ' + last_ipc + ' (' +
+ if (ipc_wait_count == 500)
+ alert('Waited more than 500 cycles on IPC command ' + last_ipc + ' (' +
ipc_count + ') in state ' + ipc_state);
return false;
@@ -157,7 +162,8 @@ function init_frames() {
return;
}
- if (location.protocol == 'http:' && main_host != location.hostname) {
+ if (location.protocol == 'http:' && main_host != location.hostname &&
+ main_host != location.host) {
alert('Config file dom_checker.js specifies main_host that does not match current hostname.\n' +
'Please check your configuration.');
return;
@@ -200,8 +206,7 @@ function check_frame() {
/* Make the page runnable. */
function init_button() {
output = document.getElementById('results');
- document.getElementById('start').disabled = false;
- document.getElementById('start').value="Click here to begin tests";
+ do_tests(); // Start the tests automatically at page load.
}
@@ -210,18 +215,18 @@ function E(x) { return eval(x); }
/* Open a new javascript: window, see if it gets to read window properties to
- other sites' about:blank windows, and phone back by pointing the window back
+ other sites' about:blank windows, and phone back by pointing the window back
to our domain. */
function open_blankwin() {
/* XXX: Is opener.* the best route to follow? Maybe open('',name) instead? */
try {
- blank_win = open('javascript:void(location = "' + same_blank +
+ blank_win = open('javascript:void(location = "' + same_blank +
'?" + opener.frames[0].frames[0].location)','blank_win',
'height=100,width=100,location=no,menubar=no,resizable=no,scrollbars=no,status=no,toolbar=no');
- } catch (e) {
- blank_win = open('javascript:void(location = "' + same_blank +
+ } catch (e) {
+ blank_win = open('javascript:void(location = "' + same_blank +
'?" + opener.frames[0].frames[0].location)','blank_win',
'height=100,width=100,location=no,menubar=no,resizable=no,scrollbars=no,status=no,toolbar=no');
}
@@ -229,7 +234,7 @@ function open_blankwin() {
}
-/* See if we get to access that window's properties, and whether it succeeded at
+/* See if we get to access that window's properties, and whether it succeeded at
retrieving the data. */
function blankwin_verify() {
@@ -245,7 +250,7 @@ function blankwin_verify() {
now_running--;
}
-
+
/* Prepare blank window checks... */
function blankwin_checks() {
@@ -273,7 +278,7 @@ function do_tests() {
if (document.getElementById('option_long').checked)
option_long = true;
- /* We need to call this first, as the ability to open new windows expires pretty
+ /* We need to call this first, as the ability to open new windows expires pretty
quickly after UI events in some browsers */
open_blankwin();
@@ -332,7 +337,7 @@ function do_tests() {
// Can setTimeout be smuggled across page transitions?
schedule_test('timeout_checks()');
-
+
// Can IFRAMEs access file:// URLs?
if (!running_local)
@@ -387,7 +392,7 @@ function next_test() {
test_count++;
if (cmd) {
- e.innerHTML = "Running test " + (test_count-1) + "/" + test_size +
+ e.innerHTML = "Running test " + (test_count-1) + "/" + test_size +
" <font color=gray>(" + cmd + ")</font>";
eval(cmd);
setTimeout(next_test, 100); // yield
@@ -402,13 +407,19 @@ function update_finalize() {
document.getElementById('start').value = "Testing complete!";
- if (bad)
- document.getElementById('status').innerHTML =
+ if (bad)
+ document.getElementById('status').innerHTML =
"<font color=red>Failed checks: " + bad + "</font>";
else
- document.getElementById('status').innerHTML =
+ document.getElementById('status').innerHTML =
"<font color=green>All checks passed (whoa!)</font>";
+ // Write the results for the test automation.
+ writeCookie('__num_tests_total', num_tests_total);
+ // Conservatively limit cookie size to 2K.
+ writeCookie('__tests_failed', convertArrayToCookieValue(tests_failed, 2048));
+ writeCookie('__tests_finished', '1');
+
}
@@ -422,6 +433,8 @@ function log(message) {
/* Log passed test event. */
function GOOD(x) {
+ num_tests_total++;
+
if (option_badonly) return;
x = x.replace('frames[0].frames[0]','(blank)').replace('frames[0]','(third-party)');
log('<font color=teal>Check passed : ' + x + ' access denied.</font>');
@@ -430,6 +443,9 @@ function GOOD(x) {
/* Log test failure. */
function BAD(x) {
+ num_tests_total++;
+ tests_failed.push(x);
+
bad++;
x = x.replace('frames[0].frames[0]','(blank)').replace('frames[0]','(third-party)');
log('<font color=red>CHECK FAILED : ' + x + ' is possible!</font>');
@@ -463,7 +479,7 @@ function variable_injection_check() {
/* See if we may just set document.domain to whatever we want. */
function opening_tricks() {
- try {
+ try {
document.domain = alt_host;
if (document.domain != alt_host) throw 1;
BAD("arbitrary document.domain");
@@ -517,6 +533,9 @@ function closing_tricks() {
GOOD("XMLHttpRequest path splitting");
}
+ // Disabled, causes the page to become unresponsive. See:
+ // http://code.google.com/p/chromium/issues/detail?id=8401
+ /*
x = new XMLHttpRequest();
try {
x.open('GET','file:///c:/boot.ini',false);
@@ -534,6 +553,7 @@ function closing_tricks() {
} catch (e) {
GOOD("XMLHttpRequest() to local files (unix)");
}
+ */
}
@@ -548,7 +568,7 @@ function closing_tricks() {
/* It would be good to test for the ability to set file:/// SRC= URLs,
but there is no convenient way to read back the result, I think...
- onerror= and onload= firing is handy, but very inconsistent across
+ onerror= and onload= firing is handy, but very inconsistent across
browsers. */
document.cookie = 'dom_checker_cookie=bar_com; path=/; domain=com';
@@ -556,7 +576,7 @@ function closing_tricks() {
document.cookie = 'dom_checker_cookie=bar_dot; path=/; domain=.';
document.cookie = 'dom_checker_cookie=bar_dotcomdot; path=/; domain=.cx.';
- // This will overwrite our cookie if domain= was silently dropped on previous
+ // This will overwrite our cookie if domain= was silently dropped on previous
// attempts:
document.cookie = 'dom_checker_cookie=invalid; path=/';
@@ -581,29 +601,29 @@ function closing_tricks() {
/* Depending on the implementation, this might not be a tragic security
flaw, as a mutual consent to this is required in most browsers; but it
- certainly encourages terrible coding practices and may make it easier
+ certainly encourages terrible coding practices and may make it easier
to go after certain targets. */
- try {
- document.domain = '.cx';
+ try {
+ document.domain = '.cx';
if (document.domain != '.cx') throw 1;
BAD("document.domain = '.cx'");
} catch (e) { GOOD("document.domain = '.cx'"); }
- try {
- document.domain = 'cx';
+ try {
+ document.domain = 'cx';
if (document.domain != 'cx') throw 1;
BAD("document.domain = 'cx'");
} catch (e) { GOOD("document.domain = 'cx'"); }
- try {
- document.domain = '.';
+ try {
+ document.domain = '.';
if (document.domain != '.') throw 1;
BAD("document.domain = '.'");
} catch (e) { GOOD("document.domain = '.'"); }
- try {
- document.domain = '';
+ try {
+ document.domain = '';
if (document.domain != '') throw 1;
BAD("document.domain = ''");
} catch (e) { GOOD("document.domain = ''"); }
@@ -848,7 +868,7 @@ function fill_read_write(control, base) {
hence are executed asynchronously. */
function try_read_write_all() {
- for(i in read_list)
+ for(i in read_list)
try_read(read_list[i]);
if (!write_list.length) return;
@@ -1005,16 +1025,16 @@ function try_call(name) {
function list_checks(name) {
var x;
- try {
+ try {
x = E(name + "[0]");
if (x == undefined) return;
BAD(name + "<!-- NOP -->[0] probe [value: " + x + "]");
} catch (e) { GOOD(name + " probe"); }
- try {
+ try {
x = E(name + ".length");
if (x == undefined) return;
- BAD(name + ".length read [value: " + x + "]");
+ BAD(name + ".length read [value: " + x + "]");
} catch (e) { GOOD(name + ".length read"); }
iterator_check(name);
@@ -1075,7 +1095,7 @@ function flip_finalize() {
/* Perform a location flip. */
function loc_flip() {
// if (Math.random() > .8) return;
- if (Math.random() > .5) document.getElementById('f').src = blank_page;
+ if (Math.random() > .5) document.getElementById('f').src = blank_page;
else document.getElementById('f').src = 'about:blank';
flip_count--;
if (!flip_count) {
@@ -1185,13 +1205,13 @@ Filipe Almeida &lt;<a href="mailto:filipe@google.com">filipe@google.com</a>&gt;<
Copyright 2008 by Google Inc., and licensed under the Apache License, Version 2.0.
<p>
<font color=gray>
-DOM access checker is a tool designed to automatically validate numerous aspects of domain
-security policy enforcement (cross-domain DOM access, Javascript cookies, XMLHttpRequest
-calls, event and transition handling) to detect common security attack or information
+DOM access checker is a tool designed to automatically validate numerous aspects of domain
+security policy enforcement (cross-domain DOM access, Javascript cookies, XMLHttpRequest
+calls, event and transition handling) to detect common security attack or information
disclosure vectors.
<p>
-Please run this tool both over HTTP, and then from local disk (file:/// namespace).
-Ideally, results in both cases should be the same, and no failed tests should be reported.
+Please run this tool both over HTTP, and then from local disk (file:/// namespace).
+Ideally, results in both cases should be the same, and no failed tests should be reported.
That said, although we worked with software vendors to resolve many of the most significant
issues, all common browsers fail anywhere from 10 to 30 of less significant tests due to
various design decisions (most of which bear some privacy considerations by making it
diff --git a/chrome/test/data/dom_checker/dom_config.js b/chrome/test/data/dom_checker/dom_config.js
index 8785d82..76721cd 100644
--- a/chrome/test/data/dom_checker/dom_config.js
+++ b/chrome/test/data/dom_checker/dom_config.js
@@ -3,7 +3,7 @@
DOM checker - configuration parameters
--------------------------------------
- Please be sure to update these to reflect the realities of the place where
+ Please be sure to update these to reflect the realities of the place where
you host the program.
Authors: Michal Zalewski <lcamtuf@google.com>
@@ -27,7 +27,7 @@
/* Host name where you intend to put the script: */
-var main_host = 'localhost';
+var main_host = 'localhost:8000';
/* Subdirectory for DOM checker files: */
var main_dir = 'dom_checker';
@@ -35,7 +35,7 @@ var main_dir = 'dom_checker';
/* An alternative way to call the same resource in a manner that
appears to the browser as completely unrelated to main_host
(try IP address): */
-var alt_host = '127.0.0.1';
+var alt_host = '127.0.0.1:8000';
/* Subdirectory for DOM checker files: */
var alt_dir = 'dom_checker';
diff --git a/chrome/test/data/dom_checker/dom_target_page.html b/chrome/test/data/dom_checker/dom_target_page.html
index a5a62b4..53fe620 100644
--- a/chrome/test/data/dom_checker/dom_target_page.html
+++ b/chrome/test/data/dom_checker/dom_target_page.html
@@ -64,13 +64,13 @@ function log(x) {
/* Wait for IPC state change, execute command, send results. */
-function get_ipc_command() {
+function get_ipc_command() {
var hval;
- try { hval = top.frames['ipc_read'].location.hash; } catch (e) {
+ try { hval = top.frames['ipc_read'].location.hash; } catch (e) {
// log('IPC command read failed from external ipc_read.');
- hval = '';
+ hval = '';
}
if (hval == prev_hval || hval == '' || hval == undefined || hval == 'NONE') {
@@ -107,7 +107,7 @@ function get_ipc_command() {
hval = hval.substr(1);
if (hval == 'RESET') res = 2;
- else try {
+ else try {
if (eval(unescape(hval))) res = 1;
} catch (e) {
// log('Evaluation exception! Final was: ' + unescape(hval));
diff --git a/chrome/test/data/dom_checker/expected_failures.txt b/chrome/test/data/dom_checker/expected_failures.txt
new file mode 100644
index 0000000..f66fa09
--- /dev/null
+++ b/chrome/test/data/dom_checker/expected_failures.txt
@@ -0,0 +1,4 @@
+frames[0].history.forward(0) call
+frames[0].length read [value: 0]
+frames[0].postMessage read [value: function () { [native code] }]
+open() frame name lookup
diff --git a/chrome/test/data/dom_checker/extra_utils.js b/chrome/test/data/dom_checker/extra_utils.js
new file mode 100644
index 0000000..bf62d7c
--- /dev/null
+++ b/chrome/test/data/dom_checker/extra_utils.js
@@ -0,0 +1,50 @@
+/*
+ Copyright (c) 2009 The Chromium Authors. All rights reserved.
+ Use of this source code is governed by a BSD-style license that can be
+ found in the LICENSE file.
+*/
+
+// Write a cookie with a given name and value.
+function writeCookie(name, value) {
+ document.cookie = name + '=' + value + '; path=/';
+}
+
+// Convert an array to a string to be stored in a cookie.
+//
+// Since cookie values are limited in length, this function takes a parameter
+// 'max_chars' to indicate the maximum length of the returned string. The
+// returned string will be less than or equal to 'max_chars' in length. Values
+// from the array are added to the string, in left to right order, until either
+// there are no more elements in the array or the next element will cause the
+// string to overflow the maximum number of characters allowed.
+function convertArrayToCookieValue(arr, max_chars) {
+ var string_builder = [];
+ var current_length = 0;
+
+ for (var i = 0; i < arr.length && current_length <= max_chars; ++i) {
+ var value = arr[i].toString();
+
+ // Get rid of newline characters.
+ value = value.replace(/[\r\n]/g, '');
+ // Replace reserved characters with spaces.
+ value = value.replace(/[,;=]/g, ' ');
+
+ // Make sure that the string length doesn't exceed the maximum allowed
+ // number of characters.
+ if (current_length + value.length > max_chars)
+ break;
+
+ string_builder.push(value);
+
+ // Add an extra 1 to factor in the length of the separator (a comma).
+ current_length += value.length + 1;
+ }
+
+ return string_builder.toString();
+}
+
+// Override functions that can spawn dialog boxes.
+
+window.alert = function() {}
+window.confirm = function() {}
+window.prompt = function() {}
diff --git a/chrome/test/ui/dom_checker_uitest.cc b/chrome/test/ui/dom_checker_uitest.cc
new file mode 100644
index 0000000..18445f4
--- /dev/null
+++ b/chrome/test/ui/dom_checker_uitest.cc
@@ -0,0 +1,156 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/command_line.h"
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/string_util.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/test/automation/tab_proxy.h"
+#include "chrome/test/ui/ui_test.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/net_util.h"
+
+namespace {
+
+static const FilePath::CharType kBaseUrl[] =
+ FILE_PATH_LITERAL("http://localhost:8000/");
+
+static const FilePath::CharType kStartFile[] =
+ FILE_PATH_LITERAL("dom_checker.html");
+
+const wchar_t kRunDomCheckerTest[] = L"run-dom-checker-test";
+
+class DomCheckerTest : public UITest {
+ public:
+ DomCheckerTest() {
+ show_window_ = true;
+ launch_arguments_.AppendSwitch(switches::kDisablePopupBlocking);
+ }
+
+ typedef std::list<std::string> ResultsList;
+ typedef std::set<std::string> ResultsSet;
+
+ void ParseResults(const std::string& input, ResultsSet* output, char sep) {
+ if (input.empty())
+ return;
+
+ std::vector<std::string> tokens;
+ SplitString(input, sep, &tokens);
+
+ std::vector<std::string>::const_iterator it = tokens.begin();
+ for (; it != tokens.end(); ++it) {
+ // Allow comments (lines that start with #).
+ if (it->length() > 0 && it->at(0) != '#')
+ output->insert(*it);
+ }
+ }
+
+ // Find the elements of "b" that are not in "a".
+ void CompareSets(const ResultsSet& a, const ResultsSet& b,
+ ResultsList* only_in_b) {
+ ResultsSet::const_iterator it = b.begin();
+ for (; it != b.end(); ++it) {
+ if (a.find(*it) == a.end())
+ only_in_b->push_back(*it);
+ }
+ }
+
+ // Return the path to the DOM checker directory on the local filesystem.
+ FilePath GetDomCheckerDir() {
+ FilePath test_dir;
+ PathService::Get(chrome::DIR_TEST_DATA, &test_dir);
+ return test_dir.AppendASCII("dom_checker");
+ }
+
+ FilePath GetExpectedFailuresPath() {
+ FilePath results_path = GetDomCheckerDir();
+ return results_path.AppendASCII("expected_failures.txt");
+ }
+
+ bool ReadExpectedResults(std::string* results) {
+ FilePath results_path = GetExpectedFailuresPath();
+ return file_util::ReadFileToString(results_path, results);
+ }
+
+ void RunDomChecker(std::wstring* total, std::wstring* failed) {
+ GURL test_url;
+ FilePath::StringType start_file(kStartFile);
+ FilePath::StringType url_string(kBaseUrl);
+ url_string.append(start_file);
+ test_url = GURL(url_string);
+
+ scoped_ptr<TabProxy> tab(GetActiveTab());
+ tab->NavigateToURL(test_url);
+
+ // Wait for the test to finish.
+ ASSERT_TRUE(WaitUntilCookieValue(tab.get(), test_url, "__tests_finished",
+ 3000, UITest::test_timeout_ms(), "1"));
+
+ std::string cookie;
+ ASSERT_TRUE(tab->GetCookieByName(test_url, "__num_tests_total", &cookie));
+ total->swap(UTF8ToWide(cookie));
+ ASSERT_FALSE(total->empty());
+ ASSERT_TRUE(tab->GetCookieByName(test_url, "__tests_failed", &cookie));
+ failed->swap(UTF8ToWide(cookie));
+ }
+
+ void RunTest(ResultsList* new_passes_list, ResultsList* new_failures_list) {
+ std::string expected_failures;
+ bool have_expected_results = ReadExpectedResults(&expected_failures);
+ ASSERT_TRUE(have_expected_results);
+
+ std::wstring total, failed;
+ RunDomChecker(&total, &failed);
+
+ printf("\n");
+ wprintf(L"__num_tests_total = [%s]\n", total.c_str());
+ wprintf(L"__tests_failed = [%s]\n", failed.c_str());
+
+ std::string current_failures = WideToUTF8(failed);
+
+ ResultsSet expected_failures_set;
+ ParseResults(expected_failures, &expected_failures_set, '\n');
+
+ ResultsSet current_failures_set;
+ ParseResults(current_failures, &current_failures_set, ',');
+
+ // Compute the list of new passes and failures.
+ CompareSets(current_failures_set, expected_failures_set, new_passes_list);
+ CompareSets(expected_failures_set, current_failures_set,
+ new_failures_list);
+ }
+
+ void PrintResults(ResultsList* new_passes_list,
+ ResultsList* new_failures_list) {
+ if (!new_failures_list->empty()) {
+ ADD_FAILURE();
+ printf("new tests failing:\n");
+ ResultsList::const_iterator it = new_failures_list->begin();
+ for (; it != new_failures_list->end(); ++it)
+ printf(" %s\n", it->c_str());
+ printf("\n");
+ }
+
+ if (!new_passes_list->empty()) {
+ printf("new tests passing:\n");
+ ResultsList::const_iterator it = new_passes_list->begin();
+ for (; it != new_passes_list->end(); ++it)
+ printf(" %s\n", it->c_str());
+ printf("\n");
+ }
+ }
+};
+
+} // namespace
+
+TEST_F(DomCheckerTest, Http) {
+ if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDomCheckerTest))
+ return;
+
+ ResultsList new_passes_list, new_failures_list;
+ RunTest(&new_passes_list, &new_failures_list);
+ PrintResults(&new_passes_list, &new_failures_list);
+}
diff --git a/chrome/test/ui/ui_tests.scons b/chrome/test/ui/ui_tests.scons
index 9bf717a..5106faa 100644
--- a/chrome/test/ui/ui_tests.scons
+++ b/chrome/test/ui/ui_tests.scons
@@ -225,6 +225,9 @@ input_files = ChromeFileList([
MSVSFilter('TestHistory', [
'history_uitest.cc',
]),
+ MSVSFilter('TestDOMChecker', [
+ 'dom_checker_uitest.cc',
+ ]),
])
if not env.Bit('windows'):
@@ -236,6 +239,7 @@ if not env.Bit('windows'):
'npapi_test_helper.cc',
'npapi_uitest.cpp',
'omnibox_uitest.cc',
+ 'dom_checker_uitest.cc',
'sandbox_uitests.cc',
diff --git a/chrome/test/ui/ui_tests.vcproj b/chrome/test/ui/ui_tests.vcproj
index e225613..eb5b374 100644
--- a/chrome/test/ui/ui_tests.vcproj
+++ b/chrome/test/ui/ui_tests.vcproj
@@ -542,6 +542,14 @@
>
</File>
</Filter>
+ <Filter
+ Name="TestDOMChecker"
+ >
+ <File
+ RelativePath=".\dom_checker_uitest.cc"
+ >
+ </File>
+ </Filter>
</Files>
<Globals>
</Globals>