diff options
author | tommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-10 14:09:37 +0000 |
---|---|---|
committer | tommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-10 14:09:37 +0000 |
commit | bbfa9a15797ba107dcae0f7fff85a7f12ffd26b9 (patch) | |
tree | ee15898939e4989b96c6419217696f63d7a5585b /chrome_frame/test | |
parent | e721ebe885b159f9b18047392be9a0f5834998fb (diff) | |
download | chromium_src-bbfa9a15797ba107dcae0f7fff85a7f12ffd26b9.zip chromium_src-bbfa9a15797ba107dcae0f7fff85a7f12ffd26b9.tar.gz chromium_src-bbfa9a15797ba107dcae0f7fff85a7f12ffd26b9.tar.bz2 |
Handle automation server crashes. When Chrome crashes, we now handle the case and support document refresh or reload.
When chrome crashes, we draw a poor man's sad tab (":-("), so that can clearly be improved.
Another thing is that if the chrome instance that crashed held several navigational entries, then that history is lost.
TEST=There are a couple of tests included, so run those (*TabCrash*) and also verify that when the chrome automation server is killed that we do the right thing. Also check info in bug report.
BUG=25839
Review URL: http://codereview.chromium.org/3061036
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@55565 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/test')
-rw-r--r-- | chrome_frame/test/automation_client_mock.cc | 143 | ||||
-rw-r--r-- | chrome_frame/test/chrome_frame_automation_mock.h | 17 | ||||
-rw-r--r-- | chrome_frame/test/ie_event_sink.h | 40 | ||||
-rw-r--r-- | chrome_frame/test/mock_ie_event_sink_actions.h | 39 | ||||
-rw-r--r-- | chrome_frame/test/mock_ie_event_sink_test.cc | 22 | ||||
-rw-r--r-- | chrome_frame/test/mock_ie_event_sink_test.h | 55 | ||||
-rw-r--r-- | chrome_frame/test/proxy_factory_mock.cc | 84 | ||||
-rw-r--r-- | chrome_frame/test/proxy_factory_mock.h | 22 | ||||
-rw-r--r-- | chrome_frame/test/ui_test.cc | 80 |
9 files changed, 352 insertions, 150 deletions
diff --git a/chrome_frame/test/automation_client_mock.cc b/chrome_frame/test/automation_client_mock.cc index d8a4cca..6ef792e 100644 --- a/chrome_frame/test/automation_client_mock.cc +++ b/chrome_frame/test/automation_client_mock.cc @@ -15,34 +15,39 @@ using testing::_; using testing::CreateFunctor; using testing::Return; -DISABLE_RUNNABLE_METHOD_REFCOUNT(ProxyFactory::LaunchDelegate); +DISABLE_RUNNABLE_METHOD_REFCOUNT(LaunchDelegate); DISABLE_RUNNABLE_METHOD_REFCOUNT(ChromeFrameAutomationClient); DISABLE_RUNNABLE_METHOD_REFCOUNT(chrome_frame_test::TimedMsgLoop); +MATCHER_P(LaunchParamProfileEq, profile_name, "Check for profile name") { + return arg->profile_name().compare(profile_name) == 0; +} + void MockProxyFactory::GetServerImpl(ChromeFrameAutomationProxy* pxy, void* proxy_id, AutomationLaunchResult result, LaunchDelegate* d, - const ChromeFrameLaunchParams& params, + ChromeFrameLaunchParams* params, void** automation_server_id) { *automation_server_id = proxy_id; Task* task = NewRunnableMethod(d, - &ProxyFactory::LaunchDelegate::LaunchComplete, pxy, result); + &LaunchDelegate::LaunchComplete, pxy, result); loop_->PostDelayedTask(FROM_HERE, task, - params.automation_server_launch_timeout/2); + params->launch_timeout() / 2); } void CFACMockTest::SetAutomationServerOk(int times) { EXPECT_CALL(factory_, GetAutomationServer(testing::NotNull(), - testing::Field(&ChromeFrameLaunchParams::profile_name, - testing::StrEq(profile_path_.BaseName().value())), - testing::NotNull())) + LaunchParamProfileEq(profile_path_.BaseName().value()), + testing::NotNull())) .Times(times) .WillRepeatedly(testing::Invoke(CreateFunctor(&factory_, &MockProxyFactory::GetServerImpl, get_proxy(), id_, AUTOMATION_SUCCESS))); - EXPECT_CALL(factory_, ReleaseAutomationServer(testing::Eq(id_))).Times(times); + EXPECT_CALL(factory_, + ReleaseAutomationServer(testing::Eq(id_), testing::NotNull())) + .Times(times); } void CFACMockTest::Set_CFD_LaunchFailed(AutomationLaunchResult result) { @@ -93,17 +98,12 @@ TEST(CFACWithChrome, CreateTooFast) { .Times(1) .WillOnce(QUIT_LOOP(loop)); - ChromeFrameLaunchParams clp = { - timeout, - GURL(), - GURL(), - profile_path, - profile_path.BaseName().value(), - L"", - false, - false, - false - }; + GURL empty; + scoped_refptr<ChromeFrameLaunchParams> clp(new ChromeFrameLaunchParams( + empty, empty, profile_path, profile_path.BaseName().value(), L"", + false, false)); + clp->set_launch_timeout(timeout); + clp->set_version_check(false); EXPECT_TRUE(client->Initialize(&cfd, clp)); loop.RunFor(10); client->Uninitialize(); @@ -130,17 +130,12 @@ TEST(CFACWithChrome, CreateNotSoFast) { EXPECT_CALL(cfd, OnAutomationServerLaunchFailed(_, _)) .Times(0); - ChromeFrameLaunchParams clp = { - timeout, - GURL(), - GURL(), - profile_path, - profile_path.BaseName().value(), - L"", - false, - false, - false - }; + GURL empty; + scoped_refptr<ChromeFrameLaunchParams> clp(new ChromeFrameLaunchParams( + empty, empty, profile_path, profile_path.BaseName().value(), L"", + false, false)); + clp->set_launch_timeout(timeout); + clp->set_version_check(false); EXPECT_TRUE(client->Initialize(&cfd, clp)); loop.RunFor(11); @@ -182,17 +177,12 @@ TEST(CFACWithChrome, NavigateOk) { .WillOnce(QUIT_LOOP(loop)); } - ChromeFrameLaunchParams clp = { - timeout, - GURL(), - GURL(), - profile_path, - profile_path.BaseName().value(), - L"", - false, - false, - false - }; + GURL empty; + scoped_refptr<ChromeFrameLaunchParams> clp(new ChromeFrameLaunchParams( + empty, empty, profile_path, profile_path.BaseName().value(), L"", + false, false)); + clp->set_launch_timeout(timeout); + clp->set_version_check(false); EXPECT_TRUE(client->Initialize(&cfd, clp)); loop.RunFor(10); client->Uninitialize(); @@ -233,17 +223,12 @@ TEST(CFACWithChrome, NavigateFailed) { .Times(1) .WillOnce(QUIT_LOOP_SOON(loop, 2)); - ChromeFrameLaunchParams clp = { - 10000, - GURL(), - GURL(), - profile_path, - profile_path.BaseName().value(), - L"", - false, - false, - false - }; + GURL empty; + scoped_refptr<ChromeFrameLaunchParams> clp(new ChromeFrameLaunchParams( + empty, empty, profile_path, profile_path.BaseName().value(), L"", + false, false)); + clp->set_launch_timeout(10000); + clp->set_version_check(false); EXPECT_TRUE(client->Initialize(&cfd, clp)); loop.RunFor(10); @@ -276,17 +261,12 @@ TEST_F(CFACMockTest, MockedCreateTabOk) { EXPECT_CALL(mock_proxy_, CancelAsync(_)).Times(testing::AnyNumber()); // Here we go! - ChromeFrameLaunchParams clp = { - timeout, - GURL(), - GURL(), - profile_path_, - profile_path_.BaseName().value(), - L"", - false, - false, - false - }; + GURL empty; + scoped_refptr<ChromeFrameLaunchParams> clp(new ChromeFrameLaunchParams( + empty, empty, profile_path_, profile_path_.BaseName().value(), L"", + false, false)); + clp->set_launch_timeout(timeout); + clp->set_version_check(false); EXPECT_TRUE(client_->Initialize(&cfd_, clp)); loop_.RunFor(10); @@ -313,17 +293,12 @@ TEST_F(CFACMockTest, MockedCreateTabFailed) { Set_CFD_LaunchFailed(AUTOMATION_CREATE_TAB_FAILED); // Here we go! - ChromeFrameLaunchParams clp = { - timeout_, - GURL(), - GURL(), - profile_path_, - profile_path_.BaseName().value(), - L"", - false, - false, - false - }; + GURL empty; + scoped_refptr<ChromeFrameLaunchParams> clp(new ChromeFrameLaunchParams( + empty, empty, profile_path_, profile_path_.BaseName().value(), L"", + false, false)); + clp->set_launch_timeout(timeout_); + clp->set_version_check(false); EXPECT_TRUE(client_->Initialize(&cfd_, clp)); loop_.RunFor(4); client_->Uninitialize(); @@ -333,7 +308,8 @@ class TestChromeFrameAutomationProxyImpl : public ChromeFrameAutomationProxyImpl { public: TestChromeFrameAutomationProxyImpl() - : ChromeFrameAutomationProxyImpl(1) { // 1 is an unneeded timeout. + // 1 is an unneeded timeout. + : ChromeFrameAutomationProxyImpl(NULL, 1) { } MOCK_METHOD3( SendAsAsync, @@ -357,17 +333,12 @@ TEST_F(CFACMockTest, OnChannelError) { TestChromeFrameAutomationProxyImpl proxy; returned_proxy_ = &proxy; - ChromeFrameLaunchParams clp = { - 1, // Unneeded timeout, but can't be 0. - GURL(), - GURL(), - profile_path_, - profile_path_.BaseName().value(), - L"", - false, - false, - false - }; + GURL empty; + scoped_refptr<ChromeFrameLaunchParams> clp(new ChromeFrameLaunchParams( + empty, empty, profile_path_, profile_path_.BaseName().value(), L"", + false, false)); + clp->set_launch_timeout(1); // Unneeded timeout, but can't be 0. + clp->set_version_check(false); HWND h1 = ::GetDesktopWindow(); HWND h2 = ::GetDesktopWindow(); diff --git a/chrome_frame/test/chrome_frame_automation_mock.h b/chrome_frame/test/chrome_frame_automation_mock.h index 141fb9c..dfa7900 100644 --- a/chrome_frame/test/chrome_frame_automation_mock.h +++ b/chrome_frame/test/chrome_frame_automation_mock.h @@ -32,17 +32,12 @@ class AutomationMockDelegate chrome_frame_test::GetProfilePath(profile_name)); automation_client_ = new ChromeFrameAutomationClient; - ChromeFrameLaunchParams clp = { - launch_timeout, - GURL(), - GURL(), - profile_path, - profile_name, - extra_chrome_arguments, - perform_version_check, - incognito, - is_widget_mode - }; + GURL empty; + scoped_refptr<ChromeFrameLaunchParams> clp( + new ChromeFrameLaunchParams(empty, empty, profile_path, profile_name, + extra_chrome_arguments, incognito, is_widget_mode)); + clp->set_launch_timeout(launch_timeout); + clp->set_version_check(perform_version_check); automation_client_->Initialize(this, clp); } ~AutomationMockDelegate() { diff --git a/chrome_frame/test/ie_event_sink.h b/chrome_frame/test/ie_event_sink.h index 48b5d30..ac1bf93 100644 --- a/chrome_frame/test/ie_event_sink.h +++ b/chrome_frame/test/ie_event_sink.h @@ -57,6 +57,14 @@ class IEEventListener { virtual void OnNewBrowserWindow(IDispatch* new_window, const wchar_t* url) {} }; +// Listener for IPropertyNotifySink. +class PropertyNotifySinkListener { + public: + virtual ~PropertyNotifySinkListener() {} + virtual void OnChanged(DISPID dispid) {} + virtual void OnRequestEdit(DISPID dispid) {} +}; + // This class sets up event sinks to the IWebBrowser interface. It forwards // all events to its listener. // TODO(kkania): Delete WebBrowserEventSink and use this class instead for @@ -229,6 +237,38 @@ END_SINK_MAP() static _ATL_FUNC_INFO kFileDownloadInfo; }; +class PropertyNotifySinkImpl + : public CComObjectRootEx<CComSingleThreadModel>, + public IPropertyNotifySink { + public: + PropertyNotifySinkImpl() : listener_(NULL) { + } + +BEGIN_COM_MAP(PropertyNotifySinkImpl) + COM_INTERFACE_ENTRY(IPropertyNotifySink) +END_COM_MAP() + + STDMETHOD(OnChanged)(DISPID dispid) { + if (listener_) + listener_->OnChanged(dispid); + return S_OK; + } + + STDMETHOD(OnRequestEdit)(DISPID dispid) { + if (listener_) + listener_->OnRequestEdit(dispid); + return S_OK; + } + + void set_listener(PropertyNotifySinkListener* listener) { + DCHECK(listener_ == NULL || listener == NULL); + listener_ = listener; + } + + protected: + PropertyNotifySinkListener* listener_; +}; + } // namespace chrome_frame_test #endif // CHROME_FRAME_TEST_IE_EVENT_SINK_H_ diff --git a/chrome_frame/test/mock_ie_event_sink_actions.h b/chrome_frame/test/mock_ie_event_sink_actions.h index 0ee8dd2..49d6d63 100644 --- a/chrome_frame/test/mock_ie_event_sink_actions.h +++ b/chrome_frame/test/mock_ie_event_sink_actions.h @@ -5,6 +5,8 @@ #ifndef CHROME_FRAME_TEST_MOCK_IE_EVENT_SINK_ACTIONS_H_ #define CHROME_FRAME_TEST_MOCK_IE_EVENT_SINK_ACTIONS_H_ +#include "base/scoped_bstr_win.h" +#include "chrome/common/chrome_switches.h" #include "chrome_frame/test/chrome_frame_test_utils.h" #include "chrome_frame/test/simulate_input.h" #include "testing/gmock/include/gmock/gmock.h" @@ -41,6 +43,28 @@ ACTION_P(ExpectRendererHasFocus, mock) { mock->event_sink()->ExpectRendererWindowHasFocus(); } +ACTION_P2(ConnectDocPropNotifySink, mock, sink) { + ScopedComPtr<IDispatch> document; + mock->event_sink()->web_browser2()->get_Document(document.Receive()); + EXPECT_TRUE(document != NULL); // NOLINT + if (document) { + sink->Attach(document); + } +} + +ACTION_P(DisconnectDocPropNotifySink, sink) { + sink->Detach(); +} + +ACTION_P3(DelayNavigateToCurrentUrl, mock, loop, delay) { + loop->PostDelayedTask(FROM_HERE, NewRunnableFunction(&NavigateToCurrentUrl, + mock), delay); +} + +ACTION_P2(ExpectDocumentReadystate, mock, ready_state) { + mock->ExpectDocumentReadystate(ready_state); +} + ACTION_P8(DelayExecCommand, mock, loop, delay, cmd_group_guid, cmd_id, cmd_exec_opt, in_args, out_args) { loop->PostDelayedTask(FROM_HERE, NewRunnableMethod(mock->event_sink(), @@ -106,6 +130,13 @@ ACTION_P4(DelaySendScanCode, loop, delay, c, mod) { simulate_input::SendScanCode, c, mod), delay); } + +ACTION(KillChromeFrameProcesses) { + KillAllNamedProcessesWithArgument( + UTF8ToWide(chrome_frame_test::kChromeImageName), + UTF8ToWide(switches::kChromeFrame)); +} + // This function selects the address bar via the Alt+d shortcut. This is done // via a delayed task which executes after the delay which is passed in. // The subsequent operations like typing in the actual url and then hitting @@ -138,10 +169,10 @@ ACTION_P5(ValidateWindowSize, mock, left, top, width, height) { int actual_height = 0; IWebBrowser2* web_browser2 = mock->event_sink()->web_browser2(); - web_browser2->get_Left(reinterpret_cast<long*>(&actual_left)); - web_browser2->get_Top(reinterpret_cast<long*>(&actual_top)); - web_browser2->get_Width(reinterpret_cast<long*>(&actual_width)); - web_browser2->get_Height(reinterpret_cast<long*>(&actual_height)); + web_browser2->get_Left(reinterpret_cast<long*>(&actual_left)); // NOLINT + web_browser2->get_Top(reinterpret_cast<long*>(&actual_top)); // NOLINT + web_browser2->get_Width(reinterpret_cast<long*>(&actual_width)); // NOLINT + web_browser2->get_Height(reinterpret_cast<long*>(&actual_height)); // NOLINT EXPECT_EQ(actual_left, left); EXPECT_EQ(actual_top, top); diff --git a/chrome_frame/test/mock_ie_event_sink_test.cc b/chrome_frame/test/mock_ie_event_sink_test.cc index ab1ac6d..fb1493a 100644 --- a/chrome_frame/test/mock_ie_event_sink_test.cc +++ b/chrome_frame/test/mock_ie_event_sink_test.cc @@ -6,6 +6,7 @@ #include <sstream> +#include "base/scoped_variant_win.h" #include "base/utf_string_conversions.h" #include "chrome_frame/test/mock_ie_event_sink_actions.h" @@ -140,6 +141,27 @@ void MockIEEventSink::ExpectAnyNavigations() { .Times(testing::AnyNumber()); } +void MockIEEventSink::ExpectDocumentReadystate(int ready_state) { + ScopedComPtr<IWebBrowser2> browser(event_sink_->web_browser2()); + EXPECT_TRUE(browser != NULL); + if (browser) { + ScopedComPtr<IDispatch> document; + browser->get_Document(document.Receive()); + EXPECT_TRUE(document != NULL); + if (document) { + DISPPARAMS params = { 0 }; + ScopedVariant result; + EXPECT_HRESULT_SUCCEEDED(document->Invoke(DISPID_READYSTATE, IID_NULL, + LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, + result.Receive(), NULL, NULL)); + EXPECT_EQ(VT_I4, result.type()); + if (result.type() == VT_I4) { + EXPECT_EQ(ready_state, static_cast<int>(V_I4(&result))); + } + } + } +} + // MockIEEventSinkTest methods MockIEEventSinkTest::MockIEEventSinkTest() : server_mock_(1337, L"127.0.0.1", GetTestDataFolder()) { diff --git a/chrome_frame/test/mock_ie_event_sink_test.h b/chrome_frame/test/mock_ie_event_sink_test.h index 73e8778..b6e772a 100644 --- a/chrome_frame/test/mock_ie_event_sink_test.h +++ b/chrome_frame/test/mock_ie_event_sink_test.h @@ -114,6 +114,8 @@ class MockIEEventSink : public IEEventListener { // Expects any and all navigations. void ExpectAnyNavigations(); + void ExpectDocumentReadystate(int ready_state); + IEEventSink* event_sink() { return event_sink_; } private: @@ -147,6 +149,59 @@ class MockIEEventSink : public IEEventListener { CComObject<IEEventSink>* event_sink_; }; +// This mocks a PropertyNotifySinkListener, providing methods for +// expecting certain sequences of events. +class MockPropertyNotifySinkListener : public PropertyNotifySinkListener { + public: + MockPropertyNotifySinkListener() : cookie_(0), sink_(NULL) { + CComObject<PropertyNotifySinkImpl>::CreateInstance(&sink_); + sink_->AddRef(); + sink_->set_listener(this); + } + + ~MockPropertyNotifySinkListener() { + Detach(); + sink_->set_listener(NULL); + DLOG_IF(ERROR, sink_->m_dwRef != 1) + << "Event sink is still referenced externally: ref count = " + << sink_->m_dwRef; + sink_->Release(); + } + + // Override PropertyNotifySinkListener methods. + MOCK_METHOD1(OnChanged, void (DISPID dispid)); // NOLINT + + bool Attach(IUnknown* obj) { + DCHECK_EQ(cookie_, 0UL); + DCHECK(obj); + HRESULT hr = AtlAdvise(obj, sink_->GetUnknown(), IID_IPropertyNotifySink, + &cookie_); + if (SUCCEEDED(hr)) { + event_source_ = obj; + } else { + LOG(ERROR) << StringPrintf("AtlAdvise: 0x%08X", hr); + cookie_ = 0; + } + + return SUCCEEDED(hr); + } + + void Detach() { + if (event_source_) { + DCHECK_NE(cookie_, 0UL); + AtlUnadvise(event_source_, IID_IPropertyNotifySink, cookie_); + event_source_.Release(); + cookie_ = 0; + } + } + + private: + CComObject<PropertyNotifySinkImpl>* sink_; + DWORD cookie_; + ScopedComPtr<IUnknown> event_source_; +}; + + // Mocks a window observer so that tests can detect new windows. class MockWindowObserver : public WindowObserver { public: diff --git a/chrome_frame/test/proxy_factory_mock.cc b/chrome_frame/test/proxy_factory_mock.cc index 8c3040e..4e9ddbc 100644 --- a/chrome_frame/test/proxy_factory_mock.cc +++ b/chrome_frame/test/proxy_factory_mock.cc @@ -17,39 +17,43 @@ TEST(ProxyFactoryTest, CreateDestroy) { LaunchDelegateMock d; EXPECT_CALL(d, LaunchComplete(testing::NotNull(), testing::_)).Times(1); - ChromeFrameLaunchParams params; - params.automation_server_launch_timeout = 0; - params.profile_name = L"Adam.N.Epilinter"; - params.extra_chrome_arguments = L""; - params.perform_version_check = false; - params.incognito_mode = false; + GURL empty; + FilePath profile_path; + scoped_refptr<ChromeFrameLaunchParams> params( + new ChromeFrameLaunchParams(empty, empty, profile_path, + L"Adam.N.Epilinter", L"", false, false)); + params->set_launch_timeout(0); + params->set_version_check(false); void* id = NULL; f.GetAutomationServer(&d, params, &id); - f.ReleaseAutomationServer(id); + f.ReleaseAutomationServer(id, &d); } TEST(ProxyFactoryTest, CreateSameProfile) { ProxyFactory f; LaunchDelegateMock d; - EXPECT_CALL(d, LaunchComplete(testing::NotNull(), testing::_)).Times(2); + LaunchDelegateMock d2; + EXPECT_CALL(d, LaunchComplete(testing::NotNull(), testing::_)).Times(1); + EXPECT_CALL(d2, LaunchComplete(testing::NotNull(), testing::_)).Times(1); - ChromeFrameLaunchParams params; - params.automation_server_launch_timeout = 0; - params.profile_name = L"Dr. Gratiano Forbeson"; - params.extra_chrome_arguments = L""; - params.perform_version_check = false; - params.incognito_mode = false; + GURL empty; + FilePath profile_path; + scoped_refptr<ChromeFrameLaunchParams> params( + new ChromeFrameLaunchParams(empty, empty, profile_path, + L"Dr. Gratiano Forbeson", L"", false, false)); + params->set_launch_timeout(0); + params->set_version_check(false); void* i1 = NULL; void* i2 = NULL; f.GetAutomationServer(&d, params, &i1); - f.GetAutomationServer(&d, params, &i2); + f.GetAutomationServer(&d2, params, &i2); EXPECT_EQ(i1, i2); - f.ReleaseAutomationServer(i2); - f.ReleaseAutomationServer(i1); + f.ReleaseAutomationServer(i2, &d2); + f.ReleaseAutomationServer(i1, &d); } TEST(ProxyFactoryTest, CreateDifferentProfiles) { @@ -57,19 +61,19 @@ TEST(ProxyFactoryTest, CreateDifferentProfiles) { LaunchDelegateMock d; EXPECT_CALL(d, LaunchComplete(testing::NotNull(), testing::_)).Times(2); - ChromeFrameLaunchParams params1; - params1.automation_server_launch_timeout = 0; - params1.profile_name = L"Adam.N.Epilinter"; - params1.extra_chrome_arguments = L""; - params1.perform_version_check = false; - params1.incognito_mode = false; + GURL empty; + FilePath profile_path; + scoped_refptr<ChromeFrameLaunchParams> params1( + new ChromeFrameLaunchParams(empty, empty, profile_path, + L"Adam.N.Epilinter", L"", false, false)); + params1->set_launch_timeout(0); + params1->set_version_check(false); - ChromeFrameLaunchParams params2; - params2.automation_server_launch_timeout = 0; - params2.profile_name = L"Dr. Gratiano Forbeson"; - params2.extra_chrome_arguments = L""; - params2.perform_version_check = false; - params2.incognito_mode = false; + scoped_refptr<ChromeFrameLaunchParams> params2( + new ChromeFrameLaunchParams(empty, empty, profile_path, + L"Dr. Gratiano Forbeson", L"", false, false)); + params2->set_launch_timeout(0); + params2->set_version_check(false); void* i1 = NULL; void* i2 = NULL; @@ -78,8 +82,8 @@ TEST(ProxyFactoryTest, CreateDifferentProfiles) { f.GetAutomationServer(&d, params2, &i2); EXPECT_NE(i1, i2); - f.ReleaseAutomationServer(i2); - f.ReleaseAutomationServer(i1); + f.ReleaseAutomationServer(i2, &d); + f.ReleaseAutomationServer(i1, &d); } TEST(ProxyFactoryTest, FastCreateDestroy) { @@ -87,17 +91,17 @@ TEST(ProxyFactoryTest, FastCreateDestroy) { LaunchDelegateMock* d1 = new LaunchDelegateMock(); LaunchDelegateMock* d2 = new LaunchDelegateMock(); - ChromeFrameLaunchParams params; - params.automation_server_launch_timeout = 10000; - params.profile_name = L"Dr. Gratiano Forbeson"; - params.extra_chrome_arguments = L""; - params.perform_version_check = false; - params.incognito_mode = false; + GURL empty; + FilePath profile_path; + scoped_refptr<ChromeFrameLaunchParams> params( + new ChromeFrameLaunchParams(empty, empty, profile_path, + L"Dr. Gratiano Forbeson", L"", false, false)); + params->set_launch_timeout(10000); + params->set_version_check(false); void* i1 = NULL; base::WaitableEvent launched(true, false); EXPECT_CALL(*d1, LaunchComplete(testing::NotNull(), AUTOMATION_SUCCESS)) - .Times(1) .WillOnce(testing::InvokeWithoutArgs(&launched, &base::WaitableEvent::Signal)); f.GetAutomationServer(d1, params, &i1); @@ -114,10 +118,10 @@ TEST(ProxyFactoryTest, FastCreateDestroy) { void* i2 = NULL; f.GetAutomationServer(d2, params, &i2); EXPECT_EQ(i1, i2); - f.ReleaseAutomationServer(i2); + f.ReleaseAutomationServer(i2, d2); delete d2; ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_NORMAL); - f.ReleaseAutomationServer(i1); + f.ReleaseAutomationServer(i1, d1); delete d1; } diff --git a/chrome_frame/test/proxy_factory_mock.h b/chrome_frame/test/proxy_factory_mock.h index 8f2bb2e..609d4b6 100644 --- a/chrome_frame/test/proxy_factory_mock.h +++ b/chrome_frame/test/proxy_factory_mock.h @@ -1,8 +1,8 @@ // Copyright (c) 2006-2010 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. -#ifndef CHROME_FRAME_PROXY_FACTORY_MOCK_H_ -#define CHROME_FRAME_PROXY_FACTORY_MOCK_H_ +#ifndef CHROME_FRAME_TEST_PROXY_FACTORY_MOCK_H_ +#define CHROME_FRAME_TEST_PROXY_FACTORY_MOCK_H_ #include <windows.h> #include <string> @@ -10,16 +10,20 @@ #include "gmock/gmock.h" #include "chrome_frame/chrome_frame_automation.h" -struct LaunchDelegateMock : public ProxyFactory::LaunchDelegate { +struct LaunchDelegateMock : public LaunchDelegate { MOCK_METHOD2(LaunchComplete, void(ChromeFrameAutomationProxy*, - AutomationLaunchResult)); + AutomationLaunchResult)); + MOCK_METHOD0(AutomationServerDied, void()); }; class MockProxyFactory : public ProxyFactory { public: - MOCK_METHOD3(GetAutomationServer, void (ProxyFactory::LaunchDelegate*, - const ChromeFrameLaunchParams& params, void** automation_server_id)); - MOCK_METHOD1(ReleaseAutomationServer, bool(void* id)); + MOCK_METHOD3(GetAutomationServer, + void (LaunchDelegate*, // NOLINT + ChromeFrameLaunchParams* params, + void** automation_server_id)); + MOCK_METHOD2(ReleaseAutomationServer, bool(void* server_id, + LaunchDelegate* delegate)); MockProxyFactory() : thread_("mock factory worker") { thread_.Start(); @@ -31,7 +35,7 @@ class MockProxyFactory : public ProxyFactory { void* proxy_id, AutomationLaunchResult result, LaunchDelegate* d, - const ChromeFrameLaunchParams& params, + ChromeFrameLaunchParams* params, void** automation_server_id); base::Thread thread_; @@ -39,5 +43,5 @@ class MockProxyFactory : public ProxyFactory { }; -#endif // CHROME_FRAME_PROXY_FACTORY_MOCK_H_ +#endif // CHROME_FRAME_TEST_PROXY_FACTORY_MOCK_H_ diff --git a/chrome_frame/test/ui_test.cc b/chrome_frame/test/ui_test.cc index 143df63..8eb4475 100644 --- a/chrome_frame/test/ui_test.cc +++ b/chrome_frame/test/ui_test.cc @@ -11,6 +11,8 @@ #include "chrome_frame/test/mock_ie_event_sink_actions.h" #include "chrome_frame/test/mock_ie_event_sink_test.h" +#include "testing/gmock_mutant.h" + using testing::_; using testing::InSequence; using testing::StrCaseEq; @@ -235,6 +237,84 @@ TEST_P(FullTabUITest, FLAKY_ViewSource) { LaunchIEAndNavigate(GetSimplePageUrl()); } +void NavigateToCurrentUrl(MockIEEventSink* mock) { + IWebBrowser2* browser = mock->event_sink()->web_browser2(); + DCHECK(browser); + ScopedBstr bstr; + HRESULT hr = browser->get_LocationURL(bstr.Receive()); + EXPECT_HRESULT_SUCCEEDED(hr); + if (SUCCEEDED(hr)) { + DCHECK(bstr.Length()); + VARIANT empty = ScopedVariant::kEmptyVariant; + hr = browser->Navigate(bstr, &empty, &empty, &empty, &empty); + EXPECT_HRESULT_SUCCEEDED(hr); + } +} + +// Tests that Chrome gets re-instantiated after crash if we reload via +// the address bar or via a new navigation. +TEST_P(FullTabUITest, TabCrashReload) { + using testing::DoAll; + + if (!GetParam().invokes_cf()) { + LOG(ERROR) << "Test needs CF."; + return; + } + + MockPropertyNotifySinkListener prop_listener; + InSequence expect_in_sequence_for_scope; + + EXPECT_CALL(ie_mock_, OnLoad(_, StrEq(GetSimplePageUrl()))) + .WillOnce(DoAll( + ExpectRendererHasFocus(&ie_mock_), + ExpectDocumentReadystate(&ie_mock_, READYSTATE_COMPLETE), + ConnectDocPropNotifySink(&ie_mock_, &prop_listener), + KillChromeFrameProcesses())); + + EXPECT_CALL(prop_listener, OnChanged(DISPID_READYSTATE)) + .WillOnce(DoAll( + ExpectDocumentReadystate(&ie_mock_, READYSTATE_UNINITIALIZED), + DelayNavigateToCurrentUrl(&ie_mock_, &loop_, 10))); + + EXPECT_CALL(ie_mock_, OnLoad(_, StrEq(GetSimplePageUrl()))) + .WillOnce(CloseBrowserMock(&ie_mock_)); + + LaunchIEAndNavigate(GetSimplePageUrl()); +} + +// Tests if Chrome gets restarted after a crash by just refreshing the document. +TEST_P(FullTabUITest, TabCrashRefresh) { + using testing::DoAll; + + if (!GetParam().invokes_cf()) { + LOG(ERROR) << "Test needs CF."; + return; + } + + MockPropertyNotifySinkListener prop_listener; + InSequence expect_in_sequence_for_scope; + + EXPECT_CALL(ie_mock_, OnLoad(_, StrEq(GetSimplePageUrl()))) + .WillOnce(DoAll( + ExpectRendererHasFocus(&ie_mock_), + ExpectDocumentReadystate(&ie_mock_, READYSTATE_COMPLETE), + ConnectDocPropNotifySink(&ie_mock_, &prop_listener), + KillChromeFrameProcesses())); + + VARIANT empty = ScopedVariant::kEmptyVariant; + EXPECT_CALL(prop_listener, OnChanged(/*DISPID_READYSTATE*/_)) + .WillOnce(DoAll( + DisconnectDocPropNotifySink(&prop_listener), + ExpectDocumentReadystate(&ie_mock_, READYSTATE_UNINITIALIZED), + DelayExecCommand(&ie_mock_, &loop_, 10, static_cast<GUID*>(NULL), + OLECMDID_REFRESH, 0, &empty, &empty))); + + EXPECT_CALL(ie_mock_, OnLoad(_, StrEq(GetSimplePageUrl()))) + .WillOnce(CloseBrowserMock(&ie_mock_)); + + LaunchIEAndNavigate(GetSimplePageUrl()); +} + // Test fixture for tests related to the context menu UI. Since the context // menus for CF and IE are different, these tests are not parameterized. class ContextMenuTest : public MockIEEventSinkTest, public testing::Test { |