diff options
author | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-09 01:09:28 +0000 |
---|---|---|
committer | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-09 01:09:28 +0000 |
commit | 7bc272f38646abb81b58c89a59d8e6842f9e9631 (patch) | |
tree | 8e3c884ad1549c445e86925df673fcd0d8285d1d /chrome_frame/test/chrome_frame_test_utils.cc | |
parent | 0923559a1a020690c1d199fda3c55f67d2d54335 (diff) | |
download | chromium_src-7bc272f38646abb81b58c89a59d8e6842f9e9631.zip chromium_src-7bc272f38646abb81b58c89a59d8e6842f9e9631.tar.gz chromium_src-7bc272f38646abb81b58c89a59d8e6842f9e9631.tar.bz2 |
Added support for running reliability tests for ChromeFrame on similar lines as Chrome. We only run these
tests for IE at this point. The reliability test code for Chrome has been copied and modified accordingly.
Other related changes in this CL include the following:-
1. If ChromeFrame is running in headless mode determined by a registry value in HKCU\Software\Google\ChromeFrame
we initialize ChromeFrame crash reporting and connect to the Chrome crash server. This would enable us to
gather crash dumps from the reliability test runs and report the same.
2. The LowIntegrity fixes for the WebBrowser which Stoyan had done a while back are only needed for IE7 on Vista.
For this CL though we just do the requisite hacks if the OS is Vista. For Windows7 the returned IWebBrowser
interface pointer works fine.
3. I moved the WebBrowserEventSink to chrome_frame_test_utils as this class is now shared.
Fixes portions of http://code.google.com/p/chromium/issues/detail?id=29451
Bug=29451
Review URL: http://codereview.chromium.org/465074
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34119 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/test/chrome_frame_test_utils.cc')
-rw-r--r-- | chrome_frame/test/chrome_frame_test_utils.cc | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/chrome_frame/test/chrome_frame_test_utils.cc b/chrome_frame/test/chrome_frame_test_utils.cc index 8777651..9f2a6de 100644 --- a/chrome_frame/test/chrome_frame_test_utils.cc +++ b/chrome_frame/test/chrome_frame_test_utils.cc @@ -16,6 +16,7 @@ #include "base/string_util.h" #include "base/win_util.h" #include "chrome/common/chrome_switches.h" +#include "chrome_frame/utils.h" #include "testing/gtest/include/gtest/gtest.h" namespace chrome_frame_test { @@ -623,4 +624,242 @@ bool LowIntegrityToken::IsImpersonated() { return false; } +HRESULT LaunchIEAsComServer(IWebBrowser2** web_browser) { + if (!web_browser) + return E_INVALIDARG; + + HRESULT hr = S_OK; + DWORD cocreate_flags = CLSCTX_LOCAL_SERVER; + chrome_frame_test::LowIntegrityToken token; + // Vista has a bug which manifests itself when a medium integrity process + // launches a COM server like IE which runs in protected mode due to UAC. + // This causes the IWebBrowser2 interface which is returned to be useless, + // i.e it does not receive any events, etc. Our workaround for this is + // to impersonate a low integrity token and then launch IE. + if (win_util::GetWinVersion() == win_util::WINVERSION_VISTA) { + // Create medium integrity browser that will launch IE broker. + ScopedComPtr<IWebBrowser2> medium_integrity_browser; + hr = medium_integrity_browser.CreateInstance(CLSID_InternetExplorer, NULL, + CLSCTX_LOCAL_SERVER); + if (FAILED(hr)) + return hr; + medium_integrity_browser->Quit(); + // Broker remains alive. + if (!token.Impersonate()) { + hr = HRESULT_FROM_WIN32(GetLastError()); + return hr; + } + + cocreate_flags |= CLSCTX_ENABLE_CLOAKING; + } + + hr = ::CoCreateInstance(CLSID_InternetExplorer, NULL, + cocreate_flags, IID_IWebBrowser2, + reinterpret_cast<void**>(web_browser)); + // ~LowIntegrityToken() will switch integrity back to medium. + return hr; +} + +_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 + } +}; + +_ATL_FUNC_INFO WebBrowserEventSink::kNewWindow3Info = { + CC_STDCALL, VT_EMPTY, 5, { + VT_DISPATCH | VT_BYREF, + VT_BOOL | VT_BYREF, + VT_UINT, + VT_BSTR, + VT_BSTR + } +}; + +_ATL_FUNC_INFO WebBrowserEventSink::kVoidMethodInfo = { + CC_STDCALL, VT_EMPTY, 0, {NULL}}; + +_ATL_FUNC_INFO WebBrowserEventSink::kDocumentCompleteInfo = { + CC_STDCALL, VT_EMPTY, 2, { + VT_DISPATCH, + VT_VARIANT | VT_BYREF + } +}; + +// WebBrowserEventSink member defines +void WebBrowserEventSink::Uninitialize() { + DisconnectFromChromeFrame(); + if (web_browser2_.get()) { + DispEventUnadvise(web_browser2_); + web_browser2_->Quit(); + web_browser2_.Release(); + } +} + +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); +} + +STDMETHODIMP_(void) WebBrowserEventSink::OnDocumentCompleteInternal( + IDispatch* dispatch, VARIANT* url) { + DLOG(INFO) << __FUNCTION__; + OnDocumentComplete(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) { + HRESULT hr = LaunchIEAsComServer(web_browser2_.Receive()); + EXPECT_EQ(S_OK, hr); + if (hr == S_OK) { + web_browser2_->put_Visible(VARIANT_TRUE); + hr = DispEventAdvise(web_browser2_, &DIID_DWebBrowserEvents2); + EXPECT_TRUE(hr == S_OK); + hr = Navigate(navigate_url); + } + return hr; +} + +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::SetFocusToChrome() { + chrome_frame_test::SetKeyboardFocusToWindow( + GetAttachedChromeRendererWindow(), 1, 1); +} + +void WebBrowserEventSink::SendInputToChrome( + const std::string& input_string) { + chrome_frame_test::SendInputToWindow( + GetAttachedChromeRendererWindow(), input_string); +} + +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)); + } + } +} + +void WebBrowserEventSink::DisconnectFromChromeFrame() { + if (chrome_frame_) { + ScopedVariant dummy(static_cast<IDispatch*>(NULL)); + chrome_frame_->put_onmessage(dummy); + chrome_frame_->put_onload(dummy); + chrome_frame_->put_onloaderror(dummy); + chrome_frame_.Release(); + } +} + +HWND WebBrowserEventSink::GetAttachedChromeRendererWindow() { + DCHECK(chrome_frame_); + HWND renderer_window = NULL; + ScopedComPtr<IOleWindow> ole_window; + ole_window.QueryFrom(chrome_frame_); + EXPECT_TRUE(ole_window.get()); + + if (ole_window) { + HWND activex_window = NULL; + ole_window->GetWindow(&activex_window); + EXPECT_TRUE(IsWindow(activex_window)); + + // chrome tab window is the first (and the only) child of activex + HWND chrome_tab_window = GetWindow(activex_window, GW_CHILD); + EXPECT_TRUE(IsWindow(chrome_tab_window)); + renderer_window = GetWindow(chrome_tab_window, GW_CHILD); + } + + DCHECK(IsWindow(renderer_window)); + return renderer_window; +} + +HRESULT WebBrowserEventSink::SetWebBrowser(IWebBrowser2* web_browser2) { + DCHECK(web_browser2_.get() == NULL); + web_browser2_ = web_browser2; + web_browser2_->put_Visible(VARIANT_TRUE); + HRESULT hr = DispEventAdvise(web_browser2_, &DIID_DWebBrowserEvents2); + return hr; +} + } // namespace chrome_frame_test |