summaryrefslogtreecommitdiffstats
path: root/chrome_frame/test/chrome_frame_unittests.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome_frame/test/chrome_frame_unittests.cc')
-rw-r--r--chrome_frame/test/chrome_frame_unittests.cc216
1 files changed, 196 insertions, 20 deletions
diff --git a/chrome_frame/test/chrome_frame_unittests.cc b/chrome_frame/test/chrome_frame_unittests.cc
index d43cd52..875695e 100644
--- a/chrome_frame/test/chrome_frame_unittests.cc
+++ b/chrome_frame/test/chrome_frame_unittests.cc
@@ -24,10 +24,12 @@
#include "chrome_frame/crash_reporting/vectored_handler-impl.h"
#include "chrome_frame/test/chrome_frame_test_utils.h"
#include "chrome_frame/test_utils.h"
-#include "chrome_frame/utils.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/installer/util/helper.h"
+
+#define GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
#include "testing/gmock_mutant.h"
+
using testing::CreateFunctor;
const wchar_t kDocRoot[] = L"chrome_frame\\test\\data";
@@ -73,6 +75,8 @@ _ATL_FUNC_INFO WebBrowserEventSink::kNewWindow3Info = {
}
};
+_ATL_FUNC_INFO WebBrowserEventSink::kVoidMethodInfo = {
+ CC_STDCALL, VT_EMPTY, 0, {NULL}};
void ChromeFrameTestWithWebServer::SetUp() {
server_.SetUp();
@@ -1334,8 +1338,45 @@ HRESULT LaunchIEAsComServer(IWebBrowser2** web_browser) {
}
// WebBrowserEventSink member defines
+STDMETHODIMP WebBrowserEventSink::OnBeforeNavigate2Internal(
+ IDispatch* dispatch, VARIANT* url, VARIANT* flags,
+ VARIANT* target_frame_name, VARIANT* post_data, VARIANT* headers,
+ VARIANT_BOOL* cancel) {
+ DLOG(INFO) << __FUNCTION__;
+ // Reset any existing reference to chrome frame since this is a new
+ // navigation.
+ chrome_frame_ = NULL;
+ return OnBeforeNavigate2(dispatch, url, flags, target_frame_name,
+ post_data, headers, cancel);
+}
+
+STDMETHODIMP_(void) WebBrowserEventSink::OnNavigateComplete2Internal(
+ IDispatch* dispatch, VARIANT* url) {
+ DLOG(INFO) << __FUNCTION__;
+ ConnectToChromeFrame();
+ OnNavigateComplete2(dispatch, url);
+}
+
+HRESULT WebBrowserEventSink::OnLoadInternal(const VARIANT* param) {
+ DLOG(INFO) << __FUNCTION__ << " " << param->bstrVal;
+ OnLoad(param->bstrVal);
+ return S_OK;
+}
+
+HRESULT WebBrowserEventSink::OnLoadErrorInternal(const VARIANT* param) {
+ DLOG(INFO) << __FUNCTION__ << " " << param->bstrVal;
+ OnLoadError(param->bstrVal);
+ return S_OK;
+}
+
+HRESULT WebBrowserEventSink::OnMessageInternal(const VARIANT* param) {
+ DLOG(INFO) << __FUNCTION__ << " " << param->bstrVal;
+ OnMessage(param->bstrVal);
+ return S_OK;
+}
+
HRESULT WebBrowserEventSink::LaunchIEAndNavigate(
- const std::wstring& navigate_url, _IDispEvent* sink) {
+ const std::wstring& navigate_url) {
int major_version = 0;
int minor_version = 0;
int bugfix_version = 0;
@@ -1351,19 +1392,47 @@ HRESULT WebBrowserEventSink::LaunchIEAndNavigate(
EXPECT_TRUE(S_OK == LaunchIEAsComServer(web_browser2_.Receive()));
web_browser2_->put_Visible(VARIANT_TRUE);
- HRESULT hr = sink->DispEventAdvise(web_browser2_,
- &DIID_DWebBrowserEvents2);
+ HRESULT hr = DispEventAdvise(web_browser2_, &DIID_DWebBrowserEvents2);
EXPECT_TRUE(hr == S_OK);
+ return Navigate(navigate_url);
+}
+HRESULT WebBrowserEventSink::Navigate(const std::wstring& navigate_url) {
VARIANT empty = ScopedVariant::kEmptyVariant;
ScopedVariant url;
url.Set(navigate_url.c_str());
+ HRESULT hr = S_OK;
hr = web_browser2_->Navigate2(url.AsInput(), &empty, &empty, &empty, &empty);
EXPECT_TRUE(hr == S_OK);
return hr;
}
+void WebBrowserEventSink::ConnectToChromeFrame() {
+ DCHECK(web_browser2_);
+ ScopedComPtr<IShellBrowser> shell_browser;
+ DoQueryService(SID_STopLevelBrowser, web_browser2_,
+ shell_browser.Receive());
+
+ if (shell_browser) {
+ ScopedComPtr<IShellView> shell_view;
+ shell_browser->QueryActiveShellView(shell_view.Receive());
+ if (shell_view) {
+ shell_view->GetItemObject(SVGIO_BACKGROUND, __uuidof(IChromeFrame),
+ reinterpret_cast<void**>(chrome_frame_.Receive()));
+ }
+
+ if (chrome_frame_) {
+ ScopedVariant onmessage(onmessage_.ToDispatch());
+ ScopedVariant onloaderror(onloaderror_.ToDispatch());
+ ScopedVariant onload(onload_.ToDispatch());
+ EXPECT_HRESULT_SUCCEEDED(chrome_frame_->put_onmessage(onmessage));
+ EXPECT_HRESULT_SUCCEEDED(chrome_frame_->put_onloaderror(onloaderror));
+ EXPECT_HRESULT_SUCCEEDED(chrome_frame_->put_onload(onload));
+ }
+ }
+}
+
const int kChromeFrameLaunchDelay = 5;
const int kChromeFrameLongNavigationTimeoutInSeconds = 10;
@@ -1402,6 +1471,10 @@ class MockWebBrowserEventSink : public WebBrowserEventSink {
VARIANT* frame_name,
VARIANT* status_code,
VARIANT* cancel));
+
+ 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
};
using testing::_;
@@ -1431,7 +1504,7 @@ TEST(ChromeFrameTest, FullTabModeIE_DisallowedUrls) {
QUIT_LOOP(loop),
testing::Return(S_OK)));
- HRESULT hr = mock.LaunchIEAndNavigate(kChromeFrameFileUrl, &mock);
+ HRESULT hr = mock.LaunchIEAndNavigate(kChromeFrameFileUrl);
ASSERT_HRESULT_SUCCEEDED(hr);
if (hr == S_FALSE)
return;
@@ -1455,29 +1528,34 @@ const wchar_t kChromeFrameFullTabWindowOpenPopupUrl[] =
// window.open target page is supposed to render within Chrome.
TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_WindowOpen) {
TimedMsgLoop loop;
-
CComObjectStackEx<MockWebBrowserEventSink> mock;
+ ::testing::InSequence sequence;
EXPECT_CALL(mock,
OnBeforeNavigate2(
_, testing::Field(&VARIANT::bstrVal,
testing::StrCaseEq(kChromeFrameFullTabWindowOpenTestUrl)),
_, _, _, _, _))
- .Times(1)
.WillOnce(testing::Return(S_OK));
+ EXPECT_CALL(mock, OnNavigateComplete2(_, _))
+ .WillOnce(testing::Return());
+ EXPECT_CALL(mock,
+ OnLoad(testing::StrEq(kChromeFrameFullTabWindowOpenTestUrl)))
+ .WillOnce(testing::Return());
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)));
+ .WillOnce(testing::Return(S_OK));
+ EXPECT_CALL(mock, OnNavigateComplete2(_, _))
+ .WillOnce(testing::Return());
+ EXPECT_CALL(mock,
+ OnLoad(testing::StrEq(kChromeFrameFullTabWindowOpenPopupUrl)))
+ .WillOnce(QUIT_LOOP_SOON(loop, 2));
- HRESULT hr = mock.LaunchIEAndNavigate(kChromeFrameFullTabWindowOpenTestUrl,
- &mock);
+ HRESULT hr = mock.LaunchIEAndNavigate(kChromeFrameFullTabWindowOpenTestUrl);
ASSERT_HRESULT_SUCCEEDED(hr);
if (hr == S_FALSE)
return;
@@ -1492,8 +1570,8 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_WindowOpen) {
chrome_frame_test::CloseAllIEWindows();
}
-const wchar_t kChromeFrameAboutBlankUrl[] =
- L"cf:about:blank";
+const wchar_t kSubFrameUrl1[] =
+ L"http://localhost:1337/files/sub_frame1.html";
const wchar_t kChromeFrameAboutVersion[] =
L"cf:about:version";
@@ -1510,18 +1588,17 @@ const wchar_t kChromeFrameAboutVersion[] =
// http://code.google.com/p/chromium/issues/detail?id=26549
TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_AboutChromeFrame) {
TimedMsgLoop loop;
-
CComObjectStackEx<MockWebBrowserEventSink> mock;
EXPECT_CALL(mock,
OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
- testing::StrCaseEq(kChromeFrameAboutBlankUrl)),
+ testing::StrCaseEq(kSubFrameUrl1)),
_, _, _, _, _))
.Times(1)
.WillOnce(testing::Return(S_OK));
-
EXPECT_CALL(mock, OnNavigateComplete2(_, _))
- .Times(1)
+ .WillOnce(testing::Return());
+ EXPECT_CALL(mock, OnLoad(testing::StrEq(kSubFrameUrl1)))
.WillOnce(testing::InvokeWithoutArgs(
&chrome_frame_test::ShowChromeFrameContextMenu));
@@ -1531,7 +1608,7 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_AboutChromeFrame) {
.Times(1)
.WillOnce(QUIT_LOOP(loop));
- HRESULT hr = mock.LaunchIEAndNavigate(kChromeFrameAboutBlankUrl, &mock);
+ HRESULT hr = mock.LaunchIEAndNavigate(kSubFrameUrl1);
ASSERT_HRESULT_SUCCEEDED(hr);
if (hr == S_FALSE)
return;
@@ -1565,3 +1642,102 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ChromeFrameKeyboardTest) {
ASSERT_TRUE(CheckResultFile(L"FullTab_KeyboardTest", "OK"));
}
+const wchar_t kSubFrameUrl2[] =
+ L"http://localhost:1337/files/sub_frame2.html";
+const wchar_t kSubFrameUrl3[] =
+ L"http://localhost:1337/files/sub_frame3.html";
+
+// Hack to pass a reference to the argument instead of value. Passing by
+// value evaluates the argument at the mock specification time which is
+// not always ideal. For e.g. At the time of mock creation, web_browser2_
+// pointer is not set up yet so by passing a reference to it instead of
+// a value we allow it to be created later.
+template <typename T> T** ReceivePointer(scoped_refptr<T>& p) { // NOLINT
+ return reinterpret_cast<T**>(&p);
+}
+
+// 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) {
+ TimedMsgLoop loop;
+ CComObjectStackEx<MockWebBrowserEventSink> mock;
+ ::testing::InSequence sequence; // Everything in sequence
+
+ // Navigate to url 2 after the previous navigation is complete
+ EXPECT_CALL(mock,
+ OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
+ testing::StrCaseEq(kSubFrameUrl1)),
+ _, _, _, _, _))
+ .WillOnce(testing::Return(S_OK));
+ EXPECT_CALL(mock, OnNavigateComplete2(_, _))
+ .WillOnce(testing::Return());
+ EXPECT_CALL(mock, OnLoad(testing::StrEq(kSubFrameUrl1)))
+ .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs(
+ CreateFunctor(&mock, &WebBrowserEventSink::Navigate,
+ std::wstring(kSubFrameUrl2)))));
+
+ // Navigate to url 3 after the previous navigation is complete
+ EXPECT_CALL(mock,
+ OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
+ testing::StrCaseEq(kSubFrameUrl2)),
+ _, _, _, _, _))
+ .WillOnce(testing::Return(S_OK));
+ EXPECT_CALL(mock, OnNavigateComplete2(_, _))
+ .WillOnce(testing::Return());
+ EXPECT_CALL(mock, OnLoad(testing::StrEq(kSubFrameUrl2)))
+ .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs(
+ CreateFunctor(&mock, &WebBrowserEventSink::Navigate,
+ std::wstring(kSubFrameUrl3)))));
+
+ // We have reached url 3 and have two back entries for url 1 & 2
+ // Go back to url 2 now
+ EXPECT_CALL(mock,
+ OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
+ testing::StrCaseEq(kSubFrameUrl3)),
+ _, _, _, _, _))
+ .WillOnce(testing::Return(S_OK));
+ EXPECT_CALL(mock, OnNavigateComplete2(_, _))
+ .WillOnce(testing::Return());
+ EXPECT_CALL(mock, OnLoad(testing::StrEq(kSubFrameUrl3)))
+ .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs(
+ CreateFunctor(ReceivePointer(mock.web_browser2_),
+ &IWebBrowser::GoBack))));
+
+ // We have reached url 2 and have 1 back & 1 forward entries for url 1 & 3
+ // Go back to url 1 now
+ EXPECT_CALL(mock,
+ OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
+ testing::StrCaseEq(kSubFrameUrl2)),
+ _, _, _, _, _))
+ .WillOnce(testing::Return(S_OK));
+ EXPECT_CALL(mock, OnNavigateComplete2(_, _))
+ .WillOnce(testing::Return());
+ EXPECT_CALL(mock, OnLoad(testing::StrEq(kSubFrameUrl2)))
+ .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs(
+ CreateFunctor(ReceivePointer(mock.web_browser2_),
+ &IWebBrowser::GoBack))));
+
+ // We have reached url 1 and have 0 back & 2 forward entries for url 2 & 3
+ // Go back to url 1 now
+ EXPECT_CALL(mock,
+ OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
+ testing::StrCaseEq(kSubFrameUrl1)),
+ _, _, _, _, _));
+ EXPECT_CALL(mock, OnNavigateComplete2(_, _))
+ .WillOnce(testing::Return());
+ EXPECT_CALL(mock, OnLoad(testing::StrEq(kSubFrameUrl1)))
+ .WillOnce(QUIT_LOOP_SOON(loop, 2));
+
+ HRESULT hr = mock.LaunchIEAndNavigate(kSubFrameUrl1);
+ ASSERT_HRESULT_SUCCEEDED(hr);
+ if (hr == S_FALSE)
+ return;
+
+ ASSERT_TRUE(mock.web_browser2() != NULL);
+
+ loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds);
+
+ mock.Uninitialize();
+ chrome_frame_test::CloseAllIEWindows();
+}
+