| OLD | NEW |
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <fstream> | 5 #include <fstream> |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 const wchar_t* const kReproRepeatSwitch = L"num-reproductions"; | 34 const wchar_t* const kReproRepeatSwitch = L"num-reproductions"; |
| 35 | 35 |
| 36 const wchar_t* const kInputFilePathSwitch = L"input"; | 36 const wchar_t* const kInputFilePathSwitch = L"input"; |
| 37 | 37 |
| 38 const wchar_t* const kOutputFilePathSwitch = L"output"; | 38 const wchar_t* const kOutputFilePathSwitch = L"output"; |
| 39 | 39 |
| 40 const wchar_t* const kDebugModeSwitch = L"debug"; | 40 const wchar_t* const kDebugModeSwitch = L"debug"; |
| 41 | 41 |
| 42 const wchar_t* const kWaitSwitch = L"wait-after-action"; | 42 const wchar_t* const kWaitSwitch = L"wait-after-action"; |
| 43 | 43 |
| 44 const wchar_t* const kDefaultInputFilePath = L"C:\\automated_ui_tests.txt"; | 44 const FilePath::CharType* const kDefaultInputFilePath = |
| 45 #if defined(OS_WIN) |
| 46 L"C:\\automated_ui_tests.txt"; |
| 47 #else |
| 48 "/tmp/automated_ui_tests.txt"; |
| 49 #endif |
| 45 | 50 |
| 46 const wchar_t* const kDefaultOutputFilePath | 51 const FilePath::CharType* const kDefaultOutputFilePath = |
| 47 = L"C:\\automated_ui_tests_error_report.txt"; | 52 #if defined(OS_WIN) |
| 53 L"C:\\automated_ui_tests_error_report.txt"; |
| 54 #else |
| 55 "/tmp/automated_ui_tests_error_report.txt"; |
| 56 #endif |
| 48 | 57 |
| 49 const int kDebuggingTimeoutMsec = 5000; | 58 const int kDebuggingTimeoutMsec = 5000; |
| 50 | 59 |
| 51 // How many commands to run when testing a dialog box. | 60 // How many commands to run when testing a dialog box. |
| 52 const int kTestDialogActionsToRun = 7; | 61 const int kTestDialogActionsToRun = 7; |
| 53 | 62 |
| 54 void SilentRuntimeReportHandler(const std::string& str) { | 63 void SilentRuntimeReportHandler(const std::string& str) { |
| 55 } | 64 } |
| 56 | 65 |
| 66 FilePath GetInputFilePath() { |
| 67 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); |
| 68 if (parsed_command_line.HasSwitch(kInputFilePathSwitch)) { |
| 69 return FilePath::FromWStringHack( |
| 70 parsed_command_line.GetSwitchValue(kInputFilePathSwitch)); |
| 71 } else { |
| 72 return FilePath(kDefaultInputFilePath); |
| 73 } |
| 74 } |
| 75 |
| 76 FilePath GetOutputFilePath() { |
| 77 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); |
| 78 if (parsed_command_line.HasSwitch(kOutputFilePathSwitch)) { |
| 79 return FilePath::FromWStringHack( |
| 80 parsed_command_line.GetSwitchValue(kOutputFilePathSwitch)); |
| 81 } else { |
| 82 return FilePath(kDefaultOutputFilePath); |
| 83 } |
| 84 } |
| 85 |
| 57 } // namespace | 86 } // namespace |
| 58 | 87 |
| 59 // This subset of commands is used to test dialog boxes, which aren't likely | 88 // This subset of commands is used to test dialog boxes, which aren't likely |
| 60 // to respond to most other commands. | 89 // to respond to most other commands. |
| 61 const std::string kTestDialogPossibleActions[] = { | 90 const std::string kTestDialogPossibleActions[] = { |
| 62 // See FuzzyTestDialog for details on why Enter and SpaceBar must appear first | 91 // See FuzzyTestDialog for details on why Enter and SpaceBar must appear first |
| 63 // in this list. | 92 // in this list. |
| 64 "PressEnterKey", | 93 "PressEnterKey", |
| 65 "PressSpaceBar", | 94 "PressSpaceBar", |
| 66 "PressTabKey", | 95 "PressTabKey", |
| (...skipping 19 matching lines...) Expand all Loading... |
| 86 post_action_delay_(0) { | 115 post_action_delay_(0) { |
| 87 show_window_ = true; | 116 show_window_ = true; |
| 88 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); | 117 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); |
| 89 if (parsed_command_line.HasSwitch(kDebugModeSwitch)) | 118 if (parsed_command_line.HasSwitch(kDebugModeSwitch)) |
| 90 debug_logging_enabled_ = true; | 119 debug_logging_enabled_ = true; |
| 91 if (parsed_command_line.HasSwitch(kWaitSwitch)) { | 120 if (parsed_command_line.HasSwitch(kWaitSwitch)) { |
| 92 std::wstring str = parsed_command_line.GetSwitchValue(kWaitSwitch); | 121 std::wstring str = parsed_command_line.GetSwitchValue(kWaitSwitch); |
| 93 if (str.empty()) { | 122 if (str.empty()) { |
| 94 post_action_delay_ = 1; | 123 post_action_delay_ = 1; |
| 95 } else { | 124 } else { |
| 96 post_action_delay_ = static_cast<int>(StringToInt64(str)); | 125 post_action_delay_ = static_cast<int>(StringToInt64(WideToUTF16(str))); |
| 97 } | 126 } |
| 98 } | 127 } |
| 99 if (base::SysInfo::HasEnvVar(env_vars::kHeadless)) | 128 if (base::SysInfo::HasEnvVar(env_vars::kHeadless)) |
| 100 logging::SetLogReportHandler(SilentRuntimeReportHandler); | 129 logging::SetLogReportHandler(SilentRuntimeReportHandler); |
| 101 } | 130 } |
| 102 | 131 |
| 103 AutomatedUITest::~AutomatedUITest() {} | 132 AutomatedUITest::~AutomatedUITest() {} |
| 104 | 133 |
| 105 void AutomatedUITest::RunReproduction() { | 134 void AutomatedUITest::RunReproduction() { |
| 106 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); | 135 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); |
| 107 xml_writer_.StartWriting(); | 136 xml_writer_.StartWriting(); |
| 108 xml_writer_.StartElement("Report"); | 137 xml_writer_.StartElement("Report"); |
| 109 std::string action_string = | 138 std::string action_string = |
| 110 WideToASCII(parsed_command_line.GetSwitchValue(kReproSwitch)); | 139 WideToASCII(parsed_command_line.GetSwitchValue(kReproSwitch)); |
| 111 | 140 |
| 112 int64 num_reproductions = 1; | 141 int64 num_reproductions = 1; |
| 113 if (parsed_command_line.HasSwitch(kReproRepeatSwitch)) { | 142 if (parsed_command_line.HasSwitch(kReproRepeatSwitch)) { |
| 114 std::wstring num_reproductions_string = | 143 std::wstring num_reproductions_string = |
| 115 parsed_command_line.GetSwitchValue(kReproRepeatSwitch); | 144 parsed_command_line.GetSwitchValue(kReproRepeatSwitch); |
| 116 std::string test = WideToASCII(num_reproductions_string); | 145 std::string test = WideToASCII(num_reproductions_string); |
| 117 num_reproductions = StringToInt64(num_reproductions_string); | 146 num_reproductions = StringToInt64(test); |
| 118 } | 147 } |
| 119 std::vector<std::string> actions; | 148 std::vector<std::string> actions; |
| 120 SplitString(action_string, L',', &actions); | 149 SplitString(action_string, L',', &actions); |
| 121 bool did_crash = false; | 150 bool did_crash = false; |
| 122 bool command_complete = false; | 151 bool command_complete = false; |
| 123 | 152 |
| 124 for (int64 i = 0; i < num_reproductions && !did_crash; ++i) { | 153 for (int64 i = 0; i < num_reproductions && !did_crash; ++i) { |
| 125 bool did_teardown = false; | 154 bool did_teardown = false; |
| 126 xml_writer_.StartElement("Executed"); | 155 xml_writer_.StartElement("Executed"); |
| 127 for (size_t j = 0; j < actions.size(); ++j) { | 156 for (size_t j = 0; j < actions.size(); ++j) { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 } else if (LowerCaseEqualsASCII(action, "clearbrowsingdata")) { | 304 } else if (LowerCaseEqualsASCII(action, "clearbrowsingdata")) { |
| 276 did_complete_action = OpenClearBrowsingDataDialog(); | 305 did_complete_action = OpenClearBrowsingDataDialog(); |
| 277 } else if (LowerCaseEqualsASCII(action, "crash")) { | 306 } else if (LowerCaseEqualsASCII(action, "crash")) { |
| 278 did_complete_action = ForceCrash(); | 307 did_complete_action = ForceCrash(); |
| 279 } else if (LowerCaseEqualsASCII(action, "dialog")) { | 308 } else if (LowerCaseEqualsASCII(action, "dialog")) { |
| 280 did_complete_action = ExerciseDialog(); | 309 did_complete_action = ExerciseDialog(); |
| 281 } else if (LowerCaseEqualsASCII(action, "downarrow")) { | 310 } else if (LowerCaseEqualsASCII(action, "downarrow")) { |
| 282 did_complete_action = PressDownArrow(); | 311 did_complete_action = PressDownArrow(); |
| 283 } else if (LowerCaseEqualsASCII(action, "downloads")) { | 312 } else if (LowerCaseEqualsASCII(action, "downloads")) { |
| 284 did_complete_action = ShowDownloads(); | 313 did_complete_action = ShowDownloads(); |
| 314 // TODO(estade): port. |
| 315 #if defined(OS_WIN) |
| 285 } else if (LowerCaseEqualsASCII(action, "dragtableft")) { | 316 } else if (LowerCaseEqualsASCII(action, "dragtableft")) { |
| 286 did_complete_action = DragActiveTab(false); | 317 did_complete_action = DragActiveTab(false); |
| 287 } else if (LowerCaseEqualsASCII(action, "dragtabout")) { | 318 } else if (LowerCaseEqualsASCII(action, "dragtabout")) { |
| 288 did_complete_action = DragTabOut(); | 319 did_complete_action = DragTabOut(); |
| 289 } else if (LowerCaseEqualsASCII(action, "dragtabright")) { | 320 } else if (LowerCaseEqualsASCII(action, "dragtabright")) { |
| 290 did_complete_action = DragActiveTab(true); | 321 did_complete_action = DragActiveTab(true); |
| 322 #endif // defined(OS_WIN) |
| 291 } else if (LowerCaseEqualsASCII(action, "duplicatetab")) { | 323 } else if (LowerCaseEqualsASCII(action, "duplicatetab")) { |
| 292 did_complete_action = DuplicateTab(); | 324 did_complete_action = DuplicateTab(); |
| 293 } else if (LowerCaseEqualsASCII(action, "editsearchengines")) { | 325 } else if (LowerCaseEqualsASCII(action, "editsearchengines")) { |
| 294 did_complete_action = OpenEditSearchEnginesDialog(); | 326 did_complete_action = OpenEditSearchEnginesDialog(); |
| 295 } else if (LowerCaseEqualsASCII(action, "findinpage")) { | 327 } else if (LowerCaseEqualsASCII(action, "findinpage")) { |
| 296 did_complete_action = FindInPage(); | 328 did_complete_action = FindInPage(); |
| 297 } else if (LowerCaseEqualsASCII(action, "forward")) { | 329 } else if (LowerCaseEqualsASCII(action, "forward")) { |
| 298 did_complete_action = ForwardButton(); | 330 did_complete_action = ForwardButton(); |
| 299 } else if (LowerCaseEqualsASCII(action, "goofftherecord")) { | 331 } else if (LowerCaseEqualsASCII(action, "goofftherecord")) { |
| 300 did_complete_action = GoOffTheRecord(); | 332 did_complete_action = GoOffTheRecord(); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 } else { | 415 } else { |
| 384 NOTREACHED() << "Unknown command passed into DoAction: " | 416 NOTREACHED() << "Unknown command passed into DoAction: " |
| 385 << action.c_str(); | 417 << action.c_str(); |
| 386 } | 418 } |
| 387 | 419 |
| 388 if (!did_complete_action) | 420 if (!did_complete_action) |
| 389 xml_writer_.AddAttribute("failed_to_complete", "yes"); | 421 xml_writer_.AddAttribute("failed_to_complete", "yes"); |
| 390 xml_writer_.EndElement(); | 422 xml_writer_.EndElement(); |
| 391 | 423 |
| 392 if (post_action_delay_) | 424 if (post_action_delay_) |
| 393 ::Sleep(1000 * post_action_delay_); | 425 PlatformThread::Sleep(1000 * post_action_delay_); |
| 394 | 426 |
| 395 return did_complete_action; | 427 return did_complete_action; |
| 396 } | 428 } |
| 397 | 429 |
| 398 bool AutomatedUITest::ChangeEncoding() { | 430 bool AutomatedUITest::ChangeEncoding() { |
| 399 // Get the encoding list that is used to populate the UI (encoding menu) | 431 // Get the encoding list that is used to populate the UI (encoding menu) |
| 400 std::string cur_locale = g_browser_process->GetApplicationLocale(); | 432 std::string cur_locale = g_browser_process->GetApplicationLocale(); |
| 401 const std::vector<CharacterEncoding::EncodingInfo>* encodings = | 433 const std::vector<CharacterEncoding::EncodingInfo>* encodings = |
| 402 CharacterEncoding::GetCurrentDisplayEncodings( | 434 CharacterEncoding::GetCurrentDisplayEncodings( |
| 403 cur_locale, L"ISO-8859-1,windows-1252", L""); | 435 cur_locale, L"ISO-8859-1,windows-1252", L""); |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 return false; | 634 return false; |
| 603 } | 635 } |
| 604 if (!window->SimulateOSKeyPress(key, flags)) { | 636 if (!window->SimulateOSKeyPress(key, flags)) { |
| 605 AddWarningAttribute("failure_simulating_key_press"); | 637 AddWarningAttribute("failure_simulating_key_press"); |
| 606 return false; | 638 return false; |
| 607 } | 639 } |
| 608 return true; | 640 return true; |
| 609 } | 641 } |
| 610 | 642 |
| 611 bool AutomatedUITest::InitXMLReader() { | 643 bool AutomatedUITest::InitXMLReader() { |
| 612 std::wstring input_path; | 644 FilePath input_path = GetInputFilePath(); |
| 613 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); | |
| 614 if (parsed_command_line.HasSwitch(kInputFilePathSwitch)) | |
| 615 input_path = parsed_command_line.GetSwitchValue(kInputFilePathSwitch); | |
| 616 else | |
| 617 input_path = kDefaultInputFilePath; | |
| 618 | 645 |
| 619 if (!file_util::ReadFileToString(input_path, &xml_init_file_)) | 646 if (!file_util::ReadFileToString(input_path, &xml_init_file_)) |
| 620 return false; | 647 return false; |
| 621 return init_reader_.Load(xml_init_file_); | 648 return init_reader_.Load(xml_init_file_); |
| 622 } | 649 } |
| 623 | 650 |
| 624 bool AutomatedUITest::WriteReportToFile() { | 651 bool AutomatedUITest::WriteReportToFile() { |
| 652 FilePath path = GetOutputFilePath(); |
| 625 std::ofstream error_file; | 653 std::ofstream error_file; |
| 626 std::wstring path; | |
| 627 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); | |
| 628 if (parsed_command_line.HasSwitch(kOutputFilePathSwitch)) | |
| 629 path = parsed_command_line.GetSwitchValue(kOutputFilePathSwitch); | |
| 630 else | |
| 631 path = kDefaultOutputFilePath; | |
| 632 | |
| 633 if (!path.empty()) | 654 if (!path.empty()) |
| 634 error_file.open(path.c_str(), std::ios::out); | 655 error_file.open(path.value().c_str(), std::ios::out); |
| 635 | 656 |
| 636 // Closes all open elements and free the writer. This is required | 657 // Closes all open elements and free the writer. This is required |
| 637 // in order to retrieve the contents of the buffer. | 658 // in order to retrieve the contents of the buffer. |
| 638 xml_writer_.StopWriting(); | 659 xml_writer_.StopWriting(); |
| 639 error_file << xml_writer_.GetWrittenString(); | 660 error_file << xml_writer_.GetWrittenString(); |
| 640 error_file.close(); | 661 error_file.close(); |
| 641 return true; | 662 return true; |
| 642 } | 663 } |
| 643 | 664 |
| 644 void AutomatedUITest::AppendToOutputFile(const std::string &append_string) { | 665 void AutomatedUITest::AppendToOutputFile(const std::string &append_string) { |
| 666 FilePath path = GetOutputFilePath(); |
| 645 std::ofstream error_file; | 667 std::ofstream error_file; |
| 646 std::wstring path; | |
| 647 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); | |
| 648 if (parsed_command_line.HasSwitch(kOutputFilePathSwitch)) | |
| 649 path = parsed_command_line.GetSwitchValue(kOutputFilePathSwitch); | |
| 650 else | |
| 651 path = kDefaultOutputFilePath; | |
| 652 | |
| 653 if (!path.empty()) | 668 if (!path.empty()) |
| 654 error_file.open(path.c_str(), std::ios::out | std::ios_base::app); | 669 error_file.open(path.value().c_str(), std::ios::out | std::ios_base::app); |
| 655 | 670 |
| 656 error_file << append_string << " "; | 671 error_file << append_string << " "; |
| 657 error_file.close(); | 672 error_file.close(); |
| 658 } | 673 } |
| 659 | 674 |
| 660 void AutomatedUITest::LogCrashResult(const std::string &crash_dump, | 675 void AutomatedUITest::LogCrashResult(const std::string &crash_dump, |
| 661 bool command_completed) { | 676 bool command_completed) { |
| 662 xml_writer_.StartElement("result"); | 677 xml_writer_.StartElement("result"); |
| 663 xml_writer_.StartElement("crash"); | 678 xml_writer_.StartElement("crash"); |
| 664 xml_writer_.AddAttribute("crash_dump", crash_dump); | 679 xml_writer_.AddAttribute("crash_dump", crash_dump); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 695 | 710 |
| 696 void AutomatedUITest::LogWarningMessage(const std::string &warning) { | 711 void AutomatedUITest::LogWarningMessage(const std::string &warning) { |
| 697 AddWarningAttribute(warning); | 712 AddWarningAttribute(warning); |
| 698 } | 713 } |
| 699 | 714 |
| 700 void AutomatedUITest::LogInfoMessage(const std::string &info) { | 715 void AutomatedUITest::LogInfoMessage(const std::string &info) { |
| 701 AddWarningAttribute(info); | 716 AddWarningAttribute(info); |
| 702 } | 717 } |
| 703 | 718 |
| 704 std::wstring AutomatedUITest::GetMostRecentCrashDump() { | 719 std::wstring AutomatedUITest::GetMostRecentCrashDump() { |
| 720 // TODO(estade): port. |
| 721 #if defined(OS_WIN) |
| 705 std::wstring crash_dump_path; | 722 std::wstring crash_dump_path; |
| 706 int file_count = 0; | 723 int file_count = 0; |
| 707 FILETIME most_recent_file_time; | 724 FILETIME most_recent_file_time; |
| 708 std::wstring most_recent_file_name; | 725 std::wstring most_recent_file_name; |
| 709 WIN32_FIND_DATA find_file_data; | 726 WIN32_FIND_DATA find_file_data; |
| 710 | 727 |
| 711 PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dump_path); | 728 PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dump_path); |
| 712 // All files in the given directory. | 729 // All files in the given directory. |
| 713 std::wstring filename_spec = crash_dump_path + L"\\*"; | 730 std::wstring filename_spec = crash_dump_path + L"\\*"; |
| 714 HANDLE find_handle = FindFirstFile(filename_spec.c_str(), &find_file_data); | 731 HANDLE find_handle = FindFirstFile(filename_spec.c_str(), &find_file_data); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 732 } while (FindNextFile(find_handle, &find_file_data)); | 749 } while (FindNextFile(find_handle, &find_file_data)); |
| 733 FindClose(find_handle); | 750 FindClose(find_handle); |
| 734 } | 751 } |
| 735 | 752 |
| 736 if (most_recent_file_name.empty()) { | 753 if (most_recent_file_name.empty()) { |
| 737 return L""; | 754 return L""; |
| 738 } else { | 755 } else { |
| 739 file_util::AppendToPath(&crash_dump_path, most_recent_file_name); | 756 file_util::AppendToPath(&crash_dump_path, most_recent_file_name); |
| 740 return crash_dump_path; | 757 return crash_dump_path; |
| 741 } | 758 } |
| 759 #else |
| 760 NOTIMPLEMENTED(); |
| 761 return std::wstring(); |
| 762 #endif |
| 742 } | 763 } |
| 743 | 764 |
| 744 bool AutomatedUITest::DidCrash(bool update_total_crashes) { | 765 bool AutomatedUITest::DidCrash(bool update_total_crashes) { |
| 745 FilePath crash_dump_path; | 766 FilePath crash_dump_path; |
| 746 PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dump_path); | 767 PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dump_path); |
| 747 // Each crash creates two dump files, so we divide by two here. | 768 // Each crash creates two dump files, so we divide by two here. |
| 748 int actual_crashes = file_util::CountFilesCreatedAfter( | 769 int actual_crashes = file_util::CountFilesCreatedAfter( |
| 749 crash_dump_path, test_start_time_) / 2; | 770 crash_dump_path, test_start_time_) / 2; |
| 750 | 771 |
| 751 // If there are more crash dumps than the total dumps which we have recorded | 772 // If there are more crash dumps than the total dumps which we have recorded |
| 752 // then this is a new crash. | 773 // then this is a new crash. |
| 753 if (actual_crashes > total_crashes_) { | 774 if (actual_crashes > total_crashes_) { |
| 754 if (update_total_crashes) | 775 if (update_total_crashes) |
| 755 total_crashes_ = actual_crashes; | 776 total_crashes_ = actual_crashes; |
| 756 return true; | 777 return true; |
| 757 } else { | 778 } else { |
| 758 return false; | 779 return false; |
| 759 } | 780 } |
| 760 } | 781 } |
| 761 | 782 |
| 762 TEST_F(AutomatedUITest, TheOneAndOnlyTest) { | 783 TEST_F(AutomatedUITest, TheOneAndOnlyTest) { |
| 763 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); | 784 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); |
| 764 if (parsed_command_line.HasSwitch(kReproSwitch)) | 785 if (parsed_command_line.HasSwitch(kReproSwitch)) |
| 765 RunReproduction(); | 786 RunReproduction(); |
| 766 else | 787 else |
| 767 RunAutomatedUITest(); | 788 RunAutomatedUITest(); |
| 768 } | 789 } |
| OLD | NEW |