1// Copyright 2013 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.
4
5#include "apps/ui/native_app_window.h"
6#include "base/path_service.h"
7#include "base/strings/stringprintf.h"
8#include "base/strings/utf_string_conversions.h"
9#include "chrome/browser/apps/app_browsertest_util.h"
10#include "chrome/browser/automation/automation_util.h"
11#include "chrome/browser/chrome_content_browser_client.h"
12#include "chrome/browser/extensions/extension_test_message_listener.h"
13#include "chrome/browser/prerender/prerender_link_manager.h"
14#include "chrome/browser/prerender/prerender_link_manager_factory.h"
15#include "chrome/browser/profiles/profile.h"
16#include "chrome/browser/ui/browser.h"
17#include "chrome/browser/ui/tabs/tab_strip_model.h"
18#include "chrome/test/base/ui_test_utils.h"
19#include "content/public/browser/gpu_data_manager.h"
20#include "content/public/browser/interstitial_page.h"
21#include "content/public/browser/interstitial_page_delegate.h"
22#include "content/public/browser/notification_service.h"
23#include "content/public/browser/render_process_host.h"
24#include "content/public/browser/web_contents_delegate.h"
25#include "content/public/common/content_switches.h"
26#include "content/public/test/browser_test_utils.h"
27#include "content/public/test/fake_speech_recognition_manager.h"
28#include "extensions/common/extension.h"
29#include "extensions/common/extensions_client.h"
30#include "net/test/embedded_test_server/embedded_test_server.h"
31#include "net/test/embedded_test_server/http_request.h"
32#include "net/test/embedded_test_server/http_response.h"
33#include "ui/gl/gl_switches.h"
34
35// For fine-grained suppression on flaky tests.
36#if defined(OS_WIN)
37#include "base/win/windows_version.h"
38#endif
39
40using prerender::PrerenderLinkManager;
41using prerender::PrerenderLinkManagerFactory;
42
43namespace {
44const char kEmptyResponsePath[] = "/close-socket";
45const char kRedirectResponsePath[] = "/server-redirect";
46const char kRedirectResponseFullPath[] =
47    "/extensions/platform_apps/web_view/shim/guest_redirect.html";
48
49// Platform-specific filename relative to the chrome executable.
50#if defined(OS_WIN)
51const wchar_t library_name[] = L"ppapi_tests.dll";
52#elif defined(OS_MACOSX)
53const char library_name[] = "ppapi_tests.plugin";
54#elif defined(OS_POSIX)
55const char library_name[] = "libppapi_tests.so";
56#endif
57
58class EmptyHttpResponse : public net::test_server::HttpResponse {
59 public:
60  virtual std::string ToResponseString() const OVERRIDE {
61    return std::string();
62  }
63};
64
65class TestInterstitialPageDelegate : public content::InterstitialPageDelegate {
66 public:
67  TestInterstitialPageDelegate() {
68  }
69  virtual ~TestInterstitialPageDelegate() {}
70  virtual std::string GetHTMLContents() OVERRIDE { return std::string(); }
71};
72
73// Used to get notified when a guest is created.
74class GuestContentBrowserClient : public chrome::ChromeContentBrowserClient {
75 public:
76  GuestContentBrowserClient() : web_contents_(NULL) {}
77
78  content::WebContents* WaitForGuestCreated() {
79    if (web_contents_)
80      return web_contents_;
81
82    message_loop_runner_ = new content::MessageLoopRunner;
83    message_loop_runner_->Run();
84    return web_contents_;
85  }
86
87 private:
88  // ChromeContentBrowserClient implementation:
89  virtual void GuestWebContentsAttached(
90      content::WebContents* guest_web_contents,
91      content::WebContents* embedder_web_contents,
92      const base::DictionaryValue& extra_params) OVERRIDE {
93    ChromeContentBrowserClient::GuestWebContentsAttached(
94        guest_web_contents, embedder_web_contents, extra_params);
95    web_contents_ = guest_web_contents;
96
97    if (message_loop_runner_)
98      message_loop_runner_->Quit();
99  }
100
101  content::WebContents* web_contents_;
102  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
103};
104
105class InterstitialObserver : public content::WebContentsObserver {
106 public:
107  InterstitialObserver(content::WebContents* web_contents,
108                       const base::Closure& attach_callback,
109                       const base::Closure& detach_callback)
110      : WebContentsObserver(web_contents),
111        attach_callback_(attach_callback),
112        detach_callback_(detach_callback) {
113  }
114
115  virtual void DidAttachInterstitialPage() OVERRIDE {
116    attach_callback_.Run();
117  }
118
119  virtual void DidDetachInterstitialPage() OVERRIDE {
120    detach_callback_.Run();
121  }
122
123 private:
124  base::Closure attach_callback_;
125  base::Closure detach_callback_;
126
127  DISALLOW_COPY_AND_ASSIGN(InterstitialObserver);
128};
129
130}  // namespace
131
132// This class intercepts media access request from the embedder. The request
133// should be triggered only if the embedder API (from tests) allows the request
134// in Javascript.
135// We do not issue the actual media request; the fact that the request reached
136// embedder's WebContents is good enough for our tests. This is also to make
137// the test run successfully on trybots.
138class MockWebContentsDelegate : public content::WebContentsDelegate {
139 public:
140  MockWebContentsDelegate() : requested_(false) {}
141  virtual ~MockWebContentsDelegate() {}
142
143  virtual void RequestMediaAccessPermission(
144      content::WebContents* web_contents,
145      const content::MediaStreamRequest& request,
146      const content::MediaResponseCallback& callback) OVERRIDE {
147    requested_ = true;
148    if (message_loop_runner_.get())
149      message_loop_runner_->Quit();
150  }
151
152  void WaitForSetMediaPermission() {
153    if (requested_)
154      return;
155    message_loop_runner_ = new content::MessageLoopRunner;
156    message_loop_runner_->Run();
157  }
158
159 private:
160  bool requested_;
161  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
162
163  DISALLOW_COPY_AND_ASSIGN(MockWebContentsDelegate);
164};
165
166// This class intercepts download request from the guest.
167class MockDownloadWebContentsDelegate : public content::WebContentsDelegate {
168 public:
169  explicit MockDownloadWebContentsDelegate(
170      content::WebContentsDelegate* orig_delegate)
171      : orig_delegate_(orig_delegate),
172        waiting_for_decision_(false),
173        expect_allow_(false),
174        decision_made_(false),
175        last_download_allowed_(false) {}
176  virtual ~MockDownloadWebContentsDelegate() {}
177
178  virtual void CanDownload(
179      content::RenderViewHost* render_view_host,
180      int request_id,
181      const std::string& request_method,
182      const base::Callback<void(bool)>& callback) OVERRIDE {
183    orig_delegate_->CanDownload(
184        render_view_host, request_id, request_method,
185        base::Bind(&MockDownloadWebContentsDelegate::DownloadDecided,
186                   base::Unretained(this)));
187  }
188
189  void WaitForCanDownload(bool expect_allow) {
190    EXPECT_FALSE(waiting_for_decision_);
191    waiting_for_decision_ = true;
192
193    if (decision_made_) {
194      EXPECT_EQ(expect_allow, last_download_allowed_);
195      return;
196    }
197
198    expect_allow_ = expect_allow;
199    message_loop_runner_ = new content::MessageLoopRunner;
200    message_loop_runner_->Run();
201  }
202
203  void DownloadDecided(bool allow) {
204    EXPECT_FALSE(decision_made_);
205    decision_made_ = true;
206
207    if (waiting_for_decision_) {
208      EXPECT_EQ(expect_allow_, allow);
209      if (message_loop_runner_.get())
210        message_loop_runner_->Quit();
211      return;
212    }
213    last_download_allowed_ = allow;
214  }
215
216  void Reset() {
217    waiting_for_decision_ = false;
218    decision_made_ = false;
219  }
220
221 private:
222  content::WebContentsDelegate* orig_delegate_;
223  bool waiting_for_decision_;
224  bool expect_allow_;
225  bool decision_made_;
226  bool last_download_allowed_;
227  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
228
229  DISALLOW_COPY_AND_ASSIGN(MockDownloadWebContentsDelegate);
230};
231
232class WebViewTest : public extensions::PlatformAppBrowserTest {
233 protected:
234  virtual void SetUp() OVERRIDE {
235    if (UsesFakeSpeech()) {
236      // SpeechRecognition test specific SetUp.
237      fake_speech_recognition_manager_.reset(
238          new content::FakeSpeechRecognitionManager());
239      fake_speech_recognition_manager_->set_should_send_fake_response(true);
240      // Inject the fake manager factory so that the test result is returned to
241      // the web page.
242      content::SpeechRecognitionManager::SetManagerForTesting(
243          fake_speech_recognition_manager_.get());
244    }
245
246    // We need real contexts, otherwise the embedder doesn't composite, but the
247    // guest does, and that isn't an expected configuration.
248    UseRealGLContexts();
249    extensions::PlatformAppBrowserTest::SetUp();
250  }
251
252  virtual void TearDown() OVERRIDE {
253    if (UsesFakeSpeech()) {
254      // SpeechRecognition test specific TearDown.
255      content::SpeechRecognitionManager::SetManagerForTesting(NULL);
256    }
257
258    extensions::PlatformAppBrowserTest::TearDown();
259  }
260
261  virtual void SetUpOnMainThread() OVERRIDE {
262    const testing::TestInfo* const test_info =
263        testing::UnitTest::GetInstance()->current_test_info();
264    // Mock out geolocation for geolocation specific tests.
265    if (!strncmp(test_info->name(), "GeolocationAPI",
266            strlen("GeolocationAPI"))) {
267      ui_test_utils::OverrideGeolocation(10, 20);
268    }
269  }
270
271  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
272    const testing::TestInfo* const test_info =
273        testing::UnitTest::GetInstance()->current_test_info();
274
275    command_line->AppendSwitchASCII(switches::kJavaScriptFlags, "--expose-gc");
276
277    // Force SW rendering to check autosize bug.
278    if (!strncmp(test_info->name(), "AutoSizeSW", strlen("AutosizeSW")))
279      command_line->AppendSwitch(switches::kDisableForceCompositingMode);
280
281    extensions::PlatformAppBrowserTest::SetUpCommandLine(command_line);
282  }
283
284  // This method is responsible for initializing a packaged app, which contains
285  // multiple webview tags. The tags have different partition identifiers and
286  // their WebContent objects are returned as output. The method also verifies
287  // the expected process allocation and storage partition assignment.
288  // The |navigate_to_url| parameter is used to navigate the main browser
289  // window.
290  //
291  // TODO(ajwong): This function is getting to be too large. Either refactor it
292  // so the test can specify a configuration of WebView tags that we will
293  // dynamically inject JS to generate, or move this test wholesale into
294  // something that RunPlatformAppTest() can execute purely in Javascript. This
295  // won't let us do a white-box examination of the StoragePartition equivalence
296  // directly, but we will be able to view the black box effects which is good
297  // enough.  http://crbug.com/160361
298  void NavigateAndOpenAppForIsolation(
299      GURL navigate_to_url,
300      content::WebContents** default_tag_contents1,
301      content::WebContents** default_tag_contents2,
302      content::WebContents** named_partition_contents1,
303      content::WebContents** named_partition_contents2,
304      content::WebContents** persistent_partition_contents1,
305      content::WebContents** persistent_partition_contents2,
306      content::WebContents** persistent_partition_contents3) {
307    GURL::Replacements replace_host;
308    std::string host_str("localhost");  // Must stay in scope with replace_host.
309    replace_host.SetHostStr(host_str);
310
311    navigate_to_url = navigate_to_url.ReplaceComponents(replace_host);
312
313    GURL tag_url1 = embedded_test_server()->GetURL(
314        "/extensions/platform_apps/web_view/isolation/cookie.html");
315    tag_url1 = tag_url1.ReplaceComponents(replace_host);
316    GURL tag_url2 = embedded_test_server()->GetURL(
317        "/extensions/platform_apps/web_view/isolation/cookie2.html");
318    tag_url2 = tag_url2.ReplaceComponents(replace_host);
319    GURL tag_url3 = embedded_test_server()->GetURL(
320        "/extensions/platform_apps/web_view/isolation/storage1.html");
321    tag_url3 = tag_url3.ReplaceComponents(replace_host);
322    GURL tag_url4 = embedded_test_server()->GetURL(
323        "/extensions/platform_apps/web_view/isolation/storage2.html");
324    tag_url4 = tag_url4.ReplaceComponents(replace_host);
325    GURL tag_url5 = embedded_test_server()->GetURL(
326        "/extensions/platform_apps/web_view/isolation/storage1.html#p1");
327    tag_url5 = tag_url5.ReplaceComponents(replace_host);
328    GURL tag_url6 = embedded_test_server()->GetURL(
329        "/extensions/platform_apps/web_view/isolation/storage1.html#p2");
330    tag_url6 = tag_url6.ReplaceComponents(replace_host);
331    GURL tag_url7 = embedded_test_server()->GetURL(
332        "/extensions/platform_apps/web_view/isolation/storage1.html#p3");
333    tag_url7 = tag_url7.ReplaceComponents(replace_host);
334
335    ui_test_utils::NavigateToURLWithDisposition(
336        browser(), navigate_to_url, CURRENT_TAB,
337        ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
338
339    ui_test_utils::UrlLoadObserver observer1(
340        tag_url1, content::NotificationService::AllSources());
341    ui_test_utils::UrlLoadObserver observer2(
342        tag_url2, content::NotificationService::AllSources());
343    ui_test_utils::UrlLoadObserver observer3(
344        tag_url3, content::NotificationService::AllSources());
345    ui_test_utils::UrlLoadObserver observer4(
346        tag_url4, content::NotificationService::AllSources());
347    ui_test_utils::UrlLoadObserver observer5(
348        tag_url5, content::NotificationService::AllSources());
349    ui_test_utils::UrlLoadObserver observer6(
350        tag_url6, content::NotificationService::AllSources());
351    ui_test_utils::UrlLoadObserver observer7(
352        tag_url7, content::NotificationService::AllSources());
353    LoadAndLaunchPlatformApp("web_view/isolation");
354    observer1.Wait();
355    observer2.Wait();
356    observer3.Wait();
357    observer4.Wait();
358    observer5.Wait();
359    observer6.Wait();
360    observer7.Wait();
361
362    content::Source<content::NavigationController> source1 = observer1.source();
363    EXPECT_TRUE(source1->GetWebContents()->GetRenderProcessHost()->IsGuest());
364    content::Source<content::NavigationController> source2 = observer2.source();
365    EXPECT_TRUE(source2->GetWebContents()->GetRenderProcessHost()->IsGuest());
366    content::Source<content::NavigationController> source3 = observer3.source();
367    EXPECT_TRUE(source3->GetWebContents()->GetRenderProcessHost()->IsGuest());
368    content::Source<content::NavigationController> source4 = observer4.source();
369    EXPECT_TRUE(source4->GetWebContents()->GetRenderProcessHost()->IsGuest());
370    content::Source<content::NavigationController> source5 = observer5.source();
371    EXPECT_TRUE(source5->GetWebContents()->GetRenderProcessHost()->IsGuest());
372    content::Source<content::NavigationController> source6 = observer6.source();
373    EXPECT_TRUE(source6->GetWebContents()->GetRenderProcessHost()->IsGuest());
374    content::Source<content::NavigationController> source7 = observer7.source();
375    EXPECT_TRUE(source7->GetWebContents()->GetRenderProcessHost()->IsGuest());
376
377    // Check that the first two tags use the same process and it is different
378    // than the process used by the other two.
379    EXPECT_EQ(source1->GetWebContents()->GetRenderProcessHost()->GetID(),
380              source2->GetWebContents()->GetRenderProcessHost()->GetID());
381    EXPECT_EQ(source3->GetWebContents()->GetRenderProcessHost()->GetID(),
382              source4->GetWebContents()->GetRenderProcessHost()->GetID());
383    EXPECT_NE(source1->GetWebContents()->GetRenderProcessHost()->GetID(),
384              source3->GetWebContents()->GetRenderProcessHost()->GetID());
385
386    // The two sets of tags should also be isolated from the main browser.
387    EXPECT_NE(source1->GetWebContents()->GetRenderProcessHost()->GetID(),
388              browser()->tab_strip_model()->GetWebContentsAt(0)->
389                  GetRenderProcessHost()->GetID());
390    EXPECT_NE(source3->GetWebContents()->GetRenderProcessHost()->GetID(),
391              browser()->tab_strip_model()->GetWebContentsAt(0)->
392                  GetRenderProcessHost()->GetID());
393
394    // Check that the storage partitions of the first two tags match and are
395    // different than the other two.
396    EXPECT_EQ(
397        source1->GetWebContents()->GetRenderProcessHost()->
398            GetStoragePartition(),
399        source2->GetWebContents()->GetRenderProcessHost()->
400            GetStoragePartition());
401    EXPECT_EQ(
402        source3->GetWebContents()->GetRenderProcessHost()->
403            GetStoragePartition(),
404        source4->GetWebContents()->GetRenderProcessHost()->
405            GetStoragePartition());
406    EXPECT_NE(
407        source1->GetWebContents()->GetRenderProcessHost()->
408            GetStoragePartition(),
409        source3->GetWebContents()->GetRenderProcessHost()->
410            GetStoragePartition());
411
412    // Ensure the persistent storage partitions are different.
413    EXPECT_EQ(
414        source5->GetWebContents()->GetRenderProcessHost()->
415            GetStoragePartition(),
416        source6->GetWebContents()->GetRenderProcessHost()->
417            GetStoragePartition());
418    EXPECT_NE(
419        source5->GetWebContents()->GetRenderProcessHost()->
420            GetStoragePartition(),
421        source7->GetWebContents()->GetRenderProcessHost()->
422            GetStoragePartition());
423    EXPECT_NE(
424        source1->GetWebContents()->GetRenderProcessHost()->
425            GetStoragePartition(),
426        source5->GetWebContents()->GetRenderProcessHost()->
427            GetStoragePartition());
428    EXPECT_NE(
429        source1->GetWebContents()->GetRenderProcessHost()->
430            GetStoragePartition(),
431        source7->GetWebContents()->GetRenderProcessHost()->
432            GetStoragePartition());
433
434    *default_tag_contents1 = source1->GetWebContents();
435    *default_tag_contents2 = source2->GetWebContents();
436    *named_partition_contents1 = source3->GetWebContents();
437    *named_partition_contents2 = source4->GetWebContents();
438    if (persistent_partition_contents1) {
439      *persistent_partition_contents1 = source5->GetWebContents();
440    }
441    if (persistent_partition_contents2) {
442      *persistent_partition_contents2 = source6->GetWebContents();
443    }
444    if (persistent_partition_contents3) {
445      *persistent_partition_contents3 = source7->GetWebContents();
446    }
447  }
448
449  void ExecuteScriptWaitForTitle(content::WebContents* web_contents,
450                                 const char* script,
451                                 const char* title) {
452    base::string16 expected_title(ASCIIToUTF16(title));
453    base::string16 error_title(ASCIIToUTF16("error"));
454
455    content::TitleWatcher title_watcher(web_contents, expected_title);
456    title_watcher.AlsoWaitForTitle(error_title);
457    EXPECT_TRUE(content::ExecuteScript(web_contents, script));
458    EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
459  }
460
461  // Handles |request| by serving a redirect response.
462  static scoped_ptr<net::test_server::HttpResponse> RedirectResponseHandler(
463      const std::string& path,
464      const GURL& redirect_target,
465      const net::test_server::HttpRequest& request) {
466    if (!StartsWithASCII(path, request.relative_url, true))
467      return scoped_ptr<net::test_server::HttpResponse>();
468
469    scoped_ptr<net::test_server::BasicHttpResponse> http_response(
470        new net::test_server::BasicHttpResponse);
471    http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
472    http_response->AddCustomHeader("Location", redirect_target.spec());
473    return http_response.PassAs<net::test_server::HttpResponse>();
474  }
475
476  // Handles |request| by serving an empty response.
477  static scoped_ptr<net::test_server::HttpResponse> EmptyResponseHandler(
478      const std::string& path,
479      const net::test_server::HttpRequest& request) {
480    if (StartsWithASCII(path, request.relative_url, true)) {
481      return scoped_ptr<net::test_server::HttpResponse>(
482          new EmptyHttpResponse);
483    }
484
485    return scoped_ptr<net::test_server::HttpResponse>();
486  }
487
488  enum TestServer {
489    NEEDS_TEST_SERVER,
490    NO_TEST_SERVER
491  };
492
493  void TestHelper(const std::string& test_name,
494                  const std::string& app_location,
495                  TestServer test_server) {
496    // For serving guest pages.
497    if (test_server == NEEDS_TEST_SERVER) {
498      if (!StartEmbeddedTestServer()) {
499        LOG(ERROR) << "FAILED TO START TEST SERVER.";
500        return;
501      }
502      embedded_test_server()->RegisterRequestHandler(
503          base::Bind(&WebViewTest::RedirectResponseHandler,
504                    kRedirectResponsePath,
505                    embedded_test_server()->GetURL(kRedirectResponseFullPath)));
506
507      embedded_test_server()->RegisterRequestHandler(
508          base::Bind(&WebViewTest::EmptyResponseHandler, kEmptyResponsePath));
509    }
510
511    ExtensionTestMessageListener launched_listener("Launched", false);
512    LoadAndLaunchPlatformApp(app_location.c_str());
513    if (!launched_listener.WaitUntilSatisfied()) {
514      LOG(ERROR) << "TEST DID NOT LAUNCH.";
515      return;
516    }
517
518    // Flush any pending events to make sure we start with a clean slate.
519    content::RunAllPendingInMessageLoop();
520
521    content::WebContents* embedder_web_contents =
522        GetFirstShellWindowWebContents();
523    if (!embedder_web_contents) {
524      LOG(ERROR) << "UNABLE TO FIND EMBEDDER WEB CONTENTS.";
525      return;
526    }
527
528    ExtensionTestMessageListener done_listener("TEST_PASSED", false);
529    done_listener.AlsoListenForFailureMessage("TEST_FAILED");
530    if (!content::ExecuteScript(
531            embedder_web_contents,
532            base::StringPrintf("runTest('%s')", test_name.c_str()))) {
533      LOG(ERROR) << "UNABLE TO START TEST.";
534      return;
535    }
536    ASSERT_TRUE(done_listener.WaitUntilSatisfied());
537  }
538
539  content::WebContents* LoadGuest(const std::string& guest_path,
540                                  const std::string& app_path) {
541    GURL::Replacements replace_host;
542    std::string host_str("localhost");  // Must stay in scope with replace_host.
543    replace_host.SetHostStr(host_str);
544
545    GURL guest_url = embedded_test_server()->GetURL(guest_path);
546    guest_url = guest_url.ReplaceComponents(replace_host);
547
548    ui_test_utils::UrlLoadObserver guest_observer(
549        guest_url, content::NotificationService::AllSources());
550
551    ExtensionTestMessageListener guest_loaded_listener("guest-loaded", false);
552    LoadAndLaunchPlatformApp(app_path.c_str());
553    guest_observer.Wait();
554
555    content::Source<content::NavigationController> source =
556        guest_observer.source();
557    EXPECT_TRUE(source->GetWebContents()->GetRenderProcessHost()->IsGuest());
558
559    bool satisfied = guest_loaded_listener.WaitUntilSatisfied();
560    if (!satisfied)
561      return NULL;
562
563    content::WebContents* guest_web_contents = source->GetWebContents();
564    return guest_web_contents;
565  }
566
567  // Runs media_access/allow tests.
568  void MediaAccessAPIAllowTestHelper(const std::string& test_name);
569
570  // Runs media_access/deny tests, each of them are run separately otherwise
571  // they timeout (mostly on Windows).
572  void MediaAccessAPIDenyTestHelper(const std::string& test_name) {
573    ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
574    ExtensionTestMessageListener loaded_listener("loaded", false);
575    LoadAndLaunchPlatformApp("web_view/media_access/deny");
576    ASSERT_TRUE(loaded_listener.WaitUntilSatisfied());
577
578    content::WebContents* embedder_web_contents =
579        GetFirstShellWindowWebContents();
580    ASSERT_TRUE(embedder_web_contents);
581
582    ExtensionTestMessageListener test_run_listener("PASSED", false);
583    test_run_listener.AlsoListenForFailureMessage("FAILED");
584    EXPECT_TRUE(
585        content::ExecuteScript(
586            embedder_web_contents,
587            base::StringPrintf("startDenyTest('%s')", test_name.c_str())));
588    ASSERT_TRUE(test_run_listener.WaitUntilSatisfied());
589  }
590
591  void WaitForInterstitial(content::WebContents* web_contents) {
592    scoped_refptr<content::MessageLoopRunner> loop_runner(
593        new content::MessageLoopRunner);
594    InterstitialObserver observer(web_contents,
595                                  loop_runner->QuitClosure(),
596                                  base::Closure());
597    if (!content::InterstitialPage::GetInterstitialPage(web_contents))
598      loop_runner->Run();
599  }
600
601 private:
602  bool UsesFakeSpeech() {
603    const testing::TestInfo* const test_info =
604        testing::UnitTest::GetInstance()->current_test_info();
605
606    // SpeechRecognition test specific SetUp.
607    return !strcmp(test_info->name(), "SpeechRecognition") ||
608           !strcmp(test_info->name(),
609                   "SpeechRecognitionAPI_HasPermissionAllow");
610  }
611
612  scoped_ptr<content::FakeSpeechRecognitionManager>
613      fake_speech_recognition_manager_;
614};
615
616// This test ensures JavaScript errors ("Cannot redefine property") do not
617// happen when a <webview> is removed from DOM and added back.
618IN_PROC_BROWSER_TEST_F(WebViewTest,
619                       AddRemoveWebView_AddRemoveWebView) {
620  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
621  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/addremove"))
622      << message_;
623}
624
625IN_PROC_BROWSER_TEST_F(WebViewTest, AutoSize) {
626#if defined(OS_WIN)
627  // Flaky on XP bot http://crbug.com/299507
628  if (base::win::GetVersion() <= base::win::VERSION_XP)
629    return;
630#endif
631
632  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/autosize"))
633      << message_;
634}
635
636#if !defined(OS_CHROMEOS)
637// This test ensures <webview> doesn't crash in SW rendering when autosize is
638// turned on.
639// Flaky on Windows http://crbug.com/299507
640#if defined(OS_WIN)
641#define MAYBE_AutoSizeSW DISABLED_AutoSizeSW
642#else
643#define MAYBE_AutoSizeSW AutoSizeSW
644#endif
645IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_AutoSizeSW) {
646  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/autosize"))
647      << message_;
648}
649#endif
650
651// http://crbug.com/326332
652IN_PROC_BROWSER_TEST_F(WebViewTest, DISABLED_Shim_TestAutosizeAfterNavigation) {
653  TestHelper("testAutosizeAfterNavigation", "web_view/shim", NO_TEST_SERVER);
654}
655
656IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestAutosizeBeforeNavigation) {
657  TestHelper("testAutosizeBeforeNavigation", "web_view/shim", NO_TEST_SERVER);
658}
659IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestAutosizeRemoveAttributes) {
660  TestHelper("testAutosizeRemoveAttributes", "web_view/shim", NO_TEST_SERVER);
661}
662
663// This test is disabled due to being flaky. http://crbug.com/282116
664#if defined(OS_WIN)
665#define MAYBE_Shim_TestAutosizeWithPartialAttributes \
666    DISABLED_Shim_TestAutosizeWithPartialAttributes
667#else
668#define MAYBE_Shim_TestAutosizeWithPartialAttributes \
669    Shim_TestAutosizeWithPartialAttributes
670#endif
671IN_PROC_BROWSER_TEST_F(WebViewTest,
672                       MAYBE_Shim_TestAutosizeWithPartialAttributes) {
673  TestHelper("testAutosizeWithPartialAttributes",
674             "web_view/shim",
675             NO_TEST_SERVER);
676}
677
678IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestAPIMethodExistence) {
679  TestHelper("testAPIMethodExistence", "web_view/shim", NO_TEST_SERVER);
680}
681
682// Tests the existence of WebRequest API event objects on the request
683// object, on the webview element, and hanging directly off webview.
684IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestWebRequestAPIExistence) {
685  TestHelper("testWebRequestAPIExistence", "web_view/shim", NO_TEST_SERVER);
686}
687
688// http://crbug.com/315920
689#if defined(GOOGLE_CHROME_BUILD) && (defined(OS_WIN) || defined(OS_LINUX))
690#define MAYBE_Shim_TestChromeExtensionURL DISABLED_Shim_TestChromeExtensionURL
691#else
692#define MAYBE_Shim_TestChromeExtensionURL Shim_TestChromeExtensionURL
693#endif
694IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_Shim_TestChromeExtensionURL) {
695  TestHelper("testChromeExtensionURL", "web_view/shim", NO_TEST_SERVER);
696}
697
698// http://crbug.com/315920
699#if defined(GOOGLE_CHROME_BUILD) && (defined(OS_WIN) || defined(OS_LINUX))
700#define MAYBE_Shim_TestChromeExtensionRelativePath \
701    DISABLED_Shim_TestChromeExtensionRelativePath
702#else
703#define MAYBE_Shim_TestChromeExtensionRelativePath \
704    Shim_TestChromeExtensionRelativePath
705#endif
706IN_PROC_BROWSER_TEST_F(WebViewTest,
707                       MAYBE_Shim_TestChromeExtensionRelativePath) {
708  TestHelper("testChromeExtensionRelativePath",
709             "web_view/shim",
710             NO_TEST_SERVER);
711}
712
713IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestInvalidChromeExtensionURL) {
714  TestHelper("testInvalidChromeExtensionURL", "web_view/shim", NO_TEST_SERVER);
715}
716
717IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestEventName) {
718  TestHelper("testEventName", "web_view/shim", NO_TEST_SERVER);
719}
720
721IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestOnEventProperty) {
722  TestHelper("testOnEventProperties", "web_view/shim", NO_TEST_SERVER);
723}
724
725IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadProgressEvent) {
726  TestHelper("testLoadProgressEvent", "web_view/shim", NO_TEST_SERVER);
727}
728
729// WebViewTest.Shim_TestDestroyOnEventListener is flaky, so disable it.
730// http://crbug.com/255106
731IN_PROC_BROWSER_TEST_F(WebViewTest, DISABLED_Shim_TestDestroyOnEventListener) {
732  TestHelper("testDestroyOnEventListener", "web_view/shim", NO_TEST_SERVER);
733}
734
735IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestCannotMutateEventName) {
736  TestHelper("testCannotMutateEventName", "web_view/shim", NO_TEST_SERVER);
737}
738
739// http://crbug.com/267304
740#if defined(OS_WIN)
741#define MAYBE_Shim_TestPartitionRaisesException \
742  DISABLED_Shim_TestPartitionRaisesException
743#else
744#define MAYBE_Shim_TestPartitionRaisesException \
745  Shim_TestPartitionRaisesException
746#endif
747
748IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_Shim_TestPartitionRaisesException) {
749  TestHelper("testPartitionRaisesException",
750             "web_view/shim",
751             NO_TEST_SERVER);
752}
753
754IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestExecuteScriptFail) {
755#if defined(OS_WIN)
756  // Flaky on XP bot http://crbug.com/266185
757  if (base::win::GetVersion() <= base::win::VERSION_XP)
758    return;
759#endif
760
761  TestHelper("testExecuteScriptFail", "web_view/shim", NEEDS_TEST_SERVER);
762}
763
764IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestExecuteScript) {
765  TestHelper("testExecuteScript", "web_view/shim", NO_TEST_SERVER);
766}
767
768IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestTerminateAfterExit) {
769  TestHelper("testTerminateAfterExit", "web_view/shim", NO_TEST_SERVER);
770}
771
772IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestAssignSrcAfterCrash) {
773  TestHelper("testAssignSrcAfterCrash", "web_view/shim", NO_TEST_SERVER);
774}
775
776IN_PROC_BROWSER_TEST_F(WebViewTest,
777                       Shim_TestNavOnConsecutiveSrcAttributeChanges) {
778  TestHelper("testNavOnConsecutiveSrcAttributeChanges",
779             "web_view/shim",
780             NO_TEST_SERVER);
781}
782
783IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNavOnSrcAttributeChange) {
784  TestHelper("testNavOnSrcAttributeChange", "web_view/shim", NO_TEST_SERVER);
785}
786
787IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestRemoveSrcAttribute) {
788  TestHelper("testRemoveSrcAttribute", "web_view/shim", NO_TEST_SERVER);
789}
790
791IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestReassignSrcAttribute) {
792  TestHelper("testReassignSrcAttribute", "web_view/shim", NO_TEST_SERVER);
793}
794
795IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestBrowserPluginNotAllowed) {
796#if defined(OS_WIN)
797  // Flaky on XP bots. http://crbug.com/267300
798  if (base::win::GetVersion() <= base::win::VERSION_XP)
799    return;
800#endif
801
802  TestHelper("testBrowserPluginNotAllowed", "web_view/shim", NO_TEST_SERVER);
803}
804
805IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNewWindow) {
806  TestHelper("testNewWindow", "web_view/shim", NEEDS_TEST_SERVER);
807}
808
809IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNewWindowTwoListeners) {
810  TestHelper("testNewWindowTwoListeners", "web_view/shim", NEEDS_TEST_SERVER);
811}
812
813IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNewWindowNoPreventDefault) {
814  TestHelper("testNewWindowNoPreventDefault",
815             "web_view/shim",
816             NEEDS_TEST_SERVER);
817}
818
819IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNewWindowNoReferrerLink) {
820  TestHelper("testNewWindowNoReferrerLink", "web_view/shim", NEEDS_TEST_SERVER);
821}
822
823IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestContentLoadEvent) {
824  TestHelper("testContentLoadEvent", "web_view/shim", NO_TEST_SERVER);
825}
826
827// http://crbug.com/326330
828IN_PROC_BROWSER_TEST_F(WebViewTest,
829                       DISABLED_Shim_TestDeclarativeWebRequestAPI) {
830  TestHelper("testDeclarativeWebRequestAPI",
831             "web_view/shim",
832             NEEDS_TEST_SERVER);
833}
834
835IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestWebRequestAPI) {
836  TestHelper("testWebRequestAPI", "web_view/shim", NEEDS_TEST_SERVER);
837}
838
839IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestWebRequestAPIGoogleProperty) {
840  TestHelper("testWebRequestAPIGoogleProperty",
841             "web_view/shim",
842             NO_TEST_SERVER);
843}
844
845// This test is disabled due to being flaky. http://crbug.com/309451
846#if defined(OS_WIN)
847#define MAYBE_Shim_TestWebRequestListenerSurvivesReparenting \
848    DISABLED_Shim_TestWebRequestListenerSurvivesReparenting
849#else
850#define MAYBE_Shim_TestWebRequestListenerSurvivesReparenting \
851    Shim_TestWebRequestListenerSurvivesReparenting
852#endif
853IN_PROC_BROWSER_TEST_F(
854    WebViewTest,
855    MAYBE_Shim_TestWebRequestListenerSurvivesReparenting) {
856  TestHelper("testWebRequestListenerSurvivesReparenting",
857             "web_view/shim",
858             NEEDS_TEST_SERVER);
859}
860
861IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadStartLoadRedirect) {
862  TestHelper("testLoadStartLoadRedirect", "web_view/shim", NEEDS_TEST_SERVER);
863}
864
865IN_PROC_BROWSER_TEST_F(WebViewTest,
866                       Shim_TestLoadAbortChromeExtensionURLWrongPartition) {
867  TestHelper("testLoadAbortChromeExtensionURLWrongPartition",
868             "web_view/shim",
869             NO_TEST_SERVER);
870}
871
872IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadAbortEmptyResponse) {
873  TestHelper("testLoadAbortEmptyResponse", "web_view/shim", NEEDS_TEST_SERVER);
874}
875
876IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadAbortIllegalChromeURL) {
877  TestHelper("testLoadAbortIllegalChromeURL",
878             "web_view/shim",
879             NO_TEST_SERVER);
880}
881
882IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadAbortIllegalFileURL) {
883  TestHelper("testLoadAbortIllegalFileURL", "web_view/shim", NO_TEST_SERVER);
884}
885
886IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadAbortIllegalJavaScriptURL) {
887  TestHelper("testLoadAbortIllegalJavaScriptURL",
888             "web_view/shim",
889             NO_TEST_SERVER);
890}
891
892IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestReload) {
893  TestHelper("testReload", "web_view/shim", NEEDS_TEST_SERVER);
894}
895
896IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestGetProcessId) {
897  TestHelper("testGetProcessId", "web_view/shim", NEEDS_TEST_SERVER);
898}
899
900IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestRemoveWebviewOnExit) {
901  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
902
903  // Launch the app and wait until it's ready to load a test.
904  ExtensionTestMessageListener launched_listener("Launched", false);
905  LoadAndLaunchPlatformApp("web_view/shim");
906  ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
907
908  content::WebContents* embedder_web_contents =
909      GetFirstShellWindowWebContents();
910  ASSERT_TRUE(embedder_web_contents);
911
912  GURL::Replacements replace_host;
913  std::string host_str("localhost");  // Must stay in scope with replace_host.
914  replace_host.SetHostStr(host_str);
915
916  std::string guest_path(
917      "/extensions/platform_apps/web_view/shim/empty_guest.html");
918  GURL guest_url = embedded_test_server()->GetURL(guest_path);
919  guest_url = guest_url.ReplaceComponents(replace_host);
920
921  ui_test_utils::UrlLoadObserver guest_observer(
922      guest_url, content::NotificationService::AllSources());
923
924  // Run the test and wait until the guest WebContents is available and has
925  // finished loading.
926  ExtensionTestMessageListener guest_loaded_listener("guest-loaded", false);
927  EXPECT_TRUE(content::ExecuteScript(
928                  embedder_web_contents,
929                  "runTest('testRemoveWebviewOnExit')"));
930  guest_observer.Wait();
931
932  content::Source<content::NavigationController> source =
933      guest_observer.source();
934  EXPECT_TRUE(source->GetWebContents()->GetRenderProcessHost()->IsGuest());
935
936  ASSERT_TRUE(guest_loaded_listener.WaitUntilSatisfied());
937
938  content::WebContentsDestroyedWatcher destroyed_watcher(
939      source->GetWebContents());
940
941  // Tell the embedder to kill the guest.
942  EXPECT_TRUE(content::ExecuteScript(
943                  embedder_web_contents,
944                  "removeWebviewOnExitDoCrash();"));
945
946  // Wait until the guest WebContents is destroyed.
947  destroyed_watcher.Wait();
948}
949
950// Remove <webview> immediately after navigating it.
951// This is a regression test for http://crbug.com/276023.
952IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestRemoveWebviewAfterNavigation) {
953  TestHelper("testRemoveWebviewAfterNavigation",
954             "web_view/shim",
955             NO_TEST_SERVER);
956}
957
958IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNavigationToExternalProtocol) {
959  TestHelper("testNavigationToExternalProtocol",
960             "web_view/shim",
961             NO_TEST_SERVER);
962}
963
964IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestResizeWebviewResizesContent) {
965  TestHelper("testResizeWebviewResizesContent",
966             "web_view/shim",
967             NO_TEST_SERVER);
968}
969
970// This test makes sure we do not crash if app is closed while interstitial
971// page is being shown in guest.
972IN_PROC_BROWSER_TEST_F(WebViewTest, InterstitialTeardown) {
973#if defined(OS_WIN)
974  // Flaky on XP bot http://crbug.com/297014
975  if (base::win::GetVersion() <= base::win::VERSION_XP)
976    return;
977#endif
978
979  // Start a HTTPS server so we can load an interstitial page inside guest.
980  net::SpawnedTestServer::SSLOptions ssl_options;
981  ssl_options.server_certificate =
982      net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
983  net::SpawnedTestServer https_server(
984      net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
985      base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
986  ASSERT_TRUE(https_server.Start());
987
988  net::HostPortPair host_and_port = https_server.host_port_pair();
989
990  ExtensionTestMessageListener embedder_loaded_listener("EmbedderLoaded",
991                                                        false);
992  LoadAndLaunchPlatformApp("web_view/interstitial_teardown");
993  ASSERT_TRUE(embedder_loaded_listener.WaitUntilSatisfied());
994
995  GuestContentBrowserClient new_client;
996  content::ContentBrowserClient* old_client =
997      SetBrowserClientForTesting(&new_client);
998
999  // Now load the guest.
1000  content::WebContents* embedder_web_contents =
1001      GetFirstShellWindowWebContents();
1002  ExtensionTestMessageListener second("GuestAddedToDom", false);
1003  EXPECT_TRUE(content::ExecuteScript(
1004      embedder_web_contents,
1005      base::StringPrintf("loadGuest(%d);\n", host_and_port.port())));
1006  ASSERT_TRUE(second.WaitUntilSatisfied());
1007
1008  // Wait for interstitial page to be shown in guest.
1009  content::WebContents* guest_web_contents = new_client.WaitForGuestCreated();
1010  SetBrowserClientForTesting(old_client);
1011  ASSERT_TRUE(guest_web_contents->GetRenderProcessHost()->IsGuest());
1012  WaitForInterstitial(guest_web_contents);
1013
1014  // Now close the app while interstitial page being shown in guest.
1015  apps::ShellWindow* window = GetFirstShellWindow();
1016  window->GetBaseWindow()->Close();
1017}
1018
1019IN_PROC_BROWSER_TEST_F(WebViewTest, ShimSrcAttribute) {
1020  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/src_attribute"))
1021      << message_;
1022}
1023
1024// Disabled on Windows for flaky failures: crbug.com/329032
1025#if defined(OS_WIN)
1026#define MAYBE_Size DISABLED_Size
1027#else
1028#define MAYBE_Size Size
1029#endif
1030IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_Size) {
1031  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/size")) << message_;
1032}
1033
1034// This test verifies that prerendering has been disabled inside <webview>.
1035// This test is here rather than in PrerenderBrowserTest for testing convenience
1036// only. If it breaks then this is a bug in the prerenderer.
1037IN_PROC_BROWSER_TEST_F(WebViewTest, NoPrerenderer) {
1038  ASSERT_TRUE(StartEmbeddedTestServer());
1039  content::WebContents* guest_web_contents =
1040      LoadGuest(
1041          "/extensions/platform_apps/web_view/noprerenderer/guest.html",
1042          "web_view/noprerenderer");
1043  ASSERT_TRUE(guest_web_contents != NULL);
1044
1045  PrerenderLinkManager* prerender_link_manager =
1046      PrerenderLinkManagerFactory::GetForProfile(
1047          Profile::FromBrowserContext(guest_web_contents->GetBrowserContext()));
1048  ASSERT_TRUE(prerender_link_manager != NULL);
1049  EXPECT_TRUE(prerender_link_manager->IsEmpty());
1050}
1051
1052// This tests cookie isolation for packaged apps with webview tags. It navigates
1053// the main browser window to a page that sets a cookie and loads an app with
1054// multiple webview tags. Each tag sets a cookie and the test checks the proper
1055// storage isolation is enforced.
1056// This test is disabled due to being flaky. http://crbug.com/294196
1057#if defined(OS_WIN)
1058#define MAYBE_CookieIsolation DISABLED_CookieIsolation
1059#else
1060#define MAYBE_CookieIsolation CookieIsolation
1061#endif
1062IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_CookieIsolation) {
1063  ASSERT_TRUE(StartEmbeddedTestServer());
1064  const std::string kExpire =
1065      "var expire = new Date(Date.now() + 24 * 60 * 60 * 1000);";
1066  std::string cookie_script1(kExpire);
1067  cookie_script1.append(
1068      "document.cookie = 'guest1=true; path=/; expires=' + expire + ';';");
1069  std::string cookie_script2(kExpire);
1070  cookie_script2.append(
1071      "document.cookie = 'guest2=true; path=/; expires=' + expire + ';';");
1072
1073  GURL::Replacements replace_host;
1074  std::string host_str("localhost");  // Must stay in scope with replace_host.
1075  replace_host.SetHostStr(host_str);
1076
1077  GURL set_cookie_url = embedded_test_server()->GetURL(
1078      "/extensions/platform_apps/isolation/set_cookie.html");
1079  set_cookie_url = set_cookie_url.ReplaceComponents(replace_host);
1080
1081  // The first two partitions will be used to set cookies and ensure they are
1082  // shared. The named partition is used to ensure that cookies are isolated
1083  // between partitions within the same app.
1084  content::WebContents* cookie_contents1;
1085  content::WebContents* cookie_contents2;
1086  content::WebContents* named_partition_contents1;
1087  content::WebContents* named_partition_contents2;
1088
1089  NavigateAndOpenAppForIsolation(set_cookie_url, &cookie_contents1,
1090                                 &cookie_contents2, &named_partition_contents1,
1091                                 &named_partition_contents2, NULL, NULL, NULL);
1092
1093  EXPECT_TRUE(content::ExecuteScript(cookie_contents1, cookie_script1));
1094  EXPECT_TRUE(content::ExecuteScript(cookie_contents2, cookie_script2));
1095
1096  int cookie_size;
1097  std::string cookie_value;
1098
1099  // Test the regular browser context to ensure we have only one cookie.
1100  automation_util::GetCookies(GURL("http://localhost"),
1101                              browser()->tab_strip_model()->GetWebContentsAt(0),
1102                              &cookie_size, &cookie_value);
1103  EXPECT_EQ("testCookie=1", cookie_value);
1104
1105  // The default behavior is to combine webview tags with no explicit partition
1106  // declaration into the same in-memory partition. Test the webview tags to
1107  // ensure we have properly set the cookies and we have both cookies in both
1108  // tags.
1109  automation_util::GetCookies(GURL("http://localhost"),
1110                              cookie_contents1,
1111                              &cookie_size, &cookie_value);
1112  EXPECT_EQ("guest1=true; guest2=true", cookie_value);
1113
1114  automation_util::GetCookies(GURL("http://localhost"),
1115                              cookie_contents2,
1116                              &cookie_size, &cookie_value);
1117  EXPECT_EQ("guest1=true; guest2=true", cookie_value);
1118
1119  // The third tag should not have any cookies as it is in a separate partition.
1120  automation_util::GetCookies(GURL("http://localhost"),
1121                              named_partition_contents1,
1122                              &cookie_size, &cookie_value);
1123  EXPECT_EQ("", cookie_value);
1124}
1125
1126// This tests that in-memory storage partitions are reset on browser restart,
1127// but persistent ones maintain state for cookies and HTML5 storage.
1128IN_PROC_BROWSER_TEST_F(WebViewTest, PRE_StoragePersistence) {
1129  ASSERT_TRUE(StartEmbeddedTestServer());
1130  const std::string kExpire =
1131      "var expire = new Date(Date.now() + 24 * 60 * 60 * 1000);";
1132  std::string cookie_script1(kExpire);
1133  cookie_script1.append(
1134      "document.cookie = 'inmemory=true; path=/; expires=' + expire + ';';");
1135  std::string cookie_script2(kExpire);
1136  cookie_script2.append(
1137      "document.cookie = 'persist1=true; path=/; expires=' + expire + ';';");
1138  std::string cookie_script3(kExpire);
1139  cookie_script3.append(
1140      "document.cookie = 'persist2=true; path=/; expires=' + expire + ';';");
1141
1142  // We don't care where the main browser is on this test.
1143  GURL blank_url("about:blank");
1144
1145  // The first two partitions will be used to set cookies and ensure they are
1146  // shared. The named partition is used to ensure that cookies are isolated
1147  // between partitions within the same app.
1148  content::WebContents* cookie_contents1;
1149  content::WebContents* cookie_contents2;
1150  content::WebContents* named_partition_contents1;
1151  content::WebContents* named_partition_contents2;
1152  content::WebContents* persistent_partition_contents1;
1153  content::WebContents* persistent_partition_contents2;
1154  content::WebContents* persistent_partition_contents3;
1155  NavigateAndOpenAppForIsolation(blank_url, &cookie_contents1,
1156                                 &cookie_contents2, &named_partition_contents1,
1157                                 &named_partition_contents2,
1158                                 &persistent_partition_contents1,
1159                                 &persistent_partition_contents2,
1160                                 &persistent_partition_contents3);
1161
1162  // Set the inmemory=true cookie for tags with inmemory partitions.
1163  EXPECT_TRUE(content::ExecuteScript(cookie_contents1, cookie_script1));
1164  EXPECT_TRUE(content::ExecuteScript(named_partition_contents1,
1165                                     cookie_script1));
1166
1167  // For the two different persistent storage partitions, set the
1168  // two different cookies so we can check that they aren't comingled below.
1169  EXPECT_TRUE(content::ExecuteScript(persistent_partition_contents1,
1170                                     cookie_script2));
1171
1172  EXPECT_TRUE(content::ExecuteScript(persistent_partition_contents3,
1173                                     cookie_script3));
1174
1175  int cookie_size;
1176  std::string cookie_value;
1177
1178  // Check that all in-memory partitions have a cookie set.
1179  automation_util::GetCookies(GURL("http://localhost"),
1180                              cookie_contents1,
1181                              &cookie_size, &cookie_value);
1182  EXPECT_EQ("inmemory=true", cookie_value);
1183  automation_util::GetCookies(GURL("http://localhost"),
1184                              cookie_contents2,
1185                              &cookie_size, &cookie_value);
1186  EXPECT_EQ("inmemory=true", cookie_value);
1187  automation_util::GetCookies(GURL("http://localhost"),
1188                              named_partition_contents1,
1189                              &cookie_size, &cookie_value);
1190  EXPECT_EQ("inmemory=true", cookie_value);
1191  automation_util::GetCookies(GURL("http://localhost"),
1192                              named_partition_contents2,
1193                              &cookie_size, &cookie_value);
1194  EXPECT_EQ("inmemory=true", cookie_value);
1195
1196  // Check that all persistent partitions kept their state.
1197  automation_util::GetCookies(GURL("http://localhost"),
1198                              persistent_partition_contents1,
1199                              &cookie_size, &cookie_value);
1200  EXPECT_EQ("persist1=true", cookie_value);
1201  automation_util::GetCookies(GURL("http://localhost"),
1202                              persistent_partition_contents2,
1203                              &cookie_size, &cookie_value);
1204  EXPECT_EQ("persist1=true", cookie_value);
1205  automation_util::GetCookies(GURL("http://localhost"),
1206                              persistent_partition_contents3,
1207                              &cookie_size, &cookie_value);
1208  EXPECT_EQ("persist2=true", cookie_value);
1209}
1210
1211// This is the post-reset portion of the StoragePersistence test.  See
1212// PRE_StoragePersistence for main comment.
1213IN_PROC_BROWSER_TEST_F(WebViewTest, DISABLED_StoragePersistence) {
1214  ASSERT_TRUE(StartEmbeddedTestServer());
1215
1216  // We don't care where the main browser is on this test.
1217  GURL blank_url("about:blank");
1218
1219  // The first two partitions will be used to set cookies and ensure they are
1220  // shared. The named partition is used to ensure that cookies are isolated
1221  // between partitions within the same app.
1222  content::WebContents* cookie_contents1;
1223  content::WebContents* cookie_contents2;
1224  content::WebContents* named_partition_contents1;
1225  content::WebContents* named_partition_contents2;
1226  content::WebContents* persistent_partition_contents1;
1227  content::WebContents* persistent_partition_contents2;
1228  content::WebContents* persistent_partition_contents3;
1229  NavigateAndOpenAppForIsolation(blank_url, &cookie_contents1,
1230                                 &cookie_contents2, &named_partition_contents1,
1231                                 &named_partition_contents2,
1232                                 &persistent_partition_contents1,
1233                                 &persistent_partition_contents2,
1234                                 &persistent_partition_contents3);
1235
1236  int cookie_size;
1237  std::string cookie_value;
1238
1239  // Check that all in-memory partitions lost their state.
1240  automation_util::GetCookies(GURL("http://localhost"),
1241                              cookie_contents1,
1242                              &cookie_size, &cookie_value);
1243  EXPECT_EQ("", cookie_value);
1244  automation_util::GetCookies(GURL("http://localhost"),
1245                              cookie_contents2,
1246                              &cookie_size, &cookie_value);
1247  EXPECT_EQ("", cookie_value);
1248  automation_util::GetCookies(GURL("http://localhost"),
1249                              named_partition_contents1,
1250                              &cookie_size, &cookie_value);
1251  EXPECT_EQ("", cookie_value);
1252  automation_util::GetCookies(GURL("http://localhost"),
1253                              named_partition_contents2,
1254                              &cookie_size, &cookie_value);
1255  EXPECT_EQ("", cookie_value);
1256
1257  // Check that all persistent partitions kept their state.
1258  automation_util::GetCookies(GURL("http://localhost"),
1259                              persistent_partition_contents1,
1260                              &cookie_size, &cookie_value);
1261  EXPECT_EQ("persist1=true", cookie_value);
1262  automation_util::GetCookies(GURL("http://localhost"),
1263                              persistent_partition_contents2,
1264                              &cookie_size, &cookie_value);
1265  EXPECT_EQ("persist1=true", cookie_value);
1266  automation_util::GetCookies(GURL("http://localhost"),
1267                              persistent_partition_contents3,
1268                              &cookie_size, &cookie_value);
1269  EXPECT_EQ("persist2=true", cookie_value);
1270}
1271
1272#if defined(OS_WIN)
1273// This test is very flaky on Win Aura, Win XP, Win 7. http://crbug.com/248873
1274#define MAYBE_DOMStorageIsolation DISABLED_DOMStorageIsolation
1275#else
1276#define MAYBE_DOMStorageIsolation DOMStorageIsolation
1277#endif
1278
1279// This tests DOM storage isolation for packaged apps with webview tags. It
1280// loads an app with multiple webview tags and each tag sets DOM storage
1281// entries, which the test checks to ensure proper storage isolation is
1282// enforced.
1283IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_DOMStorageIsolation) {
1284  ASSERT_TRUE(StartEmbeddedTestServer());
1285  GURL regular_url = embedded_test_server()->GetURL("/title1.html");
1286
1287  std::string output;
1288  std::string get_local_storage("window.domAutomationController.send("
1289      "window.localStorage.getItem('foo') || 'badval')");
1290  std::string get_session_storage("window.domAutomationController.send("
1291      "window.sessionStorage.getItem('bar') || 'badval')");
1292
1293  content::WebContents* default_tag_contents1;
1294  content::WebContents* default_tag_contents2;
1295  content::WebContents* storage_contents1;
1296  content::WebContents* storage_contents2;
1297
1298  NavigateAndOpenAppForIsolation(regular_url, &default_tag_contents1,
1299                                 &default_tag_contents2, &storage_contents1,
1300                                 &storage_contents2, NULL, NULL, NULL);
1301
1302  // Initialize the storage for the first of the two tags that share a storage
1303  // partition.
1304  EXPECT_TRUE(content::ExecuteScript(storage_contents1,
1305                                     "initDomStorage('page1')"));
1306
1307  // Let's test that the expected values are present in the first tag, as they
1308  // will be overwritten once we call the initDomStorage on the second tag.
1309  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1,
1310                                            get_local_storage.c_str(),
1311                                            &output));
1312  EXPECT_STREQ("local-page1", output.c_str());
1313  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1,
1314                                            get_session_storage.c_str(),
1315                                            &output));
1316  EXPECT_STREQ("session-page1", output.c_str());
1317
1318  // Now, init the storage in the second tag in the same storage partition,
1319  // which will overwrite the shared localStorage.
1320  EXPECT_TRUE(content::ExecuteScript(storage_contents2,
1321                                     "initDomStorage('page2')"));
1322
1323  // The localStorage value now should reflect the one written through the
1324  // second tag.
1325  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1,
1326                                            get_local_storage.c_str(),
1327                                            &output));
1328  EXPECT_STREQ("local-page2", output.c_str());
1329  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents2,
1330                                            get_local_storage.c_str(),
1331                                            &output));
1332  EXPECT_STREQ("local-page2", output.c_str());
1333
1334  // Session storage is not shared though, as each webview tag has separate
1335  // instance, even if they are in the same storage partition.
1336  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1,
1337                                            get_session_storage.c_str(),
1338                                            &output));
1339  EXPECT_STREQ("session-page1", output.c_str());
1340  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents2,
1341                                            get_session_storage.c_str(),
1342                                            &output));
1343  EXPECT_STREQ("session-page2", output.c_str());
1344
1345  // Also, let's check that the main browser and another tag that doesn't share
1346  // the same partition don't have those values stored.
1347  EXPECT_TRUE(ExecuteScriptAndExtractString(
1348      browser()->tab_strip_model()->GetWebContentsAt(0),
1349      get_local_storage.c_str(),
1350      &output));
1351  EXPECT_STREQ("badval", output.c_str());
1352  EXPECT_TRUE(ExecuteScriptAndExtractString(
1353      browser()->tab_strip_model()->GetWebContentsAt(0),
1354      get_session_storage.c_str(),
1355      &output));
1356  EXPECT_STREQ("badval", output.c_str());
1357  EXPECT_TRUE(ExecuteScriptAndExtractString(default_tag_contents1,
1358                                            get_local_storage.c_str(),
1359                                            &output));
1360  EXPECT_STREQ("badval", output.c_str());
1361  EXPECT_TRUE(ExecuteScriptAndExtractString(default_tag_contents1,
1362                                            get_session_storage.c_str(),
1363                                            &output));
1364  EXPECT_STREQ("badval", output.c_str());
1365}
1366
1367// See crbug.com/248500
1368#if defined(OS_WIN)
1369#define MAYBE_IndexedDBIsolation DISABLED_IndexedDBIsolation
1370#else
1371#define MAYBE_IndexedDBIsolation IndexedDBIsolation
1372#endif
1373
1374// This tests IndexedDB isolation for packaged apps with webview tags. It loads
1375// an app with multiple webview tags and each tag creates an IndexedDB record,
1376// which the test checks to ensure proper storage isolation is enforced.
1377IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_IndexedDBIsolation) {
1378  ASSERT_TRUE(StartEmbeddedTestServer());
1379  GURL regular_url = embedded_test_server()->GetURL("/title1.html");
1380
1381  content::WebContents* default_tag_contents1;
1382  content::WebContents* default_tag_contents2;
1383  content::WebContents* storage_contents1;
1384  content::WebContents* storage_contents2;
1385
1386  NavigateAndOpenAppForIsolation(regular_url, &default_tag_contents1,
1387                                 &default_tag_contents2, &storage_contents1,
1388                                 &storage_contents2, NULL, NULL, NULL);
1389
1390  // Initialize the storage for the first of the two tags that share a storage
1391  // partition.
1392  ExecuteScriptWaitForTitle(storage_contents1, "initIDB()", "idb created");
1393  ExecuteScriptWaitForTitle(storage_contents1, "addItemIDB(7, 'page1')",
1394                            "addItemIDB complete");
1395  ExecuteScriptWaitForTitle(storage_contents1, "readItemIDB(7)",
1396                            "readItemIDB complete");
1397
1398  std::string output;
1399  std::string get_value(
1400      "window.domAutomationController.send(getValueIDB() || 'badval')");
1401
1402  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1,
1403                                            get_value.c_str(), &output));
1404  EXPECT_STREQ("page1", output.c_str());
1405
1406  // Initialize the db in the second tag.
1407  ExecuteScriptWaitForTitle(storage_contents2, "initIDB()", "idb open");
1408
1409  // Since we share a partition, reading the value should return the existing
1410  // one.
1411  ExecuteScriptWaitForTitle(storage_contents2, "readItemIDB(7)",
1412                            "readItemIDB complete");
1413  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents2,
1414                                            get_value.c_str(), &output));
1415  EXPECT_STREQ("page1", output.c_str());
1416
1417  // Now write through the second tag and read it back.
1418  ExecuteScriptWaitForTitle(storage_contents2, "addItemIDB(7, 'page2')",
1419                            "addItemIDB complete");
1420  ExecuteScriptWaitForTitle(storage_contents2, "readItemIDB(7)",
1421                            "readItemIDB complete");
1422  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents2,
1423                                            get_value.c_str(), &output));
1424  EXPECT_STREQ("page2", output.c_str());
1425
1426  // Reset the document title, otherwise the next call will not see a change and
1427  // will hang waiting for it.
1428  EXPECT_TRUE(content::ExecuteScript(storage_contents1,
1429                                     "document.title = 'foo'"));
1430
1431  // Read through the first tag to ensure we have the second value.
1432  ExecuteScriptWaitForTitle(storage_contents1, "readItemIDB(7)",
1433                            "readItemIDB complete");
1434  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1,
1435                                            get_value.c_str(), &output));
1436  EXPECT_STREQ("page2", output.c_str());
1437
1438  // Now, let's confirm there is no database in the main browser and another
1439  // tag that doesn't share the same partition. Due to the IndexedDB API design,
1440  // open will succeed, but the version will be 1, since it creates the database
1441  // if it is not found. The two tags use database version 3, so we avoid
1442  // ambiguity.
1443  const char* script =
1444      "indexedDB.open('isolation').onsuccess = function(e) {"
1445      "  if (e.target.result.version == 1)"
1446      "    document.title = 'db not found';"
1447      "  else "
1448      "    document.title = 'error';"
1449      "}";
1450  ExecuteScriptWaitForTitle(browser()->tab_strip_model()->GetWebContentsAt(0),
1451                            script, "db not found");
1452  ExecuteScriptWaitForTitle(default_tag_contents1, script, "db not found");
1453}
1454
1455// This test ensures that closing app window on 'loadcommit' does not crash.
1456// The test launches an app with guest and closes the window on loadcommit. It
1457// then launches the app window again. The process is repeated 3 times.
1458// http://crbug.com/291278
1459#if defined(OS_WIN)
1460#define MAYBE_CloseOnLoadcommit DISABLED_CloseOnLoadcommit
1461#else
1462#define MAYBE_CloseOnLoadcommit CloseOnLoadcommit
1463#endif
1464IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_CloseOnLoadcommit) {
1465  ExtensionTestMessageListener done_test_listener(
1466      "done-close-on-loadcommit", false);
1467  LoadAndLaunchPlatformApp("web_view/close_on_loadcommit");
1468  ASSERT_TRUE(done_test_listener.WaitUntilSatisfied());
1469}
1470
1471IN_PROC_BROWSER_TEST_F(WebViewTest, MediaAccessAPIDeny_TestDeny) {
1472  MediaAccessAPIDenyTestHelper("testDeny");
1473}
1474
1475IN_PROC_BROWSER_TEST_F(WebViewTest,
1476                       MediaAccessAPIDeny_TestDenyThenAllowThrows) {
1477  MediaAccessAPIDenyTestHelper("testDenyThenAllowThrows");
1478
1479}
1480
1481IN_PROC_BROWSER_TEST_F(WebViewTest,
1482                       MediaAccessAPIDeny_TestDenyWithPreventDefault) {
1483  MediaAccessAPIDenyTestHelper("testDenyWithPreventDefault");
1484}
1485
1486IN_PROC_BROWSER_TEST_F(WebViewTest,
1487                       MediaAccessAPIDeny_TestNoListenersImplyDeny) {
1488  MediaAccessAPIDenyTestHelper("testNoListenersImplyDeny");
1489}
1490
1491IN_PROC_BROWSER_TEST_F(WebViewTest,
1492                       MediaAccessAPIDeny_TestNoPreventDefaultImpliesDeny) {
1493  MediaAccessAPIDenyTestHelper("testNoPreventDefaultImpliesDeny");
1494}
1495
1496void WebViewTest::MediaAccessAPIAllowTestHelper(const std::string& test_name) {
1497  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
1498  ExtensionTestMessageListener launched_listener("Launched", false);
1499  LoadAndLaunchPlatformApp("web_view/media_access/allow");
1500  ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
1501
1502  content::WebContents* embedder_web_contents =
1503      GetFirstShellWindowWebContents();
1504  ASSERT_TRUE(embedder_web_contents);
1505  MockWebContentsDelegate* mock = new MockWebContentsDelegate;
1506  embedder_web_contents->SetDelegate(mock);
1507
1508  ExtensionTestMessageListener done_listener("TEST_PASSED", false);
1509  done_listener.AlsoListenForFailureMessage("TEST_FAILED");
1510  EXPECT_TRUE(
1511      content::ExecuteScript(
1512          embedder_web_contents,
1513          base::StringPrintf("startAllowTest('%s')",
1514                             test_name.c_str())));
1515  ASSERT_TRUE(done_listener.WaitUntilSatisfied());
1516
1517  mock->WaitForSetMediaPermission();
1518}
1519
1520IN_PROC_BROWSER_TEST_F(WebViewTest, MediaAccessAPIAllow_TestAllow) {
1521  MediaAccessAPIAllowTestHelper("testAllow");
1522}
1523
1524IN_PROC_BROWSER_TEST_F(WebViewTest, MediaAccessAPIAllow_TestAllowAndThenDeny) {
1525  MediaAccessAPIAllowTestHelper("testAllowAndThenDeny");
1526}
1527
1528IN_PROC_BROWSER_TEST_F(WebViewTest, MediaAccessAPIAllow_TestAllowTwice) {
1529  MediaAccessAPIAllowTestHelper("testAllowTwice");
1530}
1531
1532IN_PROC_BROWSER_TEST_F(WebViewTest, MediaAccessAPIAllow_TestAllowAsync) {
1533  MediaAccessAPIAllowTestHelper("testAllowAsync");
1534}
1535
1536// Checks that window.screenX/screenY/screenLeft/screenTop works correctly for
1537// guests.
1538IN_PROC_BROWSER_TEST_F(WebViewTest, ScreenCoordinates) {
1539  ASSERT_TRUE(RunPlatformAppTestWithArg(
1540      "platform_apps/web_view/common", "screen_coordinates"))
1541          << message_;
1542}
1543
1544IN_PROC_BROWSER_TEST_F(WebViewTest, SpeechRecognition) {
1545  ASSERT_TRUE(StartEmbeddedTestServer());
1546  content::WebContents* guest_web_contents = LoadGuest(
1547      "/extensions/platform_apps/web_view/speech/guest.html",
1548      "web_view/speech");
1549  ASSERT_TRUE(guest_web_contents);
1550
1551  // Click on the guest (center of the WebContents), the guest is rendered in a
1552  // way that this will trigger clicking on speech recognition input mic.
1553  SimulateMouseClick(guest_web_contents, 0, blink::WebMouseEvent::ButtonLeft);
1554
1555  base::string16 expected_title(ASCIIToUTF16("PASSED"));
1556  base::string16 error_title(ASCIIToUTF16("FAILED"));
1557  content::TitleWatcher title_watcher(guest_web_contents, expected_title);
1558  title_watcher.AlsoWaitForTitle(error_title);
1559  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
1560}
1561
1562// Flaky on Windows. http://crbug.com/303966
1563#if defined(OS_WIN)
1564#define MAYBE_TearDownTest DISABLED_TearDownTest
1565#else
1566#define MAYBE_TearDownTest TearDownTest
1567#endif
1568IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_TearDownTest) {
1569  ExtensionTestMessageListener first_loaded_listener("guest-loaded", false);
1570  const extensions::Extension* extension =
1571      LoadAndLaunchPlatformApp("web_view/teardown");
1572  ASSERT_TRUE(first_loaded_listener.WaitUntilSatisfied());
1573  apps::ShellWindow* window = NULL;
1574  if (!GetShellWindowCount())
1575    window = CreateShellWindow(extension);
1576  else
1577    window = GetFirstShellWindow();
1578  CloseShellWindow(window);
1579
1580  // Load the app again.
1581  ExtensionTestMessageListener second_loaded_listener("guest-loaded", false);
1582  LoadAndLaunchPlatformApp("web_view/teardown");
1583  ASSERT_TRUE(second_loaded_listener.WaitUntilSatisfied());
1584}
1585
1586// In following GeolocationAPIEmbedderHasNoAccess* tests, embedder (i.e. the
1587// platform app) does not have geolocation permission for this test.
1588// No matter what the API does, geolocation permission would be denied.
1589// Note that the test name prefix must be "GeolocationAPI".
1590IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationAPIEmbedderHasNoAccessAllow) {
1591  TestHelper("testDenyDenies",
1592             "web_view/geolocation/embedder_has_no_permission",
1593             NEEDS_TEST_SERVER);
1594}
1595
1596IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationAPIEmbedderHasNoAccessDeny) {
1597  TestHelper("testDenyDenies",
1598             "web_view/geolocation/embedder_has_no_permission",
1599             NEEDS_TEST_SERVER);
1600}
1601
1602// In following GeolocationAPIEmbedderHasAccess* tests, embedder (i.e. the
1603// platform app) has geolocation permission
1604//
1605// Note that these test names must be "GeolocationAPI" prefixed (b/c we mock out
1606// geolocation in this case).
1607//
1608// Also note that these are run separately because OverrideGeolocation() doesn't
1609// mock out geolocation for multiple navigator.geolocation calls properly and
1610// the tests become flaky.
1611// GeolocationAPI* test 1 of 3.
1612IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationAPIEmbedderHasAccessAllow) {
1613  TestHelper("testAllow",
1614             "web_view/geolocation/embedder_has_permission",
1615             NEEDS_TEST_SERVER);
1616}
1617
1618// GeolocationAPI* test 2 of 3.
1619IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationAPIEmbedderHasAccessDeny) {
1620  TestHelper("testDeny",
1621             "web_view/geolocation/embedder_has_permission",
1622             NEEDS_TEST_SERVER);
1623}
1624
1625// GeolocationAPI* test 3 of 3.
1626IN_PROC_BROWSER_TEST_F(WebViewTest,
1627                       GeolocationAPIEmbedderHasAccessMultipleBridgeIdAllow) {
1628  TestHelper("testMultipleBridgeIdAllow",
1629             "web_view/geolocation/embedder_has_permission",
1630             NEEDS_TEST_SERVER);
1631}
1632
1633// Tests that
1634// BrowserPluginGeolocationPermissionContext::CancelGeolocationPermissionRequest
1635// is handled correctly (and does not crash).
1636IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationAPICancelGeolocation) {
1637  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
1638  ASSERT_TRUE(RunPlatformAppTest(
1639        "platform_apps/web_view/geolocation/cancel_request")) << message_;
1640}
1641
1642IN_PROC_BROWSER_TEST_F(WebViewTest, DISABLED_GeolocationRequestGone) {
1643  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
1644  ASSERT_TRUE(RunPlatformAppTest(
1645        "platform_apps/web_view/geolocation/geolocation_request_gone"))
1646            << message_;
1647}
1648
1649IN_PROC_BROWSER_TEST_F(WebViewTest, ClearData) {
1650#if defined(OS_WIN)
1651  // Flaky on XP bot http://crbug.com/282674
1652  if (base::win::GetVersion() <= base::win::VERSION_XP)
1653    return;
1654#endif
1655
1656  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
1657  ASSERT_TRUE(RunPlatformAppTestWithArg(
1658      "platform_apps/web_view/common", "cleardata"))
1659          << message_;
1660}
1661
1662// This test is disabled on Win due to being flaky. http://crbug.com/294592
1663#if defined(OS_WIN)
1664#define MAYBE_ConsoleMessage DISABLED_ConsoleMessage
1665#else
1666#define MAYBE_ConsoleMessage ConsoleMessage
1667#endif
1668IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_ConsoleMessage) {
1669  ASSERT_TRUE(RunPlatformAppTestWithArg(
1670      "platform_apps/web_view/common", "console_messages"))
1671          << message_;
1672}
1673
1674IN_PROC_BROWSER_TEST_F(WebViewTest, DownloadPermission) {
1675  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
1676  content::WebContents* guest_web_contents =
1677      LoadGuest("/extensions/platform_apps/web_view/download/guest.html",
1678                "web_view/download");
1679  ASSERT_TRUE(guest_web_contents);
1680
1681  // Replace WebContentsDelegate with mock version so we can intercept download
1682  // requests.
1683  content::WebContentsDelegate* delegate = guest_web_contents->GetDelegate();
1684  MockDownloadWebContentsDelegate* mock_delegate =
1685      new MockDownloadWebContentsDelegate(delegate);
1686  guest_web_contents->SetDelegate(mock_delegate);
1687
1688  // Start test.
1689  // 1. Guest requests a download that its embedder denies.
1690  EXPECT_TRUE(content::ExecuteScript(guest_web_contents,
1691                                     "startDownload('download-link-1')"));
1692  mock_delegate->WaitForCanDownload(false); // Expect to not allow.
1693  mock_delegate->Reset();
1694
1695  // 2. Guest requests a download that its embedder allows.
1696  EXPECT_TRUE(content::ExecuteScript(guest_web_contents,
1697                                     "startDownload('download-link-2')"));
1698  mock_delegate->WaitForCanDownload(true); // Expect to allow.
1699  mock_delegate->Reset();
1700
1701  // 3. Guest requests a download that its embedder ignores, this implies deny.
1702  EXPECT_TRUE(content::ExecuteScript(guest_web_contents,
1703                                     "startDownload('download-link-3')"));
1704  mock_delegate->WaitForCanDownload(false); // Expect to not allow.
1705}
1706
1707// This test makes sure loading <webview> does not crash when there is an
1708// extension which has content script whitelisted/forced.
1709IN_PROC_BROWSER_TEST_F(WebViewTest, WhitelistedContentScript) {
1710  // Whitelist the extension for running content script we are going to load.
1711  extensions::ExtensionsClient::ScriptingWhitelist whitelist;
1712  const std::string extension_id = "imeongpbjoodlnmlakaldhlcmijmhpbb";
1713  whitelist.push_back(extension_id);
1714  extensions::ExtensionsClient::Get()->SetScriptingWhitelist(whitelist);
1715
1716  // Load the extension.
1717  const extensions::Extension* content_script_whitelisted_extension =
1718      LoadExtension(test_data_dir_.AppendASCII(
1719                        "platform_apps/web_view/extension_api/content_script"));
1720  ASSERT_TRUE(content_script_whitelisted_extension);
1721  ASSERT_EQ(extension_id, content_script_whitelisted_extension->id());
1722
1723  // Now load an app with <webview>.
1724  ExtensionTestMessageListener done_listener("TEST_PASSED", false);
1725  LoadAndLaunchPlatformApp("web_view/content_script_whitelisted");
1726  ASSERT_TRUE(done_listener.WaitUntilSatisfied());
1727}
1728
1729IN_PROC_BROWSER_TEST_F(WebViewTest, SetPropertyOnDocumentReady) {
1730  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/document_ready"))
1731                  << message_;
1732}
1733
1734IN_PROC_BROWSER_TEST_F(WebViewTest, SetPropertyOnDocumentInteractive) {
1735  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/document_interactive"))
1736                  << message_;
1737}
1738
1739IN_PROC_BROWSER_TEST_F(WebViewTest, SpeechRecognitionAPI_HasPermissionAllow) {
1740  ASSERT_TRUE(
1741      RunPlatformAppTestWithArg("platform_apps/web_view/speech_recognition_api",
1742                                "allowTest"))
1743          << message_;
1744}
1745
1746IN_PROC_BROWSER_TEST_F(WebViewTest, SpeechRecognitionAPI_HasPermissionDeny) {
1747  ASSERT_TRUE(
1748      RunPlatformAppTestWithArg("platform_apps/web_view/speech_recognition_api",
1749                                "denyTest"))
1750          << message_;
1751}
1752
1753IN_PROC_BROWSER_TEST_F(WebViewTest, SpeechRecognitionAPI_NoPermission) {
1754  ASSERT_TRUE(
1755      RunPlatformAppTestWithArg("platform_apps/web_view/common",
1756                                "speech_recognition_api_no_permission"))
1757          << message_;
1758}
1759
1760// Tests overriding user agent.
1761IN_PROC_BROWSER_TEST_F(WebViewTest, UserAgent) {
1762  ASSERT_TRUE(RunPlatformAppTestWithArg(
1763              "platform_apps/web_view/common", "useragent")) << message_;
1764}
1765
1766IN_PROC_BROWSER_TEST_F(WebViewTest, UserAgent_NewWindow) {
1767  ASSERT_TRUE(RunPlatformAppTestWithArg(
1768              "platform_apps/web_view/common",
1769              "useragent_newwindow")) << message_;
1770}
1771
1772IN_PROC_BROWSER_TEST_F(WebViewTest, NoPermission) {
1773  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/nopermission"))
1774                  << message_;
1775}
1776
1777IN_PROC_BROWSER_TEST_F(WebViewTest, Dialog_TestAlertDialog) {
1778  TestHelper("testAlertDialog", "web_view/dialog", NO_TEST_SERVER);
1779}
1780
1781// Fails on official Windows and Linux builds. See http://crbug.com/313868
1782#if defined(GOOGLE_CHROME_BUILD) && (defined(OS_WIN) || defined(OS_LINUX))
1783#define MAYBE_Dialog_TestConfirmDialog DISABLED_Dialog_TestConfirmDialog
1784#else
1785#define MAYBE_Dialog_TestConfirmDialog Dialog_TestConfirmDialog
1786#endif
1787IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_Dialog_TestConfirmDialog) {
1788  TestHelper("testConfirmDialog", "web_view/dialog", NO_TEST_SERVER);
1789}
1790
1791IN_PROC_BROWSER_TEST_F(WebViewTest, Dialog_TestConfirmDialogCancel) {
1792  TestHelper("testConfirmDialogCancel", "web_view/dialog", NO_TEST_SERVER);
1793}
1794
1795IN_PROC_BROWSER_TEST_F(WebViewTest, Dialog_TestConfirmDialogDefaultCancel) {
1796  TestHelper("testConfirmDialogDefaultCancel",
1797             "web_view/dialog",
1798             NO_TEST_SERVER);
1799}
1800
1801IN_PROC_BROWSER_TEST_F(WebViewTest, Dialog_TestConfirmDialogDefaultGCCancel) {
1802  TestHelper("testConfirmDialogDefaultGCCancel",
1803             "web_view/dialog",
1804             NO_TEST_SERVER);
1805}
1806
1807// Fails on official Windows and Linux builds. See http://crbug.com/313868
1808#if defined(GOOGLE_CHROME_BUILD) && (defined(OS_WIN) || defined(OS_LINUX))
1809#define MAYBE_Dialog_TestPromptDialog DISABLED_Dialog_TestPromptDialog
1810#else
1811#define MAYBE_Dialog_TestPromptDialog Dialog_TestPromptDialog
1812#endif
1813IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_Dialog_TestPromptDialog) {
1814  TestHelper("testPromptDialog", "web_view/dialog", NO_TEST_SERVER);
1815}
1816
1817IN_PROC_BROWSER_TEST_F(WebViewTest, NoContentSettingsAPI) {
1818  // Load the extension.
1819  const extensions::Extension* content_settings_extension =
1820      LoadExtension(
1821          test_data_dir_.AppendASCII(
1822              "platform_apps/web_view/extension_api/content_settings"));
1823  ASSERT_TRUE(content_settings_extension);
1824  TestHelper("testPostMessageCommChannel", "web_view/shim", NO_TEST_SERVER);
1825}
1826
1827#if defined(ENABLE_PLUGINS)
1828class WebViewPluginTest : public WebViewTest {
1829 protected:
1830  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1831    WebViewTest::SetUpCommandLine(command_line);
1832
1833    // Append the switch to register the pepper plugin.
1834    // library name = <out dir>/<test_name>.<library_extension>
1835    // MIME type = application/x-ppapi-<test_name>
1836    base::FilePath plugin_dir;
1837    EXPECT_TRUE(PathService::Get(base::DIR_MODULE, &plugin_dir));
1838
1839    base::FilePath plugin_lib = plugin_dir.Append(library_name);
1840    EXPECT_TRUE(base::PathExists(plugin_lib));
1841    base::FilePath::StringType pepper_plugin = plugin_lib.value();
1842    pepper_plugin.append(FILE_PATH_LITERAL(";application/x-ppapi-tests"));
1843    command_line->AppendSwitchNative(switches::kRegisterPepperPlugins,
1844                                     pepper_plugin);
1845  }
1846};
1847
1848IN_PROC_BROWSER_TEST_F(WebViewPluginTest, TestLoadPluginEvent) {
1849  TestHelper("testPluginLoadPermission", "web_view/shim", NO_TEST_SERVER);
1850}
1851#endif  // defined(ENABLE_PLUGINS)
1852
1853// Taking a screenshot does not work with threaded compositing, so disable
1854// threaded compositing for this test (http://crbug.com/326756).
1855class WebViewCaptureTest : public WebViewTest,
1856  public testing::WithParamInterface<std::string> {
1857 public:
1858  WebViewCaptureTest() {}
1859  virtual ~WebViewCaptureTest() {}
1860  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1861    command_line->AppendSwitch(GetParam());
1862    // http://crbug.com/327035
1863    command_line->AppendSwitch(switches::kDisableDelegatedRenderer);
1864    WebViewTest::SetUpCommandLine(command_line);
1865  }
1866};
1867
1868IN_PROC_BROWSER_TEST_P(WebViewCaptureTest,
1869                       Shim_ScreenshotCapture) {
1870  TestHelper("testScreenshotCapture", "web_view/shim", NO_TEST_SERVER);
1871}
1872
1873INSTANTIATE_TEST_CASE_P(WithoutThreadedCompositor,
1874    WebViewCaptureTest,
1875    ::testing::Values(std::string(switches::kDisableThreadedCompositing)));
1876
1877// http://crbug.com/171744
1878#if !defined(OS_MACOSX)
1879INSTANTIATE_TEST_CASE_P(WithThreadedCompositor,
1880    WebViewCaptureTest,
1881    ::testing::Values(std::string(switches::kEnableThreadedCompositing)));
1882#endif
1883