Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: chrome/test/automation/automation_proxy_uitest.cc

Issue 468013: Get rid of ExternalTabAutomationProxy by switching the extension UI... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/test/automation/automation_proxy_uitest.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <string> 5 #include <string>
6 6
7 #include "app/app_switches.h" 7 #include "app/app_switches.h"
8 #include "app/l10n_util.h" 8 #include "app/l10n_util.h"
9 #include "app/message_box_flags.h" 9 #include "app/message_box_flags.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 11 matching lines...) Expand all
22 #include "chrome/test/automation/autocomplete_edit_proxy.h" 22 #include "chrome/test/automation/autocomplete_edit_proxy.h"
23 #include "chrome/test/automation/automation_messages.h" 23 #include "chrome/test/automation/automation_messages.h"
24 #include "chrome/test/automation/automation_proxy_uitest.h" 24 #include "chrome/test/automation/automation_proxy_uitest.h"
25 #include "chrome/test/automation/browser_proxy.h" 25 #include "chrome/test/automation/browser_proxy.h"
26 #include "chrome/test/automation/tab_proxy.h" 26 #include "chrome/test/automation/tab_proxy.h"
27 #include "chrome/test/automation/window_proxy.h" 27 #include "chrome/test/automation/window_proxy.h"
28 #include "chrome/test/ui_test_utils.h" 28 #include "chrome/test/ui_test_utils.h"
29 #include "chrome/test/ui/ui_test.h" 29 #include "chrome/test/ui/ui_test.h"
30 #include "net/base/net_util.h" 30 #include "net/base/net_util.h"
31 #include "net/url_request/url_request_unittest.h" 31 #include "net/url_request/url_request_unittest.h"
32 #include "testing/gmock/include/gmock/gmock.h"
33 #define GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING 32 #define GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
34 #include "testing/gmock_mutant.h" 33 #include "testing/gmock_mutant.h"
35 #include "views/event.h" 34 #include "views/event.h"
36 35
37 using ui_test_utils::TimedMessageLoopRunner; 36 using ui_test_utils::TimedMessageLoopRunner;
38 using testing::CreateFunctor; 37 using testing::CreateFunctor;
39 using testing::StrEq; 38 using testing::StrEq;
40 39
41 #if defined(OS_MACOSX) 40 #if defined(OS_MACOSX)
42 #define MAYBE_WindowGetViewBounds DISABLED_WindowGetViewBounds 41 #define MAYBE_WindowGetViewBounds DISABLED_WindowGetViewBounds
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 645
647 ASSERT_TRUE(tab->NavigateToURL(net::FilePathToFileURL(filename))); 646 ASSERT_TRUE(tab->NavigateToURL(net::FilePathToFileURL(filename)));
648 647
649 ASSERT_TRUE(tab->WaitForBlockedPopupCountToChangeTo(2, 5000)); 648 ASSERT_TRUE(tab->WaitForBlockedPopupCountToChangeTo(2, 5000));
650 } 649 }
651 650
652 #endif // defined(OS_WIN) 651 #endif // defined(OS_WIN)
653 652
654 // TODO(port): Remove HWND if possible 653 // TODO(port): Remove HWND if possible
655 #if defined(OS_WIN) 654 #if defined(OS_WIN)
656 static const wchar_t class_name[] = L"External_Tab_UI_Test_Class";
657 static const wchar_t window_title[] = L"External Tab Tester";
658
659 AutomationProxyForExternalTab::AutomationProxyForExternalTab(
660 int execution_timeout)
661 : AutomationProxy(execution_timeout),
662 messages_received_(0),
663 navigate_complete_(false),
664 quit_after_(QUIT_INVALID),
665 host_window_class_(NULL),
666 host_window_(NULL) {
667 }
668
669 AutomationProxyForExternalTab::~AutomationProxyForExternalTab() {
670 DestroyHostWindow();
671 UnregisterClassW(host_window_class_, NULL);
672 }
673
674 gfx::NativeWindow AutomationProxyForExternalTab::CreateHostWindow() {
675 DCHECK(!IsWindow(host_window_));
676 if (!host_window_class_) {
677 WNDCLASSEX wnd_class = {0};
678 wnd_class.cbSize = sizeof(wnd_class);
679 wnd_class.style = CS_HREDRAW | CS_VREDRAW;
680 wnd_class.lpfnWndProc = DefWindowProc;
681 wnd_class.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
682 wnd_class.lpszClassName = class_name;
683 host_window_class_ = reinterpret_cast<const wchar_t*>(
684 RegisterClassEx(&wnd_class));
685 if (!host_window_class_) {
686 NOTREACHED() << "RegisterClassEx failed. Error: " << GetLastError();
687 return false;
688 }
689 }
690
691 unsigned long style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
692 host_window_ = CreateWindow(host_window_class_, window_title, style,
693 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL,
694 NULL, NULL, NULL);
695 if (!host_window_) {
696 NOTREACHED() << "CreateWindow failed. Error: " << GetLastError();
697 return false;
698 }
699
700 ShowWindow(host_window_, SW_SHOW);
701 return host_window_;
702 }
703
704 scoped_refptr<TabProxy> AutomationProxyForExternalTab::CreateTabWithHostWindow(
705 bool is_incognito, const GURL& initial_url,
706 gfx::NativeWindow* container_wnd, gfx::NativeWindow* tab_wnd) {
707 DCHECK(container_wnd);
708 DCHECK(tab_wnd);
709
710 CreateHostWindow();
711 EXPECT_NE(FALSE, ::IsWindow(host_window_));
712
713 RECT client_area = {0};
714 GetClientRect(host_window_, &client_area);
715
716 const IPC::ExternalTabSettings settings = {
717 host_window_,
718 gfx::Rect(client_area),
719 WS_CHILD | WS_VISIBLE,
720 is_incognito,
721 false,
722 false,
723 initial_url
724 };
725
726 scoped_refptr<TabProxy> tab(CreateExternalTab(settings, container_wnd,
727 tab_wnd));
728
729 EXPECT_TRUE(tab != NULL);
730 EXPECT_NE(FALSE, ::IsWindow(*container_wnd));
731 EXPECT_NE(FALSE, ::IsWindow(*tab_wnd));
732 return tab;
733 }
734
735 void AutomationProxyForExternalTab::DestroyHostWindow() {
736 if (host_window_) {
737 DestroyWindow(host_window_);
738 host_window_ = NULL;
739 }
740 }
741
742 bool AutomationProxyForExternalTab::WaitForNavigation(int timeout_ms) {
743 set_quit_after(AutomationProxyForExternalTab::QUIT_AFTER_NAVIGATION);
744 return RunMessageLoop(timeout_ms, NULL);
745 }
746
747 bool AutomationProxyForExternalTab::WaitForMessage(int timeout_ms) {
748 set_quit_after(AutomationProxyForExternalTab::QUIT_AFTER_MESSAGE);
749 return RunMessageLoop(timeout_ms, NULL);
750 }
751
752 bool AutomationProxyForExternalTab::WaitForTabCleanup(TabProxy* tab,
753 int timeout_ms) {
754 DCHECK(tab);
755 base::Time end_time =
756 base::Time::Now() + TimeDelta::FromMilliseconds(timeout_ms);
757 while (base::Time::Now() < end_time) {
758 const int kWaitInterval = 50;
759 DWORD wait_result = MsgWaitForMultipleObjects(0, NULL, FALSE, kWaitInterval,
760 QS_ALLINPUT);
761 if (!tab->is_valid())
762 break;
763 if (WAIT_OBJECT_0 == wait_result) {
764 MSG msg = {0};
765 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
766 TranslateMessage(&msg);
767 DispatchMessage(&msg);
768 }
769 }
770 }
771
772 return !tab->is_valid();
773 }
774
775 bool AutomationProxyForExternalTab::RunMessageLoop(
776 int timeout_ms,
777 gfx::NativeWindow window_to_monitor) {
778 // If there's no host window then the abort or this loop will be stuck
779 // in GetMessage
780 if (!IsWindow(host_window_))
781 return false;
782
783 // Allow the renderers to connect.
784 const int kTimerIdQuit = 100;
785 const int kTimerIdProcessPendingMessages = 101;
786
787 if (!window_to_monitor)
788 window_to_monitor = host_window_;
789
790 UINT_PTR quit_timer = ::SetTimer(host_window_, kTimerIdQuit,
791 timeout_ms, NULL);
792 UINT_PTR pump_timer = ::SetTimer(host_window_,
793 kTimerIdProcessPendingMessages, 50, NULL);
794
795 MSG msg;
796 bool quit = false;
797 do {
798 BOOL ok = ::GetMessage(&msg, NULL, 0, 0);
799 if (!ok || ok == -1)
800 break;
801
802 if (msg.message == WM_TIMER && msg.hwnd == host_window_) {
803 switch (msg.wParam) {
804 case kTimerIdProcessPendingMessages:
805 MessageLoop::current()->RunAllPending();
806 break;
807 case kTimerIdQuit:
808 quit = true;
809 break;
810 default:
811 NOTREACHED() << "invalid timer id";
812 break;
813 }
814 } else if ((msg.message == WM_QUIT) || (msg.message == kQuitLoopMessage)) {
815 quit = true;
816 } else {
817 ::TranslateMessage(&msg);
818 ::DispatchMessage(&msg);
819 }
820 } while (!quit && ::IsWindow(window_to_monitor));
821
822 KillTimer(host_window_, quit_timer);
823 KillTimer(host_window_, pump_timer);
824 quit_after_ = QUIT_INVALID;
825 return true;
826 }
827
828 void AutomationProxyForExternalTab::OnMessageReceived(const IPC::Message& msg) {
829 IPC_BEGIN_MESSAGE_MAP(AutomationProxyForExternalTab, msg)
830 IPC_MESSAGE_HANDLER(AutomationMsg_DidNavigate, OnDidNavigate)
831 IPC_MESSAGE_HANDLER(AutomationMsg_ForwardMessageToExternalHost,
832 OnForwardMessageToExternalHost)
833 IPC_END_MESSAGE_MAP()
834 }
835
836 void AutomationProxyForExternalTab::OnDidNavigate(
837 int tab_handle,
838 const IPC::NavigationInfo& nav_info) {
839 navigate_complete_ = true;
840 if (QUIT_AFTER_NAVIGATION == quit_after_)
841 QuitLoop();
842 }
843
844 void AutomationProxyForExternalTab::OnForwardMessageToExternalHost(
845 int handle,
846 const std::string& message,
847 const std::string& origin,
848 const std::string& target) {
849 messages_received_++;
850 message_ = message;
851 origin_ = origin;
852 target_ = target;
853
854 if (QUIT_AFTER_MESSAGE == quit_after_)
855 QuitLoop();
856 }
857 655
858 const char simple_data_url[] = 656 const char simple_data_url[] =
859 "data:text/html,<html><head><title>External tab test</title></head>" 657 "data:text/html,<html><head><title>External tab test</title></head>"
860 "<body>A simple page for testing a floating/invisible tab<br></div>" 658 "<body>A simple page for testing a floating/invisible tab<br></div>"
861 "</body></html>"; 659 "</body></html>";
862 660
863 // We have to derive from AutomationProxy in order to hook up 661 ExternalTabUITestMockClient::ExternalTabUITestMockClient(int execution_timeout)
864 // OnMessageReceived callbacks. 662 : AutomationProxy(execution_timeout),
865 class ExternalTabUITestMockClient : public AutomationProxy { 663 host_window_(NULL) {
866 public: 664 }
867 explicit ExternalTabUITestMockClient(int execution_timeout)
868 : AutomationProxy(execution_timeout),
869 host_window_(NULL) {
870 }
871 665
872 MOCK_METHOD2(OnDidNavigate, void(int tab_handle, 666 void ExternalTabUITestMockClient::ReplyStarted(
873 const IPC::NavigationInfo& nav_info)); 667 const IPC::AutomationURLResponse* response,
874 MOCK_METHOD4(OnForwardMessageToExternalHost, void(int handle, 668 int tab_handle, int request_id) {
875 const std::string& message, const std::string& origin, 669 AutomationProxy::Send(new AutomationMsg_RequestStarted(0, tab_handle,
876 const std::string& target)); 670 request_id, *response));
877 MOCK_METHOD3(OnRequestStart, void(int tab_handle, int request_id, 671 }
878 const IPC::AutomationURLRequest& request));
879 MOCK_METHOD3(OnRequestRead, void(int tab_handle, int request_id,
880 int bytes_to_read));
881 MOCK_METHOD3(OnRequestEnd, void(int tab_handle, int request_id,
882 const URLRequestStatus& status));
883 MOCK_METHOD3(OnSetCookieAsync, void(int tab_handle, const GURL& url,
884 const std::string& cookie));
885 672
673 void ExternalTabUITestMockClient::ReplyData(
674 const std::string* data, int tab_handle, int request_id) {
675 AutomationProxy::Send(new AutomationMsg_RequestData(0, tab_handle,
676 request_id, *data));
677 }
886 678
887 MOCK_METHOD1(HandleClosed, void(int handle)); 679 void ExternalTabUITestMockClient::ReplyEOF(int tab_handle, int request_id) {
680 AutomationProxy::Send(new AutomationMsg_RequestEnd(0, tab_handle,
681 request_id,
682 URLRequestStatus()));
683 }
888 684
685 void ExternalTabUITestMockClient::Reply404(int tab_handle, int request_id) {
686 const IPC::AutomationURLResponse notfound = {"", "HTTP/1.1 404\r\n\r\n"};
687 ReplyStarted(&notfound, tab_handle, request_id);
688 ReplyEOF(tab_handle, request_id);
689 }
889 690
890 // Action helpers for OnRequest* incoming messages. Create the message and 691 void ExternalTabUITestMockClient::InvalidateHandle(
891 // delegate sending to the base class. Apparently we do not have wrappers 692 const IPC::Message& message) {
892 // in AutomationProxy for these messages. 693 void* iter = NULL;
893 void ReplyStarted(const IPC::AutomationURLResponse* response, 694 int handle;
894 int tab_handle, int request_id) { 695 ASSERT_TRUE(message.ReadInt(&iter, &handle));
895 AutomationProxy::Send(new AutomationMsg_RequestStarted(0, tab_handle,
896 request_id, *response));
897 }
898 696
899 void ReplyData(const std::string* data, int tab_handle, int request_id) { 697 // Call base class
900 AutomationProxy::Send(new AutomationMsg_RequestData(0, tab_handle, 698 AutomationProxy::InvalidateHandle(message);
901 request_id, *data)); 699 HandleClosed(handle);
902 } 700 }
903
904 void ReplyEOF(int tab_handle, int request_id) {
905 AutomationProxy::Send(new AutomationMsg_RequestEnd(0, tab_handle,
906 request_id,
907 URLRequestStatus()));
908 }
909
910 void Reply404(int tab_handle, int request_id) {
911 const IPC::AutomationURLResponse notfound = {"", "HTTP/1.1 404\r\n\r\n"};
912 ReplyStarted(&notfound, tab_handle, request_id);
913 ReplyEOF(tab_handle, request_id);
914 }
915
916 // Test setup helpers
917 scoped_refptr<TabProxy> CreateHostWindowAndTab(
918 const IPC::ExternalTabSettings& settings);
919 scoped_refptr<TabProxy> CreateTabWithUrl(const GURL& initial_url);
920 void DestroyHostWindow();
921
922 static const IPC::ExternalTabSettings default_settings;
923 protected:
924 HWND host_window_;
925
926 // Simple dispatcher to above OnXXX methods.
927 virtual void OnMessageReceived(const IPC::Message& msg);
928 virtual void InvalidateHandle(const IPC::Message& message) {
929 void* iter = NULL;
930 int handle;
931 ASSERT_TRUE(message.ReadInt(&iter, &handle));
932
933 // Call base class
934 AutomationProxy::InvalidateHandle(message);
935 HandleClosed(handle);
936 }
937 };
938 701
939 // Most of the time we need external tab with these settings. 702 // Most of the time we need external tab with these settings.
940 const IPC::ExternalTabSettings ExternalTabUITestMockClient::default_settings = { 703 const IPC::ExternalTabSettings ExternalTabUITestMockClient::default_settings = {
941 NULL, gfx::Rect(), // will be replaced by CreateHostWindowAndTab 704 NULL, gfx::Rect(), // will be replaced by CreateHostWindowAndTab
942 WS_CHILD | WS_VISIBLE, 705 WS_CHILD | WS_VISIBLE,
943 false, // is_off_the_record 706 false, // is_off_the_record
944 true, // load_requests_via_automation 707 true, // load_requests_via_automation
945 true, // handle_top_level_requests 708 true, // handle_top_level_requests
946 GURL() // initial_url 709 GURL() // initial_url
947 }; 710 };
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 scoped_refptr<TabProxy> ExternalTabUITestMockClient::CreateTabWithUrl( 751 scoped_refptr<TabProxy> ExternalTabUITestMockClient::CreateTabWithUrl(
989 const GURL& initial_url) { 752 const GURL& initial_url) {
990 IPC::ExternalTabSettings settings = 753 IPC::ExternalTabSettings settings =
991 ExternalTabUITestMockClient::default_settings; 754 ExternalTabUITestMockClient::default_settings;
992 settings.initial_url = initial_url; 755 settings.initial_url = initial_url;
993 return CreateHostWindowAndTab(settings); 756 return CreateHostWindowAndTab(settings);
994 } 757 }
995 758
996 void ExternalTabUITestMockClient::DestroyHostWindow() { 759 void ExternalTabUITestMockClient::DestroyHostWindow() {
997 ::DestroyWindow(host_window_); 760 ::DestroyWindow(host_window_);
761 host_window_ = NULL;
998 } 762 }
999 763
764 bool ExternalTabUITestMockClient::HostWindowExists() {
765 return (host_window_ != NULL) && ::IsWindow(host_window_);
766 }
767
768
1000 // Handy macro 769 // Handy macro
1001 #define QUIT_LOOP(loop) testing::InvokeWithoutArgs(\ 770 #define QUIT_LOOP(loop) testing::InvokeWithoutArgs(\
1002 CreateFunctor(loop, &TimedMessageLoopRunner::Quit)) 771 CreateFunctor(loop, &TimedMessageLoopRunner::Quit))
1003 #define QUIT_LOOP_SOON(loop, ms) testing::InvokeWithoutArgs(\ 772 #define QUIT_LOOP_SOON(loop, ms) testing::InvokeWithoutArgs(\
1004 CreateFunctor(loop, &TimedMessageLoopRunner::QuitAfter, ms)) 773 CreateFunctor(loop, &TimedMessageLoopRunner::QuitAfter, ms))
1005 774
1006 template <typename T> T** ReceivePointer(scoped_ptr<T>& p) { // NOLINT 775 template <typename T> T** ReceivePointer(scoped_ptr<T>& p) { // NOLINT
1007 return reinterpret_cast<T**>(&p); 776 return reinterpret_cast<T**>(&p);
1008 } 777 }
1009 778
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 1171
1403 // Allow some time for the popup to show up and close. 1172 // Allow some time for the popup to show up and close.
1404 PlatformThread::Sleep(2000); 1173 PlatformThread::Sleep(2000);
1405 1174
1406 std::wstring expected(L"string"); 1175 std::wstring expected(L"string");
1407 std::wstring jscript = CreateJSString(L"\"" + expected + L"\""); 1176 std::wstring jscript = CreateJSString(L"\"" + expected + L"\"");
1408 std::wstring actual; 1177 std::wstring actual;
1409 ASSERT_TRUE(tab->ExecuteAndExtractString(L"", jscript, &actual)); 1178 ASSERT_TRUE(tab->ExecuteAndExtractString(L"", jscript, &actual));
1410 ASSERT_EQ(expected, actual); 1179 ASSERT_EQ(expected, actual);
1411 } 1180 }
OLDNEW
« no previous file with comments | « chrome/test/automation/automation_proxy_uitest.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698