Loosen up heuristics for detecting account creation forms.
[chromium-blink-merge.git] / chrome_frame / test / test_with_web_server.cc
blobbaf4c6bd28e397b76c3e4430940305dea6353b84
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome_frame/test/test_with_web_server.h"
7 #include "base/base_paths.h"
8 #include "base/file_version_info.h"
9 #include "base/path_service.h"
10 #include "base/stringprintf.h"
11 #include "base/test/test_timeouts.h"
12 #include "base/utf_string_conversions.h"
13 #include "base/win/windows_version.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/installer/util/product.h"
16 #include "chrome/installer/util/install_util.h"
17 #include "chrome/installer/util/helper.h"
18 #include "chrome_frame/html_utils.h"
19 #include "chrome_frame/utils.h"
20 #include "chrome_frame/test/chrome_frame_test_utils.h"
21 #include "chrome_frame/test/mock_ie_event_sink_actions.h"
22 #include "chrome_frame/test/mock_ie_event_sink_test.h"
23 #include "chrome_frame/test/test_scrubber.h"
24 #include "net/base/mime_util.h"
25 #include "net/base/stream_listen_socket.h"
26 #include "net/http/http_util.h"
28 using chrome_frame_test::kChromeFrameLongNavigationTimeout;
29 using chrome_frame_test::kChromeFrameVeryLongNavigationTimeout;
31 using testing::_;
32 using testing::StrCaseEq;
34 const wchar_t kDocRoot[] = L"chrome_frame\\test\\data";
36 namespace {
38 // Helper method for creating the appropriate HTTP response headers.
39 std::string CreateHttpHeaders(CFInvocation invocation,
40 bool add_no_cache_header,
41 const std::string& content_type) {
42 std::ostringstream ss;
43 ss << "HTTP/1.1 200 OK\r\n"
44 << "Connection: close\r\n"
45 << "Content-Type: " << content_type << "\r\n";
46 if (invocation.type() == CFInvocation::HTTP_HEADER)
47 ss << "X-UA-Compatible: chrome=1\r\n";
48 if (add_no_cache_header) {
49 ss << "Cache-Control: no-cache\r\n";
50 ss << "Expires: Tue, 15 Nov 1994 08:12:31 GMT\r\n";
52 return ss.str();
55 std::string GetMockHttpHeaders(const FilePath& mock_http_headers_path) {
56 std::string headers;
57 file_util::ReadFileToString(mock_http_headers_path, &headers);
58 return headers;
61 class ChromeFrameTestEnvironment: public testing::Environment {
62 public:
63 virtual ~ChromeFrameTestEnvironment() {}
64 virtual void SetUp() OVERRIDE {
65 ScopedChromeFrameRegistrar::RegisterDefaults();
69 ::testing::Environment* const chrome_frame_env =
70 ::testing::AddGlobalTestEnvironment(new ChromeFrameTestEnvironment);
72 } // namespace
74 FilePath ChromeFrameTestWithWebServer::test_file_path_;
75 FilePath ChromeFrameTestWithWebServer::results_dir_;
76 FilePath ChromeFrameTestWithWebServer::CFInstall_path_;
77 FilePath ChromeFrameTestWithWebServer::CFInstance_path_;
78 ScopedTempDir ChromeFrameTestWithWebServer::temp_dir_;
79 FilePath ChromeFrameTestWithWebServer::chrome_user_data_dir_;
80 chrome_frame_test::TimedMsgLoop* ChromeFrameTestWithWebServer::loop_;
81 std::string ChromeFrameTestWithWebServer::local_address_;
82 testing::StrictMock<MockWebServerListener>*
83 ChromeFrameTestWithWebServer::listener_mock_;
84 testing::StrictMock<MockWebServer>* ChromeFrameTestWithWebServer::server_mock_;
86 ChromeFrameTestWithWebServer::ChromeFrameTestWithWebServer() {
89 // static
90 void ChromeFrameTestWithWebServer::SetUpTestCase() {
91 FilePath chrome_frame_source_path;
92 PathService::Get(base::DIR_SOURCE_ROOT, &chrome_frame_source_path);
93 chrome_frame_source_path = chrome_frame_source_path.Append(
94 FILE_PATH_LITERAL("chrome_frame"));
96 test_file_path_ = chrome_frame_source_path
97 .Append(FILE_PATH_LITERAL("test"))
98 .Append(FILE_PATH_LITERAL("data"));
100 results_dir_ = chrome_frame_test::GetTestDataFolder().AppendASCII("dump");
102 // Copy the CFInstance.js and CFInstall.js files from src\chrome_frame to
103 // src\chrome_frame\test\data.
104 FilePath CFInstance_src_path;
105 FilePath CFInstall_src_path;
107 CFInstance_src_path = chrome_frame_source_path.AppendASCII("CFInstance.js");
108 CFInstance_path_ = test_file_path_.AppendASCII("CFInstance.js");
110 ASSERT_TRUE(file_util::CopyFile(CFInstance_src_path, CFInstance_path_));
112 CFInstall_src_path = chrome_frame_source_path.AppendASCII("CFInstall.js");
113 CFInstall_path_ = test_file_path_.AppendASCII("CFInstall.js");
115 ASSERT_TRUE(file_util::CopyFile(CFInstall_src_path, CFInstall_path_));
117 loop_ = new chrome_frame_test::TimedMsgLoop();
118 loop_->set_snapshot_on_timeout(true);
119 local_address_ = chrome_frame_test::GetLocalIPv4Address();
120 listener_mock_ = new testing::StrictMock<MockWebServerListener>();
121 server_mock_ = new testing::StrictMock<MockWebServer>(
122 1337, ASCIIToWide(local_address_),
123 chrome_frame_test::GetTestDataFolder());
124 server_mock_->set_listener(listener_mock_);
127 // static
128 void ChromeFrameTestWithWebServer::TearDownTestCase() {
129 delete server_mock_;
130 server_mock_ = NULL;
131 delete listener_mock_;
132 listener_mock_ = NULL;
133 local_address_.clear();
134 delete loop_;
135 loop_ = NULL;
136 file_util::Delete(CFInstall_path_, false);
137 file_util::Delete(CFInstance_path_, false);
138 if (temp_dir_.IsValid())
139 EXPECT_TRUE(temp_dir_.Delete());
142 // static
143 const FilePath& ChromeFrameTestWithWebServer::GetChromeUserDataDirectory() {
144 if (!temp_dir_.IsValid()) {
145 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
146 chrome_user_data_dir_ = temp_dir_.path().AppendASCII("User Data");
148 return chrome_user_data_dir_;
151 void ChromeFrameTestWithWebServer::SetUp() {
152 // Make sure that we are not accidentally enabling gcf protocol.
153 SetConfigBool(kAllowUnsafeURLs, false);
155 server_mock().ClearResults();
156 server_mock().ExpectAndServeAnyRequests(CFInvocation(CFInvocation::NONE));
157 server_mock().set_expected_result("OK");
160 void ChromeFrameTestWithWebServer::TearDown() {
161 CloseBrowser();
162 loop().RunAllPending();
163 testing::Mock::VerifyAndClear(listener_mock_);
164 testing::Mock::VerifyAndClear(server_mock_);
167 bool ChromeFrameTestWithWebServer::LaunchBrowser(BrowserKind browser,
168 const wchar_t* page) {
169 std::wstring url = page;
171 // We should resolve the URL only if it is a relative url.
172 GURL parsed_url(WideToUTF8(page));
173 if (!parsed_url.has_scheme()) {
174 url = server_mock().Resolve(page);
177 browser_ = browser;
178 if (browser == IE) {
179 browser_handle_.Set(chrome_frame_test::LaunchIE(url));
180 } else if (browser == CHROME) {
181 const FilePath& user_data_dir = GetChromeUserDataDirectory();
182 chrome_frame_test::OverrideDataDirectoryForThisTest(user_data_dir.value());
183 browser_handle_.Set(chrome_frame_test::LaunchChrome(url, user_data_dir));
184 } else {
185 NOTREACHED();
188 return browser_handle_.IsValid();
191 void ChromeFrameTestWithWebServer::CloseBrowser() {
192 if (!browser_handle_.IsValid())
193 return;
195 int attempts = 0;
196 if (browser_ == IE) {
197 attempts = chrome_frame_test::CloseAllIEWindows();
198 } else {
199 attempts = chrome_frame_test::CloseVisibleWindowsOnAllThreads(
200 browser_handle_);
203 if (attempts > 0) {
204 DWORD wait = ::WaitForSingleObject(browser_handle_, 20000);
205 if (wait == WAIT_OBJECT_0) {
206 browser_handle_.Close();
207 } else {
208 LOG(ERROR) << "WaitForSingleObject returned " << wait;
210 } else {
211 LOG(ERROR) << "No attempts to close browser windows";
214 if (browser_handle_.IsValid()) {
215 DWORD exit_code = 0;
216 if (!::GetExitCodeProcess(browser_handle_, &exit_code) ||
217 exit_code == STILL_ACTIVE) {
218 LOG(ERROR) << L"Forcefully killing browser process. Exit:" << exit_code;
219 base::KillProcess(browser_handle_, 0, true);
221 browser_handle_.Close();
225 bool ChromeFrameTestWithWebServer::BringBrowserToTop() {
226 return simulate_input::EnsureProcessInForeground(
227 GetProcessId(browser_handle_));
230 bool ChromeFrameTestWithWebServer::WaitForTestToComplete(
231 base::TimeDelta duration) {
232 loop().RunFor(duration);
233 return !loop().WasTimedOut();
236 bool ChromeFrameTestWithWebServer::WaitForOnLoad(int milliseconds) {
237 return false;
240 const wchar_t kPostedResultSubstring[] = L"/writefile/";
242 void ChromeFrameTestWithWebServer::SimpleBrowserTestExpectedResult(
243 BrowserKind browser, const wchar_t* page, const char* result) {
244 int tries = 0;
245 ExpectAndHandlePostedResult();
246 // Retry tests that timeout once; see http://crbug.com/96449.
247 do {
248 // NOTE: Failed ASSERTs cause this function to exit immediately.
249 // Don't take a snapshot on the first try.
250 loop().set_snapshot_on_timeout(tries != 0);
251 ASSERT_TRUE(LaunchBrowser(browser, page));
252 if (WaitForTestToComplete(TestTimeouts::action_max_timeout())) {
253 // The test exited without timing out. Confirm that the expected response
254 // was posted and return.
255 ASSERT_EQ(result, server_mock().posted_result());
256 break;
258 ASSERT_EQ(std::string(), server_mock().posted_result())
259 << "Test timed out yet provided a result.";
260 ASSERT_EQ(0, tries++) << "Failing test due to two timeouts.";
261 // Close the browser and try a second time.
262 CloseBrowser();
263 LOG(ERROR) << "Retrying test once since it timed out.";
264 } while (true);
265 loop().set_snapshot_on_timeout(true);
268 void ChromeFrameTestWithWebServer::SimpleBrowserTest(BrowserKind browser,
269 const wchar_t* page) {
270 SimpleBrowserTestExpectedResult(browser, page, "OK");
273 void ChromeFrameTestWithWebServer::ExpectAndHandlePostedResult() {
274 EXPECT_CALL(listener_mock(), OnExpectedResponse())
275 .WillRepeatedly(QUIT_LOOP_SOON(loop(),
276 base::TimeDelta::FromMilliseconds(100)));
277 server_mock().ExpectAndHandlePostedResult(CFInvocation(CFInvocation::NONE),
278 kPostedResultSubstring);
281 void ChromeFrameTestWithWebServer::VersionTest(BrowserKind browser,
282 const wchar_t* page) {
283 FilePath plugin_path;
284 PathService::Get(base::DIR_MODULE, &plugin_path);
285 plugin_path = plugin_path.Append(kChromeFrameDllName);
287 static FileVersionInfo* version_info =
288 FileVersionInfo::CreateFileVersionInfo(plugin_path);
290 std::wstring version;
291 if (version_info)
292 version = version_info->product_version();
294 // If we can't find the Chrome Frame DLL in the src tree, we turn to
295 // the directory where chrome is installed.
296 if (!version_info) {
297 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
298 Version ver_system;
299 InstallUtil::GetChromeVersion(dist, true, &ver_system);
300 Version ver_user;
301 InstallUtil::GetChromeVersion(dist, false, &ver_system);
302 ASSERT_TRUE(ver_system.IsValid() || ver_user.IsValid());
304 bool system_install = ver_system.IsValid();
305 FilePath cf_dll_path(installer::GetChromeInstallPath(system_install, dist));
306 cf_dll_path = cf_dll_path.Append(UTF8ToWide(
307 ver_system.IsValid() ? ver_system.GetString() : ver_user.GetString()));
308 cf_dll_path = cf_dll_path.Append(kChromeFrameDllName);
309 version_info = FileVersionInfo::CreateFileVersionInfo(cf_dll_path);
310 if (version_info)
311 version = version_info->product_version();
314 server_mock().set_expected_result(WideToUTF8(version));
316 EXPECT_TRUE(version_info);
317 EXPECT_FALSE(version.empty());
319 SimpleBrowserTestExpectedResult(browser, page, WideToASCII(version).c_str());
322 // MockWebServer methods
323 void MockWebServer::ExpectAndServeRequest(CFInvocation invocation,
324 const std::wstring& url) {
325 ExpectAndServeRequestWithCardinality(invocation, url, testing::Exactly(1));
328 void MockWebServer::ExpectAndServeRequestWithCardinality(
329 CFInvocation invocation, const std::wstring& url,
330 testing::Cardinality cardinality) {
331 EXPECT_CALL(*this, Get(_, chrome_frame_test::UrlPathEq(url), _))
332 .Times(cardinality)
333 .WillRepeatedly(SendResponse(this, invocation));
336 void MockWebServer::ExpectAndServeRequestAllowCache(CFInvocation invocation,
337 const std::wstring &url) {
338 EXPECT_CALL(*this, Get(_, chrome_frame_test::UrlPathEq(url), _))
339 .WillOnce(SendResponse(this, invocation));
342 void MockWebServer::ExpectAndServeRequestAnyNumberTimes(
343 CFInvocation invocation, const std::wstring& path_prefix) {
344 EXPECT_CALL(*this, Get(_, testing::StartsWith(path_prefix), _))
345 .WillRepeatedly(SendResponse(this, invocation));
348 void MockWebServer::ExpectAndHandlePostedResult(
349 CFInvocation invocation, const std::wstring& post_suffix) {
350 EXPECT_CALL(*this, Post(_, testing::HasSubstr(post_suffix), _))
351 .WillRepeatedly(HandlePostedResponseHelper(this, invocation));
354 void MockWebServer::HandlePostedResponse(
355 test_server::ConfigurableConnection* connection,
356 const test_server::Request& request) {
357 posted_result_ = request.content();
358 if (listener_ && posted_result_ == expected_result_)
359 listener_->OnExpectedResponse();
360 connection->Send("HTTP/1.1 200 OK\r\n", "");
363 void MockWebServer::SendResponseHelper(
364 test_server::ConfigurableConnection* connection,
365 const std::wstring& request_uri,
366 const test_server::Request& request,
367 CFInvocation invocation,
368 bool add_no_cache_header) {
369 static const wchar_t kEchoHeader[] = L"/echoheader?";
370 if (request_uri.find(kEchoHeader) != std::wstring::npos) {
371 std::wstring header = request_uri.substr(
372 wcslen(kEchoHeader),
373 request_uri.length() - wcslen(kEchoHeader));
375 std::string header_value = http_utils::GetHttpHeaderFromHeaderList(
376 WideToUTF8(header), request.headers());
377 connection->Send(header_value, "");
378 return;
380 // Convert |request_uri| to a path.
381 std::wstring path = request_uri;
382 size_t query_index = request_uri.find(L"?");
383 if (query_index != std::string::npos) {
384 path = path.erase(query_index);
386 FilePath file_path = root_dir_;
387 if (path.size())
388 file_path = file_path.Append(path.substr(1)); // remove first '/'
390 std::string headers, body;
391 std::string content_type;
392 if (file_util::PathExists(file_path) &&
393 !file_util::DirectoryExists(file_path)) {
394 FilePath mock_http_headers(file_path.value() + L".mock-http-headers");
395 if (file_util::PathExists(mock_http_headers)) {
396 headers = GetMockHttpHeaders(mock_http_headers);
397 content_type = http_utils::GetHttpHeaderFromHeaderList("Content-type",
398 headers);
399 } else {
400 EXPECT_TRUE(net::GetMimeTypeFromFile(file_path, &content_type));
401 VLOG(1) << "Going to send file (" << WideToUTF8(file_path.value())
402 << ") with content type (" << content_type << ")";
403 headers = CreateHttpHeaders(invocation, add_no_cache_header,
404 content_type);
407 EXPECT_FALSE(headers.empty());
409 EXPECT_TRUE(file_util::ReadFileToString(file_path, &body))
410 << "Could not read file (" << WideToUTF8(file_path.value()) << ")";
411 if (invocation.type() == CFInvocation::META_TAG &&
412 StartsWithASCII(content_type, "text/html", false)) {
413 EXPECT_TRUE(chrome_frame_test::AddCFMetaTag(&body)) << "Could not add "
414 << "meta tag to HTML file.";
416 } else {
417 VLOG(1) << "Going to send 404 for non-existent file ("
418 << WideToUTF8(file_path.value()) << ")";
419 headers = "HTTP/1.1 404 Not Found";
420 body = "";
422 connection->Send(headers, body);
425 const wchar_t kPostMessageBasicPage[] = L"postmessage_basic_host.html";
427 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_PostMessageBasic) {
428 SimpleBrowserTest(IE, kPostMessageBasicPage);
431 TEST_F(ChromeFrameTestWithWebServer, FullTabIE_MIMEFilterBasic) {
432 const wchar_t kMIMEFilterBasicPage[] =
433 L"chrome_frame_mime_filter_test.html";
435 // If this test fails for IE8 then it is possible that prebinding is enabled.
436 // A known workaround is to disable it until CF properly handles it.
438 // HKCU\Software\Microsoft\Internet Explorer\Main
439 // Value name: EnablePreBinding (REG_DWORD)
440 // Value: 0
441 SimpleBrowserTest(IE, kMIMEFilterBasicPage);
444 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_Resize) {
445 SimpleBrowserTest(IE, L"chrome_frame_resize.html");
448 const wchar_t kNavigateURLAbsolutePage[] =
449 L"navigateurl_absolute_host.html";
451 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_NavigateURLAbsolute) {
452 SimpleBrowserTest(IE, kNavigateURLAbsolutePage);
455 const wchar_t kNavigateURLRelativePage[] =
456 L"navigateurl_relative_host.html";
458 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_NavigateURLRelative) {
459 SimpleBrowserTest(IE, kNavigateURLRelativePage);
462 const wchar_t kNavigateSimpleObjectFocus[] = L"simple_object_focus.html";
464 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_ObjectFocus) {
465 SimpleBrowserTest(IE, kNavigateSimpleObjectFocus);
468 const wchar_t kiframeBasicPage[] = L"iframe_basic_host.html";
470 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_iframeBasic) {
471 SimpleBrowserTest(IE, kiframeBasicPage);
474 const wchar_t kSrcPropertyTestPage[] = L"src_property_host.html";
476 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_SrcProperty) {
477 SimpleBrowserTest(IE, kSrcPropertyTestPage);
480 const wchar_t kCFInstanceBasicTestPage[] = L"CFInstance_basic_host.html";
482 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceBasic) {
483 SimpleBrowserTest(IE, kCFInstanceBasicTestPage);
486 const wchar_t kCFISingletonPage[] = L"CFInstance_singleton_host.html";
488 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceSingleton) {
489 SimpleBrowserTest(IE, kCFISingletonPage);
492 const wchar_t kCFIDelayPage[] = L"CFInstance_delay_host.html";
494 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceDelay) {
495 SimpleBrowserTest(IE, kCFIDelayPage);
498 const wchar_t kCFIFallbackPage[] = L"CFInstance_fallback_host.html";
500 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceFallback) {
501 SimpleBrowserTest(IE, kCFIFallbackPage);
504 const wchar_t kCFINoSrcPage[] = L"CFInstance_no_src_host.html";
506 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceNoSrc) {
507 SimpleBrowserTest(IE, kCFINoSrcPage);
510 const wchar_t kCFIIfrOnLoadPage[] = L"CFInstance_iframe_onload_host.html";
512 // disabled since it's unlikely that we care about this case
513 TEST_F(ChromeFrameTestWithWebServer,
514 DISABLED_WidgetModeIE_CFInstanceIfrOnLoad) {
515 SimpleBrowserTest(IE, kCFIIfrOnLoadPage);
518 const wchar_t kCFIZeroSizePage[] = L"CFInstance_zero_size_host.html";
520 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceZeroSize) {
521 SimpleBrowserTest(IE, kCFIZeroSizePage);
524 const wchar_t kCFIIfrPostPage[] = L"CFInstance_iframe_post_host.html";
526 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceIfrPost) {
527 SimpleBrowserTest(IE, kCFIIfrPostPage);
530 TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstanceIfrPost) {
531 SimpleBrowserTest(CHROME, kCFIIfrPostPage);
534 const wchar_t kCFIPostPage[] = L"CFInstance_post_host.html";
536 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstancePost) {
537 if (chrome_frame_test::GetInstalledIEVersion() == IE_9) {
538 LOG(INFO) << "Not running test on Vista/Windows 7 with IE9";
539 return;
541 SimpleBrowserTest(IE, kCFIPostPage);
544 // This test randomly fails on the ChromeFrame builder.
545 TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstancePost) {
546 SimpleBrowserTest(CHROME, kCFIPostPage);
549 const wchar_t kCFIRPCPage[] = L"CFInstance_rpc_host.html";
551 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceRPC) {
552 if (chrome_frame_test::GetInstalledIEVersion() == IE_9) {
553 LOG(INFO) << "Not running test on Vista/Windows 7 with IE9";
554 return;
556 SimpleBrowserTest(IE, kCFIRPCPage);
559 TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstanceRPC) {
560 SimpleBrowserTest(CHROME, kCFIRPCPage);
563 const wchar_t kCFIRPCInternalPage[] =
564 L"CFInstance_rpc_internal_host.html";
566 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceRPCInternal) {
567 if (chrome_frame_test::GetInstalledIEVersion() == IE_9) {
568 LOG(INFO) << "Not running test on Vista/Windows 7 with IE9";
569 return;
571 SimpleBrowserTest(IE, kCFIRPCInternalPage);
574 TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstanceRPCInternal) {
575 SimpleBrowserTest(CHROME, kCFIRPCInternalPage);
578 const wchar_t kCFIDefaultCtorPage[] =
579 L"CFInstance_default_ctor_host.html";
581 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceDefaultCtor) {
582 SimpleBrowserTest(IE, kCFIDefaultCtorPage);
585 const wchar_t kCFInstallBasicTestPage[] = L"CFInstall_basic.html";
587 TEST_F(ChromeFrameTestWithWebServer, FullTabIE_CFInstallBasic) {
588 SimpleBrowserTest(IE, kCFInstallBasicTestPage);
591 const wchar_t kCFInstallPlaceTestPage[] = L"CFInstall_place.html";
593 TEST_F(ChromeFrameTestWithWebServer, FullTabIE_CFInstallPlace) {
594 SimpleBrowserTest(IE, kCFInstallPlaceTestPage);
597 const wchar_t kCFInstallOverlayTestPage[] = L"CFInstall_overlay.html";
599 TEST_F(ChromeFrameTestWithWebServer, FullTabIE_CFInstallOverlay) {
600 SimpleBrowserTest(IE, kCFInstallOverlayTestPage);
603 const wchar_t kCFInstallDismissTestPage[] = L"CFInstall_dismiss.html";
605 TEST_F(ChromeFrameTestWithWebServer, FullTabIE_CFInstallDismiss) {
606 SimpleBrowserTest(IE, kCFInstallDismissTestPage);
609 const wchar_t kInitializeHiddenPage[] = L"initialize_hidden.html";
611 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_InitializeHidden) {
612 SimpleBrowserTest(IE, kInitializeHiddenPage);
615 const wchar_t kFullTabHttpHeaderPage[] = L"chrome_frame_http_header.html";
617 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_CFHttpHeaderBasic) {
618 SimpleBrowserTest(IE, kFullTabHttpHeaderPage);
621 const wchar_t kFullTabHttpHeaderPageIFrame[] =
622 L"chrome_frame_http_header_host.html";
624 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_CFHttpHeaderIFrame) {
625 SimpleBrowserTest(IE, kFullTabHttpHeaderPageIFrame);
628 const wchar_t kFullTabHttpHeaderPageFrameset[] =
629 L"chrome_frame_http_header_frameset.html";
631 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_CFHttpHeaderFrameSet) {
632 SimpleBrowserTest(IE, kFullTabHttpHeaderPageFrameset);
635 const wchar_t kVersionPage[] = L"version.html";
637 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_Version) {
638 VersionTest(IE, kVersionPage);
641 const wchar_t kEventListenerPage[] = L"event_listener.html";
643 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_EventListener) {
644 SimpleBrowserTest(IE, kEventListenerPage);
647 const wchar_t kPrivilegedApisPage[] = L"privileged_apis_host.html";
649 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_PrivilegedApis) {
650 SimpleBrowserTest(IE, kPrivilegedApisPage);
653 const wchar_t kMetaTagPage[] = L"meta_tag.html";
654 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_MetaTag) {
655 SimpleBrowserTest(IE, kMetaTagPage);
658 const wchar_t kCFProtocolPage[] = L"cf_protocol.html";
659 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_CFProtocol) {
660 // Temporarily enable gcf: protocol for this test.
661 SetConfigBool(kAllowUnsafeURLs, true);
662 SimpleBrowserTest(IE, kCFProtocolPage);
663 SetConfigBool(kAllowUnsafeURLs, false);
666 const wchar_t kPersistentCookieTest[] =
667 L"persistent_cookie_test_page.html";
668 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_PersistentCookieTest) {
669 SimpleBrowserTest(IE, kPersistentCookieTest);
672 const wchar_t kNavigateOutPage[] = L"navigate_out.html";
673 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_NavigateOut) {
674 SimpleBrowserTest(IE, kNavigateOutPage);
677 const wchar_t kReferrerMainTest[] = L"referrer_main.html";
679 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ReferrerTest) {
680 SimpleBrowserTest(IE, kReferrerMainTest);
683 const wchar_t kSubFrameTestPage[] = L"full_tab_sub_frame_main.html";
684 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_SubFrame) {
685 SimpleBrowserTest(IE, kSubFrameTestPage);
688 const wchar_t kSubIFrameTestPage[] = L"full_tab_sub_iframe_main.html";
689 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_SubIFrame) {
690 SimpleBrowserTest(IE, kSubIFrameTestPage);
693 const wchar_t kXMLHttpRequestTestUrl[] =
694 L"xmlhttprequest_test.html";
696 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_XHRTest) {
697 SimpleBrowserTest(IE, kXMLHttpRequestTestUrl);
700 const wchar_t kInstallFlowTestUrl[] =
701 L"install_flow_test.html";
703 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_InstallFlowTest) {
704 if (base::win::GetVersion() < base::win::VERSION_VISTA) {
705 ScopedChromeFrameRegistrar::UnregisterAtPath(
706 GetChromeFrameBuildPath().value(),
707 chrome_frame_test::GetTestBedType());
709 ASSERT_TRUE(LaunchBrowser(IE, kInstallFlowTestUrl));
711 loop().RunFor(kChromeFrameLongNavigationTimeout);
713 ScopedChromeFrameRegistrar::RegisterAtPath(
714 GetChromeFrameBuildPath().value(),
715 chrome_frame_test::GetTestBedType());
717 ExpectAndHandlePostedResult();
718 loop().RunFor(kChromeFrameLongNavigationTimeout);
720 chrome_frame_test::CloseAllIEWindows();
721 ASSERT_EQ("OK", server_mock().posted_result());
725 const wchar_t kMultipleCFInstancesTestUrl[] =
726 L"multiple_cf_instances_main.html";
728 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_MultipleCFInstances) {
729 SimpleBrowserTest(IE, kMultipleCFInstancesTestUrl);
732 const wchar_t kXHRHeaderTestUrl[] =
733 L"xmlhttprequest_header_test.html";
735 // Marking as flaky since it occasionally times out. crbug.com/127395.
736 TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_XHRHeaderTest) {
737 SimpleBrowserTest(IE, kXHRHeaderTestUrl);
740 const wchar_t kDeleteCookieTest[] =
741 L"fulltab_delete_cookie_test.html";
743 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_DeleteCookieTest) {
744 SimpleBrowserTest(IE, kDeleteCookieTest);
747 const wchar_t kAnchorUrlNavigate[] =
748 L"fulltab_anchor_url_navigate.html#chrome_frame";
750 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_AnchorUrlNavigateTest) {
751 SimpleBrowserTest(IE, kAnchorUrlNavigate);
754 // Test whether POST-ing a form from an mshtml page to a CF page will cause
755 // the request to get reissued. It should not.
756 // https://code.google.com/p/chromium/issues/detail?id=143699
757 TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_TestPostReissue) {
758 // The order of pages in this array is assumed to be mshtml, cf, script.
759 const wchar_t* kPages[] = {
760 L"full_tab_post_mshtml.html",
761 L"full_tab_post_target_cf.html",
762 L"chrome_frame_tester_helpers.js",
765 SimpleWebServerTest server(local_address_, 46664);
766 server.PopulateStaticFileListT<test_server::FileResponse>(kPages,
767 arraysize(kPages), GetCFTestFilePath());
769 ASSERT_TRUE(LaunchBrowser(IE, server.FormatHttpPath(kPages[0]).c_str()));
771 loop().RunFor(kChromeFrameLongNavigationTimeout);
773 const test_server::Request* request = NULL;
774 server.FindRequest("/quit?OK", &request);
775 ASSERT_TRUE(request != NULL);
776 EXPECT_EQ("OK", request->arguments());
778 if (request->arguments().compare("OK") == 0) {
779 // Check how many requests we got for the cf page. Also expect it to be
780 // a POST.
781 int requests = server.GetRequestCountForPage(kPages[1], "POST");
782 EXPECT_EQ(1, requests);
786 // Test whether following a link from an mshtml page to a CF page will cause
787 // multiple network requests. It should not.
788 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_TestMultipleGet) {
789 // The order of pages in this array is assumed to be mshtml, cf, script.
790 const wchar_t* kPages[] = {
791 L"full_tab_get_mshtml.html",
792 L"full_tab_get_target_cf.html",
793 L"chrome_frame_tester_helpers.js",
796 SimpleWebServerTest server(local_address_, 46664);
798 server.PopulateStaticFileListT<test_server::FileResponse>(kPages,
799 arraysize(kPages), GetCFTestFilePath());
801 ASSERT_TRUE(LaunchBrowser(IE, server.FormatHttpPath(kPages[0]).c_str()));
803 loop().RunFor(kChromeFrameVeryLongNavigationTimeout);
805 const test_server::Request* request = NULL;
806 server.FindRequest("/quit?OK", &request);
807 ASSERT_TRUE(request != NULL);
808 EXPECT_EQ("OK", request->arguments());
810 if (request->arguments().compare("OK") == 0) {
811 // Check how many requests we got for the cf page and check that it was
812 // a GET.
813 int requests = server.GetRequestCountForPage(kPages[1], "GET");
814 EXPECT_EQ(1, requests);
818 const wchar_t kSetCookieTest[] =
819 L"fulltab_set_cookie_test.html";
821 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_SetCookieTest) {
822 SimpleBrowserTest(IE, kSetCookieTest);
825 const wchar_t kXHRConditionalHeaderTestUrl[] =
826 L"xmlhttprequest_conditional_header_test.html";
828 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_XHRConditionalHeaderTest) {
829 SimpleBrowserTest(IE, kXHRConditionalHeaderTestUrl);
832 const wchar_t kWindowCloseTestUrl[] =
833 L"window_close.html";
835 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_WindowClose) {
836 SimpleBrowserTest(IE, kWindowCloseTestUrl);
839 std::string GetHeaderValue(const std::string& headers,
840 const char* header_name) {
841 net::HttpUtil::HeadersIterator it(headers.begin(), headers.end(),
842 "\r\n");
843 while (it.GetNext()) {
844 if (lstrcmpiA(it.name().c_str(), header_name) == 0) {
845 return it.values();
848 return "";
851 // Specialized implementation of test_server::FileResponse that supports
852 // adding the request's User-Agent header to the returned document.
853 // The class also supports $request_id$ which will be replaced with an
854 // id that's incremented each time the response is sent over a socket.
855 class UaTemplateFileResponse : public test_server::FileResponse {
856 public:
857 typedef test_server::FileResponse SuperClass;
859 UaTemplateFileResponse(const char* request_path, const FilePath& file_path)
860 : test_server::FileResponse(request_path, file_path), request_id_(0) {
863 virtual bool Matches(const test_server::Request& r) const {
864 bool ret = SuperClass::Matches(r);
865 if (ret)
866 ua_ = GetHeaderValue(r.headers(), "User-Agent");
867 return ret;
870 virtual size_t ContentLength() const {
871 const char kRequestIdTemplate[] = "$request_id$";
872 const char kUserAgentTemplate[] = "$UA$";
874 size_t length = SuperClass::ContentLength();
875 DCHECK(length);
876 content_.assign(reinterpret_cast<const char*>(file_->data()),
877 file_->length());
878 size_t i = content_.find(kUserAgentTemplate);
879 if (i != std::string::npos)
880 content_.replace(i, arraysize(kUserAgentTemplate) - 1, ua_);
881 i = content_.find(kRequestIdTemplate);
882 if (i != std::string::npos) {
883 content_.replace(i, arraysize(kRequestIdTemplate) - 1,
884 base::StringPrintf("%i", request_id_));
886 return content_.length();
889 virtual void WriteContents(net::StreamListenSocket* socket) const {
890 DCHECK(content_.length());
891 socket->Send(content_.c_str(), content_.length(), false);
892 request_id_++;
895 protected:
896 mutable std::string ua_;
897 mutable std::string content_;
898 mutable int request_id_;
901 // This test simulates a URL that on first request returns a document
902 // that should be rendered in mshtml, then pops up a sign-in page that
903 // after signing in, refreshes the original page that should then return
904 // a page that needs to be rendered in GCF.
906 // This test currently fails because GCF does not add the chromeframe header
907 // to requests that mshtml initiates via IInternetSession::CreateBinding.
908 TEST_F(ChromeFrameTestWithWebServer, FAILS_FullTabModeIE_RefreshMshtmlTest) {
909 const wchar_t* kPages[] = {
910 L"mshtml_refresh_test.html",
911 L"mshtml_refresh_test_popup.html",
914 SimpleWebServerTest server(local_address_, 46664);
915 server.PopulateStaticFileListT<UaTemplateFileResponse>(kPages,
916 arraysize(kPages), GetCFTestFilePath());
918 ASSERT_TRUE(LaunchBrowser(IE, server.FormatHttpPath(kPages[0]).c_str()));
920 loop().RunFor(kChromeFrameLongNavigationTimeout);
922 test_server::SimpleWebServer* ws = server.web_server();
923 const test_server::ConnectionList& connections = ws->connections();
924 test_server::ConnectionList::const_iterator it = connections.begin();
925 int requests_for_first_page = 0;
926 for (; it != connections.end(); ++it) {
927 test_server::Connection* c = (*it);
928 const test_server::Request& r = c->request();
929 if (!r.path().empty() &&
930 ASCIIToWide(r.path().substr(1)).compare(kPages[0]) == 0) {
931 requests_for_first_page++;
932 std::string ua(GetHeaderValue(r.headers(), "User-Agent"));
933 EXPECT_NE(std::string::npos, ua.find("chromeframe"));
936 EXPECT_GT(requests_for_first_page, 1);
939 // See bug 36694 for details. http://crbug.com/36694
940 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_TestDownloadFromForm) {
941 chrome_frame_test::MockWindowObserver win_observer_mock;
942 win_observer_mock.WatchWindow("File Download", "");
943 win_observer_mock.WatchWindow("View Downloads*", "");
945 // The content of our HTML test page. This will be returned whenever
946 // we reply to a GET request.
947 static const char kHtml[] =
948 "<html><head>\n"
949 "<title>ChromeFrame Form Download Test</title>\n"
950 // To see how this test runs with only IE (no CF in the picture), comment
951 // out this meta tag. The outcome of the test should be identical.
952 "<meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1\" />\n"
953 "</head>\n"
954 "<script language=\"javascript\">\n"
955 "function SubmitForm() {\n"
956 " var form = document.forms['myform'];\n"
957 " form.action = document.location;\n"
958 " form.submit();\n"
959 " return true;\n"
960 "}\n"
961 "</script>\n"
962 "<body onload=\"SubmitForm();\">\n"
963 "<form method=\"post\" action=\"foo.html\" id=\"myform\">\n"
964 " <input type=\"hidden\" name=\"Field1\" value=\"myvalue\" />\n"
965 " <input type=\"button\" name=\"btn\" value=\"Test Download\" "
966 "onclick=\"return SubmitForm();\" id=\"Button1\"/>\n"
967 "</form></body></html>\n";
969 // The content of our HTML test page. This will be returned whenever
970 // we reply to a POST request.
971 static const char kText[] =
972 "This is a text file (in case you were wondering).";
974 // This http response class will return an HTML document that contains
975 // a form whenever it receives a GET request. Whenever it gets a POST
976 // request, it will respond with a text file that needs to be downloaded
977 // (content-disposition is "attachment").
978 class CustomResponse : public test_server::ResponseForPath {
979 public:
980 explicit CustomResponse(const char* path)
981 : test_server::ResponseForPath(path), is_post_(false),
982 post_requests_(0), get_requests_(0) {
985 virtual bool GetContentType(std::string* content_type) const {
986 DCHECK(!is_post_);
987 return false;
990 virtual size_t ContentLength() const {
991 DCHECK(!is_post_);
992 return sizeof(kHtml) - 1;
995 virtual bool GetCustomHeaders(std::string* headers) const {
996 if (!is_post_)
997 return false;
998 *headers = StringPrintf(
999 "HTTP/1.1 200 OK\r\n"
1000 "Content-Disposition: attachment;filename=\"test.txt\"\r\n"
1001 "Content-Type: application/text\r\n"
1002 "Connection: close\r\n"
1003 "Content-Length: %i\r\n\r\n", sizeof(kText) - 1);
1004 return true;
1007 virtual bool Matches(const test_server::Request& r) const {
1008 bool match = __super::Matches(r);
1009 if (match) {
1010 is_post_ = LowerCaseEqualsASCII(r.method().c_str(), "post");
1012 return match;
1015 virtual void WriteContents(net::StreamListenSocket* socket) const {
1016 if (is_post_) {
1017 socket->Send(kText, sizeof(kText) - 1, false);
1018 } else {
1019 socket->Send(kHtml, sizeof(kHtml) - 1, false);
1023 virtual void IncrementAccessCounter() {
1024 __super::IncrementAccessCounter();
1025 if (is_post_) {
1026 post_requests_++;
1027 } else {
1028 get_requests_++;
1032 size_t get_request_count() const {
1033 return get_requests_;
1036 size_t post_request_count() const {
1037 return get_requests_;
1040 protected:
1041 mutable bool is_post_;
1042 size_t post_requests_;
1043 size_t get_requests_;
1046 EXPECT_CALL(win_observer_mock, OnWindowOpen(_))
1047 .Times(testing::AtMost(1))
1048 .WillOnce(chrome_frame_test::DoCloseWindow());
1050 EXPECT_CALL(win_observer_mock, OnWindowClose(_))
1051 .Times(testing::AtMost(1))
1052 .WillOnce(QUIT_LOOP(loop()));
1054 SimpleWebServerTest server(local_address_, 46664);
1055 CustomResponse* response = new CustomResponse("/form.html");
1056 server.web_server()->AddResponse(response);
1058 std::wstring url(server.FormatHttpPath(L"form.html"));
1060 ASSERT_TRUE(LaunchBrowser(IE, url.c_str()));
1061 loop().RunFor(kChromeFrameLongNavigationTimeout);
1063 EXPECT_EQ(1, response->get_request_count());
1064 EXPECT_EQ(1, response->post_request_count());