diff options
author | nyquist <nyquist@chromium.org> | 2015-04-13 12:13:50 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-13 19:14:15 +0000 |
commit | f2bd69ae5e61797b713833f67dc7ecb557a51f15 (patch) | |
tree | 084d2cd9040fb21d766103d0aa723732f77c3b9b /components | |
parent | 2411f2af4b2f92c725c0798400bc1253bae40e46 (diff) | |
download | chromium_src-f2bd69ae5e61797b713833f67dc7ecb557a51f15.zip chromium_src-f2bd69ae5e61797b713833f67dc7ecb557a51f15.tar.gz chromium_src-f2bd69ae5e61797b713833f67dc7ecb557a51f15.tar.bz2 |
Add browsertest for running DOM Distiller JS tests.
The JavaScript parts of DOM Distiller lives in a different repository,
and is using ChromeDriver to run the JS-based tests.
This CL adds a browsertest using Content Shell to run the same tests.
The tests are run as a single gtest in Chromium, and fails only if
the 'success' JSON-field is parsed to be false. The console log output
is suppressed while the tests are run, but it is output if the test
fails.
BUG=471854
Review URL: https://codereview.chromium.org/880553004
Cr-Commit-Position: refs/heads/master@{#324894}
Diffstat (limited to 'components')
4 files changed, 202 insertions, 36 deletions
diff --git a/components/components_browsertests.isolate b/components/components_browsertests.isolate index f384f85f..2dff53a 100644 --- a/components/components_browsertests.isolate +++ b/components/components_browsertests.isolate @@ -39,6 +39,7 @@ 'files': [ 'test/data/', '../testing/test_env.py', + '../third_party/dom_distiller_js/dist/test/data/', '<(PRODUCT_DIR)/components_browsertests<(EXECUTABLE_SUFFIX)', '<(PRODUCT_DIR)/components_tests_resources.pak', '<(PRODUCT_DIR)/content_shell.pak', diff --git a/components/components_tests.gyp b/components/components_tests.gyp index a1ab4f8..bf2b5a3 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp @@ -1122,6 +1122,7 @@ 'autofill/content/renderer/password_form_conversion_utils_browsertest.cc', 'dom_distiller/content/distillable_page_utils_browsertest.cc', 'dom_distiller/content/distiller_page_web_contents_browsertest.cc', + 'dom_distiller/content/test/dom_distiller_js_browsertest.cc', 'password_manager/content/renderer/credential_manager_client_browsertest.cc', ], 'conditions': [ diff --git a/components/dom_distiller/content/distiller_page_web_contents_browsertest.cc b/components/dom_distiller/content/distiller_page_web_contents_browsertest.cc index 2c84e6b..79d557a 100644 --- a/components/dom_distiller/content/distiller_page_web_contents_browsertest.cc +++ b/components/dom_distiller/content/distiller_page_web_contents_browsertest.cc @@ -30,6 +30,46 @@ using testing::ContainsRegex; using testing::HasSubstr; using testing::Not; +namespace { + +// Helper class to know how far in the loading process the current WebContents +// has come. It will call the callback either after +// DidCommitProvisionalLoadForFrame or DocumentLoadedInFrame is called for the +// main frame, based on the value of |wait_for_document_loaded|. +class WebContentsMainFrameHelper : public content::WebContentsObserver { + public: + WebContentsMainFrameHelper(content::WebContents* web_contents, + const base::Closure& callback, + bool wait_for_document_loaded) + : WebContentsObserver(web_contents), + callback_(callback), + wait_for_document_loaded_(wait_for_document_loaded) {} + + void DidCommitProvisionalLoadForFrame( + content::RenderFrameHost* render_frame_host, + const GURL& url, + ui::PageTransition transition_type) override { + if (wait_for_document_loaded_) + return; + if (!render_frame_host->GetParent()) + callback_.Run(); + } + + void DocumentLoadedInFrame( + content::RenderFrameHost* render_frame_host) override { + if (wait_for_document_loaded_) { + if (!render_frame_host->GetParent()) + callback_.Run(); + } + } + + private: + base::Closure callback_; + bool wait_for_document_loaded_; +}; + +} // namespace + namespace dom_distiller { const char* kSimpleArticlePath = "/simple_article.html"; @@ -130,42 +170,6 @@ class TestDistillerPageWebContents : public DistillerPageWebContents { bool new_web_contents_created_; }; -// Helper class to know how far in the loading process the current WebContents -// has come. It will call the callback either after -// DidCommitProvisionalLoadForFrame or DocumentLoadedInFrame is called for the -// main frame, based on the value of |wait_for_document_loaded|. -class WebContentsMainFrameHelper : public content::WebContentsObserver { - public: - WebContentsMainFrameHelper(content::WebContents* web_contents, - const base::Closure& callback, - bool wait_for_document_loaded) - : WebContentsObserver(web_contents), - callback_(callback), - wait_for_document_loaded_(wait_for_document_loaded) {} - - void DidCommitProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& url, - ui::PageTransition transition_type) override { - if (wait_for_document_loaded_) - return; - if (!render_frame_host->GetParent()) - callback_.Run(); - } - - void DocumentLoadedInFrame( - content::RenderFrameHost* render_frame_host) override { - if (wait_for_document_loaded_) { - if (!render_frame_host->GetParent()) - callback_.Run(); - } - } - - private: - base::Closure callback_; - bool wait_for_document_loaded_; -}; - IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, BasicDistillationWorks) { DistillerPageWebContents distiller_page( shell()->web_contents()->GetBrowserContext(), diff --git a/components/dom_distiller/content/test/dom_distiller_js_browsertest.cc b/components/dom_distiller/content/test/dom_distiller_js_browsertest.cc new file mode 100644 index 0000000..53b37b6 --- /dev/null +++ b/components/dom_distiller/content/test/dom_distiller_js_browsertest.cc @@ -0,0 +1,160 @@ +// Copyright 2015 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/callback.h" +#include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "base/path_service.h" +#include "base/run_loop.h" +#include "base/strings/utf_string_conversions.h" +#include "base/time/time.h" +#include "base/values.h" +#include "components/dom_distiller/content/web_contents_main_frame_observer.h" +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/test/content_browser_test.h" +#include "content/shell/browser/shell.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "ui/base/resource/resource_bundle.h" + +namespace { + +// Helper class to know how far in the loading process the current WebContents +// has come. It will call the callback after DocumentLoadedInFrame is called for +// the main frame. +class WebContentsMainFrameHelper : public content::WebContentsObserver { + public: + WebContentsMainFrameHelper(content::WebContents* web_contents, + const base::Closure& callback) + : WebContentsObserver(web_contents), callback_(callback) {} + + void DocumentLoadedInFrame( + content::RenderFrameHost* render_frame_host) override { + if (!render_frame_host->GetParent()) + callback_.Run(); + } + + private: + base::Closure callback_; +}; + +} // namespace + +namespace dom_distiller { + +const char* kExternalTestResourcesPath = + "third_party/dom_distiller_js/dist/test/data"; +// TODO(wychen) Remove filter when crbug.com/471854 is fixed. +const char* kTestFilePath = + "/war/test.html?console_log=0&filter=-*.SchemaOrgParserAccessorTest.*"; +const char* kRunJsTestsJs = + "(function() {return org.chromium.distiller.JsTestEntry.run();})();"; + +class DomDistillerJsTest : public content::ContentBrowserTest { + public: + DomDistillerJsTest() : result_(NULL) {} + + // content::ContentBrowserTest: + void SetUpOnMainThread() override { + AddComponentsResources(); + SetUpTestServer(); + content::ContentBrowserTest::SetUpOnMainThread(); + } + + void OnJsTestExecutionDone(const base::Value* value) { + result_ = value->DeepCopy(); + js_test_execution_done_callback_.Run(); + } + + protected: + base::Closure js_test_execution_done_callback_; + const base::Value* result_; + + private: + void AddComponentsResources() { + base::FilePath pak_file; + base::FilePath pak_dir; + PathService::Get(base::DIR_MODULE, &pak_dir); + pak_file = pak_dir.Append(FILE_PATH_LITERAL("components_resources.pak")); + ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath( + pak_file, ui::SCALE_FACTOR_NONE); + } + + void SetUpTestServer() { + base::FilePath path; + PathService::Get(base::DIR_SOURCE_ROOT, &path); + path = path.AppendASCII(kExternalTestResourcesPath); + embedded_test_server()->ServeFilesFromDirectory(path); + ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); + } +}; + +IN_PROC_BROWSER_TEST_F(DomDistillerJsTest, RunJsTests) { + // Load the test file in content shell and wait until it has fully loaded. + content::WebContents* web_contents = shell()->web_contents(); + dom_distiller::WebContentsMainFrameObserver::CreateForWebContents( + web_contents); + base::RunLoop url_loaded_runner; + WebContentsMainFrameHelper main_frame_loaded(web_contents, + url_loaded_runner.QuitClosure()); + web_contents->GetController().LoadURL( + embedded_test_server()->GetURL(kTestFilePath), + content::Referrer(), + ui::PAGE_TRANSITION_TYPED, + std::string()); + url_loaded_runner.Run(); + + // Execute the JS to run the tests, and wait until it has finished. + base::RunLoop run_loop; + js_test_execution_done_callback_ = run_loop.QuitClosure(); + // Add timeout in case JS Test execution fails. It is safe to call the + // QuitClosure multiple times. + base::MessageLoop::current()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromSeconds(15)); + web_contents->GetMainFrame()->ExecuteJavaScript( + base::UTF8ToUTF16(kRunJsTestsJs), + base::Bind(&DomDistillerJsTest::OnJsTestExecutionDone, + base::Unretained(this))); + run_loop.Run(); + + // By now either the timeout has triggered, or there should be a result. + ASSERT_TRUE(result_ != NULL) << "No result found. Timeout?"; + + // Convert to dictionary and parse the results. + const base::DictionaryValue* dict; + result_->GetAsDictionary(&dict); + ASSERT_TRUE(result_->GetAsDictionary(&dict)); + + ASSERT_TRUE(dict->HasKey("success")); + bool success; + ASSERT_TRUE(dict->GetBoolean("success", &success)); + + ASSERT_TRUE(dict->HasKey("numTests")); + int num_tests; + ASSERT_TRUE(dict->GetInteger("numTests", &num_tests)); + + ASSERT_TRUE(dict->HasKey("failed")); + int failed; + ASSERT_TRUE(dict->GetInteger("failed", &failed)); + + ASSERT_TRUE(dict->HasKey("skipped")); + int skipped; + ASSERT_TRUE(dict->GetInteger("skipped", &skipped)); + + VLOG(0) << "Ran " << num_tests << " tests. failed = " << failed + << " skipped = " << skipped; + // Ensure that running the tests succeeded. + EXPECT_TRUE(success); + + // Only print the log if there was an error. + if (!success) { + ASSERT_TRUE(dict->HasKey("log")); + std::string console_log; + ASSERT_TRUE(dict->GetString("log", &console_log)); + VLOG(0) << "Console log:\n" << console_log; + } +} + +} // namespace dom_distiller |