| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/command_line.h" |
| #include "base/process/launch.h" |
| #include "base/stl_util.h" |
| #include "base/test/launcher/test_launcher.h" |
| #include "base/test/test_switches.h" |
| #include "base/test/test_timeouts.h" |
| #include "build/build_config.h" |
| #include "content/public/common/content_switches.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/compositor/compositor_switches.h" |
| |
| namespace { |
| |
| // Switch for BrowserUiTest.Invoke to spawn a subprocess testing the provided |
| // argument under a consistent setup. |
| constexpr const char kUiSwitch[] = "ui"; |
| |
| // Pattern to search in test names that indicate support for UI testing. |
| constexpr const char kUiPattern[] = "InvokeUi_"; |
| |
| } // namespace |
| |
| // Adds a browser_test entry point into the UI testing framework. Without a |
| // --ui specified, just lists the available UIs and exits. |
| TEST(BrowserUiTest, Invoke) { |
| const base::CommandLine& invoker = *base::CommandLine::ForCurrentProcess(); |
| const std::string ui_name = invoker.GetSwitchValueASCII(kUiSwitch); |
| |
| std::set<std::string> ui_cases; |
| const testing::UnitTest* unit_test = testing::UnitTest::GetInstance(); |
| for (int i = 0; i < unit_test->total_test_case_count(); ++i) { |
| const testing::TestCase* test_case = unit_test->GetTestCase(i); |
| for (int j = 0; j < test_case->total_test_count(); ++j) { |
| const char* name = test_case->GetTestInfo(j)->name(); |
| if (strstr(name, kUiPattern)) |
| ui_cases.insert(test_case->name() + std::string(".") + name); |
| } |
| } |
| |
| if (ui_name.empty()) { |
| std::string case_list; |
| for (const std::string& name : ui_cases) |
| case_list += "\t" + name + "\n"; |
| VLOG(0) << "\nPass one of the following after --" << kUiSwitch << "=\n" |
| << case_list; |
| return; |
| } |
| |
| auto it = ui_cases.find(ui_name); |
| ASSERT_NE(it, ui_cases.end()) << "UI '" << ui_name << "' not found."; |
| |
| // Don't create test output for the subprocess (the paths will conflict). |
| base::CommandLine::StringVector argv = invoker.argv(); |
| std::string ascii(switches::kTestLauncherOutput); |
| base::CommandLine::StringType native_switch(ascii.begin(), ascii.end()); |
| base::EraseIf( |
| argv, [native_switch](const base::CommandLine::StringType& arg) -> bool { |
| return arg.find(native_switch) != arg.npos; // Substring search. |
| }); |
| base::CommandLine command(argv); |
| |
| // Replace TestBrowserUi.Invoke with |ui_name|. |
| command.AppendSwitchASCII(base::kGTestFilterFlag, ui_name); |
| |
| base::LaunchOptions options; |
| |
| // Generate screen output if --test-launcher-interactive was specified. |
| if (command.HasSwitch(switches::kTestLauncherInteractive)) { |
| command.AppendSwitch(switches::kEnablePixelOutputInTests); |
| #if defined(OS_WIN) |
| // Under Windows, the child process won't launch without the wait option. |
| // See http://crbug.com/688534. |
| options.wait = true; |
| // Under Windows, dialogs (but not the browser window) created in the |
| // spawned browser_test process are invisible for some unknown reason. |
| // Pass in --disable-gpu to resolve this for now. See |
| // http://crbug.com/687387. |
| command.AppendSwitch(switches::kDisableGpu); |
| #endif |
| } else { |
| options.wait = true; |
| } |
| |
| base::LaunchProcess(command, options); |
| } |