Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Side by Side Diff: chrome_frame/test/chrome_frame_unittests.cc

Issue 340029: Added unit tests for ChromeFrame IE full tab mode. These test the following c... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 #include <windows.h> 4 #include <windows.h>
5 #include <stdarg.h> 5 #include <stdarg.h>
6 6
7 // IShellWindows includes. Unfortunately we can't keep these in 7 // IShellWindows includes. Unfortunately we can't keep these in
8 // alphabetic order since exdisp will bark if some interfaces aren't fully 8 // alphabetic order since exdisp will bark if some interfaces aren't fully
9 // defined. 9 // defined.
10 #include <mshtml.h> 10 #include <mshtml.h>
11 #include <exdisp.h> 11 #include <exdisp.h>
12 12
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/file_version_info.h" 14 #include "base/file_version_info.h"
15 #include "base/file_util.h" 15 #include "base/file_util.h"
16 #include "base/scoped_bstr_win.h" 16 #include "base/scoped_bstr_win.h"
17 #include "base/scoped_comptr_win.h"
18 #include "base/scoped_variant_win.h" 17 #include "base/scoped_variant_win.h"
19 #include "base/sys_info.h" 18 #include "base/sys_info.h"
20 #include "gmock/gmock.h" 19 #include "gmock/gmock.h"
21 #include "net/url_request/url_request_unittest.h" 20 #include "net/url_request/url_request_unittest.h"
22 #include "chrome_frame/test/chrome_frame_unittests.h" 21 #include "chrome_frame/test/chrome_frame_unittests.h"
23 #include "chrome_frame/chrome_frame_automation.h" 22 #include "chrome_frame/chrome_frame_automation.h"
24 #include "chrome_frame/chrome_frame_delegate.h" 23 #include "chrome_frame/chrome_frame_delegate.h"
25 #include "chrome_frame/crash_reporting/vectored_handler-impl.h" 24 #include "chrome_frame/crash_reporting/vectored_handler-impl.h"
26 #include "chrome_frame/test/chrome_frame_test_utils.h" 25 #include "chrome_frame/test/chrome_frame_test_utils.h"
27 #include "chrome_frame/test_utils.h" 26 #include "chrome_frame/test_utils.h"
(...skipping 29 matching lines...) Expand all
57 VT_DISPATCH, 56 VT_DISPATCH,
58 VT_VARIANT | VT_BYREF, 57 VT_VARIANT | VT_BYREF,
59 VT_VARIANT | VT_BYREF, 58 VT_VARIANT | VT_BYREF,
60 VT_VARIANT | VT_BYREF, 59 VT_VARIANT | VT_BYREF,
61 VT_VARIANT | VT_BYREF, 60 VT_VARIANT | VT_BYREF,
62 VT_VARIANT | VT_BYREF, 61 VT_VARIANT | VT_BYREF,
63 VT_BOOL | VT_BYREF 62 VT_BOOL | VT_BYREF
64 } 63 }
65 }; 64 };
66 65
66 _ATL_FUNC_INFO WebBrowserEventSink::kNewWindow3Info = {
67 CC_STDCALL, VT_EMPTY, 5, {
68 VT_DISPATCH | VT_BYREF,
69 VT_BOOL | VT_BYREF,
70 VT_UINT,
71 VT_BSTR,
72 VT_BSTR
73 }
74 };
75
67 76
68
69 void ChromeFrameTestWithWebServer::SetUp() { 77 void ChromeFrameTestWithWebServer::SetUp() {
70 server_.SetUp(); 78 server_.SetUp();
71 results_dir_ = server_.GetDataDir(); 79 results_dir_ = server_.GetDataDir();
72 file_util::AppendToPath(&results_dir_, L"dump"); 80 file_util::AppendToPath(&results_dir_, L"dump");
73 } 81 }
74 82
75 void ChromeFrameTestWithWebServer::TearDown() { 83 void ChromeFrameTestWithWebServer::TearDown() {
76 CloseBrowser(); 84 CloseBrowser();
77 85
78 // Web browsers tend to relaunch themselves in other processes, meaning the 86 // Web browsers tend to relaunch themselves in other processes, meaning the
(...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 template <> struct RunnableMethodTraits<ChromeFrameAutomationClient> { 831 template <> struct RunnableMethodTraits<ChromeFrameAutomationClient> {
824 void RetainCallee(ChromeFrameAutomationClient* obj) {} 832 void RetainCallee(ChromeFrameAutomationClient* obj) {}
825 void ReleaseCallee(ChromeFrameAutomationClient* obj) {} 833 void ReleaseCallee(ChromeFrameAutomationClient* obj) {}
826 }; 834 };
827 835
828 // MessageLoopForUI wrapper that runs only for a limited time. 836 // MessageLoopForUI wrapper that runs only for a limited time.
829 // We need a UI message loop in the main thread. 837 // We need a UI message loop in the main thread.
830 struct TimedMsgLoop { 838 struct TimedMsgLoop {
831 public: 839 public:
832 void RunFor(int seconds) { 840 void RunFor(int seconds) {
833 loop_.PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask, 1000 * seconds); 841 QuitAfter(seconds);
834 loop_.MessageLoop::Run(); 842 loop_.MessageLoop::Run();
835 } 843 }
836 844
837 void Quit() { 845 void Quit() {
838 loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask); 846 loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask);
839 } 847 }
840 848
849 void QuitAfter(int seconds) {
850 loop_.PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask, 1000 * seconds);
851 }
852
841 MessageLoopForUI loop_; 853 MessageLoopForUI loop_;
842 }; 854 };
843 855
844 template <> struct RunnableMethodTraits<TimedMsgLoop> { 856 template <> struct RunnableMethodTraits<TimedMsgLoop> {
845 void RetainCallee(TimedMsgLoop* obj) {} 857 void RetainCallee(TimedMsgLoop* obj) {}
846 void ReleaseCallee(TimedMsgLoop* obj) {} 858 void ReleaseCallee(TimedMsgLoop* obj) {}
847 }; 859 };
848 860
849 // Saves typing. It's somewhat hard to create a wrapper around 861 // Saves typing. It's somewhat hard to create a wrapper around
850 // testing::InvokeWithoutArgs since it returns a 862 // testing::InvokeWithoutArgs since it returns a
851 // non-public (testing::internal) type. 863 // non-public (testing::internal) type.
852 #define QUIT_LOOP(loop) testing::InvokeWithoutArgs(\ 864 #define QUIT_LOOP(loop) testing::InvokeWithoutArgs(\
853 CreateFunctor(&loop, &TimedMsgLoop::Quit)) 865 CreateFunctor(&loop, &TimedMsgLoop::Quit))
854 866
867 #define QUIT_LOOP_SOON(loop, seconds) testing::InvokeWithoutArgs(\
868 CreateFunctor(&loop, &TimedMsgLoop::QuitAfter, seconds))
869
855 // We mock ChromeFrameDelegate only. The rest is with real AutomationProxy 870 // We mock ChromeFrameDelegate only. The rest is with real AutomationProxy
856 TEST(CFACWithChrome, CreateTooFast) { 871 TEST(CFACWithChrome, CreateTooFast) {
857 MockCFDelegate cfd; 872 MockCFDelegate cfd;
858 TimedMsgLoop loop; 873 TimedMsgLoop loop;
859 int timeout = 0; // Chrome cannot send Hello message so fast. 874 int timeout = 0; // Chrome cannot send Hello message so fast.
860 const std::wstring profile = L"Adam.N.Epilinter"; 875 const std::wstring profile = L"Adam.N.Epilinter";
861 876
862 scoped_ptr<ChromeFrameAutomationClient> client; 877 scoped_ptr<ChromeFrameAutomationClient> client;
863 client.reset(new ChromeFrameAutomationClient()); 878 client.reset(new ChromeFrameAutomationClient());
864 879
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, 1288 CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2,
1274 reinterpret_cast<void**>(web_browser2.Receive())); 1289 reinterpret_cast<void**>(web_browser2.Receive()));
1275 1290
1276 if (SUCCEEDED(hr)) { 1291 if (SUCCEEDED(hr)) {
1277 *web_browser = web_browser2.Detach(); 1292 *web_browser = web_browser2.Detach();
1278 } 1293 }
1279 1294
1280 return hr; 1295 return hr;
1281 } 1296 }
1282 1297
1283 TEST(ChromeFrameTest, FullTabModeIE_DisallowedUrls) { 1298 // WebBrowserEventSink member defines
1299 HRESULT WebBrowserEventSink::LaunchIEAndNavigate(
1300 const std::wstring& navigate_url, _IDispEvent* sink) {
1284 int major_version = 0; 1301 int major_version = 0;
1285 int minor_version = 0; 1302 int minor_version = 0;
1286 int bugfix_version = 0; 1303 int bugfix_version = 0;
1287 1304
1288 base::SysInfo::OperatingSystemVersionNumbers(&major_version, &minor_version, 1305 base::SysInfo::OperatingSystemVersionNumbers(&major_version, &minor_version,
1289 &bugfix_version); 1306 &bugfix_version);
1290 if (major_version > 5) { 1307 if (major_version > 5) {
1291 DLOG(INFO) << __FUNCTION__ << " Not running test on Windows version: " 1308 DLOG(INFO) << __FUNCTION__ << " Not running test on Windows version: "
1292 << major_version; 1309 << major_version;
1293 return; 1310 return S_FALSE;
1294 } 1311 }
1295 1312
1296 IEVersion ie_version = GetIEVersion(); 1313 IEVersion ie_version = GetIEVersion();
1297 if (ie_version == IE_8) { 1314 if (ie_version == IE_8) {
1298 DLOG(INFO) << __FUNCTION__ << " Not running test on IE8"; 1315 DLOG(INFO) << __FUNCTION__ << " Not running test on IE8";
1299 return; 1316 return S_FALSE;
1300 } 1317 }
1301 1318
1302 HRESULT hr = CoInitialize(NULL); 1319 EXPECT_TRUE(S_OK == LaunchIEAsComServer(web_browser2_.Receive()));
1303 bool should_uninit = SUCCEEDED(hr); 1320 web_browser2_->put_Visible(VARIANT_TRUE);
1304 1321
1305 ScopedComPtr<IWebBrowser2> web_browser2; 1322 HRESULT hr = sink->DispEventAdvise(web_browser2_,
1306 EXPECT_TRUE(S_OK == LaunchIEAsComServer(web_browser2.Receive())); 1323 &DIID_DWebBrowserEvents2);
1307 web_browser2->put_Visible(VARIANT_TRUE);
1308
1309 CComObject<WebBrowserEventSink>* web_browser_sink = NULL;
1310 CComObject<WebBrowserEventSink>::CreateInstance(&web_browser_sink);
1311
1312 // Pass the main thread id to the browser sink so that it can notify
1313 // us about test completion.
1314 web_browser_sink->set_main_thread_id(GetCurrentThreadId());
1315
1316 hr = web_browser_sink->DispEventAdvise(web_browser2,
1317 &DIID_DWebBrowserEvents2);
1318 EXPECT_TRUE(hr == S_OK); 1324 EXPECT_TRUE(hr == S_OK);
1319 1325
1320 VARIANT empty = ScopedVariant::kEmptyVariant; 1326 VARIANT empty = ScopedVariant::kEmptyVariant;
1321 ScopedVariant url; 1327 ScopedVariant url;
1322 url.Set(L"cf:file:///C:/"); 1328 url.Set(navigate_url.c_str());
1323 1329
1330 hr = web_browser2_->Navigate2(url.AsInput(), &empty, &empty, &empty, &empty);
1331 EXPECT_TRUE(hr == S_OK);
1332 return hr;
1333 }
1334
1335 const int kChromeFrameLongNavigationTimeoutInSeconds = 10;
1336
1337 // This class provides functionality to add expectations to IE full tab mode
1338 // tests.
1339 class MockWebBrowserEventSink : public WebBrowserEventSink {
1340 public:
1341 // Needed to support PostTask.
1342 static bool ImplementsThreadSafeReferenceCounting() {
1343 return true;
1344 }
1345
1346 MOCK_METHOD7_WITH_CALLTYPE(__stdcall, OnBeforeNavigate2,
1347 HRESULT (IDispatch* dispatch,
1348 VARIANT* url,
1349 VARIANT* flags,
1350 VARIANT* target_frame_name,
1351 VARIANT* post_data,
1352 VARIANT* headers,
1353 VARIANT_BOOL* cancel));
1354
1355 MOCK_METHOD2_WITH_CALLTYPE(__stdcall, OnNavigateComplete2,
1356 void (IDispatch* dispatch, VARIANT* url));
1357
1358 MOCK_METHOD5_WITH_CALLTYPE(__stdcall, OnNewWindow3,
1359 void (IDispatch** dispatch,
1360 VARIANT_BOOL* Cancel,
1361 DWORD flags,
1362 BSTR url_context,
1363 BSTR url));
1364
1365 MOCK_METHOD5_WITH_CALLTYPE(__stdcall, OnNavigateError,
1366 void (IDispatch* dispatch,
1367 VARIANT* url,
1368 VARIANT* frame_name,
1369 VARIANT* status_code,
1370 VARIANT* cancel));
1371 };
1372
1373 using testing::_;
1374
1375 const wchar_t kChromeFrameFileUrl[] = L"cf:file:///C:/";
1376
1377 TEST(ChromeFrameTest, FullTabModeIE_DisallowedUrls) {
1324 TimedMsgLoop loop; 1378 TimedMsgLoop loop;
1325 1379 // If a navigation fails then IE issues a navigation to an interstitial
1326 hr = web_browser2->Navigate2(url.AsInput(), &empty, &empty, &empty, &empty); 1380 // page. Catch this to track navigation errors as the NavigateError
1327 EXPECT_TRUE(hr == S_OK); 1381 // notification does not seem to fire reliably.
1328 1382 CComObjectStackEx<MockWebBrowserEventSink> mock;
1329 loop.RunFor(10); 1383
1330 1384 EXPECT_CALL(mock,
1331 EXPECT_TRUE(web_browser_sink->navigation_failed()); 1385 OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
1332 1386 testing::StrCaseEq(kChromeFrameFileUrl)),
1333 hr = web_browser_sink->DispEventUnadvise(web_browser2); 1387 _, _, _, _, _))
1334 EXPECT_TRUE(hr == S_OK); 1388 .Times(1)
1335 1389 .WillOnce(testing::Return(S_OK));
1336 web_browser2.Release(); 1390
1391 EXPECT_CALL(mock,
1392 OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
1393 testing::StartsWith(L"res:")),
1394 _, _, _, _, _))
1395 .Times(1)
1396 .WillOnce(testing::DoAll(
1397 QUIT_LOOP(loop),
1398 testing::Return(S_OK)));
1399
1400 HRESULT hr = mock.LaunchIEAndNavigate(kChromeFrameFileUrl, &mock);
1401 ASSERT_HRESULT_SUCCEEDED(hr);
1402 if (hr == S_FALSE)
1403 return;
1404
1405 ASSERT_TRUE(mock.web_browser2() != NULL);
1406
1407 loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds);
1408
1409 mock.Uninitialize();
1337 chrome_frame_test::CloseAllIEWindows(); 1410 chrome_frame_test::CloseAllIEWindows();
1338 1411 }
1339 if (should_uninit) { 1412
1340 CoUninitialize(); 1413 const wchar_t kChromeFrameFullTabWindowOpenTestUrl[] =
1341 } 1414 L"http://localhost:1337/files/chrome_frame_window_open.html";
1342 } 1415
1343 1416 const wchar_t kChromeFrameFullTabWindowOpenPopupUrl[] =
1417 L"http://localhost:1337/files/chrome_frame_window_open_popup.html";
1418
1419 // This test checks if window.open calls issued by a full tab mode ChromeFrame
1420 // instance make it back to IE and then transitions back to Chrome as the
1421 // window.open target page is supposed to render within Chrome.
1422 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_WindowOpen) {
1423 TimedMsgLoop loop;
1424
1425 CComObjectStackEx<MockWebBrowserEventSink> mock;
1426
1427 EXPECT_CALL(mock,
1428 OnBeforeNavigate2(
1429 _, testing::Field(&VARIANT::bstrVal,
1430 testing::StrCaseEq(kChromeFrameFullTabWindowOpenTestUrl)),
1431 _, _, _, _, _))
1432 .Times(1)
1433 .WillOnce(testing::Return(S_OK));
1434
1435 EXPECT_CALL(mock,
1436 OnBeforeNavigate2(
1437 _, testing::Field(&VARIANT::bstrVal,
1438 testing::StrCaseEq(kChromeFrameFullTabWindowOpenPopupUrl)),
1439 _, _, _, _, _))
1440 .Times(1)
1441 .WillOnce(testing::DoAll(
1442 QUIT_LOOP_SOON(loop, 2),
1443 testing::Return(S_OK)));
1444
1445 HRESULT hr = mock.LaunchIEAndNavigate(kChromeFrameFullTabWindowOpenTestUrl,
1446 &mock);
1447 ASSERT_HRESULT_SUCCEEDED(hr);
1448 if (hr == S_FALSE)
1449 return;
1450
1451 ASSERT_TRUE(mock.web_browser2() != NULL);
1452
1453 loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds);
1454
1455 ASSERT_TRUE(CheckResultFile(L"ChromeFrameWindowOpenPopup", "OK"));
1456
1457 mock.Uninitialize();
1458 chrome_frame_test::CloseAllIEWindows();
1459 }
1460
1461 const wchar_t kChromeFrameAboutBlankUrl[] =
1462 L"cf:about:blank";
1463
1464 const wchar_t kChromeFrameAboutVersion[] =
1465 L"cf:about:version";
1466
1467 // This test launches chrome frame in full tab mode in IE by having IE navigate
1468 // to cf:about:blank. It then looks for the chrome renderer window and posts
1469 // the WM_RBUTTONDOWN/WM_RBUTTONUP messages to it, which bring up the context
1470 // menu. This is followed by keyboard messages sent via SendInput to select
1471 // the About chrome frame menu option, which would then bring up a new window
1472 // with the chrome revision. The test finally checks for success by comparing
1473 // the URL of the window being opened with cf:about:version, which indicates
1474 // that the operation succeeded.
1475 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_AboutChromeFrame) {
1476 TimedMsgLoop loop;
1477
1478 CComObjectStackEx<MockWebBrowserEventSink> mock;
1479
1480 EXPECT_CALL(mock,
1481 OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal,
1482 testing::StrCaseEq(kChromeFrameAboutBlankUrl)),
1483 _, _, _, _, _))
1484 .Times(1)
1485 .WillOnce(testing::Return(S_OK));
1486
1487 EXPECT_CALL(mock, OnNavigateComplete2(_, _))
1488 .Times(1)
1489 .WillOnce(testing::InvokeWithoutArgs(
1490 &chrome_frame_test::ShowChromeFrameContextMenu));
1491
1492 EXPECT_CALL(mock,
1493 OnNewWindow3(_, _, _, _,
1494 testing::StrCaseEq(kChromeFrameAboutVersion)))
1495 .Times(1)
1496 .WillOnce(QUIT_LOOP(loop));
1497
1498 HRESULT hr = mock.LaunchIEAndNavigate(kChromeFrameAboutBlankUrl, &mock);
1499 ASSERT_HRESULT_SUCCEEDED(hr);
1500 if (hr == S_FALSE)
1501 return;
1502
1503 ASSERT_TRUE(mock.web_browser2() != NULL);
1504
1505 loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds);
1506
1507 mock.Uninitialize();
1508 chrome_frame_test::CloseAllIEWindows();
1509 }
1510
OLDNEW
« no previous file with comments | « chrome_frame/test/chrome_frame_unittests.h ('k') | chrome_frame/test/data/chrome_frame_tester_helpers.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698