diff options
author | Torne (Richard Coles) <torne@google.com> | 2013-10-31 11:16:26 +0000 |
---|---|---|
committer | Torne (Richard Coles) <torne@google.com> | 2013-10-31 11:16:26 +0000 |
commit | 1e9bf3e0803691d0a228da41fc608347b6db4340 (patch) | |
tree | ab2e5565f71b4219b3da406e19f16fe306704ef5 /chrome/test | |
parent | f10b58d5bc6ae3e74076fc4ccca14cbc57ef805c (diff) | |
download | chromium_org-1e9bf3e0803691d0a228da41fc608347b6db4340.tar.gz |
Merge from Chromium at DEPS revision 232015
This commit was generated by merge_to_master.py.
Change-Id: If86767ad396b9e2e1a4c1e9df1427daea29703ef
Diffstat (limited to 'chrome/test')
58 files changed, 551 insertions, 423 deletions
diff --git a/chrome/test/DEPS b/chrome/test/DEPS index 5a9fdbd848..595b0db1c9 100644 --- a/chrome/test/DEPS +++ b/chrome/test/DEPS @@ -1,6 +1,7 @@ include_rules = [ # The test directory can do whatever it wants in chrome, and may # rely on components. + "+ash", "+chrome", "+chromeos", "+components", diff --git a/chrome/test/android/OWNERS b/chrome/test/android/OWNERS index df798f4460..b8e17f3800 100644 --- a/chrome/test/android/OWNERS +++ b/chrome/test/android/OWNERS @@ -2,7 +2,7 @@ aruslan@chromium.org bulach@chromium.org dfalcantara@chromium.org dtrainor@chromium.org -miguelg@chromium.org nyquist@chromium.org +skyostil@chromium.org tedchoc@chromium.org yfriedman@chromium.org diff --git a/chrome/test/base/browser_perf_tests_main.cc b/chrome/test/base/browser_perf_tests_main.cc new file mode 100644 index 0000000000..e9aafbf7b3 --- /dev/null +++ b/chrome/test/base/browser_perf_tests_main.cc @@ -0,0 +1,11 @@ +// Copyright 2013 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/chrome_test_launcher.h" + +int main(int argc, char** argv) { + // Always run browser perf tests serially - parallel running would be less + // deterministic and distort perf measurements. + return LaunchChromeTests(1, argc, argv); +} diff --git a/chrome/test/base/browser_tests_main.cc b/chrome/test/base/browser_tests_main.cc new file mode 100644 index 0000000000..cb2accea5b --- /dev/null +++ b/chrome/test/base/browser_tests_main.cc @@ -0,0 +1,11 @@ +// Copyright 2013 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/sys_info.h" +#include "chrome/test/base/chrome_test_launcher.h" + +int main(int argc, char** argv) { + int default_jobs = std::max(1, base::SysInfo::NumberOfProcessors() / 2); + return LaunchChromeTests(default_jobs, argc, argv); +} diff --git a/chrome/test/base/browser_with_test_window_test.cc b/chrome/test/base/browser_with_test_window_test.cc index 73efa627e1..16f22df321 100644 --- a/chrome/test/base/browser_with_test_window_test.cc +++ b/chrome/test/base/browser_with_test_window_test.cc @@ -59,7 +59,7 @@ void BrowserWithTestWindowTest::SetUp() { #endif // USE_AURA // Subclasses can provide their own Profile. - profile_.reset(CreateProfile()); + profile_ = CreateProfile(); // Subclasses can provide their own test BrowserWindow. If they return NULL // then Browser will create the a production BrowserWindow and the subclass // is responsible for cleaning it up (usually by NativeWidget destruction). @@ -179,13 +179,19 @@ void BrowserWithTestWindowTest::DestroyBrowserAndProfile() { // destructor, and a test subclass owns a resource that the profile depends // on (such as g_browser_process()->local_state()) there's no way for the // subclass to free it after the profile. - profile_.reset(NULL); + if (profile_) + DestroyProfile(profile_); + profile_ = NULL; } TestingProfile* BrowserWithTestWindowTest::CreateProfile() { return new TestingProfile(); } +void BrowserWithTestWindowTest::DestroyProfile(TestingProfile* profile) { + delete profile; +} + BrowserWindow* BrowserWithTestWindowTest::CreateBrowserWindow() { return new TestBrowserWindow(); } diff --git a/chrome/test/base/browser_with_test_window_test.h b/chrome/test/base/browser_with_test_window_test.h index f4e6e51107..91bb325460 100644 --- a/chrome/test/base/browser_with_test_window_test.h +++ b/chrome/test/base/browser_with_test_window_test.h @@ -95,9 +95,9 @@ class BrowserWithTestWindowTest : public testing::Test { return browser_.release(); } - TestingProfile* profile() const { return profile_.get(); } + TestingProfile* profile() const { return profile_; } - TestingProfile* GetProfile() { return profile_.get(); } + TestingProfile* GetProfile() { return profile_; } BrowserWindow* release_browser_window() WARN_UNUSED_RESULT { return window_.release(); @@ -134,6 +134,9 @@ class BrowserWithTestWindowTest : public testing::Test { // Creates the profile used by this test. The caller owns the return value. virtual TestingProfile* CreateProfile(); + // Destroys the profile which was created through |CreateProfile|. + virtual void DestroyProfile(TestingProfile* profile); + // Creates the BrowserWindow used by this test. The caller owns the return // value. Can return NULL to use the default window created by Browser. virtual BrowserWindow* CreateBrowserWindow(); @@ -149,7 +152,10 @@ class BrowserWithTestWindowTest : public testing::Test { chromeos::ScopedTestUserManager test_user_manager_; #endif - scoped_ptr<TestingProfile> profile_; + // The profile will automatically be destroyed by TearDown using the + // |DestroyProfile()| function - which can be overwritten by derived testing + // frameworks. + TestingProfile* profile_; scoped_ptr<BrowserWindow> window_; // Usually a TestBrowserWindow. scoped_ptr<Browser> browser_; diff --git a/chrome/test/base/chrome_test_launcher.cc b/chrome/test/base/chrome_test_launcher.cc index 442e344a0f..f14ace3810 100644 --- a/chrome/test/base/chrome_test_launcher.cc +++ b/chrome/test/base/chrome_test_launcher.cc @@ -42,6 +42,9 @@ #if defined(USE_AURA) #include "ui/aura/test/ui_controls_factory_aura.h" #include "ui/base/test/ui_controls_aura.h" +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) +#include "ui/views/test/ui_controls_factory_desktop_aurax11.h" +#endif #endif #if defined(OS_CHROMEOS) @@ -52,6 +55,8 @@ #include "chrome/app/chrome_breakpad_client.h" #endif +namespace { + class ChromeTestLauncherDelegate : public content::TestLauncherDelegate { public: ChromeTestLauncherDelegate() {} @@ -123,39 +128,13 @@ class ChromeTestLauncherDelegate : public content::TestLauncherDelegate { DISALLOW_COPY_AND_ASSIGN(ChromeTestLauncherDelegate); }; -int main(int argc, char** argv) { -// http://crbug.com/163931 Disabled until interactive_ui_tests ready on Linux -// Aura. -#if defined(OS_LINUX) && defined(USE_AURA) && !defined(OS_CHROMEOS) - base::FilePath bin_dir; - CHECK(file_util::ReadSymbolicLink( - base::FilePath(base::kProcSelfExe), &bin_dir)); - std::string filename = bin_dir.value(); - // http://crbug.com/154081: early exit until interactive_ui_tests are green. - if (EndsWith(filename, "interactive_ui_tests", false)) { - LOG(INFO) << "interactive_ui_tests on Linux Aura are not ready yet."; - return 0; - } -#endif +} // namespace +int LaunchChromeTests(int default_jobs, int argc, char** argv) { #if defined(OS_MACOSX) chrome_browser_application_mac::RegisterBrowserCrApp(); #endif -// Only allow ui_controls to be used in interactive_ui_tests, since they depend -// on focus and can't be sharded. -#if defined(INTERACTIVE_TESTS) - ui_controls::EnableUIControls(); - -#if defined(OS_CHROMEOS) - ui_controls::InstallUIControlsAura(ash::test::CreateAshUIControls()); -#elif defined(USE_AURA) - // TODO(win_ash): when running interactive_ui_tests for Win Ash, use above. - ui_controls::InstallUIControlsAura(aura::test::CreateUIControlsAura(NULL)); -#endif - -#endif - #if defined(OS_LINUX) || defined(OS_ANDROID) // We leak this pointer intentionally. The breakpad client needs to outlive // all other code. @@ -166,5 +145,5 @@ int main(int argc, char** argv) { #endif ChromeTestLauncherDelegate launcher_delegate; - return content::LaunchTests(&launcher_delegate, argc, argv); + return content::LaunchTests(&launcher_delegate, default_jobs, argc, argv); } diff --git a/chrome/test/base/chrome_test_launcher.h b/chrome/test/base/chrome_test_launcher.h new file mode 100644 index 0000000000..b9254d3176 --- /dev/null +++ b/chrome/test/base/chrome_test_launcher.h @@ -0,0 +1,13 @@ +// Copyright 2013 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_CHROME_TEST_LAUNCHER_H_ +#define CHROME_TEST_BASE_CHROME_TEST_LAUNCHER_H_ + +// Launches Chrome tests using |launcher_delegate|. |default_jobs| is number +// of test jobs to be run in parallel, unless overridden from the command line. +// Returns exit code. +int LaunchChromeTests(int default_jobs, int argc, char** argv); + +#endif // CHROME_TEST_BASE_CHROME_TEST_LAUNCHER_H_ diff --git a/chrome/test/base/chrome_test_suite.cc b/chrome/test/base/chrome_test_suite.cc index ad2967e8cf..e010054e9f 100644 --- a/chrome/test/base/chrome_test_suite.cc +++ b/chrome/test/base/chrome_test_suite.cc @@ -17,6 +17,7 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_content_browser_client.h" +#include "chrome/browser/extensions/chrome_extensions_browser_client.h" #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_content_client.h" @@ -171,6 +172,8 @@ void ChromeTestSuite::Initialize() { extensions::ExtensionsClient::Set( extensions::ChromeExtensionsClient::GetInstance()); + extensions::ExtensionsBrowserClient::Set( + extensions::ChromeExtensionsBrowserClient::GetInstance()); // Only want to do this for unit tests. if (!content::GetCurrentTestLauncherDelegate()) { diff --git a/chrome/test/base/interactive_test_utils_win.cc b/chrome/test/base/interactive_test_utils_win.cc index ec7e28543f..7a4f747aaa 100644 --- a/chrome/test/base/interactive_test_utils_win.cc +++ b/chrome/test/base/interactive_test_utils_win.cc @@ -29,7 +29,7 @@ void HideNativeWindow(gfx::NativeWindow window) { HideNativeWindowAura(window); return; } - HWND hwnd = window->GetRootWindow()->GetAcceleratedWidget(); + HWND hwnd = window->GetDispatcher()->GetAcceleratedWidget(); #else HWND hwnd = window; #endif @@ -41,8 +41,9 @@ bool ShowAndFocusNativeWindow(gfx::NativeWindow window) { if (chrome::GetHostDesktopTypeForNativeWindow(window) == chrome::HOST_DESKTOP_TYPE_ASH) ShowAndFocusNativeWindowAura(window); + window->Show(); // Always make sure the window hosting ash is visible and focused. - HWND hwnd = window->GetRootWindow()->GetAcceleratedWidget(); + HWND hwnd = window->GetDispatcher()->GetAcceleratedWidget(); #else HWND hwnd = window; #endif diff --git a/chrome/test/base/interactive_ui_tests_main.cc b/chrome/test/base/interactive_ui_tests_main.cc new file mode 100644 index 0000000000..8de925a721 --- /dev/null +++ b/chrome/test/base/interactive_ui_tests_main.cc @@ -0,0 +1,41 @@ +// Copyright 2013 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/chrome_test_launcher.h" + +#include "ui/base/test/ui_controls.h" + +#if defined(USE_AURA) +#include "ui/aura/test/ui_controls_factory_aura.h" +#include "ui/base/test/ui_controls_aura.h" +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) +#include "ui/views/test/ui_controls_factory_desktop_aurax11.h" +#endif +#endif + +#if defined(OS_CHROMEOS) +#include "ash/test/ui_controls_factory_ash.h" +#endif + +int main(int argc, char** argv) { + // Only allow ui_controls to be used in interactive_ui_tests, since they + // depend on focus and can't be sharded. + ui_controls::EnableUIControls(); + +#if defined(OS_CHROMEOS) + ui_controls::InstallUIControlsAura(ash::test::CreateAshUIControls()); +#elif defined(USE_AURA) + +#if defined(OS_LINUX) + ui_controls::InstallUIControlsAura( + views::test::CreateUIControlsDesktopAura()); +#else + // TODO(win_ash): when running interactive_ui_tests for Win Ash, use above. + ui_controls::InstallUIControlsAura(aura::test::CreateUIControlsAura(NULL)); +#endif +#endif + + // Run interactive_ui_tests serially, they do not support running in parallel. + return LaunchChromeTests(1, argc, argv); +} diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index 1f2804453c..a6d9682781 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h @@ -101,6 +101,9 @@ class TestBrowserWindow : public BrowserWindow { virtual void ShowUpdateChromeDialog() OVERRIDE {} virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked) OVERRIDE {} + virtual void ShowTranslateBubble( + content::WebContents* contents, + TranslateBubbleModel::ViewState view_state) OVERRIDE {} #if defined(ENABLE_ONE_CLICK_SIGNIN) virtual void ShowOneClickSigninBubble( OneClickSigninBubbleType type, diff --git a/chrome/test/base/test_tab_strip_model_observer.cc b/chrome/test/base/test_tab_strip_model_observer.cc deleted file mode 100644 index f25a599b19..0000000000 --- a/chrome/test/base/test_tab_strip_model_observer.cc +++ /dev/null @@ -1,83 +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/test_tab_strip_model_observer.h" - -#include "base/bind.h" -#include "base/message_loop/message_loop.h" -#include "chrome/browser/printing/print_preview_dialog_controller.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/notification_types.h" -#include "content/public/browser/render_view_host_observer.h" -#include "content/public/browser/web_contents.h" -#include "content/public/test/js_injection_ready_observer.h" - -class TestTabStripModelObserver::RenderViewHostInitializedObserver - : public content::RenderViewHostObserver { - public: - RenderViewHostInitializedObserver(content::RenderViewHost* render_view_host, - content::JsInjectionReadyObserver* observer) - : content::RenderViewHostObserver(render_view_host), - injection_observer_(observer) { - } - - // content::RenderViewHostObserver: - virtual void RenderViewHostInitialized() OVERRIDE { - injection_observer_->OnJsInjectionReady(render_view_host()); - } - - private: - content::JsInjectionReadyObserver* injection_observer_; - - DISALLOW_COPY_AND_ASSIGN(RenderViewHostInitializedObserver); -}; - -TestTabStripModelObserver::TestTabStripModelObserver( - TabStripModel* tab_strip_model, - content::JsInjectionReadyObserver* js_injection_ready_observer) - : TestNavigationObserver(NULL, 1), - tab_strip_model_(tab_strip_model), - rvh_created_callback_( - base::Bind(&TestTabStripModelObserver::RenderViewHostCreated, - base::Unretained(this))), - injection_observer_(js_injection_ready_observer) { - content::RenderViewHost::AddCreatedCallback(rvh_created_callback_); - tab_strip_model_->AddObserver(this); -} - -TestTabStripModelObserver::~TestTabStripModelObserver() { - content::RenderViewHost::RemoveCreatedCallback(rvh_created_callback_); - tab_strip_model_->RemoveObserver(this); -} - -void TestTabStripModelObserver::RenderViewHostCreated( - content::RenderViewHost* rvh) { - rvh_observer_.reset( - new RenderViewHostInitializedObserver(rvh, injection_observer_)); -} - -void TestTabStripModelObserver::TabBlockedStateChanged( - content::WebContents* contents, int index) { - // Need to do this later - the print preview dialog has not been created yet. - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&TestTabStripModelObserver::ObservePrintPreviewDialog, - base::Unretained(this), - contents)); -} - -void TestTabStripModelObserver::ObservePrintPreviewDialog( - content::WebContents* contents) { - printing::PrintPreviewDialogController* dialog_controller = - printing::PrintPreviewDialogController::GetInstance(); - if (!dialog_controller) - return; - content::WebContents* preview_dialog = - dialog_controller->GetPrintPreviewForContents(contents); - if (!preview_dialog) - return; - RegisterAsObserver(preview_dialog); -} diff --git a/chrome/test/base/test_tab_strip_model_observer.h b/chrome/test/base/test_tab_strip_model_observer.h deleted file mode 100644 index 13e18ea3bf..0000000000 --- a/chrome/test/base/test_tab_strip_model_observer.h +++ /dev/null @@ -1,62 +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_TEST_TAB_STRIP_MODEL_OBSERVER_H_ -#define CHROME_TEST_BASE_TEST_TAB_STRIP_MODEL_OBSERVER_H_ - -#include "base/compiler_specific.h" -#include "chrome/browser/ui/tabs/tab_strip_model_observer.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/test/test_navigation_observer.h" - -class TabStripModel; - -namespace content { -class JsInjectionReadyObserver; -} - -// In order to support testing of print preview, we need to wait for the -// constrained window to block the current tab, and then observe notifications -// on the newly added tab's controller to wait for it to be loaded. -// To support tests registering javascript WebUI handlers, we need to inject -// the framework & registration javascript before the webui page loads by -// calling back through the TestTabStripModelObserver::LoadStartObserver when -// the new page starts loading. -class TestTabStripModelObserver : public content::TestNavigationObserver, - public TabStripModelObserver { - public: - // Observe the |tab_strip_model|, which may not be NULL. If - // |load_start_observer| is non-NULL, notify when the page load starts. - TestTabStripModelObserver( - TabStripModel* tab_strip_model, - content::JsInjectionReadyObserver* js_injection_ready_observer); - virtual ~TestTabStripModelObserver(); - - private: - class RenderViewHostInitializedObserver; - - void RenderViewHostCreated(content::RenderViewHost* rvh); - - // Callback to observer the print preview dialog associated with |contents|. - void ObservePrintPreviewDialog(content::WebContents* contents); - - // TabStripModelObserver: - virtual void TabBlockedStateChanged(content::WebContents* contents, - int index) OVERRIDE; - - // |tab_strip_model_| is the object this observes. The constructor will - // register this as an observer, and the destructor will remove the observer. - TabStripModel* tab_strip_model_; - - content::RenderViewHost::CreatedCallback rvh_created_callback_; - - // RenderViewHost watched for JS injection. - scoped_ptr<RenderViewHostInitializedObserver> rvh_observer_; - - content::JsInjectionReadyObserver* injection_observer_; - - DISALLOW_COPY_AND_ASSIGN(TestTabStripModelObserver); -}; - -#endif // CHROME_TEST_BASE_TEST_TAB_STRIP_MODEL_OBSERVER_H_ diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index bc655aa35e..83de4b47dd 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc @@ -700,12 +700,20 @@ TestingProfile::GetMediaRequestContextForStoragePartition( void TestingProfile::RequestMIDISysExPermission( int render_process_id, int render_view_id, + int bridge_id, const GURL& requesting_frame, const MIDISysExPermissionCallback& callback) { // Always reject requests for testing. callback.Run(false); } +void TestingProfile::CancelMIDISysExPermissionRequest( + int render_process_id, + int render_view_id, + int bridge_id, + const GURL& requesting_frame) { +} + net::URLRequestContextGetter* TestingProfile::GetRequestContextForExtensions() { if (!extensions_request_context_.get()) extensions_request_context_ = new TestExtensionURLRequestContextGetter(); diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h index 297cb9529f..6f2f3eb20c 100644 --- a/chrome/test/base/testing_profile.h +++ b/chrome/test/base/testing_profile.h @@ -263,8 +263,14 @@ class TestingProfile : public Profile { virtual void RequestMIDISysExPermission( int render_process_id, int render_view_id, + int bridge_id, const GURL& requesting_frame, const MIDISysExPermissionCallback& callback) OVERRIDE; + virtual void CancelMIDISysExPermissionRequest( + int render_process_id, + int render_view_id, + int bridge_id, + const GURL& requesting_frame) OVERRIDE; virtual net::URLRequestContextGetter* CreateRequestContextForStoragePartition( const base::FilePath& partition_path, bool in_memory, diff --git a/chrome/test/base/view_event_test_base.cc b/chrome/test/base/view_event_test_base.cc index eb9fb3d0de..ac4d8acd71 100644 --- a/chrome/test/base/view_event_test_base.cc +++ b/chrome/test/base/view_event_test_base.cc @@ -13,6 +13,7 @@ #include "content/public/browser/browser_thread.h" #include "ui/base/ime/input_method_initializer.h" #include "ui/base/test/ui_controls.h" +#include "ui/compositor/test/context_factories_for_test.h" #include "ui/message_center/message_center.h" #include "ui/views/view.h" #include "ui/views/widget/desktop_aura/desktop_screen.h" @@ -22,9 +23,6 @@ #include "ash/shell.h" #include "ash/test/test_session_state_delegate.h" #include "ash/test/test_shell_delegate.h" -#if defined(OS_WIN) -#include "ui/compositor/compositor.h" -#endif #endif #if defined(USE_AURA) @@ -102,17 +100,15 @@ void ViewEventTestBase::SetUp() { gfx::NativeView context = NULL; #if defined(USE_ASH) + // The ContextFactory must exist before any Compositors are created. + bool allow_test_contexts = true; + ui::InitializeContextFactoryForTests(allow_test_contexts); #if defined(OS_WIN) // http://crbug.com/154081 use ash::Shell code path below on win_ash bots when // interactive_ui_tests is brought up on that platform. gfx::Screen::SetScreenInstance( gfx::SCREEN_TYPE_NATIVE, views::CreateDesktopScreen()); - // The ContextFactory must exist before any Compositors are created. The - // ash::Shell code path below handles this, but since we skip it we must - // do this here. - bool allow_test_contexts = true; - ui::Compositor::InitializeContextFactoryForTests(allow_test_contexts); #else // !OS_WIN // Ash Shell can't just live on its own without a browser process, we need to // also create the message center. @@ -164,6 +160,7 @@ void ViewEventTestBase::TearDown() { message_center::MessageCenter::Shutdown(); #endif // !OS_WIN aura::Env::DeleteInstance(); + ui::TerminateContextFactoryForTests(); #elif defined(USE_AURA) aura_test_helper_->TearDown(); #endif // !USE_ASH && USE_AURA diff --git a/chrome/test/base/web_ui_browsertest.cc b/chrome/test/base/web_ui_browsertest.cc index bfa5f95f25..4b6d6b2102 100644 --- a/chrome/test/base/web_ui_browsertest.cc +++ b/chrome/test/base/web_ui_browsertest.cc @@ -14,27 +14,30 @@ #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" +#include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/browser/ui/webui/web_ui_test_handler.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/test_chrome_web_ui_controller_factory.h" -#include "chrome/test/base/test_tab_strip_model_observer.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" -#include "content/public/browser/render_view_host_observer.h" #include "content/public/browser/url_data_source.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_ui_controller.h" #include "content/public/browser/web_ui_message_handler.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/test_navigation_observer.h" #include "net/base/net_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest-spi.h" @@ -78,54 +81,26 @@ bool LogHandler(int severity, return false; } -class RenderViewHostInitializedObserver - : public content::RenderViewHostObserver { +class WebUIJsInjectionReadyObserver : public content::WebContentsObserver { public: - RenderViewHostInitializedObserver(content::RenderViewHost* render_view_host, - content::JsInjectionReadyObserver* observer) - : content::RenderViewHostObserver(render_view_host), - injection_observer_(observer) { - } - - // content::RenderViewHostObserver: - virtual void RenderViewHostInitialized() OVERRIDE { - injection_observer_->OnJsInjectionReady(render_view_host()); - } - - private: - content::JsInjectionReadyObserver* injection_observer_; - - DISALLOW_COPY_AND_ASSIGN(RenderViewHostInitializedObserver); -}; - -class WebUIJsInjectionReadyObserver { - public: - explicit WebUIJsInjectionReadyObserver( - content::JsInjectionReadyObserver* observer) - : injection_observer_(observer), - rvh_callback_( - base::Bind(&WebUIJsInjectionReadyObserver::RenderViewHostCreated, - base::Unretained(this))) { - content::RenderViewHost::AddCreatedCallback(rvh_callback_); - } - - ~WebUIJsInjectionReadyObserver() { - content::RenderViewHost::RemoveCreatedCallback(rvh_callback_); + WebUIJsInjectionReadyObserver(content::WebContents* web_contents, + WebUIBrowserTest* browser_test, + const std::string& preload_test_fixture, + const std::string& preload_test_name) + : content::WebContentsObserver(web_contents), + browser_test_(browser_test), + preload_test_fixture_(preload_test_fixture), + preload_test_name_(preload_test_name) {} + + virtual void RenderViewCreated(content::RenderViewHost* rvh) OVERRIDE { + browser_test_->PreLoadJavascriptLibraries( + preload_test_fixture_, preload_test_name_, rvh); } private: - void RenderViewHostCreated(content::RenderViewHost* rvh) { - rvh_observer_.reset( - new RenderViewHostInitializedObserver(rvh, injection_observer_)); - } - - content::JsInjectionReadyObserver* injection_observer_; - - scoped_ptr<RenderViewHostInitializedObserver> rvh_observer_; - - content::RenderViewHost::CreatedCallback rvh_callback_; - - DISALLOW_COPY_AND_ASSIGN(WebUIJsInjectionReadyObserver); + WebUIBrowserTest* browser_test_; + std::string preload_test_fixture_; + std::string preload_test_name_; }; } // namespace @@ -268,9 +243,11 @@ void WebUIBrowserTest::PreLoadJavascriptLibraries( } void WebUIBrowserTest::BrowsePreload(const GURL& browse_to) { - WebUIJsInjectionReadyObserver injection_observer(this); - content::TestNavigationObserver navigation_observer( - browser()->tab_strip_model()->GetActiveWebContents()); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + WebUIJsInjectionReadyObserver injection_observer( + web_contents, this, preload_test_fixture_, preload_test_name_); + content::TestNavigationObserver navigation_observer(web_contents); chrome::NavigateParams params(browser(), GURL(browse_to), content::PAGE_TRANSITION_TYPED); params.disposition = CURRENT_TAB; @@ -278,14 +255,61 @@ void WebUIBrowserTest::BrowsePreload(const GURL& browse_to) { navigation_observer.Wait(); } +#if defined(ENABLE_FULL_PRINTING) + +// This custom ContentBrowserClient is used to get notified when a WebContents +// for the print preview dialog gets created. +class PrintContentBrowserClient : public chrome::ChromeContentBrowserClient { + public: + PrintContentBrowserClient(WebUIBrowserTest* browser_test, + const std::string& preload_test_fixture, + const std::string& preload_test_name) + : browser_test_(browser_test), + preload_test_fixture_(preload_test_fixture), + preload_test_name_(preload_test_name), + preview_dialog_(NULL), + message_loop_runner_(new content::MessageLoopRunner) {} + + void Wait() { + message_loop_runner_->Run(); + content::WaitForLoadStop(preview_dialog_); + } + + private: + // ChromeContentBrowserClient implementation: + virtual content::WebContentsViewPort* OverrideCreateWebContentsView( + content::WebContents* web_contents, + content::RenderViewHostDelegateView** view) OVERRIDE { + preview_dialog_ = web_contents; + observer_.reset(new WebUIJsInjectionReadyObserver( + preview_dialog_, browser_test_, preload_test_fixture_, + preload_test_name_)); + message_loop_runner_->Quit(); + return NULL; + } + + WebUIBrowserTest* browser_test_; + scoped_ptr<WebUIJsInjectionReadyObserver> observer_; + std::string preload_test_fixture_; + std::string preload_test_name_; + content::WebContents* preview_dialog_; + scoped_refptr<content::MessageLoopRunner> message_loop_runner_; +}; +#endif + void WebUIBrowserTest::BrowsePrintPreload(const GURL& browse_to) { #if defined(ENABLE_FULL_PRINTING) ui_test_utils::NavigateToURL(browser(), browse_to); - TestTabStripModelObserver tabstrip_observer( - browser()->tab_strip_model(), this); + PrintContentBrowserClient new_client( + this, preload_test_fixture_, preload_test_name_); + content::ContentBrowserClient* old_client = + SetBrowserClientForTesting(&new_client); + chrome::Print(browser()); - tabstrip_observer.Wait(); + new_client.Wait(); + + SetBrowserClientForTesting(old_client); printing::PrintPreviewDialogController* tab_controller = printing::PrintPreviewDialogController::GetInstance(); @@ -437,11 +461,6 @@ GURL WebUIBrowserTest::WebUITestDataPathToURL( return net::FilePathToFileURL(test_path); } -void WebUIBrowserTest::OnJsInjectionReady(RenderViewHost* render_view_host) { - PreLoadJavascriptLibraries(preload_test_fixture_, preload_test_name_, - render_view_host); -} - void WebUIBrowserTest::BuildJavascriptLibraries(string16* content) { ASSERT_TRUE(content != NULL); std::string utf8_content; diff --git a/chrome/test/base/web_ui_browsertest.h b/chrome/test/base/web_ui_browsertest.h index 4dec52ebbf..dfda6614c2 100644 --- a/chrome/test/base/web_ui_browsertest.h +++ b/chrome/test/base/web_ui_browsertest.h @@ -12,7 +12,6 @@ #include "base/memory/scoped_vector.h" #include "base/strings/string16.h" #include "chrome/test/base/in_process_browser_test.h" -#include "content/public/test/js_injection_ready_observer.h" namespace base { class Value; @@ -41,9 +40,7 @@ class WebUITestHandler; // These tests should follow the form given in: // chrome/test/data/webui/sample_downloads.js. // and the lone test within this class. -class WebUIBrowserTest - : public InProcessBrowserTest, - public content::JsInjectionReadyObserver { +class WebUIBrowserTest : public InProcessBrowserTest { public: typedef ScopedVector<const base::Value> ConstValueVector; virtual ~WebUIBrowserTest(); @@ -140,10 +137,6 @@ class WebUIBrowserTest static GURL WebUITestDataPathToURL(const base::FilePath::StringType& path); private: - // content::JsInjectionReadyObserver implementation. - virtual void OnJsInjectionReady( - content::RenderViewHost* render_view_host) OVERRIDE; - // Builds a string containing all added javascript libraries. void BuildJavascriptLibraries(string16* content); diff --git a/chrome/test/chromedriver/VERSION b/chrome/test/chromedriver/VERSION index 6b4950e3de..95e3ba8192 100644 --- a/chrome/test/chromedriver/VERSION +++ b/chrome/test/chromedriver/VERSION @@ -1 +1 @@ -2.4 +2.5 diff --git a/chrome/test/chromedriver/capabilities.cc b/chrome/test/chromedriver/capabilities.cc index b8e6e45862..6e884c907d 100644 --- a/chrome/test/chromedriver/capabilities.cc +++ b/chrome/test/chromedriver/capabilities.cc @@ -277,6 +277,8 @@ Status ParseChromeOptions( parser_map["localState"] = base::Bind(&ParseDict, &capabilities->local_state); parser_map["logPath"] = base::Bind(&ParseLogPath); + parser_map["minidumpPath"] = + base::Bind(&ParseString, &capabilities->minidump_path); parser_map["prefs"] = base::Bind(&ParseDict, &capabilities->prefs); } diff --git a/chrome/test/chromedriver/capabilities.h b/chrome/test/chromedriver/capabilities.h index d23740ecee..c5f52cd461 100644 --- a/chrome/test/chromedriver/capabilities.h +++ b/chrome/test/chromedriver/capabilities.h @@ -105,6 +105,9 @@ struct Capabilities { LoggingPrefs logging_prefs; + // If set, enable minidump for chrome crashes and save to this directory. + std::string minidump_path; + scoped_ptr<base::DictionaryValue> prefs; Switches switches; diff --git a/chrome/test/chromedriver/chrome/chrome.h b/chrome/test/chromedriver/chrome/chrome.h index 2433fadccf..4c8feacd7f 100644 --- a/chrome/test/chromedriver/chrome/chrome.h +++ b/chrome/test/chromedriver/chrome/chrome.h @@ -8,7 +8,7 @@ #include <list> #include <string> -class AutomationExtension; +class ChromeDesktopImpl; class Status; class WebView; @@ -16,13 +16,7 @@ class Chrome { public: virtual ~Chrome() {} - enum Type { - DESKTOP, - ANDROID, - EXISTING - }; - - virtual Type GetType() = 0; + virtual ChromeDesktopImpl* GetAsDesktop() = 0; virtual std::string GetVersion() = 0; @@ -42,9 +36,6 @@ class Chrome { // Activates the specified WebView. virtual Status ActivateWebView(const std::string& id) = 0; - // Gets the automation extension. - virtual Status GetAutomationExtension(AutomationExtension** extension) = 0; - // Get the operation system where Chrome is running. virtual std::string GetOperatingSystemName() = 0; diff --git a/chrome/test/chromedriver/chrome/chrome_android_impl.cc b/chrome/test/chromedriver/chrome/chrome_android_impl.cc index 0bddb4ac3e..41da0a045b 100644 --- a/chrome/test/chromedriver/chrome/chrome_android_impl.cc +++ b/chrome/test/chromedriver/chrome/chrome_android_impl.cc @@ -21,10 +21,6 @@ ChromeAndroidImpl::ChromeAndroidImpl( ChromeAndroidImpl::~ChromeAndroidImpl() {} -Chrome::Type ChromeAndroidImpl::GetType() { - return ANDROID; -} - std::string ChromeAndroidImpl::GetOperatingSystemName() { return "ANDROID"; } diff --git a/chrome/test/chromedriver/chrome/chrome_android_impl.h b/chrome/test/chromedriver/chrome/chrome_android_impl.h index 43ed71a741..39da9da575 100644 --- a/chrome/test/chromedriver/chrome/chrome_android_impl.h +++ b/chrome/test/chromedriver/chrome/chrome_android_impl.h @@ -24,7 +24,6 @@ class ChromeAndroidImpl : public ChromeImpl { virtual ~ChromeAndroidImpl(); // Overridden from Chrome: - virtual Type GetType() OVERRIDE; virtual std::string GetOperatingSystemName() OVERRIDE; // Overridden from ChromeImpl: diff --git a/chrome/test/chromedriver/chrome/chrome_desktop_impl.cc b/chrome/test/chromedriver/chrome/chrome_desktop_impl.cc index 717e43f541..3982f9c93f 100644 --- a/chrome/test/chromedriver/chrome/chrome_desktop_impl.cc +++ b/chrome/test/chromedriver/chrome/chrome_desktop_impl.cc @@ -66,12 +66,14 @@ ChromeDesktopImpl::ChromeDesktopImpl( ScopedVector<DevToolsEventListener>& devtools_event_listeners, scoped_ptr<PortReservation> port_reservation, base::ProcessHandle process, + const CommandLine& command, base::ScopedTempDir* user_data_dir, base::ScopedTempDir* extension_dir) : ChromeImpl(client.Pass(), devtools_event_listeners, port_reservation.Pass()), - process_(process) { + process_(process), + command_(command) { if (user_data_dir->IsValid()) CHECK(user_data_dir_.Set(user_data_dir->Take())); if (extension_dir->IsValid()) @@ -125,10 +127,6 @@ Status ChromeDesktopImpl::WaitForPageToLoad(const std::string& url, return status; } -Chrome::Type ChromeDesktopImpl::GetType() { - return DESKTOP; -} - Status ChromeDesktopImpl::GetAutomationExtension( AutomationExtension** extension) { if (!automation_extension_) { @@ -147,6 +145,10 @@ Status ChromeDesktopImpl::GetAutomationExtension( return Status(kOk); } +ChromeDesktopImpl* ChromeDesktopImpl::GetAsDesktop() { + return this; +} + std::string ChromeDesktopImpl::GetOperatingSystemName() { return base::SysInfo::OperatingSystemName(); } @@ -156,3 +158,7 @@ Status ChromeDesktopImpl::QuitImpl() { return Status(kUnknownError, "cannot kill Chrome"); return Status(kOk); } + +const CommandLine& ChromeDesktopImpl::command() const { + return command_; +} diff --git a/chrome/test/chromedriver/chrome/chrome_desktop_impl.h b/chrome/test/chromedriver/chrome/chrome_desktop_impl.h index ab4e3933f3..f9c2ab61dd 100644 --- a/chrome/test/chromedriver/chrome/chrome_desktop_impl.h +++ b/chrome/test/chromedriver/chrome/chrome_desktop_impl.h @@ -7,6 +7,7 @@ #include <string> +#include "base/command_line.h" #include "base/compiler_specific.h" #include "base/files/scoped_temp_dir.h" #include "base/memory/scoped_ptr.h" @@ -29,6 +30,7 @@ class ChromeDesktopImpl : public ChromeImpl { ScopedVector<DevToolsEventListener>& devtools_event_listeners, scoped_ptr<PortReservation> port_reservation, base::ProcessHandle process, + const CommandLine& command, base::ScopedTempDir* user_data_dir, base::ScopedTempDir* extension_dir); virtual ~ChromeDesktopImpl(); @@ -39,17 +41,21 @@ class ChromeDesktopImpl : public ChromeImpl { const base::TimeDelta& timeout, scoped_ptr<WebView>* web_view); + // Gets the installed automation extension. + Status GetAutomationExtension(AutomationExtension** extension); + // Overridden from Chrome: - virtual Type GetType() OVERRIDE; - virtual Status GetAutomationExtension( - AutomationExtension** extension) OVERRIDE; + virtual ChromeDesktopImpl* GetAsDesktop() OVERRIDE; virtual std::string GetOperatingSystemName() OVERRIDE; // Overridden from ChromeImpl: virtual Status QuitImpl() OVERRIDE; + const CommandLine& command() const; + private: base::ProcessHandle process_; + CommandLine command_; base::ScopedTempDir user_data_dir_; base::ScopedTempDir extension_dir_; diff --git a/chrome/test/chromedriver/chrome/chrome_existing_impl.cc b/chrome/test/chromedriver/chrome/chrome_existing_impl.cc index af23106aee..b4a3387c1a 100644 --- a/chrome/test/chromedriver/chrome/chrome_existing_impl.cc +++ b/chrome/test/chromedriver/chrome/chrome_existing_impl.cc @@ -16,10 +16,6 @@ ChromeExistingImpl::ChromeExistingImpl( ChromeExistingImpl::~ChromeExistingImpl() {} -Chrome::Type ChromeExistingImpl::GetType() { - return EXISTING; -} - std::string ChromeExistingImpl::GetOperatingSystemName() { return std::string(); } diff --git a/chrome/test/chromedriver/chrome/chrome_existing_impl.h b/chrome/test/chromedriver/chrome/chrome_existing_impl.h index 2a04e5051a..284f6b7fec 100644 --- a/chrome/test/chromedriver/chrome/chrome_existing_impl.h +++ b/chrome/test/chromedriver/chrome/chrome_existing_impl.h @@ -21,7 +21,6 @@ class ChromeExistingImpl : public ChromeImpl { virtual ~ChromeExistingImpl(); // Overridden from Chrome. - virtual Type GetType() OVERRIDE; virtual std::string GetOperatingSystemName() OVERRIDE; // Overridden from ChromeImpl. diff --git a/chrome/test/chromedriver/chrome/chrome_impl.cc b/chrome/test/chromedriver/chrome/chrome_impl.cc index 772e1e37fe..f293899e15 100644 --- a/chrome/test/chromedriver/chrome/chrome_impl.cc +++ b/chrome/test/chromedriver/chrome/chrome_impl.cc @@ -16,6 +16,10 @@ ChromeImpl::~ChromeImpl() { port_reservation_->Leak(); } +ChromeDesktopImpl* ChromeImpl::GetAsDesktop() { + return NULL; +} + std::string ChromeImpl::GetVersion() { return devtools_http_client_->version(); } @@ -115,10 +119,6 @@ Status ChromeImpl::ActivateWebView(const std::string& id) { return devtools_http_client_->ActivateWebView(id); } -Status ChromeImpl::GetAutomationExtension(AutomationExtension** extension) { - return Status(kUnknownError, "automation extension not supported"); -} - Status ChromeImpl::Quit() { Status status = QuitImpl(); if (status.IsOk()) diff --git a/chrome/test/chromedriver/chrome/chrome_impl.h b/chrome/test/chromedriver/chrome/chrome_impl.h index ce23ed2ef1..792d48f015 100644 --- a/chrome/test/chromedriver/chrome/chrome_impl.h +++ b/chrome/test/chromedriver/chrome/chrome_impl.h @@ -29,6 +29,7 @@ class ChromeImpl : public Chrome { // Overridden from Chrome: virtual std::string GetVersion() OVERRIDE; + virtual ChromeDesktopImpl* GetAsDesktop() OVERRIDE; virtual int GetBuildNo() OVERRIDE; virtual bool HasCrashedWebView() OVERRIDE; virtual Status GetWebViewIds(std::list<std::string>* web_view_ids) OVERRIDE; @@ -36,8 +37,6 @@ class ChromeImpl : public Chrome { WebView** web_view) OVERRIDE; virtual Status CloseWebView(const std::string& id) OVERRIDE; virtual Status ActivateWebView(const std::string& id) OVERRIDE; - virtual Status GetAutomationExtension( - AutomationExtension** extension) OVERRIDE; virtual Status Quit() OVERRIDE; protected: diff --git a/chrome/test/chromedriver/chrome/devtools_http_client.cc b/chrome/test/chromedriver/chrome/devtools_http_client.cc index f2b2d1c5c5..7afafce4b7 100644 --- a/chrome/test/chromedriver/chrome/devtools_http_client.cc +++ b/chrome/test/chromedriver/chrome/devtools_http_client.cc @@ -302,22 +302,29 @@ Status ParseWebViewsInfo(const std::string& data, std::string id; if (!info->GetString("id", &id)) return Status(kUnknownError, "DevTools did not include id"); - std::string type; - if (!info->GetString("type", &type)) + std::string type_as_string; + if (!info->GetString("type", &type_as_string)) return Status(kUnknownError, "DevTools did not include type"); std::string url; if (!info->GetString("url", &url)) return Status(kUnknownError, "DevTools did not include url"); std::string debugger_url; info->GetString("webSocketDebuggerUrl", &debugger_url); - if (type == "page") - temp_views_info.push_back( - WebViewInfo(id, debugger_url, url, WebViewInfo::kPage)); - else if (type == "other") - temp_views_info.push_back( - WebViewInfo(id, debugger_url, url, WebViewInfo::kOther)); + WebViewInfo::Type type; + if (type_as_string == "app") + type = WebViewInfo::kApp; + else if (type_as_string == "background_page") + type = WebViewInfo::kBackgroundPage; + else if (type_as_string == "page") + type = WebViewInfo::kPage; + else if (type_as_string == "worker") + type = WebViewInfo::kWorker; + else if (type_as_string == "other") + type = WebViewInfo::kOther; else - return Status(kUnknownError, "DevTools returned unknown type:" + type); + return Status(kUnknownError, + "DevTools returned unknown type:" + type_as_string); + temp_views_info.push_back(WebViewInfo(id, debugger_url, url, type)); } *views_info = WebViewsInfo(temp_views_info); return Status(kOk); diff --git a/chrome/test/chromedriver/chrome/devtools_http_client.h b/chrome/test/chromedriver/chrome/devtools_http_client.h index 7dbb5374f3..282adcc05e 100644 --- a/chrome/test/chromedriver/chrome/devtools_http_client.h +++ b/chrome/test/chromedriver/chrome/devtools_http_client.h @@ -23,7 +23,10 @@ class URLRequestContextGetter; struct WebViewInfo { enum Type { + kApp, + kBackgroundPage, kPage, + kWorker, kOther }; diff --git a/chrome/test/chromedriver/chrome/devtools_http_client_unittest.cc b/chrome/test/chromedriver/chrome/devtools_http_client_unittest.cc index c92abb8736..673a8177d0 100644 --- a/chrome/test/chromedriver/chrome/devtools_http_client_unittest.cc +++ b/chrome/test/chromedriver/chrome/devtools_http_client_unittest.cc @@ -70,6 +70,17 @@ TEST(ParseWebViewsInfo, WithoutDebuggerUrl) { namespace { +void AssertTypeIsOk(const std::string& type_as_string, WebViewInfo::Type type) { + WebViewsInfo views_info; + std::string data = "[{\"type\": \"" + type_as_string + + "\", \"id\": \"1\", \"url\": \"http://page1\"}]"; + Status status = internal::ParseWebViewsInfo(data, &views_info); + ASSERT_TRUE(status.IsOk()); + ASSERT_EQ(1u, views_info.GetSize()); + ExpectEqual(WebViewInfo("1", std::string(), "http://page1", type), + views_info.Get(0)); +} + void AssertFails(const std::string& data) { WebViewsInfo views_info; Status status = internal::ParseWebViewsInfo(data, &views_info); @@ -79,6 +90,15 @@ void AssertFails(const std::string& data) { } // namespace +TEST(ParseWebViewsInfo, Types) { + AssertTypeIsOk("app", WebViewInfo::kApp); + AssertTypeIsOk("background_page", WebViewInfo::kBackgroundPage); + AssertTypeIsOk("page", WebViewInfo::kPage); + AssertTypeIsOk("worker", WebViewInfo::kWorker); + AssertTypeIsOk("other", WebViewInfo::kOther); + AssertFails("[{\"type\": \"\", \"id\": \"1\", \"url\": \"http://page1\"}]"); +} + TEST(ParseWebViewsInfo, NonList) { AssertFails("{\"id\": \"1\"}"); } diff --git a/chrome/test/chromedriver/chrome/stub_chrome.cc b/chrome/test/chromedriver/chrome/stub_chrome.cc index 7e5888b7a6..97de39eada 100644 --- a/chrome/test/chromedriver/chrome/stub_chrome.cc +++ b/chrome/test/chromedriver/chrome/stub_chrome.cc @@ -10,8 +10,8 @@ StubChrome::StubChrome() {} StubChrome::~StubChrome() {} -Chrome::Type StubChrome::GetType() { - return DESKTOP; +ChromeDesktopImpl* StubChrome::GetAsDesktop() { + return NULL; } std::string StubChrome::GetVersion() { @@ -42,10 +42,6 @@ Status StubChrome::ActivateWebView(const std::string& id) { return Status(kOk); } -Status StubChrome::GetAutomationExtension(AutomationExtension** extension) { - return Status(kOk); -} - std::string StubChrome::GetOperatingSystemName() { return std::string(); } diff --git a/chrome/test/chromedriver/chrome/stub_chrome.h b/chrome/test/chromedriver/chrome/stub_chrome.h index af0bd06314..ddd38be849 100644 --- a/chrome/test/chromedriver/chrome/stub_chrome.h +++ b/chrome/test/chromedriver/chrome/stub_chrome.h @@ -19,7 +19,7 @@ class StubChrome : public Chrome { virtual ~StubChrome(); // Overridden from Chrome: - virtual Type GetType() OVERRIDE; + virtual ChromeDesktopImpl* GetAsDesktop() OVERRIDE; virtual std::string GetVersion() OVERRIDE; virtual int GetBuildNo() OVERRIDE; virtual bool HasCrashedWebView() OVERRIDE; @@ -28,8 +28,6 @@ class StubChrome : public Chrome { WebView** web_view) OVERRIDE; virtual Status CloseWebView(const std::string& id) OVERRIDE; virtual Status ActivateWebView(const std::string& id) OVERRIDE; - virtual Status GetAutomationExtension( - AutomationExtension** extension) OVERRIDE; virtual std::string GetOperatingSystemName() OVERRIDE; virtual Status Quit() OVERRIDE; }; diff --git a/chrome/test/chromedriver/chrome_launcher.cc b/chrome/test/chromedriver/chrome_launcher.cc index 09cef68e6d..5db4d31691 100644 --- a/chrome/test/chromedriver/chrome_launcher.cc +++ b/chrome/test/chromedriver/chrome_launcher.cc @@ -46,6 +46,10 @@ namespace { const char* kCommonSwitches[] = { "ignore-certificate-errors", "metrics-recording-only"}; +#if defined(OS_LINUX) +const char* kEnableCrashReport = "enable-crash-reporter-for-testing"; +#endif + Status UnpackAutomationExtension(const base::FilePath& temp_dir, base::FilePath* automation_extension) { std::string decoded_extension; @@ -217,6 +221,20 @@ Status LaunchDesktopChrome( base::LaunchOptions options; +#if defined(OS_LINUX) + // If minidump path is set in the capability, enable minidump for crashes. + if (!capabilities.minidump_path.empty()) { + VLOG(0) << "Minidump generation specified. Will save dumps to: " + << capabilities.minidump_path; + + options.environ["CHROME_HEADLESS"] = 1; + options.environ["BREAKPAD_DUMP_LOCATION"] = capabilities.minidump_path; + + if (!command.HasSwitch(kEnableCrashReport)) + command.AppendSwitch(kEnableCrashReport); + } +#endif + #if !defined(OS_WIN) if (!capabilities.log_path.empty()) options.environ["CHROME_LOG_FILE"] = capabilities.log_path; @@ -277,6 +295,7 @@ Status LaunchDesktopChrome( devtools_event_listeners, port_reservation.Pass(), process, + command, &user_data_dir, &extension_dir)); for (size_t i = 0; i < extension_bg_pages.size(); ++i) { diff --git a/chrome/test/chromedriver/run_buildbot_steps.py b/chrome/test/chromedriver/run_buildbot_steps.py index 7bfdecadd6..4447fdf01b 100755 --- a/chrome/test/chromedriver/run_buildbot_steps.py +++ b/chrome/test/chromedriver/run_buildbot_steps.py @@ -8,6 +8,7 @@ import bisect import csv import datetime +import glob import json import optparse import os @@ -30,6 +31,7 @@ GS_CHROMEDRIVER_BUCKET = 'gs://chromedriver' GS_CHROMEDRIVER_DATA_BUCKET = 'gs://chromedriver-data' GS_CONTINUOUS_URL = GS_CHROMEDRIVER_DATA_BUCKET + '/continuous' GS_PREBUILTS_URL = GS_CHROMEDRIVER_DATA_BUCKET + '/prebuilts' +GS_SERVER_LOGS_URL = GS_CHROMEDRIVER_DATA_BUCKET + '/server_logs' TEST_LOG_FORMAT = '%s_log.json' SCRIPT_DIR = os.path.join(_THIS_DIR, os.pardir, os.pardir, os.pardir, os.pardir, @@ -54,6 +56,16 @@ def _ArchivePrebuilts(revision): util.MarkBuildStepError() +def _ArchiveServerLogs(): + """Uploads chromedriver server logs to google storage.""" + util.MarkBuildStepStart('archive chromedriver server logs') + for server_log in glob.glob(os.path.join(tempfile.gettempdir(), + 'chromedriver_*')): + slave_utils.GSUtilCopy( + server_log, '%s/%s' % (GS_SERVER_LOGS_URL, + os.path.basename(server_log))) + + def _DownloadPrebuilts(): """Downloads the most recent prebuilts from google storage.""" util.MarkBuildStepStart('Download latest chromedriver') @@ -354,6 +366,8 @@ def main(): passed = (util.RunCommand(cmd) == 0) + _ArchiveServerLogs() + if platform == 'android': if options.update_log: util.MarkBuildStepStart('update test result log') diff --git a/chrome/test/chromedriver/server/http_handler.cc b/chrome/test/chromedriver/server/http_handler.cc index 0ea5cef9ee..4a21932ad8 100644 --- a/chrome/test/chromedriver/server/http_handler.cc +++ b/chrome/test/chromedriver/server/http_handler.cc @@ -179,6 +179,10 @@ HttpHandler::HttpHandler( kGet, "session/:sessionId/screenshot", WrapToCommand("Screenshot", base::Bind(&ExecuteScreenshot))), + CommandMapping( + kGet, + "session/:sessionId/chromium/heap_snapshot", + WrapToCommand("HeapSnapshot", base::Bind(&ExecuteTakeHeapSnapshot))), CommandMapping(kPost, "session/:sessionId/visible", base::Bind(&UnimplementedCommand)), diff --git a/chrome/test/chromedriver/server/server.py b/chrome/test/chromedriver/server/server.py index 655aac3565..5a1a4403ff 100644 --- a/chrome/test/chromedriver/server/server.py +++ b/chrome/test/chromedriver/server/server.py @@ -13,11 +13,12 @@ import urllib2 class Server(object): """A running ChromeDriver server.""" - def __init__(self, exe_path): + def __init__(self, exe_path, log_path=None): """Starts the ChromeDriver server and waits for it to be ready. Args: exe_path: path to the ChromeDriver executable + log_path: path to the log file Raises: RuntimeError if ChromeDriver fails to start """ @@ -26,6 +27,8 @@ class Server(object): port = self._FindOpenPort() chromedriver_args = [exe_path, '--port=%d' % port] + if log_path: + chromedriver_args.append('--log-path=%s' % log_path) self._process = subprocess.Popen(chromedriver_args) self._url = 'http://127.0.0.1:%d' % port if self._process is None: diff --git a/chrome/test/chromedriver/session_commands.cc b/chrome/test/chromedriver/session_commands.cc index e5c1d46475..85809f6e04 100644 --- a/chrome/test/chromedriver/session_commands.cc +++ b/chrome/test/chromedriver/session_commands.cc @@ -76,6 +76,7 @@ scoped_ptr<base::DictionaryValue> CreateCapabilities(Chrome* chrome) { caps->SetString("platform", chrome->GetOperatingSystemName()); caps->SetBoolean("javascriptEnabled", true); caps->SetBoolean("takesScreenshot", true); + caps->SetBoolean("takesHeapSnapshot", true); caps->SetBoolean("handlesAlerts", true); caps->SetBoolean("databaseEnabled", false); caps->SetBoolean("locationContextEnabled", true); @@ -86,6 +87,14 @@ scoped_ptr<base::DictionaryValue> CreateCapabilities(Chrome* chrome) { caps->SetBoolean("rotatable", false); caps->SetBoolean("acceptSslCerts", true); caps->SetBoolean("nativeEvents", true); + scoped_ptr<base::DictionaryValue> chrome_caps(new base::DictionaryValue()); + if (chrome->GetAsDesktop()) { + chrome_caps->SetString( + "userDataDir", + chrome->GetAsDesktop()->command().GetSwitchValueNative( + "user-data-dir")); + } + caps->Set("chrome", chrome_caps.release()); return caps.Pass(); } @@ -413,8 +422,15 @@ Status ExecuteGetWindowPosition( Session* session, const base::DictionaryValue& params, scoped_ptr<base::Value>* value) { + ChromeDesktopImpl* desktop = session->chrome->GetAsDesktop(); + if (!desktop) { + return Status( + kUnknownError, + "command only supported for desktop Chrome without debuggerAddress"); + } + AutomationExtension* extension = NULL; - Status status = session->chrome->GetAutomationExtension(&extension); + Status status = desktop->GetAutomationExtension(&extension); if (status.IsError()) return status; @@ -437,8 +453,16 @@ Status ExecuteSetWindowPosition( double x, y; if (!params.GetDouble("x", &x) || !params.GetDouble("y", &y)) return Status(kUnknownError, "missing or invalid 'x' or 'y'"); + + ChromeDesktopImpl* desktop = session->chrome->GetAsDesktop(); + if (!desktop) { + return Status( + kUnknownError, + "command only supported for desktop Chrome without debuggerAddress"); + } + AutomationExtension* extension = NULL; - Status status = session->chrome->GetAutomationExtension(&extension); + Status status = desktop->GetAutomationExtension(&extension); if (status.IsError()) return status; @@ -449,8 +473,15 @@ Status ExecuteGetWindowSize( Session* session, const base::DictionaryValue& params, scoped_ptr<base::Value>* value) { + ChromeDesktopImpl* desktop = session->chrome->GetAsDesktop(); + if (!desktop) { + return Status( + kUnknownError, + "command only supported for desktop Chrome without debuggerAddress"); + } + AutomationExtension* extension = NULL; - Status status = session->chrome->GetAutomationExtension(&extension); + Status status = desktop->GetAutomationExtension(&extension); if (status.IsError()) return status; @@ -474,8 +505,16 @@ Status ExecuteSetWindowSize( if (!params.GetDouble("width", &width) || !params.GetDouble("height", &height)) return Status(kUnknownError, "missing or invalid 'width' or 'height'"); + + ChromeDesktopImpl* desktop = session->chrome->GetAsDesktop(); + if (!desktop) { + return Status( + kUnknownError, + "command only supported for desktop Chrome without debuggerAddress"); + } + AutomationExtension* extension = NULL; - Status status = session->chrome->GetAutomationExtension(&extension); + Status status = desktop->GetAutomationExtension(&extension); if (status.IsError()) return status; @@ -487,8 +526,15 @@ Status ExecuteMaximizeWindow( Session* session, const base::DictionaryValue& params, scoped_ptr<base::Value>* value) { + ChromeDesktopImpl* desktop = session->chrome->GetAsDesktop(); + if (!desktop) { + return Status( + kUnknownError, + "command only supported for desktop Chrome without debuggerAddress"); + } + AutomationExtension* extension = NULL; - Status status = session->chrome->GetAutomationExtension(&extension); + Status status = desktop->GetAutomationExtension(&extension); if (status.IsError()) return status; diff --git a/chrome/test/chromedriver/test/run_all_tests.py b/chrome/test/chromedriver/test/run_all_tests.py index 7da52faeea..ee8e1c7ed1 100755 --- a/chrome/test/chromedriver/test/run_all_tests.py +++ b/chrome/test/chromedriver/test/run_all_tests.py @@ -9,6 +9,7 @@ import optparse import os import platform import sys +import tempfile _THIS_DIR = os.path.abspath(os.path.dirname(__file__)) sys.path.insert(0, os.path.join(_THIS_DIR, os.pardir)) @@ -46,15 +47,20 @@ def _GenerateTestCommand(script, chrome_version=None, android_package=None, verbose=False): + _, log_path = tempfile.mkstemp(prefix='chromedriver_') + print 'chromedriver server log: %s' % log_path cmd = [ sys.executable, os.path.join(_THIS_DIR, script), - '--chromedriver=' + chromedriver, + '--chromedriver=%s' % chromedriver, + '--log-path=%s' % log_path, ] if ref_chromedriver: cmd.append('--reference-chromedriver=' + ref_chromedriver) + if chrome: cmd.append('--chrome=' + chrome) + if chrome_version: cmd.append('--chrome-version=' + chrome_version) @@ -62,7 +68,7 @@ def _GenerateTestCommand(script, cmd.append('--verbose') if android_package: - cmd.insert(0, 'xvfb-run') + cmd = ['xvfb-run', '-a'] + cmd cmd.append('--android-package=' + android_package) return cmd diff --git a/chrome/test/chromedriver/test/run_java_tests.py b/chrome/test/chromedriver/test/run_java_tests.py index 5b7b3beee3..7ed852404a 100755 --- a/chrome/test/chromedriver/test/run_java_tests.py +++ b/chrome/test/chromedriver/test/run_java_tests.py @@ -58,7 +58,7 @@ class TestResult(object): def _Run(java_tests_src_dir, test_filter, - chromedriver_path, chrome_path, android_package, + chromedriver_path, chrome_path, log_path, android_package, verbose, debug): """Run the WebDriver Java tests and return the test results. @@ -68,6 +68,7 @@ def _Run(java_tests_src_dir, test_filter, as Google C++ Test format. chromedriver_path: path to ChromeDriver exe. chrome_path: path to Chrome exe. + log_path: path to server log. android_package: name of Chrome's Android package. verbose: whether the output should be verbose. debug: whether the tests should wait until attached by a debugger. @@ -94,9 +95,11 @@ def _Run(java_tests_src_dir, test_filter, sys_props = ['selenium.browser=chrome', 'webdriver.chrome.driver=' + os.path.abspath(chromedriver_path)] - if chrome_path is not None: + if chrome_path: sys_props += ['webdriver.chrome.binary=' + os.path.abspath(chrome_path)] - if android_package is not None: + if log_path: + sys_props += ['webdriver.chrome.logfile=' + log_path] + if android_package: sys_props += ['webdriver.chrome.android_package=' + android_package] if test_filter: # Test jar actually takes a regex. Convert from glob. @@ -233,6 +236,9 @@ def main(): '', '--chrome', type='string', default=None, help='Path to a build of the chrome binary') parser.add_option( + '', '--log-path', + help='Output verbose server logs to this file') + parser.add_option( '', '--chrome-version', default='HEAD', help='Version of chrome. Default is \'HEAD\'') parser.add_option( @@ -302,6 +308,7 @@ def main(): test_filter=filter, chromedriver_path=options.chromedriver, chrome_path=options.chrome, + log_path=options.log_path, android_package=options.android_package, verbose=options.verbose, debug=options.debug) diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index dd38b4b1d5..97a10a78ce 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py @@ -814,6 +814,9 @@ if __name__ == '__main__': '', '--chromedriver', help='Path to chromedriver server (REQUIRED!)') parser.add_option( + '', '--log-path', + help='Output verbose server logs to this file') + parser.add_option( '', '--reference-chromedriver', help='Path to the reference chromedriver server') parser.add_option( @@ -833,7 +836,8 @@ if __name__ == '__main__': parser.error('chromedriver is required or the given path is invalid.' + 'Please run "%s --help" for help' % __file__) - chromedriver_server = server.Server(os.path.abspath(options.chromedriver)) + chromedriver_server = server.Server(os.path.abspath(options.chromedriver), + options.log_path) global _CHROMEDRIVER_SERVER_URL _CHROMEDRIVER_SERVER_URL = chromedriver_server.GetUrl() diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index 28ed9fc939..9610e60df9 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations @@ -48,8 +48,6 @@ _REVISION_NEGATIVE_FILTER['HEAD'] = [ 'ExecutingJavascriptTest.testShouldThrowAnExceptionWithMessageAndStacktraceWhenTheJavascriptIsBad', 'FormHandlingTest.testShouldNotBeAbleToSubmitAFormThatDoesNotExist', 'FrameSwitchingTest.testShouldNotBeAbleToDoAnythingTheFrameIsDeletedFromUnderUs', - # Disabled until https://code.google.com/p/chromedriver/issues/detail?id=345 is fixed. - 'I18nTest.*', 'I18nTest.testShouldBeAbleToActivateIMEEngine', # Broken because AddWebStorage.java is broken. 'LocalStorageTest.*', @@ -86,21 +84,12 @@ _REVISION_NEGATIVE_FILTER['HEAD'] = [ 'VisibilityTest.testElementHiddenByOverflowYIsNotVisible', 'VisibilityTest.tooSmallAWindowWithOverflowHiddenIsNotAProblem', 'WindowTest.*', - # https://code.google.com/p/chromedriver/issues/detail?id=412 - 'ClickTest.testCanClickOnAnElementWithTopSetToANegativeNumber', - 'ClickTest.testShouldBeAbleToClickOnAnElementInTheViewport', - 'ExecutingAsyncJavascriptTest.shouldBeAbleToExecuteAsynchronousScripts', - 'FormHandlingTest.testShouldClickOnSubmitInputElements', - 'FrameSwitchingTest.testShouldBeAbleToClickInAFrame', - 'FrameSwitchingTest.testShouldBeAbleToSwitchToTheTopIfTheFrameIsDeletedFromUnderUs', - 'FrameSwitchingTest.testShouldAllowTheUserToSwitchToAnIFrameAndRemainFocusedOnIt', - 'FrameSwitchingTest.testShouldBeAbleToClickInASubFrame', - 'FrameSwitchingTest.testShouldNotSwitchMagicallyToTheTopWindow', - 'ImplicitWaitTest.testShouldImplicitlyWaitUntilAtLeastOneElementIsFoundWhenSearchingForMany', - 'ImplicitWaitTest.testShouldImplicitlyWaitForAnElementToBeVisibleBeforeInteracting', - 'ImplicitWaitTest.testShouldReturnAfterFirstAttemptToFindManyAfterDisablingImplicitWaits', - 'ImplicitWaitTest.testShouldImplicitlyWaitForASingleElement', - 'XPathElementFindingTest.testShouldBeAbleToSearchForMultipleAttributes', +] +_REVISION_NEGATIVE_FILTER['31'] = _REVISION_NEGATIVE_FILTER['HEAD'] + [ + 'I18nTest.*', # This was fixed in a later version of 31 than we use. +] +_REVISION_NEGATIVE_FILTER['30'] = _REVISION_NEGATIVE_FILTER['HEAD'] + [ + 'I18nTest.*', ] diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc index d7195f6eb7..266361b4c9 100644 --- a/chrome/test/chromedriver/window_commands.cc +++ b/chrome/test/chromedriver/window_commands.cc @@ -16,6 +16,7 @@ #include "chrome/test/chromedriver/basic_types.h" #include "chrome/test/chromedriver/chrome/automation_extension.h" #include "chrome/test/chromedriver/chrome/chrome.h" +#include "chrome/test/chromedriver/chrome/chrome_desktop_impl.h" #include "chrome/test/chromedriver/chrome/devtools_client.h" #include "chrome/test/chromedriver/chrome/geoposition.h" #include "chrome/test/chromedriver/chrome/javascript_dialog_manager.h" @@ -739,10 +740,10 @@ Status ExecuteScreenshot( return status; std::string screenshot; - if (session->chrome->GetType() == Chrome::DESKTOP && - !session->force_devtools_screenshot) { + if (session->chrome->GetAsDesktop() && !session->force_devtools_screenshot) { AutomationExtension* extension = NULL; - status = session->chrome->GetAutomationExtension(&extension); + status = + session->chrome->GetAsDesktop()->GetAutomationExtension(&extension); if (status.IsError()) return status; status = extension->CaptureScreenshot(&screenshot); @@ -862,3 +863,11 @@ Status ExecuteSetLocation( session->overridden_geoposition.reset(new Geoposition(geoposition)); return status; } + +Status ExecuteTakeHeapSnapshot( + Session* session, + WebView* web_view, + const base::DictionaryValue& params, + scoped_ptr<base::Value>* value) { + return web_view->TakeHeapSnapshot(value); +} diff --git a/chrome/test/chromedriver/window_commands.h b/chrome/test/chromedriver/window_commands.h index 017813628b..4e97ac9f16 100644 --- a/chrome/test/chromedriver/window_commands.h +++ b/chrome/test/chromedriver/window_commands.h @@ -283,4 +283,10 @@ Status ExecuteSetLocation( const base::DictionaryValue& params, scoped_ptr<base::Value>* value); +Status ExecuteTakeHeapSnapshot( + Session* session, + WebView* web_view, + const base::DictionaryValue& params, + scoped_ptr<base::Value>* value); + #endif // CHROME_TEST_CHROMEDRIVER_WINDOW_COMMANDS_H_ diff --git a/chrome/test/functional/ispy/client/boto_bucket.py b/chrome/test/functional/ispy/client/boto_bucket.py index 4b7d15eece..df0cd1cd6c 100644 --- a/chrome/test/functional/ispy/client/boto_bucket.py +++ b/chrome/test/functional/ispy/client/boto_bucket.py @@ -1,5 +1,8 @@ # Copyright 2013 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. """Implementation of CloudBucket using Google Cloud Storage as the backend.""" +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Implementation of CloudBucket using Google Cloud Storage as the backend.""" import os import sys @@ -9,7 +12,7 @@ sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'depot_tools', 'third_party')) import boto -from common import cloud_bucket +from ..common import cloud_bucket class BotoCloudBucket(cloud_bucket.BaseCloudBucket): diff --git a/chrome/test/functional/ispy/server/debug_view_handler.py b/chrome/test/functional/ispy/server/debug_view_handler.py index 96bfe3cff1..4d5f740f62 100644 --- a/chrome/test/functional/ispy/server/debug_view_handler.py +++ b/chrome/test/functional/ispy/server/debug_view_handler.py @@ -9,7 +9,7 @@ import os import sys import webapp2 -from common import ispy_utils +from ..common import ispy_utils import views diff --git a/chrome/test/functional/ispy/server/gs_bucket.py b/chrome/test/functional/ispy/server/gs_bucket.py index a132f05d53..e73dcefcd1 100644 --- a/chrome/test/functional/ispy/server/gs_bucket.py +++ b/chrome/test/functional/ispy/server/gs_bucket.py @@ -8,7 +8,7 @@ import sys import cloudstorage -from common import cloud_bucket +from ..common import cloud_bucket class GoogleCloudStorageBucket(cloud_bucket.BaseCloudBucket): diff --git a/chrome/test/functional/ispy/server/image_handler.py b/chrome/test/functional/ispy/server/image_handler.py index d1f11f2489..f23f41f20e 100644 --- a/chrome/test/functional/ispy/server/image_handler.py +++ b/chrome/test/functional/ispy/server/image_handler.py @@ -9,8 +9,8 @@ import os import sys import webapp2 -from common import cloud_bucket -from common import constants +from ..common import cloud_bucket +from ..common import constants import gs_bucket diff --git a/chrome/test/functional/ispy/server/main_view_handler.py b/chrome/test/functional/ispy/server/main_view_handler.py index 4b3ec103f8..f6c2c72d84 100644 --- a/chrome/test/functional/ispy/server/main_view_handler.py +++ b/chrome/test/functional/ispy/server/main_view_handler.py @@ -11,8 +11,8 @@ import re import sys import webapp2 -from common import constants -from common import ispy_utils +from ..common import constants +from ..common import ispy_utils import gs_bucket import views diff --git a/chrome/test/functional/ispy/server/update_mask_handler.py b/chrome/test/functional/ispy/server/update_mask_handler.py index 4a2a2dabb7..bf66e776eb 100644 --- a/chrome/test/functional/ispy/server/update_mask_handler.py +++ b/chrome/test/functional/ispy/server/update_mask_handler.py @@ -9,9 +9,9 @@ import re import sys import os -from common import constants -from common import image_tools -from common import ispy_utils +from ..common import constants +from ..common import image_tools +from ..common import ispy_utils import gs_bucket diff --git a/chrome/test/functional/prefs.py b/chrome/test/functional/prefs.py index 9a82de998b..7dc95aea0b 100755 --- a/chrome/test/functional/prefs.py +++ b/chrome/test/functional/prefs.py @@ -85,24 +85,6 @@ class PrefsTest(pyauto.PyUITest): self.ActivateTab(1) self.assertEqual(url2, self.GetActiveTabURL().spec()) - def testHomepagePrefs(self): - """Verify homepage prefs.""" - # "Use the New Tab page" - self.SetPrefs(pyauto.kHomePageIsNewTabPage, True) - logging.debug('Setting %s to 1' % pyauto.kHomePageIsNewTabPage) - self.RestartBrowser(clear_profile=False) - self.assertEqual(self.GetPrefsInfo().Prefs(pyauto.kHomePageIsNewTabPage), - True) - # "Open this page" - url = self.GetFileURLForPath(os.path.join(self.DataDir(), 'title1.html')) - self.SetPrefs(pyauto.kHomePage, url) - self.SetPrefs(pyauto.kHomePageIsNewTabPage, False) - self.RestartBrowser(clear_profile=False) - self.assertEqual(self.GetPrefsInfo().Prefs(pyauto.kHomePage), url) - self.assertFalse(self.GetPrefsInfo().Prefs(pyauto.kHomePageIsNewTabPage)) - # TODO(nirnimesh): Actually verify that homepage loads. - # This requires telling pyauto *not* to set about:blank as homepage. - def testGeolocationPref(self): """Verify geolocation pref. @@ -132,24 +114,6 @@ class PrefsTest(pyauto.PyUITest): behavior, Behaviors.BLOCK, msg='Behavior is "%s" when it should be BLOCKED.' % behavior) - def testUnderTheHoodPref(self): - """Verify the security preferences for Under the Hood. - The setting is enabled by default.""" - pref_list = [pyauto.kNetworkPredictionEnabled, pyauto.kSafeBrowsingEnabled, - pyauto.kAlternateErrorPagesEnabled, - pyauto.kSearchSuggestEnabled] - for pref in pref_list: - # Verify the default value - self.assertEqual(self.GetPrefsInfo().Prefs(pref), True) - self.SetPrefs(pref, False) - self.RestartBrowser(clear_profile=False) - for pref in pref_list: - self.assertEqual(self.GetPrefsInfo().Prefs(pref), False) - - def testHaveLocalStatePrefs(self): - """Verify that we have some Local State prefs.""" - self.assertTrue(self.GetLocalStatePrefsInfo()) - def testAllowSelectedGeoTracking(self): """Verify hostname pattern and behavior for allowed tracking.""" # Default location tracking option "Ask me". @@ -227,14 +191,6 @@ class PrefsTest(pyauto.PyUITest): """ return self.ExecuteJavascript(script, windex=windex, tab_index=tab_index) - def testImagesNotBlockedInIncognito(self): - """Verify images are not blocked in Incognito mode.""" - url = self.GetHttpURLForDataPath('settings', 'image_page.html') - self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW) - self.NavigateToURL(url, 1, 0) - self.assertTrue(self._CheckForVisibleImage(windex=1), - msg='No visible images found in Incognito mode.') - def testBlockImagesForHostname(self): """Verify images blocked for defined hostname pattern.""" url = 'http://www.google.com' diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc index 66524df496..f465305217 100644 --- a/chrome/test/ppapi/ppapi_browsertest.cc +++ b/chrome/test/ppapi/ppapi_browsertest.cc @@ -849,7 +849,13 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, DISABLED_FileIO) { LIST_TEST(FileIO_Mmap) ); } -IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, FileIO) { +// Flaky on XP; times out, http://crbug.com/313205 +#if defined(OS_WIN) +#define MAYBE_FileIO DISABLED_FileIO +#else +#define MAYBE_FileIO FileIO +#endif +IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, MAYBE_FileIO) { RunTestViaHTTP( LIST_TEST(FileIO_Open) LIST_TEST(FileIO_AbortCalls) diff --git a/chrome/test/remoting/me2me_browsertest.cc b/chrome/test/remoting/me2me_browsertest.cc index 7cfdda7dae..1cdeb58061 100644 --- a/chrome/test/remoting/me2me_browsertest.cc +++ b/chrome/test/remoting/me2me_browsertest.cc @@ -13,52 +13,66 @@ class Me2MeBrowserTest : public RemoteDesktopBrowserTest { protected: void TestKeyboardInput(); void TestMouseInput(); + + void ConnectPinlessAndCleanupPairings(bool cleanup_all); + bool IsPairingSpinnerHidden(); }; IN_PROC_BROWSER_TEST_F(Me2MeBrowserTest, MANUAL_Me2Me_Connect_Local_Host) { VerifyInternetAccess(); - Install(); - LaunchChromotingApp(); // Authorize, Authenticate, and Approve. Auth(); + ExpandMe2Me(); - StartMe2Me(); - - ConnectToLocalHost(); + ConnectToLocalHost(false); TestKeyboardInput(); - TestMouseInput(); DisconnectMe2Me(); - Cleanup(); } IN_PROC_BROWSER_TEST_F(Me2MeBrowserTest, MANUAL_Me2Me_Connect_Remote_Host) { VerifyInternetAccess(); - Install(); - LaunchChromotingApp(); // Authorize, Authenticate, and Approve. Auth(); + ExpandMe2Me(); - StartMe2Me(); - - ConnectToRemoteHost(remote_host_name()); + ConnectToRemoteHost(remote_host_name(), false); // TODO(weitaosu): Find a way to verify keyboard input injection. // We cannot use TestKeyboardInput because it assumes // that the client and the host are on the same machine. DisconnectMe2Me(); + Cleanup(); +} + +IN_PROC_BROWSER_TEST_F(Me2MeBrowserTest, + MANUAL_Me2Me_Connect_Pinless) { + VerifyInternetAccess(); + Install(); + LaunchChromotingApp(); + + // Authorize, Authenticate, and Approve. + Auth(); + ExpandMe2Me(); + + ASSERT_FALSE(HtmlElementVisible("paired-client-manager-message")) + << "The host must have no pairings before running the pinless test."; + + // Test that cleanup works with either the Delete or Delete all buttons. + ConnectPinlessAndCleanupPairings(false); + ConnectPinlessAndCleanupPairings(true); Cleanup(); } @@ -66,7 +80,7 @@ IN_PROC_BROWSER_TEST_F(Me2MeBrowserTest, // Typing a command which writes to a temp file and then verify the contents of // the file. void Me2MeBrowserTest::TestKeyboardInput() { - // Start a terminal windows with ctrl+alt+T + // Start a terminal window with ctrl+alt+T SimulateKeyPressWithCode(ui::VKEY_T, "KeyT", true, false, true, false); // Wait for the keyboard events to be sent to and processed by the host. @@ -105,4 +119,52 @@ void Me2MeBrowserTest::TestMouseInput() { ASSERT_TRUE(TimeoutWaiter(base::TimeDelta::FromSeconds(5)).Wait()); } +void Me2MeBrowserTest::ConnectPinlessAndCleanupPairings(bool cleanup_all) { + // First connection: verify that a PIN is requested, and request pairing. + ConnectToLocalHost(true); + DisconnectMe2Me(); + + // TODO(jamiewalch): This reload is only needed because there's a bug in the + // web-app whereby it doesn't refresh its pairing state correctly. + // http://crbug.com/311290 + LaunchChromotingApp(); + ASSERT_TRUE(HtmlElementVisible("paired-client-manager-message")); + + // Second connection: verify that no PIN is requested. + ClickOnControl("this-host-connect"); + WaitForConnection(); + DisconnectMe2Me(); + + // Clean up pairings. + ClickOnControl("open-paired-client-manager-dialog"); + ASSERT_TRUE(HtmlElementVisible("paired-client-manager-dialog")); + + if (cleanup_all) { + ClickOnControl("delete-all-paired-clients"); + } else { + std::string host_id = ExecuteScriptAndExtractString( + "remoting.pairedClientManager.getFirstClientIdForTesting_()"); + std::string node_id = "delete-client-" + host_id; + ClickOnControl(node_id); + } + + // Wait for the "working" spinner to disappear. The spinner is shown by both + // methods of deleting a host and is removed when the operation completes. + ConditionalTimeoutWaiter waiter( + base::TimeDelta::FromSeconds(5), + base::TimeDelta::FromMilliseconds(200), + base::Bind(&Me2MeBrowserTest::IsPairingSpinnerHidden, this)); + EXPECT_TRUE(waiter.Wait()); + EXPECT_TRUE(ExecuteScriptAndExtractBool( + "document.getElementById('delete-all-paired-clients').disabled")); + + ClickOnControl("close-paired-client-manager-dialog"); + ASSERT_FALSE(HtmlElementVisible("paired-client-manager-dialog")); + ASSERT_FALSE(HtmlElementVisible("paired-client-manager-message")); +} + +bool Me2MeBrowserTest::IsPairingSpinnerHidden() { + return !HtmlElementVisible("paired-client-manager-dialog-working"); +} + } // namespace remoting diff --git a/chrome/test/remoting/remote_desktop_browsertest.cc b/chrome/test/remoting/remote_desktop_browsertest.cc index 156d532f2a..c9ed3d7415 100644 --- a/chrome/test/remoting/remote_desktop_browsertest.cc +++ b/chrome/test/remoting/remote_desktop_browsertest.cc @@ -305,7 +305,7 @@ void RemoteDesktopBrowserTest::Approve() { EXPECT_TRUE(IsAuthenticated()); } -void RemoteDesktopBrowserTest::StartMe2Me() { +void RemoteDesktopBrowserTest::ExpandMe2Me() { // The chromoting extension should be installed. ASSERT_TRUE(extension_); @@ -459,7 +459,7 @@ void RemoteDesktopBrowserTest::Auth() { Approve(); } -void RemoteDesktopBrowserTest::ConnectToLocalHost() { +void RemoteDesktopBrowserTest::ConnectToLocalHost(bool remember_pin) { // Verify that the local host is online. ASSERT_TRUE(ExecuteScriptAndExtractBool( "remoting.hostList.localHost_.hostName && " @@ -471,13 +471,13 @@ void RemoteDesktopBrowserTest::ConnectToLocalHost() { ClickOnControl("this-host-connect"); // Enter the pin # passed in from the command line. - EnterPin(me2me_pin()); + EnterPin(me2me_pin(), remember_pin); WaitForConnection(); } void RemoteDesktopBrowserTest::ConnectToRemoteHost( - const std::string& host_name) { + const std::string& host_name, bool remember_pin) { std::string host_id = ExecuteScriptAndExtractString( "remoting.hostList.getHostIdForName('" + host_name + "')"); @@ -492,7 +492,7 @@ void RemoteDesktopBrowserTest::ConnectToRemoteHost( ClickOnControl(element_id); // Enter the pin # passed in from the command line. - EnterPin(me2me_pin()); + EnterPin(me2me_pin(), remember_pin); WaitForConnection(); } @@ -613,7 +613,8 @@ void RemoteDesktopBrowserTest::ClickOnControl(const std::string& name) { ExecuteScript("document.getElementById(\"" + name + "\").click();"); } -void RemoteDesktopBrowserTest::EnterPin(const std::string& pin) { +void RemoteDesktopBrowserTest::EnterPin(const std::string& pin, + bool remember_pin) { // Wait for the pin-form to be displayed. This can take a while. // We also need to dismiss the host-needs-update dialog if it comes up. // TODO(weitaosu) 1: Instead of polling, can we register a callback to be @@ -630,6 +631,15 @@ void RemoteDesktopBrowserTest::EnterPin(const std::string& pin) { ExecuteScript( "document.getElementById(\"pin-entry\").value = \"" + pin + "\";"); + if (remember_pin) { + EXPECT_TRUE(HtmlElementVisible("remember-pin")); + EXPECT_FALSE(ExecuteScriptAndExtractBool( + "document.getElementById('remember-pin-checkbox').checked")); + ClickOnControl("remember-pin"); + EXPECT_TRUE(ExecuteScriptAndExtractBool( + "document.getElementById('remember-pin-checkbox').checked")); + } + ClickOnControl("pin-connect-button"); } @@ -657,6 +667,10 @@ bool RemoteDesktopBrowserTest::IsLocalHostReady() { } bool RemoteDesktopBrowserTest::IsSessionConnected() { + // If some form of PINless authentication is enabled, the host version + // warning may appear while waiting for the session to connect. + DismissHostVersionWarningIfVisible(); + return ExecuteScriptAndExtractBool( "remoting.clientSession != null && " "remoting.clientSession.getState() == " @@ -664,10 +678,13 @@ bool RemoteDesktopBrowserTest::IsSessionConnected() { } bool RemoteDesktopBrowserTest::IsPinFormVisible() { + DismissHostVersionWarningIfVisible(); + return HtmlElementVisible("pin-form"); +} + +void RemoteDesktopBrowserTest::DismissHostVersionWarningIfVisible() { if (HtmlElementVisible("host-needs-update-connect-button")) ClickOnControl("host-needs-update-connect-button"); - - return HtmlElementVisible("pin-form"); } // static diff --git a/chrome/test/remoting/remote_desktop_browsertest.h b/chrome/test/remoting/remote_desktop_browsertest.h index faa3a895a7..36abbfda1a 100644 --- a/chrome/test/remoting/remote_desktop_browsertest.h +++ b/chrome/test/remoting/remote_desktop_browsertest.h @@ -84,7 +84,7 @@ class RemoteDesktopBrowserTest : public extensions::PlatformAppBrowserTest { void Approve(); // Click on "Get Started" in the Me2Me section and show the host list. - void StartMe2Me(); + void ExpandMe2Me(); // Disconnect the active Me2Me session. void DisconnectMe2Me(); @@ -126,13 +126,13 @@ class RemoteDesktopBrowserTest : public extensions::PlatformAppBrowserTest { void Auth(); // Connect to the local host through Me2Me. - void ConnectToLocalHost(); + void ConnectToLocalHost(bool remember_pin); // Connect to a remote host through Me2Me. - void ConnectToRemoteHost(const std::string& host_name); + void ConnectToRemoteHost(const std::string& host_name, bool remember_pin); // Enter the pin number and connect. - void EnterPin(const std::string& name); + void EnterPin(const std::string& name, bool remember_pin); // Helper to get the pin number used for me2me authentication. std::string me2me_pin() { return me2me_pin_; } @@ -140,7 +140,6 @@ class RemoteDesktopBrowserTest : public extensions::PlatformAppBrowserTest { // Helper to get the name of the remote host to connect to. std::string remote_host_name() { return remote_host_name_; } - private: // Change behavior of the default host resolver to allow DNS lookup // to proceed instead of being blocked by the test infrastructure. void EnableDNSLookupForThisTest( @@ -266,10 +265,14 @@ class RemoteDesktopBrowserTest : public extensions::PlatformAppBrowserTest { return IsAuthenticatedInWindow(active_web_contents()); } + // If the "Host version out-of-date" form is visible, dismiss it. + void DismissHostVersionWarningIfVisible(); + // Callback used by Approve to check whether the chromoting app has // successfully authenticated with the Google services. static bool IsAuthenticatedInWindow(content::WebContents* web_contents); + private: // Fields // This test needs to make live DNS requests for access to |