1 // Copyright 2014 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 "extensions/browser/guest_view/web_view/web_view_apitest.h"
7 #include "base/path_service.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/stringprintf.h"
10 #include "content/public/browser/render_process_host.h"
11 #include "content/public/test/browser_test_utils.h"
12 #include "content/public/test/test_utils.h"
13 #include "extensions/browser/api/test/test_api.h"
14 #include "extensions/browser/app_window/app_window.h"
15 #include "extensions/browser/app_window/app_window_registry.h"
16 #include "extensions/browser/extension_host.h"
17 #include "extensions/browser/guest_view/guest_view_manager.h"
18 #include "extensions/browser/guest_view/guest_view_manager_factory.h"
19 #include "extensions/browser/guest_view/test_guest_view_manager.h"
20 #include "extensions/browser/process_manager.h"
21 #include "extensions/common/extension.h"
22 #include "extensions/common/extension_paths.h"
23 #include "extensions/shell/browser/shell_content_browser_client.h"
24 #include "extensions/shell/browser/shell_extension_system.h"
25 #include "extensions/shell/test/shell_test.h"
26 #include "extensions/test/extension_test_message_listener.h"
27 #include "net/base/filename_util.h"
28 #include "net/test/embedded_test_server/embedded_test_server.h"
29 #include "net/test/embedded_test_server/http_request.h"
30 #include "net/test/embedded_test_server/http_response.h"
34 const char kEmptyResponsePath
[] = "/close-socket";
35 const char kRedirectResponsePath
[] = "/server-redirect";
36 const char kRedirectResponseFullPath
[] = "/guest_redirect.html";
37 const char kTestDataDirectory
[] = "testDataDirectory";
38 const char kTestServerPort
[] = "testServer.port";
39 const char kTestWebSocketPort
[] = "testWebSocketPort";
41 class EmptyHttpResponse
: public net::test_server::HttpResponse
{
43 virtual std::string
ToResponseString() const override
{
48 // Handles |request| by serving a redirect response.
49 scoped_ptr
<net::test_server::HttpResponse
> RedirectResponseHandler(
50 const std::string
& path
,
51 const GURL
& redirect_target
,
52 const net::test_server::HttpRequest
& request
) {
53 if (!StartsWithASCII(path
, request
.relative_url
, true))
54 return scoped_ptr
<net::test_server::HttpResponse
>();
56 scoped_ptr
<net::test_server::BasicHttpResponse
> http_response(
57 new net::test_server::BasicHttpResponse
);
58 http_response
->set_code(net::HTTP_MOVED_PERMANENTLY
);
59 http_response
->AddCustomHeader("Location", redirect_target
.spec());
60 return http_response
.PassAs
<net::test_server::HttpResponse
>();
63 // Handles |request| by serving an empty response.
64 scoped_ptr
<net::test_server::HttpResponse
> EmptyResponseHandler(
65 const std::string
& path
,
66 const net::test_server::HttpRequest
& request
) {
67 if (StartsWithASCII(path
, request
.relative_url
, true)) {
68 return scoped_ptr
<net::test_server::HttpResponse
>(new EmptyHttpResponse
);
71 return scoped_ptr
<net::test_server::HttpResponse
>();
76 namespace extensions
{
78 WebViewAPITest::WebViewAPITest() {
79 GuestViewManager::set_factory_for_testing(&factory_
);
82 void WebViewAPITest::LaunchApp(const std::string
& app_location
) {
83 base::FilePath test_data_dir
;
84 PathService::Get(DIR_TEST_DATA
, &test_data_dir
);
85 test_data_dir
= test_data_dir
.AppendASCII(app_location
.c_str());
87 test_config_
.SetString(kTestDataDirectory
,
88 net::FilePathToFileURL(test_data_dir
).spec());
90 embedded_test_server()->ServeFilesFromDirectory(test_data_dir
);
92 ASSERT_TRUE(extension_system_
->LoadApp(test_data_dir
));
93 extension_system_
->LaunchApp();
95 ExtensionTestMessageListener
launch_listener("LAUNCHED", false);
96 ASSERT_TRUE(launch_listener
.WaitUntilSatisfied());
98 const AppWindowRegistry::AppWindowList
& app_window_list
=
99 AppWindowRegistry::Get(browser_context_
)->app_windows();
100 DCHECK(app_window_list
.size() == 1);
101 embedder_web_contents_
= (*app_window_list
.begin())->web_contents();
104 void WebViewAPITest::RunTest(const std::string
& test_name
,
105 const std::string
& app_location
) {
106 LaunchApp(app_location
);
108 ExtensionTestMessageListener
done_listener("TEST_PASSED", false);
109 done_listener
.set_failure_message("TEST_FAILED");
110 if (!content::ExecuteScript(
111 embedder_web_contents_
,
112 base::StringPrintf("runTest('%s')", test_name
.c_str()))) {
113 LOG(ERROR
) << "Unable to start test.";
116 ASSERT_TRUE(done_listener
.WaitUntilSatisfied());
119 void WebViewAPITest::RunTestOnMainThreadLoop() {
120 AppShellTest::RunTestOnMainThreadLoop();
121 GetGuestViewManager()->WaitForAllGuestsDeleted();
124 void WebViewAPITest::SetUpOnMainThread() {
125 AppShellTest::SetUpOnMainThread();
127 TestGetConfigFunction::set_test_config_state(&test_config_
);
128 base::FilePath test_data_dir
;
129 test_config_
.SetInteger(kTestWebSocketPort
, 0);
132 void WebViewAPITest::StartTestServer() {
133 // For serving guest pages.
134 if (!embedded_test_server()->InitializeAndWaitUntilReady()) {
135 LOG(ERROR
) << "Failed to start test server.";
139 test_config_
.SetInteger(kTestServerPort
, embedded_test_server()->port());
141 embedded_test_server()->RegisterRequestHandler(
142 base::Bind(&RedirectResponseHandler
,
143 kRedirectResponsePath
,
144 embedded_test_server()->GetURL(kRedirectResponseFullPath
)));
146 embedded_test_server()->RegisterRequestHandler(
147 base::Bind(&EmptyResponseHandler
, kEmptyResponsePath
));
150 void WebViewAPITest::StopTestServer() {
151 if (!embedded_test_server()->ShutdownAndWaitUntilComplete()) {
152 LOG(ERROR
) << "Failed to shutdown test server.";
156 void WebViewAPITest::TearDownOnMainThread() {
157 TestGetConfigFunction::set_test_config_state(nullptr);
159 AppShellTest::TearDownOnMainThread();
162 TestGuestViewManager
* WebViewAPITest::GetGuestViewManager() {
163 return static_cast<TestGuestViewManager
*>(
164 TestGuestViewManager::FromBrowserContext(
165 ShellContentBrowserClient::Get()->GetBrowserContext()));
168 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestAllowTransparencyAttribute
) {
169 RunTest("testAllowTransparencyAttribute", "web_view/apitest");
172 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestAPIMethodExistence
) {
173 RunTest("testAPIMethodExistence", "web_view/apitest");
176 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestAssignSrcAfterCrash
) {
177 RunTest("testAssignSrcAfterCrash", "web_view/apitest");
180 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestAutosizeAfterNavigation
) {
181 RunTest("testAutosizeAfterNavigation", "web_view/apitest");
184 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestAutosizeBeforeNavigation
) {
185 RunTest("testAutosizeBeforeNavigation", "web_view/apitest");
188 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestAutosizeHeight
) {
189 RunTest("testAutosizeHeight", "web_view/apitest");
192 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestAutosizeRemoveAttributes
) {
193 RunTest("testAutosizeRemoveAttributes", "web_view/apitest");
196 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestAutosizeWithPartialAttributes
) {
197 RunTest("testAutosizeWithPartialAttributes", "web_view/apitest");
200 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestCannotMutateEventName
) {
201 RunTest("testCannotMutateEventName", "web_view/apitest");
204 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestChromeExtensionRelativePath
) {
205 RunTest("testChromeExtensionRelativePath", "web_view/apitest");
208 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestChromeExtensionURL
) {
209 RunTest("testChromeExtensionURL", "web_view/apitest");
212 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestContentLoadEvent
) {
213 RunTest("testContentLoadEvent", "web_view/apitest");
216 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestDeclarativeWebRequestAPI
) {
218 RunTest("testDeclarativeWebRequestAPI", "web_view/apitest");
222 IN_PROC_BROWSER_TEST_F(WebViewAPITest
,
223 TestDeclarativeWebRequestAPISendMessage
) {
225 RunTest("testDeclarativeWebRequestAPISendMessage", "web_view/apitest");
229 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestDestroyOnEventListener
) {
230 RunTest("testDestroyOnEventListener", "web_view/apitest");
233 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestDisplayNoneWebviewLoad
) {
234 RunTest("testDisplayNoneWebviewLoad", "web_view/apitest");
237 // TODO(lfg): Re-enable this test once the fix for webview leaking
238 // RenderProcessHost has landed. See http://crbug.com/419020 .
239 IN_PROC_BROWSER_TEST_F(WebViewAPITest
,
240 DISABLED_TestDisplayNoneWebviewRemoveChild
) {
241 RunTest("testDisplayNoneWebviewRemoveChild", "web_view/apitest");
244 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestEventName
) {
245 RunTest("testEventName", "web_view/apitest");
248 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestExecuteScript
) {
249 RunTest("testExecuteScript", "web_view/apitest");
252 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestExecuteScriptFail
) {
253 RunTest("testExecuteScriptFail", "web_view/apitest");
256 IN_PROC_BROWSER_TEST_F(WebViewAPITest
,
257 TestExecuteScriptIsAbortedWhenWebViewSourceIsChanged
) {
258 RunTest("testExecuteScriptIsAbortedWhenWebViewSourceIsChanged",
262 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestFindAPI
) {
263 RunTest("testFindAPI", "web_view/apitest");
266 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestFindAPI_findupdate
) {
267 RunTest("testFindAPI_findupdate", "web_view/apitest");
270 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestGetProcessId
) {
271 RunTest("testGetProcessId", "web_view/apitest");
274 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestHiddenBeforeNavigation
) {
275 RunTest("testHiddenBeforeNavigation", "web_view/apitest");
278 IN_PROC_BROWSER_TEST_F(WebViewAPITest
,
279 TestInlineScriptFromAccessibleResources
) {
280 RunTest("testInlineScriptFromAccessibleResources", "web_view/apitest");
283 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestInvalidChromeExtensionURL
) {
284 RunTest("testInvalidChromeExtensionURL", "web_view/apitest");
287 IN_PROC_BROWSER_TEST_F(WebViewAPITest
,
288 TestLoadAbortChromeExtensionURLWrongPartition
) {
289 RunTest("testLoadAbortChromeExtensionURLWrongPartition", "web_view/apitest");
292 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestLoadAbortEmptyResponse
) {
294 RunTest("testLoadAbortEmptyResponse", "web_view/apitest");
298 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestLoadAbortIllegalChromeURL
) {
299 RunTest("testLoadAbortIllegalChromeURL", "web_view/apitest");
302 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestLoadAbortIllegalFileURL
) {
303 RunTest("testLoadAbortIllegalFileURL", "web_view/apitest");
306 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestLoadAbortIllegalJavaScriptURL
) {
307 RunTest("testLoadAbortIllegalJavaScriptURL", "web_view/apitest");
310 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestLoadAbortInvalidNavigation
) {
311 RunTest("testLoadAbortInvalidNavigation", "web_view/apitest");
314 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestLoadAbortNonWebSafeScheme
) {
315 RunTest("testLoadAbortNonWebSafeScheme", "web_view/apitest");
318 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestLoadProgressEvent
) {
319 RunTest("testLoadProgressEvent", "web_view/apitest");
322 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestLoadStartLoadRedirect
) {
324 RunTest("testLoadStartLoadRedirect", "web_view/apitest");
328 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestNavigateAfterResize
) {
329 RunTest("testNavigateAfterResize", "web_view/apitest");
332 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestNavigationToExternalProtocol
) {
333 RunTest("testNavigationToExternalProtocol", "web_view/apitest");
336 IN_PROC_BROWSER_TEST_F(WebViewAPITest
,
337 TestNavOnConsecutiveSrcAttributeChanges
) {
338 RunTest("testNavOnConsecutiveSrcAttributeChanges", "web_view/apitest");
341 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestNavOnSrcAttributeChange
) {
342 RunTest("testNavOnSrcAttributeChange", "web_view/apitest");
345 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestNewWindow
) {
347 RunTest("testNewWindow", "web_view/apitest");
351 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestNewWindowNoPreventDefault
) {
353 RunTest("testNewWindowNoPreventDefault", "web_view/apitest");
357 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestNewWindowNoReferrerLink
) {
359 RunTest("testNewWindowNoReferrerLink", "web_view/apitest");
363 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestNewWindowTwoListeners
) {
365 RunTest("testNewWindowTwoListeners", "web_view/apitest");
369 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestOnEventProperty
) {
370 RunTest("testOnEventProperties", "web_view/apitest");
373 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestPartitionRaisesException
) {
374 RunTest("testPartitionRaisesException", "web_view/apitest");
377 IN_PROC_BROWSER_TEST_F(WebViewAPITest
,
378 TestPartitionRemovalAfterNavigationFails
) {
379 RunTest("testPartitionRemovalAfterNavigationFails", "web_view/apitest");
382 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestReassignSrcAttribute
) {
383 RunTest("testReassignSrcAttribute", "web_view/apitest");
386 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestRemoveWebviewOnExit
) {
389 // Launch the app and wait until it's ready to load a test.
390 LaunchApp("web_view/apitest");
392 GURL::Replacements replace_host
;
393 std::string
host_str("localhost"); // Must stay in scope with replace_host.
394 replace_host
.SetHostStr(host_str
);
396 // Run the test and wait until the guest WebContents is available and has
398 ExtensionTestMessageListener
guest_loaded_listener("guest-loaded", false);
399 EXPECT_TRUE(content::ExecuteScript(embedder_web_contents_
,
400 "runTest('testRemoveWebviewOnExit')"));
402 content::WebContents
* guest_web_contents
=
403 GetGuestViewManager()->WaitForSingleGuestCreated();
404 EXPECT_TRUE(guest_web_contents
->GetRenderProcessHost()->IsIsolatedGuest());
405 ASSERT_TRUE(guest_loaded_listener
.WaitUntilSatisfied());
407 content::WebContentsDestroyedWatcher
destroyed_watcher(guest_web_contents
);
409 // Tell the embedder to kill the guest.
410 EXPECT_TRUE(content::ExecuteScript(embedder_web_contents_
,
411 "removeWebviewOnExitDoCrash()"));
413 // Wait until the guest WebContents is destroyed.
414 destroyed_watcher
.Wait();
418 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestReload
) {
419 RunTest("testReload", "web_view/apitest");
422 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestReloadAfterTerminate
) {
423 RunTest("testReloadAfterTerminate", "web_view/apitest");
426 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestRemoveSrcAttribute
) {
427 RunTest("testRemoveSrcAttribute", "web_view/apitest");
430 // TODO(lfg): Re-enable this test once the fix for webview leaking
431 // RenderProcessHost has landed. See http://crbug.com/419020 .
432 IN_PROC_BROWSER_TEST_F(WebViewAPITest
,
433 DISABLED_TestRemoveWebviewAfterNavigation
) {
434 RunTest("testRemoveWebviewAfterNavigation", "web_view/apitest");
437 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestResizeWebviewResizesContent
) {
438 RunTest("testResizeWebviewResizesContent", "web_view/apitest");
441 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestTerminateAfterExit
) {
442 RunTest("testTerminateAfterExit", "web_view/apitest");
445 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestWebRequestAPI
) {
447 RunTest("testWebRequestAPI", "web_view/apitest");
451 // Tests the existence of WebRequest API event objects on the request
452 // object, on the webview element, and hanging directly off webview.
453 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestWebRequestAPIExistence
) {
455 RunTest("testWebRequestAPIExistence", "web_view/apitest");
459 IN_PROC_BROWSER_TEST_F(WebViewAPITest
, TestWebRequestAPIGoogleProperty
) {
461 RunTest("testWebRequestAPIGoogleProperty", "web_view/apitest");
465 } // namespace extensions