diff options
author | Ben Murdoch <benm@google.com> | 2014-07-20 18:25:52 -0700 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2014-07-20 18:25:52 -0700 |
commit | 116680a4aac90f2aa7413d9095a592090648e557 (patch) | |
tree | f7c6fed0e63d6a2804243d4a31a752dca39fb076 /chrome/test | |
parent | 1f14a4515e04c9ffc9bac4dd1e2f68611626b800 (diff) | |
download | chromium_org-116680a4aac90f2aa7413d9095a592090648e557.tar.gz |
Merge from Chromium at DEPS revision 284076
This commit was generated by merge_to_master.py.
Change-Id: I9a279485b02fe7ceddcd32d992a714ff132e99ae
Diffstat (limited to 'chrome/test')
69 files changed, 947 insertions, 617 deletions
diff --git a/chrome/test/DEPS b/chrome/test/DEPS index 595b0db1c9..a3fac31973 100644 --- a/chrome/test/DEPS +++ b/chrome/test/DEPS @@ -14,10 +14,10 @@ include_rules = [ # within content/ and a test within chrome/. "+content/public", + "+gin/public", "+grit", # For generated headers - "+media/audio", "+media/base", - "+sandbox/win/src", + "+mojo/embedder", "+sandbox/win/tests", "+webkit/glue", "+win8/test", diff --git a/chrome/test/android/OWNERS b/chrome/test/android/OWNERS index b8e17f3800..dbab84d92b 100644 --- a/chrome/test/android/OWNERS +++ b/chrome/test/android/OWNERS @@ -1,5 +1,4 @@ aruslan@chromium.org -bulach@chromium.org dfalcantara@chromium.org dtrainor@chromium.org nyquist@chromium.org diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/TabUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/TabUtils.java deleted file mode 100644 index 861180890a..0000000000 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/TabUtils.java +++ /dev/null @@ -1,106 +0,0 @@ -// 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. - -package org.chromium.chrome.test.util; - -import android.view.ContextMenu; - -import org.chromium.base.ThreadUtils; -import org.chromium.chrome.browser.EmptyTabObserver; -import org.chromium.chrome.browser.Tab; -import org.chromium.content.browser.ContentViewClient; -import org.chromium.content.browser.test.util.CallbackHelper; -import org.chromium.content.browser.test.util.TestCallbackHelperContainer; -import org.chromium.content.browser.test.util.TestContentViewClient; -import org.chromium.content.browser.test.util.TestContentViewClientWrapper; -import org.chromium.content.browser.test.util.TestWebContentsObserver; - -import java.lang.ref.WeakReference; -import java.util.concurrent.atomic.AtomicReference; - -/** - * A utility class that contains methods generic to all Tabs tests. - */ -public class TabUtils { - private static TestContentViewClient createTestContentViewClientForTab(Tab tab) { - ContentViewClient client = tab.getContentViewCore().getContentViewClient(); - if (client instanceof TestContentViewClient) return (TestContentViewClient) client; - - TestContentViewClient testClient = new TestContentViewClientWrapper(client); - tab.getContentViewCore().setContentViewClient(testClient); - return testClient; - } - - /** - * Provides some callback helpers when waiting for certain tab-based events to occur. - */ - public static class TestCallbackHelperContainerForTab extends TestCallbackHelperContainer { - private final CallbackHelper mOnCloseTabHelper; - private final OnContextMenuShownHelper mOnContextMenuShownHelper; - - private TestCallbackHelperContainerForTab(Tab tab) { - super(createTestContentViewClientForTab(tab), - new TestWebContentsObserver(tab.getContentViewCore())); - mOnCloseTabHelper = new CallbackHelper(); - mOnContextMenuShownHelper = new OnContextMenuShownHelper(); - tab.addObserver(new EmptyTabObserver() { - @Override - public void onDestroyed(Tab tab) { - mOnCloseTabHelper.notifyCalled(); - } - - @Override - public void onContextMenuShown(Tab tab, ContextMenu menu) { - mOnContextMenuShownHelper.notifyCalled(menu); - } - }); - } - - /** - * Callback helper that also provides access to the last display ContextMenu. - */ - public static class OnContextMenuShownHelper extends CallbackHelper { - private WeakReference<ContextMenu> mContextMenu; - - public void notifyCalled(ContextMenu menu) { - mContextMenu = new WeakReference<ContextMenu>(menu); - notifyCalled(); - } - - public ContextMenu getContextMenu() { - assert getCallCount() > 0; - return mContextMenu.get(); - } - } - - public CallbackHelper getOnCloseTabHelper() { - return mOnCloseTabHelper; - } - - public OnContextMenuShownHelper getOnContextMenuShownHelper() { - return mOnContextMenuShownHelper; - } - } - - /** - * Creates, binds and returns a TestCallbackHelperContainer for a given Tab. - */ - public static TestCallbackHelperContainerForTab getTestCallbackHelperContainer(final Tab tab) { - if (tab == null) { - return null; - } - final AtomicReference<TestCallbackHelperContainerForTab> result = - new AtomicReference<TestCallbackHelperContainerForTab>(); - // TODO(yfriedman): Change callers to be executed on the UI thread. Unfortunately this is - // super convenient as the caller is nearly always on the test thread which is fine to block - // and it's cumbersome to keep bouncing to the UI thread. - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - result.set(new TestCallbackHelperContainerForTab(tab)); - } - }); - return result.get(); - } -} diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/contextmenu/ContextMenuUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/contextmenu/ContextMenuUtils.java index 7a0e8a1d7f..574b6e2e10 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/contextmenu/ContextMenuUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/contextmenu/ContextMenuUtils.java @@ -11,13 +11,14 @@ import android.view.MenuItem; import junit.framework.Assert; +import org.chromium.chrome.browser.EmptyTabObserver; import org.chromium.chrome.browser.Tab; -import org.chromium.chrome.test.util.TabUtils; -import org.chromium.chrome.test.util.TabUtils.TestCallbackHelperContainerForTab; +import org.chromium.content.browser.test.util.CallbackHelper; import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; import org.chromium.content.browser.test.util.DOMUtils; +import java.lang.ref.WeakReference; import java.util.concurrent.TimeoutException; /** @@ -25,24 +26,41 @@ import java.util.concurrent.TimeoutException; */ public class ContextMenuUtils { /** + * Callback helper that also provides access to the last display ContextMenu. + */ + private static class OnContextMenuShownHelper extends CallbackHelper { + private WeakReference<ContextMenu> mContextMenu; + + public void notifyCalled(ContextMenu menu) { + mContextMenu = new WeakReference<ContextMenu>(menu); + notifyCalled(); + } + + public ContextMenu getContextMenu() { + assert getCallCount() > 0; + return mContextMenu.get(); + } + } + + /** * Opens a context menu. * @param testCase The test harness. * @param tab The tab to open a context menu for. - * @param client The helper client for {@code tab} that can wait for events. If - * this is {@code null} one will be built automatically. * @param openerDOMNodeId The DOM node to long press to open the context menu for. * @return The {@link ContextMenu} that was opened. * @throws InterruptedException * @throws TimeoutException */ public static ContextMenu openContextMenu(ActivityInstrumentationTestCase2 testCase, - Tab tab, TestCallbackHelperContainerForTab client, String openerDOMNodeId) + Tab tab, String openerDOMNodeId) throws InterruptedException, TimeoutException { - if (client == null) client = TabUtils.getTestCallbackHelperContainer(tab); - - TestCallbackHelperContainerForTab.OnContextMenuShownHelper helper = - client.getOnContextMenuShownHelper(); - + final OnContextMenuShownHelper helper = new OnContextMenuShownHelper(); + tab.addObserver(new EmptyTabObserver() { + @Override + public void onContextMenuShown(Tab tab, ContextMenu menu) { + helper.notifyCalled(menu); + } + }); int callCount = helper.getCallCount(); DOMUtils.longPressNode(testCase, tab.getContentViewCore(), openerDOMNodeId); @@ -54,17 +72,15 @@ public class ContextMenuUtils { * Opens and selects an item from a context menu. * @param testCase The test harness. * @param tab The tab to open a context menu for. - * @param client The helper client for {@code tab} that can wait for events. If - * this is {@code null} one will be built automatically. * @param openerDOMNodeId The DOM node to long press to open the context menu for. * @param itemId The context menu item ID to select. * @throws InterruptedException * @throws TimeoutException */ public static void selectContextMenuItem(ActivityInstrumentationTestCase2 testCase, - Tab tab, TestCallbackHelperContainerForTab client, String openerDOMNodeId, + Tab tab, String openerDOMNodeId, final int itemId) throws InterruptedException, TimeoutException { - ContextMenu menu = openContextMenu(testCase, tab, client, openerDOMNodeId); + ContextMenu menu = openContextMenu(testCase, tab, openerDOMNodeId); Assert.assertNotNull("Failed to open context menu", menu); selectOpenContextMenuItem(testCase, menu, itemId); @@ -74,18 +90,16 @@ public class ContextMenuUtils { * Opens and selects an item from a context menu. * @param testCase The test harness. * @param tab The tab to open a context menu for. - * @param client The helper client for {@code tab} that can wait for events. If - * this is {@code null} one will be built automatically. * @param openerDOMNodeId The DOM node to long press to open the context menu for. * @param itemTitle The title of the context menu item to select. * @throws InterruptedException * @throws TimeoutException */ public static void selectContextMenuItemByTitle(ActivityInstrumentationTestCase2 testCase, - Tab tab, TestCallbackHelperContainerForTab client, String openerDOMNodeId, + Tab tab, String openerDOMNodeId, String itemTitle) throws InterruptedException, TimeoutException { - ContextMenu menu = openContextMenu(testCase, tab, client, openerDOMNodeId); + ContextMenu menu = openContextMenu(testCase, tab, openerDOMNodeId); Assert.assertNotNull("Failed to open context menu", menu); Integer itemId = null; diff --git a/chrome/test/base/chrome_test_launcher.cc b/chrome/test/base/chrome_test_launcher.cc index b2ee566c98..37e11414f6 100644 --- a/chrome/test/base/chrome_test_launcher.cc +++ b/chrome/test/base/chrome_test_launcher.cc @@ -28,11 +28,6 @@ #include "chrome/browser/chrome_browser_application_mac.h" #endif // defined(OS_MACOSX) -#if defined(OS_WIN) -#include "content/public/app/startup_helper_win.h" -#include "sandbox/win/src/sandbox_types.h" -#endif // defined(OS_WIN) - #if defined(USE_AURA) #include "ui/aura/test/ui_controls_factory_aura.h" #include "ui/base/test/ui_controls_aura.h" diff --git a/chrome/test/base/chrome_unit_test_suite.cc b/chrome/test/base/chrome_unit_test_suite.cc index 9e40a6590a..6d8b4efa7b 100644 --- a/chrome/test/base/chrome_unit_test_suite.cc +++ b/chrome/test/base/chrome_unit_test_suite.cc @@ -6,13 +6,15 @@ #include "base/path_service.h" #include "base/process/process_handle.h" -#include "base/metrics/stats_table.h" #include "base/strings/stringprintf.h" #include "chrome/browser/chrome_content_browser_client.h" +#include "chrome/browser/omaha_query_params/chrome_omaha_query_params_delegate.h" #include "chrome/common/chrome_content_client.h" #include "chrome/common/chrome_paths.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/utility/chrome_content_utility_client.h" +#include "components/component_updater/component_updater_paths.h" +#include "components/omaha_query_params/omaha_query_params.h" #include "content/public/common/content_paths.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/resource/resource_bundle.h" @@ -98,12 +100,6 @@ void ChromeUnitTestSuite::Initialize() { InitializeProviders(); RegisterInProcessThreads(); - // Create an anonymous stats table since we don't need to share between - // processes. - stats_table_.reset( - new base::StatsTable(base::StatsTable::TableIdentifier(), 20, 200)); - base::StatsTable::set_current(stats_table_.get()); - ChromeTestSuite::Initialize(); // This needs to run after ChromeTestSuite::Initialize which calls content's @@ -113,10 +109,6 @@ void ChromeUnitTestSuite::Initialize() { void ChromeUnitTestSuite::Shutdown() { ResourceBundle::CleanupSharedInstance(); - - base::StatsTable::set_current(NULL); - stats_table_.reset(); - ChromeTestSuite::Shutdown(); } @@ -130,6 +122,10 @@ void ChromeUnitTestSuite::InitializeProviders() { content::RegisterPathProvider(); ui::RegisterPathProvider(); + base::FilePath user_data; + if (PathService::Get(chrome::DIR_USER_DATA, &user_data)) + component_updater::RegisterPathProvider(user_data); + #if defined(OS_CHROMEOS) chromeos::RegisterPathProvider(); #endif @@ -144,6 +140,9 @@ void ChromeUnitTestSuite::InitializeProviders() { ChromeWebUIControllerFactory::GetInstance()); gfx::GLSurface::InitializeOneOffForTests(); + + omaha_query_params::OmahaQueryParams::SetDelegate( + ChromeOmahaQueryParamsDelegate::GetInstance()); #endif } diff --git a/chrome/test/base/chrome_unit_test_suite.h b/chrome/test/base/chrome_unit_test_suite.h index 0ac9eb4671..1c1ddbdf43 100644 --- a/chrome/test/base/chrome_unit_test_suite.h +++ b/chrome/test/base/chrome_unit_test_suite.h @@ -10,10 +10,6 @@ #include "base/files/file_path.h" #include "chrome/test/base/chrome_test_suite.h" -namespace base { -class StatsTable; -} - // Test suite for unit tests. Creates additional stub services that are not // needed for browser tests (e.g. a TestingBrowserProcess). class ChromeUnitTestSuite : public ChromeTestSuite { @@ -32,7 +28,6 @@ class ChromeUnitTestSuite : public ChromeTestSuite { static void InitializeResourceBundle(); private: - scoped_ptr<base::StatsTable> stats_table_; DISALLOW_COPY_AND_ASSIGN(ChromeUnitTestSuite); }; diff --git a/chrome/test/base/in_process_browser_test.cc b/chrome/test/base/in_process_browser_test.cc index 8d46230856..c6811cec5a 100644 --- a/chrome/test/base/in_process_browser_test.cc +++ b/chrome/test/base/in_process_browser_test.cc @@ -112,6 +112,7 @@ void SingleDesktopTestObserver::OnBrowserAdded(Browser* browser) { InProcessBrowserTest::InProcessBrowserTest() : browser_(NULL), exit_when_last_browser_closes_(true), + open_about_blank_on_browser_launch_(true), multi_desktop_test_(false) #if defined(OS_MACOSX) , autorelease_pool_(NULL) @@ -248,7 +249,7 @@ void InProcessBrowserTest::PrepareTestCommandLine(CommandLine* command_line) { if (exit_when_last_browser_closes_) command_line->AppendSwitch(switches::kDisableZeroBrowsersOpenForTests); - if (command_line->GetArgs().empty()) + if (open_about_blank_on_browser_launch_ && command_line->GetArgs().empty()) command_line->AppendArg(url::kAboutBlankURL); } diff --git a/chrome/test/base/in_process_browser_test.h b/chrome/test/base/in_process_browser_test.h index a64a47d349..925846eb03 100644 --- a/chrome/test/base/in_process_browser_test.h +++ b/chrome/test/base/in_process_browser_test.h @@ -171,6 +171,10 @@ class InProcessBrowserTest : public content::BrowserTestBase { exit_when_last_browser_closes_ = value; } + void set_open_about_blank_on_browser_launch(bool value) { + open_about_blank_on_browser_launch_ = value; + } + // This must be called before RunTestOnMainThreadLoop() to have any effect. void set_multi_desktop_test(bool multi_desktop_test) { multi_desktop_test_ = multi_desktop_test; @@ -198,6 +202,9 @@ class InProcessBrowserTest : public content::BrowserTestBase { // True if we should exit the tests after the last browser instance closes. bool exit_when_last_browser_closes_; + // True if the about:blank tab should be opened when the browser is launched. + bool open_about_blank_on_browser_launch_; + // True if this is a multi-desktop test (in which case this browser test will // not ensure that Browsers are only created on the tested desktop). bool multi_desktop_test_; diff --git a/chrome/test/base/in_process_browser_test_browsertest.cc b/chrome/test/base/in_process_browser_test_browsertest.cc index 7ab6d5e49c..54f6cb4b5e 100644 --- a/chrome/test/base/in_process_browser_test_browsertest.cc +++ b/chrome/test/base/in_process_browser_test_browsertest.cc @@ -38,13 +38,10 @@ class LoadFailObserver : public content::WebContentsObserver { error_code_(net::OK) { } virtual void DidFailProvisionalLoad( - int64 frame_id, - const base::string16& frame_unique_name, - bool is_main_frame, + content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, - const base::string16& error_description, - content::RenderViewHost* render_view_host) OVERRIDE { + const base::string16& error_description) OVERRIDE { failed_load_ = true; error_code_ = static_cast<net::Error>(error_code); validated_url_ = validated_url; diff --git a/chrome/test/base/js2gtest.js b/chrome/test/base/js2gtest.js index 1aba2ffbf8..c20b934b6f 100644 --- a/chrome/test/base/js2gtest.js +++ b/chrome/test/base/js2gtest.js @@ -36,6 +36,13 @@ var jsFile = arguments[1]; var jsFileBase = arguments[2]; /** + * The cwd, as determined by the paths of |jsFile| and |jsFileBase|. + * This is usually relative to the root source directory and points to the + * directory where the GYP rule processing the js file lives. + */ +var jsDirBase = jsFileBase.replace(jsFile, ''); + +/** * Path to Closure library style deps.js file. * @type {string?} */ @@ -150,9 +157,20 @@ function maybeGenHeader(testFixture) { * inclusion (path) and runtime inclusion (base). * @param {string} includeFile The file to include. * @return {{path: string, base: string}} Object describing the paths - * for |includeFile|. + * for |includeFile|. |path| is relative to cwd; |base| is relative to + * source root. */ function includeFileToPaths(includeFile) { + if (includeFile.indexOf(jsDirBase) == 0) { + // The caller supplied a path relative to root source. + var relPath = includeFile.replace(jsDirBase, ''); + return { + path: relPath, + base: jsDirBase + relPath + }; + } + + // The caller supplied a path relative to the input js file's directory (cwd). return { path: jsFile.replace(/[^\/\\]+$/, includeFile), base: jsFileBase.replace(/[^\/\\]+$/, includeFile), @@ -281,6 +299,9 @@ function GEN_BLOCK(commentEncodedCode) { /** * Generate includes for the current |jsFile| by including them * immediately and at runtime. + * The paths are allowed to be: + * 1. relative to the root src directory (i.e. similar to #include's). + * 2. relative to the directory specified in the GYP rule for the file. * @param {Array.<string>} includes Paths to JavaScript files to * include immediately and at runtime. */ diff --git a/chrome/test/base/module_system_test.cc b/chrome/test/base/module_system_test.cc deleted file mode 100644 index bfc8308f15..0000000000 --- a/chrome/test/base/module_system_test.cc +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright (c) 2012 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/module_system_test.h" - -#include "base/callback.h" -#include "base/file_util.h" -#include "base/files/file_path.h" -#include "base/lazy_instance.h" -#include "base/memory/scoped_ptr.h" -#include "base/path_service.h" -#include "base/stl_util.h" -#include "base/strings/string_piece.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/renderer/extensions/chrome_v8_context.h" -#include "extensions/renderer/logging_native_handler.h" -#include "extensions/renderer/object_backed_native_handler.h" -#include "extensions/renderer/safe_builtins.h" -#include "extensions/renderer/utils_native_handler.h" -#include "ui/base/resource/resource_bundle.h" - -#include <map> -#include <string> - -using extensions::ModuleSystem; -using extensions::NativeHandler; -using extensions::ObjectBackedNativeHandler; - -namespace { - -class FailsOnException : public ModuleSystem::ExceptionHandler { - public: - virtual void HandleUncaughtException(const v8::TryCatch& try_catch) OVERRIDE { - FAIL() << "Uncaught exception: " << CreateExceptionString(try_catch); - } -}; - -class V8ExtensionConfigurator { - public: - V8ExtensionConfigurator() - : safe_builtins_(extensions::SafeBuiltins::CreateV8Extension()), - names_(1, safe_builtins_->name()), - configuration_(new v8::ExtensionConfiguration( - names_.size(), vector_as_array(&names_))) { - v8::RegisterExtension(safe_builtins_.get()); - } - - v8::ExtensionConfiguration* GetConfiguration() { - return configuration_.get(); - } - - private: - scoped_ptr<v8::Extension> safe_builtins_; - std::vector<const char*> names_; - scoped_ptr<v8::ExtensionConfiguration> configuration_; -}; - -base::LazyInstance<V8ExtensionConfigurator>::Leaky g_v8_extension_configurator = - LAZY_INSTANCE_INITIALIZER; - -} // namespace - -// Native JS functions for doing asserts. -class ModuleSystemTest::AssertNatives : public ObjectBackedNativeHandler { - public: - explicit AssertNatives(extensions::ChromeV8Context* context) - : ObjectBackedNativeHandler(context), - assertion_made_(false), - failed_(false) { - RouteFunction("AssertTrue", base::Bind(&AssertNatives::AssertTrue, - base::Unretained(this))); - RouteFunction("AssertFalse", base::Bind(&AssertNatives::AssertFalse, - base::Unretained(this))); - } - - bool assertion_made() { return assertion_made_; } - bool failed() { return failed_; } - - void AssertTrue(const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK_EQ(1, args.Length()); - assertion_made_ = true; - failed_ = failed_ || !args[0]->ToBoolean()->Value(); - } - - void AssertFalse(const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK_EQ(1, args.Length()); - assertion_made_ = true; - failed_ = failed_ || args[0]->ToBoolean()->Value(); - } - - private: - bool assertion_made_; - bool failed_; -}; - -// Source map that operates on std::strings. -class ModuleSystemTest::StringSourceMap : public ModuleSystem::SourceMap { - public: - StringSourceMap() {} - virtual ~StringSourceMap() {} - - virtual v8::Handle<v8::Value> GetSource(v8::Isolate* isolate, - const std::string& name) OVERRIDE { - if (source_map_.count(name) == 0) - return v8::Undefined(isolate); - return v8::String::NewFromUtf8(isolate, source_map_[name].c_str()); - } - - virtual bool Contains(const std::string& name) OVERRIDE { - return source_map_.count(name); - } - - void RegisterModule(const std::string& name, const std::string& source) { - CHECK_EQ(0u, source_map_.count(name)) << "Module " << name << " not found"; - source_map_[name] = source; - } - - private: - std::map<std::string, std::string> source_map_; -}; - -ModuleSystemTest::ModuleSystemTest() - : isolate_(v8::Isolate::GetCurrent()), - handle_scope_(isolate_), - context_( - new extensions::ChromeV8Context( - v8::Context::New( - isolate_, - g_v8_extension_configurator.Get().GetConfiguration()), - NULL, // WebFrame - NULL, // Extension - extensions::Feature::UNSPECIFIED_CONTEXT)), - source_map_(new StringSourceMap()), - should_assertions_be_made_(true) { - context_->v8_context()->Enter(); - assert_natives_ = new AssertNatives(context_.get()); - - { - scoped_ptr<ModuleSystem> module_system( - new ModuleSystem(context_.get(), source_map_.get())); - context_->set_module_system(module_system.Pass()); - } - ModuleSystem* module_system = context_->module_system(); - module_system->RegisterNativeHandler("assert", scoped_ptr<NativeHandler>( - assert_natives_)); - module_system->RegisterNativeHandler("logging", scoped_ptr<NativeHandler>( - new extensions::LoggingNativeHandler(context_.get()))); - module_system->RegisterNativeHandler("utils", scoped_ptr<NativeHandler>( - new extensions::UtilsNativeHandler(context_.get()))); - module_system->SetExceptionHandlerForTest( - scoped_ptr<ModuleSystem::ExceptionHandler>(new FailsOnException)); -} - -ModuleSystemTest::~ModuleSystemTest() { - context_->v8_context()->Exit(); -} - -void ModuleSystemTest::RegisterModule(const std::string& name, - const std::string& code) { - source_map_->RegisterModule(name, code); -} - -void ModuleSystemTest::RegisterModule(const std::string& name, - int resource_id) { - const std::string& code = ResourceBundle::GetSharedInstance(). - GetRawDataResource(resource_id).as_string(); - source_map_->RegisterModule(name, code); -} - -void ModuleSystemTest::OverrideNativeHandler(const std::string& name, - const std::string& code) { - RegisterModule(name, code); - context_->module_system()->OverrideNativeHandlerForTest(name); -} - -void ModuleSystemTest::RegisterTestFile(const std::string& module_name, - const std::string& file_name) { - base::FilePath test_js_file_path; - ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_js_file_path)); - test_js_file_path = test_js_file_path.AppendASCII("extensions") - .AppendASCII(file_name); - std::string test_js; - ASSERT_TRUE(base::ReadFileToString(test_js_file_path, &test_js)); - source_map_->RegisterModule(module_name, test_js); -} - -void ModuleSystemTest::TearDown() { - // All tests must assert at least once unless otherwise specified. - EXPECT_EQ(should_assertions_be_made_, - assert_natives_->assertion_made()); - EXPECT_FALSE(assert_natives_->failed()); -} - -void ModuleSystemTest::ExpectNoAssertionsMade() { - should_assertions_be_made_ = false; -} - -v8::Handle<v8::Object> ModuleSystemTest::CreateGlobal(const std::string& name) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - v8::EscapableHandleScope handle_scope(isolate); - v8::Local<v8::Object> object = v8::Object::New(isolate); - isolate->GetCurrentContext()->Global()->Set( - v8::String::NewFromUtf8(isolate, name.c_str()), object); - return handle_scope.Escape(object); -} diff --git a/chrome/test/base/module_system_test.h b/chrome/test/base/module_system_test.h deleted file mode 100644 index 8402d57b39..0000000000 --- a/chrome/test/base/module_system_test.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef CHROME_TEST_BASE_MODULE_SYSTEM_TEST_H_ -#define CHROME_TEST_BASE_MODULE_SYSTEM_TEST_H_ - -#include "chrome/renderer/extensions/chrome_v8_context.h" -#include "extensions/renderer/module_system.h" -#include "extensions/renderer/scoped_persistent.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "v8/include/v8.h" - -// Test fixture for testing JS that makes use of the module system. -// -// Typically tests will look like: -// -// TEST_F(MyModuleSystemTest, TestStuff) { -// ModuleSystem::NativesEnabledScope natives_enabled(module_system_.get()); -// RegisterModule("test", "requireNative('assert').AssertTrue(true);"); -// module_system_->Require("test"); -// } -// -// By default a test will fail if no method in the native module 'assert' is -// called. This behaviour can be overridden by calling ExpectNoAssertionsMade(). -// -// TODO(kalman): move this back into chrome/renderer/extensions. -class ModuleSystemTest : public testing::Test { - public: - ModuleSystemTest(); - virtual ~ModuleSystemTest(); - - virtual void TearDown() OVERRIDE; - - protected: - // Register a named JS module in the module system. - void RegisterModule(const std::string& name, const std::string& code); - - // Register a named JS module with source retrieved from a ResourceBundle. - void RegisterModule(const std::string& name, int resource_id); - - // Register a named JS module in the module system and tell the module system - // to use it to handle any requireNative() calls for native modules with that - // name. - void OverrideNativeHandler(const std::string& name, const std::string& code); - - // Registers |file_name| from chrome/test/data/extensions as a module name - // |module_name|. - void RegisterTestFile(const std::string& module_name, - const std::string& file_name); - - // Make the test fail if any asserts are called. By default a test will fail - // if no asserts are called. - void ExpectNoAssertionsMade(); - - // Create an empty object in the global scope with name |name|. - v8::Handle<v8::Object> CreateGlobal(const std::string& name); - - v8::Isolate* isolate_; - v8::HandleScope handle_scope_; - scoped_ptr<extensions::ChromeV8Context> context_; - class AssertNatives; - AssertNatives* assert_natives_; - class StringSourceMap; - scoped_ptr<StringSourceMap> source_map_; - bool should_assertions_be_made_; - - private: - DISALLOW_COPY_AND_ASSIGN(ModuleSystemTest); -}; - -#endif // CHROME_TEST_BASE_MODULE_SYSTEM_TEST_H_ diff --git a/chrome/test/base/run_all_remoting_unittests.cc b/chrome/test/base/run_all_remoting_unittests.cc deleted file mode 100644 index e629b8f2e3..0000000000 --- a/chrome/test/base/run_all_remoting_unittests.cc +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2011 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. - -// A basic testrunner that supports JavaScript unittests. -// This lives in src/chrome/test/base so that it can include chrome_paths.h -// (required for JS unittests) without updating the DEPS file for each -// subproject. - -#include "base/test/launcher/unit_test_launcher.h" -#include "base/test/test_suite.h" -#include "chrome/common/chrome_paths.h" -#include "media/base/media.h" -#include "net/socket/ssl_server_socket.h" - -int main(int argc, char** argv) { - base::TestSuite test_suite(argc, argv); - -#if defined(OS_MACOSX) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) - // This is required for the JavaScript unittests. - chrome::RegisterPathProvider(); -#endif // defined(OS_MACOSX) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) - - // Enable support for SSL server sockets, which must be done while - // single-threaded. - net::EnableSSLServerSockets(); - - // Ensures runtime specific CPU features are initialized. - media::InitializeCPUSpecificMediaFeatures(); - - return base::LaunchUnitTests( - argc, argv, base::Bind(&base::TestSuite::Run, - base::Unretained(&test_suite))); -} diff --git a/chrome/test/base/run_all_unittests.cc b/chrome/test/base/run_all_unittests.cc index ae5b60067b..cfe6491e16 100644 --- a/chrome/test/base/run_all_unittests.cc +++ b/chrome/test/base/run_all_unittests.cc @@ -6,10 +6,12 @@ #include "base/test/launcher/unit_test_launcher.h" #include "chrome/test/base/chrome_unit_test_suite.h" #include "content/public/test/unittest_test_suite.h" +#include "mojo/embedder/embedder.h" int main(int argc, char **argv) { content::UnitTestTestSuite test_suite(new ChromeUnitTestSuite(argc, argv)); + mojo::embedder::Init(); return base::LaunchUnitTests( argc, argv, base::Bind(&content::UnitTestTestSuite::Run, base::Unretained(&test_suite))); diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index 6231559b49..5e33fede9a 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h @@ -11,7 +11,7 @@ #include "chrome/browser/download/test_download_shelf.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/omnibox/location_bar.h" +#include "chrome/browser/ui/location_bar/location_bar.h" class LocationBarTesting; class OmniboxView; diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index 1c7aa7aca4..be72393f90 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc @@ -4,8 +4,6 @@ #include "chrome/test/base/testing_profile.h" -#include "build/build_config.h" - #include "base/base_paths.h" #include "base/command_line.h" #include "base/file_util.h" @@ -21,10 +19,10 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/content_settings/host_content_settings_map.h" -#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_special_storage_policy.h" #include "chrome/browser/extensions/extension_system_factory.h" #include "chrome/browser/extensions/test_extension_system.h" +#include "chrome/browser/favicon/chrome_favicon_client_factory.h" #include "chrome/browser/favicon/favicon_service.h" #include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/history/chrome_history_client.h" @@ -48,7 +46,6 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/storage_partition_descriptor.h" #include "chrome/browser/search_engines/template_url_fetcher_factory.h" -#include "chrome/browser/webdata/web_data_service.h" #include "chrome/browser/webdata/web_data_service_factory.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_switches.h" @@ -69,7 +66,6 @@ #include "content/public/browser/storage_partition.h" #include "content/public/test/mock_resource_context.h" #include "content/public/test/test_utils.h" -#include "extensions/browser/extension_system.h" #include "extensions/common/constants.h" #include "net/cookies/cookie_monster.h" #include "net/url_request/url_request_context.h" @@ -89,6 +85,7 @@ #if defined(ENABLE_EXTENSIONS) #include "chrome/browser/guest_view/guest_view_manager.h" +#include "extensions/browser/extension_system.h" #endif #if defined(OS_ANDROID) @@ -136,8 +133,8 @@ class TestExtensionURLRequestContext : public net::URLRequestContext { net::CookieMonster* cookie_monster = content::CreateCookieStore(content::CookieStoreConfig())-> GetCookieMonster(); - const char* schemes[] = {extensions::kExtensionScheme}; - cookie_monster->SetCookieableSchemes(schemes, 1); + const char* const schemes[] = {extensions::kExtensionScheme}; + cookie_monster->SetCookieableSchemes(schemes, arraysize(schemes)); set_cookie_store(cookie_monster); } @@ -429,7 +426,9 @@ TestingProfile::~TestingProfile() { } static KeyedService* BuildFaviconService(content::BrowserContext* profile) { - return new FaviconService(static_cast<Profile*>(profile)); + FaviconClient* favicon_client = + ChromeFaviconClientFactory::GetForProfile(static_cast<Profile*>(profile)); + return new FaviconService(static_cast<Profile*>(profile), favicon_client); } void TestingProfile::CreateFaviconService() { @@ -657,10 +656,6 @@ bool TestingProfile::IsSupervised() { return !supervised_user_id_.empty(); } -ExtensionService* TestingProfile::GetExtensionService() { - return extensions::ExtensionSystem::Get(this)->extension_service(); -} - void TestingProfile::SetExtensionSpecialStoragePolicy( ExtensionSpecialStoragePolicy* extension_special_storage_policy) { extension_special_storage_policy_ = extension_special_storage_policy; @@ -800,7 +795,8 @@ HostContentSettingsMap* TestingProfile::GetHostContentSettingsMap() { if (!host_content_settings_map_.get()) { host_content_settings_map_ = new HostContentSettingsMap(GetPrefs(), false); #if defined(ENABLE_EXTENSIONS) - ExtensionService* extension_service = GetExtensionService(); + ExtensionService* extension_service = + extensions::ExtensionSystem::Get(this)->extension_service(); if (extension_service) host_content_settings_map_->RegisterExtensionService(extension_service); #endif @@ -852,8 +848,8 @@ void TestingProfile::BlockUntilHistoryProcessesPendingRequests() { DCHECK(history_service); DCHECK(base::MessageLoop::current()); - CancelableRequestConsumer consumer; - history_service->ScheduleDBTask(new QuittingHistoryDBTask(), &consumer); + base::CancelableTaskTracker tracker; + history_service->ScheduleDBTask(new QuittingHistoryDBTask(), &tracker); base::MessageLoop::current()->Run(); } @@ -873,14 +869,6 @@ void TestingProfile::ClearNetworkingHistorySince( } } -void TestingProfile::ClearDomainReliabilityMonitor( - domain_reliability::DomainReliabilityClearMode mode, - const base::Closure& completion) { - if (!completion.is_null()) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, completion); - } -} - GURL TestingProfile::GetHomePage() { return GURL(chrome::kChromeUINewTabURL); } diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h index 20d3b04467..97e4d19238 100644 --- a/chrome/test/base/testing_profile.h +++ b/chrome/test/base/testing_profile.h @@ -250,7 +250,6 @@ class TestingProfile : public Profile { virtual bool HasOffTheRecordProfile() OVERRIDE; virtual Profile* GetOriginalProfile() OVERRIDE; virtual bool IsSupervised() OVERRIDE; - virtual ExtensionService* GetExtensionService() OVERRIDE; void SetExtensionSpecialStoragePolicy( ExtensionSpecialStoragePolicy* extension_special_storage_policy); virtual ExtensionSpecialStoragePolicy* @@ -314,9 +313,6 @@ class TestingProfile : public Profile { virtual void ClearNetworkingHistorySince( base::Time time, const base::Closure& completion) OVERRIDE; - virtual void ClearDomainReliabilityMonitor( - domain_reliability::DomainReliabilityClearMode mode, - const base::Closure& completion) OVERRIDE; virtual GURL GetHomePage() OVERRIDE; virtual PrefService* GetOffTheRecordPrefs() OVERRIDE; diff --git a/chrome/test/base/testing_profile_manager.cc b/chrome/test/base/testing_profile_manager.cc index 6bd4abaaa1..66c54a9570 100644 --- a/chrome/test/base/testing_profile_manager.cc +++ b/chrome/test/base/testing_profile_manager.cc @@ -139,6 +139,17 @@ void TestingProfileManager::DeleteTestingProfile(const std::string& name) { profile_manager_->profiles_info_.erase(profile->GetPath()); } +void TestingProfileManager::DeleteAllTestingProfiles() { + for (TestingProfilesMap::iterator it = testing_profiles_.begin(); + it != testing_profiles_.end(); ++it) { + TestingProfile* profile = it->second; + ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache(); + cache.DeleteProfileFromCache(profile->GetPath()); + } + testing_profiles_.clear(); +} + + void TestingProfileManager::DeleteGuestProfile() { DCHECK(called_set_up_); diff --git a/chrome/test/base/testing_profile_manager.h b/chrome/test/base/testing_profile_manager.h index a1e9f2e039..8fcd7a2932 100644 --- a/chrome/test/base/testing_profile_manager.h +++ b/chrome/test/base/testing_profile_manager.h @@ -70,6 +70,10 @@ class TestingProfileManager { // Deletes a TestingProfile from the profile subsystem. void DeleteTestingProfile(const std::string& profile_name); + // Deletes all TestingProfiles from the profile subsystem, including guest + // profiles. + void DeleteAllTestingProfiles(); + // Deletes a guest TestingProfile from the profile manager. void DeleteGuestProfile(); diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc index dafacf130a..978835bd99 100644 --- a/chrome/test/base/ui_test_utils.cc +++ b/chrome/test/base/ui_test_utils.cc @@ -28,12 +28,9 @@ #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/extensions/extension_action.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/search_engines/template_url_service.h" -#include "chrome/browser/search_engines/template_url_service_test_util.h" #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h" #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h" #include "chrome/browser/ui/browser.h" @@ -46,13 +43,14 @@ #include "chrome/browser/ui/find_bar/find_notification_details.h" #include "chrome/browser/ui/find_bar/find_tab_helper.h" #include "chrome/browser/ui/host_desktop.h" -#include "chrome/browser/ui/omnibox/location_bar.h" +#include "chrome/browser/ui/location_bar/location_bar.h" #include "chrome/browser/ui/omnibox/omnibox_view.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/find_in_page_observer.h" #include "components/bookmarks/browser/bookmark_model.h" +#include "components/search_engines/template_url_service.h" #include "content/public/browser/dom_operation_notification_details.h" #include "content/public/browser/download_item.h" #include "content/public/browser/download_manager.h" @@ -269,13 +267,6 @@ void NavigateToURLBlockUntilNavigationsComplete(Browser* browser, BROWSER_TEST_WAIT_FOR_NAVIGATION); } -void WaitUntilDevToolsWindowLoaded(DevToolsWindow* window) { - scoped_refptr<content::MessageLoopRunner> runner = - new content::MessageLoopRunner; - window->SetLoadCompletedCallback(runner->QuitClosure()); - runner->Run(); -} - base::FilePath GetTestFilePath(const base::FilePath& dir, const base::FilePath& file) { base::FilePath path; @@ -571,12 +562,12 @@ HistoryEnumerator::HistoryEnumerator(Profile* profile) { HistoryService* hs = HistoryServiceFactory::GetForProfile( profile, Profile::EXPLICIT_ACCESS); - hs->QueryHistory( - base::string16(), - history::QueryOptions(), - &consumer_, - base::Bind(&HistoryEnumerator::HistoryQueryComplete, - base::Unretained(this), message_loop_runner->QuitClosure())); + hs->QueryHistory(base::string16(), + history::QueryOptions(), + base::Bind(&HistoryEnumerator::HistoryQueryComplete, + base::Unretained(this), + message_loop_runner->QuitClosure()), + &tracker_); message_loop_runner->Run(); } @@ -584,7 +575,6 @@ HistoryEnumerator::~HistoryEnumerator() {} void HistoryEnumerator::HistoryQueryComplete( const base::Closure& quit_task, - HistoryService::Handle request_handle, history::QueryResults* results) { for (size_t i = 0; i < results->size(); ++i) urls_.push_back((*results)[i].url()); diff --git a/chrome/test/base/ui_test_utils.h b/chrome/test/base/ui_test_utils.h index 8ed553a781..9e690d1534 100644 --- a/chrome/test/base/ui_test_utils.h +++ b/chrome/test/base/ui_test_utils.h @@ -28,7 +28,6 @@ class AppModalDialog; class Browser; -class DevToolsWindow; class LocationBar; class Profile; class SkBitmap; @@ -111,9 +110,6 @@ void NavigateToURLBlockUntilNavigationsComplete(Browser* browser, const GURL& url, int number_of_navigations); -// Blocks until DevTools window is loaded. -void WaitUntilDevToolsWindowLoaded(DevToolsWindow* window); - // Generate the file path for testing a particular test. // The file for the tests is all located in // test_root_directory/dir/<file> @@ -301,12 +297,11 @@ class HistoryEnumerator { private: void HistoryQueryComplete( const base::Closure& quit_task, - HistoryService::Handle request_handle, history::QueryResults* results); std::vector<GURL> urls_; - CancelableRequestConsumer consumer_; + base::CancelableTaskTracker tracker_; DISALLOW_COPY_AND_ASSIGN(HistoryEnumerator); }; diff --git a/chrome/test/base/v8_unit_test.cc b/chrome/test/base/v8_unit_test.cc index 694c9828f9..6cad93dae8 100644 --- a/chrome/test/base/v8_unit_test.cc +++ b/chrome/test/base/v8_unit_test.cc @@ -237,7 +237,7 @@ std::string V8UnitTest::ExceptionToString(const v8::TryCatch& try_catch) { if (message.IsEmpty()) { str.append(base::StringPrintf("%s\n", *exception)); } else { - v8::String::Utf8Value filename(message->GetScriptResourceName()); + v8::String::Utf8Value filename(message->GetScriptOrigin().ResourceName()); int linenum = message->GetLineNumber(); int colnum = message->GetStartColumn(); str.append(base::StringPrintf( diff --git a/chrome/test/chromedriver/alert_commands.cc b/chrome/test/chromedriver/alert_commands.cc index de7118d572..199e7bc451 100644 --- a/chrome/test/chromedriver/alert_commands.cc +++ b/chrome/test/chromedriver/alert_commands.cc @@ -44,7 +44,7 @@ Status ExecuteGetAlert( WebView* web_view, const base::DictionaryValue& params, scoped_ptr<base::Value>* value) { - value->reset(base::Value::CreateBooleanValue( + value->reset(new base::FundamentalValue( web_view->GetJavaScriptDialogManager()->IsDialogOpen())); return Status(kOk); } diff --git a/chrome/test/chromedriver/archive.py b/chrome/test/chromedriver/archive.py index 93ca15f739..c9e95fb367 100644 --- a/chrome/test/chromedriver/archive.py +++ b/chrome/test/chromedriver/archive.py @@ -91,7 +91,7 @@ def GetSnapshotDownloadSite(): For other platform, it is blink snapshot build. Because there is no linux32 blink snapshot build. """ - if _GetDownloadPlatform() == 'Linux': + if _GetDownloadPlatform() in ('Linux', 'Linux_x64', 'Mac'): return Site.CHROMIUM_SNAPSHOT else: return Site.BLINK_SNAPSHOT diff --git a/chrome/test/chromedriver/capabilities.cc b/chrome/test/chromedriver/capabilities.cc index d72372bea1..b30e871d4b 100644 --- a/chrome/test/chromedriver/capabilities.cc +++ b/chrome/test/chromedriver/capabilities.cc @@ -124,9 +124,9 @@ Status ParseMobileEmulation(const base::Value& option, if (!mobile_emulation->GetDictionary("deviceMetrics", &metrics)) return Status(kUnknownError, "'deviceMetrics' must be a dictionary"); - int width; - int height; - double device_scale_factor; + int width = 0; + int height = 0; + double device_scale_factor = 0; if (!metrics->GetInteger("width", &width) || !metrics->GetInteger("height", &height) || !metrics->GetDouble("pixelRatio", &device_scale_factor)) diff --git a/chrome/test/chromedriver/chrome/automation_extension.cc b/chrome/test/chromedriver/chrome/automation_extension.cc index 9318930006..2aa4d22a0a 100644 --- a/chrome/test/chromedriver/chrome/automation_extension.cc +++ b/chrome/test/chromedriver/chrome/automation_extension.cc @@ -76,8 +76,11 @@ Status AutomationExtension::GetWindowInfo(int* x, if (status.IsError()) return status; - int temp_x, temp_y, temp_width, temp_height; base::DictionaryValue* dict; + int temp_x = 0; + int temp_y = 0; + int temp_width = 0; + int temp_height = 0; if (!result->GetAsDictionary(&dict) || !dict->GetInteger("left", &temp_x) || !dict->GetInteger("top", &temp_y) || diff --git a/chrome/test/chromedriver/chrome/device_manager_unittest.cc b/chrome/test/chromedriver/chrome/device_manager_unittest.cc index cb12f010e1..05e789bae3 100644 --- a/chrome/test/chromedriver/chrome/device_manager_unittest.cc +++ b/chrome/test/chromedriver/chrome/device_manager_unittest.cc @@ -67,6 +67,7 @@ class FakeAdb : public Adb { virtual Status GetPidByName(const std::string& device_serial, const std::string& process_name, int* pid) OVERRIDE { + *pid = 0; // avoid uninit error crbug.com/393231 return Status(kOk); } }; diff --git a/chrome/test/chromedriver/chrome/device_metrics.cc b/chrome/test/chromedriver/chrome/device_metrics.cc index 059e55d26b..70b9592405 100644 --- a/chrome/test/chromedriver/chrome/device_metrics.cc +++ b/chrome/test/chromedriver/chrome/device_metrics.cc @@ -8,7 +8,7 @@ DeviceMetrics::DeviceMetrics(int width, int height, double device_scale_factor) : width(width), height(height), device_scale_factor(device_scale_factor), - emulate_viewport(false), + mobile(false), fit_window(true), text_autosizing(true), font_scale_factor(1) {} diff --git a/chrome/test/chromedriver/chrome/device_metrics.h b/chrome/test/chromedriver/chrome/device_metrics.h index d40159b41d..1e238ef61b 100644 --- a/chrome/test/chromedriver/chrome/device_metrics.h +++ b/chrome/test/chromedriver/chrome/device_metrics.h @@ -12,7 +12,7 @@ struct DeviceMetrics { int width; int height; double device_scale_factor; - bool emulate_viewport; + bool mobile; bool fit_window; bool text_autosizing; double font_scale_factor; diff --git a/chrome/test/chromedriver/chrome/mobile_device_list.cc b/chrome/test/chromedriver/chrome/mobile_device_list.cc new file mode 100644 index 0000000000..3486ba00be --- /dev/null +++ b/chrome/test/chromedriver/chrome/mobile_device_list.cc @@ -0,0 +1,114 @@ +// 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/chromedriver/chrome/mobile_device_list.h" + +const char kMobileDevices[] = + "[[\"Apple iPhone 3GS\",\"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like" + " Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 " + "Mobile/8C148 Safari/6533.18.5\",\"320x480x1\"],[\"Apple iPhone 4\",\"Mozi" + "lla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit" + "/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5" + "\",\"320x480x2\"],[\"Apple iPhone 5\",\"Mozilla/5.0 (iPhone; CPU iPhone O" + "S 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Vers" + "ion/7.0 Mobile/11A465 Safari/9537.53\",\"320x568x2\"],[\"BlackBerry Z10\"" + ",\"Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Vers" + "ion/10.0.9.2372 Mobile Safari/537.10+\",\"384x640x2\"],[\"BlackBerry Z30" + "\",\"Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Ver" + "sion/10.0.9.2372 Mobile Safari/537.10+\",\"360x640x2\"],[\"Google Nexus 4" + "\",\"Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 4 Build/JOP40D) Appl" + "eWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535" + ".19\",\"384x640x2\"],[\"Google Nexus 5\",\"Mozilla/5.0 (Linux; Android 4." + "2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) " + "Chrome/18.0.1025.166 Mobile Safari/535.19\",\"360x640x3\"],[\"Google Nexu" + "s S\",\"Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Nexus S Build/GRJ22)" + " AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1\"," + "\"320x533x1.5\"],[\"HTC Evo, Touch HD, Desire HD, Desire\",\"Mozilla/5.0 " + "(Linux; U; Android 2.2; en-us; Sprint APA9292KT Build/FRF91) AppleWebKit/" + "533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1\",\"320x533x1.5" + "\"],[\"HTC One X, EVO LTE\",\"Mozilla/5.0 (Linux; Android 4.0.3; HTC One " + "X Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.1" + "33 Mobile Safari/535.19\",\"360x640x2\"],[\"HTC Sensation, Evo 3D\",\"Moz" + "illa/5.0 (Linux; U; Android 4.0.3; en-us; HTC Sensation Build/IML74K) App" + "leWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30\",\"" + "360x640x1.5\"],[\"LG Optimus 2X, Optimus 3D, Optimus Black\",\"Mozilla/5." + "0 (Linux; U; Android 2.2; en-us; LG-P990/V08c Build/FRG83) AppleWebKit/53" + "3.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 MMS/LG-Android-MM" + "S-V1.0/1.2\",\"320x533x1.5\"],[\"LG Optimus G\",\"Mozilla/5.0 (Linux; And" + "roid 4.0; LG-E975 Build/IMM76L) AppleWebKit/535.19 (KHTML, like Gecko) Ch" + "rome/18.0.1025.166 Mobile Safari/535.19\",\"384x640x2\"],[\"LG Optimus LT" + "E, Optimus 4X HD\",\"Mozilla/5.0 (Linux; U; Android 2.3; en-us; LG-P930 B" + "uild/GRJ90) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safa" + "ri/533.1\",\"424x753x1.7\"],[\"LG Optimus One\",\"Mozilla/5.0 (Linux; U; " + "Android 2.2.1; en-us; LG-MS690 Build/FRG83) AppleWebKit/533.1 (KHTML, lik" + "e Gecko) Version/4.0 Mobile Safari/533.1\",\"213x320x1.5\"],[\"Motorola D" + "efy, Droid, Droid X, Milestone\",\"Mozilla/5.0 (Linux; U; Android 2.0; en" + "-us; Milestone Build/ SHOLS_U2_01.03.1) AppleWebKit/530.17 (KHTML, like G" + "ecko) Version/4.0 Mobile Safari/530.17\",\"320x569x1.5\"],[\"Motorola Dro" + "id 3, Droid 4, Droid Razr, Atrix 4G, Atrix 2\",\"Mozilla/5.0 (Linux; U; A" + "ndroid 2.2; en-us; Droid Build/FRG22D) AppleWebKit/533.1 (KHTML, like Gec" + "ko) Version/4.0 Mobile Safari/533.1\",\"540x960x1\"],[\"Motorola Droid Ra" + "zr HD\",\"Mozilla/5.0 (Linux; U; Android 2.3; en-us; DROID RAZR 4G Build/" + "6.5.1-73_DHD-11_M1-29) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 " + "Mobile Safari/533.1\",\"720x1280x1\"],[\"Nokia C5, C6, C7, N97, N8, X7\"," + "\"NokiaN97/21.1.107 (SymbianOS/9.4; Series60/5.0 Mozilla/5.0; Profile/MID" + "P-2.1 Configuration/CLDC-1.1) AppleWebkit/525 (KHTML, like Gecko) Browser" + "NG/7.1.4\",\"360x640x1\"],[\"Nokia Lumia 7X0, Lumia 8XX, Lumia 900, N800," + " N810, N900\",\"Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Tr" + "ident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 820)\",\"320x533x1.5\"" + "],[\"Samsung Galaxy Note 3\",\"Mozilla/5.0 (Linux; U; Android 4.3; en-us;" + " SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4." + "0 Mobile Safari/534.30\",\"540x960x2\"],[\"Samsung Galaxy Note II\",\"Moz" + "illa/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKi" + "t/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30\",\"360x640" + "x2\"],[\"Samsung Galaxy Note\",\"Mozilla/5.0 (Linux; U; Android 2.3; en-u" + "s; SAMSUNG-SGH-I717 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gec" + "ko) Version/4.0 Mobile Safari/533.1\",\"400x640x2\"],[\"Samsung Galaxy S " + "III, Galaxy Nexus\",\"Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300" + " Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile " + "Safari/534.30\",\"360x640x2\"],[\"Samsung Galaxy S, S II, W\",\"Mozilla/5" + ".0 (Linux; U; Android 2.1; en-us; GT-I9000 Build/ECLAIR) AppleWebKit/525." + "10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2\",\"320x533x" + "1.5\"],[\"Samsung Galaxy S4\",\"Mozilla/5.0 (Linux; Android 4.2.2; GT-I95" + "05 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.5" + "9 Mobile Safari/537.36\",\"360x640x3\"],[\"Sony Xperia S, Ion\",\"Mozilla" + "/5.0 (Linux; U; Android 4.0; en-us; LT28at Build/6.1.C.1.111) AppleWebKit" + "/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30\",\"360x640x" + "2\"],[\"Sony Xperia Sola, U\",\"Mozilla/5.0 (Linux; U; Android 2.3; en-us" + "; SonyEricssonST25i Build/6.0.B.1.564) AppleWebKit/533.1 (KHTML, like Gec" + "ko) Version/4.0 Mobile Safari/533.1\",\"480x854x1\"],[\"Sony Xperia Z, Z1" + "\",\"Mozilla/5.0 (Linux; U; Android 4.2; en-us; SonyC6903 Build/14.1.G.1." + "518) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534" + ".30\",\"360x640x3\"],[\"Amazon Kindle Fire HDX 7\\u2033\",\"Mozilla/5.0 (" + "Linux; U; en-us; KFTHWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Geck" + "o) Silk/3.13 Safari/535.19 Silk-Accelerated=true\",\"1920x1200x2\"],[\"Am" + "azon Kindle Fire HDX 8.9\\u2033\",\"Mozilla/5.0 (Linux; U; en-us; KFAPWI " + "Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535." + "19 Silk-Accelerated=true\",\"2560x1600x2\"],[\"Amazon Kindle Fire (First " + "Generation)\",\"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; " + "Silk/1.0.141.16-Gen4_11004310) AppleWebkit/533.16 (KHTML, like Gecko) Ver" + "sion/5.0 Safari/533.16 Silk-Accelerated=true\",\"1024x600x1\"],[\"Apple i" + "Pad 1 / 2 / iPad Mini\",\"Mozilla/5.0 (iPad; CPU OS 4_3_5 like Mac OS X; " + "en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8L1 " + "Safari/6533.18.5\",\"1024x768x1\"],[\"Apple iPad 3 / 4\",\"Mozilla/5.0 (i" + "Pad; CPU OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) V" + "ersion/7.0 Mobile/11A465 Safari/9537.53\",\"1024x768x2\"],[\"BlackBerry P" + "layBook\",\"Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWe" + "bKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+\",\"1024x600" + "x1\"],[\"Google Nexus 10\",\"Mozilla/5.0 (Linux; Android 4.3; Nexus 10 Bu" + "ild/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Sa" + "fari/537.36\",\"1280x800x2\"],[\"Google Nexus 7 2\",\"Mozilla/5.0 (Linux;" + " Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko" + ") Chrome/29.0.1547.72 Safari/537.36\",\"960x600x2\"],[\"Google Nexus 7\"," + "\"Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537." + "36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36\",\"966x604x1.32" + "5\"],[\"Motorola Xoom, Xyboard\",\"Mozilla/5.0 (Linux; U; Android 3.0; en" + "-us; Xoom Build/HRI39) AppleWebKit/525.10 (KHTML, like Gecko) Version/3.0" + ".4 Mobile Safari/523.12.2\",\"1280x800x1\"],[\"Samsung Galaxy Tab 7.7, 8." + "9, 10.1\",\"Mozilla/5.0 (Linux; U; Android 2.2; en-us; SCH-I800 Build/FRO" + "YO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1" + "\",\"1280x800x1\"],[\"Samsung Galaxy Tab\",\"Mozilla/5.0 (Linux; U; Andro" + "id 2.2; en-us; SCH-I800 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko" + ") Version/4.0 Mobile Safari/533.1\",\"1024x600x1\"],]"; + diff --git a/chrome/test/chromedriver/chrome/mobile_device_list.h b/chrome/test/chromedriver/chrome/mobile_device_list.h new file mode 100644 index 0000000000..5db939c484 --- /dev/null +++ b/chrome/test/chromedriver/chrome/mobile_device_list.h @@ -0,0 +1,10 @@ +// 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. + +#ifndef CHROME_TEST_CHROMEDRIVER_CHROME_MOBILE_DEVICE_LIST_H_ +#define CHROME_TEST_CHROMEDRIVER_CHROME_MOBILE_DEVICE_LIST_H_ + +extern const char kMobileDevices[]; + +#endif // CHROME_TEST_CHROMEDRIVER_CHROME_MOBILE_DEVICE_LIST_H_ diff --git a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.cc b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.cc index 4a69c66175..0e35b906dd 100644 --- a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.cc +++ b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.cc @@ -7,11 +7,15 @@ #include "chrome/test/chromedriver/chrome/devtools_client.h" #include "chrome/test/chromedriver/chrome/mobile_emulation_override_manager.h" #include "chrome/test/chromedriver/chrome/status.h" +#include "chrome/test/chromedriver/chrome/version.h" MobileEmulationOverrideManager::MobileEmulationOverrideManager( DevToolsClient* client, - const DeviceMetrics* device_metrics) - : client_(client), overridden_device_metrics_(device_metrics) { + const DeviceMetrics* device_metrics, + const BrowserInfo* browser_info) + : client_(client), + overridden_device_metrics_(device_metrics), + browser_info_(browser_info) { if (overridden_device_metrics_) client_->AddListener(this); } @@ -39,13 +43,24 @@ Status MobileEmulationOverrideManager::ApplyOverrideIfNeeded() { if (overridden_device_metrics_ == NULL) return Status(kOk); + // Old revisions of Blink expect a parameter named |emulateViewport| but in + // Blink revision 177367 (Chromium revision 281046, build number 2081) this + // was renamed to |mobile|. + std::string tmp = "mobile"; + if (browser_info_->browser_name == "chrome") { + if (browser_info_->build_no <= 2081) + tmp = "emulateViewport"; + } else { + if (browser_info_->blink_revision < 177367) + tmp = "emulateViewport"; + } + base::DictionaryValue params; params.SetInteger("width", overridden_device_metrics_->width); params.SetInteger("height", overridden_device_metrics_->height); params.SetDouble("deviceScaleFactor", overridden_device_metrics_->device_scale_factor); - params.SetBoolean("emulateViewport", - overridden_device_metrics_->emulate_viewport); + params.SetBoolean(tmp, overridden_device_metrics_->mobile); params.SetBoolean("fitWindow", overridden_device_metrics_->fit_window); params.SetBoolean("textAutosizing", overridden_device_metrics_->text_autosizing); diff --git a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.h b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.h index 4c08f44603..61a9560d83 100644 --- a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.h +++ b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.h @@ -16,6 +16,7 @@ namespace base { class DictionaryValue; } +struct BrowserInfo; class DevToolsClient; struct DeviceMetrics; class Status; @@ -25,7 +26,8 @@ class Status; class MobileEmulationOverrideManager : public DevToolsEventListener { public: MobileEmulationOverrideManager(DevToolsClient* client, - const DeviceMetrics* device_metrics); + const DeviceMetrics* device_metrics, + const BrowserInfo* browser_info); virtual ~MobileEmulationOverrideManager(); // Overridden from DevToolsEventListener: @@ -39,6 +41,7 @@ class MobileEmulationOverrideManager : public DevToolsEventListener { DevToolsClient* client_; const DeviceMetrics* overridden_device_metrics_; + const BrowserInfo* browser_info_; DISALLOW_COPY_AND_ASSIGN(MobileEmulationOverrideManager); }; diff --git a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager_unittest.cc b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager_unittest.cc index a3187835b8..8a876afd6b 100644 --- a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager_unittest.cc +++ b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager_unittest.cc @@ -11,6 +11,7 @@ #include "chrome/test/chromedriver/chrome/mobile_emulation_override_manager.h" #include "chrome/test/chromedriver/chrome/status.h" #include "chrome/test/chromedriver/chrome/stub_devtools_client.h" +#include "chrome/test/chromedriver/chrome/version.h" #include "testing/gtest/include/gtest/gtest.h" namespace { @@ -58,19 +59,19 @@ void AssertDeviceMetricsCommand(const Command& command, ASSERT_EQ("Page.setDeviceMetricsOverride", command.method); int width, height; double device_scale_factor, font_scale_factor; - bool emulate_viewport, fit_window, text_autosizing; + bool mobile, fit_window, text_autosizing; ASSERT_TRUE(command.params.GetInteger("width", &width)); ASSERT_TRUE(command.params.GetInteger("height", &height)); ASSERT_TRUE(command.params.GetDouble("deviceScaleFactor", &device_scale_factor)); - ASSERT_TRUE(command.params.GetBoolean("emulateViewport", &emulate_viewport)); + ASSERT_TRUE(command.params.GetBoolean("mobile", &mobile)); ASSERT_TRUE(command.params.GetBoolean("fitWindow", &fit_window)); ASSERT_TRUE(command.params.GetBoolean("textAutosizing", &text_autosizing)); ASSERT_TRUE(command.params.GetDouble("fontScaleFactor", &font_scale_factor)); ASSERT_EQ(device_metrics.width, width); ASSERT_EQ(device_metrics.height, height); ASSERT_EQ(device_metrics.device_scale_factor, device_scale_factor); - ASSERT_EQ(device_metrics.emulate_viewport, emulate_viewport); + ASSERT_EQ(device_metrics.mobile, mobile); ASSERT_EQ(device_metrics.fit_window, fit_window); ASSERT_EQ(device_metrics.text_autosizing, text_autosizing); ASSERT_EQ(device_metrics.font_scale_factor, font_scale_factor); @@ -81,7 +82,10 @@ void AssertDeviceMetricsCommand(const Command& command, TEST(MobileEmulationOverrideManager, SendsCommandOnConnect) { RecorderDevToolsClient client; DeviceMetrics device_metrics(1, 2, 3.0); - MobileEmulationOverrideManager manager(&client, &device_metrics); + BrowserInfo browser_info; + MobileEmulationOverrideManager manager(&client, + &device_metrics, + &browser_info); ASSERT_EQ(0u, client.commands_.size()); ASSERT_EQ(kOk, manager.OnConnected(&client).code()); @@ -95,7 +99,10 @@ TEST(MobileEmulationOverrideManager, SendsCommandOnConnect) { TEST(MobileEmulationOverrideManager, SendsCommandOnNavigation) { RecorderDevToolsClient client; DeviceMetrics device_metrics(1, 2, 3.0); - MobileEmulationOverrideManager manager(&client, &device_metrics); + BrowserInfo browser_info; + MobileEmulationOverrideManager manager(&client, + &device_metrics, + &browser_info); base::DictionaryValue main_frame_params; ASSERT_EQ(kOk, manager.OnEvent(&client, "Page.frameNavigated", main_frame_params) diff --git a/chrome/test/chromedriver/chrome/web_view_impl.cc b/chrome/test/chromedriver/chrome/web_view_impl.cc index 7e8d1bfce8..eb78c9ffb2 100644 --- a/chrome/test/chromedriver/chrome/web_view_impl.cc +++ b/chrome/test/chromedriver/chrome/web_view_impl.cc @@ -124,7 +124,9 @@ WebViewImpl::WebViewImpl(const std::string& id, navigation_tracker_(new NavigationTracker(client.get(), browser_info)), dialog_manager_(new JavaScriptDialogManager(client.get())), mobile_emulation_override_manager_( - new MobileEmulationOverrideManager(client.get(), device_metrics)), + new MobileEmulationOverrideManager(client.get(), + device_metrics, + browser_info)), geolocation_override_manager_( new GeolocationOverrideManager(client.get())), heap_snapshot_taker_(new HeapSnapshotTaker(client.get())), diff --git a/chrome/test/chromedriver/command_listener.h b/chrome/test/chromedriver/command_listener.h new file mode 100644 index 0000000000..36f77257f6 --- /dev/null +++ b/chrome/test/chromedriver/command_listener.h @@ -0,0 +1,22 @@ +// 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. + +#ifndef CHROME_TEST_CHROMEDRIVER_COMMAND_LISTENER_H_ +#define CHROME_TEST_CHROMEDRIVER_COMMAND_LISTENER_H_ + +#include <string> + +class Status; + +class CommandListener { + public: + virtual ~CommandListener() {} + + // Called just before a WebDriver command is run, but only + // for commands that operate on an existing session. Will be called for + // WindowCommands, ElementCommands, SessionCommands, and AlertCommands. + virtual Status BeforeCommand(const std::string& command_name) = 0; +}; + +#endif // CHROME_TEST_CHROMEDRIVER_COMMAND_LISTENER_H_ diff --git a/chrome/test/chromedriver/command_listener_proxy.cc b/chrome/test/chromedriver/command_listener_proxy.cc new file mode 100644 index 0000000000..bc1e94c846 --- /dev/null +++ b/chrome/test/chromedriver/command_listener_proxy.cc @@ -0,0 +1,19 @@ +// 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/chromedriver/chrome/devtools_client.h" +#include "chrome/test/chromedriver/chrome/status.h" +#include "chrome/test/chromedriver/command_listener_proxy.h" +#include "chrome/test/chromedriver/logging.h" + +CommandListenerProxy::CommandListenerProxy( + CommandListener* command_listener) : command_listener_(command_listener) { + CHECK(command_listener_); +} + +CommandListenerProxy::~CommandListenerProxy() { } + +Status CommandListenerProxy::BeforeCommand(const std::string& command_name) { + return command_listener_->BeforeCommand(command_name); +} diff --git a/chrome/test/chromedriver/command_listener_proxy.h b/chrome/test/chromedriver/command_listener_proxy.h new file mode 100644 index 0000000000..5788cae107 --- /dev/null +++ b/chrome/test/chromedriver/command_listener_proxy.h @@ -0,0 +1,30 @@ +// 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. + +#ifndef CHROME_TEST_CHROMEDRIVER_COMMAND_LISTENER_PROXY_H_ +#define CHROME_TEST_CHROMEDRIVER_COMMAND_LISTENER_PROXY_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "chrome/test/chromedriver/command_listener.h" + +class CommandListenerProxy : public CommandListener { + public: + virtual ~CommandListenerProxy(); + + // |command_listener| must not be null. + explicit CommandListenerProxy(CommandListener* command_listener); + + // Forwards commands to |command_listener_|. + virtual Status BeforeCommand(const std::string& command_name) OVERRIDE; + + private: + CommandListener* const command_listener_; + + DISALLOW_COPY_AND_ASSIGN(CommandListenerProxy); +}; + +#endif // CHROME_TEST_CHROMEDRIVER_COMMAND_LISTENER_PROXY_H_ diff --git a/chrome/test/chromedriver/command_listener_proxy_unittest.cc b/chrome/test/chromedriver/command_listener_proxy_unittest.cc new file mode 100644 index 0000000000..937605c96a --- /dev/null +++ b/chrome/test/chromedriver/command_listener_proxy_unittest.cc @@ -0,0 +1,47 @@ +// 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 <string> + +#include "base/compiler_specific.h" +#include "base/values.h" +#include "chrome/test/chromedriver/chrome/status.h" +#include "chrome/test/chromedriver/command_listener_proxy.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class MockCommandListener : public CommandListener { + public: + MockCommandListener() : called_(false) {} + virtual ~MockCommandListener() {} + + virtual Status BeforeCommand(const std::string& command_name) OVERRIDE { + called_ = true; + EXPECT_STREQ("cmd", command_name.c_str()); + return Status(kOk); + } + + void VerifyCalled() { + EXPECT_TRUE(called_); + } + + void VerifyNotCalled() { + EXPECT_FALSE(called_); + } + + private: + bool called_; +}; + +} // namespace + +TEST(CommandListenerProxy, ForwardsCommands) { + MockCommandListener listener; + listener.VerifyNotCalled(); + CommandListenerProxy proxy(&listener); + listener.VerifyNotCalled(); + ASSERT_EQ(kOk, proxy.BeforeCommand("cmd").code()); + listener.VerifyCalled(); +} diff --git a/chrome/test/chromedriver/commands.cc b/chrome/test/chromedriver/commands.cc index 25a7d69864..6b7e247d6d 100644 --- a/chrome/test/chromedriver/commands.cc +++ b/chrome/test/chromedriver/commands.cc @@ -151,6 +151,10 @@ void ExecuteSessionCommandOnSessionThread( VLOG(0) << "COMMAND " << command_name << " " << FormatValueForDisplay(*params); } + + // Notify |session|'s |CommandListener|s of the command. + NotifySessionListenersBeforeCommand(session, command_name); + scoped_ptr<base::Value> value; Status status = command.Run(session, *params, &value); diff --git a/chrome/test/chromedriver/commands_unittest.cc b/chrome/test/chromedriver/commands_unittest.cc index 4457186305..c34f197fa0 100644 --- a/chrome/test/chromedriver/commands_unittest.cc +++ b/chrome/test/chromedriver/commands_unittest.cc @@ -18,6 +18,7 @@ #include "chrome/test/chromedriver/chrome/stub_chrome.h" #include "chrome/test/chromedriver/chrome/stub_web_view.h" #include "chrome/test/chromedriver/chrome/web_view.h" +#include "chrome/test/chromedriver/command_listener_proxy.h" #include "chrome/test/chromedriver/commands.h" #include "chrome/test/chromedriver/element_commands.h" #include "chrome/test/chromedriver/session.h" @@ -546,3 +547,113 @@ TEST(CommandsTest, ErrorFindChildElement) { ExecuteFindChildElements( 1, &session, &web_view, element_id, params, &result).code()); } + +namespace { + +class MockCommandListener : public CommandListener { + public: + MockCommandListener() : called_(false) {} + virtual ~MockCommandListener() {} + + virtual Status BeforeCommand(const std::string& command_name) OVERRIDE { + called_ = true; + EXPECT_STREQ("cmd", command_name.c_str()); + return Status(kOk); + } + + void VerifyCalled() { + EXPECT_TRUE(called_); + } + + void VerifyNotCalled() { + EXPECT_FALSE(called_); + } + + private: + bool called_; +}; + +Status ExecuteAddListenerToSessionCommand( + CommandListener* listener, + Session* session, + const base::DictionaryValue& params, + scoped_ptr<base::Value>* return_value) { + session->command_listeners.push_back(listener); + return Status(kOk); +} + +Status ExecuteQuitSessionCommand( + Session* session, + const base::DictionaryValue& params, + scoped_ptr<base::Value>* return_value) { + session->quit = true; + return Status(kOk); +} + +void OnSessionCommand( + base::RunLoop* run_loop, + const Status& status, + scoped_ptr<base::Value> value, + const std::string& session_id) { + ASSERT_EQ(kOk, status.code()); + run_loop->Quit(); +} + +} // namespace + +TEST(CommandsTest, SessionNotifiedOfCommand) { + SessionThreadMap map; + linked_ptr<base::Thread> thread(new base::Thread("1")); + ASSERT_TRUE(thread->Start()); + std::string id("id"); + thread->message_loop()->PostTask( + FROM_HERE, + base::Bind(&internal::CreateSessionOnSessionThreadForTesting, id)); + map[id] = thread; + + base::DictionaryValue params; + scoped_ptr<MockCommandListener> listener(new MockCommandListener()); + CommandListenerProxy* proxy = new CommandListenerProxy(listener.get()); + // We add |proxy| to the session instead of adding |listener| directly so that + // after the session is destroyed by ExecuteQuitSessionCommand, we can still + // verify the listener was called. The session owns and will destroy |proxy|. + SessionCommand cmd = base::Bind( + &ExecuteAddListenerToSessionCommand, proxy); + base::MessageLoop loop; + base::RunLoop run_loop_addlistener; + + // |CommandListener|s are notified immediately before commands are run. + // Here, the command adds |listener| to the session, so |listener| + // should not be notified since it will not have been added yet. + ExecuteSessionCommand( + &map, + "cmd", + cmd, + false, + params, + id, + base::Bind(&OnSessionCommand, + &run_loop_addlistener)); + run_loop_addlistener.Run(); + + listener->VerifyNotCalled(); + + base::RunLoop run_loop_testlistener; + cmd = base::Bind( + &ExecuteQuitSessionCommand); + + // |listener| was added to |session| by ExecuteAddListenerToSessionCommand + // and should be notified before the next command, ExecuteQuitSessionCommand. + ExecuteSessionCommand( + &map, + "cmd", + cmd, + false, + params, + id, + base::Bind(&OnSessionCommand, + &run_loop_testlistener)); + run_loop_testlistener.Run(); + + listener->VerifyCalled(); +} diff --git a/chrome/test/chromedriver/element_util.cc b/chrome/test/chromedriver/element_util.cc index 9b15fa5118..274449f7b2 100644 --- a/chrome/test/chromedriver/element_util.cc +++ b/chrome/test/chromedriver/element_util.cc @@ -27,7 +27,8 @@ bool ParseFromValue(base::Value* value, WebPoint* point) { base::DictionaryValue* dict_value; if (!value->GetAsDictionary(&dict_value)) return false; - double x, y; + double x = 0; + double y = 0; if (!dict_value->GetDouble("x", &x) || !dict_value->GetDouble("y", &y)) return false; @@ -40,7 +41,8 @@ bool ParseFromValue(base::Value* value, WebSize* size) { base::DictionaryValue* dict_value; if (!value->GetAsDictionary(&dict_value)) return false; - double width, height; + double width = 0; + double height = 0; if (!dict_value->GetDouble("width", &width) || !dict_value->GetDouble("height", &height)) return false; @@ -53,7 +55,10 @@ bool ParseFromValue(base::Value* value, WebRect* rect) { base::DictionaryValue* dict_value; if (!value->GetAsDictionary(&dict_value)) return false; - double x, y, width, height; + double x = 0; + double y = 0; + double width = 0; + double height = 0; if (!dict_value->GetDouble("left", &x) || !dict_value->GetDouble("top", &y) || !dict_value->GetDouble("width", &width) || @@ -100,7 +105,7 @@ Status VerifyElementClickable( if (status.IsError()) return status; base::DictionaryValue* dict; - bool is_clickable; + bool is_clickable = false; if (!result->GetAsDictionary(&dict) || !dict->GetBoolean("clickable", &is_clickable)) { return Status(kUnknownError, diff --git a/chrome/test/chromedriver/embed_mobile_devices_in_cpp.py b/chrome/test/chromedriver/embed_mobile_devices_in_cpp.py index 8e741696bf..2667014c95 100755 --- a/chrome/test/chromedriver/embed_mobile_devices_in_cpp.py +++ b/chrome/test/chromedriver/embed_mobile_devices_in_cpp.py @@ -30,8 +30,8 @@ def main(): with open(file_name, 'r') as f: for line in f: if not inside_list: - if 'WebInspector.OverridesSupport._phones = [' in line or \ - 'WebInspector.OverridesSupport._tablets = [' in line: + if 'WebInspector.OverridesUI._phones = [' in line or \ + 'WebInspector.OverridesUI._tablets = [' in line: inside_list = True else: if line.strip() == '];': diff --git a/chrome/test/chromedriver/logging.cc b/chrome/test/chromedriver/logging.cc index c9ddf25c24..f0ac778f46 100644 --- a/chrome/test/chromedriver/logging.cc +++ b/chrome/test/chromedriver/logging.cc @@ -14,8 +14,9 @@ #include "base/time/time.h" #include "chrome/test/chromedriver/capabilities.h" #include "chrome/test/chromedriver/chrome/console_logger.h" -#include "chrome/test/chromedriver/chrome/performance_logger.h" #include "chrome/test/chromedriver/chrome/status.h" +#include "chrome/test/chromedriver/command_listener_proxy.h" +#include "chrome/test/chromedriver/performance_logger.h" #include "chrome/test/chromedriver/session.h" #if defined(OS_POSIX) @@ -239,9 +240,11 @@ bool InitLogging() { Status CreateLogs(const Capabilities& capabilities, ScopedVector<WebDriverLog>* out_logs, - ScopedVector<DevToolsEventListener>* out_listeners) { + ScopedVector<DevToolsEventListener>* out_devtools_listeners, + ScopedVector<CommandListener>* out_command_listeners) { ScopedVector<WebDriverLog> logs; - ScopedVector<DevToolsEventListener> listeners; + ScopedVector<DevToolsEventListener> devtools_listeners; + ScopedVector<CommandListener> command_listeners; Log::Level browser_log_level = Log::kWarning; const LoggingPrefs& prefs = capabilities.logging_prefs; @@ -254,7 +257,13 @@ Status CreateLogs(const Capabilities& capabilities, if (level != Log::kOff) { WebDriverLog* log = new WebDriverLog(type, Log::kAll); logs.push_back(log); - listeners.push_back(new PerformanceLogger(log)); + PerformanceLogger* perf_log = new PerformanceLogger(log); + // We use a proxy for |perf_log|'s |CommandListener| interface. + // session->chrome will own |perf_log|, and |session| will own |proxy|. + // session->command_listeners (the proxy) will be destroyed first. + CommandListenerProxy* proxy = new CommandListenerProxy(perf_log); + devtools_listeners.push_back(perf_log); + command_listeners.push_back(proxy); } } else if (type == WebDriverLog::kBrowserType) { browser_log_level = level; @@ -271,9 +280,10 @@ Status CreateLogs(const Capabilities& capabilities, logs.push_back(browser_log); // If the level is OFF, don't even bother listening for DevTools events. if (browser_log_level != Log::kOff) - listeners.push_back(new ConsoleLogger(browser_log)); + devtools_listeners.push_back(new ConsoleLogger(browser_log)); out_logs->swap(logs); - out_listeners->swap(listeners); + out_devtools_listeners->swap(devtools_listeners); + out_command_listeners->swap(command_listeners); return Status(kOk); } diff --git a/chrome/test/chromedriver/logging.h b/chrome/test/chromedriver/logging.h index eb2cde881c..78e0aba4b0 100644 --- a/chrome/test/chromedriver/logging.h +++ b/chrome/test/chromedriver/logging.h @@ -14,6 +14,7 @@ #include "chrome/test/chromedriver/chrome/log.h" struct Capabilities; +class CommandListener; class DevToolsEventListener; class ListValue; class Status; @@ -64,9 +65,11 @@ class WebDriverLog : public Log { // Initializes logging system for ChromeDriver. Returns true on success. bool InitLogging(); -// Creates Log's and DevToolsEventListener's based on logging preferences. +// Creates |Log|s, |DevToolsEventListener|s, and |CommandListener|s based on +// logging preferences. Status CreateLogs(const Capabilities& capabilities, ScopedVector<WebDriverLog>* out_logs, - ScopedVector<DevToolsEventListener>* out_listeners); + ScopedVector<DevToolsEventListener>* out_devtools_listeners, + ScopedVector<CommandListener>* out_command_listeners); #endif // CHROME_TEST_CHROMEDRIVER_LOGGING_H_ diff --git a/chrome/test/chromedriver/logging_unittest.cc b/chrome/test/chromedriver/logging_unittest.cc index 7912b6360e..53b627bf43 100644 --- a/chrome/test/chromedriver/logging_unittest.cc +++ b/chrome/test/chromedriver/logging_unittest.cc @@ -7,6 +7,7 @@ #include "chrome/test/chromedriver/chrome/devtools_event_listener.h" #include "chrome/test/chromedriver/chrome/log.h" #include "chrome/test/chromedriver/chrome/status.h" +#include "chrome/test/chromedriver/command_listener.h" #include "chrome/test/chromedriver/logging.h" #include "testing/gtest/include/gtest/gtest.h" @@ -101,12 +102,15 @@ TEST(Logging, CreatePerformanceLog) { capabilities.logging_prefs["performance"] = Log::kInfo; capabilities.logging_prefs["browser"] = Log::kInfo; - ScopedVector<DevToolsEventListener> listeners; + ScopedVector<DevToolsEventListener> devtools_listeners; ScopedVector<WebDriverLog> logs; - Status status = CreateLogs(capabilities, &logs, &listeners); + ScopedVector<CommandListener> command_listeners; + Status status = CreateLogs(capabilities, &logs, &devtools_listeners, + &command_listeners); ASSERT_TRUE(status.IsOk()); ASSERT_EQ(2u, logs.size()); - ASSERT_EQ(2u, listeners.size()); + ASSERT_EQ(2u, devtools_listeners.size()); + ASSERT_EQ(1u, command_listeners.size()); ASSERT_EQ("performance", logs[0]->type()); ASSERT_EQ("browser", logs[1]->type()); } @@ -115,24 +119,30 @@ TEST(Logging, IgnoreUnknownLogType) { Capabilities capabilities; capabilities.logging_prefs["gaga"] = Log::kInfo; - ScopedVector<DevToolsEventListener> listeners; + ScopedVector<DevToolsEventListener> devtools_listeners; ScopedVector<WebDriverLog> logs; - Status status = CreateLogs(capabilities, &logs, &listeners); + ScopedVector<CommandListener> command_listeners; + Status status = CreateLogs(capabilities, &logs, &devtools_listeners, + &command_listeners); EXPECT_TRUE(status.IsOk()); ASSERT_EQ(1u, logs.size()); - ASSERT_EQ(1u, listeners.size()); + ASSERT_EQ(1u, devtools_listeners.size()); + ASSERT_EQ(0u, command_listeners.size()); ASSERT_EQ("browser", logs[0]->type()); } TEST(Logging, DefaultLogs) { Capabilities capabilities; - ScopedVector<DevToolsEventListener> listeners; + ScopedVector<DevToolsEventListener> devtools_listeners; ScopedVector<WebDriverLog> logs; - Status status = CreateLogs(capabilities, &logs, &listeners); + ScopedVector<CommandListener> command_listeners; + Status status = CreateLogs(capabilities, &logs, &devtools_listeners, + &command_listeners); EXPECT_TRUE(status.IsOk()); ASSERT_EQ(1u, logs.size()); - ASSERT_EQ(1u, listeners.size()); + ASSERT_EQ(1u, devtools_listeners.size()); + ASSERT_EQ(0u, command_listeners.size()); ASSERT_EQ("browser", logs[0]->type()); } diff --git a/chrome/test/chromedriver/chrome/performance_logger.cc b/chrome/test/chromedriver/performance_logger.cc index 4e51a62584..708200d6e1 100644 --- a/chrome/test/chromedriver/chrome/performance_logger.cc +++ b/chrome/test/chromedriver/performance_logger.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// 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/chromedriver/chrome/performance_logger.h" +#include "chrome/test/chromedriver/performance_logger.h" #include "base/json/json_writer.h" #include "base/strings/string_util.h" @@ -63,3 +63,8 @@ Status PerformanceLogger::OnEvent( log_->AddEntry(Log::kInfo, log_message_json); return Status(kOk); } + +// TODO(johnmoore): Use BeforeCommand to implement tracing log. +Status PerformanceLogger::BeforeCommand(const std::string& command_name) { + return Status(kOk); +} diff --git a/chrome/test/chromedriver/chrome/performance_logger.h b/chrome/test/chromedriver/performance_logger.h index b9cc8a1410..1f33598b67 100644 --- a/chrome/test/chromedriver/chrome/performance_logger.h +++ b/chrome/test/chromedriver/performance_logger.h @@ -1,13 +1,14 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// 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. -#ifndef CHROME_TEST_CHROMEDRIVER_CHROME_PERFORMANCE_LOGGER_H_ -#define CHROME_TEST_CHROMEDRIVER_CHROME_PERFORMANCE_LOGGER_H_ +#ifndef CHROME_TEST_CHROMEDRIVER_PERFORMANCE_LOGGER_H_ +#define CHROME_TEST_CHROMEDRIVER_PERFORMANCE_LOGGER_H_ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "chrome/test/chromedriver/chrome/devtools_event_listener.h" +#include "chrome/test/chromedriver/command_listener.h" class Log; @@ -18,7 +19,7 @@ class Log; // "webview": <originating WebView ID>, // "message": { "method": "...", "params": { ... }} // DevTools message. // } -class PerformanceLogger : public DevToolsEventListener { +class PerformanceLogger : public DevToolsEventListener, public CommandListener { public: // Creates a PerformanceLogger that creates entries in the given Log object. // The log is owned elsewhere and must not be null. @@ -31,10 +32,12 @@ class PerformanceLogger : public DevToolsEventListener { const std::string& method, const base::DictionaryValue& params) OVERRIDE; + virtual Status BeforeCommand(const std::string& command_name) OVERRIDE; + private: Log* log_; // The log where to create entries. DISALLOW_COPY_AND_ASSIGN(PerformanceLogger); }; -#endif // CHROME_TEST_CHROMEDRIVER_CHROME_PERFORMANCE_LOGGER_H_ +#endif // CHROME_TEST_CHROMEDRIVER_PERFORMANCE_LOGGER_H_ diff --git a/chrome/test/chromedriver/chrome/performance_logger_unittest.cc b/chrome/test/chromedriver/performance_logger_unittest.cc index ce15810252..cab92c85b9 100644 --- a/chrome/test/chromedriver/chrome/performance_logger_unittest.cc +++ b/chrome/test/chromedriver/performance_logger_unittest.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// 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/chromedriver/chrome/performance_logger.h" +#include "chrome/test/chromedriver/performance_logger.h" #include "base/compiler_specific.h" #include "base/format_macros.h" diff --git a/chrome/test/chromedriver/run_buildbot_steps.py b/chrome/test/chromedriver/run_buildbot_steps.py index c471dbcf28..dd1a371471 100755 --- a/chrome/test/chromedriver/run_buildbot_steps.py +++ b/chrome/test/chromedriver/run_buildbot_steps.py @@ -31,6 +31,10 @@ GS_SERVER_LOGS_URL = GS_CHROMEDRIVER_DATA_BUCKET + '/server_logs' SERVER_LOGS_LINK = ( 'http://chromedriver-data.storage.googleapis.com/server_logs') TEST_LOG_FORMAT = '%s_log.json' +GS_GITHASH_TO_SVN_URL = ( + 'https://chromium.googlesource.com/chromium/src/+/%s?format=json') +GS_SEARCH_PATTERN = ( + r'.*git-svn-id: svn://svn.chromium.org/chrome/trunk/src@(\d+) ') SCRIPT_DIR = os.path.join(_THIS_DIR, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir, 'scripts') @@ -380,14 +384,46 @@ def _CleanTmpDir(): os.remove(file_path) +def _GetSVNRevisionFromGitHash(snapshot_hashcode): + json_url = GS_GITHASH_TO_SVN_URL % snapshot_hashcode + try: + response = urllib2.urlopen(json_url) + except urllib2.HTTPError as error: + util.PrintAndFlush('HTTP Error %d' % error.getcode()) + except urllib2.URLError as error: + util.PrintAndFlush('URL Error %s' % error.message) + return None + data = json.loads(response.read()[4:]) + if 'message' in data: + message = data['message'].split('\n') + message = [line for line in message if line.strip()] + search_pattern = re.compile(GS_SEARCH_PATTERN) + result = search_pattern.search(message[len(message)-1]) + if result: + return result.group(1) + util.PrintAndFlush('Failed to get svn revision number for %s' % + snapshot_hashcode) + return None + + def _WaitForLatestSnapshot(revision): util.MarkBuildStepStart('wait_for_snapshot') + def _IsRevisionNumber(revision): + if isinstance(revision, int): + return True + else: + return revision.isdigit() while True: snapshot_revision = archive.GetLatestSnapshotVersion() - if int(snapshot_revision) >= int(revision): - break - util.PrintAndFlush('Waiting for snapshot >= %s, found %s' % - (revision, snapshot_revision)) + if not _IsRevisionNumber(revision): + revision = _GetSVNRevisionFromGitHash(revision) + if not _IsRevisionNumber(snapshot_revision): + snapshot_revision = _GetSVNRevisionFromGitHash(snapshot_revision) + if revision is not None and snapshot_revision is not None: + if int(snapshot_revision) >= int(revision): + break + util.PrintAndFlush('Waiting for snapshot >= %s, found %s' % + (revision, snapshot_revision)) time.sleep(60) util.PrintAndFlush('Got snapshot revision %s' % snapshot_revision) diff --git a/chrome/test/chromedriver/session.h b/chrome/test/chromedriver/session.h index fe837fbf06..2df16d7ae6 100644 --- a/chrome/test/chromedriver/session.h +++ b/chrome/test/chromedriver/session.h @@ -16,6 +16,7 @@ #include "chrome/test/chromedriver/basic_types.h" #include "chrome/test/chromedriver/chrome/device_metrics.h" #include "chrome/test/chromedriver/chrome/geoposition.h" +#include "chrome/test/chromedriver/command_listener.h" namespace base { class DictionaryValue; @@ -77,6 +78,11 @@ struct Session { base::ScopedTempDir temp_dir; scoped_ptr<base::DictionaryValue> capabilities; bool auto_reporting_enabled; + // |command_listeners| should be declared after |chrome|. When the |Session| + // is destroyed, |command_listeners| should be freed first, since some + // |CommandListener|s might be |CommandListenerProxy|s that forward to + // |DevToolsEventListener|s owned by |chrome|. + ScopedVector<CommandListener> command_listeners; }; Session* GetThreadLocalSession(); diff --git a/chrome/test/chromedriver/session_commands.cc b/chrome/test/chromedriver/session_commands.cc index 864ffd7fa5..39eac7f2a8 100644 --- a/chrome/test/chromedriver/session_commands.cc +++ b/chrome/test/chromedriver/session_commands.cc @@ -28,6 +28,7 @@ #include "chrome/test/chromedriver/chrome/version.h" #include "chrome/test/chromedriver/chrome/web_view.h" #include "chrome/test/chromedriver/chrome_launcher.h" +#include "chrome/test/chromedriver/command_listener.h" #include "chrome/test/chromedriver/logging.h" #include "chrome/test/chromedriver/net/url_request_context_getter.h" #include "chrome/test/chromedriver/session.h" @@ -124,13 +125,18 @@ Status InitSessionHelper( // Create Log's and DevToolsEventListener's for ones that are DevTools-based. // Session will own the Log's, Chrome will own the listeners. + // Also create |CommandListener|s for the appropriate logs. ScopedVector<DevToolsEventListener> devtools_event_listeners; + ScopedVector<CommandListener> command_listeners; status = CreateLogs(capabilities, &session->devtools_logs, - &devtools_event_listeners); + &devtools_event_listeners, &command_listeners); if (status.IsError()) return status; + // |session| will own the |CommandListener|s. + session->command_listeners.swap(command_listeners); + status = LaunchChrome(bound_params.context_getter.get(), bound_params.socket_factory, bound_params.device_manager, @@ -477,7 +483,8 @@ Status ExecuteSetWindowPosition( Session* session, const base::DictionaryValue& params, scoped_ptr<base::Value>* value) { - double x, y; + double x = 0; + double y = 0; if (!params.GetDouble("x", &x) || !params.GetDouble("y", &y)) return Status(kUnknownError, "missing or invalid 'x' or 'y'"); @@ -528,7 +535,8 @@ Status ExecuteSetWindowSize( Session* session, const base::DictionaryValue& params, scoped_ptr<base::Value>* value) { - double width, height; + double width = 0; + double height = 0; if (!params.GetDouble("width", &width) || !params.GetDouble("height", &height)) return Status(kUnknownError, "missing or invalid 'width' or 'height'"); diff --git a/chrome/test/chromedriver/session_unittest.cc b/chrome/test/chromedriver/session_unittest.cc index 23fb779bd2..a9a73da71e 100644 --- a/chrome/test/chromedriver/session_unittest.cc +++ b/chrome/test/chromedriver/session_unittest.cc @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <list> #include <string> #include "base/memory/scoped_ptr.h" diff --git a/chrome/test/chromedriver/util.cc b/chrome/test/chromedriver/util.cc index e91689d45d..7671cc7670 100644 --- a/chrome/test/chromedriver/util.cc +++ b/chrome/test/chromedriver/util.cc @@ -9,6 +9,7 @@ #include "base/files/file_enumerator.h" #include "base/files/scoped_temp_dir.h" #include "base/format_macros.h" +#include "base/memory/scoped_vector.h" #include "base/rand_util.h" #include "base/strings/string16.h" #include "base/strings/string_util.h" @@ -18,7 +19,9 @@ #include "chrome/test/chromedriver/chrome/status.h" #include "chrome/test/chromedriver/chrome/ui_events.h" #include "chrome/test/chromedriver/chrome/web_view.h" +#include "chrome/test/chromedriver/command_listener.h" #include "chrome/test/chromedriver/key_converter.h" +#include "chrome/test/chromedriver/session.h" #include "third_party/zlib/google/zip.h" std::string GenerateId() { @@ -401,3 +404,15 @@ Status UnzipSoleFile(const base::FilePath& unzip_dir, *file = first_file; return Status(kOk); } + +void NotifySessionListenersBeforeCommand(Session* session, + const std::string& command_name) { + for (ScopedVector<CommandListener>::const_iterator it = + session->command_listeners.begin(); + it != session->command_listeners.end(); + ++it) { + Status status = (*it)->BeforeCommand(command_name); + if (status.IsError()) + LOG(ERROR) << "Error when notifying listener of command"; + } +} diff --git a/chrome/test/chromedriver/util.h b/chrome/test/chromedriver/util.h index 2e618ed7ae..d2b6962782 100644 --- a/chrome/test/chromedriver/util.h +++ b/chrome/test/chromedriver/util.h @@ -12,6 +12,7 @@ class FilePath; class ListValue; } +struct Session; class Status; class WebView; @@ -39,4 +40,8 @@ Status UnzipSoleFile(const base::FilePath& unzip_dir, const std::string& bytes, base::FilePath* file); +// Calls BeforeCommand for each of |session|'s |CommandListener|s. +void NotifySessionListenersBeforeCommand(Session* session, + const std::string& command_name); + #endif // CHROME_TEST_CHROMEDRIVER_UTIL_H_ diff --git a/chrome/test/ispy/common/ispy_utils.py b/chrome/test/ispy/common/ispy_utils.py index a138f07555..3d6ed15b39 100644 --- a/chrome/test/ispy/common/ispy_utils.py +++ b/chrome/test/ispy/common/ispy_utils.py @@ -290,15 +290,20 @@ class ISpyUtils(object): 'Failure', ['expected', 'diff', 'actual', 'info']) return Failure(expected, diff, actual, info) - def GetAllPaths(self, prefix): + def GetAllPaths(self, prefix, max_keys=None, marker=None, delimiter=None): """Gets urls to all files in GS whose path starts with a given prefix. Args: prefix: the prefix to filter files in GS by. + max_keys: Integer. Specifies the maximum number of objects returned + marker: String. Only objects whose fullpath starts lexicographically + after marker (exclusively) will be returned + delimiter: String. Turns on directory mode, specifies characters + to be used as directory separators Returns: a list containing urls to all objects that started with the prefix. """ - return self.cloud_bucket.GetAllPaths(prefix) - + return self.cloud_bucket.GetAllPaths( + prefix, max_keys=max_keys, marker=marker, delimiter=delimiter) diff --git a/chrome/test/ispy/server/gs_bucket.py b/chrome/test/ispy/server/gs_bucket.py index a132f05d53..263db001bd 100644 --- a/chrome/test/ispy/server/gs_bucket.py +++ b/chrome/test/ispy/server/gs_bucket.py @@ -67,6 +67,7 @@ class GoogleCloudStorageBucket(cloud_bucket.BaseCloudBucket): return '/image?file_path=%s' % path # override - def GetAllPaths(self, prefix): + def GetAllPaths(self, prefix, max_keys=None, marker=None, delimiter=None): return (f.filename[len(self.bucket) + 1:] for f in - cloudstorage.listbucket(self.bucket, prefix=prefix)) + cloudstorage.listbucket(self.bucket, prefix=prefix, + max_keys=max_keys, marker=marker, delimiter=delimiter)) diff --git a/chrome/test/ispy/server/main_view_handler.py b/chrome/test/ispy/server/main_view_handler.py index 0738a0c3d4..f82dc78fea 100644 --- a/chrome/test/ispy/server/main_view_handler.py +++ b/chrome/test/ispy/server/main_view_handler.py @@ -50,9 +50,14 @@ class MainViewHandler(webapp2.RequestHandler): """ template = JINJA.get_template('list_view.html') data = {} - test_runs = set([path.lstrip('/').split('/')[1] for path in - ispy.GetAllPaths('failures/')]) + max_keys = 1000 + marker = 'failures/%s' % self.request.get('marker') + test_runs = list([path.split('/')[1] for path in + ispy.GetAllPaths('failures/', max_keys=max_keys, + marker=marker, delimiter='/')]) base_url = '/?test_run=%s' + next_url = '/?marker=%s' % test_runs[-1] + data['next_url'] = next_url data['links'] = [(test_run, base_url % test_run) for test_run in test_runs] self.response.write(template.render(data)) diff --git a/chrome/test/ispy/server/views/list_view.html b/chrome/test/ispy/server/views/list_view.html index f6b5dc6c6f..9889a74069 100644 --- a/chrome/test/ispy/server/views/list_view.html +++ b/chrome/test/ispy/server/views/list_view.html @@ -16,6 +16,12 @@ </head> <body> <h3>Test Runs</h3> + <form method="get"> + <label for "prefix">Search Failures by Prefix:</label> + <input type="text" name="marker" id="prefix"> + <input type="submit" value="submit"> + </form> + <a href="{{ next_url }}">Next</a> <div id="container"> {% for link in links %} <div> diff --git a/chrome/test/mini_installer/test_installer.py b/chrome/test/mini_installer/test_installer.py index af6b2c3a33..25f5baff8a 100644 --- a/chrome/test/mini_installer/test_installer.py +++ b/chrome/test/mini_installer/test_installer.py @@ -254,7 +254,7 @@ def IsComponentBuild(mini_installer_path): query_command = mini_installer_path + ' --query-component-build' script_dir = os.path.dirname(os.path.abspath(__file__)) exit_status = subprocess.call(query_command, shell=True, cwd=script_dir) - return exit_status != 0 + return exit_status == 0 def main(): diff --git a/chrome/test/nacl/nacl_browsertest_uma.cc b/chrome/test/nacl/nacl_browsertest_uma.cc index 0f91ca4d2d..fb7a463f7d 100644 --- a/chrome/test/nacl/nacl_browsertest_uma.cc +++ b/chrome/test/nacl/nacl_browsertest_uma.cc @@ -28,15 +28,29 @@ NACL_BROWSER_TEST_F(NaClBrowserTest, SuccessfulLoadUMA, { LOAD_OK, 1); // Check validation cache usage: - // For the open-web, only the IRT is considered a "safe" and - // identity-cachable file. The nexes and .so files are not. - // Should have one cache query for the IRT. - histograms.ExpectBucketCount("NaCl.ValidationCache.Query", - nacl::NaClBrowser::CACHE_MISS, 1); - // TOTAL should then be 1 query so far. - histograms.ExpectTotalCount("NaCl.ValidationCache.Query", 1); - // Should have received a cache setting afterwards for IRT. - histograms.ExpectTotalCount("NaCl.ValidationCache.Set", 1); + if (IsAPnaclTest()) { + // Should have received 3 validation queries: + // - One for IRT for actual application + // - Two for two translator nexes + // The translators don't currently use the IRT, so there is no IRT cache + // query for those two loads. The PNaCl main nexe comes from a + // delete-on-close temp file, so it doesn't have a stable identity + // for validation caching. All three query results should be misses. + histograms.ExpectUniqueSample("NaCl.ValidationCache.Query", + nacl::NaClBrowser::CACHE_MISS, 3); + // Should have received a cache setting afterwards for IRT and translators. + histograms.ExpectUniqueSample("NaCl.ValidationCache.Set", + nacl::NaClBrowser::CACHE_HIT, 3); + } else { + // For the open-web, only the IRT is considered a "safe" and + // identity-cachable file. The nexes and .so files are not. + // Should have one cache query for the IRT. + histograms.ExpectUniqueSample("NaCl.ValidationCache.Query", + nacl::NaClBrowser::CACHE_MISS, 1); + // Should have received a cache setting afterwards for IRT and translators. + histograms.ExpectUniqueSample("NaCl.ValidationCache.Set", + nacl::NaClBrowser::CACHE_HIT, 1); + } // Make sure we have other important histograms. if (!IsAPnaclTest()) { @@ -110,6 +124,44 @@ IN_PROC_BROWSER_TEST_F(NaClBrowserTestVcacheExtension, histograms.ExpectTotalCount("NaCl.ValidationCache.Set", 2); } +// Test that validation for the 2 PNaCl translator nexes can be cached. +IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnacl, + ValidationCacheOfTranslatorNexes) { + // Run a load test w/ one pexe cache identity. + RunLoadTest(FILE_PATH_LITERAL("pnacl_options.html?use_nmf=o_0")); + + UMAHistogramHelper histograms; + histograms.Fetch(); + // Should have received 3 validation queries: + // - One for IRT for actual application + // - Two for two translator nexes + // The translators don't currently use the IRT, so there is no IRT cache + // query for those two loads. The PNaCl main nexe comes from a + // delete-on-close temp file, so it doesn't have a stable identity + // for validation caching. All three query results should be misses. + histograms.ExpectUniqueSample("NaCl.ValidationCache.Query", + nacl::NaClBrowser::CACHE_MISS, 3); + // Should have received a cache setting afterwards for IRT and translators. + histograms.ExpectUniqueSample("NaCl.ValidationCache.Set", + nacl::NaClBrowser::CACHE_HIT, 3); + + // Load the same pexe, but with a different cache identity. + // This means that translation will actually be redone, + // forcing the translators to be loaded a second time (but now with + // cache hits!) + RunLoadTest(FILE_PATH_LITERAL("pnacl_options.html?use_nmf=o_2")); + + // Should now have 3 more queries on top of the previous ones. + histograms.ExpectTotalCount("NaCl.ValidationCache.Query", 6); + // With the 3 extra queries being cache hits. + histograms.ExpectBucketCount("NaCl.ValidationCache.Query", + nacl::NaClBrowser::CACHE_HIT, 3); + // No extra cache settings. + histograms.ExpectUniqueSample("NaCl.ValidationCache.Set", + nacl::NaClBrowser::CACHE_HIT, 3); +} + + // TODO(ncbray) convert the rest of nacl_uma.py (currently in the NaCl repo.) // Test validation failures and crashes. diff --git a/chrome/test/nacl_test_injection/buildbot_chrome_nacl_stage.py b/chrome/test/nacl_test_injection/buildbot_chrome_nacl_stage.py index ca198f4a19..f67372900c 100755 --- a/chrome/test/nacl_test_injection/buildbot_chrome_nacl_stage.py +++ b/chrome/test/nacl_test_injection/buildbot_chrome_nacl_stage.py @@ -15,6 +15,11 @@ import sys import find_chrome +THIS_DIR = os.path.abspath(os.path.dirname(__file__)) +CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..')) +sys.path.append(os.path.join(CHROMIUM_DIR, 'build')) +import detect_host_arch + # Copied from buildbot/buildbot_lib.py def TryToCleanContents(path, file_name_filter=lambda fn: True): @@ -108,7 +113,7 @@ def BuildAndTest(options): else: chrome_filename = find_chrome.FindChrome(src_dir, [options.mode]) if chrome_filename is None: - raise Exception('Cannot find a chome binary - specify one with ' + raise Exception('Cannot find a chrome binary - specify one with ' '--browser_path?') env = dict(os.environ) @@ -149,17 +154,11 @@ def BuildAndTest(options): bits = 32 scons = [python, 'scons.py'] else: - p = subprocess.Popen( - 'uname -m | ' - 'sed -e "s/i.86/ia32/;s/x86_64/x64/;s/amd64/x64/;s/arm.*/arm/"', - shell=True, stdout=subprocess.PIPE) - (p_stdout, _) = p.communicate() - assert p.returncode == 0 if options.bits == 64: bits = 64 elif options.bits == 32: bits = 32 - elif p_stdout.find('64') >= 0: + elif '64' in detect_host_arch.HostArch(): bits = 64 else: bits = 32 diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc index 61f36365d4..7735b40974 100644 --- a/chrome/test/ppapi/ppapi_browsertest.cc +++ b/chrome/test/ppapi/ppapi_browsertest.cc @@ -65,6 +65,7 @@ using content::RenderViewHost; #define TEST_PPAPI_NACL_NO_PNACL(test_name) #define TEST_PPAPI_NACL_DISALLOWED_SOCKETS(test_name) #define TEST_PPAPI_NACL_WITH_SSL_SERVER(test_name) +#define TEST_PPAPI_NACL_SUBTESTS(test_name, run_statement) #else @@ -93,6 +94,22 @@ using content::RenderViewHost; RunTestViaHTTP(STRIP_PREFIXES(test_name)); \ } +// NaCl based PPAPI tests +#define TEST_PPAPI_NACL_SUBTESTS(test_name, run_statement) \ + IN_PROC_BROWSER_TEST_F(PPAPINaClNewlibTest, test_name) { \ + run_statement; \ + } \ + IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, MAYBE_GLIBC(test_name)) { \ + run_statement; \ + } \ + IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, test_name) { \ + run_statement; \ + } \ + IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, \ + MAYBE_PNACL_NONSFI(test_name)) { \ + run_statement; \ + } + // NaCl based PPAPI tests with disallowed socket API #define TEST_PPAPI_NACL_DISALLOWED_SOCKETS(test_name) \ IN_PROC_BROWSER_TEST_F(PPAPINaClTestDisallowedSockets, test_name) { \ @@ -974,21 +991,32 @@ IN_PROC_BROWSER_TEST_F(OutOfProcessPPAPITest, Flash) { LIST_TEST(WebSocket_UtilityGetProtocol) \ LIST_TEST(WebSocket_UtilityTextSendReceive) \ LIST_TEST(WebSocket_UtilityBinarySendReceive) \ + LIST_TEST(WebSocket_UtilityBufferedAmount) \ ) -// TODO(yhirano): List this test in SUBTESTS_2 once the close ordering -// is implemented correctly. -// LIST_TEST(WebSocket_UtilityBufferedAmount) -IN_PROC_BROWSER_TEST_F(PPAPITest, WebSocket1) { +// Repeatedly flaky on WinXP Tests(1): http://crbug.com/389084 +#if defined(OS_WIN) +#define MAYBE_WebSocket1 DISABLED_WebSocket1 +#else +#define MAYBE_WebSocket1 WebSocket1 +#endif +IN_PROC_BROWSER_TEST_F(PPAPITest, MAYBE_WebSocket1) { RUN_WEBSOCKET_SUBTESTS_1; } -IN_PROC_BROWSER_TEST_F(PPAPITest, WebSocket2) { + +// Repeatedly flaky on Win7 Tests(1): http://crbug.com/389084 +#if defined(OS_WIN) +#define MAYBE_WebSocket2 DISABLED_WebSocket2 +#else +#define MAYBE_WebSocket2 WebSocket2 +#endif +IN_PROC_BROWSER_TEST_F(PPAPITest, MAYBE_WebSocket2) { RUN_WEBSOCKET_SUBTESTS_2; } -IN_PROC_BROWSER_TEST_F(OutOfProcessPPAPITest, WebSocket1) { +IN_PROC_BROWSER_TEST_F(OutOfProcessPPAPITest, MAYBE_WebSocket1) { RUN_WEBSOCKET_SUBTESTS_1; } -IN_PROC_BROWSER_TEST_F(OutOfProcessPPAPITest, WebSocket2) { +IN_PROC_BROWSER_TEST_F(OutOfProcessPPAPITest, MAYBE_WebSocket2) { RUN_WEBSOCKET_SUBTESTS_2; } IN_PROC_BROWSER_TEST_F(PPAPINaClNewlibTest, WebSocket1) { @@ -1006,7 +1034,13 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, MAYBE_GLIBC(WebSocket2)) { IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, WebSocket1) { RUN_WEBSOCKET_SUBTESTS_1; } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, WebSocket2) { +// Flaky on XP Tests (3): http://crbug.com/389084 +#if defined(OS_WIN) +#define MAYBE_WebSocket2 DISABLED_WebSocket2 +#else +#define MAYBE_WebSocket2 WebSocket2 +#endif +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, MAYBE_WebSocket2) { RUN_WEBSOCKET_SUBTESTS_2; } IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, @@ -1112,7 +1146,7 @@ IN_PROC_BROWSER_TEST_F(OutOfProcessPPAPITest, View_CreateInvisible) { } // This test messes with tab visibility so is custom. -IN_PROC_BROWSER_TEST_F(OutOfProcessPPAPITest, View_PageHideShow) { +IN_PROC_BROWSER_TEST_F(OutOfProcessPPAPITest, DISABLED_View_PageHideShow) { // The plugin will be loaded in the foreground tab and will send us a message. PPAPITestMessageHandler handler; content::JavascriptTestObserver observer( @@ -1208,18 +1242,42 @@ IN_PROC_BROWSER_TEST_F(OutOfProcessPPAPITest, MAYBE_FlashMessageLoop) { RUN_FLASH_MESSAGE_LOOP_SUBTESTS; } +// The compositor test timeouts sometimes, so we have to split it to two +// subtests. +#define RUN_COMPOSITOR_SUBTESTS_0 \ + RunTestViaHTTP( \ + LIST_TEST(Compositor_BindUnbind) \ + LIST_TEST(Compositor_Release) \ + LIST_TEST(Compositor_ReleaseUnbound) \ + LIST_TEST(Compositor_ReleaseWithoutCommit) \ + LIST_TEST(Compositor_ReleaseWithoutCommitUnbound) \ + ) + +#define RUN_COMPOSITOR_SUBTESTS_1 \ + RunTestViaHTTP( \ + LIST_TEST(Compositor_CommitTwoTimesWithoutChange) \ + LIST_TEST(Compositor_CommitTwoTimesWithoutChangeUnbound) \ + LIST_TEST(Compositor_General) \ + LIST_TEST(Compositor_GeneralUnbound) \ + ) + #if defined(OS_WIN) // This test fails with the test compositor which is what's used by default for // browser tests on Windows. Renable when the software compositor is available. -#define MAYBE_Compositor DISABLED_Compositor +#define MAYBE_Compositor0 DISABLED_Compositor0 +#define MAYBE_Compositor1 DISABLED_Compositor1 #elif defined(OS_MACOSX) // This test fails when using the legacy software mode. Reenable when the // software compositor is enabled crbug.com/286038 -#define MAYBE_Compositor DISABLED_Compositor +#define MAYBE_Compositor0 DISABLED_Compositor0 +#define MAYBE_Compositor1 DISABLED_Compositor1 #else -#define MAYBE_Compositor Compositor +#define MAYBE_Compositor0 Compositor0 +#define MAYBE_Compositor1 Compositor1 #endif -TEST_PPAPI_NACL(MAYBE_Compositor) + +TEST_PPAPI_NACL_SUBTESTS(MAYBE_Compositor0, RUN_COMPOSITOR_SUBTESTS_0) +TEST_PPAPI_NACL_SUBTESTS(MAYBE_Compositor1, RUN_COMPOSITOR_SUBTESTS_1) TEST_PPAPI_NACL(MediaStreamAudioTrack) diff --git a/chrome/test/ppapi/ppapi_test.cc b/chrome/test/ppapi/ppapi_test.cc index 7bd3284cd5..9a951458a7 100644 --- a/chrome/test/ppapi/ppapi_test.cc +++ b/chrome/test/ppapi/ppapi_test.cc @@ -426,8 +426,10 @@ void PPAPIPrivateNaClPNaClTest::SetUpCommandLine( void PPAPINaClPNaClNonSfiTest::SetUpCommandLine( base::CommandLine* command_line) { +#if !defined(DISABLE_NACL) PPAPINaClTest::SetUpCommandLine(command_line); command_line->AppendSwitch(switches::kEnableNaClNonSfiMode); +#endif } std::string PPAPINaClPNaClNonSfiTest::BuildQuery( diff --git a/chrome/test/remoting/qunit_browser_test_runner.cc b/chrome/test/remoting/qunit_browser_test_runner.cc new file mode 100644 index 0000000000..da3509908e --- /dev/null +++ b/chrome/test/remoting/qunit_browser_test_runner.cc @@ -0,0 +1,53 @@ +// 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/remoting/qunit_browser_test_runner.h" + +#include "base/file_util.h" +#include "base/json/json_reader.h" +#include "base/values.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/test/browser_test_utils.h" +#include "net/base/filename_util.h" + +void QUnitBrowserTestRunner::QUnitStart(content::WebContents* web_contents) { + std::string result; + + // The test suite must include /third_party/qunit/src/browser_test_harness.js + // which exposes the entry point browserTestHarness.run(). + ASSERT_TRUE(content::ExecuteScriptAndExtractString( + web_contents, "browserTestHarness.run();", &result)); + + // Read in the JSON. + base::JSONReader reader; + scoped_ptr<base::Value> value; + value.reset(reader.Read(result, base::JSON_ALLOW_TRAILING_COMMAS)); + + // Convert to dictionary. + base::DictionaryValue* dict_value = NULL; + ASSERT_TRUE(value->GetAsDictionary(&dict_value)); + + // Extract the fields. + bool passed; + ASSERT_TRUE(dict_value->GetBoolean("passed", &passed)); + std::string error_message; + ASSERT_TRUE(dict_value->GetString("errorMessage", &error_message)); + + EXPECT_TRUE(passed) << error_message; +} + +void QUnitBrowserTestRunner::RunTest(const base::FilePath& file) { + ASSERT_TRUE(PathExists(file)) << "Error: The QUnit test suite <" + << file.value() << "> does not exist."; + ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(file)); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(web_contents); + + std::string result; + QUnitStart(web_contents); +} diff --git a/chrome/test/remoting/qunit_browser_test_runner.h b/chrome/test/remoting/qunit_browser_test_runner.h new file mode 100644 index 0000000000..56cc28915c --- /dev/null +++ b/chrome/test/remoting/qunit_browser_test_runner.h @@ -0,0 +1,24 @@ +// 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. + +#ifndef CHROME_TEST_REMOTING_QUNIT_BROWSER_TEST_RUNNER_H_ +#define CHROME_TEST_REMOTING_QUNIT_BROWSER_TEST_RUNNER_H_ + +#include "chrome/test/base/in_process_browser_test.h" + +namespace content { +class WebContents; +} + +// Base class for browser tests that run QUnit tests. +class QUnitBrowserTestRunner : public InProcessBrowserTest { + public: + // Runs the QUnit test suite in |file| and wait for it to complete. + void RunTest(const base::FilePath& file); + + private: + void QUnitStart(content::WebContents* web_contents); +}; + +#endif // CHROME_TEST_REMOTING_QUNIT_BROWSER_TEST_RUNNER_H_ diff --git a/chrome/test/remoting/remote_desktop_browsertest.h b/chrome/test/remoting/remote_desktop_browsertest.h index 579c2f2103..10755b8c27 100644 --- a/chrome/test/remoting/remote_desktop_browsertest.h +++ b/chrome/test/remoting/remote_desktop_browsertest.h @@ -5,6 +5,7 @@ #ifndef CHROME_TEST_REMOTING_REMOTE_DESKTOP_BROWSERTEST_H_ #define CHROME_TEST_REMOTING_REMOTE_DESKTOP_BROWSERTEST_H_ +#include "base/debug/stack_trace.h" #include "chrome/browser/apps/app_browsertest_util.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -30,6 +31,13 @@ const char kHttpServer[] = "http-server"; // ASSERT_TRUE can only be used in void returning functions. This version // should be used in non-void-returning functions. inline void _ASSERT_TRUE(bool condition) { + if (!condition) { + // ASSERT_TRUE only prints the first call frame in the error message. + // In our case, this is the _ASSERT_TRUE wrapper function, which is not + // useful. To help with debugging, we will dump the full callstack. + LOG(ERROR) << "Assertion failed."; + LOG(ERROR) << base::debug::StackTrace().ToString(); + } ASSERT_TRUE(condition); return; } diff --git a/chrome/test/remoting/webapp_javascript_unittest.cc b/chrome/test/remoting/webapp_javascript_unittest.cc new file mode 100644 index 0000000000..5b4793ed6e --- /dev/null +++ b/chrome/test/remoting/webapp_javascript_unittest.cc @@ -0,0 +1,28 @@ +// 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 "base/path_service.h" +#include "chrome/test/remoting/qunit_browser_test_runner.h" + +#if defined(OS_MACOSX) +#include "base/mac/mac_util.h" +#endif // !defined(OS_MACOSX) + +namespace remoting { + +IN_PROC_BROWSER_TEST_F(QUnitBrowserTestRunner, Remoting_Webapp_Js_Unittest) { + base::FilePath base_dir; + ASSERT_TRUE(PathService::Get(base::DIR_EXE, &base_dir)); + +#if defined(OS_MACOSX) + if (base::mac::AmIBundled()) { + // If we are inside a mac bundle, navigate up to the output directory + base_dir = base::mac::GetAppBundlePath(base_dir).DirName(); + } +#endif // !defined(OS_MACOSX) + RunTest( + base_dir.Append(FILE_PATH_LITERAL("remoting/unittests/unittest.html"))); +} + +} // namespace remoting |