diff options
Diffstat (limited to 'chrome/test/ui')
-rw-r--r-- | chrome/test/ui/inspector_controller_uitest.cc | 73 | ||||
-rw-r--r-- | chrome/test/ui/layout_plugin_uitest.cpp | 73 | ||||
-rw-r--r-- | chrome/test/ui/npapi_uitest.cpp | 281 | ||||
-rw-r--r-- | chrome/test/ui/omnibox_uitest.cc | 203 | ||||
-rw-r--r-- | chrome/test/ui/run_all_unittests.cc | 35 | ||||
-rw-r--r-- | chrome/test/ui/sandbox_uitests.cc | 51 | ||||
-rw-r--r-- | chrome/test/ui/ui_test.cc | 554 | ||||
-rw-r--r-- | chrome/test/ui/ui_test.h | 344 | ||||
-rw-r--r-- | chrome/test/ui/ui_test_suite.cc | 36 | ||||
-rw-r--r-- | chrome/test/ui/ui_test_suite.h | 81 | ||||
-rw-r--r-- | chrome/test/ui/ui_tests.vcproj | 528 |
11 files changed, 2259 insertions, 0 deletions
diff --git a/chrome/test/ui/inspector_controller_uitest.cc b/chrome/test/ui/inspector_controller_uitest.cc new file mode 100644 index 0000000..6ca6a91 --- /dev/null +++ b/chrome/test/ui/inspector_controller_uitest.cc @@ -0,0 +1,73 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "base/command_line.h" +#include "base/no_windows2000_unittest.h" +#include "base/win_util.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/test/automation/browser_proxy.h" +#include "chrome/test/automation/tab_proxy.h" +#include "chrome/test/ui/ui_test.h" +#include "net/url_request/url_request_unittest.h" + +// This test does not work on win2k. See http://b/1070036 +class InspectorControllerTest : public NoWindows2000Test<UITest> { + protected: + TabProxy* GetActiveTabProxy() { + scoped_ptr<BrowserProxy> window_proxy(automation()->GetBrowserWindow(0)); + EXPECT_TRUE(window_proxy.get()); + + int active_tab_index = 0; + EXPECT_TRUE(window_proxy->GetActiveTabIndex(&active_tab_index)); + return window_proxy->GetTab(active_tab_index); + } + + void NavigateTab(TabProxy* tab_proxy, const GURL& url) { + ASSERT_TRUE(tab_proxy->NavigateToURL(url)); + } +}; + +// This test also does not work in single process. See http://b/1214920 +TEST_F(InspectorControllerTest, InspectElement) { + if (IsTestCaseDisabled()) + return; + + if (CommandLine().HasSwitch(switches::kSingleProcess)) + return; + + TestServer server(L"chrome/test/data"); + ::scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + // We don't track resources until we've opened the inspector. + NavigateTab(tab.get(), server.TestServerPageW(L"files/inspector/test1.html")); + tab->InspectElement(0, 0); + NavigateTab(tab.get(), server.TestServerPageW(L"files/inspector/test1.html")); + EXPECT_EQ(1, tab->InspectElement(0, 0)); + NavigateTab(tab.get(), server.TestServerPageW(L"files/inspector/test2.html")); + EXPECT_EQ(2, tab->InspectElement(0, 0)); +} diff --git a/chrome/test/ui/layout_plugin_uitest.cpp b/chrome/test/ui/layout_plugin_uitest.cpp new file mode 100644 index 0000000..1a3e973 --- /dev/null +++ b/chrome/test/ui/layout_plugin_uitest.cpp @@ -0,0 +1,73 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "chrome/test/ui/ui_test.h" + +#include "base/file_util.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/test/automation/tab_proxy.h" +#include "googleurl/src/gurl.h" +#include "net/base/net_util.h" + +namespace { + +class LayoutPluginTester : public UITest { +}; + +} // namespace + +// Make sure that navigating away from a plugin referenced by JS doesn't +// crash. +TEST_F(LayoutPluginTester, UnloadNoCrash) { + // We need to copy our test-plugin into the plugins directory so that + // the browser can load it. + std::wstring plugins_directory = browser_directory_ + L"\\plugins"; + std::wstring plugin_src = browser_directory_ + L"\\npapi_layout_test_plugin.dll"; + std::wstring plugin_dest = plugins_directory + L"\\npapi_layout_test_plugin.dll"; + + CreateDirectory(plugins_directory.c_str(), NULL); + CopyFile(plugin_src.c_str(), plugin_dest.c_str(), true /* overwrite */); + + std::wstring path; + PathService::Get(chrome::DIR_TEST_DATA, &path); + file_util::AppendToPath(&path, L"npapi/layout_test_plugin.html"); + NavigateToURL(net_util::FilePathToFileURL(path)); + + std::wstring title; + TabProxy* tab = GetActiveTab(); + ASSERT_TRUE(tab); + EXPECT_TRUE(tab->GetTabTitle(&title)); + EXPECT_EQ(L"Layout Test Plugin Test", title); + + ASSERT_TRUE(tab->GoBack()); + EXPECT_TRUE(tab->GetTabTitle(&title)); + EXPECT_EQ(L"", title); + + delete tab; +} diff --git a/chrome/test/ui/npapi_uitest.cpp b/chrome/test/ui/npapi_uitest.cpp new file mode 100644 index 0000000..cf81db6 --- /dev/null +++ b/chrome/test/ui/npapi_uitest.cpp @@ -0,0 +1,281 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +// NPAPI UnitTests. +// + +// windows headers +#include <windows.h> +#include <shellapi.h> +#include <shlobj.h> +#include <atlbase.h> +#include <comutil.h> + +// runtime headers +#include <stdlib.h> +#include <string.h> +#include <memory.h> + +#include <ostream> + +#include "base/file_util.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/test/automation/tab_proxy.h" +#include "chrome/test/ui/ui_test.h" +#include "net/base/net_util.h" + +const char kTestCompleteCookie[] = "status"; +const char kTestCompleteSuccess[] = "OK"; +const int kLongWaitTimeout = 30*1000; +const int kShortWaitTimeout = 5*1000; + +std::ostream& operator<<(std::ostream& out, const CComBSTR &str) +{ + // I love strings. I really do. That's why I make sure + // to need 4 different types of strings to stream one out. + TCHAR szFinal[1024]; + _bstr_t bstrIntermediate(str); + _stprintf_s(szFinal, _T("%s"), (LPCTSTR)bstrIntermediate); + return out << szFinal; +} + + +class NPAPITester : public UITest { + protected: + NPAPITester() : UITest() + { + } + + virtual void SetUp() + { + // We need to copy our test-plugin into the plugins directory so that + // the browser can load it. + std::wstring plugins_directory = browser_directory_ + L"\\plugins"; + std::wstring plugin_src = browser_directory_ + L"\\npapi_test_plugin.dll"; + plugin_dll_ = plugins_directory + L"\\npapi_test_plugin.dll"; + + CreateDirectory(plugins_directory.c_str(), NULL); + CopyFile(plugin_src.c_str(), plugin_dll_.c_str(), FALSE); + + UITest::SetUp(); + } + + virtual void TearDown() + { + DeleteFile(plugin_dll_.c_str()); + UITest::TearDown(); + } + +protected: + // Generate the URL for testing a particular test. + // HTML for the tests is all located in test_directory\npapi\<testcase> + GURL GetTestUrl(const std::wstring &test_case) { + std::wstring path; + PathService::Get(chrome::DIR_TEST_DATA, &path); + file_util::AppendToPath(&path, L"npapi"); + file_util::AppendToPath(&path, test_case); + return net_util::FilePathToFileURL(path); + } + + // Waits for the test case to finish. + // ASSERTS if there are test failures. + void WaitForFinish(const std::string &name, const std::string &id, + const GURL &url, const int wait_time) + { + const int kSleepTime = 250; // 4 times per second + const int kMaxIntervals = wait_time / kSleepTime; + + scoped_ptr<TabProxy> tab(GetActiveTab()); + + std::string done_str; + for (int i = 0; i < kMaxIntervals; ++i) { + Sleep(kSleepTime); + + // The webpage being tested has javascript which sets a cookie + // which signals completion of the test. The cookie name is + // a concatenation of the test name and the test id. This allows + // us to run multiple tests within a single webpage and test + // that they all c + std::string cookieName = name; + cookieName.append("."); + cookieName.append(id); + cookieName.append("."); + cookieName.append(kTestCompleteCookie); + tab->GetCookieByName(url, cookieName, &done_str); + if (!done_str.empty()) + break; + } + + EXPECT_EQ(kTestCompleteSuccess, done_str); + } + +private: + std::wstring plugin_dll_; +}; + +class NPAPIVisiblePluginTester : public NPAPITester { + protected: + virtual void SetUp() { + show_window_ = true; + NPAPITester::SetUp(); + } +}; + +// Test passing arguments to a plugin. +TEST_F(NPAPITester, Arguments) { + std::wstring test_case = L"arguments.html"; + GURL url = GetTestUrl(test_case); + NavigateToURL(url); + WaitForFinish("arguments", "1", url, kShortWaitTimeout); +} + + +// Test invoking many plugins within a single page. +TEST_F(NPAPITester, ManyPlugins) { + std::wstring test_case = L"many_plugins.html"; + GURL url(GetTestUrl(test_case)); + NavigateToURL(url); + WaitForFinish("arguments", "1", url, kShortWaitTimeout); + WaitForFinish("arguments", "2", url, kShortWaitTimeout); + WaitForFinish("arguments", "3", url, kShortWaitTimeout); + WaitForFinish("arguments", "4", url, kShortWaitTimeout); + WaitForFinish("arguments", "5", url, kShortWaitTimeout); + WaitForFinish("arguments", "6", url, kShortWaitTimeout); + WaitForFinish("arguments", "7", url, kShortWaitTimeout); + WaitForFinish("arguments", "8", url, kShortWaitTimeout); + WaitForFinish("arguments", "9", url, kShortWaitTimeout); + WaitForFinish("arguments", "10", url, kShortWaitTimeout); + WaitForFinish("arguments", "11", url, kShortWaitTimeout); + WaitForFinish("arguments", "12", url, kShortWaitTimeout); + WaitForFinish("arguments", "13", url, kShortWaitTimeout); + WaitForFinish("arguments", "14", url, kShortWaitTimeout); + WaitForFinish("arguments", "15", url, kShortWaitTimeout); +} + +// Test various calls to GetURL from a plugin. +TEST_F(NPAPITester, GetURL) { + std::wstring test_case = L"geturl.html"; + GURL url = GetTestUrl(test_case); + NavigateToURL(url); + WaitForFinish("geturl", "1", url, kShortWaitTimeout); +} + +// Test various calls to GetURL for javascript URLs with +// non NULL targets from a plugin. +TEST_F(NPAPITester, GetJavaScriptURL) { + std::wstring test_case = L"get_javascript_url.html"; + GURL url = GetTestUrl(test_case); + NavigateToURL(url); + WaitForFinish("getjavascripturl", "1", url, kShortWaitTimeout); +} + + +// Tests that if an NPObject is proxies back to its original process, the +// original pointer is returned and not a proxy. If this fails the plugin +// will crash. +TEST_F(NPAPITester, NPObjectProxy) { + std::wstring test_case = L"npobject_proxy.html"; + GURL url = GetTestUrl(test_case); + NavigateToURL(url); + WaitForFinish("npobject_proxy", "1", url, kShortWaitTimeout); +} + +// Tests if a plugin executing a self deleting script using NPN_GetURL +// works without crashing or hanging +TEST_F(NPAPITester, SelfDeletePluginGetUrl) { + std::wstring test_case = L"self_delete_plugin_geturl.html"; + GURL url = GetTestUrl(test_case); + NavigateToURL(url); + WaitForFinish("self_delete_plugin_geturl", "1", url, kShortWaitTimeout); +} + +// Tests if a plugin executing a self deleting script using Invoke +// works without crashing or hanging +TEST_F(NPAPITester, SelfDeletePluginInvoke) { + std::wstring test_case = L"self_delete_plugin_invoke.html"; + GURL url = GetTestUrl(test_case); + NavigateToURL(url); + WaitForFinish("self_delete_plugin_invoke", "1", url, kShortWaitTimeout); +} + +// Tests if a plugin executing a self deleting script in the context of +// a synchronous paint event works correctly +TEST_F(NPAPIVisiblePluginTester, SelfDeletePluginInvokeInSynchronousPaint) { + if (!UITest::in_process_plugins() && !UITest::in_process_renderer()) { + show_window_ = true; + std::wstring test_case = L"execute_script_delete_in_paint.html"; + GURL url = GetTestUrl(test_case); + NavigateToURL(url); + WaitForFinish("execute_script_delete_in_paint", "1", url, kShortWaitTimeout); + } +} + +TEST_F(NPAPIVisiblePluginTester, SelfDeletePluginInNewStream) { + show_window_ = true; + std::wstring test_case = L"self_delete_plugin_stream.html"; + GURL url = GetTestUrl(test_case); + NavigateToURL(url); + WaitForFinish("self_delete_plugin_stream", "1", url, kShortWaitTimeout); +} + +// Tests if a plugin has a non zero window rect. +TEST_F(NPAPIVisiblePluginTester, VerifyPluginWindowRect) { + show_window_ = true; + std::wstring test_case = L"verify_plugin_window_rect.html"; + GURL url = GetTestUrl(test_case); + NavigateToURL(url); + WaitForFinish("checkwindowrect", "1", url, kShortWaitTimeout); +} + +TEST_F(NPAPIVisiblePluginTester, VerifyNPObjectLifetimeTest) { + if (!UITest::in_process_plugins() && !UITest::in_process_renderer()) { + show_window_ = true; + std::wstring test_case = L"npobject_lifetime_test.html"; + GURL url = GetTestUrl(test_case); + NavigateToURL(url); + WaitForFinish("npobject_lifetime_test", "1", url, kShortWaitTimeout); + } +} + +// Tests that we don't crash or assert if NPP_New fails +TEST_F(NPAPIVisiblePluginTester, NewFails) { + GURL url = GetTestUrl(L"new_fails.html"); + NavigateToURL(url); + WaitForFinish("new_fails", "1", url, kShortWaitTimeout); +} + +TEST_F(NPAPIVisiblePluginTester, SelfDeletePluginInNPNEvaluate) { + if (!UITest::in_process_plugins() && !UITest::in_process_renderer()) { + GURL url = GetTestUrl(L"execute_script_delete_in_npn_evaluate.html"); + NavigateToURL(url); + WaitForFinish("npobject_delete_plugin_in_evaluate", "1", url, + kShortWaitTimeout); + } +}
\ No newline at end of file diff --git a/chrome/test/ui/omnibox_uitest.cc b/chrome/test/ui/omnibox_uitest.cc new file mode 100644 index 0000000..933810e --- /dev/null +++ b/chrome/test/ui/omnibox_uitest.cc @@ -0,0 +1,203 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <stdio.h> + +#include "base/command_line.h" +#include "base/file_util.h" +#include "base/path_service.h" +#include "base/perftimer.h" +#include "base/string_util.h" +#include "chrome/app/chrome_dll_resource.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/libxml_utils.h" +#include "chrome/test/automation/autocomplete_edit_proxy.h" +#include "chrome/test/automation/automation_proxy.h" +#include "chrome/test/automation/browser_proxy.h" +#include "chrome/test/automation/window_proxy.h" +#include "chrome/test/ui/ui_test.h" + +const wchar_t kRunOmniboxTest[] = L"run_omnibox_test"; + +class OmniboxTest : public UITest { + public: + + double score_; + double max_score_; + + int query_count_; + int query_timeouts_; + int64 time_squared_; + int64 time_sum_; + int64 time_min_; + int64 time_max_; + + OmniboxTest() : UITest() { + show_window_ = true; + query_count_ = 0; + query_timeouts_ = 0; + score_ = 0; + max_score_ = 0; + time_squared_ = 0; + time_sum_ = 0; + time_min_ = 0; + time_max_ = 0; + } + + // Many times a user may enter something like "google.com". If + // http://www.google.com/ is suggested that should be considered a match. + // This could probably be accomplished with regex as well. Note that this + // method is called even when suggestion isn't a URL. + bool IsMatch(const std::wstring& input_test, const std::wstring& suggestion); + // Runs a query chain. This sends each proper prefix of the input to the + // omnibox and scores the autocompelte results returned. + void RunQueryChain(const std::wstring& input_text); +}; + +bool OmniboxTest::IsMatch(const std::wstring& input_text, + const std::wstring& suggestion) { + // This prefix list comes from the list used in history_url_provider.cc withiff + // the exception of "ftp." and "www.". + std::wstring prefixes[] = {L"", L"ftp://", L"http://", L"https://", + L"ftp.", L"www.", L"ftp://www.", L"ftp://ftp.", + L"http://www.", L"https://www."}; + std::wstring postfixes[] = {L"", L"/"}; + for (int i = 0; i < sizeof(prefixes) / sizeof(std::wstring); ++i) { + for (int j = 0; j < sizeof(postfixes) / sizeof(std::wstring); ++j) { + if (prefixes[i] + input_text + postfixes[j] == suggestion) + return true; + } + } + return false; +} + +void OmniboxTest::RunQueryChain(const std::wstring& input_text) { + // Get a handle on the omnibox and give it focus. + scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); + scoped_ptr<WindowProxy> window( + automation()->GetWindowForBrowser(browser.get())); + scoped_ptr<AutocompleteEditProxy> autocomplete_edit( + automation()->GetAutocompleteEditForBrowser(browser.get())); + ASSERT_TRUE(browser->ApplyAccelerator(IDC_FOCUS_LOCATION)); + + // Try every proper prefix of input_text. There's no use trying + // input_text itself since the autocomplete results will always contain it. + for (size_t i = 1; i < input_text.size(); ++i) { + Matches matches; + + // We're only going to count the time elapsed waiting for autocomplete + // matches to be returned to us. + ASSERT_TRUE(autocomplete_edit->SetText(input_text.substr(0, i))); + PerfTimer timer; + if (autocomplete_edit->WaitForQuery(30000)) { + ASSERT_TRUE(autocomplete_edit->GetAutocompleteMatches(&matches)); + int64 time_elapsed = timer.Elapsed().InMilliseconds(); + + // Adjust statistic trackers. + if (query_count_ == 0) + time_min_ = time_max_ = time_elapsed; + ++query_count_; + time_squared_ += time_elapsed * time_elapsed; + time_sum_ += time_elapsed; + if (time_elapsed < time_min_) + time_min_ = time_elapsed; + if (time_elapsed > time_max_) + time_max_ = time_elapsed; + } else { + ++query_timeouts_; + } + wprintf(L"query: %d\n", query_count_); + + // Check if any suggestions match the input text. Stop if a match is + // found. + for (Matches::const_iterator j(matches.begin()); j != matches.end(); ++j) { + if (IsMatch(input_text, j->fill_into_edit)) { + score_ += i; + break; + } + } + max_score_ += i; + } +} + +// This test reads in the omnibox_tests.xml file and performs the tests +// within. The current format of xml is fairly simple. Nothing is currently +// done with the provider information. +// <omnibox_tests> +// Zero or more test elements. +// <test query='%query%'> +// Zero or more provider elements. +// <provider name='%expected_provider_name%'/> +// </test> +// </omnibox_tests> + +TEST_F(OmniboxTest, Measure) { + if (!CommandLine().HasSwitch(kRunOmniboxTest)) return; + + std::wstring omnibox_tests_path; + PathService::Get(chrome::DIR_TEST_DATA, &omnibox_tests_path); + file_util::AppendToPath(&omnibox_tests_path, L"omnibox_tests.xml"); + + XmlReader reader; + ASSERT_TRUE(reader.LoadFile(WideToASCII(omnibox_tests_path))); + while (reader.SkipToElement()) { + ASSERT_EQ("omnibox_tests", reader.NodeName()); + reader.Read(); + while (reader.SkipToElement()) { + ASSERT_EQ("test", reader.NodeName()); + std::string query; + std::vector<std::string> expected_providers; + ASSERT_TRUE(reader.NodeAttribute("query", &query)); + reader.Read(); + while (reader.SkipToElement()) { + ASSERT_EQ("provider", reader.NodeName()); + std::string provider; + ASSERT_TRUE(reader.NodeAttribute("provider", &provider)); + expected_providers.push_back(provider); + reader.Read(); + } + RunQueryChain(ASCIIToWide(query)); + reader.Read(); + } + reader.Read(); + } + + // Output results. + ASSERT_GT(query_count_, 0); + int64 mean = time_sum_ / query_count_; + wprintf(L"__om_query_count = %d\n", query_count_); + wprintf(L"__om_query_timeouts = %d\n", query_timeouts_); + wprintf(L"__om_time_per_query_avg = %d\n", mean); + // Use the equation stddev = sqrt(Sum(x_i^2)/N - mean^2). + wprintf(L"__om_time_per_query_stddev = %d\n", static_cast<int64>( + sqrt(1.0 * time_squared_ / query_count_ - mean * mean))); + wprintf(L"__om_time_per_query_max = %d\n", time_max_); + wprintf(L"__om_time_per_query_min = %d\n", time_min_); + wprintf(L"__om_score = %.4f\n", 100.0 * score_ / max_score_); +} diff --git a/chrome/test/ui/run_all_unittests.cc b/chrome/test/ui/run_all_unittests.cc new file mode 100644 index 0000000..737a7be --- /dev/null +++ b/chrome/test/ui/run_all_unittests.cc @@ -0,0 +1,35 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "chrome/test/ui/ui_test_suite.h" + +int main(int argc, char **argv) { + Thread::SetThreadName("Tests_Main", GetCurrentThreadId()); + return UITestSuite(argc, argv).Run(); +} diff --git a/chrome/test/ui/sandbox_uitests.cc b/chrome/test/ui/sandbox_uitests.cc new file mode 100644 index 0000000..2c30ba8 --- /dev/null +++ b/chrome/test/ui/sandbox_uitests.cc @@ -0,0 +1,51 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <windows.h> +#include <string> + +#include "base/command_line.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/test/ui/ui_test.h" +#include "testing/gtest/include/gtest/gtest.h" + +class SandboxTest : public UITest { + protected: + // Launches chrome with the --test-sandbox=security_tests.dll flag. + SandboxTest() : UITest() { + CommandLine::AppendSwitchWithValue(&launch_arguments_, + switches::kTestSandbox, + L"security_tests.dll"); + } +}; + +// Verifies that chrome is running properly. +TEST_F(SandboxTest, ExecuteDll) { + EXPECT_EQ(1, GetTabCount()); +} diff --git a/chrome/test/ui/ui_test.cc b/chrome/test/ui/ui_test.cc new file mode 100644 index 0000000..f5ce685 --- /dev/null +++ b/chrome/test/ui/ui_test.cc @@ -0,0 +1,554 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <set> +#include <vector> + +#include "chrome/test/ui/ui_test.h" + +#include "base/base_switches.h" +#include "base/command_line.h" +#include "base/file_util.h" +#include "base/process_util.h" +#include "base/scoped_ptr.h" +#include "base/string_util.h" +#include "base/time.h" +#include "chrome/browser/url_fixer_upper.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/chrome_process_filter.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/debug_flags.h" +#include "chrome/common/logging_chrome.h" +#include "chrome/common/json_value_serializer.h" +#include "chrome/test/automation/browser_proxy.h" +#include "chrome/test/automation/tab_proxy.h" +#include "chrome/test/automation/window_proxy.h" +#include "chrome/test/test_file_util.h" + +bool UITest::in_process_renderer_ = false; +bool UITest::in_process_plugins_ = false; +bool UITest::no_sandbox_ = false; +bool UITest::full_memory_dump_ = false; +bool UITest::safe_plugins_ = false; +bool UITest::show_error_dialogs_ = true; +bool UITest::default_use_existing_browser_ = false; +bool UITest::dump_histograms_on_exit_ = false; +bool UITest::enable_dcheck_ = false; +bool UITest::silent_dump_on_dcheck_ = false; +int UITest::timeout_ms_ = 20 * 60 * 1000; + +// Uncomment this line to have the spawned process wait for the debugger to +// attach. +// #define WAIT_FOR_DEBUGGER_ON_OPEN 1 + +// static +bool UITest::DieFileDie(const std::wstring& file, bool recurse) { + if (!file_util::PathExists(file)) + return true; + + // Sometimes Delete fails, so try a few more times. + for (int i = 0; i < 10; ++i) { + if (file_util::Delete(file, recurse)) + return true; + Sleep(kWaitForActionMaxMsec / 10); + } + return false; +} + +UITest::UITest() + : testing::Test(), + expected_errors_(0), + expected_crashes_(0), + wait_for_initial_loads_(true), + homepage_(L"about:blank"), + dom_automation_enabled_(false), + process_(NULL), + show_window_(false), + clear_profile_(true), + include_testing_id_(true), + use_existing_browser_(default_use_existing_browser_) { + PathService::Get(chrome::DIR_APP, &browser_directory_); + PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory_); + GetSystemTimeAsFileTime(&test_start_time_); +} + +void UITest::SetUp() { + if (!use_existing_browser_) { + AssertAppNotRunning(L"Please close any other instances " + L"of the app before testing."); + } + + LaunchBrowserAndServer(); +} + +void UITest::TearDown() { + CloseBrowserAndServer(); + + // Make sure that we didn't encounter any assertion failures + logging::AssertionList assertions; + logging::GetFatalAssertions(&assertions); + + // If there were errors, get all the error strings for display. + std::wstring failures = + L"The following error(s) occurred in the application during this test:"; + if (static_cast<int>(assertions.size()) > expected_errors_) { + logging::AssertionList::const_iterator iter = assertions.begin(); + for (; iter != assertions.end(); ++iter) { + failures.append(L"\n\n"); + failures.append(*iter); + } + } + EXPECT_EQ(expected_errors_, assertions.size()) << failures; + + // Check for crashes during the test + std::wstring crash_dump_path; + PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dump_path); + // Each crash creates two dump files, so we divide by two here. + int actual_crashes = + file_util::CountFilesCreatedAfter(crash_dump_path, test_start_time_) / 2; + std::wstring error_msg = + L"Encountered an unexpected crash in the program during this test."; + if (expected_crashes_ > 0 && actual_crashes == 0) + error_msg += L" Have you started crash_service.exe?"; + EXPECT_EQ(expected_crashes_, actual_crashes) << error_msg; +} + +void UITest::LaunchBrowserAndServer() { + // Set up IPC testing interface server. + server_.reset(new AutomationProxy); + + LaunchBrowser(launch_arguments_, clear_profile_); + if (wait_for_initial_loads_) + ASSERT_TRUE(server_->WaitForInitialLoads()); + else + Sleep(2000); + + automation()->SetFilteredInet(true); +} + +void UITest::CloseBrowserAndServer() { + QuitBrowser(); + CleanupAppProcesses(); + + // Shut down IPC testing interface. + server_.reset(); +} + +void UITest::LaunchBrowser(const std::wstring& arguments, bool clear_profile) { + std::wstring command_line(browser_directory_); + file_util::AppendToPath(&command_line, + chrome::kBrowserProcessExecutableName); + + // We need cookies on file:// for things like the page cycler. + CommandLine::AppendSwitch(&command_line, switches::kEnableFileCookies); + + if (dom_automation_enabled_) + CommandLine::AppendSwitch(&command_line, + switches::kDomAutomationController); + + if (include_testing_id_) { + if (use_existing_browser_) { + // TODO(erikkay): The new switch depends on a browser instance already + // running, it won't open a new browser window if it's not. We could fix + // this by passing an url (e.g. about:blank) on the command line, but + // I decided to keep using the old switch in the existing use case to + // minimize changes in behavior. + CommandLine::AppendSwitchWithValue(&command_line, + switches::kAutomationClientChannelID, + server_->channel_id()); + } else { + CommandLine::AppendSwitchWithValue(&command_line, + switches::kTestingChannelID, + server_->channel_id()); + } + } + + if (!show_error_dialogs_) + CommandLine::AppendSwitch(&command_line, switches::kNoErrorDialogs); + if (in_process_renderer_) + CommandLine::AppendSwitch(&command_line, switches::kSingleProcess); + if (in_process_plugins_) + CommandLine::AppendSwitch(&command_line, switches::kInProcessPlugins); + if (no_sandbox_) + CommandLine::AppendSwitch(&command_line, switches::kNoSandbox); + if (full_memory_dump_) + CommandLine::AppendSwitch(&command_line, switches::kFullMemoryCrashReport); + if (safe_plugins_) + CommandLine::AppendSwitch(&command_line, switches::kSafePlugins); + if (enable_dcheck_) + CommandLine::AppendSwitch(&command_line, switches::kEnableDCHECK); + if (silent_dump_on_dcheck_) + CommandLine::AppendSwitch(&command_line, switches::kSilentDumpOnDCHECK); + if (!homepage_.empty()) + CommandLine::AppendSwitchWithValue(&command_line, + switches::kHomePage, + homepage_); + PathService::Get(chrome::DIR_USER_DATA, &user_data_dir_); + if (!user_data_dir_.empty()) + CommandLine::AppendSwitchWithValue(&command_line, + switches::kUserDataDir, + user_data_dir_); + + CommandLine::AppendSwitch(&command_line, switches::kDisableMetricsReporting); + + // We always want to enable chrome logging + CommandLine::AppendSwitch(&command_line, switches::kEnableLogging); + + if (dump_histograms_on_exit_) + CommandLine::AppendSwitch(&command_line, switches::kDumpHistogramsOnExit); + +#ifdef WAIT_FOR_DEBUGGER_ON_OPEN + CommandLine::AppendSwitch(&command_line, switches::kDebugOnStart); +#endif + + DebugFlags::ProcessDebugFlags(&command_line, DebugFlags::UNKNOWN, false); + command_line.append(L" " + arguments); + + // Clear user data directory to make sure test environment is consistent + // We balk on really short (absolute) user_data_dir directory names, because + // we're worried that they'd accidentally be root or something. + ASSERT_LT(10, static_cast<int>(user_data_dir_.size())) << + "The user data directory name passed into this test was too " + "short to delete safely. Please check the user-data-dir " + "argument and try again."; + if (clear_profile) + ASSERT_TRUE(DieFileDie(user_data_dir_, true)); + + if (!template_user_data_.empty()) { + // Recursively copy the template directory to the user_data_dir. + ASSERT_TRUE(file_util::CopyRecursiveDirNoCache(template_user_data_, + user_data_dir_)); + } + + browser_launch_time_ = TimeTicks::Now(); + + bool started = process_util::LaunchApp( + command_line, + false, // Don't wait for process object (doesn't work for + // us) + !show_window_, + &process_); + ASSERT_EQ(started, true); + + if (use_existing_browser_) { + DWORD pid = 0; + HWND hwnd = FindWindowEx(HWND_MESSAGE, NULL, chrome::kMessageWindowClass, + user_data_dir_.c_str()); + GetWindowThreadProcessId(hwnd, &pid); + // This mode doesn't work if we wound up launching a new browser ourselves. + ASSERT_NE(pid, process_util::GetProcId(process_)); + CloseHandle(process_); + process_ = OpenProcess(SYNCHRONIZE, false, pid); + } +} + +void UITest::QuitBrowser() { + typedef std::vector<HWND> HandleVector; + + // There's nothing to do here if the browser is not running. + if (IsBrowserRunning()) { + automation()->SetFilteredInet(false); + HandleVector handles; + + // Build up a list of HWNDs; we do this as a separate step so that closing + // the windows doesn't mess up the iteration. + int window_count = 0; + EXPECT_TRUE(automation()->GetBrowserWindowCount(&window_count)); + + for (int i = 0; i < window_count; ++i) { + HWND window_handle; + scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(i)); + scoped_ptr<WindowProxy> window( + automation()->GetWindowForBrowser(browser.get())); + EXPECT_TRUE(window->GetHWND(&window_handle)); + handles.push_back(window_handle); + } + + for (HandleVector::iterator iter = handles.begin(); iter != handles.end(); + ++iter) { + ::PostMessage(*iter, WM_CLOSE, 0, 0); + } + + // Wait for the browser process to quit. It should quit once all tabs have + // been closed. + int timeout = 5000; +#ifdef WAIT_FOR_DEBUGGER_ON_OPEN + timeout = 500000; +#endif + if (WAIT_TIMEOUT == WaitForSingleObject(process_, timeout)) { + // We need to force the browser to quit because it didn't quit fast + // enough. Take no chance and kill every chrome processes. + CleanupAppProcesses(); + } + } + + // Don't forget to close the handle + CloseHandle(process_); + process_ = NULL; +} + +void UITest::AssertAppNotRunning(const std::wstring& error_message) { + ASSERT_EQ(0, GetBrowserProcessCount()) << error_message; +} + +void UITest::CleanupAppProcesses() { + BrowserProcessFilter filter; + + // Make sure that no instances of the browser remain. + const int kExitTimeoutMs = 5000; + const int kExitCode = 1; + process_util::CleanupProcesses( + chrome::kBrowserProcessExecutableName, kExitTimeoutMs, kExitCode, + &filter); + + // Suppress spammy failures that seem to be occurring when running + // the UI tests in single-process mode. + // TODO(jhughes): figure out why this is necessary at all, and fix it + if (!in_process_renderer_) { + AssertAppNotRunning(L"Unable to quit all browser processes."); + } +} + +TabProxy* UITest::GetActiveTab() { + scoped_ptr<BrowserProxy> window_proxy(automation()->GetBrowserWindow(0)); + if (!window_proxy.get()) + return NULL; + + int active_tab_index = -1; + EXPECT_TRUE(window_proxy->GetActiveTabIndex(&active_tab_index)); + if (active_tab_index == -1) + return NULL; + + return window_proxy->GetTab(active_tab_index); +} + +void UITest::NavigateToURL(const GURL& url) { + scoped_ptr<TabProxy> tab_proxy(GetActiveTab()); + ASSERT_TRUE(tab_proxy.get()); + if (!tab_proxy.get()) + return; + + bool is_timeout = true; + ASSERT_TRUE(tab_proxy->NavigateToURLWithTimeout(url, kMaxTestExecutionTime, + &is_timeout)) << url.spec(); + ASSERT_FALSE(is_timeout) << url.spec(); +} + +bool UITest::WaitForDownloadShelfVisible(TabProxy* tab) { + const int kCycles = 20; + for (int i = 0; i < kCycles; i++) { + bool visible = false; + if (!tab->IsShelfVisible(&visible)) + return false; // Some error. + if (visible) + return true; // Got the download shelf. + + // Give it a chance to catch up. + Sleep(kWaitForActionMaxMsec / kCycles); + } + return false; +} + +GURL UITest::GetActiveTabURL() { + scoped_ptr<TabProxy> tab_proxy(GetActiveTab()); + if (!tab_proxy.get()) + return GURL(); + + GURL url; + if (!tab_proxy->GetCurrentURL(&url)) + return GURL(); + return url; +} + +std::wstring UITest::GetActiveTabTitle() { + std::wstring title; + scoped_ptr<TabProxy> tab_proxy(GetActiveTab()); + if (!tab_proxy.get()) + return title; + + EXPECT_TRUE(tab_proxy->GetTabTitle(&title)); + return title; +} + +bool UITest::IsBrowserRunning() { + return CrashAwareSleep(0); +} + +bool UITest::CrashAwareSleep(int time_out_ms) { + return WAIT_TIMEOUT == WaitForSingleObject(process_, time_out_ms); +} + +/*static*/ +int UITest::GetBrowserProcessCount() { + BrowserProcessFilter filter; + return process_util::GetProcessCount(chrome::kBrowserProcessExecutableName, + &filter); +} + +static DictionaryValue* LoadDictionaryValueFromPath(const std::wstring& path) { + if (path.empty()) + return NULL; + + JSONFileValueSerializer serializer(path); + Value* root_value = NULL; + if (serializer.Deserialize(&root_value) && + root_value->GetType() != Value::TYPE_DICTIONARY) { + delete root_value; + return NULL; + } + return static_cast<DictionaryValue*>(root_value); +} + +DictionaryValue* UITest::GetLocalState() { + std::wstring local_state_path; + PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path); + return LoadDictionaryValueFromPath(local_state_path); +} + +DictionaryValue* UITest::GetDefaultProfilePreferences() { + std::wstring path; + PathService::Get(chrome::DIR_USER_DATA, &path); + file_util::AppendToPath(&path, chrome::kNotSignedInProfile); + file_util::AppendToPath(&path, chrome::kPreferencesFilename); + return LoadDictionaryValueFromPath(path); +} + +int UITest::GetTabCount() { + scoped_ptr<BrowserProxy> first_window(automation()->GetBrowserWindow(0)); + if (!first_window.get()) + return 0; + + int result = 0; + EXPECT_TRUE(first_window->GetTabCount(&result)); + + return result; +} + +bool UITest::WaitUntilCookieValue(TabProxy* tab, + const GURL& url, + const char* cookie_name, + int interval_ms, + int time_out_ms, + const char* expected_value) { + const int kMaxIntervals = time_out_ms / interval_ms; + + std::string cookie_value; + bool completed = false; + for (int i = 0; i < kMaxIntervals; ++i) { + bool browser_survived = CrashAwareSleep(interval_ms); + + tab->GetCookieByName(url, cookie_name, &cookie_value); + + if (cookie_value == expected_value) { + completed = true; + break; + } + EXPECT_TRUE(browser_survived); + if (!browser_survived) { + // The browser process died. + break; + } + } + return completed; +} + +std::string UITest::WaitUntilCookieNonEmpty(TabProxy* tab, + const GURL& url, + const char* cookie_name, + int interval_ms, + int time_out_ms) { + const int kMaxIntervals = time_out_ms / interval_ms; + + std::string cookie_value; + for (int i = 0; i < kMaxIntervals; ++i) { + bool browser_survived = CrashAwareSleep(interval_ms); + + tab->GetCookieByName(url, cookie_name, &cookie_value); + + if (!cookie_value.empty()) + break; + + EXPECT_TRUE(browser_survived); + if (!browser_survived) { + // The browser process died. + break; + } + } + + return cookie_value; +} + +void UITest::WaitUntilTabCount(int tab_count) { + for (int i = 0; i < 10; ++i) { + Sleep(kWaitForActionMaxMsec / 10); + if (GetTabCount() == tab_count) + break; + } + EXPECT_EQ(tab_count, GetTabCount()); +} + +std::wstring UITest::GetDownloadDirectory() { + scoped_ptr<TabProxy> tab_proxy(GetActiveTab()); + if (!tab_proxy.get()) + return false; + + std::wstring download_directory; + EXPECT_TRUE(tab_proxy->GetDownloadDirectory(&download_directory)); + return download_directory; +} + +bool UITest::CloseBrowser(BrowserProxy* browser, + bool* application_closed) const { + DCHECK(application_closed); + if (!browser->is_valid() || !browser->handle()) + return false; + + IPC::Message* response = NULL; + bool succeeded = server_->SendAndWaitForResponse( + new AutomationMsg_CloseBrowserRequest(0, browser->handle()), + &response, AutomationMsg_CloseBrowserResponse__ID); + + if (!succeeded) + return false; + + void* iter = NULL; + bool result = true; + response->ReadBool(&iter, &result); + response->ReadBool(&iter, application_closed); + + if (*application_closed) { + // Let's wait until the process dies (if it is not gone already). + int r = WaitForSingleObject(process_, INFINITE); + DCHECK(r != WAIT_FAILED); + } + + delete response; + return result; +} diff --git a/chrome/test/ui/ui_test.h b/chrome/test/ui/ui_test.h new file mode 100644 index 0000000..daaff3d --- /dev/null +++ b/chrome/test/ui/ui_test.h @@ -0,0 +1,344 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CHROME_TEST_UI_UI_TEST_H__ +#define CHROME_TEST_UI_UI_TEST_H__ + +// This file provides a common base for running UI unit tests, which operate +// the entire browser application in a separate process for holistic +// functional testing. +// +// Tests should #include this file, subclass UITest, and use the TEST_F macro +// to declare individual test cases. This provides a running browser window +// during the test, accessible through the window_ member variable. The window +// will close when the test ends, regardless of whether the test passed. +// +// Tests which need to launch the browser with a particular set of command-line +// arguments should set the value of launch_arguments_ in their constructors. + +#include <windows.h> +#include <string> + +#include "base/path_service.h" +#include "base/scoped_ptr.h" +#include "base/time.h" +#include "chrome/test/automation/automation_proxy.h" +#include "googleurl/src/gurl.h" +#include "testing/gtest/include/gtest/gtest.h" + +class DictionaryValue; +class TabProxy; + +class UITest : public testing::Test { + protected: + // Delay to let browser complete a requested action. + static const int kWaitForActionMsec = 2000; + static const int kWaitForActionMaxMsec = 10000; + // Delay to let the browser complete the test. + static const int kMaxTestExecutionTime = 30000; + + // Tries to delete the specified file/directory returning true on success. + // This differs from file_util::Delete in that it repeatedly invokes Delete + // until successful, or a timeout is reached. Returns true on success. + static bool DieFileDie(const std::wstring& file, bool recurse); + + // Constructor + UITest(); + + // Starts the browser using the arguments in launch_arguments_, and + // sets up member variables. + virtual void SetUp(); + + // Closes the browser window. + virtual void TearDown(); + + // ********* Utility functions ********* + + // Launches the browser and IPC testing server. + void LaunchBrowserAndServer(); + + // Closes the browser and IPC testing server. + void CloseBrowserAndServer(); + + // Launches the browser with the given arguments. + void LaunchBrowser(const std::wstring& arguments, bool clear_profile); + + // Exits out browser instance. + void QuitBrowser(); + + // Tells the browser to navigate to the given URL in the active tab + // of the first app window. + // This method doesn't return until the navigation is complete. + void NavigateToURL(const GURL& url); + + // Returns the URL of the currently active tab. If there is no active tab, + // or some other error, the returned URL will be empty. + GURL GetActiveTabURL(); + + // Returns the title of the currently active tab. + std::wstring GetActiveTabTitle(); + + // Returns true when the browser process is running, independent if any + // renderer process exists or not. It will returns false if an user closed the + // window or if the browser process died by itself. + bool IsBrowserRunning(); + + // Returns true when time_out_ms milliseconds have elapsed. + // Returns false if the browser process died while waiting. + bool CrashAwareSleep(int time_out_ms); + + // Returns the number of tabs in the first window. If no windows exist, + // causes a test failure and returns 0. + int GetTabCount(); + + // Polls the tab for the cookie_name cookie and returns once one of the + // following conditions hold true: + // - The cookie is of expected_value. + // - The browser process died. + // - The time_out value has been exceeded. + bool WaitUntilCookieValue(TabProxy* tab, const GURL& url, + const char* cookie_name, + int interval_ms, + int time_out_ms, + const char* expected_value); + // Polls the tab for the cookie_name cookie and returns once one of the + // following conditions hold true: + // - The cookie is set to any value. + // - The browser process died. + // - The time_out value has been exceeded. + std::string WaitUntilCookieNonEmpty(TabProxy* tab, + const GURL& url, + const char* cookie_name, + int interval_ms, + int time_out_ms); + + // Polls up to kWaitForActionMaxMsec ms to attain a specific tab count. Will + // assert that the tab count is valid at the end of the wait. + void WaitUntilTabCount(int tab_count); + + // Checks whether the download shelf is visible in the current tab, giving it + // a chance to appear (we don't know the exact timing) while finishing as soon + // as possible. + bool WaitForDownloadShelfVisible(TabProxy* tab); + + // Closes the specified browser. Returns true if the browser was closed. + // This call is blocking. |application_closed| is set to true if this was + // the last browser window (and therefore as a result of it closing the + // browser process terminated). Note that in that case this method returns + // after the browser process has terminated. + bool CloseBrowser(BrowserProxy* browser, bool* application_closed) const; + + // Gets the directory for the currently active profile in the browser. + std::wstring GetDownloadDirectory(); + + // Get the handle of browser process connected to the automation. This + // function only retruns a reference to the handle so the caller does not + // own the handle returned. + HANDLE process() { return process_; } + + public: + // Get/Set a flag to run the renderer in process when running the + // tests. + static bool in_process_renderer() { return in_process_renderer_; } + static void set_in_process_renderer(bool value) { + in_process_renderer_ = value; + } + + // Get/Set a flag to run the plugins in the renderer process when running the + // tests. + static bool in_process_plugins() { return in_process_plugins_; } + static void set_in_process_plugins(bool value) { + in_process_plugins_ = value; + } + + // Get/Set a flag to run the renderer outside the sandbox when running the + // tests + static bool no_sandbox() { return no_sandbox_; } + static void set_no_sandbox(bool value) { + no_sandbox_ = value; + } + + // Get/Set a flag to run with DCHECKs enabled in release. + static bool enable_dcheck() { return enable_dcheck_; } + static void set_enable_dcheck(bool value) { + enable_dcheck_ = value; + } + + // Get/Set a flag to dump the process memory without crashing on DCHECKs. + static bool silent_dump_on_dcheck() { return silent_dump_on_dcheck_; } + static void set_silent_dump_on_dcheck(bool value) { + silent_dump_on_dcheck_ = value; + } + + // Get/Set a flag to run the plugin processes inside the sandbox when running + // the tests + static bool safe_plugins() { return safe_plugins_; } + static void set_safe_plugins(bool value) { + safe_plugins_ = value; + } + + static bool show_error_dialogs() { return show_error_dialogs_; } + static void set_show_error_dialogs(bool value) { + show_error_dialogs_ = value; + } + + static bool full_memory_dump() { return full_memory_dump_; } + static void set_full_memory_dump(bool value) { + full_memory_dump_ = value; + } + + static bool use_existing_browser() { return default_use_existing_browser_; } + static void set_use_existing_browser(bool value) { + default_use_existing_browser_ = value; + } + + static bool dump_histograms_on_exit() { return dump_histograms_on_exit_; } + static void set_dump_histograms_on_exit(bool value) { + dump_histograms_on_exit_ = value; + } + + static int test_timeout_ms() { return timeout_ms_; } + static void set_test_timeout_ms(int value) { + timeout_ms_ = value; + } + + // Called by some tests that wish to have a base profile to start from. This + // "user data directory" (containing one or more profiles) will be recursively + // copied into the user data directory for the test and the files will be + // evicted from the OS cache. To start with a blank profile, supply an empty + // string (the default). + std::wstring template_user_data() const { return template_user_data_; } + void set_template_user_data(const std::wstring& template_user_data) { + template_user_data_ = template_user_data; + } + + // Return the user data directory being used by the browser instance in + // UITest::SetUp(). + std::wstring user_data_dir() const { return user_data_dir_; } + + // Count the number of active browser processes. This function only counts + // browser processes that share the same profile directory as the current + // process. The count includes browser sub-processes. + static int GetBrowserProcessCount(); + + // Returns a copy of local state preferences. The caller is responsible for + // deleting the returned object. Returns NULL if there is an error. + DictionaryValue* GetLocalState(); + + // Returns a copy of the default profile preferences. The caller is + // responsible for deleting the returned object. Returns NULL if there is an + // error. + DictionaryValue* GetDefaultProfilePreferences(); + + private: + // Check that no processes related to Chrome exist, displaying + // the given message if any do. + void AssertAppNotRunning(const std::wstring& error_message); + + protected: + AutomationProxy* automation() { + EXPECT_TRUE(server_.get()); + return server_.get(); + } + + // Wait a certain amount of time for all the app processes to exit, + // forcibly killing them if they haven't exited by then. + // It has the side-effect of killing every browser window opened in your + // session, even those unrelated in the test. + void CleanupAppProcesses(); + + // Returns the proxy for the currently active tab, or NULL if there is no + // tab or there was some kind of error. The returned pointer MUST be + // deleted by the caller if non-NULL. + TabProxy* GetActiveTab(); + + // ********* Member variables ********* + + std::wstring browser_directory_; // Path to the browser executable, + // with no trailing slash + std::wstring test_data_directory_; // Path to the unit test data, + // with no trailing slash + std::wstring launch_arguments_; // Arguments to the browser on launch. + int expected_errors_; // The number of errors expected during + // the run (generally 0). + int expected_crashes_; // The number of crashes expected during + // the run (generally 0). + std::wstring homepage_; // Homepage used for testing. + bool wait_for_initial_loads_; // Wait for initial loads to complete + // in SetUp() before running test body. + TimeTicks browser_launch_time_; // Time when the browser was run. + bool dom_automation_enabled_; // This can be set to true to have the + // test run the dom automation case. + std::wstring template_user_data_; // See set_template_user_data(). + HANDLE process_; // Handle the the first Chrome process. + std::wstring user_data_dir_; // User data directory used for the test + static bool in_process_renderer_; // true if we're in single process mode + bool show_window_; // Determines if the window is shown or + // hidden. Defaults to hidden. + bool clear_profile_; // If true the profile is cleared before + // launching. Default is true. + bool include_testing_id_; // Should we supply the testing channel + // id on the command line? Default is + // true. + bool use_existing_browser_; // Duplicate of the static version. + // Default value comes from static. + + private: + FILETIME test_start_time_; // Time the test was started + // (so we can check for new crash dumps) + static bool in_process_plugins_; + static bool no_sandbox_; + static bool safe_plugins_; + static bool full_memory_dump_; // If true, write full memory dump + // during crash. + static bool show_error_dialogs_; // If true, a user is paying attention + // to the test, so show error dialogs. + static bool default_use_existing_browser_; // The test connects to an already + // running browser instance. + static bool dump_histograms_on_exit_; // Include histograms in log on exit. + static bool enable_dcheck_; // Enable dchecks in release mode. + static bool silent_dump_on_dcheck_; // Dump process memory on dcheck without + // crashing. + static int timeout_ms_; // Timeout in milliseconds to wait + // for an test to finish. + ::scoped_ptr<AutomationProxy> server_; +}; + +// These exist only to support the gTest assertion macros, and +// shouldn't be used in normal program code. +#ifdef UNIT_TEST +std::ostream& operator<<(std::ostream& out, const std::wstring& wstr); + +template<typename T> +std::ostream& operator<<(std::ostream& out, const ::scoped_ptr<T>& ptr) { + return out << ptr.get(); +} +#endif // UNIT_TEST + +#endif // CHROME_TEST_UI_UI_TEST_H__ diff --git a/chrome/test/ui/ui_test_suite.cc b/chrome/test/ui/ui_test_suite.cc new file mode 100644 index 0000000..408330a --- /dev/null +++ b/chrome/test/ui/ui_test_suite.cc @@ -0,0 +1,36 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "chrome/test/ui/ui_test_suite.h" + +// Force a test to use an already running browser instance. UI tests only. +const wchar_t UITestSuite::kUseExistingBrowser[] = L"use-existing-browser"; + +// Timeout for the test in milliseconds. UI tests only. +const wchar_t UITestSuite::kTestTimeout[] = L"test-timeout"; diff --git a/chrome/test/ui/ui_test_suite.h b/chrome/test/ui/ui_test_suite.h new file mode 100644 index 0000000..7631def --- /dev/null +++ b/chrome/test/ui/ui_test_suite.h @@ -0,0 +1,81 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CHROME_TEST_UI_UI_TEST_SUITE_H_ +#define CHROME_TEST_UI_UI_TEST_SUITE_H_ + +#include "chrome/test/ui/ui_test.h" +#include "chrome/test/unit/chrome_test_suite.h" + +class UITestSuite : public ChromeTestSuite { + public: + UITestSuite(int argc, char** argv) : ChromeTestSuite(argc, argv) { + } + + protected: + + virtual void Initialize() { + ChromeTestSuite::Initialize(); + + UITest::set_in_process_renderer( + parsed_command_line_.HasSwitch(switches::kSingleProcess)); + UITest::set_in_process_plugins( + parsed_command_line_.HasSwitch(switches::kInProcessPlugins)); + UITest::set_no_sandbox( + parsed_command_line_.HasSwitch(switches::kNoSandbox)); + UITest::set_full_memory_dump( + parsed_command_line_.HasSwitch(switches::kFullMemoryCrashReport)); + UITest::set_safe_plugins( + parsed_command_line_.HasSwitch(switches::kSafePlugins)); + UITest::set_use_existing_browser( + parsed_command_line_.HasSwitch(UITestSuite::kUseExistingBrowser)); + UITest::set_dump_histograms_on_exit( + parsed_command_line_.HasSwitch(switches::kDumpHistogramsOnExit)); + UITest::set_enable_dcheck( + parsed_command_line_.HasSwitch(switches::kEnableDCHECK)); + UITest::set_silent_dump_on_dcheck( + parsed_command_line_.HasSwitch(switches::kSilentDumpOnDCHECK)); + std::wstring test_timeout = + parsed_command_line_.GetSwitchValue(UITestSuite::kTestTimeout); + if (!test_timeout.empty()) { + UITest::set_test_timeout_ms(_wtoi(test_timeout.c_str())); + } + } + + virtual void SuppressErrorDialogs() { + TestSuite::SuppressErrorDialogs(); + UITest::set_show_error_dialogs(false); + } + + private: + static const wchar_t kUseExistingBrowser[]; + static const wchar_t kTestTimeout[]; +}; + +#endif // CHROME_TEST_UI_UI_TEST_SUITE_H_ diff --git a/chrome/test/ui/ui_tests.vcproj b/chrome/test/ui/ui_tests.vcproj new file mode 100644 index 0000000..4c9ffac --- /dev/null +++ b/chrome/test/ui/ui_tests.vcproj @@ -0,0 +1,528 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="ui_tests" + ProjectGUID="{76235B67-1C27-4627-8A33-4B2E1EF93EDE}" + RootNamespace="ui_tests" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + ConfigurationType="1" + InheritedPropertySheets="$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\build\debug.vsprops;..\..\tools\build\win\precompiled_wtl.vsprops;$(SolutionDir)..\third_party\libxml\build\using_libxml.vsprops;$(SolutionDir)..\third_party\libxslt\build\using_libxslt.vsprops;..\..\tools\build\win\unit_test.vsprops;..\..\tools\build\win\ui_test.vsprops;..\..\tools\build\win\test_memory_usage.vsprops;$(SolutionDir)..\skia\using_skia.vsprops;$(SolutionDir)..\third_party\icu38\build\using_icu.vsprops;$(SolutionDir)\tools\build\win\js_engine.vsprops;$(SolutionDir)..\testing\using_gtest.vsprops" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories=""$(OutDir)\obj\generated_resources"" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + ConfigurationType="1" + InheritedPropertySheets="$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\build\release.vsprops;$(SolutionDir)..\third_party\libxml\build\using_libxml.vsprops;$(SolutionDir)..\third_party\libxslt\build\using_libxslt.vsprops;..\..\tools\build\win\unit_test.vsprops;..\..\tools\build\win\ui_test.vsprops;$(SolutionDir)..\skia\using_skia.vsprops;$(SolutionDir)..\third_party\icu38\build\using_icu.vsprops;$(SolutionDir)\tools\build\win\js_engine.vsprops;$(SolutionDir)..\testing\using_gtest.vsprops" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories=""$(OutDir)\obj\generated_resources"" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Common" + > + <File + RelativePath="..\..\tools\build\win\precompiled_wtl.cc" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\..\tools\build\win\precompiled_wtl.h" + > + </File> + <File + RelativePath=".\run_all_unittests.cc" + > + </File> + <File + RelativePath="..\test_file_util.cc" + > + </File> + <File + RelativePath="..\testing_browser_process.h" + > + </File> + <File + RelativePath=".\ui_test.cc" + > + </File> + <File + RelativePath=".\ui_test.h" + > + </File> + <File + RelativePath=".\ui_test_suite.cc" + > + </File> + <File + RelativePath=".\ui_test_suite.h" + > + </File> + <File + RelativePath="..\..\..\net\url_request\url_request_test_job.cc" + > + </File> + <File + RelativePath="..\..\..\net\url_request\url_request_test_job.h" + > + </File> + </Filter> + <Filter + Name="TestChromeMain" + > + <File + RelativePath="..\..\app\chrome_main_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestErrorPage" + > + <File + RelativePath="..\..\browser\errorpage_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestBrowser" + > + <File + RelativePath="..\..\browser\browser_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestChromeLogging" + > + <File + RelativePath="..\..\common\logging_chrome_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestDownload" + > + <File + RelativePath="..\..\browser\download_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestImages" + > + <File + RelativePath="..\..\browser\images_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestIFrame" + > + <File + RelativePath="..\..\browser\iframe_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestCache" + > + <File + RelativePath="..\..\common\net\cache_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestSanity" + > + <File + RelativePath="..\..\browser\sanity_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestAutomationProxy" + > + <File + RelativePath="..\automation\automation_proxy_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestNPAPI" + > + <File + RelativePath=".\layout_plugin_uitest.cpp" + > + </File> + <File + RelativePath=".\npapi_uitest.cpp" + > + </File> + </Filter> + <Filter + Name="TestSessionHistory" + > + <File + RelativePath="..\..\browser\session_history_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestSessionRestore" + > + <File + RelativePath="..\..\browser\session_restore_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestTabRestore" + > + <File + RelativePath="..\..\browser\tab_restore_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestAuthentication" + > + <File + RelativePath="..\..\browser\login_prompt_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestPreferences" + > + <File + RelativePath="..\..\common\pref_service_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestViewSource" + > + <File + RelativePath="..\..\browser\view_source_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestRedirects" + > + <File + RelativePath="..\..\browser\history\redirect_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestResourceDispatcherHost" + > + <File + RelativePath="..\..\browser\resource_dispatcher_host_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestFindInPage" + > + <File + RelativePath="..\..\browser\find_in_page_controller_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestPageLoader" + > + <File + RelativePath="..\perf\mem_usage.cc" + > + </File> + <File + RelativePath="..\perf\mem_usage.h" + > + </File> + <File + RelativePath="..\reliability\page_load_test.cc" + > + </File> + <File + RelativePath="..\reliability\page_load_test.h" + > + </File> + </Filter> + <Filter + Name="TestSandbox" + > + <File + RelativePath=".\sandbox_uitests.cc" + > + </File> + </Filter> + <Filter + Name="TestInspector" + > + <File + RelativePath=".\inspector_controller_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestLocalizedBuilds" + > + <File + RelativePath="..\..\browser\locale_tests_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestMetricsService" + > + <File + RelativePath="..\..\browser\metrics_service_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestInterstitialPage" + > + <File + RelativePath="..\..\browser\interstitial_page_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestSSL" + > + <File + RelativePath="..\..\browser\ssl_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestAccessibility" + > + <File + RelativePath="..\accessibility\accessibility_tests.cc" + > + </File> + <Filter + Name="Accessibility Client" + > + <File + RelativePath="..\accessibility\accessibility_util.cc" + > + </File> + <File + RelativePath="..\accessibility\accessibility_util.h" + > + </File> + <File + RelativePath="..\accessibility\browser_impl.cc" + > + </File> + <File + RelativePath="..\accessibility\browser_impl.h" + > + </File> + <File + RelativePath="..\accessibility\constants.h" + > + </File> + <File + RelativePath="..\accessibility\keyboard_util.cc" + > + </File> + <File + RelativePath="..\accessibility\keyboard_util.h" + > + </File> + <File + RelativePath="..\accessibility\registry_util.cc" + > + </File> + <File + RelativePath="..\accessibility\registry_util.h" + > + </File> + <File + RelativePath="..\accessibility\tab_impl.cc" + > + </File> + <File + RelativePath="..\accessibility\tab_impl.h" + > + </File> + </Filter> + </Filter> + <Filter + Name="TestCrashRecovery" + > + <File + RelativePath="..\..\browser\crash_recovery_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestPrinting" + > + <File + RelativePath="..\..\browser\printing\printing_layout_uitest.cc" + > + </File> + <File + RelativePath="..\..\browser\printing\printing_test.h" + > + </File> + </Filter> + <Filter + Name="TestSavePage" + > + <File + RelativePath="..\..\browser\save_page_uitest.cc" + > + </File> + </Filter> + <Filter + Name="TestOmnibox" + > + <File + RelativePath=".\omnibox_uitest.cc" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> |