| Index: chrome_frame/test/chrome_frame_unittests.cc
|
| ===================================================================
|
| --- chrome_frame/test/chrome_frame_unittests.cc (revision 0)
|
| +++ chrome_frame/test/chrome_frame_unittests.cc (revision 0)
|
| @@ -0,0 +1,1510 @@
|
| +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +#include <windows.h>
|
| +#include <stdarg.h>
|
| +
|
| +// IShellWindows includes. Unfortunately we can't keep these in
|
| +// alphabetic order since exdisp will bark if some interfaces aren't fully
|
| +// defined.
|
| +#include <mshtml.h>
|
| +#include <exdisp.h>
|
| +
|
| +#include "base/basictypes.h"
|
| +#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"
|
| +#include "net/url_request/url_request_unittest.h"
|
| +#include "chrome_frame/test/chrome_frame_unittests.h"
|
| +#include "chrome_frame/chrome_frame_automation.h"
|
| +#include "chrome_frame/chrome_frame_delegate.h"
|
| +#include "chrome_frame/test/chrome_frame_test_utils.h"
|
| +#include "chrome_frame/test/helper_gmock.h"
|
| +#include "chrome_frame/test_utils.h"
|
| +#include "chrome_frame/utils.h"
|
| +#include "chrome_frame/vectored_handler-impl.h"
|
| +#include "chrome/installer/util/install_util.h"
|
| +#include "chrome/installer/util/helper.h"
|
| +
|
| +const wchar_t kDocRoot[] = L"chrome_frame\\test\\data";
|
| +const int kLongWaitTimeout = 60 * 1000;
|
| +const int kShortWaitTimeout = 25 * 1000;
|
| +
|
| +_ATL_FUNC_INFO WebBrowserEventSink::kNavigateErrorInfo = {
|
| + CC_STDCALL, VT_EMPTY, 5, {
|
| + VT_DISPATCH,
|
| + VT_VARIANT | VT_BYREF,
|
| + VT_VARIANT | VT_BYREF,
|
| + VT_VARIANT | VT_BYREF,
|
| + VT_BOOL | VT_BYREF,
|
| + }
|
| +};
|
| +
|
| +_ATL_FUNC_INFO WebBrowserEventSink::kNavigateComplete2Info = {
|
| + CC_STDCALL, VT_EMPTY, 2, {
|
| + VT_DISPATCH,
|
| + VT_VARIANT | VT_BYREF
|
| + }
|
| +};
|
| +
|
| +_ATL_FUNC_INFO WebBrowserEventSink::kBeforeNavigate2Info = {
|
| + CC_STDCALL, VT_EMPTY, 7, {
|
| + VT_DISPATCH,
|
| + VT_VARIANT | VT_BYREF,
|
| + VT_VARIANT | VT_BYREF,
|
| + VT_VARIANT | VT_BYREF,
|
| + VT_VARIANT | VT_BYREF,
|
| + VT_VARIANT | VT_BYREF,
|
| + VT_BOOL | VT_BYREF
|
| + }
|
| +};
|
| +
|
| +
|
| +
|
| +void ChromeFrameTestWithWebServer::SetUp() {
|
| + server_.SetUp();
|
| + results_dir_ = server_.GetDataDir();
|
| + file_util::AppendToPath(&results_dir_, L"dump");
|
| +}
|
| +
|
| +void ChromeFrameTestWithWebServer::TearDown() {
|
| + CloseBrowser();
|
| +
|
| + // Web browsers tend to relaunch themselves in other processes, meaning the
|
| + // KillProcess stuff above might not have actually cleaned up all our browser
|
| + // instances, so make really sure browsers are dead.
|
| + base::KillProcesses(chrome_frame_test::kIEImageName, 0, NULL);
|
| + base::KillProcesses(chrome_frame_test::kIEBrokerImageName, 0, NULL);
|
| + base::KillProcesses(chrome_frame_test::kFirefoxImageName, 0, NULL);
|
| + base::KillProcesses(chrome_frame_test::kSafariImageName, 0, NULL);
|
| + base::KillProcesses(chrome_frame_test::kChromeImageName, 0, NULL);
|
| +
|
| + server_.TearDown();
|
| +}
|
| +
|
| +bool ChromeFrameTestWithWebServer::LaunchBrowser(BrowserKind browser,
|
| + const wchar_t* page) {
|
| + std::wstring url = UTF8ToWide(server_.Resolve(page).spec());
|
| + browser_ = browser;
|
| + if (browser == IE) {
|
| + browser_handle_.Set(chrome_frame_test::LaunchIE(url));
|
| + } else if (browser == FIREFOX) {
|
| + browser_handle_.Set(chrome_frame_test::LaunchFirefox(url));
|
| + } else if (browser == OPERA) {
|
| + browser_handle_.Set(chrome_frame_test::LaunchOpera(url));
|
| + } else if (browser == SAFARI) {
|
| + browser_handle_.Set(chrome_frame_test::LaunchSafari(url));
|
| + } else if (browser == CHROME) {
|
| + browser_handle_.Set(chrome_frame_test::LaunchChrome(url));
|
| + } else {
|
| + NOTREACHED();
|
| + }
|
| +
|
| + return browser_handle_.IsValid();
|
| +}
|
| +
|
| +void ChromeFrameTestWithWebServer::CloseBrowser() {
|
| + if (!browser_handle_.IsValid())
|
| + return;
|
| +
|
| + int attempts = 0;
|
| + if (browser_ == IE) {
|
| + attempts = chrome_frame_test::CloseAllIEWindows();
|
| + } else {
|
| + attempts = chrome_frame_test::CloseVisibleWindowsOnAllThreads(
|
| + browser_handle_);
|
| + }
|
| +
|
| + if (attempts > 0) {
|
| + DWORD wait = ::WaitForSingleObject(browser_handle_, 20000);
|
| + if (wait == WAIT_OBJECT_0) {
|
| + browser_handle_.Close();
|
| + } else {
|
| + DLOG(ERROR) << "WaitForSingleObject returned " << wait;
|
| + }
|
| + } else {
|
| + DLOG(ERROR) << "No attempts to close browser windows";
|
| + }
|
| +
|
| + if (browser_handle_.IsValid()) {
|
| + DWORD exit_code = 0;
|
| + if (!::GetExitCodeProcess(browser_handle_, &exit_code) ||
|
| + exit_code == STILL_ACTIVE) {
|
| + DLOG(ERROR) << L"Forcefully killing browser process. Exit:" << exit_code;
|
| + base::KillProcess(browser_handle_, 0, true);
|
| + }
|
| + browser_handle_.Close();
|
| + }
|
| +}
|
| +
|
| +bool ChromeFrameTestWithWebServer::BringBrowserToTop() {
|
| + return chrome_frame_test::EnsureProcessInForeground(GetProcessId(
|
| + browser_handle_));
|
| +}
|
| +
|
| +bool ChromeFrameTestWithWebServer::WaitForTestToComplete(int milliseconds) {
|
| + return server_.WaitToFinish(milliseconds);
|
| +}
|
| +
|
| +bool ChromeFrameTestWithWebServer::WaitForOnLoad(int milliseconds) {
|
| + DWORD start = ::GetTickCount();
|
| + std::string data;
|
| + while (!ReadResultFile(L"OnLoadEvent", &data) || data.length() == 0) {
|
| + DWORD now = ::GetTickCount();
|
| + if (start > now) {
|
| + // Very simple check for overflow. In that case we just restart the
|
| + // wait.
|
| + start = now;
|
| + } else if (static_cast<int>(now - start) > milliseconds) {
|
| + break;
|
| + }
|
| + Sleep(100);
|
| + }
|
| +
|
| + return data.compare("loaded") == 0;
|
| +}
|
| +
|
| +bool ChromeFrameTestWithWebServer::ReadResultFile(const std::wstring& file_name,
|
| + std::string* data) {
|
| + std::wstring full_path = results_dir_;
|
| + file_util::AppendToPath(&full_path, file_name);
|
| + return file_util::ReadFileToString(full_path, data);
|
| +}
|
| +
|
| +bool ChromeFrameTestWithWebServer::CheckResultFile(
|
| + const std::wstring& file_name, const std::string& expected_result) {
|
| + std::string data;
|
| + bool ret = ReadResultFile(file_name, &data);
|
| + if (ret)
|
| + ret = (data == expected_result);
|
| +
|
| + if (!ret) {
|
| + DLOG(ERROR) << "Error text: " << (data.empty() ? "<empty>" : data.c_str());
|
| + }
|
| +
|
| + return ret;
|
| +}
|
| +
|
| +void ChromeFrameTestWithWebServer::SimpleBrowserTest(BrowserKind browser,
|
| + const wchar_t* page, const wchar_t* result_file_to_check) {
|
| + EXPECT_TRUE(LaunchBrowser(browser, page));
|
| + ASSERT_TRUE(WaitForTestToComplete(kLongWaitTimeout));
|
| + ASSERT_TRUE(CheckResultFile(result_file_to_check, "OK"));
|
| +}
|
| +
|
| +void ChromeFrameTestWithWebServer::OptionalBrowserTest(BrowserKind browser,
|
| + const wchar_t* page, const wchar_t* result_file_to_check) {
|
| + if (!LaunchBrowser(browser, page)) {
|
| + DLOG(ERROR) << "Failed to launch browser " << ToString(browser);
|
| + } else {
|
| + ASSERT_TRUE(WaitForTestToComplete(kLongWaitTimeout));
|
| + ASSERT_TRUE(CheckResultFile(result_file_to_check, "OK"));
|
| + }
|
| +}
|
| +
|
| +void ChromeFrameTestWithWebServer::VersionTest(BrowserKind browser,
|
| + const wchar_t* page, const wchar_t* result_file_to_check) {
|
| + std::wstring plugin_path;
|
| + PathService::Get(base::DIR_MODULE, &plugin_path);
|
| + file_util::AppendToPath(&plugin_path, L"servers/npchrome_tab.dll");
|
| +
|
| + static FileVersionInfo* version_info =
|
| + FileVersionInfo::CreateFileVersionInfo(plugin_path);
|
| +
|
| + std::wstring version;
|
| + if (version_info)
|
| + version = version_info->product_version();
|
| +
|
| + // If we can't find the npchrome_tab.dll in the src tree, we turn to
|
| + // the directory where chrome is installed.
|
| + if (!version_info) {
|
| + installer::Version* ver_system = InstallUtil::GetChromeVersion(true);
|
| + installer::Version* ver_user = InstallUtil::GetChromeVersion(false);
|
| + ASSERT_TRUE(ver_system || ver_user);
|
| +
|
| + bool system_install = ver_system ? true : false;
|
| + std::wstring npchrome_path(installer::GetChromeInstallPath(system_install));
|
| + file_util::AppendToPath(&npchrome_path,
|
| + ver_system ? ver_system->GetString() : ver_user->GetString());
|
| + file_util::AppendToPath(&npchrome_path, L"npchrome_tab.dll");
|
| + version_info = FileVersionInfo::CreateFileVersionInfo(npchrome_path);
|
| + if (version_info)
|
| + version = version_info->product_version();
|
| + }
|
| +
|
| + EXPECT_TRUE(version_info);
|
| + EXPECT_FALSE(version.empty());
|
| + EXPECT_TRUE(LaunchBrowser(browser, page));
|
| + ASSERT_TRUE(WaitForTestToComplete(kLongWaitTimeout));
|
| + ASSERT_TRUE(CheckResultFile(result_file_to_check, WideToUTF8(version)));
|
| +}
|
| +
|
| +const wchar_t kPostMessageBasicPage[] = L"files/postmessage_basic_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_PostMessageBasic) {
|
| + SimpleBrowserTest(IE, kPostMessageBasicPage, L"PostMessage");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_PostMessageBasic) {
|
| + SimpleBrowserTest(FIREFOX, kPostMessageBasicPage, L"PostMessage");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeOpera_PostMessageBasic) {
|
| + OptionalBrowserTest(OPERA, kPostMessageBasicPage, L"PostMessage");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, FullTabIE_MIMEFilterBasic) {
|
| + const wchar_t kMIMEFilterBasicPage[] =
|
| + L"files/chrome_frame_mime_filter_test.html";
|
| +
|
| + SimpleBrowserTest(IE, kMIMEFilterBasicPage, L"MIMEFilter");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_Resize) {
|
| + SimpleBrowserTest(IE, L"files/chrome_frame_resize.html", L"Resize");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_Resize) {
|
| + SimpleBrowserTest(FIREFOX, L"files/chrome_frame_resize.html", L"Resize");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeOpera_Resize) {
|
| + OptionalBrowserTest(OPERA, L"files/chrome_frame_resize.html", L"Resize");
|
| +}
|
| +
|
| +const wchar_t kNavigateURLAbsolutePage[] =
|
| + L"files/navigateurl_absolute_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_NavigateURLAbsolute) {
|
| + SimpleBrowserTest(IE, kNavigateURLAbsolutePage, L"NavigateURL");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_NavigateURLAbsolute) {
|
| + SimpleBrowserTest(FIREFOX, kNavigateURLAbsolutePage, L"NavigateURL");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeOpera_NavigateURLAbsolute) {
|
| + OptionalBrowserTest(OPERA, kNavigateURLAbsolutePage, L"NavigateURL");
|
| +}
|
| +
|
| +const wchar_t kNavigateURLRelativePage[] =
|
| + L"files/navigateurl_relative_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_NavigateURLRelative) {
|
| + SimpleBrowserTest(IE, kNavigateURLRelativePage, L"NavigateURL");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_NavigateURLRelative) {
|
| + SimpleBrowserTest(FIREFOX, kNavigateURLRelativePage, L"NavigateURL");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeOpera_NavigateURLRelative) {
|
| + OptionalBrowserTest(OPERA, kNavigateURLRelativePage, L"NavigateURL");
|
| +}
|
| +
|
| +const wchar_t kNavigateSimpleObjectFocus[] = L"files/simple_object_focus.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_ObjectFocus) {
|
| + SimpleBrowserTest(FIREFOX, kNavigateSimpleObjectFocus, L"ObjectFocus");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_ObjectFocus) {
|
| + SimpleBrowserTest(IE, kNavigateSimpleObjectFocus, L"ObjectFocus");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeOpera_ObjectFocus) {
|
| + if (!LaunchBrowser(OPERA, kNavigateSimpleObjectFocus)) {
|
| + DLOG(ERROR) << "Failed to launch browser " << ToString(OPERA);
|
| + } else {
|
| + ASSERT_TRUE(WaitForOnLoad(kLongWaitTimeout));
|
| + BringBrowserToTop();
|
| + // Tab through a couple of times. Once should be enough in theory
|
| + // but in practice activating the browser can take a few milliseconds more.
|
| + bool ok;
|
| + for (int i = 0;
|
| + i < 5 && (ok = CheckResultFile(L"ObjectFocus", "OK")) == false;
|
| + ++i) {
|
| + Sleep(300);
|
| + chrome_frame_test::SendMnemonic(VK_TAB, false, false, false);
|
| + }
|
| + ASSERT_TRUE(ok);
|
| + }
|
| +}
|
| +
|
| +const wchar_t kiframeBasicPage[] = L"files/iframe_basic_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_iframeBasic) {
|
| + SimpleBrowserTest(IE, kiframeBasicPage, L"PostMessage");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_iframeBasic) {
|
| + SimpleBrowserTest(FIREFOX, kiframeBasicPage, L"PostMessage");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeOpera_iframeBasic) {
|
| + OptionalBrowserTest(OPERA, kiframeBasicPage, L"PostMessage");
|
| +}
|
| +
|
| +const wchar_t kSrcPropertyTestPage[] = L"files/src_property_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_SrcProperty) {
|
| + SimpleBrowserTest(IE, kSrcPropertyTestPage, L"SrcProperty");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_SrcProperty) {
|
| + SimpleBrowserTest(FIREFOX, kSrcPropertyTestPage, L"SrcProperty");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeOpera_SrcProperty) {
|
| + OptionalBrowserTest(OPERA, kSrcPropertyTestPage, L"SrcProperty");
|
| +}
|
| +
|
| +const wchar_t kCFInstanceBasicTestPage[] = L"files/CFInstance_basic_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceBasic) {
|
| + SimpleBrowserTest(IE, kCFInstanceBasicTestPage, L"CFInstanceBasic");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_CFInstanceBasic) {
|
| + SimpleBrowserTest(FIREFOX, kCFInstanceBasicTestPage, L"CFInstanceBasic");
|
| +}
|
| +
|
| +const wchar_t kCFISingletonPage[] = L"files/CFInstance_singleton_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceSingleton) {
|
| + SimpleBrowserTest(IE, kCFISingletonPage, L"CFInstanceSingleton");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_CFInstanceSingleton) {
|
| + SimpleBrowserTest(FIREFOX, kCFISingletonPage, L"CFInstanceSingleton");
|
| +}
|
| +
|
| +const wchar_t kCFIDelayPage[] = L"files/CFInstance_delay_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeIE_CFInstanceDelay) {
|
| + SimpleBrowserTest(IE, kCFIDelayPage, L"CFInstanceDelay");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeFF_CFInstanceDelay) {
|
| + SimpleBrowserTest(FIREFOX, kCFIDelayPage, L"CFInstanceDelay");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeOpera_CFInstanceDelay) {
|
| + OptionalBrowserTest(OPERA, kCFIDelayPage, L"CFInstanceDelay");
|
| +}
|
| +
|
| +const wchar_t kCFIFallbackPage[] = L"files/CFInstance_fallback_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceFallback) {
|
| + SimpleBrowserTest(IE, kCFIFallbackPage, L"CFInstanceFallback");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_CFInstanceFallback) {
|
| + SimpleBrowserTest(FIREFOX, kCFIFallbackPage, L"CFInstanceFallback");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeOpera_CFInstanceFallback) {
|
| + OptionalBrowserTest(OPERA, kCFIFallbackPage, L"CFInstanceFallback");
|
| +}
|
| +
|
| +const wchar_t kCFINoSrcPage[] = L"files/CFInstance_no_src_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceNoSrc) {
|
| + SimpleBrowserTest(IE, kCFINoSrcPage, L"CFInstanceNoSrc");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_CFInstanceNoSrc) {
|
| + SimpleBrowserTest(FIREFOX, kCFINoSrcPage, L"CFInstanceNoSrc");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeOpera_CFInstanceNoSrc) {
|
| + OptionalBrowserTest(OPERA, kCFINoSrcPage, L"CFInstanceNoSrc");
|
| +}
|
| +
|
| +const wchar_t kCFIIfrOnLoadPage[] = L"files/CFInstance_iframe_onload_host.html";
|
| +
|
| +// disabled since it's unlikely that we care about this case
|
| +TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeIE_CFInstanceIfrOnLoad) {
|
| + SimpleBrowserTest(IE, kCFIIfrOnLoadPage, L"CFInstanceIfrOnLoad");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_CFInstanceIfrOnLoad) {
|
| + SimpleBrowserTest(FIREFOX, kCFIIfrOnLoadPage, L"CFInstanceIfrOnLoad");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeOpera_CFInstanceIfrOnLoad) {
|
| + OptionalBrowserTest(OPERA, kCFIIfrOnLoadPage, L"CFInstanceIfrOnLoad");
|
| +}
|
| +
|
| +const wchar_t kCFIZeroSizePage[] = L"files/CFInstance_zero_size_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceZeroSize) {
|
| + SimpleBrowserTest(IE, kCFIZeroSizePage, L"CFInstanceZeroSize");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_CFInstanceZeroSize) {
|
| + SimpleBrowserTest(FIREFOX, kCFIZeroSizePage, L"CFInstanceZeroSize");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeOpera_CFInstanceZeroSize) {
|
| + OptionalBrowserTest(OPERA, kCFIZeroSizePage, L"CFInstanceZeroSize");
|
| +}
|
| +
|
| +const wchar_t kCFIIfrPostPage[] = L"files/CFInstance_iframe_post_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceIfrPost) {
|
| + SimpleBrowserTest(IE, kCFIIfrPostPage, L"CFInstanceIfrPost");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_CFInstanceIfrPost) {
|
| + SimpleBrowserTest(FIREFOX, kCFIIfrPostPage, L"CFInstanceIfrPost");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstanceIfrPost) {
|
| + OptionalBrowserTest(CHROME, kCFIIfrPostPage, L"CFInstanceIfrPost");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeSafari_CFInstanceIfrPost) {
|
| + OptionalBrowserTest(SAFARI, kCFIIfrPostPage, L"CFInstanceIfrPost");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeOpera_CFInstanceIfrPost) {
|
| + OptionalBrowserTest(OPERA, kCFIIfrPostPage, L"CFInstanceIfrPost");
|
| +}
|
| +
|
| +const wchar_t kCFIPostPage[] = L"files/CFInstance_post_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstancePost) {
|
| + SimpleBrowserTest(IE, kCFIPostPage, L"CFInstancePost");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_CFInstancePost) {
|
| + SimpleBrowserTest(FIREFOX, kCFIPostPage, L"CFInstancePost");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstancePost) {
|
| + OptionalBrowserTest(CHROME, kCFIPostPage, L"CFInstancePost");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeSafari_CFInstancePost) {
|
| + OptionalBrowserTest(SAFARI, kCFIPostPage, L"CFInstancePost");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeOpera_CFInstancePost) {
|
| + OptionalBrowserTest(OPERA, kCFIPostPage, L"CFInstancePost");
|
| +}
|
| +
|
| +const wchar_t kCFIRPCPage[] = L"files/CFInstance_rpc_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceRPC) {
|
| + SimpleBrowserTest(IE, kCFIRPCPage, L"CFInstanceRPC");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_CFInstanceRPC) {
|
| + SimpleBrowserTest(FIREFOX, kCFIRPCPage, L"CFInstanceRPC");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstanceRPC) {
|
| + OptionalBrowserTest(CHROME, kCFIRPCPage, L"CFInstanceRPC");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeSafari_CFInstanceRPC) {
|
| + OptionalBrowserTest(SAFARI, kCFIRPCPage, L"CFInstanceRPC");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeOpera_CFInstanceRPC) {
|
| + OptionalBrowserTest(OPERA, kCFIRPCPage, L"CFInstanceRPC");
|
| +}
|
| +
|
| +const wchar_t kCFIRPCInternalPage[] =
|
| + L"files/CFInstance_rpc_internal_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceRPCInternal) {
|
| + SimpleBrowserTest(IE, kCFIRPCInternalPage, L"CFInstanceRPCInternal");
|
| +}
|
| +
|
| +// Disabled: http://b/issue?id=2050201
|
| +TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeFF_CFInstanceRPCInternal) {
|
| + SimpleBrowserTest(FIREFOX, kCFIRPCInternalPage, L"CFInstanceRPCInternal");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstanceRPCInternal) {
|
| + OptionalBrowserTest(CHROME, kCFIRPCInternalPage, L"CFInstanceRPCInternal");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeSafari_CFInstanceRPCInternal) {
|
| + OptionalBrowserTest(SAFARI, kCFIRPCInternalPage, L"CFInstanceRPCInternal");
|
| +}
|
| +
|
| +const wchar_t kCFIDefaultCtorPage[] =
|
| + L"files/CFInstance_default_ctor_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceDefaultCtor) {
|
| + SimpleBrowserTest(IE, kCFIDefaultCtorPage, L"CFInstanceDefaultCtor");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_CFInstanceDefaultCtor) {
|
| + SimpleBrowserTest(FIREFOX, kCFIDefaultCtorPage, L"CFInstanceDefaultCtor");
|
| +}
|
| +
|
| +// Class that mocks external call from VectoredHandlerT for testing purposes.
|
| +class EMock : public VEHTraitsBase {
|
| + public:
|
| + static inline bool WriteDump(EXCEPTION_POINTERS* p) {
|
| + g_dump_made = true;
|
| + return true;
|
| + }
|
| +
|
| + static inline void* Register(PVECTORED_EXCEPTION_HANDLER func,
|
| + const void* module_start,
|
| + const void* module_end) {
|
| + VEHTraitsBase::SetModule(module_start, module_end);
|
| + // Return some arbitrary number, expecting to get the same on Unregister()
|
| + return reinterpret_cast<void*>(4);
|
| + }
|
| +
|
| + static inline ULONG Unregister(void* handle) {
|
| + EXPECT_EQ(handle, reinterpret_cast<void*>(4));
|
| + return 1;
|
| + }
|
| +
|
| + static inline WORD RtlCaptureStackBackTrace(DWORD FramesToSkip,
|
| + DWORD FramesToCapture, void** BackTrace, DWORD* BackTraceHash) {
|
| + EXPECT_EQ(2, FramesToSkip);
|
| + EXPECT_LE(FramesToSkip + FramesToCapture,
|
| + VectoredHandlerBase::max_back_trace);
|
| + memcpy(BackTrace, g_stack, g_stack_entries * sizeof(BackTrace[0]));
|
| + return g_stack_entries;
|
| + }
|
| +
|
| + static inline EXCEPTION_REGISTRATION_RECORD* RtlpGetExceptionList() {
|
| + return g_seh_chain;
|
| + }
|
| +
|
| + // Test helpers
|
| +
|
| + // Create fake SEH chain of random filters - with and without our module.
|
| + static void SetHaveSEHFilter() {
|
| + SetSEHChain(reinterpret_cast<const char*>(g_module_start) - 0x1000,
|
| + reinterpret_cast<const char*>(g_module_start) + 0x1000,
|
| + reinterpret_cast<const char*>(g_module_end) + 0x7127,
|
| + NULL);
|
| + }
|
| +
|
| + static void SetNoSEHFilter() {
|
| + SetSEHChain(reinterpret_cast<const char*>(g_module_start) - 0x1000,
|
| + reinterpret_cast<const char*>(g_module_end) + 0x7127,
|
| + NULL);
|
| + }
|
| +
|
| + // Create fake stack - with and without our module.
|
| + static void SetOnStack() {
|
| + SetStack(reinterpret_cast<const char*>(g_module_start) - 0x11283,
|
| + reinterpret_cast<const char*>(g_module_start) - 0x278361,
|
| + reinterpret_cast<const char*>(g_module_start) + 0x9171,
|
| + reinterpret_cast<const char*>(g_module_end) + 1231,
|
| + NULL);
|
| + }
|
| +
|
| + static void SetNotOnStack() {
|
| + SetStack(reinterpret_cast<const char*>(g_module_start) - 0x11283,
|
| + reinterpret_cast<const char*>(g_module_start) - 0x278361,
|
| + reinterpret_cast<const char*>(g_module_end) + 1231,
|
| + NULL);
|
| + }
|
| +
|
| + // Populate stack array
|
| + static void SetStack(const void* p, ...) {
|
| + va_list vl;
|
| + va_start(vl, p);
|
| + g_stack_entries = 0;
|
| + for (; p; ++g_stack_entries) {
|
| + CHECK(g_stack_entries < arraysize(g_stack));
|
| + g_stack[g_stack_entries] = p;
|
| + p = va_arg(vl, const void*);
|
| + }
|
| + }
|
| +
|
| + static void SetSEHChain(const void* p, ...) {
|
| + va_list vl;
|
| + va_start(vl, p);
|
| + int i = 0;
|
| + for (; p; ++i) {
|
| + CHECK(i + 1 < arraysize(g_seh_chain));
|
| + g_seh_chain[i].Handler = const_cast<void*>(p);
|
| + g_seh_chain[i].Next = &g_seh_chain[i + 1];
|
| + p = va_arg(vl, const void*);
|
| + }
|
| +
|
| + g_seh_chain[i].Next = EXCEPTION_CHAIN_END;
|
| + }
|
| +
|
| + static EXCEPTION_REGISTRATION_RECORD g_seh_chain[25];
|
| + static const void* g_stack[VectoredHandlerBase::max_back_trace];
|
| + static WORD g_stack_entries;
|
| + static bool g_dump_made;
|
| +};
|
| +
|
| +EXCEPTION_REGISTRATION_RECORD EMock::g_seh_chain[25];
|
| +const void* EMock::g_stack[VectoredHandlerBase::max_back_trace];
|
| +WORD EMock::g_stack_entries;
|
| +bool EMock::g_dump_made;
|
| +
|
| +typedef VectoredHandlerT<EMock> VectoredHandlerMock;
|
| +
|
| +class ExPtrsHelper : public _EXCEPTION_POINTERS {
|
| + public:
|
| + ExPtrsHelper() {
|
| + ExceptionRecord = &er_;
|
| + ContextRecord = &ctx_;
|
| + ZeroMemory(&er_, sizeof(er_));
|
| + ZeroMemory(&ctx_, sizeof(ctx_));
|
| + }
|
| +
|
| + void Set(DWORD code, void* address, DWORD flags) {
|
| + er_.ExceptionCode = code;
|
| + er_.ExceptionAddress = address;
|
| + er_.ExceptionFlags = flags;
|
| + }
|
| +
|
| + EXCEPTION_RECORD er_;
|
| + CONTEXT ctx_;
|
| +};
|
| +
|
| +
|
| +TEST(ChromeFrame, ExceptionReport) {
|
| + char* s = reinterpret_cast<char*>(0x30000000);
|
| + char* e = s + 0x10000;
|
| + void* handler = VectoredHandlerMock::Register(s, e);
|
| + char* our_code = s + 0x1111;
|
| + char* not_our_code = s - 0x5555;
|
| + char* not_our_code2 = e + 0x5555;
|
| +
|
| + ExPtrsHelper ex;
|
| + // Exception in our code, but we have SEH filter
|
| + ex.Set(STATUS_ACCESS_VIOLATION, our_code, 0);
|
| + EMock::SetHaveSEHFilter();
|
| + EMock::SetOnStack();
|
| + EXPECT_EQ(ExceptionContinueSearch, VectoredHandlerMock::VectoredHandler(&ex));
|
| + EXPECT_EQ(1, VectoredHandlerMock::g_exceptions_seen);
|
| + EXPECT_FALSE(EMock::g_dump_made);
|
| +
|
| + // RPC_E_DISCONNECTED (0x80010108) is "The object invoked has disconnected
|
| + // from its clients", shall not be caught since it's a warning only.
|
| + ex.Set(RPC_E_DISCONNECTED, our_code, 0);
|
| + EMock::SetHaveSEHFilter();
|
| + EMock::SetOnStack();
|
| + EXPECT_EQ(ExceptionContinueSearch, VectoredHandlerMock::VectoredHandler(&ex));
|
| + EXPECT_EQ(1, VectoredHandlerMock::g_exceptions_seen);
|
| + EXPECT_FALSE(EMock::g_dump_made);
|
| +
|
| +
|
| + // Exception, not in our code, we do not have SEH and we are not in stack.
|
| + ex.Set(STATUS_INTEGER_DIVIDE_BY_ZERO, not_our_code, 0);
|
| + EMock::SetNoSEHFilter();
|
| + EMock::SetNotOnStack();
|
| + EXPECT_EQ(ExceptionContinueSearch, VectoredHandlerMock::VectoredHandler(&ex));
|
| + EXPECT_EQ(2, VectoredHandlerMock::g_exceptions_seen);
|
| + EXPECT_FALSE(EMock::g_dump_made);
|
| +
|
| + // Exception, not in our code, no SEH, but we are on the stack.
|
| + ex.Set(STATUS_INTEGER_DIVIDE_BY_ZERO, not_our_code2, 0);
|
| + EMock::SetNoSEHFilter();
|
| + EMock::SetOnStack();
|
| + EXPECT_EQ(ExceptionContinueSearch, VectoredHandlerMock::VectoredHandler(&ex));
|
| + EXPECT_EQ(3, VectoredHandlerMock::g_exceptions_seen);
|
| + EXPECT_TRUE(EMock::g_dump_made);
|
| + EMock::g_dump_made = false;
|
| +
|
| +
|
| + // Exception, in our code, no SEH, not on stack (assume FPO screwed us)
|
| + ex.Set(STATUS_INTEGER_DIVIDE_BY_ZERO, our_code, 0);
|
| + EMock::SetNoSEHFilter();
|
| + EMock::SetNotOnStack();
|
| + EXPECT_EQ(ExceptionContinueSearch, VectoredHandlerMock::VectoredHandler(&ex));
|
| + EXPECT_EQ(4, VectoredHandlerMock::g_exceptions_seen);
|
| + EXPECT_TRUE(EMock::g_dump_made);
|
| + EMock::g_dump_made = false;
|
| +
|
| + VectoredHandlerMock::Unregister();
|
| +}
|
| +
|
| +const wchar_t kInitializeHiddenPage[] = L"files/initialize_hidden.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_InitializeHidden) {
|
| + SimpleBrowserTest(IE, kInitializeHiddenPage, L"InitializeHidden");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_InitializeHidden) {
|
| + SimpleBrowserTest(FIREFOX, kInitializeHiddenPage, L"InitializeHidden");
|
| +}
|
| +
|
| +// Disabled due to a problem with Opera.
|
| +// http://b/issue?id=1708275
|
| +TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeOpera_InitializeHidden) {
|
| + OptionalBrowserTest(OPERA, kInitializeHiddenPage, L"InitializeHidden");
|
| +}
|
| +
|
| +const wchar_t kInHeadPage[] = L"files/in_head.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_InHead) {
|
| + SimpleBrowserTest(FIREFOX, kInHeadPage, L"InHead");
|
| +}
|
| +
|
| +const wchar_t kVersionPage[] = L"files/version.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_Version) {
|
| + VersionTest(IE, kVersionPage, L"version");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_Version) {
|
| + VersionTest(FIREFOX, kVersionPage, L"version");
|
| +}
|
| +
|
| +const wchar_t kEventListenerPage[] = L"files/event_listener.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_EventListener) {
|
| + SimpleBrowserTest(IE, kEventListenerPage, L"EventListener");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_EventListener) {
|
| + SimpleBrowserTest(FIREFOX, kEventListenerPage, L"EventListener");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeOpera_EventListener) {
|
| + OptionalBrowserTest(OPERA, kEventListenerPage, L"EventListener");
|
| +}
|
| +
|
| +const wchar_t kPrivilegedApisPage[] = L"files/privileged_apis_host.html";
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_PrivilegedApis) {
|
| + SimpleBrowserTest(IE, kPrivilegedApisPage, L"PrivilegedApis");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeFF_PrivilegedApis) {
|
| + SimpleBrowserTest(FIREFOX, kPrivilegedApisPage, L"PrivilegedApis");
|
| +}
|
| +
|
| +TEST_F(ChromeFrameTestWithWebServer, WidgetModeOpera_PrivilegedApis) {
|
| + OptionalBrowserTest(OPERA, kPrivilegedApisPage, L"PrivilegedApis");
|
| +}
|
| +
|
| +class ChromeFrameTestEnvironment: public testing::Environment {
|
| + public:
|
| + ~ChromeFrameTestEnvironment() {
|
| + }
|
| +
|
| + void SetUp() {
|
| + ScopedChromeFrameRegistrar::RegisterDefaults();
|
| + }
|
| +
|
| + void TearDown() {
|
| + }
|
| +};
|
| +
|
| +::testing::Environment* const chrome_frame_env =
|
| + ::testing::AddGlobalTestEnvironment(new ChromeFrameTestEnvironment);
|
| +
|
| +// TODO(stoyan): - Move everything below in separate file(s).
|
| +struct LaunchDelegateMock : public ProxyFactory::LaunchDelegate {
|
| + MOCK_METHOD2(LaunchComplete, void(ChromeFrameAutomationProxy*,
|
| + AutomationLaunchResult));
|
| +};
|
| +
|
| +TEST(ProxyFactoryTest, CreateDestroy) {
|
| + ProxyFactory f;
|
| + LaunchDelegateMock d;
|
| + EXPECT_CALL(d, LaunchComplete(testing::NotNull(), testing::_)).Times(1);
|
| + void* id = f.GetAutomationServer(0, L"Adam.N.Epilinter", L"", false, &d);
|
| + f.ReleaseAutomationServer(id);
|
| +}
|
| +
|
| +TEST(ProxyFactoryTest, CreateSameProfile) {
|
| + ProxyFactory f;
|
| + LaunchDelegateMock d;
|
| + EXPECT_CALL(d, LaunchComplete(testing::NotNull(), testing::_)).Times(2);
|
| + void* i1 = f.GetAutomationServer(0, L"Dr. Gratiano Forbeson", L"", false, &d);
|
| + void* i2 = f.GetAutomationServer(0, L"Dr. Gratiano Forbeson", L"", false, &d);
|
| + EXPECT_EQ(i1, i2);
|
| + f.ReleaseAutomationServer(i2);
|
| + f.ReleaseAutomationServer(i1);
|
| +}
|
| +
|
| +TEST(ProxyFactoryTest, CreateDifferentProfiles) {
|
| + ProxyFactory f;
|
| + LaunchDelegateMock d;
|
| + EXPECT_CALL(d, LaunchComplete(testing::NotNull(), testing::_)).Times(2);
|
| + void* i1 = f.GetAutomationServer(0, L"Adam.N.Epilinter", L"", false, &d);
|
| + void* i2 = f.GetAutomationServer(0, L"Dr. Gratiano Forbeson", L"", false, &d);
|
| + EXPECT_NE(i1, i2);
|
| + f.ReleaseAutomationServer(i2);
|
| + f.ReleaseAutomationServer(i1);
|
| +}
|
| +
|
| +// ChromeFrameAutomationClient [CFAC] tests.
|
| +struct MockCFDelegate : public ChromeFrameDelegateImpl {
|
| + MOCK_CONST_METHOD0(GetWindow, WindowType());
|
| + MOCK_METHOD1(GetBounds, void(RECT* bounds));
|
| + MOCK_METHOD0(GetDocumentUrl, std::string());
|
| + MOCK_METHOD2(ExecuteScript, bool(const std::string& script,
|
| + std::string* result));
|
| + MOCK_METHOD0(OnAutomationServerReady, void());
|
| + MOCK_METHOD2(OnAutomationServerLaunchFailed, void(
|
| + AutomationLaunchResult reason, const std::string& server_version));
|
| + // This remains in interface since we call it if Navigate()
|
| + // returns immediate error.
|
| + MOCK_METHOD2(OnLoadFailed, void(int error_code, const std::string& url));
|
| +
|
| + // Do not mock this method. :) Use it as message demuxer and dispatcher
|
| + // to the following methods (which we mock)
|
| + // MOCK_METHOD1(OnMessageReceived, void(const IPC::Message&));
|
| +
|
| +
|
| + MOCK_METHOD2(OnNavigationStateChanged, void(int tab_handle, int flags));
|
| + MOCK_METHOD2(OnUpdateTargetUrl, void(int tab_handle,
|
| + const std::wstring& new_target_url));
|
| + MOCK_METHOD2(OnAcceleratorPressed, void(int tab_handle,
|
| + const MSG& accel_message));
|
| + MOCK_METHOD2(OnTabbedOut, void(int tab_handle, bool reverse));
|
| + MOCK_METHOD3(OnOpenURL, void(int tab_handle, const GURL& url,
|
| + int open_disposition));
|
| + MOCK_METHOD2(OnDidNavigate, void(int tab_handle,
|
| + const IPC::NavigationInfo& navigation_info));
|
| + MOCK_METHOD3(OnNavigationFailed, void(int tab_handle, int error_code,
|
| + const GURL& gurl));
|
| + MOCK_METHOD2(OnLoad, void(int tab_handle, const GURL& url));
|
| + MOCK_METHOD4(OnMessageFromChromeFrame, void(int tab_handle,
|
| + const std::string& message,
|
| + const std::string& origin,
|
| + const std::string& target));
|
| + MOCK_METHOD5(OnHandleContextMenu, void(int tab_handle, HANDLE menu_handle,
|
| + int x_pos, int y_pos, int align_flags));
|
| + MOCK_METHOD3(OnRequestStart, void(int tab_handle, int request_id,
|
| + const IPC::AutomationURLRequest& request));
|
| + MOCK_METHOD3(OnRequestRead, void(int tab_handle, int request_id,
|
| + int bytes_to_read));
|
| + MOCK_METHOD3(OnRequestEnd, void(int tab_handle, int request_id,
|
| + const URLRequestStatus& status));
|
| + MOCK_METHOD3(OnSetCookieAsync, void(int tab_handle, const GURL& url,
|
| + const std::string& cookie));
|
| +
|
| + // Use for sending network responses
|
| + void SetAutomationSender(IPC::Message::Sender* automation) {
|
| + automation_ = automation;
|
| + }
|
| +
|
| + // Set-expectation helpers
|
| + void SetOnNavigationStateChanged(int tab_handle) {
|
| + EXPECT_CALL(*this,
|
| + OnNavigationStateChanged(testing::Eq(tab_handle), testing::_))
|
| + .Times(testing::AnyNumber());
|
| + }
|
| +
|
| + // Response sender helpers
|
| + void ReplyStarted(const IPC::AutomationURLResponse* response,
|
| + int tab_handle, int request_id,
|
| + const IPC::AutomationURLRequest& request) {
|
| + automation_->Send(new AutomationMsg_RequestStarted(0, tab_handle,
|
| + request_id, *response));
|
| + }
|
| +
|
| + void ReplyData(const std::string* data, int tab_handle, int request_id,
|
| + int bytes_to_read) {
|
| + automation_->Send(new AutomationMsg_RequestData(0, tab_handle,
|
| + request_id, *data));
|
| + }
|
| +
|
| + void ReplyEOF(int tab_handle, int request_id) {
|
| + automation_->Send(new AutomationMsg_RequestEnd(0, tab_handle,
|
| + request_id, URLRequestStatus()));
|
| + }
|
| +
|
| + void Reply404(int tab_handle, int request_id,
|
| + const IPC::AutomationURLRequest& request) {
|
| + const IPC::AutomationURLResponse notfound = {"", "HTTP/1.1 404\r\n\r\n"};
|
| + automation_->Send(new AutomationMsg_RequestStarted(0, tab_handle,
|
| + request_id, notfound));
|
| + automation_->Send(new AutomationMsg_RequestEnd(0, tab_handle,
|
| + request_id, URLRequestStatus()));
|
| + }
|
| +
|
| + IPC::Message::Sender* automation_;
|
| +};
|
| +
|
| +class MockProxyFactory : public ProxyFactory {
|
| + public:
|
| + MOCK_METHOD5(GetAutomationServer, void*(int, const std::wstring&,
|
| + const std::wstring& extra_argument, bool, ProxyFactory::LaunchDelegate*));
|
| + MOCK_METHOD1(ReleaseAutomationServer, bool(void* id));
|
| +
|
| + MockProxyFactory() : thread_("mock factory worker") {
|
| + thread_.Start();
|
| + loop_ = thread_.message_loop();
|
| + }
|
| +
|
| + // Fake implementation
|
| + void GetServerImpl(ChromeFrameAutomationProxy* pxy,
|
| + AutomationLaunchResult result,
|
| + int timeout,
|
| + ProxyFactory::LaunchDelegate* d) {
|
| + Task* task = NewRunnableMethod(d,
|
| + &ProxyFactory::LaunchDelegate::LaunchComplete, pxy, result);
|
| + loop_->PostDelayedTask(FROM_HERE, task, timeout/2);
|
| + }
|
| +
|
| + base::Thread thread_;
|
| + MessageLoop* loop_;
|
| +};
|
| +
|
| +class MockAutomationProxy : public ChromeFrameAutomationProxy {
|
| + public:
|
| + MOCK_METHOD1(Send, bool(IPC::Message*));
|
| + MOCK_METHOD3(SendAsAsync, void(IPC::SyncMessage* msg, void* callback,
|
| + void* key));
|
| + MOCK_METHOD1(CancelAsync, void(void* key));
|
| + MOCK_METHOD1(CreateTabProxy, scoped_refptr<TabProxy>(int handle));
|
| + MOCK_METHOD0(server_version, std::string(void));
|
| + MOCK_METHOD1(SendProxyConfig, void(const std::string&));
|
| + MOCK_METHOD1(SetEnableExtensionAutomation, void(bool enable));
|
| +
|
| + ~MockAutomationProxy() {}
|
| +};
|
| +
|
| +struct MockAutomationMessageSender : public AutomationMessageSender {
|
| + MOCK_METHOD1(Send, bool(IPC::Message*));
|
| + MOCK_METHOD3(SendWithTimeout, bool(IPC::Message* , int , bool*));
|
| +
|
| + void ForwardTo(MockAutomationProxy *p) {
|
| + proxy_ = p;
|
| + ON_CALL(*this, Send(testing::_))
|
| + .WillByDefault(testing::Invoke(proxy_, &MockAutomationProxy::Send));
|
| + }
|
| +
|
| + MockAutomationProxy* proxy_;
|
| +};
|
| +
|
| +template <> struct RunnableMethodTraits<ProxyFactory::LaunchDelegate> {
|
| + static void RetainCallee(ProxyFactory::LaunchDelegate* obj) {}
|
| + static void ReleaseCallee(ProxyFactory::LaunchDelegate* obj) {}
|
| +};
|
| +
|
| +template <> struct RunnableMethodTraits<MockProxyFactory> {
|
| + static void RetainCallee(MockProxyFactory* obj) {}
|
| + static void ReleaseCallee(MockProxyFactory* obj) {}
|
| +};
|
| +
|
| +template <> struct RunnableMethodTraits<ChromeFrameAutomationClient> {
|
| + static void RetainCallee(ChromeFrameAutomationClient* obj) {}
|
| + static void ReleaseCallee(ChromeFrameAutomationClient* obj) {}
|
| +};
|
| +
|
| +// MessageLoopForUI wrapper that runs only for a limited time.
|
| +// We need a UI message loop in the main thread.
|
| +struct TimedMsgLoop {
|
| + public:
|
| + void RunFor(int seconds) {
|
| + loop_.PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask, 1000 * seconds);
|
| + loop_.MessageLoop::Run();
|
| + }
|
| +
|
| + void Quit() {
|
| + loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask);
|
| + }
|
| +
|
| + MessageLoopForUI loop_;
|
| +};
|
| +
|
| +template <> struct RunnableMethodTraits<TimedMsgLoop> {
|
| + static void RetainCallee(TimedMsgLoop* obj) {}
|
| + static void ReleaseCallee(TimedMsgLoop* obj) {}
|
| +};
|
| +
|
| +// Saves typing. It's somewhat hard to create a wrapper around
|
| +// testing::InvokeWithoutArgs since it returns a
|
| +// non-public (testing::internal) type.
|
| +#define QUIT_LOOP(loop) testing::InvokeWithoutArgs(TaskHolder(\
|
| + NewRunnableMethod(&loop, &TimedMsgLoop::Quit)))
|
| +
|
| +// We mock ChromeFrameDelegate only. The rest is with real AutomationProxy
|
| +TEST(CFACWithChrome, CreateTooFast) {
|
| + MockCFDelegate cfd;
|
| + TimedMsgLoop loop;
|
| + int timeout = 0; // Chrome cannot send Hello message so fast.
|
| + const std::wstring profile = L"Adam.N.Epilinter";
|
| +
|
| + scoped_ptr<ChromeFrameAutomationClient> client;
|
| + client.reset(new ChromeFrameAutomationClient());
|
| +
|
| + EXPECT_CALL(cfd, OnAutomationServerLaunchFailed(AUTOMATION_TIMEOUT,
|
| + testing::_))
|
| + .Times(1)
|
| + .WillOnce(QUIT_LOOP(loop));
|
| +
|
| + EXPECT_TRUE(client->Initialize(&cfd, timeout, false, profile, L"", false));
|
| + loop.RunFor(10);
|
| + client->Uninitialize();
|
| +}
|
| +
|
| +// This test may fail if Chrome take more that 10 seconds (timeout var) to
|
| +// launch. In this case GMock shall print something like "unexpected call to
|
| +// OnAutomationServerLaunchFailed". I'm yet to find out how to specify
|
| +// that this is an unexpected call, and still to execute and action.
|
| +TEST(CFACWithChrome, CreateNotSoFast) {
|
| + MockCFDelegate cfd;
|
| + TimedMsgLoop loop;
|
| + const std::wstring profile = L"Adam.N.Epilinter";
|
| + int timeout = 10000;
|
| +
|
| + scoped_ptr<ChromeFrameAutomationClient> client;
|
| + client.reset(new ChromeFrameAutomationClient);
|
| +
|
| + EXPECT_CALL(cfd, OnAutomationServerReady())
|
| + .Times(1)
|
| + .WillOnce(QUIT_LOOP(loop));
|
| +
|
| + EXPECT_CALL(cfd, OnAutomationServerLaunchFailed(testing::_, testing::_))
|
| + .Times(0);
|
| +
|
| + EXPECT_TRUE(client->Initialize(&cfd, timeout, false, profile, L"", false));
|
| +
|
| + loop.RunFor(11);
|
| + client->Uninitialize();
|
| + client.reset(NULL);
|
| +}
|
| +
|
| +MATCHER_P(MsgType, msg_type, "IPC::Message::type()") {
|
| + const IPC::Message& m = arg;
|
| + return (m.type() == msg_type);
|
| +}
|
| +
|
| +MATCHER_P(EqNavigationInfoUrl, url, "IPC::NavigationInfo matcher") {
|
| + if (url.is_valid() && url != arg.url)
|
| + return false;
|
| + // TODO: other members
|
| + return true;
|
| +}
|
| +
|
| +TEST(CFACWithChrome, NavigateOk) {
|
| + MockCFDelegate cfd;
|
| + TimedMsgLoop loop;
|
| + const std::wstring profile = L"Adam.N.Epilinter";
|
| + const std::string url = "about:version";
|
| + int timeout = 10000;
|
| +
|
| + scoped_ptr<ChromeFrameAutomationClient> client;
|
| + client.reset(new ChromeFrameAutomationClient);
|
| +
|
| + EXPECT_CALL(cfd, OnAutomationServerReady())
|
| + .WillOnce(testing::InvokeWithoutArgs(TaskHolder(NewRunnableMethod(
|
| + client.get(), &ChromeFrameAutomationClient::InitiateNavigation,
|
| + url))));
|
| +
|
| +// cfd.SetOnNavigationStateChanged();
|
| + EXPECT_CALL(cfd,
|
| + OnNavigationStateChanged(testing::_, testing::_))
|
| + .Times(testing::AnyNumber());
|
| +
|
| + {
|
| + testing::InSequence s;
|
| +
|
| + EXPECT_CALL(cfd, OnDidNavigate(testing::_, EqNavigationInfoUrl(GURL())))
|
| + .Times(1);
|
| +
|
| + EXPECT_CALL(cfd, OnUpdateTargetUrl(testing::_, testing::_)).Times(1);
|
| +
|
| + EXPECT_CALL(cfd, OnLoad(testing::_, testing::_))
|
| + .Times(1)
|
| + .WillOnce(QUIT_LOOP(loop));
|
| + }
|
| +
|
| + EXPECT_TRUE(client->Initialize(&cfd, timeout, false, profile, L"", false));
|
| + loop.RunFor(10);
|
| + client->Uninitialize();
|
| + client.reset(NULL);
|
| +}
|
| +
|
| +// Bug: http://b/issue?id=2033644
|
| +TEST(CFACWithChrome, DISABLED_NavigateFailed) {
|
| + MockCFDelegate cfd;
|
| + TimedMsgLoop loop;
|
| + const std::wstring profile = L"Adam.N.Epilinter";
|
| + const std::string url = "http://127.0.0.3:65412/";
|
| + int timeout = 10000;
|
| +
|
| + scoped_ptr<ChromeFrameAutomationClient> client;
|
| + client.reset(new ChromeFrameAutomationClient);
|
| +
|
| + EXPECT_CALL(cfd, OnAutomationServerReady())
|
| + .WillOnce(testing::InvokeWithoutArgs(TaskHolder(NewRunnableMethod(
|
| + client.get(), &ChromeFrameAutomationClient::InitiateNavigation,
|
| + url))));
|
| +
|
| + EXPECT_CALL(cfd,
|
| + OnNavigationStateChanged(testing::_, testing::_))
|
| + .Times(testing::AnyNumber());
|
| +
|
| + EXPECT_CALL(cfd, OnNavigationFailed(testing::_, testing::_, testing::_))
|
| + .Times(1);
|
| +
|
| + EXPECT_CALL(cfd, OnUpdateTargetUrl(testing::_, testing::_))
|
| + .Times(testing::AnyNumber());
|
| +
|
| + EXPECT_CALL(cfd, OnLoad(testing::_, testing::_))
|
| + .Times(0);
|
| +
|
| + EXPECT_TRUE(client->Initialize(&cfd, timeout, false, profile, L"", false));
|
| +
|
| + loop.RunFor(10);
|
| + client->Uninitialize();
|
| + client.reset(NULL);
|
| +}
|
| +
|
| +MATCHER_P(EqURLRequest, x, "IPC::AutomationURLRequest matcher") {
|
| + if (arg.url != x.url)
|
| + return false;
|
| + if (arg.method != x.method)
|
| + return false;
|
| + if (arg.referrer != x.referrer)
|
| + return false;
|
| + if (arg.extra_request_headers != x.extra_request_headers)
|
| + return false;
|
| + // TODO: uploaddata member
|
| + return true;
|
| +}
|
| +
|
| +MATCHER_P(EqUrlGet, url, "Quick URL matcher for 'HTTP GET' request") {
|
| + if (arg.url != url)
|
| + return false;
|
| + if (arg.method != "GET")
|
| + return false;
|
| + return true;
|
| +}
|
| +
|
| +TEST(CFACWithChrome, UseHostNetworkStack) {
|
| + MockCFDelegate cfd;
|
| + TimedMsgLoop loop;
|
| + const std::wstring profile = L"Adam.N.Epilinter";
|
| + const std::string url = "http://bongo.com";
|
| + int timeout = 10000;
|
| +
|
| + scoped_ptr<ChromeFrameAutomationClient> client;
|
| + client.reset(new ChromeFrameAutomationClient);
|
| + client->set_use_chrome_network(false);
|
| + cfd.SetAutomationSender(client.get());
|
| +
|
| + EXPECT_CALL(cfd, OnAutomationServerReady())
|
| + .WillOnce(testing::InvokeWithoutArgs(TaskHolder(NewRunnableMethod(
|
| + client.get(), &ChromeFrameAutomationClient::InitiateNavigation,
|
| + url))));
|
| +
|
| + EXPECT_CALL(cfd, OnNavigationStateChanged(testing::_, testing::_))
|
| + .Times(testing::AnyNumber());
|
| +
|
| + EXPECT_CALL(cfd, GetBounds(testing::_))
|
| + .Times(testing::AtMost(1));
|
| +
|
| + EXPECT_CALL(cfd, OnUpdateTargetUrl(testing::_, testing::_))
|
| + .Times(testing::AnyNumber());
|
| +
|
| + // Note slash appending to the url string, because of GURL inside chrome
|
| + const IPC::AutomationURLResponse found = {"", "HTTP/0.9 200\r\n\r\n\r\n", };
|
| +
|
| + // Hard coded tab and request ids
|
| + static const int tab_id = 1;
|
| + int request_id = 2;
|
| +
|
| + EXPECT_CALL(cfd, OnRequestStart(tab_id, request_id, EqUrlGet(url + '/')))
|
| + .Times(1)
|
| + .WillOnce(testing::Invoke(CBF(&cfd, &MockCFDelegate::ReplyStarted,
|
| + &found)));
|
| +
|
| + // Return some trivial page, that have a link to a "logo.gif" image
|
| + const std::string data = "<!DOCTYPE html><title>Hello</title>"
|
| + "<img src=\"logo.gif\">";
|
| + EXPECT_CALL(cfd, OnRequestRead(tab_id, request_id, testing::Ge(0)))
|
| + .Times(2)
|
| + .WillOnce(testing::Invoke(CBF(&cfd, &MockCFDelegate::ReplyData, &data)))
|
| + .WillOnce(testing::WithArgs<0, 1>(testing::Invoke(CBF(&cfd,
|
| + &MockCFDelegate::ReplyEOF))));
|
| +
|
| + EXPECT_CALL(cfd, OnDidNavigate(tab_id, EqNavigationInfoUrl(GURL(url))))
|
| + .Times(1);
|
| + EXPECT_CALL(cfd, OnLoad(tab_id, GURL(url)))
|
| + .Times(1);
|
| +
|
| + // Expect request for logo.gif
|
| + request_id++;
|
| + EXPECT_CALL(cfd,
|
| + OnRequestStart(tab_id, request_id, EqUrlGet(url + "/logo.gif")))
|
| + .Times(1)
|
| + .WillOnce(testing::Invoke(CBF(&cfd, &MockCFDelegate::Reply404)));
|
| +
|
| + EXPECT_CALL(cfd, OnRequestRead(tab_id, request_id, testing::_))
|
| + .Times(testing::AtMost(1));
|
| +
|
| + // Chrome makes a brave request for favicon.ico
|
| + request_id++;
|
| + EXPECT_CALL(cfd,
|
| + OnRequestStart(tab_id, request_id, EqUrlGet(url + "/favicon.ico")))
|
| + .Times(1)
|
| + .WillOnce(testing::Invoke(CBF(&cfd, &MockCFDelegate::Reply404)));
|
| +
|
| + EXPECT_CALL(cfd, OnRequestRead(tab_id, request_id, testing::_))
|
| + .Times(testing::AtMost(1));
|
| +
|
| + bool incognito = true;
|
| + EXPECT_TRUE(client->Initialize(&cfd, timeout, false, profile, L"",
|
| + incognito));
|
| +
|
| + loop.RunFor(10);
|
| + client->Uninitialize();
|
| + client.reset(NULL);
|
| +}
|
| +
|
| +
|
| +// [CFAC] -- uses a ProxyFactory for creation of ChromeFrameAutomationProxy
|
| +// -- uses ChromeFrameAutomationProxy
|
| +// -- uses TabProxy obtained from ChromeFrameAutomationProxy
|
| +// -- uses ChromeFrameDelegate as outgoing interface
|
| +//
|
| +// We mock ProxyFactory to return mock object (MockAutomationProxy) implementing
|
| +// ChromeFrameAutomationProxy interface.
|
| +// Since CFAC uses TabProxy for few calls and TabProxy is not easy mockable,
|
| +// we create 'real' TabProxy but with fake AutomationSender (the one responsible
|
| +// for sending messages over channel).
|
| +// Additionally we have mock implementation ChromeFrameDelagate interface -
|
| +// MockCFDelegate.
|
| +
|
| +// Test fixture, saves typing all of it's members.
|
| +class CFACMockTest : public testing::Test {
|
| + public:
|
| + MockProxyFactory factory_;
|
| + MockCFDelegate cfd_;
|
| + TimedMsgLoop loop_;
|
| + MockAutomationProxy proxy_;
|
| + scoped_ptr<AutomationHandleTracker> tracker_;
|
| + MockAutomationMessageSender dummy_sender_;
|
| + scoped_refptr<TabProxy> tab_;
|
| + scoped_ptr<ChromeFrameAutomationClient> client_; // the victim of all tests
|
| +
|
| + std::wstring profile_;
|
| + int timeout_;
|
| + void* id_; // Automation server id we are going to return
|
| + int tab_handle_; // Tab handle. Any non-zero value is Ok.
|
| +
|
| + inline ChromeFrameAutomationProxy* get_proxy() {
|
| + return static_cast<ChromeFrameAutomationProxy*>(&proxy_);
|
| + }
|
| +
|
| + inline void CreateTab() {
|
| + ASSERT_EQ(NULL, tab_.get());
|
| + tab_ = new TabProxy(&dummy_sender_, tracker_.get(), tab_handle_);
|
| + }
|
| +
|
| + // Easy methods to set expectations.
|
| + void SetAutomationServerOk() {
|
| + EXPECT_CALL(factory_, GetAutomationServer(testing::Eq(timeout_),
|
| + testing::StrEq(profile_),
|
| + testing::_,
|
| + testing::_,
|
| + testing::NotNull()))
|
| + .Times(1)
|
| + .WillOnce(testing::DoAll(
|
| + testing::WithArgs<0, 4>(
|
| + testing::Invoke(CBF(&factory_, &MockProxyFactory::GetServerImpl,
|
| + get_proxy(), AUTOMATION_SUCCESS))),
|
| + testing::Return(id_)));
|
| +
|
| + EXPECT_CALL(factory_, ReleaseAutomationServer(testing::Eq(id_))).Times(1);
|
| + }
|
| +
|
| + void Set_CFD_LaunchFailed(AutomationLaunchResult result) {
|
| + EXPECT_CALL(cfd_, OnAutomationServerLaunchFailed(
|
| + testing::Eq(result), testing::_))
|
| + .Times(1)
|
| + .WillOnce(QUIT_LOOP(loop_));
|
| + }
|
| +
|
| + protected:
|
| + CFACMockTest() : tracker_(NULL), timeout_(500),
|
| + profile_(L"Adam.N.Epilinter") {
|
| + id_ = reinterpret_cast<void*>(5);
|
| + tab_handle_ = 3;
|
| + }
|
| +
|
| + virtual void SetUp() {
|
| + dummy_sender_.ForwardTo(&proxy_);
|
| + tracker_.reset(new AutomationHandleTracker(&dummy_sender_));
|
| +
|
| + client_.reset(new ChromeFrameAutomationClient);
|
| + client_->set_proxy_factory(&factory_);
|
| + }
|
| +};
|
| +
|
| +// Could be implemented as MockAutomationProxy member (we have WithArgs<>!)
|
| +ACTION_P3(HandleCreateTab, tab_handle, external_tab_container, tab_wnd) {
|
| + // arg0 - message
|
| + // arg1 - callback
|
| + // arg2 - key
|
| + CallbackRunner<Tuple3<HWND, HWND, int> >* c =
|
| + reinterpret_cast<CallbackRunner<Tuple3<HWND, HWND, int> >*>(arg1);
|
| + c->Run(external_tab_container, tab_wnd, tab_handle);
|
| + delete c;
|
| + delete arg0;
|
| +}
|
| +
|
| +TEST_F(CFACMockTest, MockedCreateTabOk) {
|
| + int timeout = 500;
|
| + CreateTab();
|
| + SetAutomationServerOk();
|
| +
|
| + EXPECT_CALL(proxy_, server_version()).Times(testing::AnyNumber())
|
| + .WillRepeatedly(testing::Return(""));
|
| +
|
| + // We need some valid HWNDs, when responding to CreateExternalTab
|
| + HWND h1 = ::GetDesktopWindow();
|
| + HWND h2 = ::GetDesktopWindow();
|
| + EXPECT_CALL(proxy_, SendAsAsync(testing::Property(&IPC::SyncMessage::type,
|
| + AutomationMsg_CreateExternalTab__ID),
|
| + testing::NotNull(), testing::_))
|
| + .Times(1)
|
| + .WillOnce(HandleCreateTab(tab_handle_, h1, h2));
|
| +
|
| + EXPECT_CALL(proxy_, CreateTabProxy(testing::Eq(tab_handle_)))
|
| + .WillOnce(testing::Return(tab_));
|
| +
|
| + EXPECT_CALL(cfd_, OnAutomationServerReady())
|
| + .WillOnce(QUIT_LOOP(loop_));
|
| +
|
| + // Here we go!
|
| + EXPECT_TRUE(client_->Initialize(&cfd_, timeout, false, profile_, L"", false));
|
| + loop_.RunFor(10);
|
| + client_->Uninitialize();
|
| +}
|
| +
|
| +TEST_F(CFACMockTest, MockedCreateTabFailed) {
|
| + HWND null_wnd = NULL;
|
| + SetAutomationServerOk();
|
| +
|
| + EXPECT_CALL(proxy_, server_version()).Times(testing::AnyNumber())
|
| + .WillRepeatedly(testing::Return(""));
|
| +
|
| + EXPECT_CALL(proxy_, SendAsAsync(testing::Property(&IPC::SyncMessage::type,
|
| + AutomationMsg_CreateExternalTab__ID),
|
| + testing::NotNull(), testing::_))
|
| + .Times(1)
|
| + .WillOnce(HandleCreateTab(tab_handle_, null_wnd, null_wnd));
|
| +
|
| + EXPECT_CALL(proxy_, CreateTabProxy(testing::_)).Times(0);
|
| +
|
| + Set_CFD_LaunchFailed(AUTOMATION_CREATE_TAB_FAILED);
|
| +
|
| + // Here we go!
|
| + EXPECT_TRUE(client_->Initialize(&cfd_, timeout_, false, profile_, L"",
|
| + false));
|
| + loop_.RunFor(4);
|
| + client_->Uninitialize();
|
| +}
|
| +
|
| +const wchar_t kMetaTagPage[] = L"files/meta_tag.html";
|
| +TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_MetaTag) {
|
| + SimpleBrowserTest(IE, kMetaTagPage, L"meta_tag");
|
| +}
|
| +
|
| +const wchar_t kCFProtocolPage[] = L"files/chrome_frame_protocol.html";
|
| +TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_CFProtocol) {
|
| + SimpleBrowserTest(IE, kCFProtocolPage, L"chrome_frame_protocol");
|
| +}
|
| +
|
| +const wchar_t kPersistentCookieTest[] =
|
| + L"files/persistent_cookie_test_page.html";
|
| +TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_PersistentCookieTest) {
|
| + SimpleBrowserTest(IE, kPersistentCookieTest, L"PersistentCookieTest");
|
| +}
|
| +
|
| +const wchar_t kNavigateOutPage[] = L"files/navigate_out.html";
|
| +TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_NavigateOut) {
|
| + SimpleBrowserTest(IE, kNavigateOutPage, L"navigate_out");
|
| +}
|
| +
|
| +HRESULT LaunchIEAsComServer(IWebBrowser2** web_browser) {
|
| + if (!web_browser)
|
| + return E_INVALIDARG;
|
| +
|
| + ScopedComPtr<IWebBrowser2> web_browser2;
|
| + HRESULT hr = CoCreateInstance(
|
| + CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2,
|
| + reinterpret_cast<void**>(web_browser2.Receive()));
|
| +
|
| + if (SUCCEEDED(hr)) {
|
| + *web_browser = web_browser2.Detach();
|
| + }
|
| +
|
| + return hr;
|
| +}
|
| +
|
| +TEST(ChromeFrameTest, FullTabModeIE_DisallowedUrls) {
|
| + int major_version = 0;
|
| + int minor_version = 0;
|
| + int bugfix_version = 0;
|
| +
|
| + base::SysInfo::OperatingSystemVersionNumbers(&major_version, &minor_version,
|
| + &bugfix_version);
|
| + if (major_version > 5) {
|
| + DLOG(INFO) << __FUNCTION__ << " Not running test on Windows version: "
|
| + << major_version;
|
| + return;
|
| + }
|
| +
|
| + IEVersion ie_version = GetIEVersion();
|
| + if (ie_version == IE_8) {
|
| + DLOG(INFO) << __FUNCTION__ << " Not running test on IE8";
|
| + return;
|
| + }
|
| +
|
| + 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);
|
| +
|
| + 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);
|
| + EXPECT_TRUE(hr == S_OK);
|
| +
|
| + VARIANT empty = ScopedVariant::kEmptyVariant;
|
| + ScopedVariant url;
|
| + url.Set(L"cf:file:///C:/");
|
| +
|
| + TimedMsgLoop loop;
|
| +
|
| + hr = web_browser2->Navigate2(url.AsInput(), &empty, &empty, &empty, &empty);
|
| + EXPECT_TRUE(hr == S_OK);
|
| +
|
| + loop.RunFor(10);
|
| +
|
| + EXPECT_TRUE(web_browser_sink->navigation_failed());
|
| +
|
| + hr = web_browser_sink->DispEventUnadvise(web_browser2);
|
| + EXPECT_TRUE(hr == S_OK);
|
| +
|
| + web_browser2.Release();
|
| + chrome_frame_test::CloseAllIEWindows();
|
| +
|
| + if (should_uninit) {
|
| + CoUninitialize();
|
| + }
|
| +}
|
| +
|
|
|