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 "base/path_service.h"
6#include "base/strings/stringprintf.h"
7#include "base/strings/utf_string_conversions.h"
8#include "chrome/browser/apps/app_browsertest_util.h"
9#include "chrome/browser/chrome_content_browser_client.h"
10#include "chrome/browser/prerender/prerender_link_manager.h"
11#include "chrome/browser/prerender/prerender_link_manager_factory.h"
12#include "chrome/browser/profiles/profile.h"
13#include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
14#include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
15#include "chrome/browser/task_manager/task_manager_browsertest_util.h"
16#include "chrome/browser/ui/browser.h"
17#include "chrome/browser/ui/browser_dialogs.h"
18#include "chrome/browser/ui/tabs/tab_strip_model.h"
19#include "chrome/test/base/ui_test_utils.h"
20#include "content/public/browser/gpu_data_manager.h"
21#include "content/public/browser/interstitial_page.h"
22#include "content/public/browser/interstitial_page_delegate.h"
23#include "content/public/browser/notification_service.h"
24#include "content/public/browser/render_process_host.h"
25#include "content/public/browser/web_contents_delegate.h"
26#include "content/public/common/content_switches.h"
27#include "content/public/test/browser_test_utils.h"
28#include "content/public/test/fake_speech_recognition_manager.h"
29#include "content/public/test/test_renderer_host.h"
30#include "extensions/browser/app_window/native_app_window.h"
31#include "extensions/browser/guest_view/guest_view_manager.h"
32#include "extensions/browser/guest_view/guest_view_manager_factory.h"
33#include "extensions/browser/guest_view/web_view/test_guest_view_manager.h"
34#include "extensions/common/extension.h"
35#include "extensions/common/extensions_client.h"
36#include "extensions/test/extension_test_message_listener.h"
37#include "media/base/media_switches.h"
38#include "net/test/embedded_test_server/embedded_test_server.h"
39#include "net/test/embedded_test_server/http_request.h"
40#include "net/test/embedded_test_server/http_response.h"
41#include "ui/gfx/switches.h"
42#include "ui/gl/gl_switches.h"
43
44#if defined(OS_CHROMEOS)
45#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
46#include "chrome/browser/chromeos/accessibility/speech_monitor.h"
47#endif
48
49// For fine-grained suppression on flaky tests.
50#if defined(OS_WIN)
51#include "base/win/windows_version.h"
52#endif
53
54using extensions::ContextMenuMatcher;
55using extensions::MenuItem;
56using prerender::PrerenderLinkManager;
57using prerender::PrerenderLinkManagerFactory;
58using task_manager::browsertest_util::MatchAboutBlankTab;
59using task_manager::browsertest_util::MatchAnyApp;
60using task_manager::browsertest_util::MatchAnyBackground;
61using task_manager::browsertest_util::MatchAnyTab;
62using task_manager::browsertest_util::MatchAnyWebView;
63using task_manager::browsertest_util::MatchApp;
64using task_manager::browsertest_util::MatchBackground;
65using task_manager::browsertest_util::MatchWebView;
66using task_manager::browsertest_util::WaitForTaskManagerRows;
67using ui::MenuModel;
68
69namespace {
70const char kEmptyResponsePath[] = "/close-socket";
71const char kRedirectResponsePath[] = "/server-redirect";
72const char kRedirectResponseFullPath[] =
73    "/extensions/platform_apps/web_view/shim/guest_redirect.html";
74
75// Platform-specific filename relative to the chrome executable.
76#if defined(OS_WIN)
77const wchar_t library_name[] = L"ppapi_tests.dll";
78#elif defined(OS_MACOSX)
79const char library_name[] = "ppapi_tests.plugin";
80#elif defined(OS_POSIX)
81const char library_name[] = "libppapi_tests.so";
82#endif
83
84class EmptyHttpResponse : public net::test_server::HttpResponse {
85 public:
86  virtual std::string ToResponseString() const OVERRIDE {
87    return std::string();
88  }
89};
90
91class TestInterstitialPageDelegate : public content::InterstitialPageDelegate {
92 public:
93  TestInterstitialPageDelegate() {
94  }
95  virtual ~TestInterstitialPageDelegate() {}
96  virtual std::string GetHTMLContents() OVERRIDE { return std::string(); }
97};
98
99class WebContentsHiddenObserver : public content::WebContentsObserver {
100 public:
101  WebContentsHiddenObserver(content::WebContents* web_contents,
102                            const base::Closure& hidden_callback)
103      : WebContentsObserver(web_contents),
104        hidden_callback_(hidden_callback),
105        hidden_observed_(false) {
106  }
107
108  // WebContentsObserver.
109  virtual void WasHidden() OVERRIDE {
110    hidden_observed_ = true;
111    hidden_callback_.Run();
112  }
113
114  bool hidden_observed() { return hidden_observed_; }
115
116 private:
117  base::Closure hidden_callback_;
118  bool hidden_observed_;
119
120  DISALLOW_COPY_AND_ASSIGN(WebContentsHiddenObserver);
121};
122
123class InterstitialObserver : public content::WebContentsObserver {
124 public:
125  InterstitialObserver(content::WebContents* web_contents,
126                       const base::Closure& attach_callback,
127                       const base::Closure& detach_callback)
128      : WebContentsObserver(web_contents),
129        attach_callback_(attach_callback),
130        detach_callback_(detach_callback) {
131  }
132
133  virtual void DidAttachInterstitialPage() OVERRIDE {
134    attach_callback_.Run();
135  }
136
137  virtual void DidDetachInterstitialPage() OVERRIDE {
138    detach_callback_.Run();
139  }
140
141 private:
142  base::Closure attach_callback_;
143  base::Closure detach_callback_;
144
145  DISALLOW_COPY_AND_ASSIGN(InterstitialObserver);
146};
147
148void ExecuteScriptWaitForTitle(content::WebContents* web_contents,
149                               const char* script,
150                               const char* title) {
151  base::string16 expected_title(base::ASCIIToUTF16(title));
152  base::string16 error_title(base::ASCIIToUTF16("error"));
153
154  content::TitleWatcher title_watcher(web_contents, expected_title);
155  title_watcher.AlsoWaitForTitle(error_title);
156  EXPECT_TRUE(content::ExecuteScript(web_contents, script));
157  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
158}
159
160}  // namespace
161
162// This class intercepts media access request from the embedder. The request
163// should be triggered only if the embedder API (from tests) allows the request
164// in Javascript.
165// We do not issue the actual media request; the fact that the request reached
166// embedder's WebContents is good enough for our tests. This is also to make
167// the test run successfully on trybots.
168class MockWebContentsDelegate : public content::WebContentsDelegate {
169 public:
170  MockWebContentsDelegate() : requested_(false) {}
171  virtual ~MockWebContentsDelegate() {}
172
173  virtual void RequestMediaAccessPermission(
174      content::WebContents* web_contents,
175      const content::MediaStreamRequest& request,
176      const content::MediaResponseCallback& callback) OVERRIDE {
177    requested_ = true;
178    if (message_loop_runner_.get())
179      message_loop_runner_->Quit();
180  }
181
182  void WaitForSetMediaPermission() {
183    if (requested_)
184      return;
185    message_loop_runner_ = new content::MessageLoopRunner;
186    message_loop_runner_->Run();
187  }
188
189 private:
190  bool requested_;
191  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
192
193  DISALLOW_COPY_AND_ASSIGN(MockWebContentsDelegate);
194};
195
196// This class intercepts download request from the guest.
197class MockDownloadWebContentsDelegate : public content::WebContentsDelegate {
198 public:
199  explicit MockDownloadWebContentsDelegate(
200      content::WebContentsDelegate* orig_delegate)
201      : orig_delegate_(orig_delegate),
202        waiting_for_decision_(false),
203        expect_allow_(false),
204        decision_made_(false),
205        last_download_allowed_(false) {}
206  virtual ~MockDownloadWebContentsDelegate() {}
207
208  virtual void CanDownload(
209      content::RenderViewHost* render_view_host,
210      const GURL& url,
211      const std::string& request_method,
212      const base::Callback<void(bool)>& callback) OVERRIDE {
213    orig_delegate_->CanDownload(
214        render_view_host, url, request_method,
215        base::Bind(&MockDownloadWebContentsDelegate::DownloadDecided,
216                   base::Unretained(this)));
217  }
218
219  void WaitForCanDownload(bool expect_allow) {
220    EXPECT_FALSE(waiting_for_decision_);
221    waiting_for_decision_ = true;
222
223    if (decision_made_) {
224      EXPECT_EQ(expect_allow, last_download_allowed_);
225      return;
226    }
227
228    expect_allow_ = expect_allow;
229    message_loop_runner_ = new content::MessageLoopRunner;
230    message_loop_runner_->Run();
231  }
232
233  void DownloadDecided(bool allow) {
234    EXPECT_FALSE(decision_made_);
235    decision_made_ = true;
236
237    if (waiting_for_decision_) {
238      EXPECT_EQ(expect_allow_, allow);
239      if (message_loop_runner_.get())
240        message_loop_runner_->Quit();
241      return;
242    }
243    last_download_allowed_ = allow;
244  }
245
246  void Reset() {
247    waiting_for_decision_ = false;
248    decision_made_ = false;
249  }
250
251 private:
252  content::WebContentsDelegate* orig_delegate_;
253  bool waiting_for_decision_;
254  bool expect_allow_;
255  bool decision_made_;
256  bool last_download_allowed_;
257  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
258
259  DISALLOW_COPY_AND_ASSIGN(MockDownloadWebContentsDelegate);
260};
261
262class WebViewTest : public extensions::PlatformAppBrowserTest {
263 protected:
264  virtual void SetUp() OVERRIDE {
265    if (UsesFakeSpeech()) {
266      // SpeechRecognition test specific SetUp.
267      fake_speech_recognition_manager_.reset(
268          new content::FakeSpeechRecognitionManager());
269      fake_speech_recognition_manager_->set_should_send_fake_response(true);
270      // Inject the fake manager factory so that the test result is returned to
271      // the web page.
272      content::SpeechRecognitionManager::SetManagerForTesting(
273          fake_speech_recognition_manager_.get());
274    }
275    extensions::PlatformAppBrowserTest::SetUp();
276  }
277
278  virtual void TearDown() OVERRIDE {
279    if (UsesFakeSpeech()) {
280      // SpeechRecognition test specific TearDown.
281      content::SpeechRecognitionManager::SetManagerForTesting(NULL);
282    }
283
284    extensions::PlatformAppBrowserTest::TearDown();
285  }
286
287  virtual void SetUpOnMainThread() OVERRIDE {
288    extensions::PlatformAppBrowserTest::SetUpOnMainThread();
289    const testing::TestInfo* const test_info =
290        testing::UnitTest::GetInstance()->current_test_info();
291    // Mock out geolocation for geolocation specific tests.
292    if (!strncmp(test_info->name(), "GeolocationAPI",
293            strlen("GeolocationAPI"))) {
294      ui_test_utils::OverrideGeolocation(10, 20);
295    }
296  }
297
298  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
299    command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
300    command_line->AppendSwitchASCII(switches::kJavaScriptFlags, "--expose-gc");
301
302    extensions::PlatformAppBrowserTest::SetUpCommandLine(command_line);
303  }
304
305  // This method is responsible for initializing a packaged app, which contains
306  // multiple webview tags. The tags have different partition identifiers and
307  // their WebContent objects are returned as output. The method also verifies
308  // the expected process allocation and storage partition assignment.
309  // The |navigate_to_url| parameter is used to navigate the main browser
310  // window.
311  //
312  // TODO(ajwong): This function is getting to be too large. Either refactor it
313  // so the test can specify a configuration of WebView tags that we will
314  // dynamically inject JS to generate, or move this test wholesale into
315  // something that RunPlatformAppTest() can execute purely in Javascript. This
316  // won't let us do a white-box examination of the StoragePartition equivalence
317  // directly, but we will be able to view the black box effects which is good
318  // enough.  http://crbug.com/160361
319  void NavigateAndOpenAppForIsolation(
320      GURL navigate_to_url,
321      content::WebContents** default_tag_contents1,
322      content::WebContents** default_tag_contents2,
323      content::WebContents** named_partition_contents1,
324      content::WebContents** named_partition_contents2,
325      content::WebContents** persistent_partition_contents1,
326      content::WebContents** persistent_partition_contents2,
327      content::WebContents** persistent_partition_contents3) {
328    GURL::Replacements replace_host;
329    std::string host_str("localhost");  // Must stay in scope with replace_host.
330    replace_host.SetHostStr(host_str);
331
332    navigate_to_url = navigate_to_url.ReplaceComponents(replace_host);
333
334    GURL tag_url1 = embedded_test_server()->GetURL(
335        "/extensions/platform_apps/web_view/isolation/cookie.html");
336    tag_url1 = tag_url1.ReplaceComponents(replace_host);
337    GURL tag_url2 = embedded_test_server()->GetURL(
338        "/extensions/platform_apps/web_view/isolation/cookie2.html");
339    tag_url2 = tag_url2.ReplaceComponents(replace_host);
340    GURL tag_url3 = embedded_test_server()->GetURL(
341        "/extensions/platform_apps/web_view/isolation/storage1.html");
342    tag_url3 = tag_url3.ReplaceComponents(replace_host);
343    GURL tag_url4 = embedded_test_server()->GetURL(
344        "/extensions/platform_apps/web_view/isolation/storage2.html");
345    tag_url4 = tag_url4.ReplaceComponents(replace_host);
346    GURL tag_url5 = embedded_test_server()->GetURL(
347        "/extensions/platform_apps/web_view/isolation/storage1.html#p1");
348    tag_url5 = tag_url5.ReplaceComponents(replace_host);
349    GURL tag_url6 = embedded_test_server()->GetURL(
350        "/extensions/platform_apps/web_view/isolation/storage1.html#p2");
351    tag_url6 = tag_url6.ReplaceComponents(replace_host);
352    GURL tag_url7 = embedded_test_server()->GetURL(
353        "/extensions/platform_apps/web_view/isolation/storage1.html#p3");
354    tag_url7 = tag_url7.ReplaceComponents(replace_host);
355
356    ui_test_utils::NavigateToURLWithDisposition(
357        browser(), navigate_to_url, CURRENT_TAB,
358        ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
359
360    ui_test_utils::UrlLoadObserver observer1(
361        tag_url1, content::NotificationService::AllSources());
362    ui_test_utils::UrlLoadObserver observer2(
363        tag_url2, content::NotificationService::AllSources());
364    ui_test_utils::UrlLoadObserver observer3(
365        tag_url3, content::NotificationService::AllSources());
366    ui_test_utils::UrlLoadObserver observer4(
367        tag_url4, content::NotificationService::AllSources());
368    ui_test_utils::UrlLoadObserver observer5(
369        tag_url5, content::NotificationService::AllSources());
370    ui_test_utils::UrlLoadObserver observer6(
371        tag_url6, content::NotificationService::AllSources());
372    ui_test_utils::UrlLoadObserver observer7(
373        tag_url7, content::NotificationService::AllSources());
374    LoadAndLaunchPlatformApp("web_view/isolation", "Launched");
375    observer1.Wait();
376    observer2.Wait();
377    observer3.Wait();
378    observer4.Wait();
379    observer5.Wait();
380    observer6.Wait();
381    observer7.Wait();
382
383    content::Source<content::NavigationController> source1 = observer1.source();
384    EXPECT_TRUE(source1->GetWebContents()->GetRenderProcessHost()->
385        IsIsolatedGuest());
386    content::Source<content::NavigationController> source2 = observer2.source();
387    EXPECT_TRUE(source2->GetWebContents()->GetRenderProcessHost()->
388        IsIsolatedGuest());
389    content::Source<content::NavigationController> source3 = observer3.source();
390    EXPECT_TRUE(source3->GetWebContents()->GetRenderProcessHost()->
391        IsIsolatedGuest());
392    content::Source<content::NavigationController> source4 = observer4.source();
393    EXPECT_TRUE(source4->GetWebContents()->GetRenderProcessHost()->
394        IsIsolatedGuest());
395    content::Source<content::NavigationController> source5 = observer5.source();
396    EXPECT_TRUE(source5->GetWebContents()->GetRenderProcessHost()->
397        IsIsolatedGuest());
398    content::Source<content::NavigationController> source6 = observer6.source();
399    EXPECT_TRUE(source6->GetWebContents()->GetRenderProcessHost()->
400        IsIsolatedGuest());
401    content::Source<content::NavigationController> source7 = observer7.source();
402    EXPECT_TRUE(source7->GetWebContents()->GetRenderProcessHost()->
403        IsIsolatedGuest());
404
405    // Check that the first two tags use the same process and it is different
406    // than the process used by the other two.
407    EXPECT_EQ(source1->GetWebContents()->GetRenderProcessHost()->GetID(),
408              source2->GetWebContents()->GetRenderProcessHost()->GetID());
409    EXPECT_EQ(source3->GetWebContents()->GetRenderProcessHost()->GetID(),
410              source4->GetWebContents()->GetRenderProcessHost()->GetID());
411    EXPECT_NE(source1->GetWebContents()->GetRenderProcessHost()->GetID(),
412              source3->GetWebContents()->GetRenderProcessHost()->GetID());
413
414    // The two sets of tags should also be isolated from the main browser.
415    EXPECT_NE(source1->GetWebContents()->GetRenderProcessHost()->GetID(),
416              browser()->tab_strip_model()->GetWebContentsAt(0)->
417                  GetRenderProcessHost()->GetID());
418    EXPECT_NE(source3->GetWebContents()->GetRenderProcessHost()->GetID(),
419              browser()->tab_strip_model()->GetWebContentsAt(0)->
420                  GetRenderProcessHost()->GetID());
421
422    // Check that the storage partitions of the first two tags match and are
423    // different than the other two.
424    EXPECT_EQ(
425        source1->GetWebContents()->GetRenderProcessHost()->
426            GetStoragePartition(),
427        source2->GetWebContents()->GetRenderProcessHost()->
428            GetStoragePartition());
429    EXPECT_EQ(
430        source3->GetWebContents()->GetRenderProcessHost()->
431            GetStoragePartition(),
432        source4->GetWebContents()->GetRenderProcessHost()->
433            GetStoragePartition());
434    EXPECT_NE(
435        source1->GetWebContents()->GetRenderProcessHost()->
436            GetStoragePartition(),
437        source3->GetWebContents()->GetRenderProcessHost()->
438            GetStoragePartition());
439
440    // Ensure the persistent storage partitions are different.
441    EXPECT_EQ(
442        source5->GetWebContents()->GetRenderProcessHost()->
443            GetStoragePartition(),
444        source6->GetWebContents()->GetRenderProcessHost()->
445            GetStoragePartition());
446    EXPECT_NE(
447        source5->GetWebContents()->GetRenderProcessHost()->
448            GetStoragePartition(),
449        source7->GetWebContents()->GetRenderProcessHost()->
450            GetStoragePartition());
451    EXPECT_NE(
452        source1->GetWebContents()->GetRenderProcessHost()->
453            GetStoragePartition(),
454        source5->GetWebContents()->GetRenderProcessHost()->
455            GetStoragePartition());
456    EXPECT_NE(
457        source1->GetWebContents()->GetRenderProcessHost()->
458            GetStoragePartition(),
459        source7->GetWebContents()->GetRenderProcessHost()->
460            GetStoragePartition());
461
462    *default_tag_contents1 = source1->GetWebContents();
463    *default_tag_contents2 = source2->GetWebContents();
464    *named_partition_contents1 = source3->GetWebContents();
465    *named_partition_contents2 = source4->GetWebContents();
466    if (persistent_partition_contents1) {
467      *persistent_partition_contents1 = source5->GetWebContents();
468    }
469    if (persistent_partition_contents2) {
470      *persistent_partition_contents2 = source6->GetWebContents();
471    }
472    if (persistent_partition_contents3) {
473      *persistent_partition_contents3 = source7->GetWebContents();
474    }
475  }
476
477  // Handles |request| by serving a redirect response.
478  static scoped_ptr<net::test_server::HttpResponse> RedirectResponseHandler(
479      const std::string& path,
480      const GURL& redirect_target,
481      const net::test_server::HttpRequest& request) {
482    if (!StartsWithASCII(path, request.relative_url, true))
483      return scoped_ptr<net::test_server::HttpResponse>();
484
485    scoped_ptr<net::test_server::BasicHttpResponse> http_response(
486        new net::test_server::BasicHttpResponse);
487    http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
488    http_response->AddCustomHeader("Location", redirect_target.spec());
489    return http_response.PassAs<net::test_server::HttpResponse>();
490  }
491
492  // Handles |request| by serving an empty response.
493  static scoped_ptr<net::test_server::HttpResponse> EmptyResponseHandler(
494      const std::string& path,
495      const net::test_server::HttpRequest& request) {
496    if (StartsWithASCII(path, request.relative_url, true)) {
497      return scoped_ptr<net::test_server::HttpResponse>(
498          new EmptyHttpResponse);
499    }
500
501    return scoped_ptr<net::test_server::HttpResponse>();
502  }
503
504  // Shortcut to return the current MenuManager.
505  extensions::MenuManager* menu_manager() {
506    return extensions::MenuManager::Get(browser()->profile());
507  }
508
509  // This gets all the items that any extension has registered for possible
510  // inclusion in context menus.
511  MenuItem::List GetItems() {
512    MenuItem::List result;
513    std::set<MenuItem::ExtensionKey> extension_ids =
514        menu_manager()->ExtensionIds();
515    std::set<MenuItem::ExtensionKey>::iterator i;
516    for (i = extension_ids.begin(); i != extension_ids.end(); ++i) {
517      const MenuItem::List* list = menu_manager()->MenuItems(*i);
518      result.insert(result.end(), list->begin(), list->end());
519    }
520    return result;
521  }
522
523  enum TestServer {
524    NEEDS_TEST_SERVER,
525    NO_TEST_SERVER
526  };
527
528  void TestHelper(const std::string& test_name,
529                  const std::string& app_location,
530                  TestServer test_server) {
531    // For serving guest pages.
532    if (test_server == NEEDS_TEST_SERVER) {
533      if (!StartEmbeddedTestServer()) {
534        LOG(ERROR) << "FAILED TO START TEST SERVER.";
535        return;
536      }
537      embedded_test_server()->RegisterRequestHandler(
538          base::Bind(&WebViewTest::RedirectResponseHandler,
539                    kRedirectResponsePath,
540                    embedded_test_server()->GetURL(kRedirectResponseFullPath)));
541
542      embedded_test_server()->RegisterRequestHandler(
543          base::Bind(&WebViewTest::EmptyResponseHandler, kEmptyResponsePath));
544    }
545
546    LoadAndLaunchPlatformApp(app_location.c_str(), "Launched");
547
548    // Flush any pending events to make sure we start with a clean slate.
549    content::RunAllPendingInMessageLoop();
550
551    content::WebContents* embedder_web_contents =
552        GetFirstAppWindowWebContents();
553    if (!embedder_web_contents) {
554      LOG(ERROR) << "UNABLE TO FIND EMBEDDER WEB CONTENTS.";
555      return;
556    }
557
558    ExtensionTestMessageListener done_listener("TEST_PASSED", false);
559    done_listener.set_failure_message("TEST_FAILED");
560    if (!content::ExecuteScript(
561            embedder_web_contents,
562            base::StringPrintf("runTest('%s')", test_name.c_str()))) {
563      LOG(ERROR) << "UNABLE TO START TEST.";
564      return;
565    }
566    ASSERT_TRUE(done_listener.WaitUntilSatisfied());
567  }
568
569  content::WebContents* LoadGuest(const std::string& guest_path,
570                                  const std::string& app_path) {
571    GURL::Replacements replace_host;
572    std::string host_str("localhost");  // Must stay in scope with replace_host.
573    replace_host.SetHostStr(host_str);
574
575    GURL guest_url = embedded_test_server()->GetURL(guest_path);
576    guest_url = guest_url.ReplaceComponents(replace_host);
577
578    ui_test_utils::UrlLoadObserver guest_observer(
579        guest_url, content::NotificationService::AllSources());
580
581    LoadAndLaunchPlatformApp(app_path.c_str(), "guest-loaded");
582
583    guest_observer.Wait();
584    content::Source<content::NavigationController> source =
585        guest_observer.source();
586    EXPECT_TRUE(source->GetWebContents()->GetRenderProcessHost()->
587        IsIsolatedGuest());
588
589    content::WebContents* guest_web_contents = source->GetWebContents();
590    return guest_web_contents;
591  }
592
593  // Runs media_access/allow tests.
594  void MediaAccessAPIAllowTestHelper(const std::string& test_name);
595
596  // Runs media_access/deny tests, each of them are run separately otherwise
597  // they timeout (mostly on Windows).
598  void MediaAccessAPIDenyTestHelper(const std::string& test_name) {
599    ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
600    LoadAndLaunchPlatformApp("web_view/media_access/deny", "loaded");
601
602    content::WebContents* embedder_web_contents =
603        GetFirstAppWindowWebContents();
604    ASSERT_TRUE(embedder_web_contents);
605
606    ExtensionTestMessageListener test_run_listener("PASSED", false);
607    test_run_listener.set_failure_message("FAILED");
608    EXPECT_TRUE(
609        content::ExecuteScript(
610            embedder_web_contents,
611            base::StringPrintf("startDenyTest('%s')", test_name.c_str())));
612    ASSERT_TRUE(test_run_listener.WaitUntilSatisfied());
613  }
614
615  void WaitForInterstitial(content::WebContents* web_contents) {
616    scoped_refptr<content::MessageLoopRunner> loop_runner(
617        new content::MessageLoopRunner);
618    InterstitialObserver observer(web_contents,
619                                  loop_runner->QuitClosure(),
620                                  base::Closure());
621    if (!content::InterstitialPage::GetInterstitialPage(web_contents))
622      loop_runner->Run();
623  }
624
625  void LoadAppWithGuest(const std::string& app_path) {
626    ExtensionTestMessageListener launched_listener("WebViewTest.LAUNCHED",
627                                                   false);
628    launched_listener.set_failure_message("WebViewTest.FAILURE");
629    LoadAndLaunchPlatformApp(app_path.c_str(), &launched_listener);
630
631    guest_web_contents_ = GetGuestViewManager()->WaitForGuestCreated();
632  }
633
634  void SendMessageToEmbedder(const std::string& message) {
635    EXPECT_TRUE(
636        content::ExecuteScript(
637            GetEmbedderWebContents(),
638            base::StringPrintf("onAppCommand('%s');", message.c_str())));
639  }
640
641  void SendMessageToGuestAndWait(const std::string& message,
642                                 const std::string& wait_message) {
643    scoped_ptr<ExtensionTestMessageListener> listener;
644    if (!wait_message.empty()) {
645      listener.reset(new ExtensionTestMessageListener(wait_message, false));
646    }
647
648    EXPECT_TRUE(
649        content::ExecuteScript(
650            GetGuestWebContents(),
651            base::StringPrintf("onAppCommand('%s');", message.c_str())));
652
653    if (listener) {
654      ASSERT_TRUE(listener->WaitUntilSatisfied());
655    }
656  }
657
658  content::WebContents* GetGuestWebContents() {
659    return guest_web_contents_;
660  }
661
662  content::WebContents* GetEmbedderWebContents() {
663    if (!embedder_web_contents_) {
664      embedder_web_contents_ = GetFirstAppWindowWebContents();
665    }
666    return embedder_web_contents_;
667  }
668
669  extensions::TestGuestViewManager* GetGuestViewManager() {
670    return static_cast<extensions::TestGuestViewManager*>(
671        extensions::TestGuestViewManager::FromBrowserContext(
672            browser()->profile()));
673  }
674
675  WebViewTest() : guest_web_contents_(NULL),
676                  embedder_web_contents_(NULL) {
677    extensions::GuestViewManager::set_factory_for_testing(&factory_);
678  }
679
680 private:
681  bool UsesFakeSpeech() {
682    const testing::TestInfo* const test_info =
683        testing::UnitTest::GetInstance()->current_test_info();
684
685    // SpeechRecognition test specific SetUp.
686    return !strcmp(test_info->name(),
687                   "SpeechRecognitionAPI_HasPermissionAllow");
688  }
689
690  scoped_ptr<content::FakeSpeechRecognitionManager>
691      fake_speech_recognition_manager_;
692
693  extensions::TestGuestViewManagerFactory factory_;
694  // Note that these are only set if you launch app using LoadAppWithGuest().
695  content::WebContents* guest_web_contents_;
696  content::WebContents* embedder_web_contents_;
697};
698
699class WebViewDPITest : public WebViewTest {
700 protected:
701  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
702    WebViewTest::SetUpCommandLine(command_line);
703    command_line->AppendSwitchASCII(switches::kForceDeviceScaleFactor,
704                                    base::StringPrintf("%f", scale()));
705  }
706
707  static float scale() { return 2.0f; }
708};
709
710// This test verifies that hiding the guest triggers WebContents::WasHidden().
711IN_PROC_BROWSER_TEST_F(WebViewTest, GuestVisibilityChanged) {
712  LoadAppWithGuest("web_view/visibility_changed");
713
714  scoped_refptr<content::MessageLoopRunner> loop_runner(
715      new content::MessageLoopRunner);
716  WebContentsHiddenObserver observer(GetGuestWebContents(),
717                                     loop_runner->QuitClosure());
718
719  // Handled in platform_apps/web_view/visibility_changed/main.js
720  SendMessageToEmbedder("hide-guest");
721  if (!observer.hidden_observed())
722    loop_runner->Run();
723}
724
725// This test verifies that hiding the embedder also hides the guest.
726IN_PROC_BROWSER_TEST_F(WebViewTest, EmbedderVisibilityChanged) {
727  LoadAppWithGuest("web_view/visibility_changed");
728
729  scoped_refptr<content::MessageLoopRunner> loop_runner(
730      new content::MessageLoopRunner);
731  WebContentsHiddenObserver observer(GetGuestWebContents(),
732                                     loop_runner->QuitClosure());
733
734  // Handled in platform_apps/web_view/visibility_changed/main.js
735  SendMessageToEmbedder("hide-embedder");
736  if (!observer.hidden_observed())
737    loop_runner->Run();
738}
739
740// This test verifies that reloading the embedder reloads the guest (and doest
741// not crash).
742IN_PROC_BROWSER_TEST_F(WebViewTest, ReloadEmbedder) {
743  // Just load a guest from other test, we do not want to add a separate
744  // platform_app for this test.
745  LoadAppWithGuest("web_view/visibility_changed");
746
747  ExtensionTestMessageListener launched_again_listener("WebViewTest.LAUNCHED",
748                                                       false);
749  GetEmbedderWebContents()->GetController().Reload(false);
750  ASSERT_TRUE(launched_again_listener.WaitUntilSatisfied());
751}
752
753IN_PROC_BROWSER_TEST_F(WebViewTest, AcceptTouchEvents) {
754  LoadAppWithGuest("web_view/accept_touch_events");
755
756  content::RenderViewHost* embedder_rvh =
757      GetEmbedderWebContents()->GetRenderViewHost();
758
759  bool embedder_has_touch_handler =
760      content::RenderViewHostTester::HasTouchEventHandler(embedder_rvh);
761  EXPECT_FALSE(embedder_has_touch_handler);
762
763  SendMessageToGuestAndWait("install-touch-handler", "installed-touch-handler");
764
765  // Note that we need to wait for the installed/registered touch handler to
766  // appear in browser process before querying |embedder_rvh|.
767  // In practice, since we do a roundrtip from browser process to guest and
768  // back, this is sufficient.
769  embedder_has_touch_handler =
770      content::RenderViewHostTester::HasTouchEventHandler(embedder_rvh);
771  EXPECT_TRUE(embedder_has_touch_handler);
772
773  SendMessageToGuestAndWait("uninstall-touch-handler",
774                            "uninstalled-touch-handler");
775  // Same as the note above about waiting.
776  embedder_has_touch_handler =
777      content::RenderViewHostTester::HasTouchEventHandler(embedder_rvh);
778  EXPECT_FALSE(embedder_has_touch_handler);
779}
780
781// This test ensures JavaScript errors ("Cannot redefine property") do not
782// happen when a <webview> is removed from DOM and added back.
783IN_PROC_BROWSER_TEST_F(WebViewTest,
784                       AddRemoveWebView_AddRemoveWebView) {
785  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
786  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/addremove"))
787      << message_;
788}
789
790IN_PROC_BROWSER_TEST_F(WebViewTest, AutoSize) {
791#if defined(OS_WIN)
792  // Flaky on XP bot http://crbug.com/299507
793  if (base::win::GetVersion() <= base::win::VERSION_XP)
794    return;
795#endif
796
797  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/autosize"))
798      << message_;
799}
800
801// Tests that a <webview> that is set to "display: none" after load and then
802// setting "display: block" re-renders the plugin properly.
803//
804// Initially after loading the <webview> and the test sets <webview> to
805// "display: none".
806// This causes the browser plugin to be destroyed, we then set the
807// style.display of the <webview> to block again and check that loadstop
808// fires properly.
809IN_PROC_BROWSER_TEST_F(WebViewTest, DisplayNoneAndBack) {
810  LoadAppWithGuest("web_view/display_none_and_back");
811
812  scoped_refptr<content::MessageLoopRunner> loop_runner(
813      new content::MessageLoopRunner);
814  WebContentsHiddenObserver observer(GetGuestWebContents(),
815                                     loop_runner->QuitClosure());
816
817  // Handled in platform_apps/web_view/display_none_and_back/main.js
818  SendMessageToEmbedder("hide-guest");
819  GetGuestViewManager()->WaitForGuestDeleted();
820  ExtensionTestMessageListener test_passed_listener("WebViewTest.PASSED",
821                                                    false);
822
823  SendMessageToEmbedder("show-guest");
824  GetGuestViewManager()->WaitForGuestCreated();
825  EXPECT_TRUE(test_passed_listener.WaitUntilSatisfied());
826}
827
828// Test for http://crbug.com/419611.
829IN_PROC_BROWSER_TEST_F(WebViewTest, DisplayNoneSetSrc) {
830  LoadAndLaunchPlatformApp("web_view/display_none_set_src",
831                           "WebViewTest.LAUNCHED");
832  // Navigate the guest while it's in "display: none" state.
833  SendMessageToEmbedder("navigate-guest");
834  GetGuestViewManager()->WaitForGuestCreated();
835
836  // Now attempt to navigate the guest again.
837  SendMessageToEmbedder("navigate-guest");
838
839  ExtensionTestMessageListener test_passed_listener("WebViewTest.PASSED",
840                                                    false);
841  // Making the guest visible would trigger loadstop.
842  SendMessageToEmbedder("show-guest");
843  EXPECT_TRUE(test_passed_listener.WaitUntilSatisfied());
844}
845
846// http://crbug.com/326332
847IN_PROC_BROWSER_TEST_F(WebViewTest, DISABLED_Shim_TestAutosizeAfterNavigation) {
848  TestHelper("testAutosizeAfterNavigation", "web_view/shim", NO_TEST_SERVER);
849}
850
851IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestAllowTransparencyAttribute) {
852  TestHelper("testAllowTransparencyAttribute", "web_view/shim", NO_TEST_SERVER);
853}
854
855IN_PROC_BROWSER_TEST_F(WebViewDPITest, Shim_TestAutosizeHeight) {
856  TestHelper("testAutosizeHeight", "web_view/shim", NO_TEST_SERVER);
857}
858
859IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestAutosizeHeight) {
860  TestHelper("testAutosizeHeight", "web_view/shim", NO_TEST_SERVER);
861}
862
863IN_PROC_BROWSER_TEST_F(WebViewDPITest, Shim_TestAutosizeBeforeNavigation) {
864  TestHelper("testAutosizeBeforeNavigation", "web_view/shim", NO_TEST_SERVER);
865}
866
867IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestAutosizeBeforeNavigation) {
868  TestHelper("testAutosizeBeforeNavigation", "web_view/shim", NO_TEST_SERVER);
869}
870
871IN_PROC_BROWSER_TEST_F(WebViewDPITest, Shim_TestAutosizeRemoveAttributes) {
872  TestHelper("testAutosizeRemoveAttributes", "web_view/shim", NO_TEST_SERVER);
873}
874
875IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestAutosizeRemoveAttributes) {
876  TestHelper("testAutosizeRemoveAttributes", "web_view/shim", NO_TEST_SERVER);
877}
878
879// This test is disabled due to being flaky. http://crbug.com/282116
880#if defined(OS_WIN) || defined(OS_MACOSX)
881#define MAYBE_Shim_TestAutosizeWithPartialAttributes \
882    DISABLED_Shim_TestAutosizeWithPartialAttributes
883#else
884#define MAYBE_Shim_TestAutosizeWithPartialAttributes \
885    Shim_TestAutosizeWithPartialAttributes
886#endif
887IN_PROC_BROWSER_TEST_F(WebViewTest,
888                       MAYBE_Shim_TestAutosizeWithPartialAttributes) {
889  TestHelper("testAutosizeWithPartialAttributes",
890             "web_view/shim",
891             NO_TEST_SERVER);
892}
893
894IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestAPIMethodExistence) {
895  TestHelper("testAPIMethodExistence", "web_view/shim", NO_TEST_SERVER);
896}
897
898// Tests the existence of WebRequest API event objects on the request
899// object, on the webview element, and hanging directly off webview.
900IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestWebRequestAPIExistence) {
901  TestHelper("testWebRequestAPIExistence", "web_view/shim", NO_TEST_SERVER);
902}
903
904// http://crbug.com/315920
905#if defined(GOOGLE_CHROME_BUILD) && (defined(OS_WIN) || defined(OS_LINUX))
906#define MAYBE_Shim_TestChromeExtensionURL DISABLED_Shim_TestChromeExtensionURL
907#else
908#define MAYBE_Shim_TestChromeExtensionURL Shim_TestChromeExtensionURL
909#endif
910IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_Shim_TestChromeExtensionURL) {
911  TestHelper("testChromeExtensionURL", "web_view/shim", NO_TEST_SERVER);
912}
913
914// http://crbug.com/315920
915#if defined(GOOGLE_CHROME_BUILD) && (defined(OS_WIN) || defined(OS_LINUX))
916#define MAYBE_Shim_TestChromeExtensionRelativePath \
917    DISABLED_Shim_TestChromeExtensionRelativePath
918#else
919#define MAYBE_Shim_TestChromeExtensionRelativePath \
920    Shim_TestChromeExtensionRelativePath
921#endif
922IN_PROC_BROWSER_TEST_F(WebViewTest,
923                       MAYBE_Shim_TestChromeExtensionRelativePath) {
924  TestHelper("testChromeExtensionRelativePath",
925             "web_view/shim",
926             NO_TEST_SERVER);
927}
928
929IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestDisplayNoneWebviewLoad) {
930  TestHelper("testDisplayNoneWebviewLoad", "web_view/shim", NO_TEST_SERVER);
931}
932
933IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestDisplayNoneWebviewRemoveChild) {
934  TestHelper("testDisplayNoneWebviewRemoveChild",
935             "web_view/shim", NO_TEST_SERVER);
936}
937
938IN_PROC_BROWSER_TEST_F(WebViewTest,
939                       Shim_TestInlineScriptFromAccessibleResources) {
940  TestHelper("testInlineScriptFromAccessibleResources",
941             "web_view/shim",
942             NO_TEST_SERVER);
943}
944
945IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestInvalidChromeExtensionURL) {
946  TestHelper("testInvalidChromeExtensionURL", "web_view/shim", NO_TEST_SERVER);
947}
948
949// Disable on Chrome OS, as it is flaking a lot. See: http://crbug.com/413618.
950#if defined(OS_CHROMEOS)
951#define MAYBE_Shim_TestEventName DISABLED_Shim_TestEventName
952#else
953#define MAYBE_Shim_TestEventName Shim_TestEventName
954#endif
955IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_Shim_TestEventName) {
956  TestHelper("testEventName", "web_view/shim", NO_TEST_SERVER);
957}
958
959// WebViewTest.Shim_TestOnEventProperty is flaky, so disable it.
960// http://crbug.com/359832.
961IN_PROC_BROWSER_TEST_F(WebViewTest, DISABLED_Shim_TestOnEventProperty) {
962  TestHelper("testOnEventProperties", "web_view/shim", NO_TEST_SERVER);
963}
964
965IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadProgressEvent) {
966  TestHelper("testLoadProgressEvent", "web_view/shim", NO_TEST_SERVER);
967}
968
969IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestDestroyOnEventListener) {
970  TestHelper("testDestroyOnEventListener", "web_view/shim", NO_TEST_SERVER);
971}
972
973IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestCannotMutateEventName) {
974  TestHelper("testCannotMutateEventName", "web_view/shim", NO_TEST_SERVER);
975}
976
977IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestPartitionRaisesException) {
978  TestHelper("testPartitionRaisesException", "web_view/shim", NO_TEST_SERVER);
979}
980
981IN_PROC_BROWSER_TEST_F(WebViewTest,
982                       Shim_TestPartitionRemovalAfterNavigationFails) {
983  TestHelper("testPartitionRemovalAfterNavigationFails",
984             "web_view/shim",
985             NO_TEST_SERVER);
986}
987
988IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestExecuteScriptFail) {
989#if defined(OS_WIN)
990  // Flaky on XP bot http://crbug.com/266185
991  if (base::win::GetVersion() <= base::win::VERSION_XP)
992    return;
993#endif
994
995  TestHelper("testExecuteScriptFail", "web_view/shim", NEEDS_TEST_SERVER);
996}
997
998IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestExecuteScript) {
999  TestHelper("testExecuteScript", "web_view/shim", NO_TEST_SERVER);
1000}
1001
1002IN_PROC_BROWSER_TEST_F(
1003    WebViewTest,
1004    Shim_TestExecuteScriptIsAbortedWhenWebViewSourceIsChanged) {
1005  TestHelper("testExecuteScriptIsAbortedWhenWebViewSourceIsChanged",
1006             "web_view/shim",
1007             NO_TEST_SERVER);
1008}
1009
1010IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestTerminateAfterExit) {
1011  TestHelper("testTerminateAfterExit", "web_view/shim", NO_TEST_SERVER);
1012}
1013
1014IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestAssignSrcAfterCrash) {
1015  TestHelper("testAssignSrcAfterCrash", "web_view/shim", NO_TEST_SERVER);
1016}
1017
1018IN_PROC_BROWSER_TEST_F(WebViewTest,
1019                       Shim_TestNavOnConsecutiveSrcAttributeChanges) {
1020  TestHelper("testNavOnConsecutiveSrcAttributeChanges",
1021             "web_view/shim",
1022             NO_TEST_SERVER);
1023}
1024
1025IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNavOnSrcAttributeChange) {
1026  TestHelper("testNavOnSrcAttributeChange", "web_view/shim", NO_TEST_SERVER);
1027}
1028
1029IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNavigateAfterResize) {
1030  TestHelper("testNavigateAfterResize", "web_view/shim", NO_TEST_SERVER);
1031}
1032
1033IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestRemoveSrcAttribute) {
1034  TestHelper("testRemoveSrcAttribute", "web_view/shim", NO_TEST_SERVER);
1035}
1036
1037IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestReassignSrcAttribute) {
1038  TestHelper("testReassignSrcAttribute", "web_view/shim", NO_TEST_SERVER);
1039}
1040
1041IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNewWindow) {
1042  TestHelper("testNewWindow", "web_view/shim", NEEDS_TEST_SERVER);
1043}
1044
1045IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNewWindowTwoListeners) {
1046  TestHelper("testNewWindowTwoListeners", "web_view/shim", NEEDS_TEST_SERVER);
1047}
1048
1049IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNewWindowNoPreventDefault) {
1050  TestHelper("testNewWindowNoPreventDefault",
1051             "web_view/shim",
1052             NEEDS_TEST_SERVER);
1053}
1054
1055IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNewWindowNoReferrerLink) {
1056  TestHelper("testNewWindowNoReferrerLink", "web_view/shim", NEEDS_TEST_SERVER);
1057}
1058
1059IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestContentLoadEvent) {
1060  TestHelper("testContentLoadEvent", "web_view/shim", NO_TEST_SERVER);
1061}
1062
1063IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestDeclarativeWebRequestAPI) {
1064  TestHelper("testDeclarativeWebRequestAPI",
1065             "web_view/shim",
1066             NEEDS_TEST_SERVER);
1067}
1068
1069IN_PROC_BROWSER_TEST_F(WebViewTest,
1070                       Shim_TestDeclarativeWebRequestAPISendMessage) {
1071  TestHelper("testDeclarativeWebRequestAPISendMessage",
1072             "web_view/shim",
1073             NEEDS_TEST_SERVER);
1074}
1075
1076IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestWebRequestAPI) {
1077  TestHelper("testWebRequestAPI", "web_view/shim", NEEDS_TEST_SERVER);
1078}
1079
1080IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestWebRequestAPIGoogleProperty) {
1081  TestHelper("testWebRequestAPIGoogleProperty",
1082             "web_view/shim",
1083             NO_TEST_SERVER);
1084}
1085
1086// This test is disabled due to being flaky. http://crbug.com/309451
1087#if defined(OS_WIN)
1088#define MAYBE_Shim_TestWebRequestListenerSurvivesReparenting \
1089    DISABLED_Shim_TestWebRequestListenerSurvivesReparenting
1090#else
1091#define MAYBE_Shim_TestWebRequestListenerSurvivesReparenting \
1092    Shim_TestWebRequestListenerSurvivesReparenting
1093#endif
1094IN_PROC_BROWSER_TEST_F(
1095    WebViewTest,
1096    MAYBE_Shim_TestWebRequestListenerSurvivesReparenting) {
1097  TestHelper("testWebRequestListenerSurvivesReparenting",
1098             "web_view/shim",
1099             NEEDS_TEST_SERVER);
1100}
1101
1102IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadStartLoadRedirect) {
1103  TestHelper("testLoadStartLoadRedirect", "web_view/shim", NEEDS_TEST_SERVER);
1104}
1105
1106IN_PROC_BROWSER_TEST_F(WebViewTest,
1107                       Shim_TestLoadAbortChromeExtensionURLWrongPartition) {
1108  TestHelper("testLoadAbortChromeExtensionURLWrongPartition",
1109             "web_view/shim",
1110             NO_TEST_SERVER);
1111}
1112
1113IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadAbortEmptyResponse) {
1114  TestHelper("testLoadAbortEmptyResponse", "web_view/shim", NEEDS_TEST_SERVER);
1115}
1116
1117IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadAbortIllegalChromeURL) {
1118  TestHelper("testLoadAbortIllegalChromeURL",
1119             "web_view/shim",
1120             NO_TEST_SERVER);
1121}
1122
1123IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadAbortIllegalFileURL) {
1124  TestHelper("testLoadAbortIllegalFileURL", "web_view/shim", NO_TEST_SERVER);
1125}
1126
1127IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadAbortIllegalJavaScriptURL) {
1128  TestHelper("testLoadAbortIllegalJavaScriptURL",
1129             "web_view/shim",
1130             NO_TEST_SERVER);
1131}
1132
1133IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadAbortInvalidNavigation) {
1134  TestHelper("testLoadAbortInvalidNavigation", "web_view/shim", NO_TEST_SERVER);
1135}
1136
1137IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestLoadAbortNonWebSafeScheme) {
1138  TestHelper("testLoadAbortNonWebSafeScheme", "web_view/shim", NO_TEST_SERVER);
1139}
1140
1141IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestReload) {
1142  TestHelper("testReload", "web_view/shim", NO_TEST_SERVER);
1143}
1144
1145IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestReloadAfterTerminate) {
1146  TestHelper("testReloadAfterTerminate", "web_view/shim", NO_TEST_SERVER);
1147}
1148
1149IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestGetProcessId) {
1150  TestHelper("testGetProcessId", "web_view/shim", NO_TEST_SERVER);
1151}
1152
1153IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestHiddenBeforeNavigation) {
1154  TestHelper("testHiddenBeforeNavigation", "web_view/shim", NO_TEST_SERVER);
1155}
1156
1157IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestRemoveWebviewOnExit) {
1158  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
1159
1160  // Launch the app and wait until it's ready to load a test.
1161  LoadAndLaunchPlatformApp("web_view/shim", "Launched");
1162
1163  content::WebContents* embedder_web_contents = GetFirstAppWindowWebContents();
1164  ASSERT_TRUE(embedder_web_contents);
1165
1166  GURL::Replacements replace_host;
1167  std::string host_str("localhost");  // Must stay in scope with replace_host.
1168  replace_host.SetHostStr(host_str);
1169
1170  std::string guest_path(
1171      "/extensions/platform_apps/web_view/shim/empty_guest.html");
1172  GURL guest_url = embedded_test_server()->GetURL(guest_path);
1173  guest_url = guest_url.ReplaceComponents(replace_host);
1174
1175  ui_test_utils::UrlLoadObserver guest_observer(
1176      guest_url, content::NotificationService::AllSources());
1177
1178  // Run the test and wait until the guest WebContents is available and has
1179  // finished loading.
1180  ExtensionTestMessageListener guest_loaded_listener("guest-loaded", false);
1181  EXPECT_TRUE(content::ExecuteScript(
1182                  embedder_web_contents,
1183                  "runTest('testRemoveWebviewOnExit')"));
1184  guest_observer.Wait();
1185
1186  content::Source<content::NavigationController> source =
1187      guest_observer.source();
1188  EXPECT_TRUE(source->GetWebContents()->GetRenderProcessHost()->
1189      IsIsolatedGuest());
1190
1191  ASSERT_TRUE(guest_loaded_listener.WaitUntilSatisfied());
1192
1193  content::WebContentsDestroyedWatcher destroyed_watcher(
1194      source->GetWebContents());
1195
1196  // Tell the embedder to kill the guest.
1197  EXPECT_TRUE(content::ExecuteScript(
1198                  embedder_web_contents,
1199                  "removeWebviewOnExitDoCrash();"));
1200
1201  // Wait until the guest WebContents is destroyed.
1202  destroyed_watcher.Wait();
1203}
1204
1205// Remove <webview> immediately after navigating it.
1206// This is a regression test for http://crbug.com/276023.
1207IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestRemoveWebviewAfterNavigation) {
1208  TestHelper("testRemoveWebviewAfterNavigation",
1209             "web_view/shim",
1210             NO_TEST_SERVER);
1211}
1212
1213IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestNavigationToExternalProtocol) {
1214  TestHelper("testNavigationToExternalProtocol",
1215             "web_view/shim",
1216             NO_TEST_SERVER);
1217}
1218
1219IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestResizeWebviewResizesContent) {
1220  TestHelper("testResizeWebviewResizesContent",
1221             "web_view/shim",
1222             NO_TEST_SERVER);
1223}
1224
1225// This test makes sure we do not crash if app is closed while interstitial
1226// page is being shown in guest.
1227// Disabled under LeakSanitizer due to memory leaks. http://crbug.com/321662
1228#if defined(LEAK_SANITIZER)
1229#define MAYBE_InterstitialTeardown DISABLED_InterstitialTeardown
1230#else
1231#define MAYBE_InterstitialTeardown InterstitialTeardown
1232#endif
1233IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_InterstitialTeardown) {
1234#if defined(OS_WIN)
1235  // Flaky on XP bot http://crbug.com/297014
1236  if (base::win::GetVersion() <= base::win::VERSION_XP)
1237    return;
1238#endif
1239
1240  // Start a HTTPS server so we can load an interstitial page inside guest.
1241  net::SpawnedTestServer::SSLOptions ssl_options;
1242  ssl_options.server_certificate =
1243      net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
1244  net::SpawnedTestServer https_server(
1245      net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
1246      base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1247  ASSERT_TRUE(https_server.Start());
1248
1249  net::HostPortPair host_and_port = https_server.host_port_pair();
1250
1251  LoadAndLaunchPlatformApp("web_view/interstitial_teardown", "EmbedderLoaded");
1252
1253  // Now load the guest.
1254  content::WebContents* embedder_web_contents = GetFirstAppWindowWebContents();
1255  ExtensionTestMessageListener second("GuestAddedToDom", false);
1256  EXPECT_TRUE(content::ExecuteScript(
1257      embedder_web_contents,
1258      base::StringPrintf("loadGuest(%d);\n", host_and_port.port())));
1259  ASSERT_TRUE(second.WaitUntilSatisfied());
1260
1261  // Wait for interstitial page to be shown in guest.
1262  content::WebContents* guest_web_contents =
1263      GetGuestViewManager()->WaitForGuestCreated();
1264  ASSERT_TRUE(guest_web_contents->GetRenderProcessHost()->IsIsolatedGuest());
1265  WaitForInterstitial(guest_web_contents);
1266
1267  // Now close the app while interstitial page being shown in guest.
1268  extensions::AppWindow* window = GetFirstAppWindow();
1269  window->GetBaseWindow()->Close();
1270}
1271
1272IN_PROC_BROWSER_TEST_F(WebViewTest, ShimSrcAttribute) {
1273  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/src_attribute"))
1274      << message_;
1275}
1276
1277// This test verifies that prerendering has been disabled inside <webview>.
1278// This test is here rather than in PrerenderBrowserTest for testing convenience
1279// only. If it breaks then this is a bug in the prerenderer.
1280IN_PROC_BROWSER_TEST_F(WebViewTest, NoPrerenderer) {
1281  ASSERT_TRUE(StartEmbeddedTestServer());
1282  content::WebContents* guest_web_contents =
1283      LoadGuest(
1284          "/extensions/platform_apps/web_view/noprerenderer/guest.html",
1285          "web_view/noprerenderer");
1286  ASSERT_TRUE(guest_web_contents != NULL);
1287
1288  PrerenderLinkManager* prerender_link_manager =
1289      PrerenderLinkManagerFactory::GetForProfile(
1290          Profile::FromBrowserContext(guest_web_contents->GetBrowserContext()));
1291  ASSERT_TRUE(prerender_link_manager != NULL);
1292  EXPECT_TRUE(prerender_link_manager->IsEmpty());
1293}
1294
1295// Verify that existing <webview>'s are detected when the task manager starts
1296// up.
1297IN_PROC_BROWSER_TEST_F(WebViewTest, TaskManagerExistingWebView) {
1298  ASSERT_TRUE(StartEmbeddedTestServer());
1299
1300  LoadGuest("/extensions/platform_apps/web_view/task_manager/guest.html",
1301            "web_view/task_manager");
1302
1303  chrome::ShowTaskManager(browser());  // Show task manager AFTER guest loads.
1304
1305  const char* guest_title = "WebViewed test content";
1306  const char* app_name = "<webview> task manager test";
1307  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchWebView(guest_title)));
1308  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
1309  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchApp(app_name)));
1310  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchBackground(app_name)));
1311
1312  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyWebView()));
1313  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
1314  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyApp()));
1315  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyBackground()));
1316}
1317
1318// Verify that the task manager notices the creation of new <webview>'s.
1319IN_PROC_BROWSER_TEST_F(WebViewTest, TaskManagerNewWebView) {
1320  ASSERT_TRUE(StartEmbeddedTestServer());
1321
1322  chrome::ShowTaskManager(browser());  // Show task manager BEFORE guest loads.
1323
1324  LoadGuest("/extensions/platform_apps/web_view/task_manager/guest.html",
1325            "web_view/task_manager");
1326
1327  const char* guest_title = "WebViewed test content";
1328  const char* app_name = "<webview> task manager test";
1329  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchWebView(guest_title)));
1330  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
1331  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchApp(app_name)));
1332  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchBackground(app_name)));
1333
1334  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyWebView()));
1335  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
1336  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyApp()));
1337  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyBackground()));
1338}
1339
1340// This tests cookie isolation for packaged apps with webview tags. It navigates
1341// the main browser window to a page that sets a cookie and loads an app with
1342// multiple webview tags. Each tag sets a cookie and the test checks the proper
1343// storage isolation is enforced.
1344IN_PROC_BROWSER_TEST_F(WebViewTest, CookieIsolation) {
1345  ASSERT_TRUE(StartEmbeddedTestServer());
1346  const std::string kExpire =
1347      "var expire = new Date(Date.now() + 24 * 60 * 60 * 1000);";
1348  std::string cookie_script1(kExpire);
1349  cookie_script1.append(
1350      "document.cookie = 'guest1=true; path=/; expires=' + expire + ';';");
1351  std::string cookie_script2(kExpire);
1352  cookie_script2.append(
1353      "document.cookie = 'guest2=true; path=/; expires=' + expire + ';';");
1354
1355  GURL::Replacements replace_host;
1356  std::string host_str("localhost");  // Must stay in scope with replace_host.
1357  replace_host.SetHostStr(host_str);
1358
1359  GURL set_cookie_url = embedded_test_server()->GetURL(
1360      "/extensions/platform_apps/isolation/set_cookie.html");
1361  set_cookie_url = set_cookie_url.ReplaceComponents(replace_host);
1362
1363  // The first two partitions will be used to set cookies and ensure they are
1364  // shared. The named partition is used to ensure that cookies are isolated
1365  // between partitions within the same app.
1366  content::WebContents* cookie_contents1;
1367  content::WebContents* cookie_contents2;
1368  content::WebContents* named_partition_contents1;
1369  content::WebContents* named_partition_contents2;
1370
1371  NavigateAndOpenAppForIsolation(set_cookie_url, &cookie_contents1,
1372                                 &cookie_contents2, &named_partition_contents1,
1373                                 &named_partition_contents2, NULL, NULL, NULL);
1374
1375  EXPECT_TRUE(content::ExecuteScript(cookie_contents1, cookie_script1));
1376  EXPECT_TRUE(content::ExecuteScript(cookie_contents2, cookie_script2));
1377
1378  int cookie_size;
1379  std::string cookie_value;
1380
1381  // Test the regular browser context to ensure we have only one cookie.
1382  ui_test_utils::GetCookies(GURL("http://localhost"),
1383                            browser()->tab_strip_model()->GetWebContentsAt(0),
1384                            &cookie_size, &cookie_value);
1385  EXPECT_EQ("testCookie=1", cookie_value);
1386
1387  // The default behavior is to combine webview tags with no explicit partition
1388  // declaration into the same in-memory partition. Test the webview tags to
1389  // ensure we have properly set the cookies and we have both cookies in both
1390  // tags.
1391  ui_test_utils::GetCookies(GURL("http://localhost"),
1392                            cookie_contents1,
1393                            &cookie_size, &cookie_value);
1394  EXPECT_EQ("guest1=true; guest2=true", cookie_value);
1395
1396  ui_test_utils::GetCookies(GURL("http://localhost"),
1397                            cookie_contents2,
1398                            &cookie_size, &cookie_value);
1399  EXPECT_EQ("guest1=true; guest2=true", cookie_value);
1400
1401  // The third tag should not have any cookies as it is in a separate partition.
1402  ui_test_utils::GetCookies(GURL("http://localhost"),
1403                            named_partition_contents1,
1404                            &cookie_size, &cookie_value);
1405  EXPECT_EQ("", cookie_value);
1406}
1407
1408// This tests that in-memory storage partitions are reset on browser restart,
1409// but persistent ones maintain state for cookies and HTML5 storage.
1410IN_PROC_BROWSER_TEST_F(WebViewTest, PRE_StoragePersistence) {
1411  ASSERT_TRUE(StartEmbeddedTestServer());
1412  const std::string kExpire =
1413      "var expire = new Date(Date.now() + 24 * 60 * 60 * 1000);";
1414  std::string cookie_script1(kExpire);
1415  cookie_script1.append(
1416      "document.cookie = 'inmemory=true; path=/; expires=' + expire + ';';");
1417  std::string cookie_script2(kExpire);
1418  cookie_script2.append(
1419      "document.cookie = 'persist1=true; path=/; expires=' + expire + ';';");
1420  std::string cookie_script3(kExpire);
1421  cookie_script3.append(
1422      "document.cookie = 'persist2=true; path=/; expires=' + expire + ';';");
1423
1424  // We don't care where the main browser is on this test.
1425  GURL blank_url("about:blank");
1426
1427  // The first two partitions will be used to set cookies and ensure they are
1428  // shared. The named partition is used to ensure that cookies are isolated
1429  // between partitions within the same app.
1430  content::WebContents* cookie_contents1;
1431  content::WebContents* cookie_contents2;
1432  content::WebContents* named_partition_contents1;
1433  content::WebContents* named_partition_contents2;
1434  content::WebContents* persistent_partition_contents1;
1435  content::WebContents* persistent_partition_contents2;
1436  content::WebContents* persistent_partition_contents3;
1437  NavigateAndOpenAppForIsolation(blank_url, &cookie_contents1,
1438                                 &cookie_contents2, &named_partition_contents1,
1439                                 &named_partition_contents2,
1440                                 &persistent_partition_contents1,
1441                                 &persistent_partition_contents2,
1442                                 &persistent_partition_contents3);
1443
1444  // Set the inmemory=true cookie for tags with inmemory partitions.
1445  EXPECT_TRUE(content::ExecuteScript(cookie_contents1, cookie_script1));
1446  EXPECT_TRUE(content::ExecuteScript(named_partition_contents1,
1447                                     cookie_script1));
1448
1449  // For the two different persistent storage partitions, set the
1450  // two different cookies so we can check that they aren't comingled below.
1451  EXPECT_TRUE(content::ExecuteScript(persistent_partition_contents1,
1452                                     cookie_script2));
1453
1454  EXPECT_TRUE(content::ExecuteScript(persistent_partition_contents3,
1455                                     cookie_script3));
1456
1457  int cookie_size;
1458  std::string cookie_value;
1459
1460  // Check that all in-memory partitions have a cookie set.
1461  ui_test_utils::GetCookies(GURL("http://localhost"),
1462                            cookie_contents1,
1463                            &cookie_size, &cookie_value);
1464  EXPECT_EQ("inmemory=true", cookie_value);
1465  ui_test_utils::GetCookies(GURL("http://localhost"),
1466                            cookie_contents2,
1467                            &cookie_size, &cookie_value);
1468  EXPECT_EQ("inmemory=true", cookie_value);
1469  ui_test_utils::GetCookies(GURL("http://localhost"),
1470                            named_partition_contents1,
1471                            &cookie_size, &cookie_value);
1472  EXPECT_EQ("inmemory=true", cookie_value);
1473  ui_test_utils::GetCookies(GURL("http://localhost"),
1474                            named_partition_contents2,
1475                            &cookie_size, &cookie_value);
1476  EXPECT_EQ("inmemory=true", cookie_value);
1477
1478  // Check that all persistent partitions kept their state.
1479  ui_test_utils::GetCookies(GURL("http://localhost"),
1480                            persistent_partition_contents1,
1481                            &cookie_size, &cookie_value);
1482  EXPECT_EQ("persist1=true", cookie_value);
1483  ui_test_utils::GetCookies(GURL("http://localhost"),
1484                            persistent_partition_contents2,
1485                            &cookie_size, &cookie_value);
1486  EXPECT_EQ("persist1=true", cookie_value);
1487  ui_test_utils::GetCookies(GURL("http://localhost"),
1488                            persistent_partition_contents3,
1489                            &cookie_size, &cookie_value);
1490  EXPECT_EQ("persist2=true", cookie_value);
1491}
1492
1493// This is the post-reset portion of the StoragePersistence test.  See
1494// PRE_StoragePersistence for main comment.
1495#if defined(OS_CHROMEOS)
1496// http://crbug.com/223888
1497#define MAYBE_StoragePersistence DISABLED_StoragePersistence
1498#else
1499#define MAYBE_StoragePersistence StoragePersistence
1500#endif
1501IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_StoragePersistence) {
1502  ASSERT_TRUE(StartEmbeddedTestServer());
1503
1504  // We don't care where the main browser is on this test.
1505  GURL blank_url("about:blank");
1506
1507  // The first two partitions will be used to set cookies and ensure they are
1508  // shared. The named partition is used to ensure that cookies are isolated
1509  // between partitions within the same app.
1510  content::WebContents* cookie_contents1;
1511  content::WebContents* cookie_contents2;
1512  content::WebContents* named_partition_contents1;
1513  content::WebContents* named_partition_contents2;
1514  content::WebContents* persistent_partition_contents1;
1515  content::WebContents* persistent_partition_contents2;
1516  content::WebContents* persistent_partition_contents3;
1517  NavigateAndOpenAppForIsolation(blank_url, &cookie_contents1,
1518                                 &cookie_contents2, &named_partition_contents1,
1519                                 &named_partition_contents2,
1520                                 &persistent_partition_contents1,
1521                                 &persistent_partition_contents2,
1522                                 &persistent_partition_contents3);
1523
1524  int cookie_size;
1525  std::string cookie_value;
1526
1527  // Check that all in-memory partitions lost their state.
1528  ui_test_utils::GetCookies(GURL("http://localhost"),
1529                            cookie_contents1,
1530                            &cookie_size, &cookie_value);
1531  EXPECT_EQ("", cookie_value);
1532  ui_test_utils::GetCookies(GURL("http://localhost"),
1533                            cookie_contents2,
1534                            &cookie_size, &cookie_value);
1535  EXPECT_EQ("", cookie_value);
1536  ui_test_utils::GetCookies(GURL("http://localhost"),
1537                            named_partition_contents1,
1538                            &cookie_size, &cookie_value);
1539  EXPECT_EQ("", cookie_value);
1540  ui_test_utils::GetCookies(GURL("http://localhost"),
1541                            named_partition_contents2,
1542                            &cookie_size, &cookie_value);
1543  EXPECT_EQ("", cookie_value);
1544
1545  // Check that all persistent partitions kept their state.
1546  ui_test_utils::GetCookies(GURL("http://localhost"),
1547                            persistent_partition_contents1,
1548                            &cookie_size, &cookie_value);
1549  EXPECT_EQ("persist1=true", cookie_value);
1550  ui_test_utils::GetCookies(GURL("http://localhost"),
1551                            persistent_partition_contents2,
1552                            &cookie_size, &cookie_value);
1553  EXPECT_EQ("persist1=true", cookie_value);
1554  ui_test_utils::GetCookies(GURL("http://localhost"),
1555                            persistent_partition_contents3,
1556                            &cookie_size, &cookie_value);
1557  EXPECT_EQ("persist2=true", cookie_value);
1558}
1559
1560// This tests DOM storage isolation for packaged apps with webview tags. It
1561// loads an app with multiple webview tags and each tag sets DOM storage
1562// entries, which the test checks to ensure proper storage isolation is
1563// enforced.
1564IN_PROC_BROWSER_TEST_F(WebViewTest, DOMStorageIsolation) {
1565  ASSERT_TRUE(StartEmbeddedTestServer());
1566  GURL regular_url = embedded_test_server()->GetURL("/title1.html");
1567
1568  std::string output;
1569  std::string get_local_storage("window.domAutomationController.send("
1570      "window.localStorage.getItem('foo') || 'badval')");
1571  std::string get_session_storage("window.domAutomationController.send("
1572      "window.sessionStorage.getItem('bar') || 'badval')");
1573
1574  content::WebContents* default_tag_contents1;
1575  content::WebContents* default_tag_contents2;
1576  content::WebContents* storage_contents1;
1577  content::WebContents* storage_contents2;
1578
1579  NavigateAndOpenAppForIsolation(regular_url, &default_tag_contents1,
1580                                 &default_tag_contents2, &storage_contents1,
1581                                 &storage_contents2, NULL, NULL, NULL);
1582
1583  // Initialize the storage for the first of the two tags that share a storage
1584  // partition.
1585  EXPECT_TRUE(content::ExecuteScript(storage_contents1,
1586                                     "initDomStorage('page1')"));
1587
1588  // Let's test that the expected values are present in the first tag, as they
1589  // will be overwritten once we call the initDomStorage on the second tag.
1590  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1,
1591                                            get_local_storage.c_str(),
1592                                            &output));
1593  EXPECT_STREQ("local-page1", output.c_str());
1594  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1,
1595                                            get_session_storage.c_str(),
1596                                            &output));
1597  EXPECT_STREQ("session-page1", output.c_str());
1598
1599  // Now, init the storage in the second tag in the same storage partition,
1600  // which will overwrite the shared localStorage.
1601  EXPECT_TRUE(content::ExecuteScript(storage_contents2,
1602                                     "initDomStorage('page2')"));
1603
1604  // The localStorage value now should reflect the one written through the
1605  // second tag.
1606  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1,
1607                                            get_local_storage.c_str(),
1608                                            &output));
1609  EXPECT_STREQ("local-page2", output.c_str());
1610  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents2,
1611                                            get_local_storage.c_str(),
1612                                            &output));
1613  EXPECT_STREQ("local-page2", output.c_str());
1614
1615  // Session storage is not shared though, as each webview tag has separate
1616  // instance, even if they are in the same storage partition.
1617  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1,
1618                                            get_session_storage.c_str(),
1619                                            &output));
1620  EXPECT_STREQ("session-page1", output.c_str());
1621  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents2,
1622                                            get_session_storage.c_str(),
1623                                            &output));
1624  EXPECT_STREQ("session-page2", output.c_str());
1625
1626  // Also, let's check that the main browser and another tag that doesn't share
1627  // the same partition don't have those values stored.
1628  EXPECT_TRUE(ExecuteScriptAndExtractString(
1629      browser()->tab_strip_model()->GetWebContentsAt(0),
1630      get_local_storage.c_str(),
1631      &output));
1632  EXPECT_STREQ("badval", output.c_str());
1633  EXPECT_TRUE(ExecuteScriptAndExtractString(
1634      browser()->tab_strip_model()->GetWebContentsAt(0),
1635      get_session_storage.c_str(),
1636      &output));
1637  EXPECT_STREQ("badval", output.c_str());
1638  EXPECT_TRUE(ExecuteScriptAndExtractString(default_tag_contents1,
1639                                            get_local_storage.c_str(),
1640                                            &output));
1641  EXPECT_STREQ("badval", output.c_str());
1642  EXPECT_TRUE(ExecuteScriptAndExtractString(default_tag_contents1,
1643                                            get_session_storage.c_str(),
1644                                            &output));
1645  EXPECT_STREQ("badval", output.c_str());
1646}
1647
1648// This tests IndexedDB isolation for packaged apps with webview tags. It loads
1649// an app with multiple webview tags and each tag creates an IndexedDB record,
1650// which the test checks to ensure proper storage isolation is enforced.
1651IN_PROC_BROWSER_TEST_F(WebViewTest, IndexedDBIsolation) {
1652  ASSERT_TRUE(StartEmbeddedTestServer());
1653  GURL regular_url = embedded_test_server()->GetURL("/title1.html");
1654
1655  content::WebContents* default_tag_contents1;
1656  content::WebContents* default_tag_contents2;
1657  content::WebContents* storage_contents1;
1658  content::WebContents* storage_contents2;
1659
1660  NavigateAndOpenAppForIsolation(regular_url, &default_tag_contents1,
1661                                 &default_tag_contents2, &storage_contents1,
1662                                 &storage_contents2, NULL, NULL, NULL);
1663
1664  // Initialize the storage for the first of the two tags that share a storage
1665  // partition.
1666  ExecuteScriptWaitForTitle(storage_contents1, "initIDB()", "idb created");
1667  ExecuteScriptWaitForTitle(storage_contents1, "addItemIDB(7, 'page1')",
1668                            "addItemIDB complete");
1669  ExecuteScriptWaitForTitle(storage_contents1, "readItemIDB(7)",
1670                            "readItemIDB complete");
1671
1672  std::string output;
1673  std::string get_value(
1674      "window.domAutomationController.send(getValueIDB() || 'badval')");
1675
1676  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1,
1677                                            get_value.c_str(), &output));
1678  EXPECT_STREQ("page1", output.c_str());
1679
1680  // Initialize the db in the second tag.
1681  ExecuteScriptWaitForTitle(storage_contents2, "initIDB()", "idb open");
1682
1683  // Since we share a partition, reading the value should return the existing
1684  // one.
1685  ExecuteScriptWaitForTitle(storage_contents2, "readItemIDB(7)",
1686                            "readItemIDB complete");
1687  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents2,
1688                                            get_value.c_str(), &output));
1689  EXPECT_STREQ("page1", output.c_str());
1690
1691  // Now write through the second tag and read it back.
1692  ExecuteScriptWaitForTitle(storage_contents2, "addItemIDB(7, 'page2')",
1693                            "addItemIDB complete");
1694  ExecuteScriptWaitForTitle(storage_contents2, "readItemIDB(7)",
1695                            "readItemIDB complete");
1696  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents2,
1697                                            get_value.c_str(), &output));
1698  EXPECT_STREQ("page2", output.c_str());
1699
1700  // Reset the document title, otherwise the next call will not see a change and
1701  // will hang waiting for it.
1702  EXPECT_TRUE(content::ExecuteScript(storage_contents1,
1703                                     "document.title = 'foo'"));
1704
1705  // Read through the first tag to ensure we have the second value.
1706  ExecuteScriptWaitForTitle(storage_contents1, "readItemIDB(7)",
1707                            "readItemIDB complete");
1708  EXPECT_TRUE(ExecuteScriptAndExtractString(storage_contents1,
1709                                            get_value.c_str(), &output));
1710  EXPECT_STREQ("page2", output.c_str());
1711
1712  // Now, let's confirm there is no database in the main browser and another
1713  // tag that doesn't share the same partition. Due to the IndexedDB API design,
1714  // open will succeed, but the version will be 1, since it creates the database
1715  // if it is not found. The two tags use database version 3, so we avoid
1716  // ambiguity.
1717  const char* script =
1718      "indexedDB.open('isolation').onsuccess = function(e) {"
1719      "  if (e.target.result.version == 1)"
1720      "    document.title = 'db not found';"
1721      "  else "
1722      "    document.title = 'error';"
1723      "}";
1724  ExecuteScriptWaitForTitle(browser()->tab_strip_model()->GetWebContentsAt(0),
1725                            script, "db not found");
1726  ExecuteScriptWaitForTitle(default_tag_contents1, script, "db not found");
1727}
1728
1729// This test ensures that closing app window on 'loadcommit' does not crash.
1730// The test launches an app with guest and closes the window on loadcommit. It
1731// then launches the app window again. The process is repeated 3 times.
1732// http://crbug.com/291278
1733#if defined(OS_WIN)
1734#define MAYBE_CloseOnLoadcommit DISABLED_CloseOnLoadcommit
1735#else
1736#define MAYBE_CloseOnLoadcommit CloseOnLoadcommit
1737#endif
1738IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_CloseOnLoadcommit) {
1739  LoadAndLaunchPlatformApp("web_view/close_on_loadcommit",
1740                           "done-close-on-loadcommit");
1741}
1742
1743IN_PROC_BROWSER_TEST_F(WebViewTest, MediaAccessAPIDeny_TestDeny) {
1744  MediaAccessAPIDenyTestHelper("testDeny");
1745}
1746
1747IN_PROC_BROWSER_TEST_F(WebViewTest,
1748                       MediaAccessAPIDeny_TestDenyThenAllowThrows) {
1749  MediaAccessAPIDenyTestHelper("testDenyThenAllowThrows");
1750
1751}
1752
1753IN_PROC_BROWSER_TEST_F(WebViewTest,
1754                       MediaAccessAPIDeny_TestDenyWithPreventDefault) {
1755  MediaAccessAPIDenyTestHelper("testDenyWithPreventDefault");
1756}
1757
1758IN_PROC_BROWSER_TEST_F(WebViewTest,
1759                       MediaAccessAPIDeny_TestNoListenersImplyDeny) {
1760  MediaAccessAPIDenyTestHelper("testNoListenersImplyDeny");
1761}
1762
1763IN_PROC_BROWSER_TEST_F(WebViewTest,
1764                       MediaAccessAPIDeny_TestNoPreventDefaultImpliesDeny) {
1765  MediaAccessAPIDenyTestHelper("testNoPreventDefaultImpliesDeny");
1766}
1767
1768void WebViewTest::MediaAccessAPIAllowTestHelper(const std::string& test_name) {
1769  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
1770  LoadAndLaunchPlatformApp("web_view/media_access/allow", "Launched");
1771
1772  content::WebContents* embedder_web_contents = GetFirstAppWindowWebContents();
1773  ASSERT_TRUE(embedder_web_contents);
1774  scoped_ptr<MockWebContentsDelegate> mock(new MockWebContentsDelegate());
1775  embedder_web_contents->SetDelegate(mock.get());
1776
1777  ExtensionTestMessageListener done_listener("TEST_PASSED", false);
1778  done_listener.set_failure_message("TEST_FAILED");
1779  EXPECT_TRUE(
1780      content::ExecuteScript(
1781          embedder_web_contents,
1782          base::StringPrintf("startAllowTest('%s')",
1783                             test_name.c_str())));
1784  ASSERT_TRUE(done_listener.WaitUntilSatisfied());
1785
1786  mock->WaitForSetMediaPermission();
1787}
1788
1789IN_PROC_BROWSER_TEST_F(WebViewTest, ContextMenusAPI_Basic) {
1790  LoadAppWithGuest("web_view/context_menus/basic");
1791
1792  content::WebContents* guest_web_contents = GetGuestWebContents();
1793  content::WebContents* embedder = GetEmbedderWebContents();
1794  ASSERT_TRUE(embedder);
1795
1796  // 1. Basic property test.
1797  ExecuteScriptWaitForTitle(embedder, "checkProperties()", "ITEM_CHECKED");
1798
1799  // 2. Create a menu item and wait for created callback to be called.
1800  ExecuteScriptWaitForTitle(embedder, "createMenuItem()", "ITEM_CREATED");
1801
1802  // 3. Click the created item, wait for the click handlers to fire from JS.
1803  ExtensionTestMessageListener click_listener("ITEM_CLICKED", false);
1804  GURL page_url("http://www.google.com");
1805  // Create and build our test context menu.
1806  scoped_ptr<TestRenderViewContextMenu> menu(TestRenderViewContextMenu::Create(
1807      guest_web_contents, page_url, GURL(), GURL()));
1808
1809  // Look for the extension item in the menu, and execute it.
1810  int command_id = ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0);
1811  ASSERT_TRUE(menu->IsCommandIdEnabled(command_id));
1812  menu->ExecuteCommand(command_id, 0);
1813
1814  // Wait for embedder's script to tell us its onclick fired, it does
1815  // chrome.test.sendMessage('ITEM_CLICKED')
1816  ASSERT_TRUE(click_listener.WaitUntilSatisfied());
1817
1818  // 4. Update the item's title and verify.
1819  ExecuteScriptWaitForTitle(embedder, "updateMenuItem()", "ITEM_UPDATED");
1820  MenuItem::List items = GetItems();
1821  ASSERT_EQ(1u, items.size());
1822  MenuItem* item = items.at(0);
1823  EXPECT_EQ("new_title", item->title());
1824
1825  // 5. Remove the item.
1826  ExecuteScriptWaitForTitle(embedder, "removeItem()", "ITEM_REMOVED");
1827  MenuItem::List items_after_removal = GetItems();
1828  ASSERT_EQ(0u, items_after_removal.size());
1829
1830  // 6. Add some more items.
1831  ExecuteScriptWaitForTitle(
1832      embedder, "createThreeMenuItems()", "ITEM_MULTIPLE_CREATED");
1833  MenuItem::List items_after_insertion = GetItems();
1834  ASSERT_EQ(3u, items_after_insertion.size());
1835
1836  // 7. Test removeAll().
1837  ExecuteScriptWaitForTitle(embedder, "removeAllItems()", "ITEM_ALL_REMOVED");
1838  MenuItem::List items_after_all_removal = GetItems();
1839  ASSERT_EQ(0u, items_after_all_removal.size());
1840}
1841
1842IN_PROC_BROWSER_TEST_F(WebViewTest, MediaAccessAPIAllow_TestAllow) {
1843  MediaAccessAPIAllowTestHelper("testAllow");
1844}
1845
1846IN_PROC_BROWSER_TEST_F(WebViewTest, MediaAccessAPIAllow_TestAllowAndThenDeny) {
1847  MediaAccessAPIAllowTestHelper("testAllowAndThenDeny");
1848}
1849
1850IN_PROC_BROWSER_TEST_F(WebViewTest, MediaAccessAPIAllow_TestAllowTwice) {
1851  MediaAccessAPIAllowTestHelper("testAllowTwice");
1852}
1853
1854IN_PROC_BROWSER_TEST_F(WebViewTest, MediaAccessAPIAllow_TestAllowAsync) {
1855  MediaAccessAPIAllowTestHelper("testAllowAsync");
1856}
1857
1858// Checks that window.screenX/screenY/screenLeft/screenTop works correctly for
1859// guests.
1860IN_PROC_BROWSER_TEST_F(WebViewTest, ScreenCoordinates) {
1861  ASSERT_TRUE(RunPlatformAppTestWithArg(
1862      "platform_apps/web_view/common", "screen_coordinates"))
1863          << message_;
1864}
1865
1866#if defined(OS_CHROMEOS)
1867IN_PROC_BROWSER_TEST_F(WebViewTest, ChromeVoxInjection) {
1868  EXPECT_FALSE(
1869      chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled());
1870
1871  ASSERT_TRUE(StartEmbeddedTestServer());
1872  content::WebContents* guest_web_contents = LoadGuest(
1873      "/extensions/platform_apps/web_view/chromevox_injection/guest.html",
1874      "web_view/chromevox_injection");
1875  ASSERT_TRUE(guest_web_contents);
1876
1877  chromeos::SpeechMonitor monitor;
1878  chromeos::AccessibilityManager::Get()->EnableSpokenFeedback(
1879      true, ash::A11Y_NOTIFICATION_NONE);
1880  EXPECT_TRUE(monitor.SkipChromeVoxEnabledMessage());
1881
1882  EXPECT_EQ("chrome vox test title", monitor.GetNextUtterance());
1883}
1884#endif
1885
1886// Flaky on Windows. http://crbug.com/303966
1887#if defined(OS_WIN)
1888#define MAYBE_TearDownTest DISABLED_TearDownTest
1889#else
1890#define MAYBE_TearDownTest TearDownTest
1891#endif
1892IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_TearDownTest) {
1893  const extensions::Extension* extension =
1894      LoadAndLaunchPlatformApp("web_view/teardown", "guest-loaded");
1895  extensions::AppWindow* window = NULL;
1896  if (!GetAppWindowCount())
1897    window = CreateAppWindow(extension);
1898  else
1899    window = GetFirstAppWindow();
1900  CloseAppWindow(window);
1901
1902  // Load the app again.
1903  LoadAndLaunchPlatformApp("web_view/teardown", "guest-loaded");
1904}
1905
1906// In following GeolocationAPIEmbedderHasNoAccess* tests, embedder (i.e. the
1907// platform app) does not have geolocation permission for this test.
1908// No matter what the API does, geolocation permission would be denied.
1909// Note that the test name prefix must be "GeolocationAPI".
1910IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationAPIEmbedderHasNoAccessAllow) {
1911  TestHelper("testDenyDenies",
1912             "web_view/geolocation/embedder_has_no_permission",
1913             NEEDS_TEST_SERVER);
1914}
1915
1916IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationAPIEmbedderHasNoAccessDeny) {
1917  TestHelper("testDenyDenies",
1918             "web_view/geolocation/embedder_has_no_permission",
1919             NEEDS_TEST_SERVER);
1920}
1921
1922// In following GeolocationAPIEmbedderHasAccess* tests, embedder (i.e. the
1923// platform app) has geolocation permission
1924//
1925// Note that these test names must be "GeolocationAPI" prefixed (b/c we mock out
1926// geolocation in this case).
1927//
1928// Also note that these are run separately because OverrideGeolocation() doesn't
1929// mock out geolocation for multiple navigator.geolocation calls properly and
1930// the tests become flaky.
1931// GeolocationAPI* test 1 of 3.
1932IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationAPIEmbedderHasAccessAllow) {
1933  TestHelper("testAllow",
1934             "web_view/geolocation/embedder_has_permission",
1935             NEEDS_TEST_SERVER);
1936}
1937
1938// GeolocationAPI* test 2 of 3.
1939IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationAPIEmbedderHasAccessDeny) {
1940  TestHelper("testDeny",
1941             "web_view/geolocation/embedder_has_permission",
1942             NEEDS_TEST_SERVER);
1943}
1944
1945// GeolocationAPI* test 3 of 3.
1946IN_PROC_BROWSER_TEST_F(WebViewTest,
1947                       GeolocationAPIEmbedderHasAccessMultipleBridgeIdAllow) {
1948  TestHelper("testMultipleBridgeIdAllow",
1949             "web_view/geolocation/embedder_has_permission",
1950             NEEDS_TEST_SERVER);
1951}
1952
1953// Tests that
1954// BrowserPluginGeolocationPermissionContext::CancelGeolocationPermissionRequest
1955// is handled correctly (and does not crash).
1956IN_PROC_BROWSER_TEST_F(WebViewTest, GeolocationAPICancelGeolocation) {
1957  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
1958  ASSERT_TRUE(RunPlatformAppTest(
1959        "platform_apps/web_view/geolocation/cancel_request")) << message_;
1960}
1961
1962IN_PROC_BROWSER_TEST_F(WebViewTest, DISABLED_GeolocationRequestGone) {
1963  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
1964  ASSERT_TRUE(RunPlatformAppTest(
1965        "platform_apps/web_view/geolocation/geolocation_request_gone"))
1966            << message_;
1967}
1968
1969// In following FilesystemAPIRequestFromMainThread* tests, guest request
1970// filesystem access from main thread of the guest.
1971// FileSystemAPIRequestFromMainThread* test 1 of 3
1972IN_PROC_BROWSER_TEST_F(WebViewTest, FileSystemAPIRequestFromMainThreadAllow) {
1973  TestHelper("testAllow", "web_view/filesystem/main", NEEDS_TEST_SERVER);
1974}
1975
1976// FileSystemAPIRequestFromMainThread* test 2 of 3.
1977IN_PROC_BROWSER_TEST_F(WebViewTest, FileSystemAPIRequestFromMainThreadDeny) {
1978  TestHelper("testDeny", "web_view/filesystem/main", NEEDS_TEST_SERVER);
1979}
1980
1981// FileSystemAPIRequestFromMainThread* test 3 of 3.
1982IN_PROC_BROWSER_TEST_F(WebViewTest,
1983                       FileSystemAPIRequestFromMainThreadDefaultAllow) {
1984  TestHelper("testDefaultAllow", "web_view/filesystem/main", NEEDS_TEST_SERVER);
1985}
1986
1987// In following FilesystemAPIRequestFromWorker* tests, guest create a worker
1988// to request filesystem access from worker thread.
1989// FileSystemAPIRequestFromWorker* test 1 of 3
1990IN_PROC_BROWSER_TEST_F(WebViewTest, FileSystemAPIRequestFromWorkerAllow) {
1991  TestHelper("testAllow", "web_view/filesystem/worker", NEEDS_TEST_SERVER);
1992}
1993
1994// FileSystemAPIRequestFromWorker* test 2 of 3.
1995IN_PROC_BROWSER_TEST_F(WebViewTest, FileSystemAPIRequestFromWorkerDeny) {
1996  TestHelper("testDeny", "web_view/filesystem/worker", NEEDS_TEST_SERVER);
1997}
1998
1999// FileSystemAPIRequestFromWorker* test 3 of 3.
2000IN_PROC_BROWSER_TEST_F(WebViewTest,
2001                       FileSystemAPIRequestFromWorkerDefaultAllow) {
2002  TestHelper(
2003      "testDefaultAllow", "web_view/filesystem/worker", NEEDS_TEST_SERVER);
2004}
2005
2006// In following FilesystemAPIRequestFromSharedWorkerOfSingleWebViewGuest* tests,
2007// embedder contains a single webview guest. The guest creates a shared worker
2008// to request filesystem access from worker thread.
2009// FileSystemAPIRequestFromSharedWorkerOfSingleWebViewGuest* test 1 of 3
2010IN_PROC_BROWSER_TEST_F(
2011    WebViewTest,
2012    FileSystemAPIRequestFromSharedWorkerOfSingleWebViewGuestAllow) {
2013  TestHelper("testAllow",
2014             "web_view/filesystem/shared_worker/single",
2015             NEEDS_TEST_SERVER);
2016}
2017
2018// FileSystemAPIRequestFromSharedWorkerOfSingleWebViewGuest* test 2 of 3.
2019IN_PROC_BROWSER_TEST_F(
2020    WebViewTest,
2021    FileSystemAPIRequestFromSharedWorkerOfSingleWebViewGuestDeny) {
2022  TestHelper("testDeny",
2023             "web_view/filesystem/shared_worker/single",
2024             NEEDS_TEST_SERVER);
2025}
2026
2027// FileSystemAPIRequestFromSharedWorkerOfSingleWebViewGuest* test 3 of 3.
2028IN_PROC_BROWSER_TEST_F(
2029    WebViewTest,
2030    FileSystemAPIRequestFromSharedWorkerOfSingleWebViewGuestDefaultAllow) {
2031  TestHelper(
2032      "testDefaultAllow",
2033      "web_view/filesystem/shared_worker/single",
2034      NEEDS_TEST_SERVER);
2035}
2036
2037// In following FilesystemAPIRequestFromSharedWorkerOfMultiWebViewGuests* tests,
2038// embedder contains mutiple webview guests. Each guest creates a shared worker
2039// to request filesystem access from worker thread.
2040// FileSystemAPIRequestFromSharedWorkerOfMultiWebViewGuests* test 1 of 3
2041IN_PROC_BROWSER_TEST_F(
2042    WebViewTest,
2043    FileSystemAPIRequestFromSharedWorkerOfMultiWebViewGuestsAllow) {
2044  TestHelper("testAllow",
2045             "web_view/filesystem/shared_worker/multiple",
2046             NEEDS_TEST_SERVER);
2047}
2048
2049// FileSystemAPIRequestFromSharedWorkerOfMultiWebViewGuests* test 2 of 3.
2050IN_PROC_BROWSER_TEST_F(
2051    WebViewTest,
2052    FileSystemAPIRequestFromSharedWorkerOfMultiWebViewGuestsDeny) {
2053  TestHelper("testDeny",
2054             "web_view/filesystem/shared_worker/multiple",
2055             NEEDS_TEST_SERVER);
2056}
2057
2058// FileSystemAPIRequestFromSharedWorkerOfMultiWebViewGuests* test 3 of 3.
2059IN_PROC_BROWSER_TEST_F(
2060    WebViewTest,
2061    FileSystemAPIRequestFromSharedWorkerOfMultiWebViewGuestsDefaultAllow) {
2062  TestHelper(
2063      "testDefaultAllow",
2064      "web_view/filesystem/shared_worker/multiple",
2065      NEEDS_TEST_SERVER);
2066}
2067
2068IN_PROC_BROWSER_TEST_F(WebViewTest, ClearData) {
2069#if defined(OS_WIN)
2070  // Flaky on XP bot http://crbug.com/282674
2071  if (base::win::GetVersion() <= base::win::VERSION_XP)
2072    return;
2073#endif
2074
2075  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
2076  ASSERT_TRUE(RunPlatformAppTestWithArg(
2077      "platform_apps/web_view/common", "cleardata"))
2078          << message_;
2079}
2080
2081// This test is disabled on Win due to being flaky. http://crbug.com/294592
2082#if defined(OS_WIN)
2083#define MAYBE_ConsoleMessage DISABLED_ConsoleMessage
2084#else
2085#define MAYBE_ConsoleMessage ConsoleMessage
2086#endif
2087IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_ConsoleMessage) {
2088  ASSERT_TRUE(RunPlatformAppTestWithArg(
2089      "platform_apps/web_view/common", "console_messages"))
2090          << message_;
2091}
2092
2093IN_PROC_BROWSER_TEST_F(WebViewTest, DownloadPermission) {
2094  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
2095  content::WebContents* guest_web_contents =
2096      LoadGuest("/extensions/platform_apps/web_view/download/guest.html",
2097                "web_view/download");
2098  ASSERT_TRUE(guest_web_contents);
2099
2100  // Replace WebContentsDelegate with mock version so we can intercept download
2101  // requests.
2102  content::WebContentsDelegate* delegate = guest_web_contents->GetDelegate();
2103  scoped_ptr<MockDownloadWebContentsDelegate>
2104      mock_delegate(new MockDownloadWebContentsDelegate(delegate));
2105  guest_web_contents->SetDelegate(mock_delegate.get());
2106
2107  // Start test.
2108  // 1. Guest requests a download that its embedder denies.
2109  EXPECT_TRUE(content::ExecuteScript(guest_web_contents,
2110                                     "startDownload('download-link-1')"));
2111  mock_delegate->WaitForCanDownload(false); // Expect to not allow.
2112  mock_delegate->Reset();
2113
2114  // 2. Guest requests a download that its embedder allows.
2115  EXPECT_TRUE(content::ExecuteScript(guest_web_contents,
2116                                     "startDownload('download-link-2')"));
2117  mock_delegate->WaitForCanDownload(true); // Expect to allow.
2118  mock_delegate->Reset();
2119
2120  // 3. Guest requests a download that its embedder ignores, this implies deny.
2121  EXPECT_TRUE(content::ExecuteScript(guest_web_contents,
2122                                     "startDownload('download-link-3')"));
2123  mock_delegate->WaitForCanDownload(false); // Expect to not allow.
2124}
2125
2126// This test makes sure loading <webview> does not crash when there is an
2127// extension which has content script whitelisted/forced.
2128IN_PROC_BROWSER_TEST_F(WebViewTest, WhitelistedContentScript) {
2129  // Whitelist the extension for running content script we are going to load.
2130  extensions::ExtensionsClient::ScriptingWhitelist whitelist;
2131  const std::string extension_id = "imeongpbjoodlnmlakaldhlcmijmhpbb";
2132  whitelist.push_back(extension_id);
2133  extensions::ExtensionsClient::Get()->SetScriptingWhitelist(whitelist);
2134
2135  // Load the extension.
2136  const extensions::Extension* content_script_whitelisted_extension =
2137      LoadExtension(test_data_dir_.AppendASCII(
2138                        "platform_apps/web_view/extension_api/content_script"));
2139  ASSERT_TRUE(content_script_whitelisted_extension);
2140  ASSERT_EQ(extension_id, content_script_whitelisted_extension->id());
2141
2142  // Now load an app with <webview>.
2143  LoadAndLaunchPlatformApp("web_view/content_script_whitelisted",
2144                           "TEST_PASSED");
2145}
2146
2147IN_PROC_BROWSER_TEST_F(WebViewTest, SetPropertyOnDocumentReady) {
2148  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/document_ready"))
2149                  << message_;
2150}
2151
2152IN_PROC_BROWSER_TEST_F(WebViewTest, SetPropertyOnDocumentInteractive) {
2153  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/document_interactive"))
2154                  << message_;
2155}
2156
2157IN_PROC_BROWSER_TEST_F(WebViewTest, SpeechRecognitionAPI_HasPermissionAllow) {
2158  ASSERT_TRUE(
2159      RunPlatformAppTestWithArg("platform_apps/web_view/speech_recognition_api",
2160                                "allowTest"))
2161          << message_;
2162}
2163
2164IN_PROC_BROWSER_TEST_F(WebViewTest, SpeechRecognitionAPI_HasPermissionDeny) {
2165  ASSERT_TRUE(
2166      RunPlatformAppTestWithArg("platform_apps/web_view/speech_recognition_api",
2167                                "denyTest"))
2168          << message_;
2169}
2170
2171IN_PROC_BROWSER_TEST_F(WebViewTest, SpeechRecognitionAPI_NoPermission) {
2172  ASSERT_TRUE(
2173      RunPlatformAppTestWithArg("platform_apps/web_view/common",
2174                                "speech_recognition_api_no_permission"))
2175          << message_;
2176}
2177
2178// Tests overriding user agent.
2179IN_PROC_BROWSER_TEST_F(WebViewTest, UserAgent) {
2180  ASSERT_TRUE(RunPlatformAppTestWithArg(
2181              "platform_apps/web_view/common", "useragent")) << message_;
2182}
2183
2184IN_PROC_BROWSER_TEST_F(WebViewTest, UserAgent_NewWindow) {
2185  ASSERT_TRUE(RunPlatformAppTestWithArg(
2186              "platform_apps/web_view/common",
2187              "useragent_newwindow")) << message_;
2188}
2189
2190IN_PROC_BROWSER_TEST_F(WebViewTest, NoPermission) {
2191  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/nopermission"))
2192                  << message_;
2193}
2194
2195IN_PROC_BROWSER_TEST_F(WebViewTest, Dialog_TestAlertDialog) {
2196  TestHelper("testAlertDialog", "web_view/dialog", NO_TEST_SERVER);
2197}
2198
2199IN_PROC_BROWSER_TEST_F(WebViewTest, TestConfirmDialog) {
2200  TestHelper("testConfirmDialog", "web_view/dialog", NO_TEST_SERVER);
2201}
2202
2203IN_PROC_BROWSER_TEST_F(WebViewTest, Dialog_TestConfirmDialogCancel) {
2204  TestHelper("testConfirmDialogCancel", "web_view/dialog", NO_TEST_SERVER);
2205}
2206
2207IN_PROC_BROWSER_TEST_F(WebViewTest, Dialog_TestConfirmDialogDefaultCancel) {
2208  TestHelper("testConfirmDialogDefaultCancel",
2209             "web_view/dialog",
2210             NO_TEST_SERVER);
2211}
2212
2213IN_PROC_BROWSER_TEST_F(WebViewTest, Dialog_TestConfirmDialogDefaultGCCancel) {
2214  TestHelper("testConfirmDialogDefaultGCCancel",
2215             "web_view/dialog",
2216             NO_TEST_SERVER);
2217}
2218
2219IN_PROC_BROWSER_TEST_F(WebViewTest, Dialog_TestPromptDialog) {
2220  TestHelper("testPromptDialog", "web_view/dialog", NO_TEST_SERVER);
2221}
2222
2223IN_PROC_BROWSER_TEST_F(WebViewTest, NoContentSettingsAPI) {
2224  // Load the extension.
2225  const extensions::Extension* content_settings_extension =
2226      LoadExtension(
2227          test_data_dir_.AppendASCII(
2228              "platform_apps/web_view/extension_api/content_settings"));
2229  ASSERT_TRUE(content_settings_extension);
2230  TestHelper("testPostMessageCommChannel", "web_view/shim", NO_TEST_SERVER);
2231}
2232
2233#if defined(ENABLE_PLUGINS)
2234class WebViewPluginTest : public WebViewTest {
2235 protected:
2236  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
2237    WebViewTest::SetUpCommandLine(command_line);
2238
2239    // Append the switch to register the pepper plugin.
2240    // library name = <out dir>/<test_name>.<library_extension>
2241    // MIME type = application/x-ppapi-<test_name>
2242    base::FilePath plugin_dir;
2243    EXPECT_TRUE(PathService::Get(base::DIR_MODULE, &plugin_dir));
2244
2245    base::FilePath plugin_lib = plugin_dir.Append(library_name);
2246    EXPECT_TRUE(base::PathExists(plugin_lib));
2247    base::FilePath::StringType pepper_plugin = plugin_lib.value();
2248    pepper_plugin.append(FILE_PATH_LITERAL(";application/x-ppapi-tests"));
2249    command_line->AppendSwitchNative(switches::kRegisterPepperPlugins,
2250                                     pepper_plugin);
2251  }
2252};
2253
2254IN_PROC_BROWSER_TEST_F(WebViewPluginTest, TestLoadPluginEvent) {
2255  TestHelper("testPluginLoadPermission", "web_view/shim", NO_TEST_SERVER);
2256}
2257#endif  // defined(ENABLE_PLUGINS)
2258
2259class WebViewCaptureTest : public WebViewTest {
2260 public:
2261  WebViewCaptureTest() {}
2262  virtual ~WebViewCaptureTest() {}
2263  virtual void SetUp() OVERRIDE {
2264    EnablePixelOutput();
2265    WebViewTest::SetUp();
2266  }
2267};
2268
2269IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestZoomAPI) {
2270  TestHelper("testZoomAPI", "web_view/shim", NO_TEST_SERVER);
2271}
2272
2273IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestFindAPI) {
2274  TestHelper("testFindAPI", "web_view/shim", NO_TEST_SERVER);
2275}
2276
2277IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestFindAPI_findupdate) {
2278  TestHelper("testFindAPI_findupdate", "web_view/shim", NO_TEST_SERVER);
2279}
2280
2281// <webview> screenshot capture fails with ubercomp.
2282// See http://crbug.com/327035.
2283IN_PROC_BROWSER_TEST_F(WebViewCaptureTest,
2284                       DISABLED_Shim_ScreenshotCapture) {
2285  TestHelper("testScreenshotCapture", "web_view/shim", NO_TEST_SERVER);
2286}
2287
2288#if defined(OS_WIN)
2289// Test is disabled on Windows because it times out often.
2290// http://crbug.com/403325
2291#define MAYBE_WebViewInBackgroundPage \
2292    DISABLED_WebViewInBackgroundPage
2293#else
2294#define MAYBE_WebViewInBackgroundPage WebViewInBackgroundPage
2295#endif
2296IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_WebViewInBackgroundPage) {
2297  ASSERT_TRUE(RunExtensionTest("platform_apps/web_view/background"))
2298      << message_;
2299}
2300