diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
commit | 09911bf300f1a419907a9412154760efd0b7abc3 (patch) | |
tree | f131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/test/automated_ui_tests | |
parent | 586acc5fe142f498261f52c66862fa417c3d52d2 (diff) | |
download | chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2 |
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test/automated_ui_tests')
-rw-r--r-- | chrome/test/automated_ui_tests/automated_ui_tests.cc | 887 | ||||
-rw-r--r-- | chrome/test/automated_ui_tests/automated_ui_tests.h | 443 | ||||
-rw-r--r-- | chrome/test/automated_ui_tests/automated_ui_tests.vcproj | 212 |
3 files changed, 1542 insertions, 0 deletions
diff --git a/chrome/test/automated_ui_tests/automated_ui_tests.cc b/chrome/test/automated_ui_tests/automated_ui_tests.cc new file mode 100644 index 0000000..0129e81 --- /dev/null +++ b/chrome/test/automated_ui_tests/automated_ui_tests.cc @@ -0,0 +1,887 @@ +// 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 <fstream> + +#include "base/command_line.h" +#include "base/file_util.h" +#include "base/path_service.h" +#include "base/string_util.h" +#include "chrome/app/chrome_dll_resource.h" +#include "chrome/browser/view_ids.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/libxml_utils.h" +#include "chrome/common/rand_util.h" +#include "chrome/common/win_util.h" +#include "chrome/test/automated_ui_tests/automated_ui_tests.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/ui/ui_test.h" +#include "chrome/views/view.h" +#include "googleurl/src/gurl.h" + +namespace { + +const wchar_t* const kReproSwitch = L"key"; + +const wchar_t* const kReproRepeatSwitch = L"num-reproductions"; + +const wchar_t* const kInputFilePathSwitch = L"input"; + +const wchar_t* const kOutputFilePathSwitch = L"output"; + +const wchar_t* const kDebugModeSwitch = L"debug"; + +const wchar_t* const kDefaultInputFilePath = L"C:\\automated_ui_tests.txt"; + +const wchar_t* const kDefaultOutputFilePath + = L"C:\\automated_ui_tests_error_report.txt"; + +const int kDebuggingTimeoutMsec = 5000; + +// How many commands to run when testing a dialog box. +const int kTestDialogActionsToRun = 7; + +} // namespace + +// This subset of commands is used to test dialog boxes, which aren't likely +// to respond to most other commands. +std::string AutomatedUITest::test_dialog_possible_actions_[] = { + "PressTabKey", + "PressEnterKey", + "PressSpaceBar", + "DownArrow" +}; + +AutomatedUITest::AutomatedUITest() + : total_crashes_(0), + debug_logging_enabled_(false) { + show_window_ = true; + GetSystemTimeAsFileTime(&test_start_time_); + CommandLine parsed_command_line; + if (parsed_command_line.HasSwitch(kDebugModeSwitch)) + debug_logging_enabled_ = true; +} + +AutomatedUITest::~AutomatedUITest() {} + +void AutomatedUITest::RunReproduction() { + CommandLine parsed_command_line; + xml_writer_.StartWriting(); + xml_writer_.StartElement("Report"); + std::string action_string = + WideToASCII(parsed_command_line.GetSwitchValue(kReproSwitch)); + + int64 num_reproductions = 1; + if (parsed_command_line.HasSwitch(kReproRepeatSwitch)) { + std::wstring num_reproductions_string = + parsed_command_line.GetSwitchValue(kReproRepeatSwitch); + std::string test = WideToASCII(num_reproductions_string); + num_reproductions = StringToInt64(num_reproductions_string); + } + std::vector<std::string> actions; + SplitString(action_string, L',', &actions); + bool did_crash = false; + bool command_complete = false; + + for (int64 i = 0; i < num_reproductions && !did_crash; ++i) { + bool did_teardown = false; + xml_writer_.StartElement("Executed"); + for (size_t j = 0; j < actions.size(); ++j) { + DoAction(actions[j]); + if (DidCrash(true)) { + did_crash = true; + if (j >= (actions.size() - 1)) + command_complete = true; + break; + } + if (LowerCaseEqualsASCII(actions[j], "teardown")) + did_teardown = true; + } + + // Force proper teardown after each run, if it didn't already happen. But + // don't teardown after crashes. + if (!did_teardown && !did_crash) + DoAction("TearDown"); + + xml_writer_.EndElement(); // End "Executed" element. + } + + if (did_crash) { + std::string crash_dump = WideToASCII(GetMostRecentCrashDump()); + std::string result = + "*** Crash dump produced. See result file for more details. Dump = "; + result.append(crash_dump); + result.append(" ***\n"); + printf("%s", result.c_str()); + LogCrashResult(crash_dump, command_complete); + EXPECT_TRUE(false) << "Crash detected."; + } else { + printf("*** No crashes. See result file for more details. ***\n"); + LogSuccessResult(); + } + + WriteReportToFile(); +} + + +void AutomatedUITest::RunAutomatedUITest() { + ASSERT_TRUE(InitXMLReader()) << "Error initializing XMLReader"; + xml_writer_.StartWriting(); + xml_writer_.StartElement("Report"); + + while (init_reader_.Read()) { + init_reader_.SkipToElement(); + std::string node_name = init_reader_.NodeName(); + if (LowerCaseEqualsASCII(node_name, "command")) { + bool no_errors = true; + xml_writer_.StartElement("Executed"); + std::string command_number; + if (init_reader_.NodeAttribute("number", &command_number)) { + xml_writer_.AddAttribute("command_number", command_number); + } + xml_writer_.StopIndenting(); + + // Starts the browser, logging it as an action. + DoAction("SetUp"); + + // Record the depth of the root of the command subtree, then advance to + // the first element in preperation for parsing. + int start_depth = init_reader_.Depth(); + ASSERT_TRUE(init_reader_.Read()) << "Malformed XML file."; + init_reader_.SkipToElement(); + + // Check for a crash right after startup. + if (DidCrash(true)) { + LogCrashResult(WideToASCII(GetMostRecentCrashDump()), false); + // Try and start up again. + CloseBrowserAndServer(); + LaunchBrowserAndServer(); + if (DidCrash(true)) { + no_errors = false; + // We crashed again, so skip to the end of the this command. + while (init_reader_.Depth() != start_depth) { + ASSERT_TRUE(init_reader_.Read()) << "Malformed XML file."; + } + } else { + // We didn't crash, so end the old element, logging a crash for that. + // Then start a new element to log this command. + xml_writer_.StartIndenting(); + xml_writer_.EndElement(); + xml_writer_.StartElement("Executed"); + xml_writer_.AddAttribute("command_number", command_number); + xml_writer_.StopIndenting(); + xml_writer_.StartElement("SetUp"); + xml_writer_.EndElement(); + } + } + // Parse the command, performing the specified actions and checking + // for a crash after each one. + while (init_reader_.Depth() != start_depth) { + node_name = init_reader_.NodeName(); + + DoAction(node_name); + + // Advance to the next element + ASSERT_TRUE(init_reader_.Read()) << "Malformed XML file."; + init_reader_.SkipToElement(); + if (DidCrash(true)) { + no_errors = false; + // This was the last action if we've returned to the initial depth + // of the command subtree. + bool wasLastAction = init_reader_.Depth() == start_depth; + LogCrashResult(WideToASCII(GetMostRecentCrashDump()), wasLastAction); + // Skip to the beginning of the next command. + while (init_reader_.Depth() != start_depth) { + ASSERT_TRUE(init_reader_.Read()) << "Malformed XML file."; + } + } + } + + if (no_errors) { + // If there were no previous crashes, log our tear down and check for + // a crash, log success for the entire command if this doesn't crash. + DoAction("TearDown"); + if (DidCrash(true)) + LogCrashResult(WideToASCII(GetMostRecentCrashDump()), true); + else + LogSuccessResult(); + } else { + // If there was a previous crash, just tear down without logging, so + // that we know what the last command was before we crashed. + CloseBrowserAndServer(); + } + + xml_writer_.StartIndenting(); + xml_writer_.EndElement(); // End "Executed" element. + } + } + // The test is finished so write our report. + WriteReportToFile(); +} + +bool AutomatedUITest::DoAction(const std::string & action) { + bool did_complete_action = false; + xml_writer_.StartElement(action); + if (debug_logging_enabled_) + AppendToOutputFile(action); + + if (LowerCaseEqualsASCII(action, "navigate")) { + did_complete_action = Navigate(); + } else if (LowerCaseEqualsASCII(action, "newtab")) { + did_complete_action = NewTab(); + } else if (LowerCaseEqualsASCII(action, "back")) { + did_complete_action = BackButton(); + } else if (LowerCaseEqualsASCII(action, "forward")) { + did_complete_action = ForwardButton(); + } else if (LowerCaseEqualsASCII(action, "closetab")) { + did_complete_action = CloseActiveTab(); + } else if (LowerCaseEqualsASCII(action, "openwindow")) { + did_complete_action = OpenAndActivateNewBrowserWindow(); + } else if (LowerCaseEqualsASCII(action, "reload")) { + did_complete_action = ReloadPage(); + } else if (LowerCaseEqualsASCII(action, "star")) { + did_complete_action = StarPage(); + } else if (LowerCaseEqualsASCII(action, "findinpage")) { + did_complete_action = FindInPage(); + } else if (LowerCaseEqualsASCII(action, "selectnexttab")) { + did_complete_action = SelectNextTab(); + } else if (LowerCaseEqualsASCII(action, "selectprevtab")) { + did_complete_action = SelectPreviousTab(); + } else if (LowerCaseEqualsASCII(action, "zoomplus")) { + did_complete_action = ZoomPlus(); + } else if (LowerCaseEqualsASCII(action, "zoomminus")) { + did_complete_action = ZoomMinus(); + } else if (LowerCaseEqualsASCII(action, "history")) { + did_complete_action = ShowHistory(); + } else if (LowerCaseEqualsASCII(action, "downloads")) { + did_complete_action = ShowDownloads(); + } else if (LowerCaseEqualsASCII(action, "importsettings")) { + did_complete_action = ImportSettings(); + } else if (LowerCaseEqualsASCII(action, "viewpasswords")) { + did_complete_action = ViewPasswords(); + } else if (LowerCaseEqualsASCII(action, "clearbrowserdata")) { + did_complete_action = ClearBrowserData(); + } else if (LowerCaseEqualsASCII(action, "taskmanager")) { + did_complete_action = TaskManager(); + } else if (LowerCaseEqualsASCII(action, "goofftherecord")) { + did_complete_action = GoOffTheRecord(); + } else if (LowerCaseEqualsASCII(action, "pressescapekey")) { + did_complete_action = PressEscapeKey(); + } else if (LowerCaseEqualsASCII(action, "presstabkey")) { + did_complete_action = PressTabKey(); + } else if (LowerCaseEqualsASCII(action, "pressenterkey")) { + did_complete_action = PressEnterKey(); + } else if (LowerCaseEqualsASCII(action, "pressspacebar")) { + did_complete_action = PressSpaceBar(); + } else if (LowerCaseEqualsASCII(action, "pagedown")) { + did_complete_action = PageDown(); + } else if (LowerCaseEqualsASCII(action, "pageup")) { + did_complete_action = PageUp(); + } else if (LowerCaseEqualsASCII(action, "dragtabright")) { + did_complete_action = DragActiveTab(true, false); + } else if (LowerCaseEqualsASCII(action, "dragtableft")) { + did_complete_action = DragActiveTab(false, false); + } else if (LowerCaseEqualsASCII(action, "dragtabout")) { + did_complete_action = DragActiveTab(false, true); + } else if (LowerCaseEqualsASCII(action, "uparrow")) { + did_complete_action = UpArrow(); + } else if (LowerCaseEqualsASCII(action, "downarrow")) { + did_complete_action = DownArrow(); + } else if (LowerCaseEqualsASCII(action, "testeditkeywords")) { + did_complete_action = TestEditKeywords(); + } else if (LowerCaseEqualsASCII(action, "testtaskmanager")) { + did_complete_action = TestTaskManager(); + } else if (LowerCaseEqualsASCII(action, "testviewpasswords")) { + did_complete_action = TestViewPasswords(); + } else if (LowerCaseEqualsASCII(action, "testclearbrowserdata")) { + did_complete_action = TestClearBrowserData(); + } else if (LowerCaseEqualsASCII(action, "testimportsettings")) { + did_complete_action = TestImportSettings(); + } else if (LowerCaseEqualsASCII(action, "crash")) { + did_complete_action = ForceCrash(); + } else if (LowerCaseEqualsASCII(action, "sleep")) { + // This is for debugging, it probably shouldn't be used real tests. + Sleep(kDebuggingTimeoutMsec); + did_complete_action = true; + } else if (LowerCaseEqualsASCII(action, "setup")) { + LaunchBrowserAndServer(); + did_complete_action = true; + } else if (LowerCaseEqualsASCII(action, "teardown")) { + CloseBrowserAndServer(); + did_complete_action = true; + } + + if (!did_complete_action) + xml_writer_.AddAttribute("failed_to_complete", "yes"); + xml_writer_.EndElement(); + + return did_complete_action; +} + +bool AutomatedUITest::Navigate() { + scoped_ptr<BrowserProxy> browser(automation()->GetLastActiveBrowserWindow()); + if (browser.get() == NULL) { + AddErrorAttribute("browser_window_not_found"); + return false; + } + bool did_timeout; + scoped_ptr<TabProxy> tab( + browser->GetActiveTabWithTimeout(kWaitForActionMaxMsec, &did_timeout)); + // TODO(devint): This might be masking a bug. I can't think of many + // valid cases where we would get a browser window, but not be able + // to return an active tab. Yet this has happened and has triggered crashes. + // Investigate this. + if (tab.get() == NULL) { + AddErrorAttribute("active_tab_not_found"); + return false; + } + std::string url = "about:blank"; + if (init_reader_.NodeAttribute("url", &url)) { + xml_writer_.AddAttribute("url", url); + } + GURL test_url(url); + did_timeout = false; + tab->NavigateToURLWithTimeout(test_url, kMaxTestExecutionTime, &did_timeout); + + if (did_timeout) { + AddWarningAttribute("timeout"); + return false; + } + return true; +} + +bool AutomatedUITest::NewTab() { + scoped_ptr<BrowserProxy> browser(automation()->GetLastActiveBrowserWindow()); + if (browser.get() == NULL) { + AddErrorAttribute("browser_window_not_found"); + return false; + } + int old_tab_count; + int new_tab_count; + bool is_timeout; + browser->GetTabCountWithTimeout(&old_tab_count, kWaitForActionMaxMsec, + &is_timeout); + // Apply accelerator and wait for a new tab to open, if either + // fails, return false. Apply Accelerator takes care of logging its failure. + bool return_value = ApplyAccelerator(IDC_NEWTAB); + if (!browser->WaitForTabCountToChange( + old_tab_count, &new_tab_count, kWaitForActionMaxMsec)) { + AddWarningAttribute("tab_count_failed_to_change"); + return false; + } + return return_value; +} + +bool AutomatedUITest::BackButton() { + return ApplyAccelerator(IDC_BACK); +} + +bool AutomatedUITest::ForwardButton() { + return ApplyAccelerator(IDC_FORWARD); +} + +bool AutomatedUITest::CloseActiveTab() { + bool return_value = false; + scoped_ptr<BrowserProxy> browser(automation()->GetLastActiveBrowserWindow()); + if (browser.get() == NULL) { + AddErrorAttribute("browser_window_not_found"); + return false; + } + int browser_windows_count; + int tab_count; + bool is_timeout; + browser->GetTabCountWithTimeout(&tab_count, kWaitForActionMaxMsec, + &is_timeout); + automation()->GetBrowserWindowCount(&browser_windows_count); + // Avoid quitting the application by not closing the last window. + if (tab_count > 1) { + int new_tab_count; + return_value = browser->ApplyAccelerator(IDC_CLOSETAB); + // Wait for the tab to close before we continue. + if (!browser->WaitForTabCountToChange( + tab_count, &new_tab_count, kWaitForActionMaxMsec)) { + AddWarningAttribute("tab_count_failed_to_change"); + return false; + } + } else if (tab_count == 1 && browser_windows_count > 1) { + int new_window_count; + return_value = browser->ApplyAccelerator(IDC_CLOSETAB); + // Wait for the window to close before we continue. + if (!automation()->WaitForWindowCountToChange( + browser_windows_count, &new_window_count, kWaitForActionMaxMsec)) { + AddWarningAttribute("window_count_failed_to_change"); + return false; + } + } else { + AddInfoAttribute("would_have_exited_application"); + return false; + } + return return_value; +} + +bool AutomatedUITest::OpenAndActivateNewBrowserWindow() { + if (!automation()->OpenNewBrowserWindow(SW_SHOWNORMAL)) { + AddWarningAttribute("failed_to_open_new_browser_window"); + return false; + } + int num_browser_windows; + automation()->GetBrowserWindowCount(&num_browser_windows); + // Get the most recently opened browser window and activate the tab + // in order to activate this browser window. + scoped_ptr<BrowserProxy> browser( + automation()->GetBrowserWindow(num_browser_windows - 1)); + if (browser.get() == NULL) { + AddErrorAttribute("browser_window_not_found"); + return false; + } + bool is_timeout; + if (!browser->ActivateTabWithTimeout(0, kWaitForActionMaxMsec, + &is_timeout)) { + AddWarningAttribute("failed_to_activate_tab"); + return false; + } + return true; +} + +bool AutomatedUITest::ReloadPage() { + return ApplyAccelerator(IDC_RELOAD); +} + +bool AutomatedUITest::StarPage() { + return ApplyAccelerator(IDC_STAR); +} + +bool AutomatedUITest::FindInPage() { + return ApplyAccelerator(IDC_FIND); +} + +bool AutomatedUITest::SelectNextTab() { + return ApplyAccelerator(IDC_SELECT_NEXT_TAB); +} + +bool AutomatedUITest::SelectPreviousTab() { + return ApplyAccelerator(IDC_SELECT_PREV_TAB); +} + +bool AutomatedUITest::ZoomPlus() { + return ApplyAccelerator(IDC_ZOOM_PLUS); +} + +bool AutomatedUITest::ZoomMinus() { + return ApplyAccelerator(IDC_ZOOM_MINUS); +} + +bool AutomatedUITest::ShowHistory() { + return ApplyAccelerator(IDC_SHOW_HISTORY); +} + +bool AutomatedUITest::ShowDownloads() { + return ApplyAccelerator(IDC_SHOW_DOWNLOADS); +} + +bool AutomatedUITest::ImportSettings() { + return ApplyAccelerator(IDC_IMPORT_SETTINGS); +} + +bool AutomatedUITest::ViewPasswords() { + return ApplyAccelerator(IDC_VIEW_PASSWORDS); +} + +bool AutomatedUITest::ClearBrowserData() { + return ApplyAccelerator(IDC_CLEAR_BROWSING_DATA); +} + +bool AutomatedUITest::TaskManager() { + return ApplyAccelerator(IDC_TASKMANAGER); +} + +bool AutomatedUITest::GoOffTheRecord() { + return ApplyAccelerator(IDC_GOOFFTHERECORD); +} + +bool AutomatedUITest::PressEscapeKey() { + return SimulateKeyPressInActiveWindow(VK_ESCAPE, 0); +} + +bool AutomatedUITest::PressTabKey() { + return SimulateKeyPressInActiveWindow(VK_TAB, 0); +} + +bool AutomatedUITest::PressEnterKey() { + return SimulateKeyPressInActiveWindow(VK_RETURN, 0); +} + +bool AutomatedUITest::PressSpaceBar() { + return SimulateKeyPressInActiveWindow(VK_SPACE, 0); +} + +bool AutomatedUITest::PageDown() { + return SimulateKeyPressInActiveWindow(VK_PRIOR, 0); +} + + +bool AutomatedUITest::PageUp() { + return SimulateKeyPressInActiveWindow(VK_NEXT, 0); +} + +bool AutomatedUITest::UpArrow() { + return SimulateKeyPressInActiveWindow(VK_UP, 0); +} + +bool AutomatedUITest::DownArrow() { + return SimulateKeyPressInActiveWindow(VK_DOWN, 0); +} + +bool AutomatedUITest::TestEditKeywords() { + DoAction("EditKeywords"); + return TestDialog(kTestDialogActionsToRun); +} + +bool AutomatedUITest::TestTaskManager() { + DoAction("TaskManager"); + return TestDialog(kTestDialogActionsToRun); +} + +bool AutomatedUITest::TestViewPasswords() { + DoAction("ViewPasswords"); + return TestDialog(kTestDialogActionsToRun); +} + +bool AutomatedUITest::TestClearBrowserData() { + DoAction("ClearBrowserData"); + return TestDialog(kTestDialogActionsToRun); +} + +bool AutomatedUITest::TestImportSettings() { + DoAction("ImportSettings"); + return TestDialog(kTestDialogActionsToRun); +} + +bool AutomatedUITest::TestDialog(int num_actions) { + bool return_value = true; + + for (int i = 0; i < num_actions; i++) { + int action_index = rand_util::RandInt(0, kNumTestDialogActions - 1); + return_value = return_value && + DoAction(test_dialog_possible_actions_[action_index]); + if (DidCrash(false)) + break; + } + return DoAction("PressEscapeKey") && return_value; +} + +bool AutomatedUITest::ForceCrash() { + scoped_ptr<BrowserProxy> browser(automation()->GetLastActiveBrowserWindow()); + if (browser.get() == NULL) { + AddErrorAttribute("browser_window_not_found"); + return false; + } + scoped_ptr<TabProxy> tab(browser->GetActiveTab()); + GURL test_url("about:crash"); + bool did_timeout; + tab->NavigateToURLWithTimeout(test_url, kDebuggingTimeoutMsec, &did_timeout); + if (!did_timeout) { + AddInfoAttribute("expected_crash"); + return false; + } + return true; +} + +bool AutomatedUITest::DragActiveTab(bool drag_right, bool drag_out) { + scoped_ptr<BrowserProxy> browser(automation()->GetLastActiveBrowserWindow()); + scoped_ptr<WindowProxy> window( + GetAndActivateWindowForBrowser(browser.get())); + if (window.get() == NULL) { + AddErrorAttribute("active_window_not_found"); + return false; + } + bool is_timeout; + + if (browser.get() == NULL) { + AddErrorAttribute("browser_window_not_found"); + return false; + } + int tab_count; + browser->GetTabCountWithTimeout(&tab_count, kWaitForActionMaxMsec, + &is_timeout); + // As far as we're concerned, if we can't get a view for a tab, it doesn't + // exist, so cap tab_count at the number of tab view ids there are. + tab_count = std::min(tab_count, VIEW_ID_TAB_LAST - VIEW_ID_TAB_0); + + int tab_index; + if (!browser->GetActiveTabIndexWithTimeout(&tab_index, + kWaitForActionMaxMsec, + &is_timeout)) { + AddWarningAttribute("no_active_tab"); + return false; + } + + gfx::Rect dragged_tab_bounds; + if (!window->GetViewBoundsWithTimeout(VIEW_ID_TAB_0 + tab_index, + &dragged_tab_bounds, false, + kWaitForActionMaxMsec, + &is_timeout)) { + AddWarningAttribute("no_tab_view_found"); + return false; + } + + // Click on the center of the tab, and drag it to the left or the right. + POINT dragged_tab_point(dragged_tab_bounds.CenterPoint().ToPOINT()); + POINT destination_point(dragged_tab_point); + + int window_count; + if (drag_out) { + destination_point.y += 3*dragged_tab_bounds.height(); + automation()->GetBrowserWindowCount(&window_count); + } else if (drag_right) { + if (tab_index >= (tab_count-1)) { + AddInfoAttribute("index_cant_be_moved"); + return false; + } + destination_point.x += 2*dragged_tab_bounds.width()/3; + } else { + if (tab_index <= 0) { + AddInfoAttribute("index_cant_be_moved"); + return false; + } + destination_point.x -= 2*dragged_tab_bounds.width()/3; + } + + if (!browser->SimulateDragWithTimeout(dragged_tab_point, + destination_point, + ChromeViews::Event::EF_LEFT_BUTTON_DOWN, + kWaitForActionMaxMsec, + &is_timeout)) { + AddWarningAttribute("failed_to_simulate_drag"); + return false; + } + + // If we try to drag the tab out and the window we drag from contains more + // than just the dragged tab, we would expect the window count to increase + // because the dragged tab should open in a new window. If not, we probably + // just dragged into another tabstrip. + if (drag_out && tab_count > 1) { + int new_window_count; + automation()->GetBrowserWindowCount(&new_window_count); + if (new_window_count == window_count) { + AddInfoAttribute("no_new_browser_window"); + return false; + } + } + return true; +} + +WindowProxy* AutomatedUITest::GetAndActivateWindowForBrowser( + BrowserProxy* browser) { + WindowProxy* window = automation()->GetWindowForBrowser(browser); + + bool did_timeout; + if (!browser->BringToFrontWithTimeout(kWaitForActionMaxMsec, &did_timeout)) { + AddWarningAttribute("failed_to_bring_window_to_front"); + return NULL; + } + return window; +} + +bool AutomatedUITest::ApplyAccelerator(int id) { + scoped_ptr<BrowserProxy> browser(automation()->GetLastActiveBrowserWindow()); + if (browser.get() == NULL) { + AddErrorAttribute("browser_window_not_found"); + return false; + } + if (!browser->ApplyAccelerator(id)) { + AddWarningAttribute("failure_applying_accelerator"); + return false; + } + return true; +} + +bool AutomatedUITest::SimulateKeyPressInActiveWindow(wchar_t key, int flags) { + scoped_ptr<BrowserProxy> browser(automation()->GetLastActiveBrowserWindow()); + scoped_ptr<WindowProxy> window( + GetAndActivateWindowForBrowser(browser.get())); + if (window.get() == NULL) { + AddErrorAttribute("active_window_not_found"); + return false; + } + if (!window->SimulateOSKeyPress(key, flags)) { + AddWarningAttribute("failure_simulating_key_press"); + return false; + } + return true; +} + +bool AutomatedUITest::InitXMLReader() { + std::wstring input_path; + CommandLine parsed_command_line; + if (parsed_command_line.HasSwitch(kInputFilePathSwitch)) + input_path = parsed_command_line.GetSwitchValue(kInputFilePathSwitch); + else + input_path = kDefaultInputFilePath; + + if (!file_util::ReadFileToString(input_path, &xml_init_file_)) + return false; + return init_reader_.Load(xml_init_file_); +} + +bool AutomatedUITest::WriteReportToFile() { + std::ofstream error_file; + std::wstring path; + CommandLine parsed_command_line; + if (parsed_command_line.HasSwitch(kOutputFilePathSwitch)) + path = parsed_command_line.GetSwitchValue(kOutputFilePathSwitch); + else + path = kDefaultOutputFilePath; + + if (!path.empty()) + error_file.open(path.c_str(), std::ios::out); + + // Closes all open elements and free the writer. This is required + // in order to retrieve the contents of the buffer. + xml_writer_.StopWriting(); + error_file << xml_writer_.GetWrittenString(); + error_file.close(); + return true; +} + +void AutomatedUITest::AppendToOutputFile(const std::string &append_string) { + std::ofstream error_file; + std::wstring path; + CommandLine parsed_command_line; + if (parsed_command_line.HasSwitch(kOutputFilePathSwitch)) + path = parsed_command_line.GetSwitchValue(kOutputFilePathSwitch); + else + path = kDefaultOutputFilePath; + + if (!path.empty()) + error_file.open(path.c_str(), std::ios::out | std::ios_base::app); + + error_file << append_string << " "; + error_file.close(); +} + +void AutomatedUITest::LogCrashResult(const std::string &crash_dump, + bool command_completed) { + xml_writer_.StartElement("result"); + xml_writer_.StartElement("crash"); + xml_writer_.AddAttribute("crash_dump", crash_dump); + if (command_completed) + xml_writer_.AddAttribute("command_completed", "yes"); + else + xml_writer_.AddAttribute("command_completed", "no"); + xml_writer_.EndElement(); + xml_writer_.EndElement(); +} + +void AutomatedUITest::LogSuccessResult() { + xml_writer_.StartElement("result"); + xml_writer_.StartElement("success"); + xml_writer_.EndElement(); + xml_writer_.EndElement(); +} + +void AutomatedUITest::AddInfoAttribute(const std::string &info) { + xml_writer_.AddAttribute("info", info); +} + +void AutomatedUITest::AddWarningAttribute(const std::string &warning) { + xml_writer_.AddAttribute("warning", warning); +} + +void AutomatedUITest::AddErrorAttribute(const std::string &error) { + xml_writer_.AddAttribute("error", error); +} + +std::wstring AutomatedUITest::GetMostRecentCrashDump() { + std::wstring crash_dump_path; + int file_count = 0; + FILETIME most_recent_file_time; + std::wstring most_recent_file_name; + WIN32_FIND_DATA find_file_data; + + PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dump_path); + // All files in the given directory. + std::wstring filename_spec = crash_dump_path + L"\\*"; + HANDLE find_handle = FindFirstFile(filename_spec.c_str(), &find_file_data); + if (find_handle != INVALID_HANDLE_VALUE) { + most_recent_file_time = find_file_data.ftCreationTime; + most_recent_file_name = find_file_data.cFileName; + do { + // Don't count current or parent directories. + if ((wcscmp(find_file_data.cFileName, L"..") == 0) || + (wcscmp(find_file_data.cFileName, L".") == 0)) + continue; + + long result = CompareFileTime(&find_file_data.ftCreationTime, + &most_recent_file_time); + + // File was created on or after the current most recent file. + if ((result == 1) || (result == 0)) { + most_recent_file_time = find_file_data.ftCreationTime; + most_recent_file_name = find_file_data.cFileName; + } + } while (FindNextFile(find_handle, &find_file_data)); + FindClose(find_handle); + } + + if (most_recent_file_name.empty()) { + return L""; + } else { + file_util::AppendToPath(&crash_dump_path, most_recent_file_name); + return crash_dump_path; + } +} + +bool AutomatedUITest::DidCrash(bool update_total_crashes) { + 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; + + // If there are more crash dumps than the total dumps which we have recorded + // then this is a new crash. + if (actual_crashes > total_crashes_) { + if (update_total_crashes) + total_crashes_ = actual_crashes; + return true; + } else { + return false; + } +} + +TEST_F(AutomatedUITest, TheOneAndOnlyTest) { + CommandLine parsed_command_line; + if (parsed_command_line.HasSwitch(kReproSwitch)) + RunReproduction(); + else + RunAutomatedUITest(); +} diff --git a/chrome/test/automated_ui_tests/automated_ui_tests.h b/chrome/test/automated_ui_tests/automated_ui_tests.h new file mode 100644 index 0000000..96475ee --- /dev/null +++ b/chrome/test/automated_ui_tests/automated_ui_tests.h @@ -0,0 +1,443 @@ +// 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_AUTOMATED_UI_TESTS_AUTOMATED_UI_TESTS_H__ +#define CHROME_TEST_AUTOMATED_UI_TESTS_AUTOMATED_UI_TESTS_H__ + +// This takes an input file of commands, which consist of a series of +// actions, and runs every command, reporting the status of each one +// to an output file once all the commands have been run. +// +// The input file should be an XML file that has a root of any name followed +// by a series of elements named "command" with child elements representing +// the various actions, in order, to be performed during each command. A +// command element can optionally include an "number" attribute to identify it. +// +// Example: +// <CommandList> +// <command number="1"><NewTab/><Navigate/><OpenWindow/><Navigate/><Back/> +// </command> +// <command number="2"><NewTab/><Navigate/><Navigate/><Back/><Forward/> +// </command> +// <command number="3"><CloseTab/><OpenWindow/><NewTab/><Navigate/><CloseTab/> +// </command> +// </CommandList> +// +// When the test is finished it will output results to the output file, +// overwriting any previous version of this file. The output file is an +// XML file which reports on each command, indicating whether it successfully +// ran and if there were any errors. +// +// Example: (actual output will probably contain more actions per command): +// <Report> +// <Executed command_number="1"><NewTab/><Navigate/><result><success/> +// </result> </Executed> +// <Executed command_number="2"><Back/><Forward/><result><success/></result> +// </Executed> +// <Executed command_number="3"><CloseTab/><result> +// <crash crash_dump="C:\a_crash.txt" command_completed="no"/></result> +// </Executed> +// </Report> +// +// A "crash" result will have two attributes, crash_dump, which points +// to the full path of crash dump associated with this crash, and +// command_completed which indicates whether or not the last +// action recorded was the final action of the command. +// +// Furthermore, each individual action may contain additional attributes +// to log non-fatal failures. If the attribute 'failed_to_complete="yes"' +// is present, then the action did not complete. If that attribute is present, +// an info, warning, or error attribute will also be present, and will contain +// a string describing the error. The presence of info means the failure was +// expected, probably due to a state making the action impossible to perform +// like trying to close the last remaining window. Warnings usually mean the +// action couldn't complete for an unknown and unexpected reason, but that the +// test state is probably fine. Errors are like warnings, but they mean the test +// state is probably incorrect, and more failures are likely to be caused by +// the same problem. +// +// Example of some failed actions: +// <CloseTab failed_to_complete="yes" info="would_have_exited_application"/> +// <Reload failed_to_complete="yes" warning="failed_to_apply_accelerator"/> +// <Star failed_to_complete="yes" error="browser_window_not_found"/> +// +// +// Switches +// --input : Specifies the input file, must be an absolute directory. +// Default is "C:\automated_ui_tests.txt" +// +// --output : Specifies the output file, must be an absolute directory. +// Default is "C:\automated_ui_tests_error_report.txt" +// +// +// Test reproduction options: +// +// If you're trying to reproduce the results from crash reports use the +// following switches +// +// --key : Specifies, via a comma delimited list, what actions to run. Examples: +// --key=SetUp,ZoomPlus,Forward,History,Navigate,Back,TearDown +// --key=SetUp,ZoomPlus +// Note, the second key doesn't include a TearDown, that will +// automatically be added if the result doesn't crash. +// +// --num-reproductions : Specifies the number of reproductions to run, the +// default is 1. Suggested use: run without this flag +// to see if we reproduce a crash, then run with the flag +// if there isn't a crash, to see if it might be a rare +// race condition that causes the crash. +// +// +// Debugging options: +// +// --debug : Will append each action that is performed to the output file, as +// soon as the action is performed. If the program finishes, this file +// will be overwritten with the normal results. This flag is used to +// help debug the tests if they are crashing before they get a chance +// to write their results to file. + +#include "chrome/test/ui/ui_test.h" + +// Size of the array of possible actions to use when testing a dialog. +const int kNumTestDialogActions = 4; + +class AutomatedUITest : public UITest { + protected: + AutomatedUITest(); + ~AutomatedUITest(); + + // Runs a reproduction of one set of actions, reporting whether they crash + // or not. + void RunReproduction(); + + // Runs automated UI tests which are read from the input file. + // Reports crashes to the output file. + void RunAutomatedUITest(); + + // Attempts to perform an action based on the input string. See below for + // possible actions. Returns true if the action completes, false otherwise. + bool DoAction(const std::string &action); + + // Actions ------------------------------------------------------------------ + + // Navigates the activate tab to about:blank. + // XML element: <Navigate/> + // Optional Attributes: url="|address|" will navigate to |address| + bool Navigate(); + + // Opens a new tab in the active window using an accelerator. + // Returns true if call to activate the accelerator is successful. + // XML element: <NewTab/> + bool NewTab(); + + // Activates back button in active window. + // Returns true if call to activate the accelerator is successful. + // XML element: <Back/> + bool BackButton(); + + // Activates forward button in active window. + // Returns true if call to activate the accelerator is successful. + // XML element: <Forward/> + bool ForwardButton(); + + // Uses accelerator to close the active tab if it isn't the only tab. + // Returns false if active tab is the only tab, true otherwise. + // XML element: <CloseTab/> + bool CloseActiveTab(); + + // Opens a new browser window by calling automation()->OpenNewBrowserWindow + // Then activates the tab opened in the new window. + // Returns true if window is successfully created. + // XML element: <OpenWindow/> + bool OpenAndActivateNewBrowserWindow(); + + // Reload the active tab. Returns false on failure. + // XML element: <Reload/> + bool ReloadPage(); + + // Stars the current page. This opens a dialog that may or may not be + // dismissed. + // XML element: <Star/> + bool StarPage(); + + // Activates "find in page" on the current page. + // XML element: <FindInPage/> + bool FindInPage(); + + // Activates the next tab on the active browser window. + // XML element: <SelectNextTab/> + bool SelectNextTab(); + + // Activates the previous tab on the active browser window. + // XML element: <SelectPrevTab/> + bool SelectPreviousTab(); + + // Increases the text size on the current active tab. + // XML element: <ZoomPlus/> + bool ZoomPlus(); + + // Decreases the text size on the current active tab. + // XML element: <ZoomMinus/> + bool ZoomMinus(); + + // Opens the History page in the current active browser window. + // XML element: <History/> + bool ShowHistory(); + + // Opens the Downloads page in the current active browser window. + // XML element: <Downloads/> + bool ShowDownloads(); + + // Opens the Import Settings dialog, this dialog is modal so a majority of + // the test can't be completed until it is dismissed. + // XML element: <ImportSettings/> + bool ImportSettings(); + + // Opens the View Passwords dialog, this dialog is modal so a majority of + // the test can't be completed until it is dismissed. + // XML element: <ViewPasswords/> + bool ViewPasswords(); + + // Opens the Clear Browser Data dialog, this dialog is modal so a majority of + // the test can't be completed until it is dismissed. + // XML element: <ClearBrowserData/> + bool ClearBrowserData(); + + // Opens the Task Manager dialog. While it isn't modal, it takes focus from + // the current browser window, so most of the test can't continue until is + // dismissed. + // XML element: <TaskManager/> + bool TaskManager(); + + // Opens and focuses an OffTheRecord browser window. + // XML element: <GoOffTheRecord/> + bool GoOffTheRecord(); + + // Simulates an escape key press on the active window. + // XML element: <PressEscapeKey/> + bool PressEscapeKey(); + + // Simulates a tab key press on the active window. + // XML element: <PressTabKey/> + bool PressTabKey(); + + // Simulates an enter key press on the active window. + // XML element: <PressEnterKey/> + bool PressEnterKey(); + + // Simulates a space bar press on the active window. + // XML element: <PressSpaceBar/> + bool PressSpaceBar(); + + // Simulates a page down key press on the active window. + // XML element: <PageDown/> + bool PageDown(); + + // Simulates a page up key press on the active window. + // XML element: <PageUp/> + bool PageUp(); + + // Simulates a page up key press on the active window. + // XML element: <UpArrow/> + bool UpArrow(); + + // Simulates a page up key press on the active window. + // XML element: <DownArrow/> + bool DownArrow(); + + // Test Dialog Actions ****************************************************** + // These are a special set of actions that perform multiple actions on a + // specified dialog. They run kTestDialogActionsToRun actions randomly + // chosen from test_dialog_possible_actions_ after opening the dialog. They + // then always end with a PressEscapeKey action, to attempt to close the + // dialog. + // + // The randomly performed actions are logged as child elements of the + // TestDialog action. For example (for kTestDialogActionsToRun = 4): + // <TestEditKeywords> <PressTabKey/><PressEnterKey/><DownArrow/> + // <DownArrow/><PressEscapeKey/> </TestEditKeywords> + + // Opens Edit Keywords dialog and runs random actions on it. + // XML element: <TestEditKeywords/> + bool TestEditKeywords(); + + // Opens Task Manager and runs random actions on it. + // This has the possibility of killing both the browser and renderer + // processes, which will cause non-fatal errors for the remaining actions + // in this command. + // XML element: <TestTaskManager/> + bool TestTaskManager(); + + // Opens View Passwords dialog and runs random actions on it. + // XML element: <TestViewPasswords/> + bool TestViewPasswords(); + + // Opens Clear Browser Data dialog and runs random actions on it. + // XML element: <TestClearBrowserData/> + bool TestClearBrowserData(); + + // Opens Import Settings dialog and runs random actions on it. + // XML element: <TestImportSettings/> + bool TestImportSettings(); + + // End Test Dialog Actions ************************************************** + + // Runs a limited set of actions designed to test dialogs. Will run + // |num_actions| from the set defined in test_dialog_possible_actions_. + bool TestDialog(int num_actions); + + // Navigates to about:crash. + // XML element: <Crash/> + bool ForceCrash(); + + // Drags the active tab. If |drag_out| is true, |drag_right| is ignored and + // the tab is dragged vertically to remove it from the tabstrip. Otherwise, + // If |drag_right| is true, if there is a tab to the right of the active tab, + // the active tab is dragged to that tabs position. If |drag_right| is false, + // if there is a tab to the left of the active tab, the active tab is dragged + // to that tabs position. Returns false if the tab isn't dragged, or if an + // attempt to drag out doesn't create a new window (likely because it was + // dragged in to another window). + // XML element (multiple elements use this): + // <DragTabRight/> - Calls DragActiveTab(true, false) (attempt to drag right) + // <DragTabLeft/> - Calls DragActiveTab(false, false) (attempt to drag left) + // <DragTabOut/> - Calls DragActiveTab(false, true) (attempt to drag tab out) + bool DragActiveTab(bool drag_right, bool drag_out); + + // Utility functions -------------------------------------------------------- + + // Returns the WindowProxy associated with the given BrowserProxy + // (transferring ownership of the pointer to the caller) and brings that + // window to the top. + WindowProxy* GetAndActivateWindowForBrowser(BrowserProxy* browser); + + // Applies the accelerator with the given ID to the current active window. + // Returns true if the call is successful. + // Returns false if the active window is not a browser window or if the + // message to apply the accelerator fails. + bool ApplyAccelerator(int id); + + // Calls SimulateOSKeyPress on the active window. Simulates a key press at + // the OS level. |key| is the key pressed and |flags| specifies which + // modifiers keys are also pressed (as defined inchrome/views/event.h). + bool SimulateKeyPressInActiveWindow(wchar_t key, int flags); + + // Opens init file, reads it into the reader, and closes the file. + // Returns false if there are any errors. + bool InitXMLReader(); + + // Closes the xml_writer and outputs the contents of its buffer to + // the output file. + bool WriteReportToFile(); + + // Appends the provided string to the output file. + void AppendToOutputFile(const std::string &append_string); + + // Logs a crash to the xml_writer in the form of: + // <result><crash crash_dump="|crash_dump|" command_completed="yes/no"/> + // </result> + // crash_dump - Location of crash dump if applicable. + // command_completed - True if all actions in the command were completed + // before the crash occured. + void LogCrashResult(const std::string &crash_dump, bool command_completed); + + // Logs a successful command to the xml_writer in the form of: + // <result><success/><result/> + void LogSuccessResult(); + + // Adds the attribute "reason=|reason|" to the current element. + // Used to log the reason for a given failure while performing an action. + void LogActionFailureReason(const std::string &reason); + + // Adds the attribute 'info="|info|"' to the current element. Used when an + // action could not complete for a non-serious issue. Usually because the + // state of the test wouldn't allow for a particular action. + void AddInfoAttribute(const std::string &info); + + // Adds the attribute "warning=|warning|" to the current element. Used when + // an action could not complete because of a potentially troublesome issue. + void AddWarningAttribute(const std::string &warning); + + // Adds the attribute "error=|error|" to the current element. Used when an + // action could not complete due to an unexpected problem which might + // invalidate the results of the entire command (not just the action). + // This is usually used when the testing environment isn't acting as we'd + // expect. For example, no chrome windows are focused, or key presses aren't + // being registered. + void AddErrorAttribute(const std::string &error); + + // Returns the full path of the crash dump. This is likely to be the + // .txt file, not the actual crash dump. Although they do share + // a common name. + std::wstring GetMostRecentCrashDump(); + + // Returns true if the test has produced any new crash logs. + // A "new" crash log is one that was produced since DidCrash was last called + // with |update_total_crashes| set to true. + bool DidCrash(bool update_total_crashes); + + // Overridden so that UI Test doesn't set up when the tests start. + // We use DoAction("SetUp") to set up, because it logs it and makes + // it easier to check for crashes when we start the browser. + virtual void SetUp() {} + + // Overridden so that UI Test doesn't close the browser (which is already + // closed) at the end of the test. + // We use DoAction("TearDown") to tear down, because it logs it and makes + // it easier to check for crashes when we close the browser. + virtual void TearDown() {} + + private: + // Parses the init file. + XmlReader init_reader_; + + // Builds the output file. + XmlWriter xml_writer_; + + // Time the test was started. Used to find crash dumps. + FILETIME test_start_time_; + + // Number of times the browser has crashed during this run. + // Used to check for new crashes. + int total_crashes_; + + // Used to init the init_reader_. It must exist as long as the reader does. + std::string xml_init_file_; + + // If true, appends the commands to the output file as they are executed. + // Used for debugging when automated_ui_tests.cc crashes before it outputs + // results. + bool debug_logging_enabled_; + + static std::string test_dialog_possible_actions_[kNumTestDialogActions]; + + DISALLOW_EVIL_CONSTRUCTORS(AutomatedUITest); +}; + +#endif // #define CHROME_TEST_AUTOMATED_UI_TESTS_AUTOMATED_UI_TESTS_H__ diff --git a/chrome/test/automated_ui_tests/automated_ui_tests.vcproj b/chrome/test/automated_ui_tests/automated_ui_tests.vcproj new file mode 100644 index 0000000..71914d1 --- /dev/null +++ b/chrome/test/automated_ui_tests/automated_ui_tests.vcproj @@ -0,0 +1,212 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="automated_ui_tests" + ProjectGUID="{D2250C20-3A94-4FB9-AF73-11BC5B73884B}" + RootNamespace="page_cycler_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;..\..\tools\build\win\unit_test.vsprops;..\..\tools\build\win\ui_test.vsprops;$(SolutionDir)..\skia\using_skia.vsprops;$(SolutionDir)..\third_party\libxml\build\using_libxml.vsprops;$(SolutionDir)..\third_party\icu38\build\using_icu.vsprops;..\..\tools\build\win\test_memory_usage.vsprops;$(SolutionDir)..\testing\using_gtest.vsprops" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + /> + <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;..\..\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\libxml\build\using_libxml.vsprops;$(SolutionDir)..\third_party\icu38\build\using_icu.vsprops;$(SolutionDir)..\testing\using_gtest.vsprops" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + /> + <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="..\ui\run_all_unittests.cc" + > + </File> + <File + RelativePath="..\test_file_util.cc" + > + </File> + <File + RelativePath="..\testing_browser_process.h" + > + </File> + <File + RelativePath="..\ui\ui_test.cc" + > + </File> + <File + RelativePath="..\ui\ui_test.h" + > + </File> + <File + RelativePath="..\ui\ui_test_suite.cc" + > + </File> + </Filter> + <Filter + Name="MemoryUsage" + > + <File + RelativePath="..\perf\mem_usage.cc" + > + </File> + <File + RelativePath="..\perf\mem_usage.h" + > + </File> + </Filter> + <Filter + Name="AutomatedUITest" + > + <File + RelativePath=".\automated_ui_tests.cc" + > + </File> + <File + RelativePath=".\automated_ui_tests.h" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> |