summaryrefslogtreecommitdiffstats
path: root/chrome_frame
diff options
context:
space:
mode:
authorananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-29 21:46:21 +0000
committerananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-29 21:46:21 +0000
commitcb4b1e0d5f1e80938a19fbe837b5a1535cd80b60 (patch)
treef4b556d31ef4d6625370b30e29e99dcb724d319a /chrome_frame
parent3782951259d8a3ab02c379754e6c55b622d2bc8e (diff)
downloadchromium_src-cb4b1e0d5f1e80938a19fbe837b5a1535cd80b60.zip
chromium_src-cb4b1e0d5f1e80938a19fbe837b5a1535cd80b60.tar.gz
chromium_src-cb4b1e0d5f1e80938a19fbe837b5a1535cd80b60.tar.bz2
Added unit tests for ChromeFrame IE full tab mode. These test the following cases:-
1. A window.open call issued from a page within ChromeFrame in IE full tab mode makes it back to IE before being shunted into Chrome. 2. Brings up the chrome frame context menu in full tab mode and invokes the About Chrome frame option. While I was working on these tests based on a lot of help from Stoyan, we had these tests use gmock and I also changed the disallowed URL test to use gmock. The other changes are to always run the chrome frame tests in the STA apartment as the newly added full tab mode tests cannot handle calls coming in from background RPC worker threads. Bug=26066,26172 Review URL: http://codereview.chromium.org/340029 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30520 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame')
-rw-r--r--chrome_frame/test/chrome_frame_test_utils.cc63
-rw-r--r--chrome_frame/test/chrome_frame_test_utils.h12
-rw-r--r--chrome_frame/test/chrome_frame_unittests.cc229
-rw-r--r--chrome_frame/test/chrome_frame_unittests.h60
-rw-r--r--chrome_frame/test/data/chrome_frame_tester_helpers.js26
-rw-r--r--chrome_frame/test/data/chrome_frame_window_open.html33
-rw-r--r--chrome_frame/test/data/chrome_frame_window_open_popup.html22
-rw-r--r--chrome_frame/test/run_all_unittests.cc4
8 files changed, 390 insertions, 59 deletions
diff --git a/chrome_frame/test/chrome_frame_test_utils.cc b/chrome_frame/test/chrome_frame_test_utils.cc
index 2b350dd..bd33db6 100644
--- a/chrome_frame/test/chrome_frame_test_utils.cc
+++ b/chrome_frame/test/chrome_frame_test_utils.cc
@@ -8,12 +8,14 @@
#include <atlwin.h>
#include <iepmapi.h>
+#include "base/message_loop.h"
#include "base/registry.h" // to find IE and firefox
#include "base/scoped_handle.h"
#include "base/scoped_comptr_win.h"
#include "base/string_util.h"
#include "base/win_util.h"
#include "chrome/common/chrome_switches.h"
+#include "testing/gtest/include/gtest/gtest.h"
namespace chrome_frame_test {
@@ -412,4 +414,65 @@ int CloseAllIEWindows() {
return ret;
}
+void ShowChromeFrameContextMenuTask() {
+ static const int kChromeFrameContextMenuTimeout = 500;
+ HWND renderer_window = GetChromeRendererWindow();
+ EXPECT_TRUE(IsWindow(renderer_window));
+
+ // Bring up the context menu in the Chrome renderer window.
+ PostMessage(renderer_window, WM_RBUTTONDOWN, MK_RBUTTON, MAKELPARAM(50, 50));
+ PostMessage(renderer_window, WM_RBUTTONUP, MK_RBUTTON, MAKELPARAM(50, 50));
+
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ NewRunnableFunction(SelectAboutChromeFrame),
+ kChromeFrameContextMenuTimeout);
+}
+
+void ShowChromeFrameContextMenu() {
+ static const int kContextMenuDelay = 5000;
+
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ NewRunnableFunction(ShowChromeFrameContextMenuTask),
+ kContextMenuDelay);
+}
+
+void SelectAboutChromeFrame() {
+ // Send a key up message to enable the About chrome frame option to be
+ // selected followed by a return to select it.
+ chrome_frame_test::SendVirtualKey(VK_UP);
+ chrome_frame_test::SendVirtualKey(VK_RETURN);
+}
+
+BOOL CALLBACK FindChromeRendererWindowProc(
+ HWND window, LPARAM lParam) {
+ HWND* target_window = reinterpret_cast<HWND*>(lParam);
+ wchar_t class_name[MAX_PATH] = {0};
+
+ GetClassName(window, class_name, arraysize(class_name));
+ if (!_wcsicmp(class_name, L"Chrome_RenderWidgetHostHWND")) {
+ *target_window = window;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL CALLBACK EnumHostBrowserWindowProc(
+ HWND window, LPARAM lParam) {
+ EnumChildWindows(window, FindChromeRendererWindowProc, lParam);
+ HWND* target_window = reinterpret_cast<HWND*>(lParam);
+ if (IsWindow(*target_window))
+ return FALSE;
+ return TRUE;
+}
+
+HWND GetChromeRendererWindow() {
+ HWND chrome_window = NULL;
+ EnumWindows(EnumHostBrowserWindowProc,
+ reinterpret_cast<LPARAM>(&chrome_window));
+ return chrome_window;
+}
+
} // namespace chrome_frame_test
diff --git a/chrome_frame/test/chrome_frame_test_utils.h b/chrome_frame/test/chrome_frame_test_utils.h
index 95e0c9b..a9e1b3a 100644
--- a/chrome_frame/test/chrome_frame_test_utils.h
+++ b/chrome_frame/test/chrome_frame_test_utils.h
@@ -56,6 +56,18 @@ extern const wchar_t kOperaImageName[];
extern const wchar_t kSafariImageName[];
extern const wchar_t kChromeImageName[];
+// Displays the chrome frame context menu by posting mouse move messages to
+// Chrome
+void ShowChromeFrameContextMenu();
+
+// Sends keyboard messages to the chrome frame context menu to select the About
+// Chrome frame option.
+void SelectAboutChromeFrame();
+
+// Returns a handle to the chrome frame render widget child window.
+// Returns NULL on failure.
+HWND GetChromeRendererWindow();
+
} // namespace chrome_frame_test
#endif // CHROME_FRAME_CHROMETAB_UNITTESTS_CF_TEST_UTILS_H_
diff --git a/chrome_frame/test/chrome_frame_unittests.cc b/chrome_frame/test/chrome_frame_unittests.cc
index 14eb757..1d6dfe3 100644
--- a/chrome_frame/test/chrome_frame_unittests.cc
+++ b/chrome_frame/test/chrome_frame_unittests.cc
@@ -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::kBeforeNavigate2Info = {
}
};
+_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 @@ template <> struct RunnableMethodTraits<ChromeFrameAutomationClient> {
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 @@ struct TimedMsgLoop {
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 @@ template <> struct RunnableMethodTraits<TimedMsgLoop> {
#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 @@ HRESULT LaunchIEAsComServer(IWebBrowser2** web_browser) {
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 @@ TEST(ChromeFrameTest, FullTabModeIE_DisallowedUrls) {
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);
-
- ScopedComPtr<IWebBrowser2> web_browser2;
- EXPECT_TRUE(S_OK == LaunchIEAsComServer(web_browser2.Receive()));
- web_browser2->put_Visible(VARIANT_TRUE);
+ 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;
+
+ EXPECT_CALL(mock,
+ OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
+ testing::StrCaseEq(kChromeFrameFileUrl)),
+ _, _, _, _, _))
+ .Times(1)
+ .WillOnce(testing::Return(S_OK));
- hr = web_browser2->Navigate2(url.AsInput(), &empty, &empty, &empty, &empty);
- EXPECT_TRUE(hr == S_OK);
+ EXPECT_CALL(mock,
+ OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
+ testing::StartsWith(L"res:")),
+ _, _, _, _, _))
+ .Times(1)
+ .WillOnce(testing::DoAll(
+ QUIT_LOOP(loop),
+ testing::Return(S_OK)));
- loop.RunFor(10);
+ HRESULT hr = mock.LaunchIEAndNavigate(kChromeFrameFileUrl, &mock);
+ ASSERT_HRESULT_SUCCEEDED(hr);
+ if (hr == S_FALSE)
+ return;
- EXPECT_TRUE(web_browser_sink->navigation_failed());
+ ASSERT_TRUE(mock.web_browser2() != NULL);
- hr = web_browser_sink->DispEventUnadvise(web_browser2);
- EXPECT_TRUE(hr == S_OK);
+ loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds);
- web_browser2.Release();
+ 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();
}
diff --git a/chrome_frame/test/chrome_frame_unittests.h b/chrome_frame/test/chrome_frame_unittests.h
index 98b5985..9dcaadc 100644
--- a/chrome_frame/test/chrome_frame_unittests.h
+++ b/chrome_frame/test/chrome_frame_unittests.h
@@ -11,6 +11,7 @@
#include <exdispid.h>
#include "base/ref_counted.h"
+#include "base/scoped_comptr_win.h"
#include "base/scoped_handle_win.h"
#include "googleurl/src/gurl.h"
#include "chrome_frame/test/http_server.h"
@@ -94,18 +95,34 @@ class ChromeFrameTestWithWebServer: public testing::Test {
// subscribes to the following events:-
// 1. DISPID_BEFORENAVIGATE2
// 2. DISPID_NAVIGATEERROR
-// 3. DISPID_NAVIGATECOMPLETE2
+// 3. DISPID_NAVIGATECOMPLETE2
+// 4. DISPID_NEWWINDOW3
// Other events can be subscribed to on an if needed basis.
class WebBrowserEventSink
: public CComObjectRootEx<CComSingleThreadModel>,
public IDispEventSimpleImpl<0, WebBrowserEventSink,
&DIID_DWebBrowserEvents2> {
public:
- WebBrowserEventSink()
- : navigation_failed_(false),
- main_thread_id_(0) {
+ typedef IDispEventSimpleImpl<0, WebBrowserEventSink,
+ &DIID_DWebBrowserEvents2> DispEventsImpl;
+ WebBrowserEventSink() {}
+ ~WebBrowserEventSink() {
+ Uninitialize();
}
+ void Uninitialize() {
+ if (web_browser2_.get()) {
+ DispEventUnadvise(web_browser2_);
+ web_browser2_.Release();
+ }
+ }
+
+ // Helper function to launch IE and navigate to a URL.
+ // Returns S_OK on success, S_FALSE if the test was not run, other
+ // errors on failure.
+ HRESULT LaunchIEAndNavigate(const std::wstring& navigate_url,
+ _IDispEvent* sink);
+
BEGIN_COM_MAP(WebBrowserEventSink)
END_COM_MAP()
@@ -116,12 +133,14 @@ BEGIN_SINK_MAP(WebBrowserEventSink)
OnNavigateComplete2, &kNavigateComplete2Info)
SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_NAVIGATEERROR,
OnNavigateError, &kNavigateErrorInfo)
+ SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_NEWWINDOW3,
+ OnNewWindow3, &kNewWindow3Info)
END_SINK_MAP()
STDMETHOD_(void, OnNavigateError)(IDispatch* dispatch, VARIANT* url,
VARIANT* frame_name, VARIANT* status_code,
VARIANT* cancel) {
- navigation_failed_ = true;
+ DLOG(INFO) << __FUNCTION__;
}
STDMETHOD(OnBeforeNavigate2)(IDispatch* dispatch, VARIANT* url, VARIANT*
@@ -129,13 +148,6 @@ END_SINK_MAP()
VARIANT* post_data, VARIANT* headers,
VARIANT_BOOL* cancel) {
DLOG(INFO) << __FUNCTION__;
- // 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.
- GURL crack_url(url->bstrVal);
- if (crack_url.scheme() == "res") {
- navigation_failed_ = true;
- }
return S_OK;
}
@@ -143,21 +155,31 @@ END_SINK_MAP()
DLOG(INFO) << __FUNCTION__;
}
- bool navigation_failed() const {
- return navigation_failed_;
+ STDMETHOD_(void, OnNewWindow3)(IDispatch** dispatch, VARIANT_BOOL* Cancel,
+ DWORD flags, BSTR url_context, BSTR url) {
+ DLOG(INFO) << __FUNCTION__;
}
- void set_main_thread_id(DWORD thread_id) {
- main_thread_id_ = thread_id;
+#ifdef _DEBUG
+ STDMETHOD(Invoke)(DISPID dispid, REFIID riid,
+ LCID lcid, WORD flags, DISPPARAMS* params, VARIANT* result,
+ EXCEPINFO* except_info, UINT* arg_error) {
+ DLOG(INFO) << __FUNCTION__ << L" disp id :" << dispid;
+ return DispEventsImpl::Invoke(dispid, riid, lcid, flags, params, result,
+ except_info, arg_error);
}
+#endif // _DEBUG
- protected:
- bool navigation_failed_;
+ IWebBrowser2* web_browser2() {
+ return web_browser2_.get();
+ }
+ protected:
static _ATL_FUNC_INFO kBeforeNavigate2Info;
static _ATL_FUNC_INFO kNavigateComplete2Info;
static _ATL_FUNC_INFO kNavigateErrorInfo;
- DWORD main_thread_id_;
+ static _ATL_FUNC_INFO kNewWindow3Info;
+ ScopedComPtr<IWebBrowser2> web_browser2_;
};
#endif // CHROME_FRAME_TEST_CHROME_FRAME_UNITTESTS_H_
diff --git a/chrome_frame/test/data/chrome_frame_tester_helpers.js b/chrome_frame/test/data/chrome_frame_tester_helpers.js
index 1c914ee..67df52a 100644
--- a/chrome_frame/test/data/chrome_frame_tester_helpers.js
+++ b/chrome_frame/test/data/chrome_frame_tester_helpers.js
@@ -13,8 +13,8 @@ function getXHRObject(){
var XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP',
'Msxml2.XMLHTTP.4.0'];
var http = null;
- try {
- http = new XMLHttpRequest();
+ try {
+ http = new XMLHttpRequest();
} catch(e) {
}
@@ -26,10 +26,10 @@ function getXHRObject(){
try {
http = new ActiveXObject(progid);
} catch(e) {
- }
-
- if (http)
- break;
+ }
+
+ if (http)
+ break;
}
return http;
}
@@ -69,7 +69,7 @@ function writeToServer(name, result) {
appendStatus("XHR send failed. Error: " + e.description);
}
}
-
+
function postResult(name, result) {
writeToServer(name, result);
// NOTE:
@@ -77,7 +77,7 @@ function postResult(name, result) {
shutdownServer();
}
-// Finish running a test by setting the status
+// Finish running a test by setting the status
// and the cookie.
function onFinished(name, id, result) {
appendStatus(result);
@@ -85,7 +85,7 @@ function onFinished(name, id, result) {
// set a cookie to report the results...
var cookie = name + "." + id + ".status=" + result + "; path=/";
document.cookie = cookie;
-
+
// ...and POST the status back to the server
postResult(name, result);
}
@@ -140,3 +140,11 @@ function reloadUsingCFProtocol() {
window.location = redirect_location;
}
+function TestIfRunningInChrome() {
+ var is_chrome = /chrome/.test(navigator.userAgent.toLowerCase());
+ if (!is_chrome) {
+ onFailure("ChromeFrameWindowOpen", "Window Open failed :-(",
+ "User agent = " + navigator.userAgent.toLowerCase());
+ }
+ return is_chrome;
+}
diff --git a/chrome_frame/test/data/chrome_frame_window_open.html b/chrome_frame/test/data/chrome_frame_window_open.html
new file mode 100644
index 0000000..8102d5c
--- /dev/null
+++ b/chrome_frame/test/data/chrome_frame_window_open.html
@@ -0,0 +1,33 @@
+<!-- saved from url=(0014)about:internet -->
+<!-- Note that for the above Mark of the Web to work, the comment must
+ be followed by a CR/LF ending, so please do not change the line endings. -->
+<html>
+<!-- This page is meant to load inside a host browser like IE/FF -->
+<head>
+<meta http-equiv="X-UA-Compatible" content="chrome=1"/>
+<script type="text/javascript" src="chrome_frame_tester_helpers.js"></script>
+<script type="text/javascript">
+
+function onLoad() {
+ if (!TestIfRunningInChrome()) {
+ onFailure("ChromeFrameWindowOpen", "Window Open failed :-(",
+ "User agent = " + navigator.userAgent.toLowerCase());
+ } else {
+ setTimeout(OpenPopup, 100);
+ }
+}
+
+function OpenPopup() {
+ window.open("chrome_frame_window_open_popup.html", "_self");
+}
+</script>
+</head>
+
+<body onload="onLoad();">
+<div id="statusPanel" style="border: 1px solid red; width: 100%">
+ChromeFrame full tab mode window open test running....
+</div>
+<p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/chrome_frame/test/data/chrome_frame_window_open_popup.html b/chrome_frame/test/data/chrome_frame_window_open_popup.html
new file mode 100644
index 0000000..22b4bbf
--- /dev/null
+++ b/chrome_frame/test/data/chrome_frame_window_open_popup.html
@@ -0,0 +1,22 @@
+<html>
+<head>
+<meta http-equiv="x-ua-compatible" content="chrome=1" />
+ <title>ChromeFrame window open popup</title>
+<script type="text/javascript" src="chrome_frame_tester_helpers.js"></script>
+<script type="text/javascript">
+function onLoad() {
+ if (!TestIfRunningInChrome()) {
+ onFailure("ChromeFrameWindowOpenPopup",
+ "Window Open failed to enter Chrome:-(",
+ "User agent = " + navigator.userAgent.toLowerCase());
+ } else {
+ onSuccess("ChromeFrameWindowOpenPopup", 1);
+ }
+}
+
+</script>
+</head>
+<body onload="onLoad();">
+ChromeFrame full tab mode window open popup test
+</body>
+</html>
diff --git a/chrome_frame/test/run_all_unittests.cc b/chrome_frame/test/run_all_unittests.cc
index 6c2abe9..f5f479d 100644
--- a/chrome_frame/test/run_all_unittests.cc
+++ b/chrome_frame/test/run_all_unittests.cc
@@ -18,6 +18,10 @@
// To enable ATL-based code to run in this module
class ChromeFrameUnittestsModule
: public CAtlExeModuleT<ChromeFrameUnittestsModule> {
+ public:
+ static HRESULT InitializeCom() {
+ return CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ }
};
ChromeFrameUnittestsModule _AtlModule;