| // 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. |
| |
| #include <string> |
| |
| #include "base/command_line.h" |
| #include "base/compiler_specific.h" |
| #include "base/file_path.h" |
| #include "base/file_util.h" |
| #include "base/i18n/rtl.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/scoped_temp_dir.h" |
| #include "base/string_util.h" |
| #include "base/stringprintf.h" |
| #include "base/sys_info.h" |
| #include "base/test/test_timeouts.h" |
| #include "base/utf_string_conversions.h" |
| #include "build/build_config.h" |
| #include "chrome/app/chrome_command_ids.h" |
| #include "chrome/browser/ui/view_ids.h" |
| #include "chrome/common/automation_messages.h" |
| #include "chrome/common/chrome_constants.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/url_constants.h" |
| #include "chrome/test/automation/automation_proxy_uitest.h" |
| #include "chrome/test/automation/browser_proxy.h" |
| #include "chrome/test/automation/proxy_launcher.h" |
| #include "chrome/test/automation/tab_proxy.h" |
| #include "chrome/test/automation/window_proxy.h" |
| #include "chrome/test/ui/ui_test.h" |
| #include "chrome/test/ui_test_utils.h" |
| #include "content/browser/net/url_request_slow_http_job.h" |
| #include "content/common/json_value_serializer.h" |
| #include "net/base/host_port_pair.h" |
| #include "net/base/net_util.h" |
| #include "net/test/test_server.h" |
| #define GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING |
| #include "testing/gmock_mutant.h" |
| #include "third_party/skia/include/core/SkBitmap.h" |
| #include "ui/base/message_box_flags.h" |
| #include "ui/base/ui_base_switches.h" |
| #include "ui/gfx/codec/png_codec.h" |
| #include "ui/gfx/rect.h" |
| |
| using ui_test_utils::TimedMessageLoopRunner; |
| using testing::CreateFunctor; |
| using testing::StrEq; |
| using testing::_; |
| |
| |
| // Replace the default automation proxy with our mock client. |
| class ExternalTabUITestMockLauncher : public ProxyLauncher { |
| public: |
| explicit ExternalTabUITestMockLauncher(ExternalTabUITestMockClient **mock) |
| : mock_(mock) { |
| channel_id_ = AutomationProxy::GenerateChannelID(); |
| } |
| |
| AutomationProxy* CreateAutomationProxy(int execution_timeout) { |
| *mock_ = new ExternalTabUITestMockClient(execution_timeout); |
| (*mock_)->InitializeChannel(channel_id_, false); |
| return *mock_; |
| } |
| |
| void InitializeConnection(const LaunchState& state, |
| bool wait_for_initial_loads) { |
| ASSERT_TRUE(LaunchBrowserAndServer(state, wait_for_initial_loads)); |
| } |
| |
| void TerminateConnection() { |
| CloseBrowserAndServer(); |
| } |
| |
| std::string PrefixedChannelID() const { |
| return channel_id_; |
| } |
| |
| private: |
| ExternalTabUITestMockClient **mock_; |
| std::string channel_id_; // Channel id of automation proxy. |
| }; |
| |
| class AutomationProxyTest : public UITest { |
| protected: |
| AutomationProxyTest() { |
| dom_automation_enabled_ = true; |
| launch_arguments_.AppendSwitchASCII(switches::kLang, "en-US"); |
| } |
| }; |
| |
| TEST_F(AutomationProxyTest, GetBrowserWindowCount) { |
| int window_count = 0; |
| EXPECT_TRUE(automation()->GetBrowserWindowCount(&window_count)); |
| EXPECT_EQ(1, window_count); |
| #ifdef NDEBUG |
| ASSERT_FALSE(automation()->GetBrowserWindowCount(NULL)); |
| #endif |
| } |
| |
| TEST_F(AutomationProxyTest, GetBrowserWindow) { |
| { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| } |
| |
| { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(-1)); |
| ASSERT_FALSE(window.get()); |
| } |
| |
| { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(1)); |
| ASSERT_FALSE(window.get()); |
| } |
| }; |
| |
| #if defined(OS_MACOSX) |
| // Missing automation provider support: http://crbug.com/45892 |
| #define MAYBE_WindowGetViewBounds FAILS_WindowGetViewBounds |
| #else |
| #define MAYBE_WindowGetViewBounds WindowGetViewBounds |
| #endif |
| TEST_F(AutomationProxyVisibleTest, MAYBE_WindowGetViewBounds) { |
| { |
| scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(browser.get()); |
| scoped_refptr<WindowProxy> window(browser->GetWindow()); |
| ASSERT_TRUE(window.get()); |
| |
| scoped_refptr<TabProxy> tab1(browser->GetTab(0)); |
| ASSERT_TRUE(tab1.get()); |
| GURL tab1_url; |
| ASSERT_TRUE(tab1->GetCurrentURL(&tab1_url)); |
| |
| // Add another tab so we can simulate dragging. |
| ASSERT_TRUE(browser->AppendTab(GURL(chrome::kChromeUIVersionURL))); |
| |
| scoped_refptr<TabProxy> tab2(browser->GetTab(1)); |
| ASSERT_TRUE(tab2.get()); |
| GURL tab2_url; |
| ASSERT_TRUE(tab2->GetCurrentURL(&tab2_url)); |
| |
| EXPECT_NE(tab1_url.spec(), tab2_url.spec()); |
| |
| gfx::Rect bounds; |
| ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_0, &bounds, false)); |
| EXPECT_GT(bounds.width(), 0); |
| EXPECT_GT(bounds.height(), 0); |
| |
| gfx::Rect bounds2; |
| ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_LAST, &bounds2, false)); |
| EXPECT_GT(bounds2.x(), 0); |
| EXPECT_GT(bounds2.width(), 0); |
| EXPECT_GT(bounds2.height(), 0); |
| |
| // The tab logic is mirrored in RTL locales, so what is to the right in |
| // LTR locales is now on the left with RTL ones. |
| string16 browser_locale; |
| |
| EXPECT_TRUE(automation()->GetBrowserLocale(&browser_locale)); |
| |
| const std::string& locale_utf8 = UTF16ToUTF8(browser_locale); |
| if (base::i18n::GetTextDirectionForLocale(locale_utf8.c_str()) == |
| base::i18n::RIGHT_TO_LEFT) { |
| EXPECT_LT(bounds2.x(), bounds.x()); |
| } else { |
| EXPECT_GT(bounds2.x(), bounds.x()); |
| } |
| EXPECT_EQ(bounds2.y(), bounds.y()); |
| |
| // Sometimes tests start the browser in full screen mode. Don't check the |
| // location bar in such a case. |
| bool fullscreen = false; |
| if (browser->IsFullscreen(&fullscreen) && !fullscreen) { |
| gfx::Rect urlbar_bounds; |
| ASSERT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &urlbar_bounds, |
| false)); |
| EXPECT_GT(urlbar_bounds.x(), 0); |
| EXPECT_GT(urlbar_bounds.y(), 0); |
| EXPECT_GT(urlbar_bounds.width(), 0); |
| EXPECT_GT(urlbar_bounds.height(), 0); |
| } |
| |
| /* |
| |
| TODO(beng): uncomment this section or move to interactive_ui_tests post |
| haste! |
| |
| // Now that we know where the tabs are, let's try dragging one. |
| POINT start; |
| POINT end; |
| start.x = bounds.x() + bounds.width() / 2; |
| start.y = bounds.y() + bounds.height() / 2; |
| end.x = start.x + 2 * bounds.width() / 3; |
| end.y = start.y; |
| ASSERT_TRUE(browser->SimulateDrag(start, end, ui::EF_LEFT_BUTTON_DOWN)); |
| |
| // Check to see that the drag event successfully swapped the two tabs. |
| tab1 = browser->GetTab(0); |
| ASSERT_TRUE(tab1.get()); |
| GURL tab1_new_url; |
| ASSERT_TRUE(tab1->GetCurrentURL(&tab1_new_url)); |
| |
| tab2 = browser->GetTab(1); |
| ASSERT_TRUE(tab2.get()); |
| GURL tab2_new_url; |
| ASSERT_TRUE(tab2->GetCurrentURL(&tab2_new_url)); |
| |
| EXPECT_EQ(tab1_url.spec(), tab2_new_url.spec()); |
| EXPECT_EQ(tab2_url.spec(), tab1_new_url.spec()); |
| |
| */ |
| } |
| } |
| |
| TEST_F(AutomationProxyTest, GetTabCount) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| |
| int tab_count = 0; |
| ASSERT_TRUE(window->GetTabCount(&tab_count)); |
| ASSERT_EQ(1, tab_count); |
| } |
| |
| TEST_F(AutomationProxyTest, GetActiveTabIndex) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| |
| int active_tab_index = -1; |
| ASSERT_TRUE(window->GetActiveTabIndex(&active_tab_index)); |
| ASSERT_EQ(0, active_tab_index); |
| } |
| |
| TEST_F(AutomationProxyVisibleTest, AppendTab) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| |
| int original_tab_count; |
| ASSERT_TRUE(window->GetTabCount(&original_tab_count)); |
| ASSERT_EQ(1, original_tab_count); // By default there are 2 tabs opened. |
| |
| int original_active_tab_index; |
| ASSERT_TRUE(window->GetActiveTabIndex(&original_active_tab_index)); |
| ASSERT_EQ(0, original_active_tab_index); // By default 0-th tab is active |
| |
| ASSERT_TRUE(window->AppendTab(GURL("about:blank"))); |
| int tab_count; |
| ASSERT_TRUE(window->GetTabCount(&tab_count)); |
| ASSERT_EQ(original_tab_count + 1, tab_count); |
| |
| int active_tab_index = -1; |
| ASSERT_TRUE(window->GetActiveTabIndex(&active_tab_index)); |
| ASSERT_EQ(tab_count - 1, active_tab_index); |
| ASSERT_NE(original_active_tab_index, active_tab_index); |
| |
| FilePath filename(test_data_directory_); |
| filename = filename.AppendASCII("title2.html"); |
| ASSERT_TRUE(window->AppendTab(net::FilePathToFileURL(filename))); |
| |
| int appended_tab_index; |
| // Append tab will also be active tab |
| ASSERT_TRUE(window->GetActiveTabIndex(&appended_tab_index)); |
| |
| scoped_refptr<TabProxy> tab(window->GetTab(appended_tab_index)); |
| ASSERT_TRUE(tab.get()); |
| std::wstring title; |
| ASSERT_TRUE(tab->GetTabTitle(&title)); |
| ASSERT_STREQ(L"Title Of Awesomeness", title.c_str()); |
| } |
| |
| TEST_F(AutomationProxyTest, ActivateTab) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| |
| ASSERT_TRUE(window->AppendTab(GURL("about:blank"))); |
| |
| ASSERT_TRUE(window->ActivateTab(1)); |
| int active_tab_index = -1; |
| ASSERT_TRUE(window->GetActiveTabIndex(&active_tab_index)); |
| ASSERT_EQ(1, active_tab_index); |
| |
| ASSERT_TRUE(window->ActivateTab(0)); |
| ASSERT_TRUE(window->GetActiveTabIndex(&active_tab_index)); |
| ASSERT_EQ(0, active_tab_index); |
| } |
| |
| TEST_F(AutomationProxyTest, GetTab) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| { |
| scoped_refptr<TabProxy> tab(window->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| std::wstring title; |
| ASSERT_TRUE(tab->GetTabTitle(&title)); |
| ASSERT_STREQ(L"about:blank", title.c_str()); |
| } |
| |
| { |
| ASSERT_FALSE(window->GetTab(-1)); |
| } |
| |
| { |
| scoped_refptr<TabProxy> tab(window->GetTab(1)); |
| ASSERT_FALSE(tab.get()); |
| } |
| }; |
| |
| TEST_F(AutomationProxyTest, NavigateToURL) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| scoped_refptr<TabProxy> tab(window->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| |
| std::wstring title; |
| ASSERT_TRUE(tab->GetTabTitle(&title)); |
| ASSERT_STREQ(L"about:blank", title.c_str()); |
| |
| FilePath filename(test_data_directory_); |
| filename = filename.AppendASCII("title2.html"); |
| |
| ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, |
| tab->NavigateToURL(net::FilePathToFileURL(filename))); |
| ASSERT_TRUE(tab->GetTabTitle(&title)); |
| ASSERT_STREQ(L"Title Of Awesomeness", title.c_str()); |
| |
| // TODO(vibhor) : Add a test using testserver. |
| } |
| |
| TEST_F(AutomationProxyTest, GoBackForward) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| scoped_refptr<TabProxy> tab(window->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| |
| std::wstring title; |
| ASSERT_TRUE(tab->GetTabTitle(&title)); |
| ASSERT_STREQ(L"about:blank", title.c_str()); |
| |
| ASSERT_FALSE(tab->GoBack()); |
| ASSERT_TRUE(tab->GetTabTitle(&title)); |
| ASSERT_STREQ(L"about:blank", title.c_str()); |
| |
| FilePath filename(test_data_directory_); |
| filename = filename.AppendASCII("title2.html"); |
| ASSERT_TRUE(tab->NavigateToURL(net::FilePathToFileURL(filename))); |
| ASSERT_TRUE(tab->GetTabTitle(&title)); |
| ASSERT_STREQ(L"Title Of Awesomeness", title.c_str()); |
| |
| ASSERT_TRUE(tab->GoBack()); |
| ASSERT_TRUE(tab->GetTabTitle(&title)); |
| ASSERT_STREQ(L"about:blank", title.c_str()); |
| |
| ASSERT_TRUE(tab->GoForward()); |
| ASSERT_TRUE(tab->GetTabTitle(&title)); |
| ASSERT_STREQ(L"Title Of Awesomeness", title.c_str()); |
| |
| ASSERT_FALSE(tab->GoForward()); |
| ASSERT_TRUE(tab->GetTabTitle(&title)); |
| ASSERT_STREQ(L"Title Of Awesomeness", title.c_str()); |
| } |
| |
| TEST_F(AutomationProxyTest, GetCurrentURL) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| scoped_refptr<TabProxy> tab(window->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| GURL url; |
| ASSERT_TRUE(tab->GetCurrentURL(&url)); |
| ASSERT_STREQ("about:blank", url.spec().c_str()); |
| |
| FilePath filename(test_data_directory_); |
| filename = filename.AppendASCII("cookie1.html"); |
| GURL newurl = net::FilePathToFileURL(filename); |
| ASSERT_TRUE(tab->NavigateToURL(newurl)); |
| ASSERT_TRUE(tab->GetCurrentURL(&url)); |
| // compare canonical urls... |
| ASSERT_STREQ(newurl.spec().c_str(), url.spec().c_str()); |
| } |
| |
| class AutomationProxyTest2 : public AutomationProxyVisibleTest { |
| protected: |
| AutomationProxyTest2() { |
| document1_= test_data_directory_.AppendASCII("title1.html"); |
| |
| document2_ = test_data_directory_.AppendASCII("title2.html"); |
| launch_arguments_ = CommandLine(CommandLine::NO_PROGRAM); |
| launch_arguments_.AppendArgPath(document1_); |
| launch_arguments_.AppendArgPath(document2_); |
| } |
| |
| FilePath document1_; |
| FilePath document2_; |
| }; |
| |
| TEST_F(AutomationProxyTest2, GetActiveTabIndex) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| |
| int active_tab_index = -1; |
| ASSERT_TRUE(window->GetActiveTabIndex(&active_tab_index)); |
| ASSERT_EQ(0, active_tab_index); |
| |
| ASSERT_TRUE(window->ActivateTab(1)); |
| ASSERT_TRUE(window->GetActiveTabIndex(&active_tab_index)); |
| ASSERT_EQ(1, active_tab_index); |
| } |
| |
| TEST_F(AutomationProxyTest2, GetTabTitle) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| scoped_refptr<TabProxy> tab(window->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| std::wstring title; |
| ASSERT_TRUE(tab->GetTabTitle(&title)); |
| ASSERT_STREQ(L"title1.html", title.c_str()); |
| |
| tab = window->GetTab(1); |
| ASSERT_TRUE(tab.get()); |
| ASSERT_TRUE(tab->GetTabTitle(&title)); |
| ASSERT_STREQ(L"Title Of Awesomeness", title.c_str()); |
| } |
| |
| TEST_F(AutomationProxyTest, Cookies) { |
| GURL url("http://mojo.jojo.google.com"); |
| std::string value_result; |
| |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| |
| scoped_refptr<TabProxy> tab(window->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| |
| // test setting the cookie: |
| ASSERT_TRUE(tab->SetCookie(url, "foo=baz")); |
| |
| ASSERT_TRUE(tab->GetCookieByName(url, "foo", &value_result)); |
| ASSERT_FALSE(value_result.empty()); |
| ASSERT_STREQ("baz", value_result.c_str()); |
| |
| // test clearing the cookie: |
| ASSERT_TRUE(tab->SetCookie(url, "foo=")); |
| |
| ASSERT_TRUE(tab->GetCookieByName(url, "foo", &value_result)); |
| ASSERT_TRUE(value_result.empty()); |
| |
| // now, test that we can get multiple cookies: |
| ASSERT_TRUE(tab->SetCookie(url, "foo1=baz1")); |
| ASSERT_TRUE(tab->SetCookie(url, "foo2=baz2")); |
| |
| ASSERT_TRUE(tab->GetCookies(url, &value_result)); |
| ASSERT_FALSE(value_result.empty()); |
| EXPECT_TRUE(value_result.find("foo1=baz1") != std::string::npos); |
| EXPECT_TRUE(value_result.find("foo2=baz2") != std::string::npos); |
| |
| // test deleting cookie |
| ASSERT_TRUE(tab->SetCookie(url, "foo3=deleteme")); |
| |
| ASSERT_TRUE(tab->GetCookieByName(url, "foo3", &value_result)); |
| ASSERT_FALSE(value_result.empty()); |
| ASSERT_STREQ("deleteme", value_result.c_str()); |
| |
| ASSERT_TRUE(tab->DeleteCookie(url, "foo3")); |
| } |
| |
| TEST_F(AutomationProxyTest, NavigateToURLAsync) { |
| AutomationProxy* automation_object = automation(); |
| scoped_refptr<BrowserProxy> window(automation_object->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| scoped_refptr<TabProxy> tab(window->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| |
| FilePath filename(test_data_directory_); |
| filename = filename.AppendASCII("cookie1.html"); |
| GURL newurl = net::FilePathToFileURL(filename); |
| |
| ASSERT_TRUE(tab->NavigateToURLAsync(newurl)); |
| std::string value = WaitUntilCookieNonEmpty( |
| tab.get(), newurl, "foo", TestTimeouts::action_max_timeout_ms()); |
| ASSERT_STREQ("baz", value.c_str()); |
| } |
| |
| TEST_F(AutomationProxyTest, AcceleratorNewTab) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| |
| int tab_count = -1; |
| ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB)); |
| ASSERT_TRUE(window->GetTabCount(&tab_count)); |
| EXPECT_EQ(2, tab_count); |
| |
| scoped_refptr<TabProxy> tab(window->GetTab(1)); |
| ASSERT_TRUE(tab.get()); |
| } |
| |
| TEST_F(AutomationProxyTest, AcceleratorDownloads) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| |
| ASSERT_TRUE(window->RunCommand(IDC_SHOW_DOWNLOADS)); |
| |
| // We expect the RunCommand above to wait until the title is updated. |
| EXPECT_EQ(L"Downloads", GetActiveTabTitle()); |
| } |
| |
| TEST_F(AutomationProxyTest, AcceleratorExtensions) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| |
| ASSERT_TRUE(window->RunCommand(IDC_MANAGE_EXTENSIONS)); |
| |
| // We expect the RunCommand above to wait until the title is updated. |
| EXPECT_EQ(L"Extensions", GetActiveTabTitle()); |
| } |
| |
| TEST_F(AutomationProxyTest, AcceleratorHistory) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| |
| ASSERT_TRUE(window->RunCommand(IDC_SHOW_HISTORY)); |
| |
| // We expect the RunCommand above to wait until the title is updated. |
| EXPECT_EQ(L"History", GetActiveTabTitle()); |
| } |
| |
| class AutomationProxyTest4 : public UITest { |
| protected: |
| AutomationProxyTest4() : UITest() { |
| dom_automation_enabled_ = true; |
| } |
| }; |
| |
| std::wstring CreateJSString(const std::wstring& value) { |
| std::wstring jscript; |
| base::SStringPrintf(&jscript, |
| L"window.domAutomationController.send(%ls);", |
| value.c_str()); |
| return jscript; |
| } |
| |
| TEST_F(AutomationProxyTest4, StringValueIsEchoedByDomAutomationController) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| |
| scoped_refptr<TabProxy> tab(window->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| |
| std::wstring expected(L"string"); |
| std::wstring jscript = CreateJSString(L"\"" + expected + L"\""); |
| std::wstring actual; |
| ASSERT_TRUE(tab->ExecuteAndExtractString(L"", jscript, &actual)); |
| ASSERT_STREQ(expected.c_str(), actual.c_str()); |
| } |
| |
| std::wstring BooleanToString(bool bool_value) { |
| Value* value = Value::CreateBooleanValue(bool_value); |
| std::string json_string; |
| JSONStringValueSerializer serializer(&json_string); |
| serializer.Serialize(*value); |
| return UTF8ToWide(json_string); |
| } |
| |
| TEST_F(AutomationProxyTest4, BooleanValueIsEchoedByDomAutomationController) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| |
| scoped_refptr<TabProxy> tab(window->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| |
| bool expected = true; |
| std::wstring jscript = CreateJSString(BooleanToString(expected)); |
| bool actual = false; |
| ASSERT_TRUE(tab->ExecuteAndExtractBool(L"", jscript, &actual)); |
| ASSERT_EQ(expected, actual); |
| } |
| |
| TEST_F(AutomationProxyTest4, NumberValueIsEchoedByDomAutomationController) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| |
| scoped_refptr<TabProxy> tab(window->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| |
| int expected = 1; |
| int actual = 0; |
| std::wstring expected_string; |
| base::SStringPrintf(&expected_string, L"%d", expected); |
| std::wstring jscript = CreateJSString(expected_string); |
| ASSERT_TRUE(tab->ExecuteAndExtractInt(L"", jscript, &actual)); |
| ASSERT_EQ(expected, actual); |
| } |
| |
| // TODO(vibhor): Add a test for ExecuteAndExtractValue() for JSON Dictionary |
| // type value |
| |
| class AutomationProxyTest3 : public UITest { |
| protected: |
| AutomationProxyTest3() : UITest() { |
| document1_ = test_data_directory_; |
| document1_ = document1_.AppendASCII("frame_dom_access"); |
| document1_ = document1_.AppendASCII("frame_dom_access.html"); |
| |
| dom_automation_enabled_ = true; |
| launch_arguments_ = CommandLine(CommandLine::NO_PROGRAM); |
| launch_arguments_.AppendArgPath(document1_); |
| } |
| |
| FilePath document1_; |
| }; |
| |
| std::wstring CreateJSStringForDOMQuery(const std::wstring& id) { |
| std::wstring jscript(L"window.domAutomationController"); |
| base::StringAppendF(&jscript, |
| L".send(document.getElementById('%ls').nodeName);", |
| id.c_str()); |
| return jscript; |
| } |
| |
| TEST_F(AutomationProxyTest3, FrameDocumentCanBeAccessed) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| |
| scoped_refptr<TabProxy> tab(window->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| |
| std::wstring actual; |
| std::wstring xpath1 = L""; // top level frame |
| std::wstring jscript1 = CreateJSStringForDOMQuery(L"myinput"); |
| ASSERT_TRUE(tab->ExecuteAndExtractString(xpath1, jscript1, &actual)); |
| ASSERT_EQ(L"INPUT", actual); |
| |
| std::wstring xpath2 = L"/html/body/iframe"; |
| std::wstring jscript2 = CreateJSStringForDOMQuery(L"myspan"); |
| ASSERT_TRUE(tab->ExecuteAndExtractString(xpath2, jscript2, &actual)); |
| ASSERT_EQ(L"SPAN", actual); |
| |
| std::wstring xpath3 = L"/html/body/iframe\n/html/body/iframe"; |
| std::wstring jscript3 = CreateJSStringForDOMQuery(L"mydiv"); |
| ASSERT_TRUE(tab->ExecuteAndExtractString(xpath3, jscript3, &actual)); |
| ASSERT_EQ(L"DIV", actual); |
| } |
| |
| // Flaky, http://crbug.com/70937 |
| TEST_F(AutomationProxyTest, FLAKY_BlockedPopupTest) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| |
| scoped_refptr<TabProxy> tab(window->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| |
| FilePath filename(test_data_directory_); |
| filename = filename.AppendASCII("constrained_files"); |
| filename = filename.AppendASCII("constrained_window.html"); |
| |
| ASSERT_TRUE(tab->NavigateToURL(net::FilePathToFileURL(filename))); |
| |
| ASSERT_TRUE(tab->WaitForBlockedPopupCountToChangeTo( |
| 2, TestTimeouts::action_max_timeout_ms())); |
| } |
| |
| // TODO(port): Remove HWND if possible |
| #if defined(OS_WIN) |
| |
| const char simple_data_url[] = |
| "data:text/html,<html><head><title>External tab test</title></head>" |
| "<body>A simple page for testing a floating/invisible tab<br></div>" |
| "</body></html>"; |
| |
| ExternalTabUITestMockClient::ExternalTabUITestMockClient(int execution_timeout) |
| : AutomationProxy(execution_timeout, false), |
| host_window_style_(WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE), |
| host_window_(NULL) { |
| } |
| |
| ExternalTabUITestMockClient::~ExternalTabUITestMockClient() { |
| EXPECT_TRUE(host_window_ == NULL); |
| } |
| |
| void ExternalTabUITestMockClient::ReplyStarted( |
| const AutomationURLResponse* response, |
| int tab_handle, int request_id) { |
| AutomationProxy::Send(new AutomationMsg_RequestStarted(tab_handle, |
| request_id, *response)); |
| } |
| |
| void ExternalTabUITestMockClient::ReplyData( |
| const std::string* data, int tab_handle, int request_id) { |
| AutomationProxy::Send(new AutomationMsg_RequestData(tab_handle, |
| request_id, *data)); |
| } |
| |
| void ExternalTabUITestMockClient::ReplyEOF(int tab_handle, int request_id) { |
| ReplyEnd(net::URLRequestStatus(), tab_handle, request_id); |
| } |
| |
| void ExternalTabUITestMockClient::ReplyEnd(const net::URLRequestStatus& status, |
| int tab_handle, int request_id) { |
| AutomationProxy::Send(new AutomationMsg_RequestEnd(tab_handle, |
| request_id, status)); |
| } |
| |
| void ExternalTabUITestMockClient::Reply404(int tab_handle, int request_id) { |
| const AutomationURLResponse notfound("", "HTTP/1.1 404\r\n\r\n", 0, |
| base::Time(), "", 0, |
| net::HostPortPair()); |
| ReplyStarted(¬found, tab_handle, request_id); |
| ReplyEOF(tab_handle, request_id); |
| } |
| |
| void ExternalTabUITestMockClient::ServeHTMLData(int tab_handle, |
| const GURL& url, |
| const std::string& data) { |
| EXPECT_CALL(*this, OnRequestStart(tab_handle, testing::AllOf( |
| testing::Field(&AutomationURLRequest::url, url.spec()), |
| testing::Field(&AutomationURLRequest::method, StrEq("GET"))))) |
| .Times(1) |
| .WillOnce(testing::WithArgs<0, 0>(testing::Invoke(CreateFunctor(this, |
| &ExternalTabUITestMockClient::ReplyStarted, &http_200)))); |
| |
| EXPECT_CALL(*this, OnRequestRead(tab_handle, testing::Gt(0))) |
| .Times(2) |
| .WillOnce(testing::WithArgs<0, 0>(testing::Invoke(CreateFunctor(this, |
| &ExternalTabUITestMockClient::ReplyData, &data)))) |
| .WillOnce(testing::WithArgs<0, 0>(testing::Invoke(CreateFunctor(this, |
| &ExternalTabUITestMockClient::ReplyEOF)))); |
| } |
| |
| void ExternalTabUITestMockClient::IgnoreFaviconNetworkRequest() { |
| // Ignore favicon.ico |
| EXPECT_CALL(*this, OnRequestStart(_, testing::AllOf( |
| testing::Field(&AutomationURLRequest::url, |
| testing::EndsWith("favicon.ico")), |
| testing::Field(&AutomationURLRequest::method, StrEq("GET"))))) |
| .Times(testing::AnyNumber()) |
| .WillRepeatedly(testing::WithArgs<0, 0>(testing::Invoke( |
| CreateFunctor(this, &ExternalTabUITestMockClient::ReplyEnd, |
| net::URLRequestStatus(net::URLRequestStatus::FAILED, 0))))); |
| } |
| |
| void ExternalTabUITestMockClient::InvalidateHandle( |
| const IPC::Message& message) { |
| void* iter = NULL; |
| int handle; |
| ASSERT_TRUE(message.ReadInt(&iter, &handle)); |
| |
| // Call base class |
| AutomationProxy::InvalidateHandle(message); |
| HandleClosed(handle); |
| } |
| |
| // Most of the time we need external tab with these settings. |
| const ExternalTabSettings ExternalTabUITestMockClient::default_settings( |
| NULL, gfx::Rect(), // will be replaced by CreateHostWindowAndTab |
| WS_CHILD | WS_VISIBLE, |
| false, // is_incognito |
| true, // load_requests_via_automation |
| true, // handle_top_level_requests |
| GURL(), // initial_url |
| GURL(), // referrer |
| false, // infobars_enabled |
| false); // route_all_top_level_navigations |
| |
| // static |
| const AutomationURLResponse ExternalTabUITestMockClient::http_200( |
| "", |
| "HTTP/0.9 200\r\n\r\n", |
| 0, |
| base::Time(), |
| "", |
| 0, |
| net::HostPortPair()); |
| |
| bool ExternalTabUITestMockClient::OnMessageReceived(const IPC::Message& msg) { |
| bool handled = true; |
| IPC_BEGIN_MESSAGE_MAP(ExternalTabUITestMockClient, msg) |
| IPC_MESSAGE_HANDLER(AutomationMsg_DidNavigate, OnDidNavigate) |
| IPC_MESSAGE_HANDLER(AutomationMsg_ForwardMessageToExternalHost, |
| OnForwardMessageToExternalHost) |
| IPC_MESSAGE_HANDLER(AutomationMsg_RequestStart, OnRequestStart) |
| IPC_MESSAGE_HANDLER(AutomationMsg_RequestRead, OnRequestRead) |
| IPC_MESSAGE_HANDLER(AutomationMsg_RequestEnd, OnRequestEnd) |
| IPC_MESSAGE_HANDLER(AutomationMsg_SetCookieAsync, OnSetCookieAsync) |
| IPC_MESSAGE_HANDLER(AutomationMsg_TabLoaded, OnLoad) |
| IPC_MESSAGE_HANDLER(AutomationMsg_AttachExternalTab, OnAttachExternalTab) |
| IPC_MESSAGE_HANDLER(AutomationMsg_OpenURL, OnOpenURL) |
| IPC_MESSAGE_HANDLER(AutomationMsg_NavigationStateChanged, |
| OnNavigationStateChanged) |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| IPC_END_MESSAGE_MAP() |
| return handled; |
| } |
| |
| scoped_refptr<TabProxy> ExternalTabUITestMockClient::CreateHostWindowAndTab( |
| const ExternalTabSettings& settings) { |
| EXPECT_THAT(settings.parent, testing::IsNull()); |
| |
| host_window_ = CreateWindowW(L"Button", NULL, host_window_style_, |
| CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, |
| NULL, NULL, NULL, NULL); |
| EXPECT_THAT(host_window_, testing::Truly(::IsWindow)); |
| RECT client_area = {0}; |
| ::GetClientRect(host_window_, &client_area); |
| |
| ExternalTabSettings s = settings; |
| s.parent = host_window_; |
| s.dimensions = client_area; |
| |
| HWND container_wnd = NULL; |
| HWND tab_wnd = NULL; |
| scoped_refptr<TabProxy> tab(CreateExternalTab(s, &container_wnd, &tab_wnd)); |
| |
| EXPECT_TRUE(tab != NULL); |
| EXPECT_NE(FALSE, ::IsWindow(container_wnd)); |
| EXPECT_NE(FALSE, ::IsWindow(tab_wnd)); |
| return tab; |
| } |
| |
| scoped_refptr<TabProxy> ExternalTabUITestMockClient::CreateTabWithUrl( |
| const GURL& initial_url) { |
| ExternalTabSettings settings = |
| ExternalTabUITestMockClient::default_settings; |
| settings.initial_url = initial_url; |
| return CreateHostWindowAndTab(settings); |
| } |
| |
| void ExternalTabUITestMockClient::NavigateInExternalTab(int tab_handle, |
| const GURL& url, const GURL& referrer /* = GURL()*/) { |
| channel_->ChannelProxy::Send(new AutomationMsg_NavigateInExternalTab( |
| tab_handle, url, referrer, NULL)); |
| } |
| |
| void ExternalTabUITestMockClient::ConnectToExternalTab(gfx::NativeWindow parent, |
| const AttachExternalTabParams& attach_params) { |
| gfx::NativeWindow tab_container = NULL; |
| gfx::NativeWindow tab_window = NULL; |
| int tab_handle = 0; |
| int session_id = -1; |
| |
| IPC::SyncMessage* message = new AutomationMsg_ConnectExternalTab( |
| attach_params.cookie, true, NULL, &tab_container, &tab_window, |
| &tab_handle, &session_id); |
| channel_->Send(message); |
| |
| RECT rect; |
| ::GetClientRect(parent, &rect); |
| Reposition_Params params = {0}; |
| params.window = tab_container; |
| params.flags = SWP_NOZORDER | SWP_SHOWWINDOW; |
| params.width = rect.right - rect.left; |
| params.height = rect.bottom - rect.top; |
| params.set_parent = true; |
| params.parent_window = parent; |
| |
| channel_->Send(new AutomationMsg_TabReposition(tab_handle, params)); |
| ::ShowWindow(parent, SW_SHOWNORMAL); |
| } |
| |
| void ExternalTabUITestMockClient::NavigateThroughUserGesture() { |
| ASSERT_THAT(host_window_, testing::Truly(::IsWindow)); |
| HWND tab_container = ::GetWindow(host_window_, GW_CHILD); |
| ASSERT_THAT(tab_container, testing::Truly(::IsWindow)); |
| HWND tab = ::GetWindow(tab_container, GW_CHILD); |
| ASSERT_THAT(tab, testing::Truly(::IsWindow)); |
| HWND renderer_window = ::GetWindow(tab, GW_CHILD); |
| ASSERT_THAT(renderer_window, testing::Truly(::IsWindow)); |
| ::SetFocus(renderer_window); |
| ::PostMessage(renderer_window, WM_KEYDOWN, VK_TAB, 0); |
| ::PostMessage(renderer_window, WM_KEYUP, VK_TAB, 0); |
| ::PostMessage(renderer_window, WM_KEYDOWN, VK_RETURN, 0); |
| ::PostMessage(renderer_window, WM_KEYUP, VK_RETURN, 0); |
| } |
| |
| void ExternalTabUITestMockClient::DestroyHostWindow() { |
| ::DestroyWindow(host_window_); |
| host_window_ = NULL; |
| } |
| |
| bool ExternalTabUITestMockClient::HostWindowExists() { |
| return (host_window_ != NULL) && ::IsWindow(host_window_); |
| } |
| |
| // Handy macro |
| #define QUIT_LOOP(loop) testing::InvokeWithoutArgs(\ |
| CreateFunctor(loop, &TimedMessageLoopRunner::Quit)) |
| #define QUIT_LOOP_SOON(loop, ms) testing::InvokeWithoutArgs(\ |
| CreateFunctor(loop, &TimedMessageLoopRunner::QuitAfter, ms)) |
| |
| template <typename T> T** ReceivePointer(scoped_ptr<T>& p) { // NOLINT |
| return reinterpret_cast<T**>(&p); |
| } |
| |
| template <typename T> T** ReceivePointer(scoped_refptr<T>& p) { // NOLINT |
| return reinterpret_cast<T**>(&p); |
| } |
| |
| ExternalTabUITest::ExternalTabUITest() : UITest(MessageLoop::TYPE_UI) {} |
| |
| // Replace the default automation proxy with our mock client. |
| ProxyLauncher* ExternalTabUITest::CreateProxyLauncher() { |
| return new ExternalTabUITestMockLauncher(&mock_); |
| } |
| |
| // Create with specifying a url |
| // Flaky, http://crbug.com/32293 |
| TEST_F(ExternalTabUITest, FLAKY_CreateExternalTab1) { |
| scoped_refptr<TabProxy> tab; |
| TimedMessageLoopRunner loop(MessageLoop::current()); |
| ASSERT_THAT(mock_, testing::NotNull()); |
| |
| EXPECT_CALL(*mock_, OnNavigationStateChanged(_, _)) |
| .Times(testing::AnyNumber()); |
| |
| EXPECT_CALL(*mock_, OnDidNavigate(testing::_)) |
| .Times(1) |
| .WillOnce(testing::InvokeWithoutArgs(mock_, |
| &ExternalTabUITestMockClient::DestroyHostWindow)); |
| |
| EXPECT_CALL(*mock_, HandleClosed(1)) |
| .Times(1) |
| .WillOnce(QUIT_LOOP(&loop)); |
| |
| tab = mock_->CreateTabWithUrl(GURL(simple_data_url)); |
| loop.RunFor(TestTimeouts::action_max_timeout_ms()); |
| } |
| |
| // Create with empty url and then navigate |
| // Flaky, http://crbug.com/32293 |
| TEST_F(ExternalTabUITest, FLAKY_CreateExternalTab2) { |
| scoped_refptr<TabProxy> tab; |
| TimedMessageLoopRunner loop(MessageLoop::current()); |
| ASSERT_THAT(mock_, testing::NotNull()); |
| |
| EXPECT_CALL(*mock_, OnNavigationStateChanged(_, _)) |
| .Times(testing::AnyNumber()); |
| |
| EXPECT_CALL(*mock_, OnDidNavigate(testing::_)) |
| .Times(1) |
| .WillOnce(testing::InvokeWithoutArgs(mock_, |
| &ExternalTabUITestMockClient::DestroyHostWindow)); |
| |
| EXPECT_CALL(*mock_, HandleClosed(1)) |
| .Times(1) |
| .WillOnce(QUIT_LOOP(&loop)); |
| |
| tab = mock_->CreateTabWithUrl(GURL()); |
| mock_->NavigateInExternalTab(tab->handle(), GURL(simple_data_url)); |
| loop.RunFor(TestTimeouts::action_max_timeout_ms()); |
| } |
| |
| // FLAKY: http://crbug.com/60409 |
| TEST_F(ExternalTabUITest, FLAKY_IncognitoMode) { |
| scoped_refptr<TabProxy> tab; |
| TimedMessageLoopRunner loop(MessageLoop::current()); |
| ASSERT_THAT(mock_, testing::NotNull()); |
| |
| GURL url("http://anatomyofmelancholy.net"); |
| std::string cookie = "robert=burton; expires=Thu, 13 Oct 2011 05:04:03 UTC;"; |
| |
| EXPECT_CALL(*mock_, HandleClosed(1)).Times(1); |
| |
| ExternalTabSettings incognito = |
| ExternalTabUITestMockClient::default_settings; |
| incognito.is_incognito = true; |
| // SetCookie is a sync call and deadlock can happen if window is visible, |
| // since it shares same thread with AutomationProxy. |
| mock_->host_window_style_ &= ~WS_VISIBLE; |
| tab = mock_->CreateHostWindowAndTab(incognito); |
| std::string value_result; |
| |
| EXPECT_TRUE(tab->SetCookie(url, cookie)); |
| EXPECT_TRUE(tab->GetCookieByName(url, "robert", &value_result)); |
| EXPECT_EQ("burton", value_result); |
| mock_->DestroyHostWindow(); |
| CloseBrowserAndServer(); |
| tab = NULL; |
| |
| value_result.clear(); |
| clear_profile_ = false; |
| LaunchBrowserAndServer(); |
| // SetCookie is a sync call and deadlock can happen if window is visible, |
| // since it shares same thread with AutomationProxy. |
| mock_->host_window_style_ &= ~WS_VISIBLE; |
| tab = mock_->CreateTabWithUrl(GURL()); |
| EXPECT_TRUE(tab->GetCookieByName(url, "robert", &value_result)); |
| EXPECT_EQ("", value_result); |
| EXPECT_CALL(*mock_, HandleClosed(1)).Times(1); |
| mock_->DestroyHostWindow(); |
| CloseBrowserAndServer(); |
| tab = NULL; |
| } |
| |
| // FLAKY: http://crbug.com/44617 |
| TEST_F(ExternalTabUITest, FLAKY_TabPostMessage) { |
| scoped_refptr<TabProxy> tab; |
| TimedMessageLoopRunner loop(MessageLoop::current()); |
| ASSERT_THAT(mock_, testing::NotNull()); |
| |
| EXPECT_CALL(*mock_, OnNavigationStateChanged(_, _)) |
| .Times(testing::AnyNumber()); |
| EXPECT_CALL(*mock_, OnLoad(_)).Times(testing::AnyNumber()); |
| |
| std::string content = |
| "data:text/html,<html><head><script>" |
| "function onload() {" |
| " window.externalHost.onmessage = onMessage;" |
| "}" |
| "function onMessage(evt) {" |
| " window.externalHost.postMessage(evt.data, '*');" |
| "}" |
| "</script></head>" |
| "<body onload='onload()'>external tab test<br></div>" |
| "</body></html>"; |
| |
| EXPECT_CALL(*mock_, OnDidNavigate(testing::_)) |
| .Times(1) |
| .WillOnce(testing::InvokeWithoutArgs(CreateFunctor( |
| ReceivePointer(tab), |
| &TabProxy::HandleMessageFromExternalHost, |
| std::string("Hello from gtest"), |
| std::string("null"), std::string("*")))); |
| |
| EXPECT_CALL(*mock_, OnForwardMessageToExternalHost( |
| testing::StrEq("Hello from gtest"), testing::_, testing::_)) |
| .Times(1) |
| .WillOnce(testing::DoAll( |
| testing::InvokeWithoutArgs(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::DestroyHostWindow)), |
| QUIT_LOOP_SOON(&loop, 50))); |
| |
| EXPECT_CALL(*mock_, HandleClosed(1)).Times(1); |
| |
| tab = mock_->CreateTabWithUrl(GURL(content)); |
| loop.RunFor(TestTimeouts::action_max_timeout_ms()); |
| } |
| |
| // Flaky: http://crbug.com/62143 |
| TEST_F(ExternalTabUITest, FLAKY_PostMessageTarget) { |
| net::TestServer test_server( |
| net::TestServer::TYPE_HTTP, |
| FilePath(FILE_PATH_LITERAL("chrome/test/data/external_tab"))); |
| ASSERT_TRUE(test_server.Start()); |
| |
| scoped_refptr<TabProxy> tab; |
| TimedMessageLoopRunner loop(MessageLoop::current()); |
| ASSERT_THAT(mock_, testing::NotNull()); |
| EXPECT_CALL(*mock_, OnNavigationStateChanged(_, _)) |
| .Times(testing::AnyNumber()); |
| EXPECT_CALL(*mock_, OnLoad(_)).Times(testing::AnyNumber()); |
| |
| std::string kTestMessage("Hello from gtest"); |
| std::string kTestOrigin("http://www.external.tab"); |
| |
| EXPECT_CALL(*mock_, OnDidNavigate(testing::_)) |
| .Times(1) |
| .WillOnce(testing::InvokeWithoutArgs(CreateFunctor( |
| ReceivePointer(tab), |
| &TabProxy::HandleMessageFromExternalHost, |
| kTestMessage, kTestOrigin, std::string("http://localhost:1337/")))); |
| |
| EXPECT_CALL(*mock_, OnForwardMessageToExternalHost( |
| testing::StrEq(kTestMessage), |
| testing::_, |
| testing::StrEq(GURL(kTestOrigin).GetOrigin().spec()))) |
| .Times(1) |
| .WillOnce(testing::DoAll( |
| testing::InvokeWithoutArgs(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::DestroyHostWindow)), |
| QUIT_LOOP_SOON(&loop, 50))); |
| |
| EXPECT_CALL(*mock_, HandleClosed(1)).Times(1); |
| |
| ExternalTabSettings s = ExternalTabUITestMockClient::default_settings; |
| s.load_requests_via_automation = false; |
| s.initial_url = GURL("http://localhost:1337/files/post_message.html"); |
| tab = mock_->CreateHostWindowAndTab(s); |
| loop.RunFor(TestTimeouts::action_max_timeout_ms()); |
| } |
| |
| // Flaky, http://crbug.com/42545. |
| TEST_F(ExternalTabUITest, FLAKY_HostNetworkStack) { |
| scoped_refptr<TabProxy> tab; |
| TimedMessageLoopRunner loop(MessageLoop::current()); |
| ASSERT_THAT(mock_, testing::NotNull()); |
| EXPECT_CALL(*mock_, OnNavigationStateChanged(_, _)) |
| .Times(testing::AnyNumber()); |
| EXPECT_CALL(*mock_, OnLoad(_)).Times(testing::AnyNumber()); |
| |
| std::string url = "http://placetogo.org"; |
| |
| testing::InSequence sequence; |
| EXPECT_CALL(*mock_, OnRequestStart(2, testing::AllOf( |
| testing::Field(&AutomationURLRequest::url, StrEq(url + "/")), |
| testing::Field(&AutomationURLRequest::method, StrEq("GET"))))) |
| .Times(1) |
| // We can simply do CreateFunctor(1, 2, &http_200) since we know the |
| // tab handle and request id, but using WithArgs<> is much more fancy :) |
| .WillOnce(testing::WithArgs<0, 0>(testing::Invoke(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::ReplyStarted, |
| &ExternalTabUITestMockClient::http_200)))); |
| |
| // Return some trivial page, that have a link to a "logo.gif" image |
| const std::string data = "<!DOCTYPE html><title>Hello</title>" |
| "<img src=\"logo.gif\">"; |
| |
| EXPECT_CALL(*mock_, OnRequestRead(2, testing::Gt(0))) |
| .Times(2) |
| .WillOnce(testing::InvokeWithoutArgs(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::ReplyData, &data, 1, 2))) |
| .WillOnce(testing::WithArgs<0, 0>(testing::Invoke(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::ReplyEOF)))); |
| |
| // Expect navigation is ok. |
| EXPECT_CALL(*mock_, OnDidNavigate(testing::Field(&NavigationInfo::url, |
| GURL(url)))) |
| .Times(1); |
| |
| // Expect GET request for logo.gif |
| EXPECT_CALL(*mock_, OnRequestStart(3, testing::AllOf( |
| testing::Field(&AutomationURLRequest::url, StrEq(url + "/logo.gif")), |
| testing::Field(&AutomationURLRequest::method, StrEq("GET"))))) |
| .Times(1) |
| .WillOnce(testing::InvokeWithoutArgs(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::Reply404, 1, 3))); |
| |
| EXPECT_CALL(*mock_, OnRequestRead(3, testing::Gt(0))) |
| .Times(1); |
| |
| // Chrome makes a brave request for favicon.ico |
| EXPECT_CALL(*mock_, OnRequestStart(4, testing::AllOf( |
| testing::Field(&AutomationURLRequest::url, |
| StrEq(url + "/favicon.ico")), |
| testing::Field(&AutomationURLRequest::method, StrEq("GET"))))) |
| .Times(1) |
| .WillOnce(testing::DoAll( |
| testing::InvokeWithoutArgs(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::Reply404, 1, 4)), |
| testing::InvokeWithoutArgs(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::DestroyHostWindow)))); |
| |
| EXPECT_CALL(*mock_, HandleClosed(1)).Times(1); |
| |
| EXPECT_CALL(*mock_, OnRequestRead(4, testing::Gt(0))) |
| .Times(1) |
| .WillOnce(QUIT_LOOP_SOON(&loop, 300)); |
| |
| tab = mock_->CreateTabWithUrl(GURL(url)); |
| loop.RunFor(TestTimeouts::action_max_timeout_ms()); |
| } |
| |
| // Flaky, http://crbug.com/61023. |
| TEST_F(ExternalTabUITest, FLAKY_HostNetworkStackAbortRequest) { |
| scoped_refptr<TabProxy> tab; |
| TimedMessageLoopRunner loop(MessageLoop::current()); |
| ASSERT_THAT(mock_, testing::NotNull()); |
| EXPECT_CALL(*mock_, OnNavigationStateChanged(_, _)) |
| .Times(testing::AnyNumber()); |
| |
| std::string url = "http://placetogo.org"; |
| |
| testing::InSequence sequence; |
| EXPECT_CALL(*mock_, OnRequestStart(2, testing::AllOf( |
| testing::Field(&AutomationURLRequest::url, StrEq(url + "/")), |
| testing::Field(&AutomationURLRequest::method, StrEq("GET"))))) |
| .Times(1) |
| // We can simply do CreateFunctor(1, 2, &http_200) since we know the |
| // tab handle and request id, but using WithArgs<> is much more fancy :) |
| .WillOnce(testing::WithArgs<0, 0>(testing::Invoke(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::ReplyStarted, |
| &ExternalTabUITestMockClient::http_200)))); |
| |
| // Return some trivial page, that have a link to a "logo.gif" image |
| const std::string data = "<!DOCTYPE html><title>Hello"; |
| |
| EXPECT_CALL(*mock_, OnRequestRead(2, testing::Gt(0))) |
| .Times(2) |
| .WillOnce(testing::InvokeWithoutArgs(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::ReplyData, &data, 1, 2))) |
| .WillOnce(testing::WithArgs<0, 0>( |
| testing::InvokeWithoutArgs(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::DestroyHostWindow)))); |
| |
| EXPECT_CALL(*mock_, HandleClosed(1)).Times(1); |
| |
| EXPECT_CALL(*mock_, OnRequestEnd(2, testing::_)) |
| .Times(1) |
| .WillOnce(QUIT_LOOP_SOON(&loop, 300)); |
| |
| tab = mock_->CreateTabWithUrl(GURL(url)); |
| loop.RunFor(TestTimeouts::action_max_timeout_ms()); |
| } |
| |
| // Flaky, http://crbug.com/61023. |
| TEST_F(ExternalTabUITest, FLAKY_HostNetworkStackUnresponsiveRenderer) { |
| scoped_refptr<TabProxy> tab; |
| TimedMessageLoopRunner loop(MessageLoop::current()); |
| ASSERT_THAT(mock_, testing::NotNull()); |
| EXPECT_CALL(*mock_, OnNavigationStateChanged(_, _)) |
| .Times(testing::AnyNumber()); |
| EXPECT_CALL(*mock_, OnLoad(_)).Times(testing::AnyNumber()); |
| |
| std::string url = "http://placetogo.org"; |
| |
| EXPECT_CALL(*mock_, OnRequestStart(3, testing::_)) |
| .Times(testing::AnyNumber()); |
| EXPECT_CALL(*mock_, OnDidNavigate(_)).Times(testing::AnyNumber()); |
| |
| testing::InSequence sequence; |
| EXPECT_CALL(*mock_, OnRequestStart(2, testing::AllOf( |
| testing::Field(&AutomationURLRequest::url, StrEq(url + "/")), |
| testing::Field(&AutomationURLRequest::method, StrEq("GET"))))) |
| .Times(1) |
| // We can simply do CreateFunctor(1, 2, &http_200) since we know the |
| // tab handle and request id, but using WithArgs<> is much more fancy :) |
| .WillOnce(testing::WithArgs<0, 0>(testing::Invoke(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::ReplyStarted, |
| &ExternalTabUITestMockClient::http_200)))); |
| |
| const std::string head = "<html><title>Hello</title><body>"; |
| |
| const std::string data = "<table border=\"1\"><tr><th>Month</th>" |
| "<th>Savings</th></tr><tr><td>January</td>" |
| "<td>$100</td></tr><tr><td>February</td>" |
| "<td>$100</td></tr><tr><td>March</td>" |
| "<td>$100</td></tr><tr><td>April</td>" |
| "<td>$100</td></tr><tr><td>May</td>" |
| "<td>$100</td></tr><tr><td>June</td>" |
| "<td>$100</td></tr><tr><td>July</td>" |
| "<td>$100</td></tr><tr><td>Aug</td>" |
| "<td>$100</td></tr><tr><td>Sept</td>" |
| "<td>$100</td></tr><tr><td>Oct</td>" |
| "<td>$100</td></tr><tr><td>Nov</td>" |
| "<td>$100</td></tr><tr><td>Dec</td>" |
| "<td>$100</td></tr></table>"; |
| |
| const std::string tail = "</body></html>"; |
| |
| EXPECT_CALL(*mock_, OnRequestRead(2, testing::Gt(0))) |
| .Times(1) |
| .WillOnce(testing::InvokeWithoutArgs(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::ReplyData, &head, 1, 2))); |
| |
| EXPECT_CALL(*mock_, OnRequestRead(2, testing::Gt(0))) |
| .Times(100) |
| .WillRepeatedly(testing::InvokeWithoutArgs(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::ReplyData, &data, 1, 2))); |
| |
| EXPECT_CALL(*mock_, OnRequestRead(2, testing::Gt(0))) |
| .Times(testing::AnyNumber()) |
| .WillOnce(testing::DoAll( |
| testing::InvokeWithoutArgs(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::ReplyData, &tail, 1, 2)), |
| testing::InvokeWithoutArgs(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::ReplyEOF, 1, 2)), |
| QUIT_LOOP_SOON(&loop, 300))); |
| EXPECT_CALL(*mock_, HandleClosed(1)).Times(1); |
| |
| tab = mock_->CreateTabWithUrl(GURL(url)); |
| loop.RunFor(TestTimeouts::action_max_timeout_ms()); |
| mock_->DestroyHostWindow(); |
| } |
| |
| class ExternalTabUITestPopupEnabled : public ExternalTabUITest { |
| public: |
| ExternalTabUITestPopupEnabled() { |
| launch_arguments_.AppendSwitch(switches::kDisablePopupBlocking); |
| } |
| }; |
| |
| #if defined(OS_WIN) |
| // http://crbug.com/61023 - Fails on one popular operating system. |
| #define MAYBE_WindowDotOpen FLAKY_WindowDotOpen |
| #define MAYBE_UserGestureTargetBlank FLAKY_UserGestureTargetBlank |
| #else |
| #define MAYBE_WindowDotOpen WindowDotOpen |
| #define MAYBE_UserGestureTargetBlank UserGestureTargetBlank |
| #endif |
| |
| // Testing AutomationMsg_AttachExternalTab callback from Chrome. |
| // Open a popup window with window.open() call. The created popup window opens |
| // another popup window (again using window.open() call). |
| TEST_F(ExternalTabUITestPopupEnabled, MAYBE_WindowDotOpen) { |
| TimedMessageLoopRunner loop(MessageLoop::current()); |
| ASSERT_THAT(mock_, testing::NotNull()); |
| mock_->IgnoreFaviconNetworkRequest(); |
| // Ignore navigation state changes. |
| EXPECT_CALL(*mock_, OnNavigationStateChanged(_, _)) |
| .Times(testing::AnyNumber()); |
| EXPECT_CALL(*mock_, OnDidNavigate(_)).Times(testing::AnyNumber()); |
| |
| GURL main_url("http://placetogo.com/"); |
| std::string main_html = |
| "<html><head><script type='text/javascript' language='JavaScript'>" |
| "window.open('popup1.html','','toolbar=no,menubar=no,location=yes," |
| "height=320,width=300,left=1');" |
| "</script></head><body>Main.</body></html>"; |
| mock_->ServeHTMLData(1, main_url, main_html); |
| EXPECT_CALL(*mock_, OnLoad(_)).Times(1); |
| |
| GURL popup1_url("http://placetogo.com/popup1.html"); |
| std::string popup1_html = |
| "<html><head><script type='text/javascript' language='JavaScript'>" |
| "window.open('popup2.html','','');" |
| "</script></head><body>Popup1.</body></html>"; |
| mock_->ServeHTMLData(2, popup1_url, popup1_html); |
| EXPECT_CALL(*mock_, OnLoad(_)).Times(1); |
| |
| GURL popup2_url("http://placetogo.com/popup2.html"); |
| std::string popup2_html = "<html><body>Popup2.</body></html>"; |
| mock_->ServeHTMLData(3, popup2_url, popup2_html); |
| EXPECT_CALL(*mock_, OnLoad(_)).Times(1) |
| .WillOnce(QUIT_LOOP_SOON(&loop, 500)); |
| |
| DWORD style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN; |
| HWND popup1_host = CreateWindowW(L"Button", L"popup1_host", style, |
| CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, |
| NULL, NULL, NULL, NULL); |
| |
| HWND popup2_host = CreateWindowW(L"Button", L"popup2_host", style, |
| CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, |
| NULL, NULL, NULL, NULL); |
| |
| EXPECT_CALL(*mock_, OnAttachExternalTab(_)) |
| .Times(1) |
| .WillOnce(testing::WithArgs<0>(testing::Invoke(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::ConnectToExternalTab, popup1_host)))); |
| |
| EXPECT_CALL(*mock_, OnAttachExternalTab(_)) |
| .Times(1) |
| .WillOnce(testing::WithArgs<0>(testing::Invoke(CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::ConnectToExternalTab, popup2_host)))); |
| |
| mock_->CreateTabWithUrl(main_url); |
| |
| loop.RunFor(TestTimeouts::action_max_timeout_ms()); |
| |
| EXPECT_CALL(*mock_, HandleClosed(1)); |
| EXPECT_CALL(*mock_, HandleClosed(2)); |
| EXPECT_CALL(*mock_, HandleClosed(3)); |
| |
| mock_->DestroyHostWindow(); |
| ::DestroyWindow(popup1_host); |
| ::DestroyWindow(popup2_host); |
| } |
| |
| // Open a new window by simulating a user gesture through keyboard. |
| TEST_F(ExternalTabUITestPopupEnabled, MAYBE_UserGestureTargetBlank) { |
| TimedMessageLoopRunner loop(MessageLoop::current()); |
| ASSERT_THAT(mock_, testing::NotNull()); |
| mock_->IgnoreFaviconNetworkRequest(); |
| // Ignore navigation state changes. |
| EXPECT_CALL(*mock_, OnNavigationStateChanged(_, _)) |
| .Times(testing::AnyNumber()); |
| EXPECT_CALL(*mock_, OnDidNavigate(_)).Times(testing::AnyNumber()); |
| |
| GURL main_url("http://placetogo.com/"); |
| std::string main_html = "<!DOCTYPE html><title>Hello</title>" |
| "<a href='http://foo.com/' target='_blank'>Link</a>"; |
| mock_->ServeHTMLData(1, main_url, main_html); |
| |
| HWND foo_host = CreateWindowW(L"Button", L"foo_host", |
| WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, |
| CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL); |
| |
| testing::InSequence s; |
| EXPECT_CALL(*mock_, OnLoad(_)) |
| .WillOnce(testing::InvokeWithoutArgs(testing::CreateFunctor(mock_, |
| &ExternalTabUITestMockClient::NavigateThroughUserGesture))); |
| |
| EXPECT_CALL(*mock_, OnAttachExternalTab(_)) |
| .Times(1) |
| .WillOnce(QUIT_LOOP_SOON(&loop, 500)); |
| |
| mock_->CreateTabWithUrl(main_url); |
| loop.RunFor(TestTimeouts::action_max_timeout_ms()); |
| |
| EXPECT_CALL(*mock_, HandleClosed(1)); |
| ::DestroyWindow(foo_host); |
| mock_->DestroyHostWindow(); |
| } |
| #endif // defined(OS_WIN) |
| |
| // Flaky especially on Windows. See crbug.com/25039. |
| TEST_F(AutomationProxyTest, FLAKY_AppModalDialogTest) { |
| scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(browser.get()); |
| scoped_refptr<TabProxy> tab(browser->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| |
| bool modal_dialog_showing = false; |
| ui::MessageBoxFlags::DialogButton button = |
| ui::MessageBoxFlags::DIALOGBUTTON_NONE; |
| EXPECT_TRUE(automation()->GetShowingAppModalDialog(&modal_dialog_showing, |
| &button)); |
| EXPECT_FALSE(modal_dialog_showing); |
| EXPECT_EQ(ui::MessageBoxFlags::DIALOGBUTTON_NONE, button); |
| |
| // Show a simple alert. |
| std::string content = |
| "data:text/html,<html><head><script>function onload() {" |
| "setTimeout(\"alert('hello');\", 1000); }</script></head>" |
| "<body onload='onload()'></body></html>"; |
| ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, |
| tab->NavigateToURL(GURL(content))); |
| EXPECT_TRUE(automation()->WaitForAppModalDialog()); |
| EXPECT_TRUE(automation()->GetShowingAppModalDialog(&modal_dialog_showing, |
| &button)); |
| EXPECT_TRUE(modal_dialog_showing); |
| EXPECT_EQ(ui::MessageBoxFlags::DIALOGBUTTON_OK, button); |
| |
| // Test that clicking missing button fails graciously and does not close the |
| // dialog. |
| EXPECT_FALSE(automation()->ClickAppModalDialogButton( |
| ui::MessageBoxFlags::DIALOGBUTTON_CANCEL)); |
| EXPECT_TRUE(automation()->GetShowingAppModalDialog(&modal_dialog_showing, |
| &button)); |
| EXPECT_TRUE(modal_dialog_showing); |
| |
| // Now click OK, that should close the dialog. |
| EXPECT_TRUE(automation()->ClickAppModalDialogButton( |
| ui::MessageBoxFlags::DIALOGBUTTON_OK)); |
| EXPECT_TRUE(automation()->GetShowingAppModalDialog(&modal_dialog_showing, |
| &button)); |
| EXPECT_FALSE(modal_dialog_showing); |
| |
| // Show a confirm dialog. |
| content = |
| "data:text/html,<html><head><script>var result = -1; function onload() {" |
| "setTimeout(\"result = confirm('hello') ? 0 : 1;\", 1000);} </script>" |
| "</head><body onload='onload()'></body></html>"; |
| ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, |
| tab->NavigateToURL(GURL(content))); |
| EXPECT_TRUE(automation()->WaitForAppModalDialog()); |
| EXPECT_TRUE(automation()->GetShowingAppModalDialog(&modal_dialog_showing, |
| &button)); |
| EXPECT_TRUE(modal_dialog_showing); |
| EXPECT_EQ(ui::MessageBoxFlags::DIALOGBUTTON_OK | |
| ui::MessageBoxFlags::DIALOGBUTTON_CANCEL, button); |
| |
| // Click OK. |
| EXPECT_TRUE(automation()->ClickAppModalDialogButton( |
| ui::MessageBoxFlags::DIALOGBUTTON_OK)); |
| EXPECT_TRUE(automation()->GetShowingAppModalDialog(&modal_dialog_showing, |
| &button)); |
| EXPECT_FALSE(modal_dialog_showing); |
| int result = -1; |
| EXPECT_TRUE(tab->ExecuteAndExtractInt( |
| std::wstring(), |
| L"window.domAutomationController.send(result);", &result)); |
| EXPECT_EQ(0, result); |
| |
| // Try again. |
| ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, |
| tab->NavigateToURL(GURL(content))); |
| EXPECT_TRUE(automation()->WaitForAppModalDialog()); |
| EXPECT_TRUE(automation()->GetShowingAppModalDialog(&modal_dialog_showing, |
| &button)); |
| EXPECT_TRUE(modal_dialog_showing); |
| EXPECT_EQ(ui::MessageBoxFlags::DIALOGBUTTON_OK | |
| ui::MessageBoxFlags::DIALOGBUTTON_CANCEL, button); |
| |
| // Click Cancel this time. |
| EXPECT_TRUE(automation()->ClickAppModalDialogButton( |
| ui::MessageBoxFlags::DIALOGBUTTON_CANCEL)); |
| EXPECT_TRUE(automation()->GetShowingAppModalDialog(&modal_dialog_showing, |
| &button)); |
| EXPECT_FALSE(modal_dialog_showing); |
| EXPECT_TRUE(tab->ExecuteAndExtractInt( |
| std::wstring(), |
| L"window.domAutomationController.send(result);", &result)); |
| EXPECT_EQ(1, result); |
| } |
| |
| class AutomationProxyTest5 : public UITest { |
| protected: |
| AutomationProxyTest5() { |
| show_window_ = true; |
| dom_automation_enabled_ = true; |
| // We need to disable popup blocking to ensure that the RenderView |
| // instance for the popup actually closes. |
| launch_arguments_.AppendSwitch(switches::kDisablePopupBlocking); |
| } |
| }; |
| |
| TEST_F(AutomationProxyTest5, TestLifetimeOfDomAutomationController) { |
| scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(window.get()); |
| |
| scoped_refptr<TabProxy> tab(window->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| |
| FilePath filename(test_data_directory_); |
| filename = filename.AppendASCII("dom_automation_test_with_popup.html"); |
| |
| ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, |
| tab->NavigateToURL(net::FilePathToFileURL(filename))); |
| |
| // Allow some time for the popup to show up and close. |
| base::PlatformThread::Sleep(TestTimeouts::action_timeout_ms()); |
| |
| std::wstring expected(L"string"); |
| std::wstring jscript = CreateJSString(L"\"" + expected + L"\""); |
| std::wstring actual; |
| ASSERT_TRUE(tab->ExecuteAndExtractString(L"", jscript, &actual)); |
| ASSERT_EQ(expected, actual); |
| } |
| |
| class AutomationProxySnapshotTest : public UITest { |
| protected: |
| AutomationProxySnapshotTest() { |
| dom_automation_enabled_ = true; |
| if (!snapshot_dir_.CreateUniqueTempDir()) |
| ADD_FAILURE() << "Unable to create temporary directory"; |
| else |
| snapshot_path_ = snapshot_dir_.path().AppendASCII("snapshot.png"); |
| } |
| |
| // Asserts that the given png file can be read and decoded into the given |
| // bitmap. |
| void AssertReadPNG(const FilePath& filename, SkBitmap* bitmap) { |
| DCHECK(bitmap); |
| ASSERT_TRUE(file_util::PathExists(filename)); |
| |
| int64 size64; |
| ASSERT_TRUE(file_util::GetFileSize(filename, &size64)); |
| // Check that the file is not too big to read in (less than 100 MB). |
| ASSERT_LT(size64, 1024 * 1024 * 100); |
| |
| // Read and decode image. |
| int size = static_cast<int>(size64); |
| scoped_array<char> data(new char[size]); |
| int bytes_read = file_util::ReadFile(filename, &data[0], size); |
| ASSERT_EQ(size, bytes_read); |
| ASSERT_TRUE(gfx::PNGCodec::Decode( |
| reinterpret_cast<unsigned char*>(&data[0]), |
| bytes_read, |
| bitmap)); |
| } |
| |
| // Returns the file path for the directory for these tests appended with |
| // the given relative path. |
| FilePath GetTestFilePath(const std::string& relative_path) { |
| FilePath filename(test_data_directory_); |
| return filename.AppendASCII("automation_proxy_snapshot") |
| .AppendASCII(relative_path); |
| } |
| |
| GURL GetTestUrl(const std::string& relative_path, const std::string& query) { |
| FilePath file_path = GetTestFilePath(relative_path); |
| return ui_test_utils::GetFileUrlWithQuery(file_path, query); |
| } |
| |
| FilePath snapshot_path_; |
| ScopedTempDir snapshot_dir_; |
| }; |
| |
| // See http://crbug.com/63022. |
| #if defined(OS_LINUX) |
| #define MAYBE_ContentLargerThanView FAILS_ContentLargerThanView |
| #else |
| #define MAYBE_ContentLargerThanView ContentLargerThanView |
| #endif |
| // Tests that taking a snapshot when the content is larger than the view |
| // produces a snapshot equal to the content size. |
| TEST_F(AutomationProxySnapshotTest, MAYBE_ContentLargerThanView) { |
| scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(browser.get()); |
| |
| // Resize the window to guarantee that the content is larger than the view. |
| scoped_refptr<WindowProxy> window(browser->GetWindow()); |
| ASSERT_TRUE(window.get()); |
| ASSERT_TRUE(window->SetBounds(gfx::Rect(300, 400))); |
| |
| scoped_refptr<TabProxy> tab(browser->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| |
| ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, |
| tab->NavigateToURL(GetTestUrl("set_size.html", "600,800"))); |
| |
| ASSERT_TRUE(tab->CaptureEntirePageAsPNG(snapshot_path_)); |
| |
| SkBitmap bitmap; |
| ASSERT_NO_FATAL_FAILURE(AssertReadPNG(snapshot_path_, &bitmap)); |
| ASSERT_EQ(600, bitmap.width()); |
| ASSERT_EQ(800, bitmap.height()); |
| } |
| |
| // Tests taking a large snapshot works. |
| TEST_F(AutomationProxySnapshotTest, LargeSnapshot) { |
| scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(browser.get()); |
| |
| scoped_refptr<TabProxy> tab(browser->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| |
| // 2000x2000 creates an approximately 15 MB bitmap. |
| // Don't increase this too much. At least my linux box has SHMMAX set at |
| // 32 MB. |
| ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, |
| tab->NavigateToURL(GetTestUrl("set_size.html", "2000,2000"))); |
| |
| ASSERT_TRUE(tab->CaptureEntirePageAsPNG(snapshot_path_)); |
| |
| SkBitmap bitmap; |
| ASSERT_NO_FATAL_FAILURE(AssertReadPNG(snapshot_path_, &bitmap)); |
| ASSERT_EQ(2000, bitmap.width()); |
| ASSERT_EQ(2000, bitmap.height()); |
| } |
| |
| #if defined(OS_MACOSX) |
| // Most pixels on mac are slightly off. |
| #define MAYBE_ContentsCorrect DISABLED_ContentsCorrect |
| #elif defined(OS_LINUX) |
| // See http://crbug.com/63022. |
| #define MAYBE_ContentsCorrect FAILS_ContentsCorrect |
| #else |
| #define MAYBE_ContentsCorrect ContentsCorrect |
| #endif |
| |
| // Tests that the snapshot contents are correct. |
| TEST_F(AutomationProxySnapshotTest, MAYBE_ContentsCorrect) { |
| scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); |
| ASSERT_TRUE(browser.get()); |
| |
| const gfx::Size img_size(400, 300); |
| scoped_refptr<WindowProxy> window(browser->GetWindow()); |
| ASSERT_TRUE(window.get()); |
| ASSERT_TRUE(window->SetBounds(gfx::Rect(img_size))); |
| |
| scoped_refptr<TabProxy> tab(browser->GetTab(0)); |
| ASSERT_TRUE(tab.get()); |
| |
| ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, |
| tab->NavigateToURL(GetTestUrl("just_image.html", ""))); |
| |
| ASSERT_TRUE(tab->CaptureEntirePageAsPNG(snapshot_path_)); |
| |
| SkBitmap snapshot_bmp; |
| ASSERT_NO_FATAL_FAILURE(AssertReadPNG(snapshot_path_, &snapshot_bmp)); |
| ASSERT_EQ(img_size.width(), snapshot_bmp.width()); |
| ASSERT_EQ(img_size.height(), snapshot_bmp.height()); |
| |
| SkBitmap reference_bmp; |
| ASSERT_NO_FATAL_FAILURE(AssertReadPNG(GetTestFilePath("image.png"), |
| &reference_bmp)); |
| ASSERT_EQ(img_size.width(), reference_bmp.width()); |
| ASSERT_EQ(img_size.height(), reference_bmp.height()); |
| |
| SkAutoLockPixels lock_snapshot(snapshot_bmp); |
| SkAutoLockPixels lock_reference(reference_bmp); |
| int diff_pixels_count = 0; |
| for (int x = 0; x < img_size.width(); ++x) { |
| for (int y = 0; y < img_size.height(); ++y) { |
| if (*snapshot_bmp.getAddr32(x, y) != *reference_bmp.getAddr32(x, y)) { |
| ++diff_pixels_count; |
| } |
| } |
| } |
| ASSERT_EQ(diff_pixels_count, 0); |
| } |