diff options
author | amit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-11 22:33:58 +0000 |
---|---|---|
committer | amit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-11 22:33:58 +0000 |
commit | f5cde2b583d923436f728660e18e181f83cfa602 (patch) | |
tree | c419f1b05a7525bdd7b24d86641974e45a8f1237 /chrome/test | |
parent | 279cd421c952d1581b4ac9bbc977e5f08b45d3b3 (diff) | |
download | chromium_src-f5cde2b583d923436f728660e18e181f83cfa602.zip chromium_src-f5cde2b583d923436f728660e18e181f83cfa602.tar.gz chromium_src-f5cde2b583d923436f728660e18e181f83cfa602.tar.bz2 |
ExternalTabcontainer browser to initial URL
Browse the newly created external tab to the specified initial URL
if present, to about:blank otherwise. Also send information about
SSL status when sending navigation updates to the automation client.
BUG=none
TEST=CreateExternalTabWithUrl UI test
Review URL: http://codereview.chromium.org/193054
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26037 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test')
-rw-r--r-- | chrome/test/automation/automation_messages.h | 19 | ||||
-rw-r--r-- | chrome/test/automation/automation_proxy_uitest.cc | 388 | ||||
-rw-r--r-- | chrome/test/automation/automation_proxy_uitest.h | 70 |
3 files changed, 302 insertions, 175 deletions
diff --git a/chrome/test/automation/automation_messages.h b/chrome/test/automation/automation_messages.h index 01d3a3f..416d168 100644 --- a/chrome/test/automation/automation_messages.h +++ b/chrome/test/automation/automation_messages.h @@ -325,6 +325,7 @@ struct ExternalTabSettings { bool is_off_the_record; bool load_requests_via_automation; bool handle_top_level_requests; + GURL initial_url; }; // Traits for ExternalTabSettings structure to pack/unpack. @@ -338,6 +339,7 @@ struct ParamTraits<ExternalTabSettings> { WriteParam(m, p.is_off_the_record); WriteParam(m, p.load_requests_via_automation); WriteParam(m, p.handle_top_level_requests); + WriteParam(m, p.initial_url); } static bool Read(const Message* m, void** iter, param_type* p) { return ReadParam(m, iter, &p->parent) && @@ -345,7 +347,8 @@ struct ParamTraits<ExternalTabSettings> { ReadParam(m, iter, &p->style) && ReadParam(m, iter, &p->is_off_the_record) && ReadParam(m, iter, &p->load_requests_via_automation) && - ReadParam(m, iter, &p->handle_top_level_requests); + ReadParam(m, iter, &p->handle_top_level_requests) && + ReadParam(m, iter, &p->initial_url); } static void Log(const param_type& p, std::wstring* l) { l->append(L"("); @@ -360,6 +363,8 @@ struct ParamTraits<ExternalTabSettings> { LogParam(p.load_requests_via_automation, l); l->append(L", "); LogParam(p.handle_top_level_requests, l); + l->append(L", "); + LogParam(p.initial_url, l); l->append(L")"); } }; @@ -370,6 +375,8 @@ struct NavigationInfo { int navigation_index; std::wstring title; GURL url; + SecurityStyle security_style; + bool has_mixed_content; }; // Traits for NavigationInfo structure to pack/unpack. @@ -382,13 +389,17 @@ struct ParamTraits<NavigationInfo> { WriteParam(m, p.navigation_index); WriteParam(m, p.title); WriteParam(m, p.url); + WriteParam(m, p.security_style); + WriteParam(m, p.has_mixed_content); } static bool Read(const Message* m, void** iter, param_type* p) { return ReadParam(m, iter, &p->navigation_type) && ReadParam(m, iter, &p->relative_offset) && ReadParam(m, iter, &p->navigation_index) && ReadParam(m, iter, &p->title) && - ReadParam(m, iter, &p->url); + ReadParam(m, iter, &p->url) && + ReadParam(m, iter, &p->security_style) && + ReadParam(m, iter, &p->has_mixed_content); } static void Log(const param_type& p, std::wstring* l) { l->append(L"("); @@ -401,6 +412,10 @@ struct ParamTraits<NavigationInfo> { LogParam(p.title, l); l->append(L", "); LogParam(p.url, l); + l->append(L", "); + LogParam(p.security_style, l); + l->append(L", "); + LogParam(p.has_mixed_content, l); l->append(L")"); } }; diff --git a/chrome/test/automation/automation_proxy_uitest.cc b/chrome/test/automation/automation_proxy_uitest.cc index 2566bb8..b12ad63 100644 --- a/chrome/test/automation/automation_proxy_uitest.cc +++ b/chrome/test/automation/automation_proxy_uitest.cc @@ -655,54 +655,144 @@ TEST_F(AutomationProxyTest, BlockedPopupTest) { // TODO(port): Remove HWND if possible #if defined(OS_WIN) -// Creates a top-level window, makes the |external_tab_window| a child of -// that window and displays them. After displaying the windows the -// function enters a message loop that processes window messages as well -// as calling MessageLoop::current()->RunAllPending() to process any -// incoming IPC messages. The time_to_wait_ms parameter is the maximum -// time the loop will run. To end the loop earlier, post a quit message to -// the thread. -bool ExternalTabMessageLoop(HWND external_tab_window, int time_to_wait_ms) { - static const wchar_t class_name[] = L"External_Tab_UI_Test_Class"; - static const wchar_t window_title[] = L"External Tab Tester"; - - WNDCLASSEX wnd_class = {0}; - wnd_class.cbSize = sizeof(wnd_class); - wnd_class.style = CS_HREDRAW | CS_VREDRAW; - wnd_class.lpfnWndProc = DefWindowProc; - wnd_class.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); - wnd_class.lpszClassName = class_name; - ATOM atom = RegisterClassEx(&wnd_class); - if (0 == atom) { - NOTREACHED() << "RegisterClassEx"; - return false; +static const wchar_t class_name[] = L"External_Tab_UI_Test_Class"; +static const wchar_t window_title[] = L"External Tab Tester"; + +AutomationProxyForExternalTab::AutomationProxyForExternalTab( + int execution_timeout) + : AutomationProxy(execution_timeout), + messages_received_(0), + navigate_complete_(false), + quit_after_(QUIT_INVALID), + host_window_class_(NULL), + host_window_(NULL) { +} + +AutomationProxyForExternalTab::~AutomationProxyForExternalTab() { + DestroyHostWindow(); + UnregisterClassW(host_window_class_, NULL); +} + +gfx::NativeWindow AutomationProxyForExternalTab::CreateHostWindow() { + DCHECK(!IsWindow(host_window_)); + if (!host_window_class_) { + WNDCLASSEX wnd_class = {0}; + wnd_class.cbSize = sizeof(wnd_class); + wnd_class.style = CS_HREDRAW | CS_VREDRAW; + wnd_class.lpfnWndProc = DefWindowProc; + wnd_class.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wnd_class.lpszClassName = class_name; + host_window_class_ = reinterpret_cast<const wchar_t*>( + RegisterClassEx(&wnd_class)); + if (!host_window_class_) { + NOTREACHED() << "RegisterClassEx failed. Error: " << GetLastError(); + return false; + } } unsigned long style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN; - HWND external_tab_ui_parent = CreateWindow(class_name, window_title, - style, CW_USEDEFAULT, 0, - CW_USEDEFAULT, 0, NULL, NULL, - NULL, NULL); - style = GetWindowLong(external_tab_window, GWL_STYLE); - style |= WS_CHILD; - style &= ~WS_POPUP; - SetWindowLong(external_tab_window, GWL_STYLE, style); - SetParent(external_tab_window, external_tab_ui_parent); - RECT client_rect = {0}; - GetClientRect(external_tab_ui_parent, &client_rect); - SetWindowPos(external_tab_window, NULL, 0, 0, client_rect.right, - client_rect.bottom, SWP_NOZORDER); - ShowWindow(external_tab_window, SW_SHOW); - ShowWindow(external_tab_ui_parent, SW_SHOW); + host_window_ = CreateWindow(host_window_class_, window_title, style, + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, + NULL, NULL, NULL); + if (!host_window_) { + NOTREACHED() << "CreateWindow failed. Error: " << GetLastError(); + return false; + } - // Allow the renderers to connect. + ShowWindow(host_window_, SW_SHOW); + return host_window_; +} + +scoped_refptr<TabProxy> AutomationProxyForExternalTab::CreateTabWithHostWindow( + bool is_incognito, const GURL& initial_url, + gfx::NativeWindow* container_wnd, gfx::NativeWindow* tab_wnd) { + DCHECK(container_wnd); + DCHECK(tab_wnd); + + CreateHostWindow(); + EXPECT_NE(FALSE, ::IsWindow(host_window_)); + + RECT client_area = {0}; + GetClientRect(host_window_, &client_area); + + const IPC::ExternalTabSettings settings = { + host_window_, + gfx::Rect(client_area), + WS_CHILD | WS_VISIBLE, + is_incognito, + false, + false, + initial_url + }; + + scoped_refptr<TabProxy> tab(CreateExternalTab(settings, container_wnd, + tab_wnd)); + + EXPECT_TRUE(tab != NULL); + EXPECT_NE(FALSE, ::IsWindow(*container_wnd)); + EXPECT_NE(FALSE, ::IsWindow(*tab_wnd)); + return tab; +} + +void AutomationProxyForExternalTab::DestroyHostWindow() { + if (host_window_) { + DestroyWindow(host_window_); + host_window_ = NULL; + } +} + +bool AutomationProxyForExternalTab::WaitForNavigation(int timeout_ms) { + set_quit_after(AutomationProxyForExternalTab::QUIT_AFTER_NAVIGATION); + return RunMessageLoop(timeout_ms, NULL); +} + +bool AutomationProxyForExternalTab::WaitForMessage(int timeout_ms) { + set_quit_after(AutomationProxyForExternalTab::QUIT_AFTER_MESSAGE); + return RunMessageLoop(timeout_ms, NULL); +} + +bool AutomationProxyForExternalTab::WaitForTabCleanup(TabProxy* tab, + int timeout_ms) { + DCHECK(tab); + base::Time end_time = + base::Time::Now() + TimeDelta::FromMilliseconds(timeout_ms); + while (base::Time::Now() < end_time) { + const int kWaitInterval = 50; + DWORD wait_result = MsgWaitForMultipleObjects(0, NULL, FALSE, kWaitInterval, + QS_ALLINPUT); + if (!tab->is_valid()) + break; + if (WAIT_OBJECT_0 == wait_result) { + MSG msg = {0}; + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + + return !tab->is_valid(); +} + +bool AutomationProxyForExternalTab::RunMessageLoop( + int timeout_ms, + gfx::NativeWindow window_to_monitor) { + // If there's no host window then the abort or this loop will be stuck + // in GetMessage + if (!IsWindow(host_window_)) + return false; + // Allow the renderers to connect. const int kTimerIdQuit = 100; const int kTimerIdProcessPendingMessages = 101; - ::SetTimer(external_tab_ui_parent, kTimerIdQuit, time_to_wait_ms, NULL); - // Process pending messages every 50 milliseconds - ::SetTimer(external_tab_ui_parent, kTimerIdProcessPendingMessages, 50, NULL); + if (!window_to_monitor) + window_to_monitor = host_window_; + + UINT_PTR quit_timer = ::SetTimer(host_window_, kTimerIdQuit, + timeout_ms, NULL); + UINT_PTR pump_timer = ::SetTimer(host_window_, + kTimerIdProcessPendingMessages, 50, NULL); MSG msg; bool quit = false; @@ -711,56 +801,29 @@ bool ExternalTabMessageLoop(HWND external_tab_window, int time_to_wait_ms) { if (!ok || ok == -1) break; - if (msg.message == WM_TIMER && msg.hwnd == external_tab_ui_parent) { + if (msg.message == WM_TIMER && msg.hwnd == host_window_) { switch (msg.wParam) { case kTimerIdProcessPendingMessages: MessageLoop::current()->RunAllPending(); break; - case kTimerIdQuit: - ::KillTimer(external_tab_ui_parent, msg.wParam); quit = true; break; - default: NOTREACHED() << "invalid timer id"; break; } - } else if (msg.message == WM_QUIT) { + } else if ((msg.message == WM_QUIT) || (msg.message == kQuitLoopMessage)) { quit = true; } else { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } - // In case there's an interactive user that closes the window. - } while (!quit && ::IsWindow(external_tab_ui_parent)); - - DestroyWindow(external_tab_ui_parent); - - EXPECT_TRUE(UnregisterClassW(reinterpret_cast<const wchar_t*>(atom), - wnd_class.hInstance)); + } while (!quit && ::IsWindow(window_to_monitor)); - return true; -} - -AutomationProxyForExternalTab::AutomationProxyForExternalTab( - int execution_timeout) - : AutomationProxy(execution_timeout), - messages_received_(0), - navigate_complete_(false) { -} - -bool AutomationProxyForExternalTab::WaitForNavigationComplete( - int max_time_to_wait_ms) { - base::TimeTicks start(base::TimeTicks::Now()); - while (!navigate_complete_) { - PlatformThread::Sleep(50); - MessageLoop::current()->RunAllPending(); - base::TimeTicks end(base::TimeTicks::Now()); - base::TimeDelta delta = end - start; - if (static_cast<int>(delta.InMilliseconds()) > max_time_to_wait_ms) - return false; - } + KillTimer(host_window_, quit_timer); + KillTimer(host_window_, pump_timer); + quit_after_ = QUIT_INVALID; return true; } @@ -772,6 +835,14 @@ void AutomationProxyForExternalTab::OnMessageReceived(const IPC::Message& msg) { IPC_END_MESSAGE_MAP() } +void AutomationProxyForExternalTab::OnDidNavigate( + int tab_handle, + const IPC::NavigationInfo& nav_info) { + navigate_complete_ = true; + if (QUIT_AFTER_NAVIGATION == quit_after_) + QuitLoop(); +} + void AutomationProxyForExternalTab::OnForwardMessageToExternalHost( int handle, const std::string& message, @@ -781,65 +852,95 @@ void AutomationProxyForExternalTab::OnForwardMessageToExternalHost( message_ = message; origin_ = origin; target_ = target; - PostQuitMessage(0); + + if (QUIT_AFTER_MESSAGE == quit_after_) + QuitLoop(); } -TEST_F(ExternalTabTestType, CreateExternalTab) { - const IPC::ExternalTabSettings settings = { - NULL, - gfx::Rect(), - WS_POPUP, - false, - false - }; +GURL simple_data_url = GURL(std::string( + "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>")); + +// Create with specifying a url +TEST_F(ExternalTabTestType, CreateExternalTab1) { + AutomationProxyForExternalTab* proxy = + static_cast<AutomationProxyForExternalTab*>(automation()); HWND external_tab_container = NULL; HWND tab_wnd = NULL; + scoped_refptr<TabProxy> tab(proxy->CreateTabWithHostWindow(false, + simple_data_url, &external_tab_container, &tab_wnd)); - scoped_refptr<TabProxy> tab(automation()->CreateExternalTab(settings, - &external_tab_container, &tab_wnd)); - EXPECT_TRUE(tab != NULL); - EXPECT_NE(FALSE, ::IsWindow(external_tab_container)); + EXPECT_TRUE(tab->is_valid()); if (tab != NULL) { - tab->NavigateInExternalTab(GURL(L"http://www.google.com")); - EXPECT_EQ(true, ExternalTabMessageLoop(external_tab_container, 1000)); - // Since the tab goes away lazily, wait a bit - PlatformThread::Sleep(1000); + EXPECT_TRUE(proxy->WaitForNavigation(action_max_timeout_ms())); + + proxy->DestroyHostWindow(); + proxy->WaitForTabCleanup(tab, action_max_timeout_ms()); + EXPECT_FALSE(tab->is_valid()); + EXPECT_EQ(FALSE, ::IsWindow(external_tab_container)); + EXPECT_EQ(FALSE, ::IsWindow(tab_wnd)); + } +} + +// Create with empty url and then navigate +TEST_F(ExternalTabTestType, CreateExternalTab2) { + AutomationProxyForExternalTab* proxy = + static_cast<AutomationProxyForExternalTab*>(automation()); + HWND external_tab_container = NULL; + HWND tab_wnd = NULL; + scoped_refptr<TabProxy> tab(proxy->CreateTabWithHostWindow(false, + GURL(), &external_tab_container, &tab_wnd)); + + // Enter a message loop to allow the tab to be created + proxy->WaitForNavigation(2000); + EXPECT_TRUE(tab->is_valid()); + + if (tab != NULL) { + // Wait for navigation + tab->NavigateInExternalTab(simple_data_url); + EXPECT_TRUE(proxy->WaitForNavigation(action_max_timeout_ms())); + + // Now destroy the external tab + proxy->DestroyHostWindow(); + proxy->WaitForTabCleanup(tab, action_max_timeout_ms()); + + EXPECT_FALSE(tab->is_valid()); + EXPECT_EQ(FALSE, ::IsWindow(external_tab_container)); + EXPECT_EQ(FALSE, ::IsWindow(tab_wnd)); } } TEST_F(ExternalTabTestType, IncognitoMode) { - IPC::ExternalTabSettings settings = { - NULL, - gfx::Rect(), - WS_POPUP, - true, - false, - false - }; + AutomationProxyForExternalTab* proxy = + static_cast<AutomationProxyForExternalTab*>(automation()); HWND external_tab_container = NULL; HWND tab_wnd = NULL; + + // Create incognito tab GURL url("http://anatomyofmelancholy.net"); + scoped_refptr<TabProxy> tab(proxy->CreateTabWithHostWindow(true, url, + &external_tab_container, &tab_wnd)); + EXPECT_TRUE(proxy->WaitForNavigation(action_max_timeout_ms())); + std::string value_result; - // Create incognito tab - scoped_refptr<TabProxy> tab(automation()->CreateExternalTab(settings, - &external_tab_container, &tab_wnd)); EXPECT_TRUE(tab->SetCookie(url, "robert=burton; " "expires=Thu, 13 Oct 2011 05:04:03 UTC;")); EXPECT_TRUE(tab->GetCookieByName(url, "robert", &value_result)); EXPECT_EQ("burton", value_result); - tab = NULL; + proxy->DestroyHostWindow(); CloseBrowserAndServer(); + tab = NULL; value_result.clear(); clear_profile_ = false; external_tab_container = NULL; tab_wnd = NULL; LaunchBrowserAndServer(); - settings.is_off_the_record = false; - tab = automation()->CreateExternalTab(settings, &external_tab_container, - &tab_wnd); + tab = proxy->CreateTabWithHostWindow(false, url, &external_tab_container, + &tab_wnd); EXPECT_TRUE(tab->GetCookieByName(url, "robert", &value_result)); EXPECT_EQ("", value_result); } @@ -847,39 +948,29 @@ TEST_F(ExternalTabTestType, IncognitoMode) { TEST_F(ExternalTabTestType, ExternalTabPostMessage) { AutomationProxyForExternalTab* proxy = static_cast<AutomationProxyForExternalTab*>(automation()); - - IPC::ExternalTabSettings settings = { - NULL, - gfx::Rect(), - WS_POPUP, - false, - false, - false - }; HWND external_tab_container = NULL; HWND tab_wnd = NULL; - scoped_refptr<TabProxy> tab(proxy->CreateExternalTab(settings, - &external_tab_container, &tab_wnd)); - EXPECT_TRUE(tab != NULL); - EXPECT_NE(FALSE, ::IsWindow(external_tab_container)); + 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>"; + scoped_refptr<TabProxy> tab(proxy->CreateTabWithHostWindow(false, + GURL(content), &external_tab_container, &tab_wnd)); + if (tab != NULL) { - 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>"; - tab->NavigateInExternalTab(GURL(content)); - EXPECT_TRUE(proxy->WaitForNavigationComplete(10000)); + // Wait for navigation + EXPECT_TRUE(proxy->WaitForNavigation(action_max_timeout_ms())); tab->HandleMessageFromExternalHost("Hello from gtest", "null", "*"); + EXPECT_TRUE(proxy->WaitForMessage(5000)); - EXPECT_TRUE(ExternalTabMessageLoop(external_tab_container, 10000)); EXPECT_NE(0, proxy->messages_received()); if (proxy->messages_received()) { @@ -889,31 +980,21 @@ TEST_F(ExternalTabTestType, ExternalTabPostMessage) { } TEST_F(ExternalTabTestType, ExternalTabPostMessageTarget) { + const wchar_t kDocRoot[] = L"chrome/test/data/external_tab"; + scoped_refptr<HTTPTestServer> server( + HTTPTestServer::CreateServer(kDocRoot, NULL)); + + const char kTestUrl[] = "http://localhost:1337/files/post_message.html"; + AutomationProxyForExternalTab* proxy = static_cast<AutomationProxyForExternalTab*>(automation()); - - IPC::ExternalTabSettings settings = { - NULL, - gfx::Rect(), - WS_POPUP, - false, - false, - false - }; HWND external_tab_container = NULL; HWND tab_wnd = NULL; - scoped_refptr<TabProxy> tab(proxy->CreateExternalTab(settings, - &external_tab_container, &tab_wnd)); - EXPECT_TRUE(tab != NULL); - EXPECT_NE(FALSE, ::IsWindow(external_tab_container)); - if (tab != NULL) { - const wchar_t kDocRoot[] = L"chrome/test/data/external_tab"; - scoped_refptr<HTTPTestServer> server( - HTTPTestServer::CreateServer(kDocRoot, NULL)); + scoped_refptr<TabProxy> tab(proxy->CreateTabWithHostWindow(false, + GURL(kTestUrl), &external_tab_container, &tab_wnd)); - const char kTestUrl[] = "http://localhost:1337/files/post_message.html"; - tab->NavigateInExternalTab(GURL(kTestUrl)); - EXPECT_TRUE(proxy->WaitForNavigationComplete(10000)); + if (tab != NULL) { + EXPECT_TRUE(proxy->WaitForNavigation(action_max_timeout_ms())); // Post a message to the page, specifying a target. // If the page receives it, it will post the same message right back to us. @@ -922,7 +1003,7 @@ TEST_F(ExternalTabTestType, ExternalTabPostMessageTarget) { tab->HandleMessageFromExternalHost(kTestMessage, kTestOrigin, "http://localhost:1337/"); - EXPECT_TRUE(ExternalTabMessageLoop(external_tab_container, 10000)); + EXPECT_TRUE(proxy->WaitForMessage(5000)); EXPECT_NE(0, proxy->messages_received()); if (proxy->messages_received()) { @@ -931,7 +1012,6 @@ TEST_F(ExternalTabTestType, ExternalTabPostMessageTarget) { } } } - #endif // defined(OS_WIN) // TODO(port): Need to port autocomplete_edit_proxy.* first. diff --git a/chrome/test/automation/automation_proxy_uitest.h b/chrome/test/automation/automation_proxy_uitest.h index 692fbc9..7ca2662 100644 --- a/chrome/test/automation/automation_proxy_uitest.h +++ b/chrome/test/automation/automation_proxy_uitest.h @@ -7,6 +7,7 @@ #include <string> +#include "base/gfx/native_widget_types.h" #include "base/message_loop.h" #include "base/platform_thread.h" #include "base/time.h" @@ -14,6 +15,8 @@ #include "chrome/test/ui/ui_test.h" #include "googleurl/src/gurl.h" +class TabProxy; + // Base class for automation proxy testing. class AutomationProxyVisibleTest : public UITest { protected: @@ -46,7 +49,17 @@ class CustomAutomationProxyTest : public AutomationProxyVisibleTest { // was received. class AutomationProxyForExternalTab : public AutomationProxy { public: + // Allows us to reuse this mock for multiple tests. This is done + // by setting a state to trigger posting of Quit message to the + // wait loop. + enum QuitAfter { + QUIT_INVALID, + QUIT_AFTER_NAVIGATION, + QUIT_AFTER_MESSAGE, + }; + explicit AutomationProxyForExternalTab(int execution_timeout); + ~AutomationProxyForExternalTab(); int messages_received() const { return messages_received_; @@ -64,17 +77,46 @@ class AutomationProxyForExternalTab : public AutomationProxy { return target_; } - // Waits for the DidNavigate event to be processed on the current thread. - // Returns true if the event arrived, false if there was a timeout. - bool WaitForNavigationComplete(int max_time_to_wait_ms); + // Creates and sisplays a top-level window, that can be used as a parent + // to the external tab.window. + gfx::NativeWindow CreateHostWindow(); + scoped_refptr<TabProxy> CreateTabWithHostWindow(bool is_incognito, + const GURL& initial_url, gfx::NativeWindow* container_wnd, + gfx::NativeWindow* tab_wnd); + void DestroyHostWindow(); + + // Wait for the event to happen or timeout + bool WaitForNavigation(int timeout_ms); + bool WaitForMessage(int timeout_ms); + bool WaitForTabCleanup(TabProxy* tab, int timeout_ms); + + // Enters a message loop that processes window messages as well + // as calling MessageLoop::current()->RunAllPending() to process any + // incoming IPC messages. The timeout_ms parameter is the maximum + // time the loop will run. To end the loop earlier, post a quit message to + // the thread. + bool RunMessageLoop(int timeout_ms, gfx::NativeWindow window_to_monitor); protected: - virtual void OnMessageReceived(const IPC::Message& msg); +#if defined(OS_WIN) + static const int kQuitLoopMessage = WM_APP + 11; + // Quit the message loop + void QuitLoop() { + DCHECK(IsWindow(host_window_)); + // We could post WM_QUIT but lets keep it out of accidental usage + // by anyone else peeking it. + PostMessage(host_window_, kQuitLoopMessage, 0, 0); + } +#endif // defined(OS_WIN) - void OnDidNavigate(int tab_handle, const IPC::NavigationInfo& nav_info) { - navigate_complete_ = true; + // Internal state to flag posting of a quit message to the loop + void set_quit_after(QuitAfter q) { + quit_after_ = q; } + virtual void OnMessageReceived(const IPC::Message& msg); + + void OnDidNavigate(int tab_handle, const IPC::NavigationInfo& nav_info); void OnForwardMessageToExternalHost(int handle, const std::string& message, const std::string& origin, @@ -84,23 +126,13 @@ class AutomationProxyForExternalTab : public AutomationProxy { bool navigate_complete_; int messages_received_; std::string message_, origin_, target_; + QuitAfter quit_after_; + const wchar_t* host_window_class_; + gfx::NativeWindow host_window_; }; // A test harness for testing external tabs. typedef CustomAutomationProxyTest<AutomationProxyForExternalTab> ExternalTabTestType; -#if defined(OS_WIN) -// Custom message loop for external tab testing. -// -// Creates a window and makes external_tab_window (the external tab's -// window handle) a child of that window. -// -// The time_to_wait_ms parameter is the maximum time the loop will run. To -// end the loop earlier, post a quit message (using the Win32 -// PostQuitMessage API) to the thread. -bool ExternalTabMessageLoop(HWND external_tab_window, - int time_to_wait_ms); -#endif // defined(OS_WIN) - #endif // CHROME_TEST_AUTOMATION_AUTOMATION_PROXY_UITEST_H__ |