diff options
author | tommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-17 04:24:49 +0000 |
---|---|---|
committer | tommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-17 04:24:49 +0000 |
commit | 7aa8d97a76a427986a30a48ed1ed2f8c4b463323 (patch) | |
tree | 90d236dfc722eac565fb430da49d2b94f07d2c5c /chrome_frame | |
parent | cbcf9cc32b5f6cd73e3b734b1c19248f6ac65fec (diff) | |
download | chromium_src-7aa8d97a76a427986a30a48ed1ed2f8c4b463323.zip chromium_src-7aa8d97a76a427986a30a48ed1ed2f8c4b463323.tar.gz chromium_src-7aa8d97a76a427986a30a48ed1ed2f8c4b463323.tar.bz2 |
Beginnings of a unit test for downloads that occur in a new window.
For now this works for IE regularly (no cf in the picture) and triggers a download in a new window.
It is disabled since support for this scenario is not yet ready in CF.
I'm adding a couple of things to WebBrowserEventSink:
- A way to gracefully close IE. This way we allow IE to quit on its own and don't go the "kill" route unless necessary.
This should help with reducing cases where we've killed IE and the next time it is started it presents the user with an "IE crashed" dialog which could cause subsequent unit tests to fail.
Another thing this adds is support for the OnQuit event that can be useful to add to unit tests as an expected event.
- A new OnFileDownload event. I also updated several tests to expect this event.
TEST=Adds a unit test.
BUG=none
Review URL: http://codereview.chromium.org/569011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39190 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame')
-rw-r--r-- | chrome_frame/test/chrome_frame_test_utils.cc | 90 | ||||
-rw-r--r-- | chrome_frame/test/chrome_frame_test_utils.h | 42 | ||||
-rw-r--r-- | chrome_frame/test/data/download_file.zip | bin | 0 -> 76992 bytes | |||
-rw-r--r-- | chrome_frame/test/data/full_tab_download_from_new_window.html | 18 | ||||
-rw-r--r-- | chrome_frame/test/test_mock_with_web_server.cc | 402 | ||||
-rw-r--r-- | chrome_frame/test/test_mock_with_web_server.h | 7 |
6 files changed, 429 insertions, 130 deletions
diff --git a/chrome_frame/test/chrome_frame_test_utils.cc b/chrome_frame/test/chrome_frame_test_utils.cc index 0fcf9ee..dc1f116 100644 --- a/chrome_frame/test/chrome_frame_test_utils.cc +++ b/chrome_frame/test/chrome_frame_test_utils.cc @@ -23,6 +23,8 @@ namespace chrome_frame_test { +const int kDefaultWaitForIEToTerminateMs = 10 * 1000; + const wchar_t kIEImageName[] = L"iexplore.exe"; const wchar_t kIEBrokerImageName[] = L"ieuser.exe"; const wchar_t kFirefoxImageName[] = L"firefox.exe"; @@ -325,6 +327,8 @@ HRESULT LaunchIEAsComServer(IWebBrowser2** web_browser) { if (!web_browser) return E_INVALIDARG; + AllowSetForegroundWindow(ASFW_ANY); + HRESULT hr = S_OK; DWORD cocreate_flags = CLSCTX_LOCAL_SERVER; chrome_frame_test::LowIntegrityToken token; @@ -413,6 +417,13 @@ _ATL_FUNC_INFO WebBrowserEventSink::kDocumentCompleteInfo = { } }; +_ATL_FUNC_INFO WebBrowserEventSink::kFileDownloadInfo = { + CC_STDCALL, VT_EMPTY, 2, { + VT_BOOL, + VT_BOOL | VT_BYREF + } +}; + // WebBrowserEventSink member defines void WebBrowserEventSink::Attach(IDispatch* browser_disp) { EXPECT_TRUE(NULL != browser_disp); @@ -427,8 +438,60 @@ void WebBrowserEventSink::Uninitialize() { DisconnectFromChromeFrame(); if (web_browser2_.get()) { DispEventUnadvise(web_browser2_); - web_browser2_->Quit(); + + ScopedHandle process; + // process_id_to_wait_for_ is set when we receive OnQuit. + // So, we should only attempt to wait for the browser if we know that + // the browser is truly quitting and if this instance actually launched + // the browser. + if (process_id_to_wait_for_) { + if (is_main_browser_object_) { + process.Set(OpenProcess(SYNCHRONIZE, FALSE, process_id_to_wait_for_)); + DLOG_IF(ERROR, !process.IsValid()) + << StringPrintf("OpenProcess failed: %i", ::GetLastError()); + } + process_id_to_wait_for_ = 0; + } else { + DLOG_IF(ERROR, is_main_browser_object_) + << "Main browser event object did not have a valid the process id."; + web_browser2_->Quit(); + } + web_browser2_.Release(); + + if (process) { + DWORD max_wait = kDefaultWaitForIEToTerminateMs; + while (true) { + base::Time start = base::Time::Now(); + HANDLE wait_for = process; + DWORD wait = MsgWaitForMultipleObjects(1, &wait_for, FALSE, max_wait, + QS_ALLINPUT); + if (wait == WAIT_OBJECT_0 + 1) { + MSG msg; + while (PeekMessage(&msg, NULL, 0, 0, TRUE) > 0) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } else if (wait == WAIT_OBJECT_0) { + break; + } else { + DCHECK(wait == WAIT_TIMEOUT); + DLOG(ERROR) << "Wait for IE timed out"; + break; + } + + base::TimeDelta elapsed = base::Time::Now() - start; + ULARGE_INTEGER ms; + ms.QuadPart = elapsed.InMilliseconds(); + DCHECK(ms.HighPart == 0); + if (ms.LowPart > max_wait) { + DLOG(ERROR) << "Wait for IE timed out (2)"; + break; + } else { + max_wait -= ms.LowPart; + } + } + } } } @@ -436,7 +499,8 @@ STDMETHODIMP WebBrowserEventSink::OnBeforeNavigate2Internal( IDispatch* dispatch, VARIANT* url, VARIANT* flags, VARIANT* target_frame_name, VARIANT* post_data, VARIANT* headers, VARIANT_BOOL* cancel) { - DLOG(INFO) << __FUNCTION__; + DLOG(INFO) << __FUNCTION__ + << StringPrintf("%ls - 0x%08X", url->bstrVal, this); // Reset any existing reference to chrome frame since this is a new // navigation. chrome_frame_ = NULL; @@ -457,6 +521,14 @@ STDMETHODIMP_(void) WebBrowserEventSink::OnDocumentCompleteInternal( OnDocumentComplete(dispatch, url); } +STDMETHODIMP_(void) WebBrowserEventSink::OnFileDownloadInternal( + VARIANT_BOOL active_doc, VARIANT_BOOL* cancel) { + DLOG(INFO) << __FUNCTION__ << StringPrintf(" 0x%08X ad=%i", this, active_doc); + OnFileDownload(active_doc, cancel); + // Always cancel file downloads in tests. + *cancel = VARIANT_TRUE; +} + STDMETHODIMP_(void) WebBrowserEventSink::OnNewWindow3Internal( IDispatch** dispatch, VARIANT_BOOL* cancel, DWORD flags, BSTR url_context, BSTR url) { @@ -527,6 +599,7 @@ HRESULT WebBrowserEventSink::OnMessageInternal(const VARIANT* param) { HRESULT WebBrowserEventSink::LaunchIEAndNavigate( const std::wstring& navigate_url) { + is_main_browser_object_ = true; HRESULT hr = LaunchIEAsComServer(web_browser2_.Receive()); EXPECT_EQ(S_OK, hr); if (hr == S_OK) { @@ -622,12 +695,25 @@ HWND WebBrowserEventSink::GetRendererWindow() { HRESULT WebBrowserEventSink::SetWebBrowser(IWebBrowser2* web_browser2) { DCHECK(web_browser2_.get() == NULL); + DCHECK(!is_main_browser_object_); web_browser2_ = web_browser2; web_browser2_->put_Visible(VARIANT_TRUE); HRESULT hr = DispEventAdvise(web_browser2_, &DIID_DWebBrowserEvents2); return hr; } +HRESULT WebBrowserEventSink::CloseWebBrowser() { + DCHECK(process_id_to_wait_for_ == 0); + if (!web_browser2_) + return E_FAIL; + HWND hwnd = NULL; + HRESULT hr = web_browser2_->get_HWND(reinterpret_cast<SHANDLE_PTR*>(&hwnd)); + if (!::IsWindow(hwnd)) + return E_UNEXPECTED; + EXPECT_TRUE(::PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0)); + return S_OK; +} + void WebBrowserEventSink::ExpectRendererWindowHasfocus() { HWND renderer_window = GetRendererWindow(); EXPECT_TRUE(IsWindow(renderer_window)); diff --git a/chrome_frame/test/chrome_frame_test_utils.h b/chrome_frame/test/chrome_frame_test_utils.h index 95a0a4f..91d8438 100644 --- a/chrome_frame/test/chrome_frame_test_utils.h +++ b/chrome_frame/test/chrome_frame_test_utils.h @@ -138,7 +138,9 @@ class WebBrowserEventSink ALLOW_THIS_IN_INITIALIZER_LIST( onloaderror_(this, &WebBrowserEventSink::OnLoadErrorInternal)), ALLOW_THIS_IN_INITIALIZER_LIST( - onload_(this, &WebBrowserEventSink::OnLoadInternal)) { + onload_(this, &WebBrowserEventSink::OnLoadInternal)), + process_id_to_wait_for_(0), + is_main_browser_object_(false) { } ~WebBrowserEventSink() { @@ -187,6 +189,10 @@ BEGIN_SINK_MAP(WebBrowserEventSink) OnNewWindow3Internal, &kNewWindow3Info) SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentCompleteInternal, &kDocumentCompleteInfo) + SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_FILEDOWNLOAD, + OnFileDownloadInternal, &kFileDownloadInfo) + SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_ONQUIT, + OnQuitInternal, &kVoidMethodInfo) END_SINK_MAP() STDMETHOD_(void, OnNavigateError)(IDispatch* dispatch, VARIANT* url, @@ -195,8 +201,8 @@ END_SINK_MAP() DLOG(INFO) << __FUNCTION__; } - STDMETHOD(OnBeforeNavigate2)(IDispatch* dispatch, VARIANT* url, VARIANT* - flags, VARIANT* target_frame_name, + STDMETHOD(OnBeforeNavigate2)(IDispatch* dispatch, VARIANT* url, + VARIANT* flags, VARIANT* target_frame_name, VARIANT* post_data, VARIANT* headers, VARIANT_BOOL* cancel) { return S_OK; @@ -209,6 +215,23 @@ END_SINK_MAP() DWORD flags, BSTR url_context, BSTR url) {} STDMETHOD_(void, OnDocumentComplete)(IDispatch* dispatch, VARIANT* url) {} + + STDMETHOD_(void, OnFileDownloadInternal)(VARIANT_BOOL active_doc, + VARIANT_BOOL* cancel); + STDMETHOD_(void, OnFileDownload)(VARIANT_BOOL active_doc, + VARIANT_BOOL* cancel) {} + STDMETHOD_(void, OnQuit)() {} + STDMETHOD_(void, OnQuitInternal)() { + DLOG(INFO) << __FUNCTION__; + // Grab the process id here in case it will be too late to do it + // in Uninitialize. + HWND hwnd = NULL; + web_browser2_->get_HWND(reinterpret_cast<SHANDLE_PTR*>(&hwnd)); + if (::IsWindow(hwnd)) + ::GetWindowThreadProcessId(hwnd, &process_id_to_wait_for_); + + OnQuit(); + } #ifdef _DEBUG STDMETHOD(Invoke)(DISPID dispid, REFIID riid, LCID lcid, WORD flags, DISPPARAMS* params, VARIANT* result, @@ -234,6 +257,10 @@ END_SINK_MAP() HRESULT SetWebBrowser(IWebBrowser2* web_browser2); void ExpectRendererWindowHasfocus(); + // Closes the web browser in such a way that the OnQuit notification will + // be fired when the window closes (async). + HRESULT CloseWebBrowser(); + protected: STDMETHOD(OnBeforeNavigate2Internal)(IDispatch* dispatch, VARIANT* url, VARIANT* flags, @@ -245,7 +272,7 @@ END_SINK_MAP() STDMETHOD_(void, OnDocumentCompleteInternal)(IDispatch* dispatch, VARIANT* url); STDMETHOD_(void, OnNewWindow3Internal)(IDispatch** dispatch, - VARIANT_BOOL* Cancel, DWORD flags, + VARIANT_BOOL* cancel, DWORD flags, BSTR url_context, BSTR url); // IChromeFrame callbacks @@ -263,6 +290,12 @@ END_SINK_MAP() DispCallback<WebBrowserEventSink> onmessage_; DispCallback<WebBrowserEventSink> onloaderror_; DispCallback<WebBrowserEventSink> onload_; + base::ProcessId process_id_to_wait_for_; + + // Set to true if this instance was used to launch the browser process. + // For instances used to connect to popup windows etc, this will be + // set to false. + bool is_main_browser_object_; protected: static _ATL_FUNC_INFO kBeforeNavigate2Info; @@ -272,6 +305,7 @@ END_SINK_MAP() static _ATL_FUNC_INFO kNewWindow3Info; static _ATL_FUNC_INFO kVoidMethodInfo; static _ATL_FUNC_INFO kDocumentCompleteInfo; + static _ATL_FUNC_INFO kFileDownloadInfo; }; } // namespace chrome_frame_test diff --git a/chrome_frame/test/data/download_file.zip b/chrome_frame/test/data/download_file.zip Binary files differnew file mode 100644 index 0000000..a12500d --- /dev/null +++ b/chrome_frame/test/data/download_file.zip diff --git a/chrome_frame/test/data/full_tab_download_from_new_window.html b/chrome_frame/test/data/full_tab_download_from_new_window.html new file mode 100644 index 0000000..bb6abe3 --- /dev/null +++ b/chrome_frame/test/data/full_tab_download_from_new_window.html @@ -0,0 +1,18 @@ +<html> + <head> + <meta http-equiv="x-ua-compatible" content="chrome=1" /> + <script language="javascript"> + function downloadInNewWindow() { + var download_url = "download_file.zip"; + window.open(download_url, 'download', 'toolbar=0,location=no'); + return false; // cancel form submission + } + </script> + </head> +<body onload="downloadInNewWindow();"> +<form method="POST" action="hero"> + <input onclick="return downloadInNewWindow()" value="Download" + id="downloadButton" type="button"> +</form> +</body> +</html> diff --git a/chrome_frame/test/test_mock_with_web_server.cc b/chrome_frame/test/test_mock_with_web_server.cc index 76079b4..c2c56e8 100644 --- a/chrome_frame/test/test_mock_with_web_server.cc +++ b/chrome_frame/test/test_mock_with_web_server.cc @@ -22,12 +22,46 @@ const wchar_t kChromeFrameFileUrl[] = L"gcf:file:///C:/"; const wchar_t enter_key[] = { VK_RETURN, 0 }; const wchar_t tab_enter_keys[] = { VK_TAB, VK_RETURN, 0 }; +// A convenience class to close all open IE windows at the end +// of a scope. It's more convenient to do it this way than to +// explicitly call chrome_frame_test::CloseAllIEWindows at the +// end of a test since part of the test's cleanup code may be +// in object destructors that would run after CloseAllIEWindows +// would get called. +// Ideally all IE windows should be closed when this happens so +// if the test ran normally, we should not have any windows to +// close at this point. +class CloseIeAtEndOfScope { + public: + CloseIeAtEndOfScope() {} + ~CloseIeAtEndOfScope() { + int closed = chrome_frame_test::CloseAllIEWindows(); + DLOG_IF(ERROR, closed != 0) + << StringPrintf("Closed %i windows forcefully", closed); + } +}; + +// Specialization of CComObjectStackEx that performs object cleanup via +// calling Base::Uninitialize() before we get to CComObjectStackEx' destructor. +// The CComObjectStackEx destructor expects the reference count to be 0 +// or it will throw an assert. To work around that and to avoid having to +// explicitly call Uninitialize() at the end of every test, we override the +// destructor here to perform the cleanup. +template <class Base> +class ComStackObjectWithUninitialize : public CComObjectStackEx<Base> { + public: + virtual ~ComStackObjectWithUninitialize() { + Base::Uninitialize(); + } +}; + TEST(ChromeFrameTest, FullTabModeIE_DisallowedUrls) { + CloseIeAtEndOfScope last_resort_close_ie; chrome_frame_test::TimedMsgLoop loop; // If a navigation fails then IE issues a navigation to an interstitial // page. Catch this to track navigation errors as the NavigateError // notification does not seem to fire reliably. - CComObjectStackEx<MockWebBrowserEventSink> mock; + ComStackObjectWithUninitialize<MockWebBrowserEventSink> mock; EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, @@ -41,9 +75,14 @@ TEST(ChromeFrameTest, FullTabModeIE_DisallowedUrls) { testing::StartsWith(L"res:")), _, _, _, _, _)) .Times(1) - .WillOnce(testing::DoAll( - QUIT_LOOP(loop), - testing::Return(S_OK))); + .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); + EXPECT_CALL(mock, OnNavigateComplete2(_, _)) + .WillOnce( + testing::IgnoreResult(testing::InvokeWithoutArgs(CreateFunctor(&mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + EXPECT_CALL(mock, OnQuit()).WillOnce(QUIT_LOOP(loop)); HRESULT hr = mock.LaunchIEAndNavigate(kChromeFrameFileUrl); ASSERT_HRESULT_SUCCEEDED(hr); @@ -53,9 +92,6 @@ TEST(ChromeFrameTest, FullTabModeIE_DisallowedUrls) { ASSERT_TRUE(mock.web_browser2() != NULL); loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds); - - mock.Uninitialize(); - chrome_frame_test::CloseAllIEWindows(); } const wchar_t kKeyEventUrl[] = L"http://localhost:1337/files/keyevent.html"; @@ -63,13 +99,16 @@ const wchar_t kKeyEventUrl[] = L"http://localhost:1337/files/keyevent.html"; // Marking this test FLAKY as it fails at times on the buildbot. // http://code.google.com/p/chromium/issues/detail?id=26549 TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_KeyboardTest) { + CloseIeAtEndOfScope last_resort_close_ie; chrome_frame_test::TimedMsgLoop loop; - CComObjectStackEx<MockWebBrowserEventSink> mock; + ComStackObjectWithUninitialize<MockWebBrowserEventSink> mock; EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, testing::StrCaseEq(kKeyEventUrl)), _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); @@ -82,7 +121,10 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_KeyboardTest) { &MockWebBrowserEventSink::SendKeys, input), 500))); EXPECT_CALL(mock, OnMessage(testing::StrEq(input), _, _)) - .WillOnce(QUIT_LOOP(loop)); + .WillOnce( + testing::IgnoreResult(testing::InvokeWithoutArgs(CreateFunctor(&mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + EXPECT_CALL(mock, OnQuit()).WillOnce(QUIT_LOOP(loop)); HRESULT hr = mock.LaunchIEAndNavigate(kKeyEventUrl); ASSERT_HRESULT_SUCCEEDED(hr); @@ -90,22 +132,22 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_KeyboardTest) { return; loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds); - - mock.Uninitialize(); - chrome_frame_test::CloseAllIEWindows(); } const wchar_t kAboutVersionUrl[] = L"gcf:about:version"; const wchar_t kAboutVersion[] = L"about:version"; TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_FocusTest) { + CloseIeAtEndOfScope last_resort_close_ie; chrome_frame_test::TimedMsgLoop loop; - CComObjectStackEx<MockWebBrowserEventSink> mock; + ComStackObjectWithUninitialize<MockWebBrowserEventSink> mock; EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, testing::StrCaseEq(kAboutVersionUrl)), _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); @@ -113,19 +155,15 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_FocusTest) { .WillOnce(testing::DoAll( testing::InvokeWithoutArgs(CreateFunctor(&mock, &MockWebBrowserEventSink::ExpectRendererWindowHasfocus)), - testing::InvokeWithoutArgs(CreateFunctor(&mock, - &MockWebBrowserEventSink::Uninitialize)), - testing::IgnoreResult(testing::InvokeWithoutArgs( - &chrome_frame_test::CloseAllIEWindows)), - QUIT_LOOP_SOON(loop, 2))); + testing::IgnoreResult(testing::InvokeWithoutArgs(CreateFunctor(&mock, + &MockWebBrowserEventSink::CloseWebBrowser))))); + + EXPECT_CALL(mock, OnQuit()).WillOnce(QUIT_LOOP(loop)); HRESULT hr = mock.LaunchIEAndNavigate(kAboutVersionUrl); // Allow some time for chrome to be launched. loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds); - - mock.Uninitialize(); - chrome_frame_test::CloseAllIEWindows(); } const wchar_t kFullTabWindowOpenTestUrl[] = @@ -141,12 +179,13 @@ const wchar_t kFullTabWindowOpenPopupUrl[] = // input which don't work correctly at times. // http://code.google.com/p/chromium/issues/detail?id=26549 TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_WindowOpenInChrome) { + CloseIeAtEndOfScope last_resort_close_ie; chrome_frame_test::TimedMsgLoop loop; - CComObjectStackEx<MockWebBrowserEventSink> mock; + ComStackObjectWithUninitialize<MockWebBrowserEventSink> mock; // 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 + // per mock, it's OK to be not in sequence as long as all the expectations // are satisfied. Moreover, since the second mock expects a new window, // its events happen in random order. EXPECT_CALL(mock, @@ -155,6 +194,8 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_WindowOpenInChrome) { testing::StrCaseEq(kFullTabWindowOpenTestUrl)), _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); @@ -167,7 +208,7 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_WindowOpenInChrome) { &mock, &MockWebBrowserEventSink::SendKeys, input), 500))); // Watch for new window - CComObjectStackEx<MockWebBrowserEventSink> new_window_mock; + ComStackObjectWithUninitialize<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(_, _)) @@ -178,18 +219,21 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_WindowOpenInChrome) { // Expect navigations on the new mock EXPECT_CALL(new_window_mock, OnBeforeNavigate2(_, _, _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(new_window_mock, OnFileDownload(VARIANT_TRUE, _)) + .WillOnce(testing::Return()); EXPECT_CALL(new_window_mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(new_window_mock, OnLoad(testing::StrEq(kFullTabWindowOpenPopupUrl))) - .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))); + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs( + CreateFunctor(&new_window_mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + + EXPECT_CALL(new_window_mock, OnQuit()) + .WillOnce( + testing::IgnoreResult(testing::InvokeWithoutArgs(CreateFunctor(&mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + EXPECT_CALL(mock, OnQuit()).WillOnce(QUIT_LOOP(loop)); HRESULT hr = mock.LaunchIEAndNavigate(kFullTabWindowOpenTestUrl); ASSERT_HRESULT_SUCCEEDED(hr); @@ -199,9 +243,6 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_WindowOpenInChrome) { ASSERT_TRUE(mock.web_browser2() != NULL); loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds); - - mock.Uninitialize(); - chrome_frame_test::CloseAllIEWindows(); } const wchar_t kSubFrameUrl1[] = @@ -218,13 +259,17 @@ const wchar_t kSubFrameUrl1[] = // Marking this test FLAKY as it fails at times on the buildbot. // http://code.google.com/p/chromium/issues/detail?id=26549 TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_AboutChromeFrame) { + CloseIeAtEndOfScope last_resort_close_ie; + chrome_frame_test::TimedMsgLoop loop; - CComObjectStackEx<MockWebBrowserEventSink> mock; + ComStackObjectWithUninitialize<MockWebBrowserEventSink> mock; EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, testing::StrCaseEq(kSubFrameUrl1)), _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); @@ -245,7 +290,7 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_AboutChromeFrame) { 600)))); // Watch for new window - CComObjectStackEx<MockWebBrowserEventSink> new_window_mock; + ComStackObjectWithUninitialize<MockWebBrowserEventSink> new_window_mock; EXPECT_CALL(mock, OnNewWindow3(_, _, _, _, testing::StrCaseEq(kAboutVersionUrl))); EXPECT_CALL(mock, OnNewBrowserWindow(_, _)) @@ -256,17 +301,19 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_AboutChromeFrame) { // Expect navigations on the new mock EXPECT_CALL(new_window_mock, OnBeforeNavigate2(_, _, _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(new_window_mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(new_window_mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(new_window_mock, OnLoad(testing::StrEq(kAboutVersion))) - .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))); + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs( + CreateFunctor(&new_window_mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + EXPECT_CALL(new_window_mock, OnQuit()) + .WillOnce( + testing::IgnoreResult(testing::InvokeWithoutArgs(CreateFunctor(&mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + EXPECT_CALL(mock, OnQuit()).WillOnce(QUIT_LOOP(loop)); HRESULT hr = mock.LaunchIEAndNavigate(kSubFrameUrl1); ASSERT_HRESULT_SUCCEEDED(hr); @@ -275,9 +322,6 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_AboutChromeFrame) { ASSERT_TRUE(mock.web_browser2() != NULL); loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds); - - mock.Uninitialize(); - chrome_frame_test::CloseAllIEWindows(); } const wchar_t kSubFrameUrl2[] = @@ -297,8 +341,9 @@ template <typename T> T** ReceivePointer(scoped_refptr<T>& p) { // NOLINT // Full tab mode back/forward test // Launch and navigate chrome frame to a set of URLs and test back forward TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_BackForward) { + CloseIeAtEndOfScope last_resort_close_ie; chrome_frame_test::TimedMsgLoop loop; - CComObjectStackEx<MockWebBrowserEventSink> mock; + ComStackObjectWithUninitialize<MockWebBrowserEventSink> mock; ::testing::InSequence sequence; // Everything in sequence // When the onhttpequiv patch is enabled, we will get two @@ -313,6 +358,9 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_BackForward) { _, _, _, _, _)) .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .WillOnce(testing::Return()); + EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .WillOnce(testing::Return()); @@ -322,6 +370,9 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_BackForward) { _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return()); + EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); @@ -339,6 +390,9 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_BackForward) { _, _, _, _, _)) .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return()); + EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .WillOnce(testing::Return()); @@ -348,6 +402,9 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_BackForward) { _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return()); + EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); @@ -366,6 +423,9 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_BackForward) { _, _, _, _, _)) .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return()); + EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .WillOnce(testing::Return()); @@ -375,6 +435,9 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_BackForward) { _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return()); + EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); @@ -411,12 +474,10 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_BackForward) { .WillOnce(testing::Return()); EXPECT_CALL(mock, OnLoad(testing::StrEq(kSubFrameUrl1))) - .WillOnce(testing::DoAll( - testing::InvokeWithoutArgs(CreateFunctor(&mock, - &chrome_frame_test::WebBrowserEventSink::Uninitialize)), - testing::IgnoreResult(testing::InvokeWithoutArgs( - &chrome_frame_test::CloseAllIEWindows)), - QUIT_LOOP_SOON(loop, 2))); + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs( + CreateFunctor(&mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + EXPECT_CALL(mock, OnQuit()).WillOnce(QUIT_LOOP(loop)); HRESULT hr = mock.LaunchIEAndNavigate(kSubFrameUrl1); ASSERT_HRESULT_SUCCEEDED(hr); @@ -425,8 +486,6 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_BackForward) { ASSERT_TRUE(mock.web_browser2() != NULL); loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds); - mock.Uninitialize(); - chrome_frame_test::CloseAllIEWindows(); } const wchar_t kAnchorUrl[] = L"http://localhost:1337/files/anchor.html"; @@ -439,8 +498,9 @@ const wchar_t kAnchor3Url[] = L"http://localhost:1337/files/anchor.html#a3"; // Marking this test FLAKY as it fails at times on the buildbot. // http://code.google.com/p/chromium/issues/detail?id=26549 TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_BackForwardAnchor) { + CloseIeAtEndOfScope last_resort_close_ie; chrome_frame_test::TimedMsgLoop loop; - CComObjectStackEx<MockWebBrowserEventSink> mock; + ComStackObjectWithUninitialize<MockWebBrowserEventSink> mock; ::testing::InSequence sequence; // Everything in sequence // When the onhttpequiv patch is enabled, we will get two @@ -457,12 +517,16 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_BackForwardAnchor) { testing::StrCaseEq(kAnchorUrl)), _, _, _, _, _)) .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .WillOnce(testing::Return()); EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, testing::StrCaseEq(kAnchorUrl)), _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); @@ -488,6 +552,8 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_BackForwardAnchor) { testing::StrCaseEq(kAnchor1Url)), _, _, _, _, _)) .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .WillOnce(testing::Return()); @@ -507,6 +573,8 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_BackForwardAnchor) { testing::StrCaseEq(kAnchor2Url)), _, _, _, _, _)) .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .WillOnce(testing::Return()); @@ -526,6 +594,8 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_BackForwardAnchor) { testing::StrCaseEq(kAnchor3Url)), _, _, _, _, _)) .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .WillOnce(testing::Return()); @@ -542,6 +612,8 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_BackForwardAnchor) { testing::StrCaseEq(kAnchor2Url)), _, _, _, _, _)) .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .WillOnce(testing::Return()); @@ -594,12 +666,10 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_BackForwardAnchor) { // We have gone a few steps back and forward, this should be enough for now. EXPECT_CALL(mock, OnLoad(testing::StrEq(kAnchor3Url))) - .WillOnce(testing::DoAll( - testing::InvokeWithoutArgs(CreateFunctor(&mock, - &chrome_frame_test::WebBrowserEventSink::Uninitialize)), - testing::IgnoreResult(testing::InvokeWithoutArgs( - &chrome_frame_test::CloseAllIEWindows)), - QUIT_LOOP_SOON(loop, 2))); + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs( + CreateFunctor(&mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + EXPECT_CALL(mock, OnQuit()).WillOnce(QUIT_LOOP(loop)); HRESULT hr = mock.LaunchIEAndNavigate(kAnchorUrl); ASSERT_HRESULT_SUCCEEDED(hr); @@ -608,8 +678,6 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_BackForwardAnchor) { ASSERT_TRUE(mock.web_browser2() != NULL); loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds); - mock.Uninitialize(); - chrome_frame_test::CloseAllIEWindows(); } // Full tab mode view source test @@ -617,9 +685,10 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_BackForwardAnchor) { // This test has been marked FLAKY // http://code.google.com/p/chromium/issues/detail?id=35370 TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_ViewSource) { + CloseIeAtEndOfScope last_resort_close_ie; chrome_frame_test::TimedMsgLoop loop; - CComObjectStackEx<MockWebBrowserEventSink> mock; - CComObjectStackEx<MockWebBrowserEventSink> view_source_mock; + ComStackObjectWithUninitialize<MockWebBrowserEventSink> mock; + ComStackObjectWithUninitialize<MockWebBrowserEventSink> view_source_mock; ::testing::InSequence sequence; // Everything in sequence // After navigation invoke view soruce action using IWebBrowser2::ExecWB @@ -627,12 +696,16 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_ViewSource) { testing::StrCaseEq(kAnchorUrl)), _, _, _, _, _)) .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .WillOnce(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .WillOnce(testing::Return()); EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, testing::StrCaseEq(kAnchorUrl)), _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .WillOnce(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); @@ -664,18 +737,19 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_ViewSource) { testing::Field(&VARIANT::bstrVal, testing::StrCaseEq(url_in_new_window)), _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(view_source_mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); 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))); - + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs( + CreateFunctor(&view_source_mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + EXPECT_CALL(view_source_mock, OnQuit()) + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs( + CreateFunctor(&mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + EXPECT_CALL(mock, OnQuit()).WillOnce(QUIT_LOOP(loop)); HRESULT hr = mock.LaunchIEAndNavigate(kAnchorUrl); ASSERT_HRESULT_SUCCEEDED(hr); if (hr == S_FALSE) @@ -683,8 +757,6 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_ViewSource) { ASSERT_TRUE(mock.web_browser2() != NULL); loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds); - mock.Uninitialize(); - chrome_frame_test::CloseAllIEWindows(); } const wchar_t kFullTabModeBeforeUnloadEventTest[] = @@ -694,8 +766,9 @@ const wchar_t kFullTabModeBeforeUnloadEventMain[] = L"http://localhost:1337/files/fulltab_before_unload_event_main.html"; TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_UnloadEventTest) { + CloseIeAtEndOfScope last_resort_close_ie; chrome_frame_test::TimedMsgLoop loop; - CComObjectStackEx<MockWebBrowserEventSink> mock; + ComStackObjectWithUninitialize<MockWebBrowserEventSink> mock; ::testing::InSequence sequence; // Everything in sequence // We will get two BeforeNavigate2/OnNavigateComplete2 notifications due to @@ -708,6 +781,9 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_UnloadEventTest) { _, _, _, _, _)) .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .WillOnce(testing::Return()); + EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .WillOnce(testing::Return()); @@ -719,6 +795,9 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_UnloadEventTest) { _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .WillOnce(testing::Return()); + EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); @@ -734,6 +813,9 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_UnloadEventTest) { _, _, _, _, _)) .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .WillOnce(testing::Return()); + EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .WillOnce(testing::Return()); @@ -745,19 +827,19 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_UnloadEventTest) { _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .WillOnce(testing::Return()); + EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(mock, OnLoad(_)).WillOnce(testing::Return()); EXPECT_CALL(mock, OnMessage(_, _, _)) - .WillOnce(testing::DoAll( - testing::InvokeWithoutArgs(CreateFunctor(&mock, - &chrome_frame_test::WebBrowserEventSink::Uninitialize)), - testing::IgnoreResult(testing::InvokeWithoutArgs( - &chrome_frame_test::CloseAllIEWindows)), - QUIT_LOOP_SOON(loop, 2))); - + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs( + CreateFunctor(&mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + EXPECT_CALL(mock, OnQuit()).WillOnce(QUIT_LOOP(loop)); HRESULT hr = mock.LaunchIEAndNavigate(kFullTabModeBeforeUnloadEventTest); ASSERT_HRESULT_SUCCEEDED(hr); if (hr == S_FALSE) @@ -765,26 +847,97 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_UnloadEventTest) { ASSERT_TRUE(mock.web_browser2() != NULL); loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds); - mock.Uninitialize(); - chrome_frame_test::CloseAllIEWindows(); +} + +// NOTE: This test is currently disabled as we haven't finished implementing +// support for this yet. The test (as written) works fine for IE. CF might +// have a different set of requirements once we fully support this and hence +// the test might need some refining before being enabled. +TEST_F(ChromeFrameTestWithWebServer, + DISABLED_FullTabModeIE_DownloadInNewWindow) { + CloseIeAtEndOfScope last_resort_close_ie; + const wchar_t kDownloadFromNewWin[] = + L"http://localhost:1337/files/full_tab_download_from_new_window.html"; + + chrome_frame_test::TimedMsgLoop loop; + ComStackObjectWithUninitialize<MockWebBrowserEventSink> mock; + + EXPECT_CALL(mock, + OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, + testing::StrCaseEq(kDownloadFromNewWin)), + _, _, _, _, _)) + .Times(testing::AnyNumber()) + .WillRepeatedly(testing::Return(S_OK)); + + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .WillOnce(testing::Return()); + + EXPECT_CALL(mock, + OnNavigateComplete2(_, _)) + .Times(testing::AnyNumber()) + .WillRepeatedly(testing::Return()); + + EXPECT_CALL(mock, OnNewWindow3(_, _, _, _, _)) + .WillOnce(testing::Return()); + + ComStackObjectWithUninitialize<MockWebBrowserEventSink> new_window_mock; + EXPECT_CALL(mock, OnNewBrowserWindow(_, _)) + .WillOnce(testing::WithArgs<0>( + testing::Invoke(CreateFunctor(&new_window_mock, + &MockWebBrowserEventSink::Attach)))); + EXPECT_CALL(new_window_mock, + OnBeforeNavigate2(_, _, _, _, _, _, _)) + .WillOnce(testing::Return(S_OK)); + + EXPECT_CALL(new_window_mock, + OnFileDownload(VARIANT_FALSE, _)) + .Times(2) + .WillRepeatedly(testing::IgnoreResult(testing::InvokeWithoutArgs( + CreateFunctor(&new_window_mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + + EXPECT_CALL(new_window_mock, + OnNavigateComplete2(_, _)) + .WillOnce(testing::Return()); + + EXPECT_CALL(new_window_mock, OnQuit()) + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs( + CreateFunctor(&mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + + EXPECT_CALL(mock, OnQuit()).WillOnce(QUIT_LOOP(loop)); + + HRESULT hr = mock.LaunchIEAndNavigate(kDownloadFromNewWin); + ASSERT_HRESULT_SUCCEEDED(hr); + if (hr == S_FALSE) + return; + + ASSERT_TRUE(mock.web_browser2() != NULL); + + loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds); } // Test Back/Forward from context menu. Loads page 1 in chrome and page 2 // in IE. Then it tests back and forward using context menu TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ContextMenuBackForward) { + CloseIeAtEndOfScope last_resort_close_ie; chrome_frame_test::TimedMsgLoop loop; - CComObjectStackEx<MockWebBrowserEventSink> mock; + ComStackObjectWithUninitialize<MockWebBrowserEventSink> mock; ::testing::InSequence sequence; // Everything in sequence EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, testing::StrCaseEq(kSubFrameUrl1)), _, _, _, _, _)) .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)).WillOnce(testing::Return()); EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, testing::StrCaseEq(kSubFrameUrl1)), _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); @@ -799,11 +952,15 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ContextMenuBackForward) { testing::StrCaseEq(kSubFrameUrl2)), _, _, _, _, _)) .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)).WillOnce(testing::Return()); EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, testing::StrCaseEq(kSubFrameUrl2)), _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); @@ -874,13 +1031,10 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ContextMenuBackForward) { .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(mock, OnLoad(testing::StrEq(kSubFrameUrl2))) - .WillOnce(testing::DoAll( - testing::InvokeWithoutArgs(CreateFunctor(&mock, - &MockWebBrowserEventSink::Uninitialize)), - testing::IgnoreResult(testing::InvokeWithoutArgs( - &chrome_frame_test::CloseAllIEWindows)), - QUIT_LOOP_SOON(loop, 2))); - + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs( + CreateFunctor(&mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + EXPECT_CALL(mock, OnQuit()).WillOnce(QUIT_LOOP(loop)); HRESULT hr = mock.LaunchIEAndNavigate(kSubFrameUrl1); ASSERT_HRESULT_SUCCEEDED(hr); if (hr == S_FALSE) @@ -888,25 +1042,28 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ContextMenuBackForward) { ASSERT_TRUE(mock.web_browser2() != NULL); loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds); - mock.Uninitialize(); - chrome_frame_test::CloseAllIEWindows(); } // Test Reload from context menu. TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ContextMenuReload) { + CloseIeAtEndOfScope last_resort_close_ie; chrome_frame_test::TimedMsgLoop loop; - CComObjectStackEx<MockWebBrowserEventSink> mock; + ComStackObjectWithUninitialize<MockWebBrowserEventSink> mock; ::testing::InSequence sequence; // Everything in sequence EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, testing::StrCaseEq(kSubFrameUrl1)), _, _, _, _, _)) .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)).WillOnce(testing::Return()); EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, testing::StrCaseEq(kSubFrameUrl1)), _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); @@ -940,15 +1097,11 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ContextMenuReload) { simulate_input::SendString<wchar_t>, &enter_key[0]), 800)))); - // Go forward using Rt-Click + DOWN + DOWN + ENTER EXPECT_CALL(mock, OnLoad(testing::StrEq(kSubFrameUrl1))) - .WillOnce(testing::DoAll( - testing::InvokeWithoutArgs(CreateFunctor(&mock, - &MockWebBrowserEventSink::Uninitialize)), - testing::IgnoreResult(testing::InvokeWithoutArgs( - &chrome_frame_test::CloseAllIEWindows)), - QUIT_LOOP_SOON(loop, 2))); - + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs( + CreateFunctor(&mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + EXPECT_CALL(mock, OnQuit()).WillOnce(QUIT_LOOP(loop)); HRESULT hr = mock.LaunchIEAndNavigate(kSubFrameUrl1); ASSERT_HRESULT_SUCCEEDED(hr); if (hr == S_FALSE) @@ -956,15 +1109,14 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ContextMenuReload) { ASSERT_TRUE(mock.web_browser2() != NULL); loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds); - mock.Uninitialize(); - chrome_frame_test::CloseAllIEWindows(); } // Test view source using context menu TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ContextMenuViewSource) { + CloseIeAtEndOfScope last_resort_close_ie; chrome_frame_test::TimedMsgLoop loop; - CComObjectStackEx<MockWebBrowserEventSink> mock; - CComObjectStackEx<MockWebBrowserEventSink> view_source_mock; + ComStackObjectWithUninitialize<MockWebBrowserEventSink> mock; + ComStackObjectWithUninitialize<MockWebBrowserEventSink> view_source_mock; ::testing::InSequence sequence; // Everything in sequence // After navigation invoke view soruce action using IWebBrowser2::ExecWB @@ -972,12 +1124,16 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ContextMenuViewSource) { testing::StrCaseEq(kAnchorUrl)), _, _, _, _, _)) .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .WillOnce(testing::Return()); EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, testing::StrCaseEq(kAnchorUrl)), _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); EXPECT_CALL(mock, OnNavigateComplete2(_, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); @@ -1038,18 +1194,19 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ContextMenuViewSource) { testing::Field(&VARIANT::bstrVal, testing::StrCaseEq(url_in_new_window)), _, _, _, _, _)) .Times(testing::AnyNumber()).WillRepeatedly(testing::Return(S_OK)); + EXPECT_CALL(view_source_mock, OnFileDownload(VARIANT_TRUE, _)) + .Times(testing::AnyNumber()).WillRepeatedly(testing::Return()); 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))); - + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs( + CreateFunctor(&view_source_mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + EXPECT_CALL(view_source_mock, OnQuit()) + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs( + CreateFunctor(&mock, + &MockWebBrowserEventSink::CloseWebBrowser)))); + EXPECT_CALL(mock, OnQuit()).WillOnce(QUIT_LOOP(loop)); HRESULT hr = mock.LaunchIEAndNavigate(kAnchorUrl); ASSERT_HRESULT_SUCCEEDED(hr); if (hr == S_FALSE) @@ -1057,8 +1214,5 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ContextMenuViewSource) { ASSERT_TRUE(mock.web_browser2() != NULL); loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds); - mock.Uninitialize(); - chrome_frame_test::CloseAllIEWindows(); } - diff --git a/chrome_frame/test/test_mock_with_web_server.h b/chrome_frame/test/test_mock_with_web_server.h index 57a6e99..8c38e4d 100644 --- a/chrome_frame/test/test_mock_with_web_server.h +++ b/chrome_frame/test/test_mock_with_web_server.h @@ -53,6 +53,13 @@ class MockWebBrowserEventSink : public chrome_frame_test::WebBrowserEventSink { VARIANT* status_code, VARIANT* cancel)); + MOCK_METHOD2_WITH_CALLTYPE(__stdcall, OnFileDownload, + void (VARIANT_BOOL active_doc, + VARIANT_BOOL* cancel)); + + MOCK_METHOD0_WITH_CALLTYPE(__stdcall, OnQuit, + void ()); + MOCK_METHOD1(OnLoad, void (const wchar_t* url)); // NOLINT MOCK_METHOD1(OnLoadError, void (const wchar_t* url)); // NOLINT MOCK_METHOD3(OnMessage, void (const wchar_t* message, |