diff options
Diffstat (limited to 'chrome_frame/test')
-rw-r--r-- | chrome_frame/test/chrome_frame_test_utils.cc | 52 | ||||
-rw-r--r-- | chrome_frame/test/chrome_frame_test_utils.h | 37 | ||||
-rw-r--r-- | chrome_frame/test/chrome_frame_unittests.cc | 133 | ||||
-rw-r--r-- | chrome_frame/test/data/cf_protocol.html | 2 | ||||
-rw-r--r-- | chrome_frame/test/data/chrome_frame_tester_helpers.js | 2 | ||||
-rw-r--r-- | chrome_frame/test/data/navigate_out.html | 2 | ||||
-rw-r--r-- | chrome_frame/test/reliability/page_load_test.cc | 8 |
7 files changed, 194 insertions, 42 deletions
diff --git a/chrome_frame/test/chrome_frame_test_utils.cc b/chrome_frame/test/chrome_frame_test_utils.cc index faee92a..0b8176d 100644 --- a/chrome_frame/test/chrome_frame_test_utils.cc +++ b/chrome_frame/test/chrome_frame_test_utils.cc @@ -690,6 +690,13 @@ _ATL_FUNC_INFO WebBrowserEventSink::kBeforeNavigate2Info = { } }; +_ATL_FUNC_INFO WebBrowserEventSink::kNewWindow2Info = { + CC_STDCALL, VT_EMPTY, 2, { + VT_DISPATCH | VT_BYREF, + VT_BOOL | VT_BYREF, + } +}; + _ATL_FUNC_INFO WebBrowserEventSink::kNewWindow3Info = { CC_STDCALL, VT_EMPTY, 5, { VT_DISPATCH | VT_BYREF, @@ -711,6 +718,15 @@ _ATL_FUNC_INFO WebBrowserEventSink::kDocumentCompleteInfo = { }; // WebBrowserEventSink member defines +void WebBrowserEventSink::Attach(IDispatch* browser_disp) { + EXPECT_TRUE(NULL != browser_disp); + if(browser_disp) { + EXPECT_HRESULT_SUCCEEDED(web_browser2_.QueryFrom(browser_disp)); + EXPECT_TRUE(S_OK == DispEventAdvise(web_browser2_, + &DIID_DWebBrowserEvents2)); + } +} + void WebBrowserEventSink::Uninitialize() { DisconnectFromChromeFrame(); if (web_browser2_.get()) { @@ -745,6 +761,34 @@ STDMETHODIMP_(void) WebBrowserEventSink::OnDocumentCompleteInternal( OnDocumentComplete(dispatch, url); } +STDMETHODIMP_(void) WebBrowserEventSink::OnNewWindow3Internal( + IDispatch** dispatch, VARIANT_BOOL* cancel, DWORD flags, BSTR url_context, + BSTR url) { + DLOG(INFO) << __FUNCTION__; + if (!dispatch) { + NOTREACHED() << "Invalid argument - dispatch"; + return; + } + + // Call the OnNewWindow3 with original args + OnNewWindow3(dispatch, cancel, flags, url_context, url); + + // Note that |dispatch| is an [in/out] argument. IE is asking listeners if + // they want to use a IWebBrowser2 of their choice for the new window. + // Since we need to listen on events on the new browser, we create one + // if needed. + if (!*dispatch) { + ScopedComPtr<IDispatch> new_browser; + HRESULT hr = new_browser.CreateInstance(CLSID_InternetExplorer, NULL, + CLSCTX_LOCAL_SERVER); + DCHECK(SUCCEEDED(hr) && new_browser); + *dispatch = new_browser.Detach(); + } + + if (*dispatch) + OnNewBrowserWindow(*dispatch, url); +} + HRESULT WebBrowserEventSink::OnLoadInternal(const VARIANT* param) { DLOG(INFO) << __FUNCTION__ << " " << param->bstrVal; OnLoad(param->bstrVal); @@ -788,14 +832,12 @@ HRESULT WebBrowserEventSink::Navigate(const std::wstring& navigate_url) { } void WebBrowserEventSink::SetFocusToChrome() { - chrome_frame_test::SetKeyboardFocusToWindow( - GetAttachedChromeRendererWindow(), 1, 1); + chrome_frame_test::SetKeyboardFocusToWindow(GetTabWindow(), 1, 1); } void WebBrowserEventSink::SendInputToChrome( const std::string& input_string) { - chrome_frame_test::SendInputToWindow( - GetAttachedChromeRendererWindow(), input_string); + chrome_frame_test::SendInputToWindow(GetTabWindow(), input_string); } void WebBrowserEventSink::ConnectToChromeFrame() { @@ -833,7 +875,7 @@ void WebBrowserEventSink::DisconnectFromChromeFrame() { } } -HWND WebBrowserEventSink::GetAttachedChromeRendererWindow() { +HWND WebBrowserEventSink::GetTabWindow() { DCHECK(chrome_frame_); HWND renderer_window = NULL; ScopedComPtr<IOleWindow> ole_window; diff --git a/chrome_frame/test/chrome_frame_test_utils.h b/chrome_frame/test/chrome_frame_test_utils.h index 57e356c..1cc6e82 100644 --- a/chrome_frame/test/chrome_frame_test_utils.h +++ b/chrome_frame/test/chrome_frame_test_utils.h @@ -177,6 +177,7 @@ class WebBrowserEventSink Uninitialize(); } + void Attach(IDispatch* browser_disp); void Uninitialize(); // Helper function to launch IE and navigate to a URL. @@ -205,8 +206,10 @@ BEGIN_SINK_MAP(WebBrowserEventSink) OnNavigateComplete2Internal, &kNavigateComplete2Info) SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_NAVIGATEERROR, OnNavigateError, &kNavigateErrorInfo) + SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_NEWWINDOW2, + OnNewWindow2, &kNewWindow2Info) SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_NEWWINDOW3, - OnNewWindow3, &kNewWindow3Info) + OnNewWindow3Internal, &kNewWindow3Info) SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentCompleteInternal, &kDocumentCompleteInfo) END_SINK_MAP() @@ -224,21 +227,11 @@ END_SINK_MAP() return S_OK; } - STDMETHOD(OnBeforeNavigate2Internal)(IDispatch* dispatch, VARIANT* url, - VARIANT* flags, - VARIANT* target_frame_name, - VARIANT* post_data, VARIANT* headers, - VARIANT_BOOL* cancel); STDMETHOD_(void, OnDownloadBegin)() {} - STDMETHOD_(void, OnNavigateComplete2Internal)(IDispatch* dispatch, - VARIANT* url); STDMETHOD_(void, OnNavigateComplete2)(IDispatch* dispatch, VARIANT* url) {} - STDMETHOD_(void, OnNewWindow3)(IDispatch** dispatch, VARIANT_BOOL* Cancel, + STDMETHOD_(void, OnNewWindow2)(IDispatch** dispatch, VARIANT_BOOL* cancel) {} + STDMETHOD_(void, OnNewWindow3)(IDispatch** dispatch, VARIANT_BOOL* cancel, DWORD flags, BSTR url_context, BSTR url) {} - - STDMETHOD_(void, OnDocumentCompleteInternal)(IDispatch* dispatch, - VARIANT* url); - STDMETHOD_(void, OnDocumentComplete)(IDispatch* dispatch, VARIANT* url) {} #ifdef _DEBUG @@ -260,9 +253,24 @@ END_SINK_MAP() return web_browser2_.get(); } + virtual void OnNewBrowserWindow(IDispatch* new_window, const wchar_t* url) {} + HRESULT SetWebBrowser(IWebBrowser2* web_browser2); protected: + STDMETHOD(OnBeforeNavigate2Internal)(IDispatch* dispatch, VARIANT* url, + VARIANT* flags, + VARIANT* target_frame_name, + VARIANT* post_data, VARIANT* headers, + VARIANT_BOOL* cancel); + STDMETHOD_(void, OnNavigateComplete2Internal)(IDispatch* dispatch, + VARIANT* url); + STDMETHOD_(void, OnDocumentCompleteInternal)(IDispatch* dispatch, + VARIANT* url); + STDMETHOD_(void, OnNewWindow3Internal)(IDispatch** dispatch, + VARIANT_BOOL* Cancel, DWORD flags, + BSTR url_context, BSTR url); + // IChromeFrame callbacks HRESULT OnLoadInternal(const VARIANT* param); HRESULT OnLoadErrorInternal(const VARIANT* param); @@ -270,7 +278,7 @@ END_SINK_MAP() void ConnectToChromeFrame(); void DisconnectFromChromeFrame(); - HWND GetAttachedChromeRendererWindow(); + HWND GetTabWindow(); public: ScopedComPtr<IWebBrowser2> web_browser2_; @@ -283,6 +291,7 @@ END_SINK_MAP() static _ATL_FUNC_INFO kBeforeNavigate2Info; static _ATL_FUNC_INFO kNavigateComplete2Info; static _ATL_FUNC_INFO kNavigateErrorInfo; + static _ATL_FUNC_INFO kNewWindow2Info; static _ATL_FUNC_INFO kNewWindow3Info; static _ATL_FUNC_INFO kVoidMethodInfo; static _ATL_FUNC_INFO kDocumentCompleteInfo; diff --git a/chrome_frame/test/chrome_frame_unittests.cc b/chrome_frame/test/chrome_frame_unittests.cc index f343ff2c..fa63ab6 100644 --- a/chrome_frame/test/chrome_frame_unittests.cc +++ b/chrome_frame/test/chrome_frame_unittests.cc @@ -9,6 +9,7 @@ // defined. #include <mshtml.h> #include <exdisp.h> +#include <mshtmcid.h> #include "base/basictypes.h" #include "base/file_version_info.h" @@ -24,6 +25,7 @@ #include "chrome_frame/test/chrome_frame_test_utils.h" #include "chrome_frame/test_utils.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/url_constants.h" #include "chrome/installer/util/install_util.h" #include "chrome/installer/util/helper.h" @@ -1238,11 +1240,15 @@ class MockWebBrowserEventSink : public chrome_frame_test::WebBrowserEventSink { MOCK_METHOD5_WITH_CALLTYPE(__stdcall, OnNewWindow3, void (IDispatch** dispatch, // NOLINT - VARIANT_BOOL* Cancel, + VARIANT_BOOL* cancel, DWORD flags, BSTR url_context, BSTR url)); + MOCK_METHOD2_WITH_CALLTYPE(__stdcall, OnNewWindow2, + void (IDispatch** dispatch, // NOLINT + VARIANT_BOOL* cancel)); + MOCK_METHOD5_WITH_CALLTYPE(__stdcall, OnNavigateError, void (IDispatch* dispatch, // NOLINT VARIANT* url, @@ -1253,11 +1259,13 @@ class MockWebBrowserEventSink : public chrome_frame_test::WebBrowserEventSink { MOCK_METHOD1(OnLoad, void (const wchar_t* url)); // NOLINT MOCK_METHOD1(OnLoadError, void (const wchar_t* url)); // NOLINT MOCK_METHOD1(OnMessage, void (const wchar_t* message)); // NOLINT + MOCK_METHOD2(OnNewBrowserWindow, void (IDispatch* dispatch, // NOLINT + const wchar_t* url)); }; using testing::_; -const wchar_t kChromeFrameFileUrl[] = L"cf:file:///C:/"; +const wchar_t kChromeFrameFileUrl[] = L"gcf:file:///C:/"; TEST(ChromeFrameTest, FullTabModeIE_DisallowedUrls) { chrome_frame_test::TimedMsgLoop loop; @@ -1311,16 +1319,11 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_WindowOpenInChrome) { chrome_frame_test::TimedMsgLoop loop; CComObjectStackEx<MockWebBrowserEventSink> mock; - ::testing::InSequence sequence; - EXPECT_CALL(mock, - OnBeforeNavigate2( - _, testing::Field(&VARIANT::bstrVal, - testing::StrCaseEq(kChromeFrameFullTabWindowOpenTestUrl)), - _, _, _, _, _)) - .WillOnce(testing::Return(S_OK)); - EXPECT_CALL(mock, OnNavigateComplete2(_, _)) - .WillOnce(testing::Return()); - + // NOTE: + // Intentionally not in sequence since we have just one navigation + // per mock, it's OK to be not in sequence as long as all the expections + // are satisfied. Moreover, since the second mock expects a new window, + // its events happen in random order. EXPECT_CALL(mock, OnBeforeNavigate2( _, testing::Field(&VARIANT::bstrVal, @@ -1342,8 +1345,30 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_WindowOpenInChrome) { &chrome_frame_test::WebBrowserEventSink::SendInputToChrome, std::string("A")), 0)))); - EXPECT_CALL(mock, - OnNewWindow3(_, _, _, _, _)); + // Watch for new window + CComObjectStackEx<MockWebBrowserEventSink> new_window_mock; + // Can't really check URL here since it will be of the form gcf:attach... + EXPECT_CALL(mock, OnNewWindow3(_, _, _, _, _)); + EXPECT_CALL(mock, OnNewBrowserWindow(_, _)) + .WillOnce(testing::WithArgs<0>( + testing::Invoke(CreateFunctor(&new_window_mock, + &MockWebBrowserEventSink::Attach)))); + + // Expect navigations on the new mock + EXPECT_CALL(new_window_mock, OnBeforeNavigate2(_, _, _, _, _, _, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return(S_OK)); + EXPECT_CALL(new_window_mock, OnNavigateComplete2(_, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return()); + EXPECT_CALL(new_window_mock, + OnLoad(testing::StrEq(kChromeFrameFullTabWindowOpenPopupUrl))) + .WillOnce(testing::DoAll( + testing::InvokeWithoutArgs(CreateFunctor(&mock, + &MockWebBrowserEventSink::Uninitialize)), + testing::InvokeWithoutArgs(CreateFunctor(&new_window_mock, + &MockWebBrowserEventSink::Uninitialize)), + testing::IgnoreResult(testing::InvokeWithoutArgs( + &chrome_frame_test::CloseAllIEWindows)), + QUIT_LOOP_SOON(loop, 2))); HRESULT hr = mock.LaunchIEAndNavigate(kChromeFrameFullTabWindowOpenTestUrl); ASSERT_HRESULT_SUCCEEDED(hr); @@ -1363,10 +1388,10 @@ const wchar_t kSubFrameUrl1[] = L"http://localhost:1337/files/sub_frame1.html"; const wchar_t kChromeFrameAboutVersion[] = - L"cf:about:version"; + L"gcf:about:version"; // This test launches chrome frame in full tab mode in IE by having IE navigate -// to cf:about:blank. It then looks for the chrome renderer window and posts +// to gcf:about:blank. It then looks for the chrome renderer window and posts // the WM_RBUTTONDOWN/WM_RBUTTONUP messages to it, which bring up the context // menu. This is followed by keyboard messages sent via SendInput to select // the About chrome frame menu option, which would then bring up a new window @@ -1583,7 +1608,7 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_BackForward) { } -const wchar_t kChromeFrameAboutBlankUrl[] = L"cf:about:blank"; +const wchar_t kChromeFrameAboutBlankUrl[] = L"gcf:about:blank"; TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ChromeFrameFocusTest) { chrome_frame_test::TimedMsgLoop loop; @@ -1797,6 +1822,80 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_BackForwardAnchor) { chrome_frame_test::CloseAllIEWindows(); } +// Full tab mode view source test +// Launch and navigate chrome frame and invoke view source functionality +TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ViewSource) { + chrome_frame_test::TimedMsgLoop loop; + CComObjectStackEx<MockWebBrowserEventSink> mock; + CComObjectStackEx<MockWebBrowserEventSink> view_source_mock; + ::testing::InSequence sequence; // Everything in sequence + + // After navigation invoke view soruce action using IWebBrowser2::ExecWB + EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, + testing::StrCaseEq(kAnchorUrl)), + _, _, _, _, _)) + .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnNavigateComplete2(_, _)) + .WillOnce(testing::Return()); + EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, + testing::StrCaseEq(kAnchorUrl)), + _, _, _, _, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnNavigateComplete2(_, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return()); + + VARIANT empty = ScopedVariant::kEmptyVariant; + EXPECT_CALL(mock, OnLoad(testing::StrEq(kAnchorUrl))) + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs( + CreateFunctor(ReceivePointer(mock.web_browser2_), + &IWebBrowser2::ExecWB, + static_cast<OLECMDID>(IDM_VIEWSOURCE), + OLECMDEXECOPT_DONTPROMPTUSER, &empty, &empty)))); + + // Expect notification for view-source window, handle new window event + // and attach a new mock to the received web browser + std::wstring view_source_url; + view_source_url += UTF8ToWide(chrome::kViewSourceScheme); + view_source_url += L":"; + view_source_url += kAnchorUrl; + std::wstring url_in_new_window = kChromeProtocolPrefix; + url_in_new_window += view_source_url; + + EXPECT_CALL(mock, OnNewWindow3(_, _, _, _, + testing::StrCaseEq(url_in_new_window))); + EXPECT_CALL(mock, OnNewBrowserWindow(_, _)) + .WillOnce(testing::WithArgs<0>( + testing::Invoke(CreateFunctor(&view_source_mock, + &MockWebBrowserEventSink::Attach)))); + + // Expect navigations on the new mock + EXPECT_CALL(view_source_mock, OnBeforeNavigate2(_, + testing::Field(&VARIANT::bstrVal, + testing::StrCaseEq(url_in_new_window)), _, _, _, _, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return(S_OK)); + EXPECT_CALL(view_source_mock, OnNavigateComplete2(_, _)) + .WillOnce(testing::Return()); + EXPECT_CALL(view_source_mock, OnLoad(testing::StrEq(view_source_url))) + .WillOnce(testing::DoAll( + testing::InvokeWithoutArgs(CreateFunctor(&mock, + &MockWebBrowserEventSink::Uninitialize)), + testing::InvokeWithoutArgs(CreateFunctor(&view_source_mock, + &MockWebBrowserEventSink::Uninitialize)), + testing::IgnoreResult(testing::InvokeWithoutArgs( + &chrome_frame_test::CloseAllIEWindows)), + QUIT_LOOP_SOON(loop, 2))); + + HRESULT hr = mock.LaunchIEAndNavigate(kAnchorUrl); + ASSERT_HRESULT_SUCCEEDED(hr); + if (hr == S_FALSE) + return; + + ASSERT_TRUE(mock.web_browser2() != NULL); + loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds); + mock.Uninitialize(); + chrome_frame_test::CloseAllIEWindows(); +} + const wchar_t kChromeFrameFullTabModeXMLHttpRequestTestUrl[] = L"files/xmlhttprequest_test.html"; diff --git a/chrome_frame/test/data/cf_protocol.html b/chrome_frame/test/data/cf_protocol.html index 0036555..bee4055 100644 --- a/chrome_frame/test/data/cf_protocol.html +++ b/chrome_frame/test/data/cf_protocol.html @@ -15,6 +15,6 @@ </head>
<body onLoad="setTimeout(test, 100);">
<h2>Prepare to be redirected!</h2>
- <p>Redirects the same page to its 'cf:' version</p>
+ <p>Redirects the same page to its 'gcf:' version</p>
</body>
</html>
diff --git a/chrome_frame/test/data/chrome_frame_tester_helpers.js b/chrome_frame/test/data/chrome_frame_tester_helpers.js index f3ccd58..a6cc9c2 100644 --- a/chrome_frame/test/data/chrome_frame_tester_helpers.js +++ b/chrome_frame/test/data/chrome_frame_tester_helpers.js @@ -139,7 +139,7 @@ function isRunningInMSIE() { } function reloadUsingCFProtocol() { - var redirect_location = "cf:"; + var redirect_location = "gcf:"; redirect_location += window.location; window.location = redirect_location; } diff --git a/chrome_frame/test/data/navigate_out.html b/chrome_frame/test/data/navigate_out.html index 7b910b4..5f447c9 100644 --- a/chrome_frame/test/data/navigate_out.html +++ b/chrome_frame/test/data/navigate_out.html @@ -15,6 +15,6 @@ </head>
<body onLoad="setTimeout(test, 100);">
<h2>Prepare to be redirected!</h2>
- <p>Redirects the same page to its 'cf:' version and </p>
+ <p>Redirects the same page to its 'gcf:' version and </p>
</body>
</html>
diff --git a/chrome_frame/test/reliability/page_load_test.cc b/chrome_frame/test/reliability/page_load_test.cc index dd869e5..21fded4 100644 --- a/chrome_frame/test/reliability/page_load_test.cc +++ b/chrome_frame/test/reliability/page_load_test.cc @@ -133,9 +133,9 @@ class WebBrowserEventSinkImpl : public chrome_frame_test::WebBrowserEventSink { } virtual HRESULT Navigate(const std::wstring& navigate_url) { - if (StartsWith(navigate_url, L"cf:", true)) { + if (StartsWith(navigate_url, kChromeProtocolPrefix, true)) { is_chrome_frame_navigation_ = true; - url_ = navigate_url.substr(wcslen(L"cf:")); + url_ = navigate_url.substr(wcslen(kChromeProtocolPrefix)); } else { url_ = navigate_url; } @@ -349,7 +349,7 @@ class PageLoadTest : public testing::Test { // Every 3rd URL goes into the host browser. if (line_index % 3 != 0) { std::string actual_url; - actual_url = "cf:"; + actual_url = WideToUTF8(kChromeProtocolPrefix); actual_url += url_str; url_str = actual_url; } @@ -382,10 +382,12 @@ class PageLoadTest : public testing::Test { } SetConfigBool(kChromeFrameHeadlessMode, true); + SetConfigBool(kEnableGCFProtocol, true); } virtual void TearDown() { DeleteConfigValue(kChromeFrameHeadlessMode); + DeleteConfigValue(kEnableGCFProtocol); } FilePath ConstructSavedDebugLogPath(const FilePath& debug_log_path, |