| Index: chrome_frame/test/chrome_frame_unittests.cc
|
| ===================================================================
|
| --- chrome_frame/test/chrome_frame_unittests.cc (revision 30411)
|
| +++ chrome_frame/test/chrome_frame_unittests.cc (working copy)
|
| @@ -14,7 +14,6 @@
|
| #include "base/file_version_info.h"
|
| #include "base/file_util.h"
|
| #include "base/scoped_bstr_win.h"
|
| -#include "base/scoped_comptr_win.h"
|
| #include "base/scoped_variant_win.h"
|
| #include "base/sys_info.h"
|
| #include "gmock/gmock.h"
|
| @@ -64,6 +63,15 @@
|
| }
|
| };
|
|
|
| +_ATL_FUNC_INFO WebBrowserEventSink::kNewWindow3Info = {
|
| + CC_STDCALL, VT_EMPTY, 5, {
|
| + VT_DISPATCH | VT_BYREF,
|
| + VT_BOOL | VT_BYREF,
|
| + VT_UINT,
|
| + VT_BSTR,
|
| + VT_BSTR
|
| + }
|
| +};
|
|
|
|
|
| void ChromeFrameTestWithWebServer::SetUp() {
|
| @@ -830,7 +838,7 @@
|
| struct TimedMsgLoop {
|
| public:
|
| void RunFor(int seconds) {
|
| - loop_.PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask, 1000 * seconds);
|
| + QuitAfter(seconds);
|
| loop_.MessageLoop::Run();
|
| }
|
|
|
| @@ -838,6 +846,10 @@
|
| loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask);
|
| }
|
|
|
| + void QuitAfter(int seconds) {
|
| + loop_.PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask, 1000 * seconds);
|
| + }
|
| +
|
| MessageLoopForUI loop_;
|
| };
|
|
|
| @@ -852,6 +864,9 @@
|
| #define QUIT_LOOP(loop) testing::InvokeWithoutArgs(\
|
| CreateFunctor(&loop, &TimedMsgLoop::Quit))
|
|
|
| +#define QUIT_LOOP_SOON(loop, seconds) testing::InvokeWithoutArgs(\
|
| + CreateFunctor(&loop, &TimedMsgLoop::QuitAfter, seconds))
|
| +
|
| // We mock ChromeFrameDelegate only. The rest is with real AutomationProxy
|
| TEST(CFACWithChrome, CreateTooFast) {
|
| MockCFDelegate cfd;
|
| @@ -1280,7 +1295,9 @@
|
| return hr;
|
| }
|
|
|
| -TEST(ChromeFrameTest, FullTabModeIE_DisallowedUrls) {
|
| +// WebBrowserEventSink member defines
|
| +HRESULT WebBrowserEventSink::LaunchIEAndNavigate(
|
| + const std::wstring& navigate_url, _IDispEvent* sink) {
|
| int major_version = 0;
|
| int minor_version = 0;
|
| int bugfix_version = 0;
|
| @@ -1290,54 +1307,204 @@
|
| if (major_version > 5) {
|
| DLOG(INFO) << __FUNCTION__ << " Not running test on Windows version: "
|
| << major_version;
|
| - return;
|
| + return S_FALSE;
|
| }
|
|
|
| IEVersion ie_version = GetIEVersion();
|
| if (ie_version == IE_8) {
|
| DLOG(INFO) << __FUNCTION__ << " Not running test on IE8";
|
| - return;
|
| + return S_FALSE;
|
| }
|
|
|
| - HRESULT hr = CoInitialize(NULL);
|
| - bool should_uninit = SUCCEEDED(hr);
|
| + EXPECT_TRUE(S_OK == LaunchIEAsComServer(web_browser2_.Receive()));
|
| + web_browser2_->put_Visible(VARIANT_TRUE);
|
|
|
| - ScopedComPtr<IWebBrowser2> web_browser2;
|
| - EXPECT_TRUE(S_OK == LaunchIEAsComServer(web_browser2.Receive()));
|
| - web_browser2->put_Visible(VARIANT_TRUE);
|
| -
|
| - CComObject<WebBrowserEventSink>* web_browser_sink = NULL;
|
| - CComObject<WebBrowserEventSink>::CreateInstance(&web_browser_sink);
|
| -
|
| - // Pass the main thread id to the browser sink so that it can notify
|
| - // us about test completion.
|
| - web_browser_sink->set_main_thread_id(GetCurrentThreadId());
|
| -
|
| - hr = web_browser_sink->DispEventAdvise(web_browser2,
|
| - &DIID_DWebBrowserEvents2);
|
| + HRESULT hr = sink->DispEventAdvise(web_browser2_,
|
| + &DIID_DWebBrowserEvents2);
|
| EXPECT_TRUE(hr == S_OK);
|
|
|
| VARIANT empty = ScopedVariant::kEmptyVariant;
|
| ScopedVariant url;
|
| - url.Set(L"cf:file:///C:/");
|
| + url.Set(navigate_url.c_str());
|
|
|
| + hr = web_browser2_->Navigate2(url.AsInput(), &empty, &empty, &empty, &empty);
|
| + EXPECT_TRUE(hr == S_OK);
|
| + return hr;
|
| +}
|
| +
|
| +const int kChromeFrameLongNavigationTimeoutInSeconds = 10;
|
| +
|
| +// This class provides functionality to add expectations to IE full tab mode
|
| +// tests.
|
| +class MockWebBrowserEventSink : public WebBrowserEventSink {
|
| + public:
|
| + // Needed to support PostTask.
|
| + static bool ImplementsThreadSafeReferenceCounting() {
|
| + return true;
|
| + }
|
| +
|
| + MOCK_METHOD7_WITH_CALLTYPE(__stdcall, OnBeforeNavigate2,
|
| + HRESULT (IDispatch* dispatch,
|
| + VARIANT* url,
|
| + VARIANT* flags,
|
| + VARIANT* target_frame_name,
|
| + VARIANT* post_data,
|
| + VARIANT* headers,
|
| + VARIANT_BOOL* cancel));
|
| +
|
| + MOCK_METHOD2_WITH_CALLTYPE(__stdcall, OnNavigateComplete2,
|
| + void (IDispatch* dispatch, VARIANT* url));
|
| +
|
| + MOCK_METHOD5_WITH_CALLTYPE(__stdcall, OnNewWindow3,
|
| + void (IDispatch** dispatch,
|
| + VARIANT_BOOL* Cancel,
|
| + DWORD flags,
|
| + BSTR url_context,
|
| + BSTR url));
|
| +
|
| + MOCK_METHOD5_WITH_CALLTYPE(__stdcall, OnNavigateError,
|
| + void (IDispatch* dispatch,
|
| + VARIANT* url,
|
| + VARIANT* frame_name,
|
| + VARIANT* status_code,
|
| + VARIANT* cancel));
|
| +};
|
| +
|
| +using testing::_;
|
| +
|
| +const wchar_t kChromeFrameFileUrl[] = L"cf:file:///C:/";
|
| +
|
| +TEST(ChromeFrameTest, FullTabModeIE_DisallowedUrls) {
|
| 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;
|
|
|
| - hr = web_browser2->Navigate2(url.AsInput(), &empty, &empty, &empty, &empty);
|
| - EXPECT_TRUE(hr == S_OK);
|
| + EXPECT_CALL(mock,
|
| + OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
|
| + testing::StrCaseEq(kChromeFrameFileUrl)),
|
| + _, _, _, _, _))
|
| + .Times(1)
|
| + .WillOnce(testing::Return(S_OK));
|
|
|
| - loop.RunFor(10);
|
| + EXPECT_CALL(mock,
|
| + OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
|
| + testing::StartsWith(L"res:")),
|
| + _, _, _, _, _))
|
| + .Times(1)
|
| + .WillOnce(testing::DoAll(
|
| + QUIT_LOOP(loop),
|
| + testing::Return(S_OK)));
|
|
|
| - EXPECT_TRUE(web_browser_sink->navigation_failed());
|
| + HRESULT hr = mock.LaunchIEAndNavigate(kChromeFrameFileUrl, &mock);
|
| + ASSERT_HRESULT_SUCCEEDED(hr);
|
| + if (hr == S_FALSE)
|
| + return;
|
|
|
| - hr = web_browser_sink->DispEventUnadvise(web_browser2);
|
| - EXPECT_TRUE(hr == S_OK);
|
| + ASSERT_TRUE(mock.web_browser2() != NULL);
|
|
|
| - web_browser2.Release();
|
| + loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds);
|
| +
|
| + mock.Uninitialize();
|
| chrome_frame_test::CloseAllIEWindows();
|
| +}
|
|
|
| - if (should_uninit) {
|
| - CoUninitialize();
|
| - }
|
| +const wchar_t kChromeFrameFullTabWindowOpenTestUrl[] =
|
| + L"http://localhost:1337/files/chrome_frame_window_open.html";
|
| +
|
| +const wchar_t kChromeFrameFullTabWindowOpenPopupUrl[] =
|
| + L"http://localhost:1337/files/chrome_frame_window_open_popup.html";
|
| +
|
| +// This test checks if window.open calls issued by a full tab mode ChromeFrame
|
| +// instance make it back to IE and then transitions back to Chrome as the
|
| +// window.open target page is supposed to render within Chrome.
|
| +TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_WindowOpen) {
|
| + TimedMsgLoop loop;
|
| +
|
| + CComObjectStackEx<MockWebBrowserEventSink> mock;
|
| +
|
| + EXPECT_CALL(mock,
|
| + OnBeforeNavigate2(
|
| + _, testing::Field(&VARIANT::bstrVal,
|
| + testing::StrCaseEq(kChromeFrameFullTabWindowOpenTestUrl)),
|
| + _, _, _, _, _))
|
| + .Times(1)
|
| + .WillOnce(testing::Return(S_OK));
|
| +
|
| + EXPECT_CALL(mock,
|
| + OnBeforeNavigate2(
|
| + _, testing::Field(&VARIANT::bstrVal,
|
| + testing::StrCaseEq(kChromeFrameFullTabWindowOpenPopupUrl)),
|
| + _, _, _, _, _))
|
| + .Times(1)
|
| + .WillOnce(testing::DoAll(
|
| + QUIT_LOOP_SOON(loop, 2),
|
| + testing::Return(S_OK)));
|
| +
|
| + HRESULT hr = mock.LaunchIEAndNavigate(kChromeFrameFullTabWindowOpenTestUrl,
|
| + &mock);
|
| + ASSERT_HRESULT_SUCCEEDED(hr);
|
| + if (hr == S_FALSE)
|
| + return;
|
| +
|
| + ASSERT_TRUE(mock.web_browser2() != NULL);
|
| +
|
| + loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds);
|
| +
|
| + ASSERT_TRUE(CheckResultFile(L"ChromeFrameWindowOpenPopup", "OK"));
|
| +
|
| + mock.Uninitialize();
|
| + chrome_frame_test::CloseAllIEWindows();
|
| }
|
|
|
| +const wchar_t kChromeFrameAboutBlankUrl[] =
|
| + L"cf:about:blank";
|
| +
|
| +const wchar_t kChromeFrameAboutVersion[] =
|
| + L"cf: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
|
| +// 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
|
| +// with the chrome revision. The test finally checks for success by comparing
|
| +// the URL of the window being opened with cf:about:version, which indicates
|
| +// that the operation succeeded.
|
| +TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_AboutChromeFrame) {
|
| + TimedMsgLoop loop;
|
| +
|
| + CComObjectStackEx<MockWebBrowserEventSink> mock;
|
| +
|
| + EXPECT_CALL(mock,
|
| + OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
|
| + testing::StrCaseEq(kChromeFrameAboutBlankUrl)),
|
| + _, _, _, _, _))
|
| + .Times(1)
|
| + .WillOnce(testing::Return(S_OK));
|
| +
|
| + EXPECT_CALL(mock, OnNavigateComplete2(_, _))
|
| + .Times(1)
|
| + .WillOnce(testing::InvokeWithoutArgs(
|
| + &chrome_frame_test::ShowChromeFrameContextMenu));
|
| +
|
| + EXPECT_CALL(mock,
|
| + OnNewWindow3(_, _, _, _,
|
| + testing::StrCaseEq(kChromeFrameAboutVersion)))
|
| + .Times(1)
|
| + .WillOnce(QUIT_LOOP(loop));
|
| +
|
| + HRESULT hr = mock.LaunchIEAndNavigate(kChromeFrameAboutBlankUrl, &mock);
|
| + ASSERT_HRESULT_SUCCEEDED(hr);
|
| + if (hr == S_FALSE)
|
| + return;
|
| +
|
| + ASSERT_TRUE(mock.web_browser2() != NULL);
|
| +
|
| + loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds);
|
| +
|
| + mock.Uninitialize();
|
| + chrome_frame_test::CloseAllIEWindows();
|
| +}
|
| +
|
|
|