| // Copyright 2014 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 "chrome/test/base/web_ui_browser_test.h" |
| |
| #include <stddef.h> |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/bind.h" |
| #include "base/containers/contains.h" |
| #include "base/files/file_util.h" |
| #include "base/lazy_instance.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/ref_counted_memory.h" |
| #include "base/path_service.h" |
| #include "base/strings/strcat.h" |
| #include "base/strings/string_util.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/test/test_switches.h" |
| #include "base/threading/thread_restrictions.h" |
| #include "base/values.h" |
| #include "chrome/browser/chrome_content_browser_client.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_commands.h" |
| #include "chrome/browser/ui/browser_navigator.h" |
| #include "chrome/browser/ui/browser_navigator_params.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/browser/ui/webui/web_ui_test_handler.h" |
| #include "chrome/common/chrome_paths.h" |
| #include "chrome/common/url_constants.h" |
| #include "chrome/test/base/js_test_api.h" |
| #include "chrome/test/base/test_chrome_web_ui_controller_factory.h" |
| #include "chrome/test/base/test_switches.h" |
| #include "chrome/test/base/ui_test_utils.h" |
| #include "content/public/browser/global_routing_id.h" |
| #include "content/public/browser/url_data_source.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/browser/web_ui_controller.h" |
| #include "content/public/browser/web_ui_message_handler.h" |
| #include "content/public/common/content_client.h" |
| #include "content/public/common/content_switches.h" |
| #include "content/public/common/url_constants.h" |
| #include "content/public/test/browser_test_utils.h" |
| #include "content/public/test/scoped_web_ui_controller_factory_registration.h" |
| #include "content/public/test/test_launcher.h" |
| #include "content/public/test/test_navigation_observer.h" |
| #include "net/base/filename_util.h" |
| #include "services/network/public/mojom/content_security_policy.mojom.h" |
| #include "ui/base/resource/resource_bundle.h" |
| #include "ui/base/resource/resource_handle.h" |
| |
| using content::RenderFrameHost; |
| using content::WebContents; |
| using content::WebUIController; |
| using content::WebUIMessageHandler; |
| |
| namespace { |
| |
| base::LazyInstance<std::vector<std::string>>::DestructorAtExit |
| g_error_messages = LAZY_INSTANCE_INITIALIZER; |
| |
| // Intercepts all log messages. |
| bool LogHandler(int severity, |
| const char* file, |
| int line, |
| size_t message_start, |
| const std::string& str) { |
| if (severity == logging::LOG_ERROR && file && |
| std::string("CONSOLE") == file) { |
| g_error_messages.Get().push_back(str); |
| } |
| |
| return false; |
| } |
| |
| class WebUIJsInjectionReadyObserver : public content::WebContentsObserver { |
| public: |
| WebUIJsInjectionReadyObserver(content::WebContents* web_contents, |
| BaseWebUIBrowserTest* browser_test, |
| const std::string& preload_test_fixture, |
| const std::string& preload_test_name) |
| : content::WebContentsObserver(web_contents), |
| browser_test_(browser_test), |
| preload_test_fixture_(preload_test_fixture), |
| preload_test_name_(preload_test_name) {} |
| |
| void RenderFrameCreated(content::RenderFrameHost* frame_host) override { |
| // We only load JS libraries in the main frame. |
| if (!frame_host->GetParent()) { |
| browser_test_->PreLoadJavascriptLibraries(preload_test_fixture_, |
| preload_test_name_, frame_host); |
| } |
| } |
| |
| private: |
| const raw_ptr<BaseWebUIBrowserTest> browser_test_; |
| std::string preload_test_fixture_; |
| std::string preload_test_name_; |
| }; |
| |
| // Handles chrome.send()-style test communication. |
| class WebUITestMessageHandler : public content::WebUIMessageHandler, |
| public WebUITestHandler { |
| public: |
| WebUITestMessageHandler() = default; |
| WebUITestMessageHandler(const WebUITestMessageHandler&) = delete; |
| WebUITestMessageHandler& operator=(const WebUITestMessageHandler&) = delete; |
| ~WebUITestMessageHandler() override = default; |
| |
| // Receives testResult messages. |
| void HandleTestResult(const base::ListValue* test_result) { |
| // To ensure this gets done, do this before ASSERT* calls. |
| RunQuitClosure(); |
| |
| const auto& list = test_result->GetListDeprecated(); |
| ASSERT_FALSE(list.empty()); |
| const bool test_succeeded = list[0].is_bool() && list[0].GetBool(); |
| std::string message; |
| if (!test_succeeded) { |
| ASSERT_EQ(2U, list.size()); |
| message = list[1].GetString(); |
| } |
| |
| TestComplete(test_succeeded ? absl::optional<std::string>() : message); |
| } |
| |
| // content::WebUIMessageHandler: |
| void RegisterMessages() override { |
| web_ui()->RegisterDeprecatedMessageCallback( |
| "testResult", |
| base::BindRepeating(&WebUITestMessageHandler::HandleTestResult, |
| base::Unretained(this))); |
| } |
| |
| content::WebUI* GetWebUI() override { return web_ui(); } |
| }; |
| |
| WebUICoverageObserver::WebUICoverageObserver( |
| base::FilePath devtools_code_coverage_dir) |
| : devtools_code_coverage_dir_(devtools_code_coverage_dir) { |
| content::DevToolsAgentHost::AddObserver(this); |
| } |
| |
| WebUICoverageObserver::~WebUICoverageObserver() = default; |
| |
| bool WebUICoverageObserver::CoverageEnabled() { |
| return !devtools_code_coverage_dir_.empty(); |
| } |
| |
| void WebUICoverageObserver::CollectCoverage(const std::string& test_name) { |
| ASSERT_TRUE(CoverageEnabled()); |
| |
| content::DevToolsAgentHost::RemoveObserver(this); |
| content::RunAllTasksUntilIdle(); |
| |
| base::ScopedAllowBlockingForTesting allow_blocking; |
| base::FilePath store = |
| devtools_code_coverage_dir_.AppendASCII("webui_javascript_code_coverage"); |
| coverage::DevToolsListener::SetupCoverageStore(store); |
| |
| for (auto& agent : devtools_agent_) { |
| auto* host = agent.first; |
| if (agent.second->HasCoverage(host)) |
| agent.second->GetCoverage(host, store, test_name); |
| agent.second->Detach(host); |
| } |
| |
| content::DevToolsAgentHost::DetachAllClients(); |
| } |
| |
| bool WebUICoverageObserver::ShouldForceDevToolsAgentHostCreation() { |
| return CoverageEnabled(); |
| } |
| |
| void WebUICoverageObserver::DevToolsAgentHostCreated( |
| content::DevToolsAgentHost* host) { |
| CHECK(devtools_agent_.find(host) == devtools_agent_.end()); |
| |
| uint32_t process_id = base::GetUniqueIdForProcess().GetUnsafeValue(); |
| devtools_agent_[host] = |
| std::make_unique<coverage::DevToolsListener>(host, process_id); |
| } |
| |
| void WebUICoverageObserver::DevToolsAgentHostAttached( |
| content::DevToolsAgentHost* host) {} |
| |
| void WebUICoverageObserver::DevToolsAgentHostNavigated( |
| content::DevToolsAgentHost* host) { |
| if (devtools_agent_.find(host) == devtools_agent_.end()) |
| return; |
| |
| devtools_agent_.find(host)->second->Navigated(host); |
| } |
| |
| void WebUICoverageObserver::DevToolsAgentHostDetached( |
| content::DevToolsAgentHost* host) {} |
| |
| void WebUICoverageObserver::DevToolsAgentHostCrashed( |
| content::DevToolsAgentHost* host, |
| base::TerminationStatus status) { |
| ASSERT_TRUE(devtools_agent_.find(host) == devtools_agent_.end()); |
| } |
| |
| } // namespace |
| |
| BaseWebUIBrowserTest::~BaseWebUIBrowserTest() = default; |
| |
| bool BaseWebUIBrowserTest::RunJavascriptFunction( |
| const std::string& function_name) { |
| std::vector<base::Value> empty_args; |
| return RunJavascriptFunction(function_name, std::move(empty_args)); |
| } |
| |
| bool BaseWebUIBrowserTest::RunJavascriptFunction( |
| const std::string& function_name, |
| base::Value arg) { |
| std::vector<base::Value> args; |
| args.push_back(std::move(arg)); |
| return RunJavascriptFunction(function_name, std::move(args)); |
| } |
| |
| bool BaseWebUIBrowserTest::RunJavascriptFunction( |
| const std::string& function_name, |
| base::Value arg1, |
| base::Value arg2) { |
| std::vector<base::Value> args; |
| args.push_back(std::move(arg1)); |
| args.push_back(std::move(arg2)); |
| return RunJavascriptFunction(function_name, std::move(args)); |
| } |
| |
| bool BaseWebUIBrowserTest::RunJavascriptFunction( |
| const std::string& function_name, |
| std::vector<base::Value> function_arguments) { |
| return RunJavascriptUsingHandler(function_name, std::move(function_arguments), |
| false, false, nullptr); |
| } |
| |
| bool BaseWebUIBrowserTest::RunJavascriptTestF(bool is_async, |
| const std::string& test_fixture, |
| const std::string& test_name) { |
| std::vector<base::Value> args; |
| args.push_back(base::Value(test_fixture)); |
| args.push_back(base::Value(test_name)); |
| |
| bool result = is_async ? RunJavascriptAsyncTest("RUN_TEST_F", std::move(args)) |
| : RunJavascriptTest("RUN_TEST_F", std::move(args)); |
| |
| if (coverage_handler_ && coverage_handler_->CoverageEnabled()) { |
| const std::string& full_test_name = base::StrCat({test_fixture, test_name}); |
| coverage_handler_->CollectCoverage(full_test_name); |
| } |
| |
| return result; |
| } |
| |
| bool BaseWebUIBrowserTest::RunJavascriptTest(const std::string& test_name) { |
| std::vector<base::Value> empty_args; |
| return RunJavascriptTest(test_name, std::move(empty_args)); |
| } |
| |
| bool BaseWebUIBrowserTest::RunJavascriptTest(const std::string& test_name, |
| base::Value arg) { |
| std::vector<base::Value> args; |
| args.push_back(std::move(arg)); |
| return RunJavascriptTest(test_name, std::move(args)); |
| } |
| |
| bool BaseWebUIBrowserTest::RunJavascriptTest(const std::string& test_name, |
| base::Value arg1, |
| base::Value arg2) { |
| std::vector<base::Value> args; |
| args.push_back(std::move(arg1)); |
| args.push_back(std::move(arg2)); |
| return RunJavascriptTest(test_name, std::move(args)); |
| } |
| |
| bool BaseWebUIBrowserTest::RunJavascriptTest( |
| const std::string& test_name, |
| std::vector<base::Value> test_arguments) { |
| return RunJavascriptUsingHandler(test_name, std::move(test_arguments), true, |
| false, nullptr); |
| } |
| |
| bool BaseWebUIBrowserTest::RunJavascriptAsyncTest( |
| const std::string& test_name) { |
| std::vector<base::Value> empty_args; |
| return RunJavascriptAsyncTest(test_name, std::move(empty_args)); |
| } |
| |
| bool BaseWebUIBrowserTest::RunJavascriptAsyncTest(const std::string& test_name, |
| base::Value arg) { |
| std::vector<base::Value> args; |
| args.push_back(std::move(arg)); |
| return RunJavascriptAsyncTest(test_name, std::move(args)); |
| } |
| |
| bool BaseWebUIBrowserTest::RunJavascriptAsyncTest(const std::string& test_name, |
| base::Value arg1, |
| base::Value arg2) { |
| std::vector<base::Value> args; |
| args.push_back(std::move(arg1)); |
| args.push_back(std::move(arg2)); |
| return RunJavascriptAsyncTest(test_name, std::move(args)); |
| } |
| |
| bool BaseWebUIBrowserTest::RunJavascriptAsyncTest(const std::string& test_name, |
| base::Value arg1, |
| base::Value arg2, |
| base::Value arg3) { |
| std::vector<base::Value> args; |
| args.push_back(std::move(arg1)); |
| args.push_back(std::move(arg2)); |
| args.push_back(std::move(arg3)); |
| return RunJavascriptAsyncTest(test_name, std::move(args)); |
| } |
| |
| bool BaseWebUIBrowserTest::RunJavascriptAsyncTest( |
| const std::string& test_name, |
| std::vector<base::Value> test_arguments) { |
| return RunJavascriptUsingHandler(test_name, std::move(test_arguments), true, |
| true, nullptr); |
| } |
| |
| void BaseWebUIBrowserTest::PreLoadJavascriptLibraries( |
| const std::string& preload_test_fixture, |
| const std::string& preload_test_name, |
| RenderFrameHost* preload_frame) { |
| // We shouldn't preload libraries twice for the same frame in the same |
| // process. |
| auto global_frame_routing_id = preload_frame->GetGlobalId(); |
| ASSERT_FALSE( |
| base::Contains(libraries_preloaded_for_frames_, global_frame_routing_id)); |
| |
| std::vector<base::Value> args; |
| args.push_back(base::Value(preload_test_fixture)); |
| args.push_back(base::Value(preload_test_name)); |
| RunJavascriptUsingHandler("preloadJavascriptLibraries", std::move(args), |
| false, false, preload_frame); |
| libraries_preloaded_for_frames_.emplace(global_frame_routing_id); |
| |
| bool should_wait_flag = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| ::switches::kWaitForDebuggerWebUI); |
| |
| if (should_wait_flag) |
| RunJavascriptUsingHandler("setWaitUser", {}, false, false, preload_frame); |
| } |
| |
| void BaseWebUIBrowserTest::BrowsePreload(const GURL& browse_to) { |
| content::WebContents* web_contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| WebUIJsInjectionReadyObserver injection_observer( |
| web_contents, this, preload_test_fixture_, preload_test_name_); |
| content::TestNavigationObserver navigation_observer(web_contents); |
| |
| NavigateParams params(browser(), browse_to, ui::PAGE_TRANSITION_TYPED); |
| params.disposition = WindowOpenDisposition::CURRENT_TAB; |
| |
| Navigate(¶ms); |
| navigation_observer.Wait(); |
| } |
| |
| #if BUILDFLAG(ENABLE_PRINT_PREVIEW) |
| |
| // This custom ContentBrowserClient is used to get notified when a WebContents |
| // for the print preview dialog gets created. |
| class PrintContentBrowserClient : public ChromeContentBrowserClient { |
| public: |
| PrintContentBrowserClient(BaseWebUIBrowserTest* browser_test, |
| const std::string& preload_test_fixture, |
| const std::string& preload_test_name) |
| : browser_test_(browser_test), |
| preload_test_fixture_(preload_test_fixture), |
| preload_test_name_(preload_test_name), |
| message_loop_runner_( |
| base::MakeRefCounted<content::MessageLoopRunner>()) {} |
| |
| void Wait() { |
| message_loop_runner_->Run(); |
| EXPECT_TRUE(content::WaitForLoadStop(preview_dialog_)); |
| } |
| |
| private: |
| // ChromeContentBrowserClient implementation: |
| content::WebContentsViewDelegate* GetWebContentsViewDelegate( |
| content::WebContents* web_contents) override { |
| preview_dialog_ = web_contents; |
| observer_ = std::make_unique<WebUIJsInjectionReadyObserver>( |
| preview_dialog_, browser_test_, preload_test_fixture_, |
| preload_test_name_); |
| message_loop_runner_->Quit(); |
| return nullptr; |
| } |
| |
| const raw_ptr<BaseWebUIBrowserTest> browser_test_; |
| std::unique_ptr<WebUIJsInjectionReadyObserver> observer_; |
| std::string preload_test_fixture_; |
| std::string preload_test_name_; |
| raw_ptr<content::WebContents> preview_dialog_ = nullptr; |
| scoped_refptr<content::MessageLoopRunner> message_loop_runner_; |
| }; |
| #endif |
| |
| BaseWebUIBrowserTest::BaseWebUIBrowserTest() = default; |
| |
| void BaseWebUIBrowserTest::set_preload_test_fixture( |
| const std::string& preload_test_fixture) { |
| preload_test_fixture_ = preload_test_fixture; |
| } |
| |
| void BaseWebUIBrowserTest::set_preload_test_name( |
| const std::string& preload_test_name) { |
| preload_test_name_ = preload_test_name; |
| } |
| |
| void BaseWebUIBrowserTest::set_webui_host(const std::string& webui_host) { |
| test_factory_->set_webui_host(webui_host); |
| } |
| |
| namespace { |
| |
| const GURL& DummyUrl() { |
| static GURL url(content::GetWebUIURLString("DummyURL")); |
| return url; |
| } |
| |
| // DataSource for the dummy URL. If no data source is provided then an error |
| // page is shown. While this doesn't matter for most tests, without it, |
| // navigation to different anchors cannot be listened to (via the hashchange |
| // event). |
| class MockWebUIDataSource : public content::URLDataSource { |
| public: |
| MockWebUIDataSource() = default; |
| MockWebUIDataSource(const MockWebUIDataSource&) = delete; |
| MockWebUIDataSource& operator=(const MockWebUIDataSource&) = delete; |
| ~MockWebUIDataSource() override = default; |
| |
| private: |
| std::string GetSource() override { return "dummyurl"; } |
| |
| void StartDataRequest( |
| const GURL& url, |
| const content::WebContents::Getter& wc_getter, |
| content::URLDataSource::GotDataCallback callback) override { |
| std::string dummy_html = "<html><body>Dummy</body></html>"; |
| scoped_refptr<base::RefCountedString> response = |
| base::RefCountedString::TakeString(&dummy_html); |
| std::move(callback).Run(response.get()); |
| } |
| |
| std::string GetMimeType(const std::string& path) override { |
| return "text/html"; |
| } |
| |
| std::string GetContentSecurityPolicy( |
| const network::mojom::CSPDirectiveName directive) override { |
| if (directive == network::mojom::CSPDirectiveName::ScriptSrc) { |
| return "script-src chrome://resources 'self';"; |
| } else if (directive == |
| network::mojom::CSPDirectiveName::RequireTrustedTypesFor || |
| directive == network::mojom::CSPDirectiveName::TrustedTypes) { |
| return std::string(); |
| } |
| |
| return content::URLDataSource::GetContentSecurityPolicy(directive); |
| } |
| }; |
| |
| // WebUIProvider to allow attaching the DataSource for the dummy URL when |
| // testing. |
| class MockWebUIProvider |
| : public TestChromeWebUIControllerFactory::WebUIProvider { |
| public: |
| MockWebUIProvider() = default; |
| MockWebUIProvider(const MockWebUIProvider&) = delete; |
| MockWebUIProvider& operator=(const MockWebUIProvider&) = delete; |
| ~MockWebUIProvider() override = default; |
| |
| // Returns a new WebUI |
| std::unique_ptr<WebUIController> NewWebUI(content::WebUI* web_ui, |
| const GURL& url) override { |
| content::URLDataSource::Add(Profile::FromWebUI(web_ui), |
| std::make_unique<MockWebUIDataSource>()); |
| return std::make_unique<content::WebUIController>(web_ui); |
| } |
| }; |
| |
| base::LazyInstance<MockWebUIProvider>::DestructorAtExit mock_provider_ = |
| LAZY_INSTANCE_INITIALIZER; |
| |
| } // namespace |
| |
| void BaseWebUIBrowserTest::SetUpCommandLine(base::CommandLine* command_line) { |
| JavaScriptBrowserTest::SetUpCommandLine(command_line); |
| |
| // Enables the MojoJSTest bindings which are used for WebUI tests. |
| base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( |
| switches::kEnableBlinkFeatures, "MojoJSTest"); |
| } |
| |
| void BaseWebUIBrowserTest::SetUpOnMainThread() { |
| JavaScriptBrowserTest::SetUpOnMainThread(); |
| |
| base::FilePath pak_path; |
| ASSERT_TRUE(base::PathService::Get(base::DIR_ASSETS, &pak_path)); |
| pak_path = pak_path.AppendASCII("browser_tests.pak"); |
| ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath( |
| pak_path, ui::kScaleFactorNone); |
| |
| base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| if (command_line->HasSwitch(switches::kDevtoolsCodeCoverage)) { |
| base::FilePath devtools_code_coverage_dir = |
| command_line->GetSwitchValuePath(switches::kDevtoolsCodeCoverage); |
| coverage_handler_ = |
| std::make_unique<WebUICoverageObserver>(devtools_code_coverage_dir); |
| } |
| |
| logging::SetLogMessageHandler(&LogHandler); |
| |
| test_factory_ = std::make_unique<TestChromeWebUIControllerFactory>(); |
| factory_registration_ = |
| std::make_unique<content::ScopedWebUIControllerFactoryRegistration>( |
| test_factory_.get(), ChromeWebUIControllerFactory::GetInstance()); |
| |
| test_factory_->AddFactoryOverride(DummyUrl().host(), |
| mock_provider_.Pointer()); |
| test_factory_->AddFactoryOverride(content::kChromeUIResourcesHost, |
| mock_provider_.Pointer()); |
| } |
| |
| void BaseWebUIBrowserTest::TearDownOnMainThread() { |
| logging::SetLogMessageHandler(nullptr); |
| |
| test_factory_->RemoveFactoryOverride(DummyUrl().host()); |
| // |factory_registration_| must be reset before |test_factory_| to remove |
| // any pointers to |test_factory_| from the factory registry before its |
| // destruction. |
| factory_registration_.reset(); |
| test_factory_.reset(); |
| } |
| |
| void BaseWebUIBrowserTest::SetWebUIInstance(content::WebUI* web_ui) { |
| override_selected_web_ui_ = web_ui; |
| } |
| |
| WebUIMessageHandler* BaseWebUIBrowserTest::GetMockMessageHandler() { |
| return nullptr; |
| } |
| |
| bool BaseWebUIBrowserTest::RunJavascriptUsingHandler( |
| const std::string& function_name, |
| std::vector<base::Value> function_arguments, |
| bool is_test, |
| bool is_async, |
| RenderFrameHost* preload_frame) { |
| if (!preload_frame) |
| SetupHandlers(); |
| |
| // Get the user libraries. Preloading them individually is best, then |
| // we can assign each one a filename for better stack traces. Otherwise |
| // append them all to |content|. |
| std::u16string content; |
| std::vector<std::u16string> libraries; |
| |
| // Some tests don't use `BaseWebUIBrowserTest::BrowsePreload()`, which is |
| // where we attach WebUIJsInjectionReadyObserver and preload libraries. In |
| // these cases prepend the libraries to the test itself. |
| auto* frame_for_libraries = preload_frame |
| ? preload_frame |
| : test_handler_->GetRenderFrameHostForTest(); |
| if (!base::Contains(libraries_preloaded_for_frames_, |
| frame_for_libraries->GetGlobalId())) { |
| BuildJavascriptLibraries(&libraries); |
| if (!preload_frame) { |
| content = base::JoinString(libraries, u"\n"); |
| libraries.clear(); |
| } |
| } |
| |
| if (!function_name.empty()) { |
| std::u16string called_function; |
| if (is_test) { |
| called_function = BuildRunTestJSCall(is_async, function_name, |
| std::move(function_arguments)); |
| } else { |
| std::vector<const base::Value*> ptr_vector(function_arguments.size()); |
| for (size_t i = 0; i < function_arguments.size(); ++i) |
| ptr_vector[i] = &function_arguments[i]; |
| called_function = |
| content::WebUI::GetJavascriptCall(function_name, ptr_vector); |
| } |
| content.append(called_function); |
| } |
| |
| bool result = true; |
| |
| for (const std::u16string& library : libraries) |
| test_handler_->PreloadJavaScript(library, preload_frame); |
| |
| if (is_test) |
| result = test_handler_->RunJavaScriptTestWithResult(content); |
| else if (preload_frame) |
| test_handler_->PreloadJavaScript(content, preload_frame); |
| else |
| test_handler_->RunJavaScript(content); |
| |
| if (g_error_messages.Get().size() > 0) { |
| LOG(ERROR) << "CONDITION FAILURE: encountered javascript console error(s):"; |
| for (const auto& msg : g_error_messages.Get()) { |
| LOG(ERROR) << "JS ERROR: '" << msg << "'"; |
| } |
| LOG(ERROR) << "JS call assumed failed, because JS console error(s) found."; |
| |
| result = false; |
| g_error_messages.Get().clear(); |
| } |
| return result; |
| } |
| |
| GURL BaseWebUIBrowserTest::WebUITestDataPathToURL( |
| const base::FilePath::StringType& path) { |
| base::ScopedAllowBlockingForTesting allow_blocking; |
| base::FilePath test_path(JsTestApiConfig().search_path); |
| EXPECT_TRUE(base::PathExists(test_path)); |
| return net::FilePathToFileURL(test_path); |
| } |
| |
| WebUIBrowserTest::WebUIBrowserTest() |
| : test_message_handler_(new WebUITestMessageHandler) { |
| set_test_handler(std::unique_ptr<WebUITestHandler>(test_message_handler_)); |
| } |
| |
| WebUIBrowserTest::~WebUIBrowserTest() = default; |
| |
| void WebUIBrowserTest::SetupHandlers() { |
| content::WebUI* web_ui_instance = |
| override_selected_web_ui() |
| ? override_selected_web_ui() |
| : browser()->tab_strip_model()->GetActiveWebContents()->GetWebUI(); |
| ASSERT_TRUE(web_ui_instance); |
| |
| test_message_handler_->set_web_ui(web_ui_instance); |
| test_message_handler_->RegisterMessages(); |
| |
| if (GetMockMessageHandler()) { |
| GetMockMessageHandler()->set_web_ui(web_ui_instance); |
| GetMockMessageHandler()->RegisterMessages(); |
| } |
| } |
| |
| void WebUIBrowserTest::CollectCoverage(const std::string& test_name) { |
| return coverage_handler_->CollectCoverage(test_name); |
| } |