// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <set>
#include <utility>

#include "base/callback_helpers.h"
#include "base/containers/queue.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/guid.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/path_service.h"
#include "base/process/process.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/apps/app_browsertest_util.h"
#include "chrome/browser/chrome_content_browser_client.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/download/download_core_service.h"
#include "chrome/browser/download/download_core_service_factory.h"
#include "chrome/browser/download/download_history.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/pdf/pdf_extension_test_util.h"
#include "chrome/browser/prerender/prerender_link_manager.h"
#include "chrome/browser/prerender/prerender_link_manager_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
#include "chrome/browser/task_manager/task_manager_browsertest_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/guest_view/browser/guest_view_manager.h"
#include "components/guest_view/browser/guest_view_manager_delegate.h"
#include "components/guest_view/browser/guest_view_manager_factory.h"
#include "components/guest_view/browser/test_guest_view_manager.h"
#include "components/viz/common/features.h"
#include "content/public/browser/ax_event_notification_details.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/interstitial_page.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/result_codes.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/download_test_observer.h"
#include "content/public/test/fake_speech_recognition_manager.h"
#include "content/public/test/test_file_error_injector.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/test_utils.h"
#include "device/geolocation/public/cpp/scoped_geolocation_overrider.h"
#include "extensions/browser/api/declarative/rules_registry.h"
#include "extensions/browser/api/declarative/rules_registry_service.h"
#include "extensions/browser/api/declarative/test_rules_registry.h"
#include "extensions/browser/api/declarative_webrequest/webrequest_constants.h"
#include "extensions/browser/api/extensions_api_client.h"
#include "extensions/browser/app_window/native_app_window.h"
#include "extensions/browser/guest_view/web_view/web_view_guest.h"
#include "extensions/common/extension.h"
#include "extensions/common/extensions_client.h"
#include "extensions/test/extension_test_message_listener.h"
#include "media/base/media_switches.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "ppapi/features/features.h"
#include "third_party/WebKit/public/platform/WebMouseEvent.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/compositor_observer.h"
#include "ui/display/display_switches.h"
#include "ui/events/gesture_detection/gesture_configuration.h"
#include "ui/gl/gl_switches.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"

#if BUILDFLAG(ENABLE_PLUGINS)
#include "content/public/browser/plugin_service.h"
#include "content/public/common/webplugininfo.h"
#include "content/public/test/ppapi_test_utils.h"
#endif

using extensions::ContextMenuMatcher;
using extensions::ExtensionsAPIClient;
using extensions::MenuItem;
using guest_view::GuestViewManager;
using guest_view::TestGuestViewManager;
using guest_view::TestGuestViewManagerFactory;
using prerender::PrerenderLinkManager;
using prerender::PrerenderLinkManagerFactory;
using task_manager::browsertest_util::MatchAboutBlankTab;
using task_manager::browsertest_util::MatchAnyApp;
using task_manager::browsertest_util::MatchAnyBackground;
using task_manager::browsertest_util::MatchAnyTab;
using task_manager::browsertest_util::MatchAnyWebView;
using task_manager::browsertest_util::MatchApp;
using task_manager::browsertest_util::MatchBackground;
using task_manager::browsertest_util::MatchWebView;
using task_manager::browsertest_util::WaitForTaskManagerRows;
using ui::MenuModel;

namespace {
const char kEmptyResponsePath[] = "/close-socket";
const char kRedirectResponsePath[] = "/server-redirect";
const char kUserAgentRedirectResponsePath[] = "/detect-user-agent";
const char kCacheResponsePath[] = "/cache-control-response";
const char kRedirectResponseFullPath[] =
    "/extensions/platform_apps/web_view/shim/guest_redirect.html";

class WebContentsHiddenObserver : public content::WebContentsObserver {
 public:
  WebContentsHiddenObserver(content::WebContents* web_contents,
                            const base::Closure& hidden_callback)
      : WebContentsObserver(web_contents),
        hidden_callback_(hidden_callback),
        hidden_observed_(false) {
  }

  // WebContentsObserver.
  void WasHidden() override {
    hidden_observed_ = true;
    hidden_callback_.Run();
  }

  bool hidden_observed() { return hidden_observed_; }

 private:
  base::Closure hidden_callback_;
  bool hidden_observed_;

  DISALLOW_COPY_AND_ASSIGN(WebContentsHiddenObserver);
};

// Watches for context menu to be shown, records count of how many times
// context menu was shown.
class ContextMenuCallCountObserver {
 public:
  ContextMenuCallCountObserver()
      : num_times_shown_(0),
        menu_observer_(chrome::NOTIFICATION_RENDER_VIEW_CONTEXT_MENU_SHOWN,
                       base::Bind(&ContextMenuCallCountObserver::OnMenuShown,
                                  base::Unretained(this))) {
  }
  ~ContextMenuCallCountObserver() {}

  bool OnMenuShown(const content::NotificationSource& source,
                   const content::NotificationDetails& details) {
    ++num_times_shown_;
    auto* context_menu = content::Source<RenderViewContextMenu>(source).ptr();
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(&RenderViewContextMenuBase::Cancel,
                                  base::Unretained(context_menu)));
    return true;
  }

  void Wait() { menu_observer_.Wait(); }

  int num_times_shown() { return num_times_shown_; }

 private:
  int num_times_shown_;
  content::WindowedNotificationObserver menu_observer_;

  DISALLOW_COPY_AND_ASSIGN(ContextMenuCallCountObserver);
};

class EmbedderWebContentsObserver : public content::WebContentsObserver {
 public:
  explicit EmbedderWebContentsObserver(content::WebContents* web_contents)
      : WebContentsObserver(web_contents), terminated_(false) {}

  // WebContentsObserver.
  void RenderProcessGone(base::TerminationStatus status) override {
    terminated_ = true;
    if (message_loop_runner_.get())
      message_loop_runner_->Quit();
  }

  void WaitForEmbedderRenderProcessTerminate() {
    if (terminated_)
      return;
    message_loop_runner_ = new content::MessageLoopRunner;
    message_loop_runner_->Run();
  }

 private:
  bool terminated_;
  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;

  DISALLOW_COPY_AND_ASSIGN(EmbedderWebContentsObserver);
};

void ExecuteScriptWaitForTitle(content::WebContents* web_contents,
                               const char* script,
                               const char* title) {
  base::string16 expected_title(base::ASCIIToUTF16(title));
  base::string16 error_title(base::ASCIIToUTF16("error"));

  content::TitleWatcher title_watcher(web_contents, expected_title);
  title_watcher.AlsoWaitForTitle(error_title);
  EXPECT_TRUE(content::ExecuteScript(web_contents, script));
  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
}

#if defined (USE_AURA)
views::View* FindWebView(views::View* view) {
  base::queue<views::View*> queue;
  queue.push(view);
  while (!queue.empty()) {
    views::View* current = queue.front();
    queue.pop();
    if (std::string(current->GetClassName()).find("WebView") !=
        std::string::npos) {
      return current;
    }

    for (int i = 0; i < current->child_count(); ++i)
      queue.push(current->child_at(i));
  }
  return nullptr;
}

// Waits for select control shown/closed.
class SelectControlWaiter : public aura::WindowObserver,
                            public aura::EnvObserver {
 public:
  SelectControlWaiter() {
    aura::Env::GetInstanceDontCreate()->AddObserver(this);
  }

  ~SelectControlWaiter() override {
    aura::Env::GetInstanceDontCreate()->RemoveObserver(this);
  }

  void Wait(bool wait_for_widget_shown) {
    wait_for_widget_shown_ = wait_for_widget_shown;
    message_loop_runner_ = new content::MessageLoopRunner;
    message_loop_runner_->Run();
    base::RunLoop().RunUntilIdle();
  }

  void OnWindowVisibilityChanged(aura::Window* window, bool visible) override {
    if (wait_for_widget_shown_ && visible)
      message_loop_runner_->Quit();
  }

  void OnWindowInitialized(aura::Window* window) override {
    if (window->type() != aura::client::WINDOW_TYPE_MENU)
      return;
    window->AddObserver(this);
    observed_windows_.insert(window);
  }

  void OnWindowDestroyed(aura::Window* window) override {
    observed_windows_.erase(window);
    if (!wait_for_widget_shown_ && observed_windows_.empty())
      message_loop_runner_->Quit();
  }

 private:
  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
  std::set<aura::Window*> observed_windows_;
  bool wait_for_widget_shown_ = false;

  DISALLOW_COPY_AND_ASSIGN(SelectControlWaiter);
};

// Simulate real click with delay between mouse down and up.
class LeftMouseClick {
 public:
  explicit LeftMouseClick(content::WebContents* web_contents)
      : web_contents_(web_contents),
        mouse_event_(blink::WebInputEvent::kMouseDown,
                     blink::WebInputEvent::kNoModifiers,
                     blink::WebInputEvent::kTimeStampForTesting) {
    mouse_event_.button = blink::WebMouseEvent::Button::kLeft;
  }

  ~LeftMouseClick() {
    DCHECK(click_completed_);
  }

  void Click(const gfx::Point& point, int duration_ms) {
    DCHECK(click_completed_);
    click_completed_ = false;
    mouse_event_.SetType(blink::WebInputEvent::kMouseDown);
    mouse_event_.SetPositionInWidget(point.x(), point.y());
    const gfx::Rect offset = web_contents_->GetContainerBounds();
    mouse_event_.SetPositionInScreen(point.x() + offset.x(),
                                     point.y() + offset.y());
    mouse_event_.click_count = 1;
    web_contents_->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
        mouse_event_);

    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE,
        base::BindOnce(&LeftMouseClick::SendMouseUp, base::Unretained(this)),
        base::TimeDelta::FromMilliseconds(duration_ms));
  }

  // Wait for click completed.
  void Wait() {
    if (click_completed_)
      return;
    message_loop_runner_ = new content::MessageLoopRunner;
    message_loop_runner_->Run();
    message_loop_runner_ = nullptr;
  }

 private:
  void SendMouseUp() {
    mouse_event_.SetType(blink::WebInputEvent::kMouseUp);
    web_contents_->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
        mouse_event_);
    click_completed_ = true;
    if (message_loop_runner_)
      message_loop_runner_->Quit();
  }

  // Unowned pointer.
  content::WebContents* web_contents_;

  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;

  blink::WebMouseEvent mouse_event_;

  bool click_completed_ = true;

  DISALLOW_COPY_AND_ASSIGN(LeftMouseClick);
};

#endif

}  // namespace

// This class intercepts media access request from the embedder. The request
// should be triggered only if the embedder API (from tests) allows the request
// in Javascript.
// We do not issue the actual media request; the fact that the request reached
// embedder's WebContents is good enough for our tests. This is also to make
// the test run successfully on trybots.
class MockWebContentsDelegate : public content::WebContentsDelegate {
 public:
  MockWebContentsDelegate()
      : requested_(false),
        checked_(false) {}
  ~MockWebContentsDelegate() override {}

  void RequestMediaAccessPermission(
      content::WebContents* web_contents,
      const content::MediaStreamRequest& request,
      const content::MediaResponseCallback& callback) override {
    requested_ = true;
    if (request_message_loop_runner_.get())
      request_message_loop_runner_->Quit();
  }

  bool CheckMediaAccessPermission(content::WebContents* web_contents,
                                  const GURL& security_origin,
                                  content::MediaStreamType type) override {
    checked_ = true;
    if (check_message_loop_runner_.get())
      check_message_loop_runner_->Quit();
    return true;
  }

  void WaitForRequestMediaPermission() {
    if (requested_)
      return;
    request_message_loop_runner_ = new content::MessageLoopRunner;
    request_message_loop_runner_->Run();
  }

  void WaitForCheckMediaPermission() {
    if (checked_)
      return;
    check_message_loop_runner_ = new content::MessageLoopRunner;
    check_message_loop_runner_->Run();
  }

 private:
  bool requested_;
  bool checked_;
  scoped_refptr<content::MessageLoopRunner> request_message_loop_runner_;
  scoped_refptr<content::MessageLoopRunner> check_message_loop_runner_;

  DISALLOW_COPY_AND_ASSIGN(MockWebContentsDelegate);
};

// This class intercepts download request from the guest.
class MockDownloadWebContentsDelegate : public content::WebContentsDelegate {
 public:
  explicit MockDownloadWebContentsDelegate(
      content::WebContentsDelegate* orig_delegate)
      : orig_delegate_(orig_delegate),
        waiting_for_decision_(false),
        expect_allow_(false),
        decision_made_(false),
        last_download_allowed_(false) {}
  ~MockDownloadWebContentsDelegate() override {}

  void CanDownload(const GURL& url,
                   const std::string& request_method,
                   const base::Callback<void(bool)>& callback) override {
    orig_delegate_->CanDownload(
        url, request_method,
        base::Bind(&MockDownloadWebContentsDelegate::DownloadDecided,
                   base::Unretained(this), callback));
  }

  void WaitForCanDownload(bool expect_allow) {
    EXPECT_FALSE(waiting_for_decision_);
    waiting_for_decision_ = true;

    if (decision_made_) {
      EXPECT_EQ(expect_allow, last_download_allowed_);
      return;
    }

    expect_allow_ = expect_allow;
    message_loop_runner_ = new content::MessageLoopRunner;
    message_loop_runner_->Run();
  }

  void DownloadDecided(const base::Callback<void(bool)>& callback, bool allow) {
    EXPECT_FALSE(decision_made_);
    decision_made_ = true;

    if (waiting_for_decision_) {
      EXPECT_EQ(expect_allow_, allow);
      if (message_loop_runner_.get())
        message_loop_runner_->Quit();
      callback.Run(allow);
      return;
    }
    last_download_allowed_ = allow;
    callback.Run(allow);
  }

  void Reset() {
    waiting_for_decision_ = false;
    decision_made_ = false;
  }

 private:
  content::WebContentsDelegate* orig_delegate_;
  bool waiting_for_decision_;
  bool expect_allow_;
  bool decision_made_;
  bool last_download_allowed_;
  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;

  DISALLOW_COPY_AND_ASSIGN(MockDownloadWebContentsDelegate);
};

// TODO(wjmaclean): Fix this test class at some point so it can be re-enabled on
// the site isolation bots, and then look at re-enabling WebViewFocusTest when
// that happens.
// https://crbug.com/503751
class WebViewTestBase : public extensions::PlatformAppBrowserTest {
 protected:
  void SetUp() override {
    if (UsesFakeSpeech()) {
      // SpeechRecognition test specific SetUp.
      fake_speech_recognition_manager_.reset(
          new content::FakeSpeechRecognitionManager());
      fake_speech_recognition_manager_->set_should_send_fake_response(true);
      // Inject the fake manager factory so that the test result is returned to
      // the web page.
      content::SpeechRecognitionManager::SetManagerForTesting(
          fake_speech_recognition_manager_.get());
    }
    extensions::PlatformAppBrowserTest::SetUp();
  }

  void TearDown() override {
    if (UsesFakeSpeech()) {
      // SpeechRecognition test specific TearDown.
      content::SpeechRecognitionManager::SetManagerForTesting(NULL);
    }

    extensions::PlatformAppBrowserTest::TearDown();
  }

  void SetUpOnMainThread() override {
    extensions::PlatformAppBrowserTest::SetUpOnMainThread();
    const testing::TestInfo* const test_info =
        testing::UnitTest::GetInstance()->current_test_info();
    // Mock out geolocation for geolocation specific tests.
    if (!strncmp(test_info->name(), "GeolocationAPI",
            strlen("GeolocationAPI"))) {
      geolocation_overrider_ =
          std::make_unique<device::ScopedGeolocationOverrider>(10, 20);
    }
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
    command_line->AppendSwitchASCII(switches::kJavaScriptFlags, "--expose-gc");

    extensions::PlatformAppBrowserTest::SetUpCommandLine(command_line);
  }

  // Handles |request| by serving a redirect response if the |User-Agent| is
  // foobar.
  static std::unique_ptr<net::test_server::HttpResponse>
  UserAgentResponseHandler(const std::string& path,
                           const GURL& redirect_target,
                           const net::test_server::HttpRequest& request) {
    if (!base::StartsWith(path, request.relative_url,
                          base::CompareCase::SENSITIVE))
      return std::unique_ptr<net::test_server::HttpResponse>();

    auto it = request.headers.find("User-Agent");
    EXPECT_TRUE(it != request.headers.end());
    if (!base::StartsWith("foobar", it->second,
                          base::CompareCase::SENSITIVE))
      return std::unique_ptr<net::test_server::HttpResponse>();

    std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
        new net::test_server::BasicHttpResponse);
    http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
    http_response->AddCustomHeader("Location", redirect_target.spec());
    return std::move(http_response);
  }

  // Handles |request| by serving a redirect response.
  static std::unique_ptr<net::test_server::HttpResponse>
  RedirectResponseHandler(const std::string& path,
                          const GURL& redirect_target,
                          const net::test_server::HttpRequest& request) {
    if (!base::StartsWith(path, request.relative_url,
                          base::CompareCase::SENSITIVE))
      return std::unique_ptr<net::test_server::HttpResponse>();

    std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
        new net::test_server::BasicHttpResponse);
    http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
    http_response->AddCustomHeader("Location", redirect_target.spec());
    return std::move(http_response);
  }

  // Handles |request| by serving an empty response.
  static std::unique_ptr<net::test_server::HttpResponse> EmptyResponseHandler(
      const std::string& path,
      const net::test_server::HttpRequest& request) {
    if (base::StartsWith(path, request.relative_url,
                         base::CompareCase::SENSITIVE))
      return std::unique_ptr<net::test_server::HttpResponse>(
          new net::test_server::RawHttpResponse("", ""));

    return std::unique_ptr<net::test_server::HttpResponse>();
  }

  // Handles |request| by serving cache-able response.
  static std::unique_ptr<net::test_server::HttpResponse>
  CacheControlResponseHandler(const std::string& path,
                              const net::test_server::HttpRequest& request) {
    if (!base::StartsWith(path, request.relative_url,
                          base::CompareCase::SENSITIVE))
      return std::unique_ptr<net::test_server::HttpResponse>();

    std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
        new net::test_server::BasicHttpResponse);
    http_response->AddCustomHeader("Cache-control", "max-age=3600");
    http_response->set_content_type("text/plain");
    http_response->set_content("dummy text");
    return std::move(http_response);
  }

  // Shortcut to return the current MenuManager.
  extensions::MenuManager* menu_manager() {
    return extensions::MenuManager::Get(browser()->profile());
  }

  // This gets all the items that any extension has registered for possible
  // inclusion in context menus.
  MenuItem::List GetItems() {
    MenuItem::List result;
    std::set<MenuItem::ExtensionKey> extension_ids =
        menu_manager()->ExtensionIds();
    std::set<MenuItem::ExtensionKey>::iterator i;
    for (i = extension_ids.begin(); i != extension_ids.end(); ++i) {
      const MenuItem::OwnedList* list = menu_manager()->MenuItems(*i);
      for (const auto& item : *list)
        result.push_back(item.get());
    }
    return result;
  }

  enum TestServer {
    NEEDS_TEST_SERVER,
    NO_TEST_SERVER
  };

  void TestHelper(const std::string& test_name,
                  const std::string& app_location,
                  TestServer test_server) {
    // For serving guest pages.
    if (test_server == NEEDS_TEST_SERVER) {
      if (!InitializeEmbeddedTestServer()) {
        LOG(ERROR) << "FAILED TO START TEST SERVER.";
        return;
      }
      embedded_test_server()->RegisterRequestHandler(base::Bind(
          &WebViewTestBase::RedirectResponseHandler, kRedirectResponsePath,
          embedded_test_server()->GetURL(kRedirectResponseFullPath)));

      embedded_test_server()->RegisterRequestHandler(base::Bind(
          &WebViewTestBase::EmptyResponseHandler, kEmptyResponsePath));

      embedded_test_server()->RegisterRequestHandler(base::Bind(
          &WebViewTestBase::UserAgentResponseHandler,
          kUserAgentRedirectResponsePath,
          embedded_test_server()->GetURL(kRedirectResponseFullPath)));

      embedded_test_server()->RegisterRequestHandler(base::Bind(
          &WebViewTestBase::CacheControlResponseHandler, kCacheResponsePath));

      EmbeddedTestServerAcceptConnections();
    }

    LoadAndLaunchPlatformApp(app_location.c_str(), "Launched");

    // Flush any pending events to make sure we start with a clean slate.
    content::RunAllPendingInMessageLoop();

    content::WebContents* embedder_web_contents =
        GetFirstAppWindowWebContents();
    if (!embedder_web_contents) {
      LOG(ERROR) << "UNABLE TO FIND EMBEDDER WEB CONTENTS.";
      return;
    }

    ExtensionTestMessageListener done_listener("TEST_PASSED", false);
    done_listener.set_failure_message("TEST_FAILED");
    if (!content::ExecuteScript(
            embedder_web_contents,
            base::StringPrintf("runTest('%s')", test_name.c_str()))) {
      LOG(ERROR) << "UNABLE TO START TEST.";
      return;
    }
    ASSERT_TRUE(done_listener.WaitUntilSatisfied());
  }

  content::WebContents* LoadGuest(const std::string& guest_path,
                                  const std::string& app_path) {
    GURL::Replacements replace_host;
    replace_host.SetHostStr("localhost");

    GURL guest_url = embedded_test_server()->GetURL(guest_path);
    guest_url = guest_url.ReplaceComponents(replace_host);

    ui_test_utils::UrlLoadObserver guest_observer(
        guest_url, content::NotificationService::AllSources());

    LoadAndLaunchPlatformApp(app_path.c_str(), "guest-loaded");

    guest_observer.Wait();
    content::Source<content::NavigationController> source =
        guest_observer.source();
    EXPECT_TRUE(source->GetWebContents()
                    ->GetMainFrame()
                    ->GetProcess()
                    ->IsForGuestsOnly());

    content::WebContents* guest_web_contents = source->GetWebContents();
    return guest_web_contents;
  }

  // Helper to load interstitial page in a <webview>.
  void InterstitialTestHelper() {
    // Start a HTTPS server so we can load an interstitial page inside guest.
    net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
    https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_MISMATCHED_NAME);
    https_server.ServeFilesFromSourceDirectory("chrome/test/data");
    ASSERT_TRUE(https_server.Start());

    net::HostPortPair host_and_port = https_server.host_port_pair();

    LoadAndLaunchPlatformApp("web_view/interstitial_teardown",
                             "EmbedderLoaded");

    // Create the guest.
    content::WebContents* embedder_web_contents =
        GetFirstAppWindowWebContents();
    ExtensionTestMessageListener guest_added("GuestAddedToDom", false);
    EXPECT_TRUE(content::ExecuteScript(embedder_web_contents,
                                       base::StringPrintf("createGuest();\n")));
    ASSERT_TRUE(guest_added.WaitUntilSatisfied());

    // Now load the guest.
    ExtensionTestMessageListener guest_loaded("GuestLoaded", false);
    EXPECT_TRUE(content::ExecuteScript(
        embedder_web_contents,
        base::StringPrintf("loadGuest(%d);\n", host_and_port.port())));
    ASSERT_TRUE(guest_loaded.WaitUntilSatisfied());

    // Wait for interstitial page to be shown in guest.
    content::WebContents* guest_web_contents =
        GetGuestViewManager()->WaitForSingleGuestCreated();
    ASSERT_TRUE(
        guest_web_contents->GetMainFrame()->GetProcess()->IsForGuestsOnly());
    content::WaitForInterstitialAttach(guest_web_contents);
  }

  // Runs media_access/allow tests.
  void MediaAccessAPIAllowTestHelper(const std::string& test_name);

  // Runs media_access/deny tests, each of them are run separately otherwise
  // they timeout (mostly on Windows).
  void MediaAccessAPIDenyTestHelper(const std::string& test_name) {
    ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
    LoadAndLaunchPlatformApp("web_view/media_access/deny", "loaded");

    content::WebContents* embedder_web_contents =
        GetFirstAppWindowWebContents();
    ASSERT_TRUE(embedder_web_contents);

    ExtensionTestMessageListener test_run_listener("PASSED", false);
    test_run_listener.set_failure_message("FAILED");
    EXPECT_TRUE(
        content::ExecuteScript(
            embedder_web_contents,
            base::StringPrintf("startDenyTest('%s')", test_name.c_str())));
    ASSERT_TRUE(test_run_listener.WaitUntilSatisfied());
  }

  // Loads an app with a <webview> in it, returns once a guest is created.
  void LoadAppWithGuest(const std::string& app_path) {
    ExtensionTestMessageListener launched_listener("WebViewTest.LAUNCHED",
                                                   false);
    launched_listener.set_failure_message("WebViewTest.FAILURE");
    LoadAndLaunchPlatformApp(app_path.c_str(), &launched_listener);

    guest_web_contents_ = GetGuestViewManager()->WaitForSingleGuestCreated();
  }

  void SendMessageToEmbedder(const std::string& message) {
    EXPECT_TRUE(
        content::ExecuteScript(
            GetEmbedderWebContents(),
            base::StringPrintf("onAppCommand('%s');", message.c_str())));
  }

  void SendMessageToGuestAndWait(const std::string& message,
                                 const std::string& wait_message) {
    std::unique_ptr<ExtensionTestMessageListener> listener;
    if (!wait_message.empty()) {
      listener.reset(new ExtensionTestMessageListener(wait_message, false));
    }

    EXPECT_TRUE(
        content::ExecuteScript(
            GetGuestWebContents(),
            base::StringPrintf("onAppCommand('%s');", message.c_str())));

    if (listener) {
      ASSERT_TRUE(listener->WaitUntilSatisfied());
    }
  }

  void OpenContextMenu(content::WebContents* web_contents) {
    blink::WebMouseEvent mouse_event(
        blink::WebInputEvent::kMouseDown, blink::WebInputEvent::kNoModifiers,
        blink::WebInputEvent::kTimeStampForTesting);
    mouse_event.button = blink::WebMouseEvent::Button::kRight;
    mouse_event.SetPositionInWidget(1, 1);
    web_contents->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
        mouse_event);
    mouse_event.SetType(blink::WebInputEvent::kMouseUp);
    web_contents->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
        mouse_event);
  }

  content::WebContents* GetGuestWebContents() {
    return guest_web_contents_;
  }

  content::WebContents* GetEmbedderWebContents() {
    if (!embedder_web_contents_) {
      embedder_web_contents_ = GetFirstAppWindowWebContents();
    }
    return embedder_web_contents_;
  }

  TestGuestViewManager* GetGuestViewManager() {
    TestGuestViewManager* manager = static_cast<TestGuestViewManager*>(
        TestGuestViewManager::FromBrowserContext(browser()->profile()));
    // TestGuestViewManager::WaitForSingleGuestCreated may and will get called
    // before a guest is created.
    if (!manager) {
      manager = static_cast<TestGuestViewManager*>(
          GuestViewManager::CreateWithDelegate(
              browser()->profile(),
              ExtensionsAPIClient::Get()->CreateGuestViewManagerDelegate(
                  browser()->profile())));
    }
    return manager;
  }

  WebViewTestBase() : guest_web_contents_(NULL), embedder_web_contents_(NULL) {
    GuestViewManager::set_factory_for_testing(&factory_);
  }

  ~WebViewTestBase() override {}

 private:
  bool UsesFakeSpeech() {
    const testing::TestInfo* const test_info =
        testing::UnitTest::GetInstance()->current_test_info();

    // SpeechRecognition test specific SetUp.
    const char* name = "SpeechRecognitionAPI_HasPermissionAllow";
    return !strncmp(test_info->name(), name, strlen(name));
  }

  std::unique_ptr<device::ScopedGeolocationOverrider> geolocation_overrider_;
  std::unique_ptr<content::FakeSpeechRecognitionManager>
      fake_speech_recognition_manager_;

  TestGuestViewManagerFactory factory_;
  // Note that these are only set if you launch app using LoadAppWithGuest().
  content::WebContents* guest_web_contents_;
  content::WebContents* embedder_web_contents_;
};

class WebViewTest : public WebViewTestBase,
                    public testing::WithParamInterface<bool> {
 public:
  WebViewTest() {}
  ~WebViewTest() override {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    WebViewTestBase::SetUpCommandLine(command_line);

    bool use_cross_process_frames_for_guests = GetParam();
    if (use_cross_process_frames_for_guests) {
      scoped_feature_list_.InitAndEnableFeature(
          features::kGuestViewCrossProcessFrames);
    } else {
      scoped_feature_list_.InitAndDisableFeature(
          features::kGuestViewCrossProcessFrames);
    }
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

INSTANTIATE_TEST_CASE_P(WebViewTests, WebViewTest, testing::Bool());

class WebViewNewWindowTest : public WebViewTest {};
INSTANTIATE_TEST_CASE_P(WebViewTests, WebViewNewWindowTest, testing::Bool());

class WebViewSizeTest : public WebViewTest {};
INSTANTIATE_TEST_CASE_P(WebViewTests, WebViewSizeTest, testing::Bool());

class WebViewVisibilityTest : public WebViewTest {};
INSTANTIATE_TEST_CASE_P(WebViewTests, WebViewVisibilityTest, testing::Bool());

class WebViewSpeechAPITest : public WebViewTest {};
INSTANTIATE_TEST_CASE_P(WebViewTests, WebViewSpeechAPITest, testing::Bool());

// The following test suites are created to group tests based on specific
// features of <webview>.
class WebViewAccessibilityTest : public WebViewTest {};
INSTANTIATE_TEST_CASE_P(WebViewTests,
                        WebViewAccessibilityTest,
                        testing::Bool());

class WebViewDPITest : public WebViewTest {
 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    WebViewTest::SetUpCommandLine(command_line);
    command_line->AppendSwitchASCII(switches::kForceDeviceScaleFactor,
                                    base::StringPrintf("%f", scale()));
  }

  static float scale() { return 2.0f; }
};
INSTANTIATE_TEST_CASE_P(WebViewTests, WebViewDPITest, testing::Bool());

class WebViewSurfaceSynchronizationTest : public WebViewTest {
 public:
  WebViewSurfaceSynchronizationTest() = default;
  ~WebViewSurfaceSynchronizationTest() override = default;

  void SetUp() override {
    scoped_feature_list_.InitAndEnableFeature(
        features::kEnableSurfaceSynchronization);
    WebViewTestBase::SetUp();
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;

  DISALLOW_COPY_AND_ASSIGN(WebViewSurfaceSynchronizationTest);
};

INSTANTIATE_TEST_CASE_P(WebViewTests,
                        WebViewSurfaceSynchronizationTest,
                        testing::Bool());

class WebViewWithZoomForDSFTest : public WebViewTest {
 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    WebViewTest::SetUpCommandLine(command_line);
    command_line->AppendSwitchASCII(switches::kForceDeviceScaleFactor,
                                    base::StringPrintf("%f", scale()));
    command_line->AppendSwitch(switches::kEnableUseZoomForDSF);
  }

  static float scale() { return 2.0f; }
};

class WebContentsAudioMutedObserver : public content::WebContentsObserver {
 public:
  explicit WebContentsAudioMutedObserver(content::WebContents* web_contents)
      : WebContentsObserver(web_contents),
        loop_runner_(new content::MessageLoopRunner),
        muting_update_observed_(false) {}

  // WebContentsObserver.
  void DidUpdateAudioMutingState(bool muted) override {
    muting_update_observed_ = true;
    loop_runner_->Quit();
  }

  void WaitForUpdate() {
    loop_runner_->Run();
  }

  bool muting_update_observed() { return muting_update_observed_; }

 private:
  scoped_refptr<content::MessageLoopRunner> loop_runner_;
  bool muting_update_observed_;

  DISALLOW_COPY_AND_ASSIGN(WebContentsAudioMutedObserver);
};

class WasAudibleWebContentsDelegate : public content::WebContentsDelegate {
 public:
  WasAudibleWebContentsDelegate() : invalidate_type_tab_seen_(false) {}

  void NavigationStateChanged(content::WebContents* contents,
                              content::InvalidateTypes changed_flags) override {
    if (changed_flags == content::INVALIDATE_TYPE_TAB) {
      invalidate_type_tab_seen_ = true;
      if (message_loop_runner_.get())
        message_loop_runner_->Quit();
    }
  }

  void WaitForInvalidateTypeTab() {
    if (!invalidate_type_tab_seen_) {
      message_loop_runner_ = new content::MessageLoopRunner;
      message_loop_runner_->Run();
    }
    invalidate_type_tab_seen_ = false;
  }

 private:
  bool invalidate_type_tab_seen_;
  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;

  DISALLOW_COPY_AND_ASSIGN(WasAudibleWebContentsDelegate);
};

IN_PROC_BROWSER_TEST_P(WebViewTest, AudibilityStatePropagates) {
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest audio.

  LoadAppWithGuest("web_view/simple");

  content::WebContents* embedder = GetEmbedderWebContents();
  content::WebContents* guest = GetGuestWebContents();

  EXPECT_FALSE(embedder->WasRecentlyAudible());
  EXPECT_FALSE(guest->WasRecentlyAudible());

  std::unique_ptr<WasAudibleWebContentsDelegate> was_audible_delegate(
      new WasAudibleWebContentsDelegate);
  embedder->SetDelegate(was_audible_delegate.get());

  // Just in case we get console error messages from the guest, we should
  // surface them in the test output.
  EXPECT_TRUE(content::ExecuteScript(
      embedder,
      "wv = document.getElementsByTagName('webview')[0];"
      "wv.addEventListener('consolemessage', function (e) {"
      "  console.log('WebViewTest Guest: ' + e.message);"
      "});"));

  // Inject JS to start audio.
  GURL audio_url = embedded_test_server()->GetURL(
      "/extensions/platform_apps/web_view/simple/ping.mp3");
  std::string setup_audio_script = base::StringPrintf(
      "ae = document.createElement('audio');"
      "ae.src='%s';"
      "document.body.appendChild(ae);"
      "ae.play();",
      audio_url.spec().c_str());
  EXPECT_TRUE(content::ExecuteScript(guest, setup_audio_script));

  was_audible_delegate->WaitForInvalidateTypeTab();
  EXPECT_TRUE(embedder->WasRecentlyAudible());
  EXPECT_TRUE(guest->WasRecentlyAudible());

  // Wait for audio to stop (the .mp3 is shorter than the audio stream
  // monitor's timeout, so no need to explicitly stop it. Other callers may
  // call NotifyNavigationStateChanged() on the embedder web contents, so
  // we may have to wait several times).
  while (embedder->WasRecentlyAudible())
    was_audible_delegate->WaitForInvalidateTypeTab();
  EXPECT_FALSE(embedder->WasRecentlyAudible());
  EXPECT_FALSE(guest->WasRecentlyAudible());
}

IN_PROC_BROWSER_TEST_P(WebViewTest, AudioMutesWhileAttached) {
  LoadAppWithGuest("web_view/simple");

  content::WebContents* embedder = GetEmbedderWebContents();
  content::WebContents* guest = GetGuestWebContents();

  EXPECT_FALSE(embedder->IsAudioMuted());
  EXPECT_FALSE(guest->IsAudioMuted());

  embedder->SetAudioMuted(true);
  EXPECT_TRUE(embedder->IsAudioMuted());
  EXPECT_TRUE(guest->IsAudioMuted());

  embedder->SetAudioMuted(false);
  EXPECT_FALSE(embedder->IsAudioMuted());
  EXPECT_FALSE(guest->IsAudioMuted());
}

IN_PROC_BROWSER_TEST_P(WebViewTest, AudioMutesOnAttach) {
  LoadAndLaunchPlatformApp("web_view/app_creates_webview",
                           "WebViewTest.LAUNCHED");
  content::WebContents* embedder = GetEmbedderWebContents();
  embedder->SetAudioMuted(true);
  EXPECT_TRUE(embedder->IsAudioMuted());

  SendMessageToEmbedder("create-guest");
  content::WebContents* guest =
      GetGuestViewManager()->WaitForSingleGuestCreated();

  EXPECT_TRUE(embedder->IsAudioMuted());
  WebContentsAudioMutedObserver observer(guest);
  // If the guest hasn't attached yet, it may not have received the muting
  // update, in which case we should wait until it does.
  if (!guest->IsAudioMuted())
    observer.WaitForUpdate();
  EXPECT_TRUE(guest->IsAudioMuted());
}

IN_PROC_BROWSER_TEST_P(WebViewTest, AudioStateJavascriptAPI) {
  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      switches::kAutoplayPolicy,
      switches::autoplay::kNoUserGestureRequiredPolicy);

  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/audio_state_api"))
      << message_;
}

// Test that WebView does not override autoplay policy.
IN_PROC_BROWSER_TEST_P(WebViewTest, AutoplayPolicy) {
  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      switches::kAutoplayPolicy,
      switches::autoplay::kDocumentUserActivationRequiredPolicy);

  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/autoplay"))
      << message_;
}

// This test verifies that hiding the guest triggers WebContents::WasHidden().
IN_PROC_BROWSER_TEST_P(WebViewVisibilityTest, GuestVisibilityChanged) {
  LoadAppWithGuest("web_view/visibility_changed");

  scoped_refptr<content::MessageLoopRunner> loop_runner(
      new content::MessageLoopRunner);
  WebContentsHiddenObserver observer(GetGuestWebContents(),
                                     loop_runner->QuitClosure());

  // Handled in platform_apps/web_view/visibility_changed/main.js
  SendMessageToEmbedder("hide-guest");
  if (!observer.hidden_observed())
    loop_runner->Run();
}

// This test verifies that hiding the embedder also hides the guest.
IN_PROC_BROWSER_TEST_P(WebViewVisibilityTest, EmbedderVisibilityChanged) {
  LoadAppWithGuest("web_view/visibility_changed");

  scoped_refptr<content::MessageLoopRunner> loop_runner(
      new content::MessageLoopRunner);
  WebContentsHiddenObserver observer(GetGuestWebContents(),
                                     loop_runner->QuitClosure());

  // Handled in platform_apps/web_view/visibility_changed/main.js
  SendMessageToEmbedder("hide-embedder");
  if (!observer.hidden_observed())
    loop_runner->Run();
}

// This test verifies that reloading the embedder reloads the guest (and doest
// not crash).
IN_PROC_BROWSER_TEST_P(WebViewTest, ReloadEmbedder) {
  // Just load a guest from other test, we do not want to add a separate
  // platform_app for this test.
  LoadAppWithGuest("web_view/visibility_changed");

  ExtensionTestMessageListener launched_again_listener("WebViewTest.LAUNCHED",
                                                       false);
  GetEmbedderWebContents()->GetController().Reload(content::ReloadType::NORMAL,
                                                   false);
  ASSERT_TRUE(launched_again_listener.WaitUntilSatisfied());
}

IN_PROC_BROWSER_TEST_P(WebViewTest, AcceptTouchEvents) {
  // This test only makes sense for non-OOPIF WebView, since with
  // GuestViewCrossProcessFrames events are routed directly to the
  // guest, so the embedder does not need to know about the installation of
  // touch handlers.
  if (base::FeatureList::IsEnabled(::features::kGuestViewCrossProcessFrames))
    return;

  LoadAppWithGuest("web_view/accept_touch_events");

  content::RenderViewHost* embedder_rvh =
      GetEmbedderWebContents()->GetRenderViewHost();

  bool embedder_has_touch_handler =
      content::RenderViewHostTester::HasTouchEventHandler(embedder_rvh);
  EXPECT_FALSE(embedder_has_touch_handler);

  SendMessageToGuestAndWait("install-touch-handler", "installed-touch-handler");

  // Note that we need to wait for the installed/registered touch handler to
  // appear in browser process before querying |embedder_rvh|.
  // In practice, since we do a roundrtip from browser process to guest and
  // back, this is sufficient.
  embedder_has_touch_handler =
      content::RenderViewHostTester::HasTouchEventHandler(embedder_rvh);
  EXPECT_TRUE(embedder_has_touch_handler);

  SendMessageToGuestAndWait("uninstall-touch-handler",
                            "uninstalled-touch-handler");
  // Same as the note above about waiting.
  embedder_has_touch_handler =
      content::RenderViewHostTester::HasTouchEventHandler(embedder_rvh);
  EXPECT_FALSE(embedder_has_touch_handler);
}

// This test ensures JavaScript errors ("Cannot redefine property") do not
// happen when a <webview> is removed from DOM and added back.
IN_PROC_BROWSER_TEST_P(WebViewTest, AddRemoveWebView_AddRemoveWebView) {
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/addremove"))
      << message_;
}

IN_PROC_BROWSER_TEST_P(WebViewSizeTest, AutoSize) {
  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/autosize"))
      << message_;
}

IN_PROC_BROWSER_TEST_P(WebViewSurfaceSynchronizationTest, AutoSize) {
  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/autosize"))
      << message_;
}

IN_PROC_BROWSER_TEST_P(WebViewSurfaceSynchronizationTest, AutoSizeHeight) {
  TestHelper("testAutosizeHeight", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewSurfaceSynchronizationTest,
                       AutosizeBeforeNavigation) {
  TestHelper("testAutosizeBeforeNavigation", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewSurfaceSynchronizationTest,
                       AutosizeRemoveAttributes) {
  TestHelper("testAutosizeRemoveAttributes", "web_view/shim", NO_TEST_SERVER);
}

// Test for http://crbug.com/419611.
IN_PROC_BROWSER_TEST_P(WebViewTest, DisplayNoneSetSrc) {
  LoadAndLaunchPlatformApp("web_view/display_none_set_src",
                           "WebViewTest.LAUNCHED");
  // Navigate the guest while it's in "display: none" state.
  SendMessageToEmbedder("navigate-guest");
  GetGuestViewManager()->WaitForSingleGuestCreated();

  // Now attempt to navigate the guest again.
  SendMessageToEmbedder("navigate-guest");

  ExtensionTestMessageListener test_passed_listener("WebViewTest.PASSED",
                                                    false);
  // Making the guest visible would trigger loadstop.
  SendMessageToEmbedder("show-guest");
  EXPECT_TRUE(test_passed_listener.WaitUntilSatisfied());
}

// Checks that {allFrames: true} injects script correctly to subframes
// inside <webview>.
IN_PROC_BROWSER_TEST_P(WebViewTest, ExecuteScript) {
  ASSERT_TRUE(RunPlatformAppTestWithArg(
      "platform_apps/web_view/common", "execute_script")) << message_;
}

// http://crbug.com/326332
IN_PROC_BROWSER_TEST_P(WebViewSizeTest,
                       DISABLED_Shim_TestAutosizeAfterNavigation) {
  TestHelper("testAutosizeAfterNavigation", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestAllowTransparencyAttribute) {
  TestHelper("testAllowTransparencyAttribute", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewDPITest, Shim_TestAutosizeHeight) {
  TestHelper("testAutosizeHeight", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewWithZoomForDSFTest, Shim_TestAutosizeHeight) {
  TestHelper("testAutosizeHeight", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewSizeTest, Shim_TestAutosizeHeight) {
  TestHelper("testAutosizeHeight", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewDPITest, Shim_TestAutosizeBeforeNavigation) {
  TestHelper("testAutosizeBeforeNavigation", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewWithZoomForDSFTest,
                       Shim_TestAutosizeBeforeNavigation) {
  TestHelper("testAutosizeBeforeNavigation", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewSizeTest, Shim_TestAutosizeBeforeNavigation) {
  TestHelper("testAutosizeBeforeNavigation", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewDPITest, Shim_TestAutosizeRemoveAttributes) {
  TestHelper("testAutosizeRemoveAttributes", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewWithZoomForDSFTest,
                       Shim_TestAutosizeRemoveAttributes) {
  TestHelper("testAutosizeRemoveAttributes", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewSizeTest, Shim_TestAutosizeRemoveAttributes) {
  TestHelper("testAutosizeRemoveAttributes", "web_view/shim", NO_TEST_SERVER);
}

// This test is disabled due to being flaky. http://crbug.com/282116
IN_PROC_BROWSER_TEST_P(WebViewSizeTest,
                       DISABLED_Shim_TestAutosizeWithPartialAttributes) {
  TestHelper("testAutosizeWithPartialAttributes",
             "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestAPIMethodExistence) {
  TestHelper("testAPIMethodExistence", "web_view/shim", NO_TEST_SERVER);
}

// Tests the existence of WebRequest API event objects on the request
// object, on the webview element, and hanging directly off webview.
IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestWebRequestAPIExistence) {
  TestHelper("testWebRequestAPIExistence", "web_view/shim", NO_TEST_SERVER);
}

// Tests that addListener call succeeds on webview's WebRequest API events.
IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestWebRequestAPIAddListener) {
  TestHelper("testWebRequestAPIAddListener", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestWebRequestAPIErrorOccurred) {
  TestHelper("testWebRequestAPIErrorOccurred", "web_view/shim", NO_TEST_SERVER);
}

#if defined(USE_AURA)
// Test validates that select tag can be shown and hidden in webview safely
// using quick touch.
IN_PROC_BROWSER_TEST_P(WebViewTest, SelectShowHide) {
  LoadAppWithGuest("web_view/select");

  content::WebContents* embedder_contents = GetFirstAppWindowWebContents();
  ASSERT_TRUE(embedder_contents);

  std::vector<content::WebContents*> guest_contents_list;
  GetGuestViewManager()->GetGuestWebContentsList(&guest_contents_list);
  ASSERT_EQ(1u, guest_contents_list.size());
  content::WebContents* guest_contents = guest_contents_list[0];

  const gfx::Rect embedder_rect = embedder_contents->GetContainerBounds();
  const gfx::Rect guest_rect = guest_contents->GetContainerBounds();
  const gfx::Point click_point(guest_rect.x() - embedder_rect.x() + 10,
                               guest_rect.y() - embedder_rect.y() + 10);

  // Important, pass mouse click to embedder in order to transfer focus. Note
  // that SelectControlWaiter may be waited ealier than click is completed.
  LeftMouseClick mouse_click(GetParam() ? guest_contents : embedder_contents);
  SelectControlWaiter select_control_waiter;

  for (int i = 0; i < 5; ++i) {
    const int click_duration_ms = 10 + i * 25;
    mouse_click.Click(click_point, click_duration_ms);
    select_control_waiter.Wait(true);
    mouse_click.Wait();

    mouse_click.Click(click_point, click_duration_ms);
    select_control_waiter.Wait(false);
    mouse_click.Wait();
  }
}
#endif

// http://crbug.com/315920
#if defined(GOOGLE_CHROME_BUILD) && (defined(OS_WIN) || defined(OS_LINUX))
#define MAYBE_Shim_TestChromeExtensionURL DISABLED_Shim_TestChromeExtensionURL
#else
#define MAYBE_Shim_TestChromeExtensionURL Shim_TestChromeExtensionURL
#endif
IN_PROC_BROWSER_TEST_P(WebViewTest, MAYBE_Shim_TestChromeExtensionURL) {
  TestHelper("testChromeExtensionURL", "web_view/shim", NO_TEST_SERVER);
}

// http://crbug.com/315920
#if defined(GOOGLE_CHROME_BUILD) && (defined(OS_WIN) || defined(OS_LINUX))
#define MAYBE_Shim_TestChromeExtensionRelativePath \
    DISABLED_Shim_TestChromeExtensionRelativePath
#else
#define MAYBE_Shim_TestChromeExtensionRelativePath \
    Shim_TestChromeExtensionRelativePath
#endif
IN_PROC_BROWSER_TEST_P(WebViewTest,
                       MAYBE_Shim_TestChromeExtensionRelativePath) {
  TestHelper("testChromeExtensionRelativePath",
             "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest,
                       Shim_TestContentInitiatedNavigationToDataUrlBlocked) {
  TestHelper("testContentInitiatedNavigationToDataUrlBlocked", "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestDisplayNoneWebviewLoad) {
  TestHelper("testDisplayNoneWebviewLoad", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestDisplayNoneWebviewRemoveChild) {
  TestHelper("testDisplayNoneWebviewRemoveChild",
             "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestDisplayBlock) {
  TestHelper("testDisplayBlock", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest,
                       Shim_TestInlineScriptFromAccessibleResources) {
  TestHelper("testInlineScriptFromAccessibleResources",
             "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestInvalidChromeExtensionURL) {
  TestHelper("testInvalidChromeExtensionURL", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestEventName) {
  TestHelper("testEventName", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestOnEventProperty) {
  TestHelper("testOnEventProperties", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestLoadProgressEvent) {
  TestHelper("testLoadProgressEvent", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestDestroyOnEventListener) {
  TestHelper("testDestroyOnEventListener", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestCannotMutateEventName) {
  TestHelper("testCannotMutateEventName", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestPartitionChangeAfterNavigation) {
  TestHelper("testPartitionChangeAfterNavigation",
             "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest,
                       Shim_TestPartitionRemovalAfterNavigationFails) {
  TestHelper("testPartitionRemovalAfterNavigationFails",
             "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestAddContentScript) {
  TestHelper("testAddContentScript", "web_view/shim", NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestAddMultipleContentScripts) {
  TestHelper("testAddMultipleContentScripts", "web_view/shim",
             NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(
    WebViewTest,
    Shim_TestAddContentScriptWithSameNameShouldOverwriteTheExistingOne) {
  TestHelper("testAddContentScriptWithSameNameShouldOverwriteTheExistingOne",
             "web_view/shim", NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(
    WebViewTest,
    Shim_TestAddContentScriptToOneWebViewShouldNotInjectToTheOtherWebView) {
  TestHelper("testAddContentScriptToOneWebViewShouldNotInjectToTheOtherWebView",
             "web_view/shim", NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestAddAndRemoveContentScripts) {
  TestHelper("testAddAndRemoveContentScripts", "web_view/shim",
             NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewNewWindowTest,
                       Shim_TestAddContentScriptsWithNewWindowAPI) {
  TestHelper("testAddContentScriptsWithNewWindowAPI", "web_view/shim",
             NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(
    WebViewTest,
    Shim_TestContentScriptIsInjectedAfterTerminateAndReloadWebView) {
  TestHelper("testContentScriptIsInjectedAfterTerminateAndReloadWebView",
             "web_view/shim", NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest,
                       Shim_TestContentScriptExistsAsLongAsWebViewTagExists) {
  TestHelper("testContentScriptExistsAsLongAsWebViewTagExists", "web_view/shim",
             NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestAddContentScriptWithCode) {
  TestHelper("testAddContentScriptWithCode", "web_view/shim",
             NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(
    WebViewTest,
    Shim_TestAddMultipleContentScriptsWithCodeAndCheckGeneratedScriptUrl) {
  TestHelper("testAddMultipleContentScriptsWithCodeAndCheckGeneratedScriptUrl",
             "web_view/shim", NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestExecuteScriptFail) {
  TestHelper("testExecuteScriptFail", "web_view/shim", NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestExecuteScript) {
  TestHelper("testExecuteScript", "web_view/shim", NO_TEST_SERVER);
}

// Flaky and likely not testing the right assertion. https://crbug.com/703727
IN_PROC_BROWSER_TEST_P(
    WebViewTest,
    DISABLED_Shim_TestExecuteScriptIsAbortedWhenWebViewSourceIsChanged) {
  TestHelper("testExecuteScriptIsAbortedWhenWebViewSourceIsChanged",
             "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(
    WebViewTest,
    Shim_TestExecuteScriptIsAbortedWhenWebViewSourceIsInvalid) {
  TestHelper("testExecuteScriptIsAbortedWhenWebViewSourceIsInvalid",
             "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestTerminateAfterExit) {
  TestHelper("testTerminateAfterExit", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestAssignSrcAfterCrash) {
  TestHelper("testAssignSrcAfterCrash", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest,
                       Shim_TestNavOnConsecutiveSrcAttributeChanges) {
  TestHelper("testNavOnConsecutiveSrcAttributeChanges",
             "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestNavOnSrcAttributeChange) {
  TestHelper("testNavOnSrcAttributeChange", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestNavigateAfterResize) {
  TestHelper("testNavigateAfterResize", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestNestedCrossOriginSubframes) {
  TestHelper("testNestedCrossOriginSubframes",
             "web_view/shim", NEEDS_TEST_SERVER);
}

#if defined(OS_MACOSX)
// Flaky on Mac. See https://crbug.com/674904.
#define MAYBE_Shim_TestNestedSubframes DISABLED_Shim_TestNestedSubframes
#else
#define MAYBE_Shim_TestNestedSubframes Shim_TestNestedSubframes
#endif
IN_PROC_BROWSER_TEST_P(WebViewTest, MAYBE_Shim_TestNestedSubframes) {
  TestHelper("testNestedSubframes", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestRemoveSrcAttribute) {
  TestHelper("testRemoveSrcAttribute", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestReassignSrcAttribute) {
  TestHelper("testReassignSrcAttribute", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewNewWindowTest, Shim_TestNewWindow) {
  TestHelper("testNewWindow", "web_view/shim", NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewNewWindowTest, Shim_TestNewWindowTwoListeners) {
  TestHelper("testNewWindowTwoListeners", "web_view/shim", NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewNewWindowTest,
                       Shim_TestNewWindowNoPreventDefault) {
  TestHelper("testNewWindowNoPreventDefault",
             "web_view/shim",
             NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewNewWindowTest, Shim_TestNewWindowNoReferrerLink) {
  TestHelper("testNewWindowNoReferrerLink", "web_view/shim", NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewNewWindowTest,
                       Shim_TestWebViewAndEmbedderInNewWindow) {
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.

  // Launch the app and wait until it's ready to load a test.
  LoadAndLaunchPlatformApp("web_view/shim", "Launched");

  content::WebContents* embedder_web_contents = GetFirstAppWindowWebContents();
  ASSERT_TRUE(embedder_web_contents);

  GURL::Replacements replace_host;
  replace_host.SetHostStr("localhost");

  std::string empty_guest_path(
      "/extensions/platform_apps/web_view/shim/empty_guest.html");
  GURL empty_guest_url = embedded_test_server()->GetURL(empty_guest_path);
  empty_guest_url = empty_guest_url.ReplaceComponents(replace_host);

  ui_test_utils::UrlLoadObserver empty_guest_observer(
      empty_guest_url, content::NotificationService::AllSources());

  // Run the test and wait until the guest WebContents is available and has
  // finished loading.
  ExtensionTestMessageListener done_listener("TEST_PASSED", false);
  done_listener.set_failure_message("TEST_FAILED");
  EXPECT_TRUE(content::ExecuteScript(
      embedder_web_contents, "runTest('testWebViewAndEmbedderInNewWindow')"));

  empty_guest_observer.Wait();

  content::Source<content::NavigationController> source =
      empty_guest_observer.source();
  EXPECT_TRUE(source->GetWebContents()
                  ->GetMainFrame()
                  ->GetProcess()
                  ->IsForGuestsOnly());
  ASSERT_TRUE(done_listener.WaitUntilSatisfied());

  // Make sure opener and owner for the empty_guest source are different.
  // In general, we should have two guests and two embedders. Once we know the
  // guests are different and the embedders are different, then we have four
  // distinct WebContents, as we expect.
  std::vector<content::WebContents*> guest_contents_list;
  GetGuestViewManager()->GetGuestWebContentsList(&guest_contents_list);
  ASSERT_EQ(2u, guest_contents_list.size());
  content::WebContents* new_window_guest_contents = guest_contents_list[0];

  content::WebContents* empty_guest_web_contents = source->GetWebContents();
  ASSERT_EQ(empty_guest_web_contents, guest_contents_list[1]);
  ASSERT_NE(empty_guest_web_contents, new_window_guest_contents);
  content::WebContents* empty_guest_embedder =
      GetEmbedderForGuest(empty_guest_web_contents);
  ASSERT_NE(empty_guest_embedder, embedder_web_contents);
  ASSERT_TRUE(empty_guest_embedder);
  content::RenderFrameHost* empty_guest_opener =
      empty_guest_web_contents->GetOriginalOpener();
  ASSERT_TRUE(empty_guest_opener);
  ASSERT_NE(empty_guest_opener, empty_guest_embedder->GetMainFrame());
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestContentLoadEvent) {
  TestHelper("testContentLoadEvent", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestContentLoadEventWithDisplayNone) {
  TestHelper("testContentLoadEventWithDisplayNone",
             "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestDeclarativeWebRequestAPI) {
  TestHelper("testDeclarativeWebRequestAPI",
             "web_view/shim",
             NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest,
                       Shim_TestDeclarativeWebRequestAPISendMessage) {
  TestHelper("testDeclarativeWebRequestAPISendMessage",
             "web_view/shim",
             NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(
    WebViewTest,
    Shim_TestDeclarativeWebRequestAPISendMessageSecondWebView) {
  TestHelper("testDeclarativeWebRequestAPISendMessageSecondWebView",
             "web_view/shim", NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestWebRequestAPI) {
  TestHelper("testWebRequestAPI", "web_view/shim", NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestWebRequestAPIOnlyForInstance) {
  TestHelper("testWebRequestAPIOnlyForInstance", "web_view/shim",
             NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestWebRequestAPIWithHeaders) {
  TestHelper("testWebRequestAPIWithHeaders",
             "web_view/shim",
             NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestWebRequestAPIGoogleProperty) {
  TestHelper("testWebRequestAPIGoogleProperty",
             "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest,
                       Shim_TestWebRequestListenerSurvivesReparenting) {
  TestHelper("testWebRequestListenerSurvivesReparenting",
             "web_view/shim",
             NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestLoadStartLoadRedirect) {
  TestHelper("testLoadStartLoadRedirect", "web_view/shim", NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest,
                       Shim_TestLoadAbortChromeExtensionURLWrongPartition) {
  TestHelper("testLoadAbortChromeExtensionURLWrongPartition",
             "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestLoadAbortEmptyResponse) {
  TestHelper("testLoadAbortEmptyResponse", "web_view/shim", NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestLoadAbortIllegalChromeURL) {
  TestHelper("testLoadAbortIllegalChromeURL",
             "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestLoadAbortIllegalFileURL) {
  TestHelper("testLoadAbortIllegalFileURL", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestLoadAbortIllegalJavaScriptURL) {
  TestHelper("testLoadAbortIllegalJavaScriptURL",
             "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestLoadAbortInvalidNavigation) {
  TestHelper("testLoadAbortInvalidNavigation", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestLoadAbortNonWebSafeScheme) {
  TestHelper("testLoadAbortNonWebSafeScheme", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestReload) {
  TestHelper("testReload", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestReloadAfterTerminate) {
  TestHelper("testReloadAfterTerminate", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestGetProcessId) {
  TestHelper("testGetProcessId", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewVisibilityTest, Shim_TestHiddenBeforeNavigation) {
  TestHelper("testHiddenBeforeNavigation", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestRemoveWebviewOnExit) {
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.

  // Launch the app and wait until it's ready to load a test.
  LoadAndLaunchPlatformApp("web_view/shim", "Launched");

  content::WebContents* embedder_web_contents = GetFirstAppWindowWebContents();
  ASSERT_TRUE(embedder_web_contents);

  GURL::Replacements replace_host;
  replace_host.SetHostStr("localhost");

  std::string guest_path(
      "/extensions/platform_apps/web_view/shim/empty_guest.html");
  GURL guest_url = embedded_test_server()->GetURL(guest_path);
  guest_url = guest_url.ReplaceComponents(replace_host);

  ui_test_utils::UrlLoadObserver guest_observer(
      guest_url, content::NotificationService::AllSources());

  // Run the test and wait until the guest WebContents is available and has
  // finished loading.
  ExtensionTestMessageListener guest_loaded_listener("guest-loaded", false);
  EXPECT_TRUE(content::ExecuteScript(
                  embedder_web_contents,
                  "runTest('testRemoveWebviewOnExit')"));
  guest_observer.Wait();

  content::Source<content::NavigationController> source =
      guest_observer.source();
  EXPECT_TRUE(source->GetWebContents()
                  ->GetMainFrame()
                  ->GetProcess()
                  ->IsForGuestsOnly());

  ASSERT_TRUE(guest_loaded_listener.WaitUntilSatisfied());

  content::WebContentsDestroyedWatcher destroyed_watcher(
      source->GetWebContents());

  // Tell the embedder to kill the guest.
  EXPECT_TRUE(content::ExecuteScript(
                  embedder_web_contents,
                  "removeWebviewOnExitDoCrash();"));

  // Wait until the guest WebContents is destroyed.
  destroyed_watcher.Wait();
}

// Remove <webview> immediately after navigating it.
// This is a regression test for http://crbug.com/276023.
IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestRemoveWebviewAfterNavigation) {
  TestHelper("testRemoveWebviewAfterNavigation",
             "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestNavigationToExternalProtocol) {
  TestHelper("testNavigationToExternalProtocol",
             "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewSizeTest,
                       Shim_TestResizeWebviewWithDisplayNoneResizesContent) {
  TestHelper("testResizeWebviewWithDisplayNoneResizesContent",
             "web_view/shim",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewSizeTest, Shim_TestResizeWebviewResizesContent) {
  TestHelper("testResizeWebviewResizesContent",
             "web_view/shim",
             NO_TEST_SERVER);
}

// Test makes sure that interstitial pages renders in <webview>.
// Flaky on Win dbg: crbug.com/779973
#if defined(OS_WIN) && !defined(NDEBUG)
#define MAYBE_InterstitialPage DISABLED_InterstitialPage
#else
#define MAYBE_InterstitialPage InterstitialPage
#endif

IN_PROC_BROWSER_TEST_P(WebViewTest, MAYBE_InterstitialPage) {
  // This test tests that a inner WebContents' InterstitialPage is properly
  // connected to an outer WebContents through a CrossProcessFrameConnector, it
  // doesn't make sense for BrowserPlugin based guests.
  if (!base::FeatureList::IsEnabled(::features::kGuestViewCrossProcessFrames))
    return;

  InterstitialTestHelper();

  content::WebContents* guest_web_contents =
      GetGuestViewManager()->WaitForSingleGuestCreated();

  EXPECT_TRUE(guest_web_contents->ShowingInterstitialPage());
  EXPECT_TRUE(guest_web_contents->GetInterstitialPage()
                  ->GetMainFrame()
                  ->GetView()
                  ->IsShowing());
  EXPECT_TRUE(content::IsInnerInterstitialPageConnected(
      guest_web_contents->GetInterstitialPage()));
}

// Test makes sure that interstitial pages are registered in the
// RenderWidgetHostInputEventRouter when inside a <webview>.
// Flaky on Win dbg: crbug.com/779973
#if defined(OS_WIN) && !defined(NDEBUG)
#define MAYBE_InterstitialPageRouteEvents DISABLED_InterstitialPageRouteEvents
#else
#define MAYBE_InterstitialPageRouteEvents InterstitialPageRouteEvents
#endif

IN_PROC_BROWSER_TEST_P(WebViewTest, MAYBE_InterstitialPageRouteEvents) {
  // This test tests that a inner WebContents' InterstitialPage is properly
  // connected to an outer WebContents through a CrossProcessFrameConnector, it
  // doesn't make sense for BrowserPlugin based guests.
  if (!base::FeatureList::IsEnabled(::features::kGuestViewCrossProcessFrames))
    return;

  InterstitialTestHelper();

  content::WebContents* outer_web_contents = GetFirstAppWindowWebContents();
  content::WebContents* guest_web_contents =
      GetGuestViewManager()->WaitForSingleGuestCreated();
  content::InterstitialPage* interstitial_page =
      guest_web_contents->GetInterstitialPage();

  std::vector<content::RenderWidgetHostView*> hosts =
      content::GetInputEventRouterRenderWidgetHostViews(outer_web_contents);
  EXPECT_TRUE(
      base::ContainsValue(hosts, interstitial_page->GetMainFrame()->GetView()));
}

// Test makes sure that interstitial pages will receive input events and can be
// focused.
// Flaky on Win dbg: crbug.com/779973
#if defined(OS_WIN) && !defined(NDEBUG)
#define MAYBE_InterstitialPageFocusedWidget \
  DISABLED_InterstitialPageFocusedWidget
#else
#define MAYBE_InterstitialPageFocusedWidget InterstitialPageFocusedWidget
#endif

IN_PROC_BROWSER_TEST_P(WebViewTest, MAYBE_InterstitialPageFocusedWidget) {
  // This test tests that a inner WebContents' InterstitialPage is properly
  // connected to an outer WebContents through a CrossProcessFrameConnector, it
  // doesn't make sense for BrowserPlugin based guests.
  if (!base::FeatureList::IsEnabled(::features::kGuestViewCrossProcessFrames))
    return;

  InterstitialTestHelper();

  content::WebContents* outer_web_contents = GetFirstAppWindowWebContents();
  content::WebContents* guest_web_contents =
      GetGuestViewManager()->WaitForSingleGuestCreated();
  content::InterstitialPage* interstitial_page =
      guest_web_contents->GetInterstitialPage();
  content::RenderFrameHost* interstitial_main_frame =
      interstitial_page->GetMainFrame();
  content::RenderWidgetHost* interstitial_widget =
      interstitial_main_frame->GetRenderViewHost()->GetWidget();

  content::WaitForChildFrameSurfaceReady(interstitial_main_frame);

  EXPECT_NE(interstitial_widget,
            content::GetFocusedRenderWidgetHost(guest_web_contents));
  EXPECT_NE(interstitial_widget,
            content::GetFocusedRenderWidgetHost(outer_web_contents));

  // Send mouse down.
  blink::WebMouseEvent event;
  event.button = blink::WebPointerProperties::Button::kLeft;
  event.SetType(blink::WebInputEvent::kMouseDown);
  event.SetPositionInWidget(10, 10);
  content::RouteMouseEvent(outer_web_contents, &event);

  // Wait a frame.
  content::MainThreadFrameObserver observer(interstitial_widget);
  observer.Wait();

  // Send mouse up.
  event.SetType(blink::WebInputEvent::kMouseUp);
  event.SetPositionInWidget(10, 10);
  content::RouteMouseEvent(outer_web_contents, &event);

  // Wait another frame.
  observer.Wait();

  EXPECT_EQ(interstitial_widget,
            content::GetFocusedRenderWidgetHost(guest_web_contents));
  EXPECT_EQ(interstitial_widget,
            content::GetFocusedRenderWidgetHost(outer_web_contents));
}

// Test makes sure that the browser does not crash when a <webview> navigates
// out of an interstitial.
// Flaky on Win dbg: crbug.com/779973
#if defined(OS_WIN) && !defined(NDEBUG)
#define MAYBE_InterstitialPageDetach DISABLED_InterstitialPageDetach
#else
#define MAYBE_InterstitialPageDetach InterstitialPageDetach
#endif

IN_PROC_BROWSER_TEST_P(WebViewTest, MAYBE_InterstitialPageDetach) {
  InterstitialTestHelper();

  content::WebContents* guest_web_contents =
      GetGuestViewManager()->WaitForSingleGuestCreated();
  EXPECT_TRUE(guest_web_contents->ShowingInterstitialPage());

  // Navigate to about:blank.
  content::TestNavigationObserver load_observer(guest_web_contents);
  bool result = ExecuteScript(guest_web_contents,
                              "window.location.assign('about:blank')");
  EXPECT_TRUE(result);
  load_observer.Wait();
}

// This test makes sure the browser process does not crash if app is closed
// while an interstitial page is being shown in guest.
// Flaky on Win dbg: crbug.com/779973
#if defined(OS_WIN) && !defined(NDEBUG)
#define MAYBE_InterstitialTeardown DISABLED_InterstitialTeardown
#else
#define MAYBE_InterstitialTeardown InterstitialTeardown
#endif

IN_PROC_BROWSER_TEST_P(WebViewTest, MAYBE_InterstitialTeardown) {
  InterstitialTestHelper();

  // Now close the app while interstitial page being shown in guest.
  extensions::AppWindow* window = GetFirstAppWindow();
  window->GetBaseWindow()->Close();
}

// This test makes sure the browser process does not crash if browser is shut
// down while an interstitial page is being shown in guest.
// Flaky. http://crbug.com/627962.
IN_PROC_BROWSER_TEST_P(WebViewTest,
                       DISABLED_InterstitialTeardownOnBrowserShutdown) {
  InterstitialTestHelper();

  // Now close the app while interstitial page being shown in guest.
  extensions::AppWindow* window = GetFirstAppWindow();
  window->GetBaseWindow()->Close();

  // InterstitialPage is not destroyed immediately, so the
  // RenderWidgetHostViewGuest for it is still there, closing all
  // renderer processes will cause the RWHVGuest's RenderProcessGone()
  // shutdown path to be exercised.
  chrome::CloseAllBrowsers();
}

IN_PROC_BROWSER_TEST_P(WebViewTest, ShimSrcAttribute) {
  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/src_attribute"))
      << message_;
}

// This test verifies that prerendering has been disabled inside <webview>.
// This test is here rather than in PrerenderBrowserTest for testing convenience
// only. If it breaks then this is a bug in the prerenderer.
IN_PROC_BROWSER_TEST_P(WebViewTest, NoPrerenderer) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  content::WebContents* guest_web_contents =
      LoadGuest(
          "/extensions/platform_apps/web_view/noprerenderer/guest.html",
          "web_view/noprerenderer");
  ASSERT_TRUE(guest_web_contents != NULL);

  PrerenderLinkManager* prerender_link_manager =
      PrerenderLinkManagerFactory::GetForProfile(
          Profile::FromBrowserContext(guest_web_contents->GetBrowserContext()));
  ASSERT_TRUE(prerender_link_manager != NULL);
  EXPECT_TRUE(prerender_link_manager->IsEmpty());
}

// Verify that existing <webview>'s are detected when the task manager starts
// up.
IN_PROC_BROWSER_TEST_P(WebViewTest, TaskManagerExistingWebView) {
  ASSERT_TRUE(StartEmbeddedTestServer());

  LoadGuest("/extensions/platform_apps/web_view/task_manager/guest.html",
            "web_view/task_manager");

  chrome::ShowTaskManager(browser());  // Show task manager AFTER guest loads.

  const char* guest_title = "WebViewed test content";
  const char* app_name = "<webview> task manager test";
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchWebView(guest_title)));
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchApp(app_name)));
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchBackground(app_name)));

  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyWebView()));
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyApp()));
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyBackground()));
}

// Verify that the task manager notices the creation of new <webview>'s.
IN_PROC_BROWSER_TEST_P(WebViewTest, TaskManagerNewWebView) {
  ASSERT_TRUE(StartEmbeddedTestServer());

  chrome::ShowTaskManager(browser());  // Show task manager BEFORE guest loads.

  LoadGuest("/extensions/platform_apps/web_view/task_manager/guest.html",
            "web_view/task_manager");

  const char* guest_title = "WebViewed test content";
  const char* app_name = "<webview> task manager test";
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchWebView(guest_title)));
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAboutBlankTab()));
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchApp(app_name)));
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchBackground(app_name)));

  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyWebView()));
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab()));
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyApp()));
  ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyBackground()));
}

// This tests cookie isolation for packaged apps with webview tags. It navigates
// the main browser window to a page that sets a cookie and loads an app with
// multiple webview tags. Each tag sets a cookie and the test checks the proper
// storage isolation is enforced.
IN_PROC_BROWSER_TEST_P(WebViewTest, CookieIsolation) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  // Navigate the browser to a page which writes a sample cookie
  // The cookie is "testCookie=1"
  GURL set_cookie_url = embedded_test_server()->GetURL(
      "/extensions/platform_apps/web_view/cookie_isolation/set_cookie.html");
  GURL::Replacements replace_host;
  replace_host.SetHostStr("localhost");
  set_cookie_url = set_cookie_url.ReplaceComponents(replace_host);

  ui_test_utils::NavigateToURL(browser(), set_cookie_url);
  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/cookie_isolation"))
      << message_;
  // Finally, verify that the browser cookie has not changed.
  int cookie_size;
  std::string cookie_value;

  ui_test_utils::GetCookies(GURL("http://localhost"),
                            browser()->tab_strip_model()->GetWebContentsAt(0),
                            &cookie_size, &cookie_value);
  EXPECT_EQ("testCookie=1", cookie_value);
}

// This tests that in-memory storage partitions are reset on browser restart,
// but persistent ones maintain state for cookies and HTML5 storage.
IN_PROC_BROWSER_TEST_P(WebViewTest, PRE_StoragePersistence) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  // We don't care where the main browser is on this test.
  ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
  // Since this test is PRE_ step, we need file access.
  ASSERT_TRUE(RunPlatformAppTestWithFlags(
      "platform_apps/web_view/storage_persistence", "PRE_StoragePersistence",
      kFlagEnableFileAccess))
      << message_;
}

// This is the post-reset portion of the StoragePersistence test.  See
// PRE_StoragePersistence for main comment.
IN_PROC_BROWSER_TEST_P(WebViewTest, StoragePersistence) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  // We don't care where the main browser is on this test.
  ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));

  // Since this test has PRE_ step, we need file access (possibly because we
  // need to access previous profile).
  ASSERT_TRUE(RunPlatformAppTestWithFlags(
      "platform_apps/web_view/storage_persistence", "StoragePersistence",
      kFlagEnableFileAccess))
      << message_;
}

// This tests DOM storage isolation for packaged apps with webview tags. It
// loads an app with multiple webview tags and each tag sets DOM storage
// entries, which the test checks to ensure proper storage isolation is
// enforced.
IN_PROC_BROWSER_TEST_P(WebViewTest, DOMStorageIsolation) {
  ASSERT_TRUE(StartEmbeddedTestServer());

  GURL navigate_to_url = embedded_test_server()->GetURL(
      "/extensions/platform_apps/web_view/dom_storage_isolation/page.html");
  GURL::Replacements replace_host;
  replace_host.SetHostStr("localhost");
  navigate_to_url = navigate_to_url.ReplaceComponents(replace_host);

  ui_test_utils::NavigateToURL(browser(), navigate_to_url);
  ASSERT_TRUE(
      RunPlatformAppTest("platform_apps/web_view/dom_storage_isolation"));
  // Verify that the browser tab's local/session storage does not have the same
  // values which were stored by the webviews.
  std::string output;
  std::string get_local_storage(
      "window.domAutomationController.send("
      "window.localStorage.getItem('foo') || 'badval')");
  std::string get_session_storage(
      "window.domAutomationController.send("
      "window.localStorage.getItem('baz') || 'badval')");
  ASSERT_TRUE(ExecuteScriptAndExtractString(
      browser()->tab_strip_model()->GetWebContentsAt(0),
      get_local_storage.c_str(), &output));
  EXPECT_STREQ("badval", output.c_str());
  ASSERT_TRUE(ExecuteScriptAndExtractString(
      browser()->tab_strip_model()->GetWebContentsAt(0),
      get_session_storage.c_str(), &output));
  EXPECT_STREQ("badval", output.c_str());
}

// This tests IndexedDB isolation for packaged apps with webview tags. It loads
// an app with multiple webview tags and each tag creates an IndexedDB record,
// which the test checks to ensure proper storage isolation is enforced.
IN_PROC_BROWSER_TEST_P(WebViewTest, IndexedDBIsolation) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(RunPlatformAppTest(
      "platform_apps/web_view/isolation_indexeddb")) << message_;
}

// This test ensures that closing app window on 'loadcommit' does not crash.
// The test launches an app with guest and closes the window on loadcommit. It
// then launches the app window again. The process is repeated 3 times.
IN_PROC_BROWSER_TEST_P(WebViewTest, CloseOnLoadcommit) {
  LoadAndLaunchPlatformApp("web_view/close_on_loadcommit",
                           "done-close-on-loadcommit");
}

IN_PROC_BROWSER_TEST_P(WebViewTest, MediaAccessAPIDeny_TestDeny) {
  MediaAccessAPIDenyTestHelper("testDeny");
}

IN_PROC_BROWSER_TEST_P(WebViewTest,
                       MediaAccessAPIDeny_TestDenyThenAllowThrows) {
  MediaAccessAPIDenyTestHelper("testDenyThenAllowThrows");
}

IN_PROC_BROWSER_TEST_P(WebViewTest,
                       MediaAccessAPIDeny_TestDenyWithPreventDefault) {
  MediaAccessAPIDenyTestHelper("testDenyWithPreventDefault");
}

IN_PROC_BROWSER_TEST_P(WebViewTest,
                       MediaAccessAPIDeny_TestNoListenersImplyDeny) {
  MediaAccessAPIDenyTestHelper("testNoListenersImplyDeny");
}

IN_PROC_BROWSER_TEST_P(WebViewTest,
                       MediaAccessAPIDeny_TestNoPreventDefaultImpliesDeny) {
  MediaAccessAPIDenyTestHelper("testNoPreventDefaultImpliesDeny");
}

void WebViewTestBase::MediaAccessAPIAllowTestHelper(
    const std::string& test_name) {
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
  LoadAndLaunchPlatformApp("web_view/media_access/allow", "Launched");

  content::WebContents* embedder_web_contents = GetFirstAppWindowWebContents();
  ASSERT_TRUE(embedder_web_contents);
  std::unique_ptr<MockWebContentsDelegate> mock(new MockWebContentsDelegate());
  embedder_web_contents->SetDelegate(mock.get());

  ExtensionTestMessageListener done_listener("TEST_PASSED", false);
  done_listener.set_failure_message("TEST_FAILED");
  EXPECT_TRUE(
      content::ExecuteScript(
          embedder_web_contents,
          base::StringPrintf("startAllowTest('%s')",
                             test_name.c_str())));
  ASSERT_TRUE(done_listener.WaitUntilSatisfied());

  mock->WaitForRequestMediaPermission();
}

IN_PROC_BROWSER_TEST_P(WebViewTest, OpenURLFromTab_CurrentTab_Abort) {
  LoadAppWithGuest("web_view/simple");

  // Verify that OpenURLFromTab with a window disposition of CURRENT_TAB will
  // navigate the current <webview>.
  ExtensionTestMessageListener load_listener("WebViewTest.LOADSTOP", false);

  // Navigating to a file URL is forbidden inside a <webview>.
  content::OpenURLParams params(GURL("file://foo"), content::Referrer(),
                                WindowOpenDisposition::CURRENT_TAB,
                                ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
                                true /* is_renderer_initiated */);
  GetGuestWebContents()->GetDelegate()->OpenURLFromTab(
      GetGuestWebContents(), params);

  ASSERT_TRUE(load_listener.WaitUntilSatisfied());

  // Verify that the <webview> ends up at about:blank.
  EXPECT_EQ(GURL(url::kAboutBlankURL),
            GetGuestWebContents()->GetLastCommittedURL());
}

// A navigation to a web-safe URL should succeed, even if it is not renderer-
// initiated, such as a navigation from the PDF viewer.
IN_PROC_BROWSER_TEST_P(WebViewTest, OpenURLFromTab_CurrentTab_Succeed) {
  LoadAppWithGuest("web_view/simple");

  // Verify that OpenURLFromTab with a window disposition of CURRENT_TAB will
  // navigate the current <webview>.
  ExtensionTestMessageListener load_listener("WebViewTest.LOADSTOP", false);

  GURL test_url("http://www.google.com");
  content::OpenURLParams params(
      test_url, content::Referrer(), WindowOpenDisposition::CURRENT_TAB,
      ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false /* is_renderer_initiated */);
  GetGuestWebContents()->GetDelegate()->OpenURLFromTab(GetGuestWebContents(),
                                                       params);

  ASSERT_TRUE(load_listener.WaitUntilSatisfied());

  EXPECT_EQ(test_url, GetGuestWebContents()->GetLastCommittedURL());
}

IN_PROC_BROWSER_TEST_P(WebViewNewWindowTest, OpenURLFromTab_NewWindow_Abort) {
  LoadAppWithGuest("web_view/simple");

  // Verify that OpenURLFromTab with a window disposition of NEW_BACKGROUND_TAB
  // will trigger the <webview>'s New Window API.
  ExtensionTestMessageListener new_window_listener(
      "WebViewTest.NEWWINDOW", false);

  // Navigating to a file URL is forbidden inside a <webview>.
  content::OpenURLParams params(GURL("file://foo"), content::Referrer(),
                                WindowOpenDisposition::NEW_BACKGROUND_TAB,
                                ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
                                true /* is_renderer_initiated */);
  GetGuestWebContents()->GetDelegate()->OpenURLFromTab(
      GetGuestWebContents(), params);

  ASSERT_TRUE(new_window_listener.WaitUntilSatisfied());

  // Verify that a new guest was created.
  content::WebContents* new_guest_web_contents =
      GetGuestViewManager()->GetLastGuestCreated();
  EXPECT_NE(GetGuestWebContents(), new_guest_web_contents);

  // Verify that the new <webview> guest ends up at about:blank.
  EXPECT_EQ(GURL(url::kAboutBlankURL),
            new_guest_web_contents->GetLastCommittedURL());
}

IN_PROC_BROWSER_TEST_P(WebViewTest, ContextMenuInspectElement) {
  LoadAppWithGuest("web_view/context_menus/basic");
  content::WebContents* guest_web_contents = GetGuestWebContents();
  ASSERT_TRUE(guest_web_contents);

  content::ContextMenuParams params;
  TestRenderViewContextMenu menu(guest_web_contents->GetMainFrame(), params);
  menu.Init();

  // Expect "Inspect" to be shown as we are running webview in a chrome app.
  EXPECT_TRUE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_INSPECTELEMENT));
}

// This test executes the context menu command 'LanguageSettings' which will
// load chrome://settings/languages in a browser window. This is a browser-
// initiated operation and so we expect this to succeed if the embedder is
// allowed to perform the operation.
IN_PROC_BROWSER_TEST_P(WebViewTest, ContextMenuLanguageSettings) {
  LoadAppWithGuest("web_view/context_menus/basic");

  content::WebContents* guest_web_contents = GetGuestWebContents();
  content::WebContents* embedder = GetEmbedderWebContents();
  ASSERT_TRUE(embedder);

  // Create and build our test context menu.
  content::WebContentsAddedObserver web_contents_added_observer;

  GURL page_url("http://www.google.com");
  std::unique_ptr<TestRenderViewContextMenu> menu(
      TestRenderViewContextMenu::Create(guest_web_contents, page_url, GURL(),
                                        GURL()));
  menu->ExecuteCommand(IDC_CONTENT_CONTEXT_LANGUAGE_SETTINGS, 0);

  content::WebContents* new_contents =
      web_contents_added_observer.GetWebContents();

  // Verify that a new WebContents has been created that is at the Language
  // Settings page.
  EXPECT_EQ(GURL("chrome://settings/languages"),
            new_contents->GetVisibleURL());
}

IN_PROC_BROWSER_TEST_P(WebViewTest, ContextMenusAPI_Basic) {
  LoadAppWithGuest("web_view/context_menus/basic");

  content::WebContents* guest_web_contents = GetGuestWebContents();
  content::WebContents* embedder = GetEmbedderWebContents();
  ASSERT_TRUE(embedder);

  // 1. Basic property test.
  ExecuteScriptWaitForTitle(embedder, "checkProperties()", "ITEM_CHECKED");

  // 2. Create a menu item and wait for created callback to be called.
  ExecuteScriptWaitForTitle(embedder, "createMenuItem()", "ITEM_CREATED");

  // 3. Click the created item, wait for the click handlers to fire from JS.
  ExtensionTestMessageListener click_listener("ITEM_CLICKED", false);
  GURL page_url("http://www.google.com");
  // Create and build our test context menu.
  std::unique_ptr<TestRenderViewContextMenu> menu(
      TestRenderViewContextMenu::Create(guest_web_contents, page_url, GURL(),
                                        GURL()));
  // Look for the extension item in the menu, and execute it.
  int command_id = ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0);
  ASSERT_TRUE(menu->IsCommandIdEnabled(command_id));
  menu->ExecuteCommand(command_id, 0);
  // Wait for embedder's script to tell us its onclick fired, it does
  // chrome.test.sendMessage('ITEM_CLICKED')
  ASSERT_TRUE(click_listener.WaitUntilSatisfied());

  // 4. Update the item's title and verify.
  ExecuteScriptWaitForTitle(embedder, "updateMenuItem()", "ITEM_UPDATED");
  MenuItem::List items = GetItems();
  ASSERT_EQ(1u, items.size());
  MenuItem* item = items.at(0);
  EXPECT_EQ("new_title", item->title());

  // 5. Remove the item.
  ExecuteScriptWaitForTitle(embedder, "removeItem()", "ITEM_REMOVED");
  MenuItem::List items_after_removal = GetItems();
  ASSERT_EQ(0u, items_after_removal.size());

  // 6. Add some more items.
  ExecuteScriptWaitForTitle(
      embedder, "createThreeMenuItems()", "ITEM_MULTIPLE_CREATED");
  MenuItem::List items_after_insertion = GetItems();
  ASSERT_EQ(3u, items_after_insertion.size());

  // 7. Test removeAll().
  ExecuteScriptWaitForTitle(embedder, "removeAllItems()", "ITEM_ALL_REMOVED");
  MenuItem::List items_after_all_removal = GetItems();
  ASSERT_EQ(0u, items_after_all_removal.size());
}

// Called in the TestContextMenu test to cancel the context menu after its
// shown notification is received.
static bool ContextMenuNotificationCallback(
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  auto* context_menu = content::Source<RenderViewContextMenu>(source).ptr();
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(&RenderViewContextMenuBase::Cancel,
                                base::Unretained(context_menu)));
  return true;
}

IN_PROC_BROWSER_TEST_P(WebViewTest, ContextMenusAPI_PreventDefault) {
  LoadAppWithGuest("web_view/context_menus/basic");

  content::WebContents* guest_web_contents = GetGuestWebContents();
  content::WebContents* embedder = GetEmbedderWebContents();
  ASSERT_TRUE(embedder);

  // Add a preventDefault() call on context menu event so context menu
  // does not show up.
  ExtensionTestMessageListener prevent_default_listener(
      "WebViewTest.CONTEXT_MENU_DEFAULT_PREVENTED", false);
  EXPECT_TRUE(content::ExecuteScript(embedder, "registerPreventDefault()"));
  ContextMenuCallCountObserver context_menu_shown_observer;

  OpenContextMenu(guest_web_contents);

  EXPECT_TRUE(prevent_default_listener.WaitUntilSatisfied());
  // Expect the menu to not show up.
  EXPECT_EQ(0, context_menu_shown_observer.num_times_shown());

  // Now remove the preventDefault() and expect context menu to be shown.
  ExecuteScriptWaitForTitle(
      embedder, "removePreventDefault()", "PREVENT_DEFAULT_LISTENER_REMOVED");
  OpenContextMenu(guest_web_contents);

  // We expect to see a context menu for the second call to |OpenContextMenu|.
  context_menu_shown_observer.Wait();
  EXPECT_EQ(1, context_menu_shown_observer.num_times_shown());
}

// Tests that a context menu is created when right-clicking in the webview. This
// also tests that the 'contextmenu' event is handled correctly.
IN_PROC_BROWSER_TEST_P(WebViewTest, TestContextMenu) {
  LoadAppWithGuest("web_view/context_menus/basic");
  content::WebContents* guest_web_contents = GetGuestWebContents();

  // Register an observer for the context menu.
  content::WindowedNotificationObserver menu_observer(
      chrome::NOTIFICATION_RENDER_VIEW_CONTEXT_MENU_SHOWN,
      base::Bind(ContextMenuNotificationCallback));

  OpenContextMenu(guest_web_contents);

  // Wait for the context menu to be visible.
  menu_observer.Wait();
}

IN_PROC_BROWSER_TEST_P(WebViewTest, MediaAccessAPIAllow_TestAllow) {
  MediaAccessAPIAllowTestHelper("testAllow");
}

IN_PROC_BROWSER_TEST_P(WebViewTest, MediaAccessAPIAllow_TestAllowAndThenDeny) {
  MediaAccessAPIAllowTestHelper("testAllowAndThenDeny");
}

IN_PROC_BROWSER_TEST_P(WebViewTest, MediaAccessAPIAllow_TestAllowTwice) {
  MediaAccessAPIAllowTestHelper("testAllowTwice");
}

IN_PROC_BROWSER_TEST_P(WebViewTest, MediaAccessAPIAllow_TestAllowAsync) {
  MediaAccessAPIAllowTestHelper("testAllowAsync");
}

IN_PROC_BROWSER_TEST_P(WebViewTest, MediaAccessAPIAllow_TestCheck) {
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
  LoadAndLaunchPlatformApp("web_view/media_access/check", "Launched");

  content::WebContents* embedder_web_contents = GetFirstAppWindowWebContents();
  ASSERT_TRUE(embedder_web_contents);
  std::unique_ptr<MockWebContentsDelegate> mock(new MockWebContentsDelegate());
  embedder_web_contents->SetDelegate(mock.get());

  ExtensionTestMessageListener done_listener("TEST_PASSED", false);
  done_listener.set_failure_message("TEST_FAILED");
  EXPECT_TRUE(
      content::ExecuteScript(
          embedder_web_contents,
          base::StringPrintf("startCheckTest('')")));
  ASSERT_TRUE(done_listener.WaitUntilSatisfied());

  mock->WaitForCheckMediaPermission();
}

// Checks that window.screenX/screenY/screenLeft/screenTop works correctly for
// guests.
IN_PROC_BROWSER_TEST_P(WebViewTest, ScreenCoordinates) {
  ASSERT_TRUE(RunPlatformAppTestWithArg(
      "platform_apps/web_view/common", "screen_coordinates"))
          << message_;
}

// Flaky on Windows. http://crbug.com/303966
#if defined(OS_WIN)
#define MAYBE_TearDownTest DISABLED_TearDownTest
#else
#define MAYBE_TearDownTest TearDownTest
#endif
IN_PROC_BROWSER_TEST_P(WebViewTest, MAYBE_TearDownTest) {
  const extensions::Extension* extension =
      LoadAndLaunchPlatformApp("web_view/simple", "WebViewTest.LAUNCHED");
  extensions::AppWindow* window = NULL;
  if (!GetAppWindowCount())
    window = CreateAppWindow(browser()->profile(), extension);
  else
    window = GetFirstAppWindow();
  CloseAppWindow(window);

  // Load the app again.
  LoadAndLaunchPlatformApp("web_view/simple", "WebViewTest.LAUNCHED");
}

// Tests that an app can inject a content script into a webview, and that it can
// send cross-origin requests with CORS headers.
IN_PROC_BROWSER_TEST_P(WebViewTest, ContentScriptFetch) {
  TestHelper("testContentScriptFetch", "web_view/content_script_fetch",
             NEEDS_TEST_SERVER);
}

// In following GeolocationAPIEmbedderHasNoAccess* tests, embedder (i.e. the
// platform app) does not have geolocation permission for this test.
// No matter what the API does, geolocation permission would be denied.
// Note that the test name prefix must be "GeolocationAPI".
IN_PROC_BROWSER_TEST_P(WebViewTest, GeolocationAPIEmbedderHasNoAccessAllow) {
  TestHelper("testDenyDenies",
             "web_view/geolocation/embedder_has_no_permission",
             NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, GeolocationAPIEmbedderHasNoAccessDeny) {
  TestHelper("testDenyDenies",
             "web_view/geolocation/embedder_has_no_permission",
             NEEDS_TEST_SERVER);
}

// In following GeolocationAPIEmbedderHasAccess* tests, embedder (i.e. the
// platform app) has geolocation permission
//
// Note that these test names must be "GeolocationAPI" prefixed (b/c we mock out
// geolocation in this case).
//
// Also note that these are run separately because OverrideGeolocation() doesn't
// mock out geolocation for multiple navigator.geolocation calls properly and
// the tests become flaky.
//
// GeolocationAPI* test 1 of 3.
// Currently disabled until crbug.com/526788 is fixed.
IN_PROC_BROWSER_TEST_P(WebViewTest,
                       DISABLED_GeolocationAPIEmbedderHasAccessAllow) {
  TestHelper("testAllow",
             "web_view/geolocation/embedder_has_permission",
             NEEDS_TEST_SERVER);
}

// GeolocationAPI* test 2 of 3.
IN_PROC_BROWSER_TEST_P(WebViewTest, GeolocationAPIEmbedderHasAccessDeny) {
  TestHelper("testDeny",
             "web_view/geolocation/embedder_has_permission",
             NEEDS_TEST_SERVER);
}

// GeolocationAPI* test 3 of 3.
// Currently disabled until crbug.com/526788 is fixed.
IN_PROC_BROWSER_TEST_P(
    WebViewTest,
    DISABLED_GeolocationAPIEmbedderHasAccessMultipleBridgeIdAllow) {
  TestHelper("testMultipleBridgeIdAllow",
             "web_view/geolocation/embedder_has_permission",
             NEEDS_TEST_SERVER);
}

// Tests that
// BrowserPluginGeolocationPermissionContext::CancelGeolocationPermissionRequest
// is handled correctly (and does not crash).
IN_PROC_BROWSER_TEST_P(WebViewTest, GeolocationAPICancelGeolocation) {
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
  ASSERT_TRUE(RunPlatformAppTest(
        "platform_apps/web_view/geolocation/cancel_request")) << message_;
}

IN_PROC_BROWSER_TEST_P(WebViewTest, DISABLED_GeolocationRequestGone) {
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
  ASSERT_TRUE(RunPlatformAppTest(
        "platform_apps/web_view/geolocation/geolocation_request_gone"))
            << message_;
}

// In following FilesystemAPIRequestFromMainThread* tests, guest request
// filesystem access from main thread of the guest.
// FileSystemAPIRequestFromMainThread* test 1 of 3
IN_PROC_BROWSER_TEST_P(WebViewTest, FileSystemAPIRequestFromMainThreadAllow) {
  TestHelper("testAllow", "web_view/filesystem/main", NEEDS_TEST_SERVER);
}

// FileSystemAPIRequestFromMainThread* test 2 of 3.
IN_PROC_BROWSER_TEST_P(WebViewTest, FileSystemAPIRequestFromMainThreadDeny) {
  TestHelper("testDeny", "web_view/filesystem/main", NEEDS_TEST_SERVER);
}

// FileSystemAPIRequestFromMainThread* test 3 of 3.
IN_PROC_BROWSER_TEST_P(WebViewTest,
                       FileSystemAPIRequestFromMainThreadDefaultAllow) {
  TestHelper("testDefaultAllow", "web_view/filesystem/main", NEEDS_TEST_SERVER);
}

// In following FilesystemAPIRequestFromWorker* tests, guest create a worker
// to request filesystem access from worker thread.
// FileSystemAPIRequestFromWorker* test 1 of 3
IN_PROC_BROWSER_TEST_P(WebViewTest, FileSystemAPIRequestFromWorkerAllow) {
  TestHelper("testAllow", "web_view/filesystem/worker", NEEDS_TEST_SERVER);
}

// FileSystemAPIRequestFromWorker* test 2 of 3.
IN_PROC_BROWSER_TEST_P(WebViewTest, FileSystemAPIRequestFromWorkerDeny) {
  TestHelper("testDeny", "web_view/filesystem/worker", NEEDS_TEST_SERVER);
}

// FileSystemAPIRequestFromWorker* test 3 of 3.
IN_PROC_BROWSER_TEST_P(WebViewTest,
                       FileSystemAPIRequestFromWorkerDefaultAllow) {
  TestHelper(
      "testDefaultAllow", "web_view/filesystem/worker", NEEDS_TEST_SERVER);
}

// In following FilesystemAPIRequestFromSharedWorkerOfSingleWebViewGuest* tests,
// embedder contains a single webview guest. The guest creates a shared worker
// to request filesystem access from worker thread.
// FileSystemAPIRequestFromSharedWorkerOfSingleWebViewGuest* test 1 of 3
IN_PROC_BROWSER_TEST_P(
    WebViewTest,
    FileSystemAPIRequestFromSharedWorkerOfSingleWebViewGuestAllow) {
  TestHelper("testAllow",
             "web_view/filesystem/shared_worker/single",
             NEEDS_TEST_SERVER);
}

// FileSystemAPIRequestFromSharedWorkerOfSingleWebViewGuest* test 2 of 3.
IN_PROC_BROWSER_TEST_P(
    WebViewTest,
    FileSystemAPIRequestFromSharedWorkerOfSingleWebViewGuestDeny) {
  TestHelper("testDeny",
             "web_view/filesystem/shared_worker/single",
             NEEDS_TEST_SERVER);
}

// FileSystemAPIRequestFromSharedWorkerOfSingleWebViewGuest* test 3 of 3.
IN_PROC_BROWSER_TEST_P(
    WebViewTest,
    FileSystemAPIRequestFromSharedWorkerOfSingleWebViewGuestDefaultAllow) {
  TestHelper(
      "testDefaultAllow",
      "web_view/filesystem/shared_worker/single",
      NEEDS_TEST_SERVER);
}

// In following FilesystemAPIRequestFromSharedWorkerOfMultiWebViewGuests* tests,
// embedder contains mutiple webview guests. Each guest creates a shared worker
// to request filesystem access from worker thread.
// FileSystemAPIRequestFromSharedWorkerOfMultiWebViewGuests* test 1 of 3
IN_PROC_BROWSER_TEST_P(
    WebViewTest,
    FileSystemAPIRequestFromSharedWorkerOfMultiWebViewGuestsAllow) {
  TestHelper("testAllow",
             "web_view/filesystem/shared_worker/multiple",
             NEEDS_TEST_SERVER);
}

// FileSystemAPIRequestFromSharedWorkerOfMultiWebViewGuests* test 2 of 3.
IN_PROC_BROWSER_TEST_P(
    WebViewTest,
    FileSystemAPIRequestFromSharedWorkerOfMultiWebViewGuestsDeny) {
  TestHelper("testDeny",
             "web_view/filesystem/shared_worker/multiple",
             NEEDS_TEST_SERVER);
}

// FileSystemAPIRequestFromSharedWorkerOfMultiWebViewGuests* test 3 of 3.
IN_PROC_BROWSER_TEST_P(
    WebViewTest,
    FileSystemAPIRequestFromSharedWorkerOfMultiWebViewGuestsDefaultAllow) {
  TestHelper(
      "testDefaultAllow",
      "web_view/filesystem/shared_worker/multiple",
      NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, ClearData) {
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
  ASSERT_TRUE(
      RunPlatformAppTestWithArg("platform_apps/web_view/common", "cleardata"))
      << message_;
}

IN_PROC_BROWSER_TEST_P(WebViewTest, ClearSessionCookies) {
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
  ASSERT_TRUE(RunPlatformAppTestWithArg("platform_apps/web_view/common",
                                        "cleardata_session"))
      << message_;
}

IN_PROC_BROWSER_TEST_P(WebViewTest, ClearPersistentCookies) {
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
  ASSERT_TRUE(RunPlatformAppTestWithArg("platform_apps/web_view/common",
                                        "cleardata_persistent"))
      << message_;
}

// Regression test for https://crbug.com/615429.
IN_PROC_BROWSER_TEST_P(WebViewTest, ClearDataTwice) {
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
  ASSERT_TRUE(RunPlatformAppTestWithArg("platform_apps/web_view/common",
                                        "cleardata_twice"))
      << message_;
}

#if defined(OS_WIN)
// Test is disabled on Windows because it fails often (~9% time)
// http://crbug.com/489088
#define MAYBE_ClearDataCache DISABLED_ClearDataCache
#else
#define MAYBE_ClearDataCache ClearDataCache
#endif
IN_PROC_BROWSER_TEST_P(WebViewTest, MAYBE_ClearDataCache) {
  TestHelper("testClearCache", "web_view/clear_data_cache", NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, ConsoleMessage) {
  ASSERT_TRUE(RunPlatformAppTestWithArg(
      "platform_apps/web_view/common", "console_messages"))
          << message_;
}

IN_PROC_BROWSER_TEST_P(WebViewTest, DownloadPermission) {
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
  content::WebContents* guest_web_contents =
      LoadGuest("/extensions/platform_apps/web_view/download/guest.html",
                "web_view/download");
  ASSERT_TRUE(guest_web_contents);

  base::ScopedAllowBlockingForTesting allow_blocking;
  base::ScopedTempDir temporary_download_dir;
  ASSERT_TRUE(temporary_download_dir.CreateUniqueTempDir());
  DownloadPrefs::FromBrowserContext(guest_web_contents->GetBrowserContext())
      ->SetDownloadPath(temporary_download_dir.GetPath());

  std::unique_ptr<content::DownloadTestObserver> completion_observer(
      new content::DownloadTestObserverTerminal(
          content::BrowserContext::GetDownloadManager(
              guest_web_contents->GetBrowserContext()),
          1, content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));

  // Replace WebContentsDelegate with mock version so we can intercept download
  // requests.
  content::WebContentsDelegate* delegate = guest_web_contents->GetDelegate();
  std::unique_ptr<MockDownloadWebContentsDelegate> mock_delegate(
      new MockDownloadWebContentsDelegate(delegate));
  guest_web_contents->SetDelegate(mock_delegate.get());

  // Start test.
  // 1. Guest requests a download that its embedder denies.
  EXPECT_TRUE(content::ExecuteScript(guest_web_contents,
                                     "startDownload('download-link-1')"));
  mock_delegate->WaitForCanDownload(false);  // Expect to not allow.
  mock_delegate->Reset();

  // 2. Guest requests a download that its embedder allows.
  EXPECT_TRUE(content::ExecuteScript(guest_web_contents,
                                     "startDownload('download-link-2')"));
  mock_delegate->WaitForCanDownload(true);  // Expect to allow.
  mock_delegate->Reset();

  // 3. Guest requests a download that its embedder ignores, this implies deny.
  EXPECT_TRUE(content::ExecuteScript(guest_web_contents,
                                     "startDownload('download-link-3')"));
  mock_delegate->WaitForCanDownload(false);  // Expect to not allow.
  completion_observer->WaitForFinished();
}

namespace {

const char kDownloadPathPrefix[] = "/download_cookie_isolation_test";

// EmbeddedTestServer request handler for use with DownloadCookieIsolation test.
// Responds with the next status code 200 if the 'Cookie' header sent with the
// request matches the query() part of the URL. Otherwise, fails the request
// with an HTTP 403. The body of the response is the value of the Cookie
// header.
std::unique_ptr<net::test_server::HttpResponse> HandleDownloadRequestWithCookie(
    const net::test_server::HttpRequest& request) {
  if (!base::StartsWith(request.relative_url, kDownloadPathPrefix,
                        base::CompareCase::SENSITIVE)) {
    return std::unique_ptr<net::test_server::HttpResponse>();
  }

  std::string cookie_to_expect = request.GetURL().query();
  const auto cookie_header_it = request.headers.find("cookie");
  std::unique_ptr<net::test_server::BasicHttpResponse> response;

  // Return a 403 if there's no cookie or if the cookie doesn't match.
  if (cookie_header_it == request.headers.end() ||
      cookie_header_it->second != cookie_to_expect) {
    response.reset(new net::test_server::BasicHttpResponse);
    response->set_code(net::HTTP_FORBIDDEN);
    response->set_content_type("text/plain");
    response->set_content("Forbidden");
    return std::move(response);
  }

  // We have a cookie. Send some content along with the next status code.
  response.reset(new net::test_server::BasicHttpResponse);
  response->set_code(net::HTTP_OK);
  response->set_content_type("application/octet-stream");
  response->set_content(cookie_to_expect);
  return std::move(response);
}

class DownloadHistoryWaiter : public DownloadHistory::Observer {
 public:
  explicit DownloadHistoryWaiter(content::BrowserContext* browser_context) {
    DownloadCoreService* service =
        DownloadCoreServiceFactory::GetForBrowserContext(browser_context);
    download_history_ = service->GetDownloadHistory();
    download_history_->AddObserver(this);
  }

  ~DownloadHistoryWaiter() override { download_history_->RemoveObserver(this); }

  void WaitForStored(size_t download_count) {
    if (stored_downloads_.size() >= download_count)
      return;
    stored_download_target_ = download_count;
    Wait();
  }

  void WaitForHistoryLoad() {
    if (history_query_complete_)
      return;
    Wait();
  }

 private:
  void Wait() {
    base::RunLoop run_loop;
    quit_closure_ = run_loop.QuitClosure();
    run_loop.Run();
  }

  void OnDownloadStored(content::DownloadItem* item,
                        const history::DownloadRow& info) override {
    stored_downloads_.insert(item);
    if (!quit_closure_.is_null() &&
        stored_downloads_.size() >= stored_download_target_) {
      base::ResetAndReturn(&quit_closure_).Run();
    }
  }

  void OnHistoryQueryComplete() override {
    history_query_complete_ = true;
    if (!quit_closure_.is_null())
      base::ResetAndReturn(&quit_closure_).Run();
  }

  std::unordered_set<content::DownloadItem*> stored_downloads_;
  size_t stored_download_target_ = 0;
  bool history_query_complete_ = false;
  base::Closure quit_closure_;
  DownloadHistory* download_history_ = nullptr;
};

}  // namespace

// Downloads initiated from isolated guest parititons should use their
// respective cookie stores. In addition, if those downloads are resumed, they
// should continue to use their respective cookie stores.
IN_PROC_BROWSER_TEST_P(WebViewTest, DownloadCookieIsolation) {
  embedded_test_server()->RegisterRequestHandler(
      base::BindRepeating(&HandleDownloadRequestWithCookie));
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
  LoadAndLaunchPlatformApp("web_view/download_cookie_isolation",
                           "created-webviews");

  content::WebContents* web_contents = GetFirstAppWindowWebContents();
  ASSERT_TRUE(web_contents);

  base::ScopedAllowBlockingForTesting allow_blocking;
  base::ScopedTempDir temporary_download_dir;
  ASSERT_TRUE(temporary_download_dir.CreateUniqueTempDir());
  DownloadPrefs::FromBrowserContext(web_contents->GetBrowserContext())
      ->SetDownloadPath(temporary_download_dir.GetPath());

  content::DownloadManager* download_manager =
      content::BrowserContext::GetDownloadManager(
          web_contents->GetBrowserContext());

  scoped_refptr<content::TestFileErrorInjector> error_injector(
      content::TestFileErrorInjector::Create(download_manager));

  content::TestFileErrorInjector::FileErrorInfo error_info(
      content::TestFileErrorInjector::FILE_OPERATION_STREAM_COMPLETE, 0,
      content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED);
  error_info.stream_offset = 0;
  error_injector->InjectError(error_info);

  std::unique_ptr<content::DownloadTestObserver> interrupted_observer(
      new content::DownloadTestObserverInterrupted(
          download_manager, 2,
          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));

  EXPECT_TRUE(content::ExecuteScript(
      web_contents,
      base::StringPrintf(
          "startDownload('first', '%s?cookie=first')",
          embedded_test_server()->GetURL(kDownloadPathPrefix).spec().c_str())));

  EXPECT_TRUE(content::ExecuteScript(
      web_contents,
      base::StringPrintf(
          "startDownload('second', '%s?cookie=second')",
          embedded_test_server()->GetURL(kDownloadPathPrefix).spec().c_str())));

  // Both downloads should fail due to the error that was injected above to the
  // download manager. This maps to DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED.
  interrupted_observer->WaitForFinished();

  error_injector->ClearError();

  content::DownloadManager::DownloadVector downloads;
  download_manager->GetAllDownloads(&downloads);
  ASSERT_EQ(2u, downloads.size());

  CloseAppWindow(GetFirstAppWindow());

  std::unique_ptr<content::DownloadTestObserver> completion_observer(
      new content::DownloadTestObserverTerminal(
          download_manager, 2,
          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));

  for (auto* download : downloads) {
    ASSERT_TRUE(download->CanResume());
    EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED,
              download->GetLastReason());
    download->Resume();
  }

  completion_observer->WaitForFinished();

  std::set<std::string> cookies;
  for (auto* download : downloads) {
    ASSERT_EQ(content::DownloadItem::COMPLETE, download->GetState());
    ASSERT_TRUE(base::PathExists(download->GetTargetFilePath()));
    std::string content;
    ASSERT_TRUE(
        base::ReadFileToString(download->GetTargetFilePath(), &content));
    // Note that the contents of the file is the value of the cookie.
    EXPECT_EQ(content, download->GetURL().query());
    cookies.insert(content);
  }

  ASSERT_EQ(2u, cookies.size());
  ASSERT_TRUE(cookies.find("cookie=first") != cookies.end());
  ASSERT_TRUE(cookies.find("cookie=second") != cookies.end());
}

IN_PROC_BROWSER_TEST_P(WebViewTest, PRE_DownloadCookieIsolation_CrossSession) {
  embedded_test_server()->RegisterRequestHandler(
      base::BindRepeating(&HandleDownloadRequestWithCookie));
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
  LoadAndLaunchPlatformApp("web_view/download_cookie_isolation",
                           "created-webviews");

  content::WebContents* web_contents = GetFirstAppWindowWebContents();
  ASSERT_TRUE(web_contents);

  base::ScopedAllowBlockingForTesting allow_blocking;
  base::ScopedTempDir temporary_download_dir;
  ASSERT_TRUE(temporary_download_dir.CreateUniqueTempDir());
  DownloadPrefs::FromBrowserContext(web_contents->GetBrowserContext())
      ->SetDownloadPath(temporary_download_dir.GetPath());

  content::DownloadManager* download_manager =
      content::BrowserContext::GetDownloadManager(
          web_contents->GetBrowserContext());

  DownloadHistoryWaiter history_waiter(web_contents->GetBrowserContext());

  std::unique_ptr<content::DownloadTestObserver> interrupted_observer(
      new content::DownloadTestObserverInterrupted(
          download_manager, 2,
          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));

  scoped_refptr<content::TestFileErrorInjector> error_injector(
      content::TestFileErrorInjector::Create(download_manager));

  content::TestFileErrorInjector::FileErrorInfo error_info(
      content::TestFileErrorInjector::FILE_OPERATION_STREAM_COMPLETE, 0,
      content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED);
  error_info.stream_offset = 0;
  error_injector->InjectError(error_info);

  EXPECT_TRUE(content::ExecuteScript(
      web_contents,
      base::StringPrintf(
          "startDownload('first', '%s?cookie=first')",
          embedded_test_server()->GetURL(kDownloadPathPrefix).spec().c_str())));

  // Note that the second webview uses an in-memory partition.
  EXPECT_TRUE(content::ExecuteScript(
      web_contents,
      base::StringPrintf(
          "startDownload('second', '%s?cookie=second')",
          embedded_test_server()->GetURL(kDownloadPathPrefix).spec().c_str())));

  // Both downloads should fail due to the error that was injected above to the
  // download manager. This maps to DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED.
  interrupted_observer->WaitForFinished();

  // Wait for both downloads to be stored.
  history_waiter.WaitForStored(2);

  // Leak the temporary download directory. We'll retake ownership in the next
  // browser session.
  temporary_download_dir.Take();
}

IN_PROC_BROWSER_TEST_P(WebViewTest, DownloadCookieIsolation_CrossSession) {
  embedded_test_server()->RegisterRequestHandler(
      base::BindRepeating(&HandleDownloadRequestWithCookie));
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.

  content::BrowserContext* browser_context = profile();
  content::DownloadManager* download_manager =
      content::BrowserContext::GetDownloadManager(browser_context);

  DownloadHistoryWaiter history_waiter(browser_context);
  history_waiter.WaitForHistoryLoad();

  base::ScopedAllowBlockingForTesting allow_blocking;
  base::ScopedTempDir temporary_download_dir;
  ASSERT_TRUE(temporary_download_dir.Set(
      DownloadPrefs::FromBrowserContext(browser_context)->DownloadPath()));

  content::DownloadManager::DownloadVector saved_downloads;
  download_manager->GetAllDownloads(&saved_downloads);
  ASSERT_EQ(2u, saved_downloads.size());

  content::DownloadManager::DownloadVector downloads;
  // We can't trivially resume the previous downloads because they are going to
  // try to talk to the old EmbeddedTestServer instance. We need to update the
  // URL to point to the new instance, which should only differ by the port
  // number.
  for (auto* download : saved_downloads) {
    const std::string port_string =
        base::UintToString(embedded_test_server()->port());
    url::Replacements<char> replacements;
    replacements.SetPort(port_string.c_str(),
                         url::Component(0, port_string.size()));
    std::vector<GURL> url_chain;
    url_chain.push_back(download->GetURL().ReplaceComponents(replacements));

    downloads.push_back(download_manager->CreateDownloadItem(
        base::GenerateGUID(), download->GetId() + 2, download->GetFullPath(),
        download->GetTargetFilePath(), url_chain, download->GetReferrerUrl(),
        download->GetSiteUrl(), download->GetTabUrl(),
        download->GetTabReferrerUrl(), download->GetMimeType(),
        download->GetOriginalMimeType(), download->GetStartTime(),
        download->GetEndTime(), download->GetETag(),
        download->GetLastModifiedTime(), download->GetReceivedBytes(),
        download->GetTotalBytes(), download->GetHash(), download->GetState(),
        download->GetDangerType(), download->GetLastReason(),
        download->GetOpened(), download->GetLastAccessTime(),
        download->IsTransient(), download->GetReceivedSlices()));
  }

  std::unique_ptr<content::DownloadTestObserver> completion_observer(
      new content::DownloadTestObserverTerminal(
          download_manager, 2,
          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));

  for (auto* download : downloads) {
    ASSERT_TRUE(download->CanResume());
    ASSERT_TRUE(temporary_download_dir.GetPath().IsParent(
        download->GetTargetFilePath()));
    ASSERT_TRUE(download->GetFullPath().empty());
    EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED,
              download->GetLastReason());
    download->Resume();
  }

  completion_observer->WaitForFinished();

  // Of the two downloads, ?cookie=first will succeed and ?cookie=second will
  // fail. The latter fails because the underlying storage partition was not
  // persisted.

  content::DownloadItem* succeeded_download = downloads[0];
  content::DownloadItem* failed_download = downloads[1];

  if (downloads[0]->GetState() == content::DownloadItem::INTERRUPTED)
    std::swap(succeeded_download, failed_download);

  ASSERT_EQ(content::DownloadItem::COMPLETE, succeeded_download->GetState());
  ASSERT_TRUE(base::PathExists(succeeded_download->GetTargetFilePath()));
  std::string content;
  ASSERT_TRUE(base::ReadFileToString(succeeded_download->GetTargetFilePath(),
                                     &content));
  // This is the cookie that should've been stored in the persisted storage
  // partition.
  EXPECT_STREQ("cookie=first", content.c_str());

  ASSERT_EQ(content::DownloadItem::INTERRUPTED, failed_download->GetState());
  EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_SERVER_FORBIDDEN,
            failed_download->GetLastReason());
}

// This test makes sure loading <webview> does not crash when there is an
// extension which has content script whitelisted/forced.
IN_PROC_BROWSER_TEST_P(WebViewTest, WhitelistedContentScript) {
  // Whitelist the extension for running content script we are going to load.
  extensions::ExtensionsClient::ScriptingWhitelist whitelist;
  const std::string extension_id = "imeongpbjoodlnmlakaldhlcmijmhpbb";
  whitelist.push_back(extension_id);
  extensions::ExtensionsClient::Get()->SetScriptingWhitelist(whitelist);

  // Load the extension.
  const extensions::Extension* content_script_whitelisted_extension =
      LoadExtension(test_data_dir_.AppendASCII(
                        "platform_apps/web_view/extension_api/content_script"));
  ASSERT_TRUE(content_script_whitelisted_extension);
  ASSERT_EQ(extension_id, content_script_whitelisted_extension->id());

  // Now load an app with <webview>.
  LoadAndLaunchPlatformApp("web_view/content_script_whitelisted",
                           "TEST_PASSED");
}

IN_PROC_BROWSER_TEST_P(WebViewTest, SendMessageToExtensionFromGuest) {
  // Load the extension as a normal, non-component extension.
  const extensions::Extension* extension =
      LoadExtension(test_data_dir_.AppendASCII(
          "platform_apps/web_view/extension_api/component_extension"));
  ASSERT_TRUE(extension);

  TestHelper("testNonComponentExtension", "web_view/component_extension",
             NEEDS_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, SendMessageToComponentExtensionFromGuest) {
  const extensions::Extension* component_extension =
      LoadExtensionAsComponent(test_data_dir_.AppendASCII(
          "platform_apps/web_view/extension_api/component_extension"));
  ASSERT_TRUE(component_extension);

  TestHelper("testComponentExtension", "web_view/component_extension",
             NEEDS_TEST_SERVER);

  content::WebContents* embedder_web_contents = GetFirstAppWindowWebContents();
  ASSERT_TRUE(embedder_web_contents);

  // Retrive the guestProcessId and guestRenderFrameRoutingId from the
  // extension.
  int guest_process_id = content::ChildProcessHost::kInvalidUniqueID;
  content::ExecuteScriptAndGetValue(embedder_web_contents->GetMainFrame(),
                                    "window.guestProcessId")
      ->GetAsInteger(&guest_process_id);
  int guest_render_frame_routing_id = MSG_ROUTING_NONE;
  content::ExecuteScriptAndGetValue(embedder_web_contents->GetMainFrame(),
                                    "window.guestRenderFrameRoutingId")
      ->GetAsInteger(&guest_render_frame_routing_id);

  auto* guest_rfh = content::RenderFrameHost::FromID(
      guest_process_id, guest_render_frame_routing_id);
  // Verify that the guest related info (guest_process_id and
  // guest_render_frame_routing_id) actually points to a WebViewGuest.
  ASSERT_TRUE(extensions::WebViewGuest::FromWebContents(
      content::WebContents::FromRenderFrameHost(guest_rfh)));
}

IN_PROC_BROWSER_TEST_P(WebViewTest, SetPropertyOnDocumentReady) {
  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/document_ready"))
                  << message_;
}

IN_PROC_BROWSER_TEST_P(WebViewTest, SetPropertyOnDocumentInteractive) {
  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/document_interactive"))
                  << message_;
}

IN_PROC_BROWSER_TEST_P(WebViewSpeechAPITest,
                       SpeechRecognitionAPI_HasPermissionAllow) {
  ASSERT_TRUE(
      RunPlatformAppTestWithArg("platform_apps/web_view/speech_recognition_api",
                                "allowTest"))
          << message_;
}

IN_PROC_BROWSER_TEST_P(WebViewSpeechAPITest,
                       SpeechRecognitionAPI_HasPermissionDeny) {
  ASSERT_TRUE(
      RunPlatformAppTestWithArg("platform_apps/web_view/speech_recognition_api",
                                "denyTest"))
          << message_;
}

IN_PROC_BROWSER_TEST_P(WebViewSpeechAPITest,
                       SpeechRecognitionAPI_NoPermission) {
  ASSERT_TRUE(
      RunPlatformAppTestWithArg("platform_apps/web_view/common",
                                "speech_recognition_api_no_permission"))
          << message_;
}

// Tests overriding user agent.
IN_PROC_BROWSER_TEST_P(WebViewTest, UserAgent) {
  ASSERT_TRUE(RunPlatformAppTestWithArg(
              "platform_apps/web_view/common", "useragent")) << message_;
}

IN_PROC_BROWSER_TEST_P(WebViewNewWindowTest, UserAgent_NewWindow) {
  ASSERT_TRUE(RunPlatformAppTestWithArg(
              "platform_apps/web_view/common",
              "useragent_newwindow")) << message_;
}

IN_PROC_BROWSER_TEST_P(WebViewTest, NoPermission) {
  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/nopermission"))
                  << message_;
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Dialog_TestAlertDialog) {
  TestHelper("testAlertDialog", "web_view/dialog", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, TestConfirmDialog) {
  TestHelper("testConfirmDialog", "web_view/dialog", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Dialog_TestConfirmDialogCancel) {
  TestHelper("testConfirmDialogCancel", "web_view/dialog", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Dialog_TestConfirmDialogDefaultCancel) {
  TestHelper("testConfirmDialogDefaultCancel",
             "web_view/dialog",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Dialog_TestConfirmDialogDefaultGCCancel) {
  TestHelper("testConfirmDialogDefaultGCCancel",
             "web_view/dialog",
             NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Dialog_TestPromptDialog) {
  TestHelper("testPromptDialog", "web_view/dialog", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, NoContentSettingsAPI) {
  // Load the extension.
  const extensions::Extension* content_settings_extension =
      LoadExtension(
          test_data_dir_.AppendASCII(
              "platform_apps/web_view/extension_api/content_settings"));
  ASSERT_TRUE(content_settings_extension);
  TestHelper("testPostMessageCommChannel", "web_view/shim", NO_TEST_SERVER);
}

#if BUILDFLAG(ENABLE_PLUGINS)
class WebViewPluginTest : public WebViewTest {
 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    WebViewTest::SetUpCommandLine(command_line);
    ASSERT_TRUE(ppapi::RegisterTestPlugin(command_line));
  }
};
INSTANTIATE_TEST_CASE_P(WebViewTests, WebViewPluginTest, testing::Bool());

IN_PROC_BROWSER_TEST_P(WebViewPluginTest, TestLoadPluginEvent) {
  TestHelper("testPluginLoadPermission", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewPluginTest, TestLoadPluginInternalResource) {
  const char kTestMimeType[] = "application/pdf";
  const char kTestFileType[] = "pdf";
  content::WebPluginInfo plugin_info;
  plugin_info.type = content::WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS;
  plugin_info.mime_types.push_back(
      content::WebPluginMimeType(kTestMimeType, kTestFileType, std::string()));
  content::PluginService::GetInstance()->RegisterInternalPlugin(plugin_info,
                                                                true);

  TestHelper("testPluginLoadInternalResource", "web_view/shim", NO_TEST_SERVER);
}
#endif  // BUILDFLAG(ENABLE_PLUGINS)

class WebViewCaptureTest : public WebViewTest {
 public:
  WebViewCaptureTest() {}
  ~WebViewCaptureTest() override {}
  void SetUp() override {
    EnablePixelOutput();
    WebViewTest::SetUp();
  }
};
INSTANTIATE_TEST_CASE_P(WebViewTests, WebViewCaptureTest, testing::Bool());

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestZoomAPI) {
  TestHelper("testZoomAPI", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestFindAPI) {
  TestHelper("testFindAPI", "web_view/shim", NO_TEST_SERVER);
}

// crbug.com/710486
#if defined(MEMORY_SANITIZER)
#define MAYBE_Shim_TestFindAPI_findupdate DISABLED_Shim_TestFindAPI_findupdate
#else
#define MAYBE_Shim_TestFindAPI_findupdate Shim_TestFindAPI_findupdate
#endif
IN_PROC_BROWSER_TEST_P(WebViewTest, MAYBE_Shim_TestFindAPI_findupdate) {
  TestHelper("testFindAPI_findupdate", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_testFindInMultipleWebViews) {
  TestHelper("testFindInMultipleWebViews", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestLoadDataAPI) {
  TestHelper("testLoadDataAPI", "web_view/shim", NEEDS_TEST_SERVER);
}

// This test verifies that the resize and contentResize events work correctly.
IN_PROC_BROWSER_TEST_P(WebViewSizeTest, Shim_TestResizeEvents) {
  TestHelper("testResizeEvents", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestPerOriginZoomMode) {
  TestHelper("testPerOriginZoomMode", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestPerViewZoomMode) {
  TestHelper("testPerViewZoomMode", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestDisabledZoomMode) {
  TestHelper("testDisabledZoomMode", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestZoomBeforeNavigation) {
  TestHelper("testZoomBeforeNavigation", "web_view/shim", NO_TEST_SERVER);
}

// This test verify that the set of rules registries of a webview will be
// removed from RulesRegistryService after the webview is gone.
// http://crbug.com/438327
IN_PROC_BROWSER_TEST_P(
    WebViewTest,
    DISABLED_Shim_TestRulesRegistryIDAreRemovedAfterWebViewIsGone) {
  LoadAppWithGuest("web_view/rules_registry");

  content::WebContents* embedder_web_contents = GetEmbedderWebContents();
  ASSERT_TRUE(embedder_web_contents);
  std::unique_ptr<EmbedderWebContentsObserver> observer(
      new EmbedderWebContentsObserver(embedder_web_contents));

  content::WebContents* guest_web_contents = GetGuestWebContents();
  ASSERT_TRUE(guest_web_contents);
  extensions::WebViewGuest* guest =
      extensions::WebViewGuest::FromWebContents(guest_web_contents);
  ASSERT_TRUE(guest);

  // Register rule for the guest.
  Profile* profile = browser()->profile();
  int rules_registry_id =
      extensions::WebViewGuest::GetOrGenerateRulesRegistryID(
          guest->owner_web_contents()->GetMainFrame()->GetProcess()->GetID(),
          guest->view_instance_id());

  extensions::RulesRegistryService* registry_service =
      extensions::RulesRegistryService::Get(profile);
  extensions::TestRulesRegistry* rules_registry =
      new extensions::TestRulesRegistry(
          content::BrowserThread::UI, "ui", rules_registry_id);
  registry_service->RegisterRulesRegistry(base::WrapRefCounted(rules_registry));

  EXPECT_TRUE(registry_service->GetRulesRegistry(
      rules_registry_id, "ui").get());

  // Kill the embedder's render process, so the webview will go as well.
  base::Process process = base::Process::DeprecatedGetProcessFromHandle(
      embedder_web_contents->GetMainFrame()->GetProcess()->GetHandle());
  process.Terminate(0, false);
  observer->WaitForEmbedderRenderProcessTerminate();

  EXPECT_FALSE(registry_service->GetRulesRegistry(
      rules_registry_id, "ui").get());
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_WebViewWebRequestRegistryHasNoCache) {
  LoadAppWithGuest("web_view/rules_registry");

  content::WebContents* guest_web_contents = GetGuestWebContents();
  ASSERT_TRUE(guest_web_contents);
  extensions::WebViewGuest* guest =
      extensions::WebViewGuest::FromWebContents(guest_web_contents);
  ASSERT_TRUE(guest);

  Profile* profile = browser()->profile();
  extensions::RulesRegistryService* registry_service =
      extensions::RulesRegistryService::Get(profile);
  int rules_registry_id =
      extensions::WebViewGuest::GetOrGenerateRulesRegistryID(
          guest->owner_web_contents()->GetMainFrame()->GetProcess()->GetID(),
          guest->view_instance_id());

  // Get an existing registered rule for the guest.
  extensions::RulesRegistry* registry =
      registry_service->GetRulesRegistry(
          rules_registry_id,
          extensions::declarative_webrequest_constants::kOnRequest).get();

  EXPECT_TRUE(registry);
  EXPECT_FALSE(registry->rules_cache_delegate_for_testing());
}

// This test verifies that webview.contentWindow works inside an iframe.
IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestWebViewInsideFrame) {
  LoadAppWithGuest("web_view/inside_iframe");
}

// <webview> screenshot capture fails with ubercomp.
// See http://crbug.com/327035.
IN_PROC_BROWSER_TEST_P(WebViewCaptureTest, DISABLED_Shim_ScreenshotCapture) {
  TestHelper("testScreenshotCapture", "web_view/shim", NO_TEST_SERVER);
}

// Tests that browser process does not crash when loading plugin inside
// <webview> with content settings set to CONTENT_SETTING_BLOCK.
IN_PROC_BROWSER_TEST_P(WebViewTest, TestPlugin) {
  HostContentSettingsMapFactory::GetForProfile(browser()->profile())
    ->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS,
                               CONTENT_SETTING_BLOCK);
  TestHelper("testPlugin", "web_view/shim", NEEDS_TEST_SERVER);
}

#if defined(OS_WIN)
// Test is disabled on Windows because it times out often.
// http://crbug.com/403325
#define MAYBE_WebViewInBackgroundPage \
    DISABLED_WebViewInBackgroundPage
#else
#define MAYBE_WebViewInBackgroundPage WebViewInBackgroundPage
#endif
IN_PROC_BROWSER_TEST_P(WebViewTest, MAYBE_WebViewInBackgroundPage) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(RunExtensionTest("platform_apps/web_view/background"))
      << message_;
}

// This test verifies that the allowtransparency attribute properly propagates.
IN_PROC_BROWSER_TEST_P(WebViewTest, AllowTransparencyAndAllowScalingPropagate) {
  LoadAppWithGuest("web_view/simple");

  ASSERT_TRUE(GetGuestWebContents());
  extensions::WebViewGuest* guest =
      extensions::WebViewGuest::FromWebContents(GetGuestWebContents());
  ASSERT_TRUE(guest->allow_transparency());
  ASSERT_TRUE(guest->allow_scaling());
}

IN_PROC_BROWSER_TEST_P(WebViewTest, BasicPostMessage) {
  ASSERT_TRUE(StartEmbeddedTestServer());  // For serving guest pages.
  ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/post_message/basic"))
      << message_;
}

// Tests that webviews do get garbage collected.
IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestGarbageCollect) {
  TestHelper("testGarbageCollect", "web_view/shim", NO_TEST_SERVER);
  GetGuestViewManager()->WaitForSingleViewGarbageCollected();
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestCloseNewWindowCleanup) {
  TestHelper("testCloseNewWindowCleanup", "web_view/shim", NEEDS_TEST_SERVER);
  auto* gvm = GetGuestViewManager();
  gvm->WaitForLastGuestDeleted();
  ASSERT_EQ(gvm->num_embedder_processes_destroyed(), 0);
}

// Ensure that focusing a WebView while it is already focused does not blur the
// guest content.
IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestFocusWhileFocused) {
  TestHelper("testFocusWhileFocused", "web_view/shim", NO_TEST_SERVER);
}

IN_PROC_BROWSER_TEST_P(WebViewTest, NestedGuestContainerBounds) {
  // TODO(crbug.com/776539): Disabled due to being flaky.
  if (GetParam() == true) {
    DLOG(ERROR) << "Disabled due to flakiness.";
    return;
  }

  TestHelper("testPDFInWebview", "web_view/shim", NO_TEST_SERVER);

  std::vector<content::WebContents*> guest_web_contents_list;
  GetGuestViewManager()->WaitForNumGuestsCreated(2u);
  GetGuestViewManager()->GetGuestWebContentsList(&guest_web_contents_list);
  ASSERT_EQ(2u, guest_web_contents_list.size());

  content::WebContents* web_view_contents = guest_web_contents_list[0];
  content::WebContents* mime_handler_view_contents = guest_web_contents_list[1];

  // Make sure we've completed loading |mime_handler_view_guest|.
  bool load_success = pdf_extension_test_util::EnsurePDFHasLoaded(
      web_view_contents);
  EXPECT_TRUE(load_success);

  gfx::Rect web_view_container_bounds = web_view_contents->GetContainerBounds();
  gfx::Rect mime_handler_view_container_bounds =
      mime_handler_view_contents->GetContainerBounds();
  EXPECT_EQ(web_view_container_bounds.origin(),
            mime_handler_view_container_bounds.origin());
}

// Test that context menu Back/Forward items in a MimeHandlerViewGuest affect
// the embedder WebContents. See crbug.com/587355.
IN_PROC_BROWSER_TEST_P(WebViewTest, ContextMenuNavigationInMimeHandlerView) {
  TestHelper("testNavigateToPDFInWebview", "web_view/shim", NO_TEST_SERVER);

  std::vector<content::WebContents*> guest_web_contents_list;
  GetGuestViewManager()->WaitForNumGuestsCreated(2u);
  GetGuestViewManager()->GetGuestWebContentsList(&guest_web_contents_list);
  ASSERT_EQ(2u, guest_web_contents_list.size());

  content::WebContents* web_view_contents = guest_web_contents_list[0];
  content::WebContents* mime_handler_view_contents = guest_web_contents_list[1];
  ASSERT_TRUE(pdf_extension_test_util::EnsurePDFHasLoaded(web_view_contents));

  // Ensure the <webview> has a previous entry, so we can navigate back to it.
  ASSERT_TRUE(web_view_contents->GetController().CanGoBack());

  // Open a context menu for the MimeHandlerViewGuest. Since the <webview> can
  // navigate back, the Back item should be enabled.
  content::ContextMenuParams params;
  TestRenderViewContextMenu menu(mime_handler_view_contents->GetMainFrame(),
                                 params);
  menu.Init();
  ASSERT_TRUE(menu.IsCommandIdEnabled(IDC_BACK));

  // Verify that the Back item causes the <webview> to navigate back to the
  // previous entry.
  content::TestNavigationObserver observer(web_view_contents);
  menu.ExecuteCommand(IDC_BACK, 0);
  observer.Wait();
  EXPECT_EQ(GURL(url::kAboutBlankURL),
            web_view_contents->GetLastCommittedURL());
}

IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestMailtoLink) {
  TestHelper("testMailtoLink", "web_view/shim", NEEDS_TEST_SERVER);
}

// Tests that a renderer navigation from an unattached guest that results in a
// server redirect works properly.
IN_PROC_BROWSER_TEST_P(WebViewTest,
                       Shim_TestRendererNavigationRedirectWhileUnattached) {
  TestHelper("testRendererNavigationRedirectWhileUnattached",
             "web_view/shim", NEEDS_TEST_SERVER);
}

// Tests that the embedder can create a blob URL and navigate a WebView to it.
// See https://crbug.com/652077.
IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestBlobURL) {
  TestHelper("testBlobURL", "web_view/shim", NEEDS_TEST_SERVER);
}

// Tests that a WebView accessible resource can actually be loaded from a
// webpage in a WebView.
IN_PROC_BROWSER_TEST_P(WebViewTest, LoadWebviewAccessibleResource) {
  TestHelper("testLoadWebviewAccessibleResource",
             "web_view/load_webview_accessible_resource", NEEDS_TEST_SERVER);
}

// Tests that a WebView can reload a WebView accessible resource. See
// https://crbug.com/691941.
IN_PROC_BROWSER_TEST_P(WebViewTest, ReloadWebviewAccessibleResource) {
  TestHelper("testReloadWebviewAccessibleResource",
             "web_view/load_webview_accessible_resource", NEEDS_TEST_SERVER);

  content::WebContents* embedder_contents = GetEmbedderWebContents();
  content::WebContents* web_view_contents =
      GetGuestViewManager()->GetLastGuestCreated();
  ASSERT_TRUE(embedder_contents);
  ASSERT_TRUE(web_view_contents);

  GURL embedder_url(embedder_contents->GetLastCommittedURL());
  GURL webview_url(embedder_url.GetOrigin().spec() + "assets/foo.html");

  EXPECT_EQ(webview_url, web_view_contents->GetLastCommittedURL());
}

// Tests that a WebView can navigate an iframe to a blob URL that it creates
// while its main frame is at a WebView accessible resource.
IN_PROC_BROWSER_TEST_P(WebViewTest, BlobInWebviewAccessibleResource) {
  TestHelper("testBlobInWebviewAccessibleResource",
             "web_view/load_webview_accessible_resource", NEEDS_TEST_SERVER);

  content::WebContents* embedder_contents = GetEmbedderWebContents();
  content::WebContents* web_view_contents =
      GetGuestViewManager()->GetLastGuestCreated();
  ASSERT_TRUE(embedder_contents);
  ASSERT_TRUE(web_view_contents);

  GURL embedder_url(embedder_contents->GetLastCommittedURL());
  GURL webview_url(embedder_url.GetOrigin().spec() + "assets/foo.html");

  EXPECT_EQ(webview_url, web_view_contents->GetLastCommittedURL());

  content::RenderFrameHost* main_frame = web_view_contents->GetMainFrame();
  content::RenderFrameHost* blob_frame = ChildFrameAt(main_frame, 0);
  EXPECT_TRUE(blob_frame->GetLastCommittedURL().SchemeIsBlob());

  std::string result;
  EXPECT_TRUE(ExecuteScriptAndExtractString(
      blob_frame,
      "window.domAutomationController.send(document.body.innerText);",
      &result));
  EXPECT_EQ("Blob content", result);
}

// Tests that a WebView cannot load a webview-inaccessible resource. See
// https://crbug.com/640072.
IN_PROC_BROWSER_TEST_P(WebViewTest, LoadWebviewInaccessibleResource) {
  TestHelper("testLoadWebviewInaccessibleResource",
             "web_view/load_webview_accessible_resource", NEEDS_TEST_SERVER);

  content::WebContents* embedder_contents = GetEmbedderWebContents();
  content::WebContents* web_view_contents =
      GetGuestViewManager()->GetLastGuestCreated();
  ASSERT_TRUE(embedder_contents);
  ASSERT_TRUE(web_view_contents);

  // Check that the webview stays at the first page that it loaded (foo.html),
  // and does not commit inaccessible.html.
  GURL embedder_url(embedder_contents->GetLastCommittedURL());
  GURL foo_url(embedder_url.GetOrigin().spec() + "assets/foo.html");

  EXPECT_EQ(foo_url, web_view_contents->GetLastCommittedURL());
}

// Tests that a webview inside an iframe can load and that it is destroyed when
// the iframe is detached.
// Flakily times out under MSan. crbug.com/793422
#if defined(MEMORY_SANITIZER)
#define MAYBE_LoadWebviewInsideIframe DISABLED_LoadWebviewInsideIframe
#else
#define MAYBE_LoadWebviewInsideIframe LoadWebviewInsideIframe
#endif
IN_PROC_BROWSER_TEST_P(WebViewTest, MAYBE_LoadWebviewInsideIframe) {
  TestHelper("testLoadWebviewInsideIframe",
             "web_view/load_webview_inside_iframe", NEEDS_TEST_SERVER);

  // WebContents is leaked when using BrowserPlugin.
  if (!base::FeatureList::IsEnabled(::features::kGuestViewCrossProcessFrames))
    return;

  content::WebContentsDestroyedWatcher watcher(
      GetGuestViewManager()->GetLastGuestCreated());

  // Remove the iframe.
  EXPECT_TRUE(content::ExecuteScript(
      GetEmbedderWebContents(), "document.querySelector('iframe').remove()"));

  // Wait for guest to be destroyed.
  watcher.Wait();
}

// Makes sure that a webview will display correctly after reloading it after a
// crash.
IN_PROC_BROWSER_TEST_P(WebViewTest, ReloadAfterCrash) {
  if (!base::FeatureList::IsEnabled(::features::kGuestViewCrossProcessFrames))
    return;

  // Load guest and wait for it to appear.
  LoadAppWithGuest("web_view/simple");
  EXPECT_TRUE(GetGuestWebContents()->GetMainFrame()->GetView());
  WaitForChildFrameSurfaceReady(GetGuestWebContents()->GetMainFrame());

  // Kill guest.
  auto* rph = GetGuestWebContents()->GetMainFrame()->GetProcess();
  content::RenderProcessHostWatcher crash_observer(
      rph, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  EXPECT_TRUE(rph->Shutdown(content::RESULT_CODE_KILLED, false));
  crash_observer.Wait();
  EXPECT_FALSE(GetGuestWebContents()->GetMainFrame()->GetView());

  // Reload guest and make sure it appears.
  content::TestNavigationObserver load_observer(GetGuestWebContents());
  EXPECT_TRUE(ExecuteScript(GetEmbedderWebContents(),
                            "document.querySelector('webview').reload()"));
  load_observer.Wait();
  EXPECT_TRUE(GetGuestWebContents()->GetMainFrame()->GetView());

  // When the frame passed has a RenderWidgetHostViewChildFrame,
  // WaitForChildFrameSurfaceReady will only return when the guest is embedded
  // within the root surface.
  WaitForChildFrameSurfaceReady(GetGuestWebContents()->GetMainFrame());
}

IN_PROC_BROWSER_TEST_P(WebViewAccessibilityTest, LoadWebViewAccessibility) {
  LoadAppWithGuest("web_view/focus_accessibility");
  content::WebContents* web_contents = GetFirstAppWindowWebContents();
  content::EnableAccessibilityForWebContents(web_contents);
  content::WebContents* guest_web_contents = GetGuestWebContents();
  content::EnableAccessibilityForWebContents(guest_web_contents);
  content::WaitForAccessibilityTreeToContainNodeWithName(web_contents,
                                                         "Guest button");
}

IN_PROC_BROWSER_TEST_P(WebViewAccessibilityTest, FocusAccessibility) {
  LoadAppWithGuest("web_view/focus_accessibility");
  content::WebContents* web_contents = GetFirstAppWindowWebContents();
  content::EnableAccessibilityForWebContents(web_contents);
  content::WebContents* guest_web_contents = GetGuestWebContents();
  content::EnableAccessibilityForWebContents(guest_web_contents);

  // Wait for focus to land on the "root web area" role, representing
  // focus on the main document itself.
  while (content::GetFocusedAccessibilityNodeInfo(web_contents).role !=
             ui::AX_ROLE_ROOT_WEB_AREA) {
    content::WaitForAccessibilityFocusChange();
  }

  // Now keep pressing the Tab key until focus lands on a button.
  while (content::GetFocusedAccessibilityNodeInfo(web_contents).role !=
             ui::AX_ROLE_BUTTON) {
    content::SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('\t'),
                              ui::DomCode::TAB, ui::VKEY_TAB, false, false,
                              false, false);
    content::WaitForAccessibilityFocusChange();
  }

  // Ensure that we hit the button inside the guest frame labeled
  // "Guest button".
  ui::AXNodeData node_data =
      content::GetFocusedAccessibilityNodeInfo(web_contents);
  EXPECT_EQ("Guest button", node_data.GetStringAttribute(ui::AX_ATTR_NAME));
}

class WebContentsAccessibilityEventWatcher
    : public content::WebContentsObserver {
 public:
  WebContentsAccessibilityEventWatcher(
      content::WebContents* web_contents,
      ui::AXEvent event)
      : content::WebContentsObserver(web_contents),
        event_(event),
        count_(0) {}
  ~WebContentsAccessibilityEventWatcher() override {}

  void Wait() {
    if (count_ == 0) {
      loop_runner_ = new content::MessageLoopRunner();
      loop_runner_->Run();
    }
  }

  void AccessibilityEventReceived(
      const std::vector<content::AXEventNotificationDetails>& details_vector)
          override {
    for (auto& details : details_vector) {
      if (details.event_type == event_ && details.update.nodes.size() > 0) {
        count_++;
        node_data_ = details.update.nodes[0];
        loop_runner_->Quit();
      }
    }
  }

  size_t count() const { return count_; }

  const ui::AXNodeData& node_data() const { return node_data_; }

 private:
  scoped_refptr<content::MessageLoopRunner> loop_runner_;
  ui::AXEvent event_;
  ui::AXNodeData node_data_;
  size_t count_;
};

IN_PROC_BROWSER_TEST_P(WebViewAccessibilityTest, DISABLED_TouchAccessibility) {
  LoadAppWithGuest("web_view/touch_accessibility");
  content::WebContents* web_contents = GetFirstAppWindowWebContents();
  content::EnableAccessibilityForWebContents(web_contents);
  content::WebContents* guest_web_contents = GetGuestWebContents();
  content::EnableAccessibilityForWebContents(guest_web_contents);

  // Listen for accessibility events on both WebContents.
  WebContentsAccessibilityEventWatcher main_event_watcher(
      web_contents, ui::AX_EVENT_HOVER);
  WebContentsAccessibilityEventWatcher guest_event_watcher(
      guest_web_contents, ui::AX_EVENT_HOVER);

  // Send an accessibility touch event to the main WebContents, but
  // positioned on top of the button inside the inner WebView.
  blink::WebMouseEvent accessibility_touch_event(
      blink::WebInputEvent::kMouseMove,
      blink::WebInputEvent::kIsTouchAccessibility,
      blink::WebInputEvent::kTimeStampForTesting);
  accessibility_touch_event.SetPositionInWidget(95, 55);
  web_contents->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
      accessibility_touch_event);

  // Ensure that we got just a single hover event on the guest WebContents,
  // and that it was fired on a button.
  guest_event_watcher.Wait();
  ui::AXNodeData hit_node = guest_event_watcher.node_data();
  EXPECT_EQ(1U, guest_event_watcher.count());
  EXPECT_EQ(ui::AX_ROLE_BUTTON, hit_node.role);
  EXPECT_EQ(0U, main_event_watcher.count());
}

class WebViewGuestScrollTest
    : public WebViewTestBase,
      public testing::WithParamInterface<testing::tuple<bool, bool>> {
 protected:
  WebViewGuestScrollTest() {}
  ~WebViewGuestScrollTest() {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    WebViewTestBase::SetUpCommandLine(command_line);

    bool use_cross_process_frames_for_guests = testing::get<0>(GetParam());
    if (use_cross_process_frames_for_guests) {
      scoped_feature_list_.InitAndEnableFeature(
          features::kGuestViewCrossProcessFrames);
    } else {
      scoped_feature_list_.InitAndDisableFeature(
          features::kGuestViewCrossProcessFrames);
    }
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;

  DISALLOW_COPY_AND_ASSIGN(WebViewGuestScrollTest);
};

class WebViewGuestScrollTouchTest : public WebViewGuestScrollTest {
 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    WebViewGuestScrollTest::SetUpCommandLine(command_line);

    command_line->AppendSwitchASCII(
        switches::kTouchEventFeatureDetection,
        switches::kTouchEventFeatureDetectionEnabled);
  }
};

namespace {

class ScrollWaiter {
 public:
  explicit ScrollWaiter(content::RenderWidgetHostView* host_view)
      : host_view_(host_view) {}
  ~ScrollWaiter() {}

  void WaitForScrollChange(gfx::Vector2dF target_offset) {
    while (target_offset != host_view_->GetLastScrollOffset())
      base::RunLoop().RunUntilIdle();
  }

 private:
  content::RenderWidgetHostView* host_view_;
};

}  // namespace

// Tests that scrolls bubble from guest to embedder.
// Create two test instances, one where the guest body is scrollable and the
// other where the body is not scrollable: fast-path scrolling will generate
// different ack results in between these two cases.
INSTANTIATE_TEST_CASE_P(WebViewScrollBubbling,
                        WebViewGuestScrollTest,
                        testing::Combine(testing::Bool(), testing::Bool()));

// Flaky on all platforms, see http://crbug.com/544782.
IN_PROC_BROWSER_TEST_P(WebViewGuestScrollTest,
                       DISABLED_TestGuestWheelScrollsBubble) {
  LoadAppWithGuest("web_view/scrollable_embedder_and_guest");

  if (testing::get<1>(GetParam()))
    SendMessageToGuestAndWait("set_overflow_hidden", "overflow_is_hidden");

  content::WebContents* embedder_contents = GetEmbedderWebContents();

  std::vector<content::WebContents*> guest_web_contents_list;
  GetGuestViewManager()->WaitForNumGuestsCreated(1u);
  GetGuestViewManager()->GetGuestWebContentsList(&guest_web_contents_list);
  ASSERT_EQ(1u, guest_web_contents_list.size());

  content::WebContents* guest_contents = guest_web_contents_list[0];

  gfx::Rect embedder_rect = embedder_contents->GetContainerBounds();
  gfx::Rect guest_rect = guest_contents->GetContainerBounds();

  guest_rect.set_x(guest_rect.x() - embedder_rect.x());
  guest_rect.set_y(guest_rect.y() - embedder_rect.y());
  embedder_rect.set_x(0);
  embedder_rect.set_y(0);

  // Send scroll gesture to embedder & verify.
  content::RenderWidgetHostView* embedder_host_view =
      embedder_contents->GetRenderWidgetHostView();
  EXPECT_EQ(gfx::Vector2dF(), embedder_host_view->GetLastScrollOffset());

  // Make sure wheel events don't get filtered.
  float scroll_magnitude = 15.f;

  {
    // Scroll the embedder from a position in the embedder that is not over
    // the guest.
    gfx::Point embedder_scroll_location(
        embedder_rect.x() + embedder_rect.width() / 2,
        (embedder_rect.y() + guest_rect.y()) / 2);

    gfx::Vector2dF expected_offset(0.f, scroll_magnitude);

    ScrollWaiter waiter(embedder_host_view);

    content::SimulateMouseEvent(embedder_contents,
                                blink::WebInputEvent::kMouseMove,
                                embedder_scroll_location);
    content::SimulateMouseWheelEvent(embedder_contents,
                                     embedder_scroll_location,
                                     gfx::Vector2d(0, -scroll_magnitude),
                                     blink::WebMouseWheelEvent::kPhaseBegan);
    waiter.WaitForScrollChange(expected_offset);
  }

  content::RenderWidgetHostView* guest_host_view =
      guest_contents->GetRenderWidgetHostView();
  EXPECT_EQ(gfx::Vector2dF(), guest_host_view->GetLastScrollOffset());

  // Send scroll gesture to guest and verify embedder scrolls.
  // Perform a scroll gesture of the same magnitude, but in the opposite
  // direction and centered over the GuestView this time.
  guest_rect = guest_contents->GetContainerBounds();
  embedder_rect = embedder_contents->GetContainerBounds();
  guest_rect.set_x(guest_rect.x() - embedder_rect.x());
  guest_rect.set_y(guest_rect.y() - embedder_rect.y());
  {
    gfx::Point guest_scroll_location(guest_rect.x() + guest_rect.width() / 2,
                                     guest_rect.y());
    ScrollWaiter waiter(embedder_host_view);

    content::SimulateMouseEvent(embedder_contents,
                                blink::WebInputEvent::kMouseMove,
                                guest_scroll_location);
    content::SimulateMouseWheelEvent(embedder_contents, guest_scroll_location,
                                     gfx::Vector2d(0, scroll_magnitude),
                                     blink::WebMouseWheelEvent::kPhaseChanged);

    waiter.WaitForScrollChange(gfx::Vector2dF());
  }
}

// Tests scroll latching behaviour with WebViews.
// Only applicable with OOPIF-based guests when scroll latching is enabled.
// We can move these tests to a more general fixture once the features
// have landed (crbug.com/533069 and crbug.com/526463).
class WebViewGuestScrollLatchingTest : public WebViewTestBase {
 protected:
  WebViewGuestScrollLatchingTest() {}
  ~WebViewGuestScrollLatchingTest() override {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    WebViewTestBase::SetUpCommandLine(command_line);
    feature_list_.InitWithFeatures(
        {features::kTouchpadAndWheelScrollLatching, features::kAsyncWheelEvents,
         features::kGuestViewCrossProcessFrames},
        {});
  }

 private:
  base::test::ScopedFeatureList feature_list_;

  DISALLOW_COPY_AND_ASSIGN(WebViewGuestScrollLatchingTest);
};

// Test that when we bubble scroll from a guest, the guest does not also
// consume the scroll.
IN_PROC_BROWSER_TEST_F(WebViewGuestScrollLatchingTest,
                       ScrollLatchingPreservedInGuests) {
  LoadAppWithGuest("web_view/scrollable_embedder_and_guest");

  content::WebContents* embedder_contents = GetEmbedderWebContents();

  std::vector<content::WebContents*> guest_web_contents_list;
  GetGuestViewManager()->WaitForNumGuestsCreated(1u);
  GetGuestViewManager()->GetGuestWebContentsList(&guest_web_contents_list);
  ASSERT_EQ(1u, guest_web_contents_list.size());

  content::WebContents* guest_contents = guest_web_contents_list[0];
  content::RenderWidgetHostView* guest_host_view =
      guest_contents->GetRenderWidgetHostView();

  content::RenderWidgetHostView* embedder_host_view =
      embedder_contents->GetRenderWidgetHostView();
  ASSERT_EQ(gfx::Vector2dF(), guest_host_view->GetLastScrollOffset());
  ASSERT_EQ(gfx::Vector2dF(), embedder_host_view->GetLastScrollOffset());

  gfx::Point guest_scroll_location(1, 1);
  gfx::Point guest_scroll_location_in_root =
      guest_host_view->TransformPointToRootCoordSpace(guest_scroll_location);

  // When the guest is already scrolled to the top, scroll up so that we bubble
  // scroll.
  blink::WebGestureEvent scroll_begin(
      blink::WebGestureEvent::kGestureScrollBegin,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::kTimeStampForTesting);
  scroll_begin.source_device = blink::kWebGestureDeviceTouchpad;
  scroll_begin.x = guest_scroll_location.x();
  scroll_begin.y = guest_scroll_location.y();
  scroll_begin.global_x = guest_scroll_location_in_root.x();
  scroll_begin.global_y = guest_scroll_location_in_root.y();
  scroll_begin.data.scroll_begin.delta_x_hint = 0;
  scroll_begin.data.scroll_begin.delta_y_hint = 5;
  content::SimulateGestureEvent(guest_contents, scroll_begin,
                                ui::LatencyInfo(ui::SourceEventType::WHEEL));

  content::InputEventAckWaiter update_waiter(
      guest_contents->GetRenderViewHost()->GetWidget(),
      base::BindRepeating([](content::InputEventAckSource,
                             content::InputEventAckState state,
                             const blink::WebInputEvent& event) {
        return event.GetType() ==
                   blink::WebGestureEvent::kGestureScrollUpdate &&
               state != content::INPUT_EVENT_ACK_STATE_CONSUMED;
      }));

  blink::WebGestureEvent scroll_update(
      blink::WebGestureEvent::kGestureScrollUpdate,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::kTimeStampForTesting);
  scroll_update.source_device = scroll_begin.source_device;
  scroll_update.x = scroll_begin.x;
  scroll_update.y = scroll_begin.y;
  scroll_update.global_x = scroll_begin.global_x;
  scroll_update.global_y = scroll_begin.global_y;
  scroll_update.data.scroll_update.delta_x =
      scroll_begin.data.scroll_begin.delta_x_hint;
  scroll_update.data.scroll_update.delta_y =
      scroll_begin.data.scroll_begin.delta_y_hint;
  content::SimulateGestureEvent(guest_contents, scroll_update,
                                ui::LatencyInfo(ui::SourceEventType::WHEEL));
  update_waiter.Wait();
  update_waiter.Reset();

  ASSERT_EQ(gfx::Vector2dF(), guest_host_view->GetLastScrollOffset());

  // Now we switch directions and scroll down. The guest can scroll in this
  // direction, but since we're bubbling, the guest should not consume this.
  scroll_update.data.scroll_update.delta_y = -5;
  content::SimulateGestureEvent(guest_contents, scroll_update,
                                ui::LatencyInfo(ui::SourceEventType::WHEEL));
  update_waiter.Wait();

  EXPECT_EQ(gfx::Vector2dF(), guest_host_view->GetLastScrollOffset());
}

INSTANTIATE_TEST_CASE_P(WebViewScrollBubbling,
                        WebViewGuestScrollTouchTest,
                        testing::Combine(testing::Bool(), testing::Bool()));

#if defined(USE_AURA)
class WebViewGuestTouchFocusTest : public WebViewTestBase {
 public:
  WebViewGuestTouchFocusTest() {}
  void SetUpCommandLine(base::CommandLine* command_line) override {
    WebViewTestBase::SetUpCommandLine(command_line);

    command_line->AppendSwitchASCII(
        switches::kTouchEventFeatureDetection,
        switches::kTouchEventFeatureDetectionEnabled);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(WebViewGuestTouchFocusTest);
};

class FocusChangeWaiter {
 public:
  explicit FocusChangeWaiter(content::WebContents* web_contents,
                             bool expected_focus)
      : web_contents_(web_contents), expected_focus_(expected_focus) {}
  ~FocusChangeWaiter() {}

  void WaitForFocusChange() {
    while (expected_focus_ !=
           IsWebContentsBrowserPluginFocused(web_contents_)) {
      base::RunLoop().RunUntilIdle();
    }
  }

 private:
  content::WebContents* web_contents_;
  bool expected_focus_;
};

IN_PROC_BROWSER_TEST_F(WebViewGuestTouchFocusTest,
                       TouchFocusesBrowserPluginInEmbedder) {
  // This test is only relevant for non-OOPIF WebView.
  if (base::FeatureList::IsEnabled(::features::kGuestViewCrossProcessFrames))
    return;

  LoadAppWithGuest("web_view/guest_focus_test");

  // Lookup relevant information about guest and embedder.
  content::WebContents* embedder_contents = GetEmbedderWebContents();

  std::vector<content::WebContents*> guest_web_contents_list;
  GetGuestViewManager()->WaitForNumGuestsCreated(1u);
  GetGuestViewManager()->GetGuestWebContentsList(&guest_web_contents_list);
  ASSERT_EQ(1u, guest_web_contents_list.size());

  content::WebContents* guest_contents = guest_web_contents_list[0];

  gfx::Rect embedder_rect = embedder_contents->GetContainerBounds();
  gfx::Rect guest_rect = guest_contents->GetContainerBounds();

  guest_rect.set_x(guest_rect.x() - embedder_rect.x());
  guest_rect.set_y(guest_rect.y() - embedder_rect.y());
  embedder_rect.set_x(0);
  embedder_rect.set_y(0);

  // Don't send events that need to be routed until we know the child's surface
  // is ready for hit testing.
  WaitForGuestSurfaceReady(guest_contents);

  // 1) BrowserPlugin should not be focused at start.
  EXPECT_FALSE(IsWebContentsBrowserPluginFocused(guest_contents));

  // 2) Send touch event to guest, now BrowserPlugin should get focus.
  {
    gfx::Point point = guest_rect.CenterPoint();
    FocusChangeWaiter focus_waiter(guest_contents, true);
    SendRoutedTouchTapSequence(embedder_contents, point);
    SendRoutedGestureTapSequence(embedder_contents, point);
    focus_waiter.WaitForFocusChange();
    EXPECT_TRUE(IsWebContentsBrowserPluginFocused(guest_contents));
  }

  // 3) Send touch start to embedder, now BrowserPlugin should lose focus.
  {
    gfx::Point point(10, 10);
    FocusChangeWaiter focus_waiter(guest_contents, false);
    SendRoutedTouchTapSequence(embedder_contents, point);
    SendRoutedGestureTapSequence(embedder_contents, point);
    focus_waiter.WaitForFocusChange();
    EXPECT_FALSE(IsWebContentsBrowserPluginFocused(guest_contents));
  }
}
#endif

IN_PROC_BROWSER_TEST_P(WebViewGuestScrollTouchTest,
                       TestGuestGestureScrollsBubble) {
  // Just in case we're running ChromeOS tests, we need to make sure the
  // debounce interval is set to zero so our back-to-back gesture-scrolls don't
  // get munged together. Since the first scroll will be put on the fast
  // (compositor) path, while the second one should always be slow-path so it
  // gets to BrowserPlugin, having them merged is definitely an error.
  ui::GestureConfiguration* gesture_config =
      ui::GestureConfiguration::GetInstance();
  gesture_config->set_scroll_debounce_interval_in_ms(0);

  LoadAppWithGuest("web_view/scrollable_embedder_and_guest");

  if (testing::get<1>(GetParam()))
    SendMessageToGuestAndWait("set_overflow_hidden", "overflow_is_hidden");

  content::WebContents* embedder_contents = GetEmbedderWebContents();

  std::vector<content::WebContents*> guest_web_contents_list;
  GetGuestViewManager()->WaitForNumGuestsCreated(1u);
  GetGuestViewManager()->GetGuestWebContentsList(&guest_web_contents_list);
  ASSERT_EQ(1u, guest_web_contents_list.size());

  content::WebContents* guest_contents = guest_web_contents_list[0];

  gfx::Rect embedder_rect = embedder_contents->GetContainerBounds();
  gfx::Rect guest_rect = guest_contents->GetContainerBounds();

  guest_rect.set_x(guest_rect.x() - embedder_rect.x());
  guest_rect.set_y(guest_rect.y() - embedder_rect.y());
  embedder_rect.set_x(0);
  embedder_rect.set_y(0);

  // Send scroll gesture to embedder & verify.
  content::RenderWidgetHostView* embedder_host_view =
      embedder_contents->GetRenderWidgetHostView();
  EXPECT_EQ(gfx::Vector2dF(), embedder_host_view->GetLastScrollOffset());

  float gesture_distance = 15.f;
  {
    // Scroll the embedder from a position in the embedder that is not over
    // the guest.
    gfx::Point embedder_scroll_location(
        embedder_rect.x() + embedder_rect.width() / 2,
        (embedder_rect.y() + guest_rect.y()) / 2);

    gfx::Vector2dF expected_offset(0.f, gesture_distance);

    content::SimulateGestureScrollSequence(
        embedder_contents, embedder_scroll_location,
        gfx::Vector2dF(0, -gesture_distance));

    ScrollWaiter waiter(embedder_host_view);

    waiter.WaitForScrollChange(expected_offset);
  }

  content::RenderWidgetHostView* guest_host_view =
      guest_contents->GetRenderWidgetHostView();
  EXPECT_EQ(gfx::Vector2dF(), guest_host_view->GetLastScrollOffset());

  // Send scroll gesture to guest and verify embedder scrolls.
  // Perform a scroll gesture of the same magnitude, but in the opposite
  // direction and centered over the GuestView this time.
  guest_rect = guest_contents->GetContainerBounds();
  {
    gfx::Point guest_scroll_location(guest_rect.width() / 2,
                                     guest_rect.height() / 2);

    ScrollWaiter waiter(embedder_host_view);

    content::SimulateGestureScrollSequence(guest_contents,
                                           guest_scroll_location,
                                           gfx::Vector2dF(0, gesture_distance));

    waiter.WaitForScrollChange(gfx::Vector2dF());
  }
}

class WebViewScrollGuestContentTest : public WebViewTest {
 public:
  ~WebViewScrollGuestContentTest() override {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    WebViewTest::SetUpCommandLine(command_line);

    command_line->AppendSwitchASCII(
        switches::kTouchEventFeatureDetection,
        switches::kTouchEventFeatureDetectionEnabled);
  }
};

INSTANTIATE_TEST_CASE_P(WebViewScrollGuestContent,
                        WebViewScrollGuestContentTest,
                        testing::Values(false));

#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX)
#define MAYBE_ScrollGuestContent DISABLED_ScrollGuestContent
#else
#define MAYBE_ScrollGuestContent ScrollGuestContent
#endif
IN_PROC_BROWSER_TEST_P(WebViewScrollGuestContentTest,
                       MAYBE_ScrollGuestContent) {
  LoadAppWithGuest("web_view/scrollable_embedder_and_guest");

  content::WebContents* embedder_contents = GetEmbedderWebContents();

  std::vector<content::WebContents*> guest_web_contents_list;
  GetGuestViewManager()->WaitForNumGuestsCreated(1u);
  GetGuestViewManager()->GetGuestWebContentsList(&guest_web_contents_list);
  ASSERT_EQ(1u, guest_web_contents_list.size());

  content::WebContents* guest_contents = guest_web_contents_list[0];
  content::RenderWidgetHostView* guest_host_view =
      guest_contents->GetRenderWidgetHostView();

  gfx::Rect embedder_rect = embedder_contents->GetContainerBounds();
  gfx::Rect guest_rect = guest_contents->GetContainerBounds();
  guest_rect.set_x(guest_rect.x() - embedder_rect.x());
  guest_rect.set_y(guest_rect.y() - embedder_rect.y());

  content::RenderWidgetHostView* embedder_host_view =
      embedder_contents->GetRenderWidgetHostView();
  EXPECT_EQ(gfx::Vector2dF(), guest_host_view->GetLastScrollOffset());
  EXPECT_EQ(gfx::Vector2dF(), embedder_host_view->GetLastScrollOffset());

  gfx::Point guest_scroll_location(guest_rect.width() / 2, 0);

  float gesture_distance = 15.f;
  {
    gfx::Vector2dF expected_offset(0.f, gesture_distance);

    ScrollWaiter waiter(guest_host_view);

    content::SimulateGestureScrollSequence(
        guest_contents, guest_scroll_location,
        gfx::Vector2dF(0, -gesture_distance));

    waiter.WaitForScrollChange(expected_offset);
  }
  EXPECT_EQ(gfx::Vector2dF(), embedder_host_view->GetLastScrollOffset());

  // Use fling gesture to scroll back, velocity should be big enough to scroll
  // content back.
  float fling_velocity = 300.f;
  {
    ScrollWaiter waiter(guest_host_view);

    content::SimulateGestureFlingSequence(
        guest_contents, guest_scroll_location,
        gfx::Vector2dF(0, fling_velocity));

    waiter.WaitForScrollChange(gfx::Vector2dF());
  }

  EXPECT_EQ(gfx::Vector2dF(), embedder_host_view->GetLastScrollOffset());
}

#if defined(USE_AURA)
// This verifies the fix for crbug.com/694393 .
IN_PROC_BROWSER_TEST_P(WebViewScrollGuestContentTest,
                       OverscrollControllerSeesConsumedScrollsInGuest) {
  // This test is only relevant for non-OOPIF WebView as OOPIF-based WebView
  // uses different scroll bubbling logic.
  DCHECK(
      !base::FeatureList::IsEnabled(::features::kGuestViewCrossProcessFrames));

  LoadAppWithGuest("web_view/scrollable_embedder_and_guest");

  content::WebContents* embedder_contents = GetEmbedderWebContents();

  std::vector<content::WebContents*> guest_web_contents_list;
  GetGuestViewManager()->WaitForNumGuestsCreated(1u);
  GetGuestViewManager()->GetGuestWebContentsList(&guest_web_contents_list);
  ASSERT_EQ(1u, guest_web_contents_list.size());

  content::WebContents* guest_contents = guest_web_contents_list[0];
  content::RenderWidgetHostView* guest_host_view =
      guest_contents->GetRenderWidgetHostView();

  gfx::Rect embedder_rect = embedder_contents->GetContainerBounds();
  gfx::Rect guest_rect = guest_contents->GetContainerBounds();
  guest_rect.set_x(guest_rect.x() - embedder_rect.x());
  guest_rect.set_y(guest_rect.y() - embedder_rect.y());

  content::RenderWidgetHostView* embedder_host_view =
      embedder_contents->GetRenderWidgetHostView();
  EXPECT_EQ(gfx::Vector2dF(), guest_host_view->GetLastScrollOffset());
  EXPECT_EQ(gfx::Vector2dF(), embedder_host_view->GetLastScrollOffset());

  // If we scroll the guest, the OverscrollController for the
  // RenderWidgetHostViewAura should see that the scroll was consumed.
  // If it doesn't, this test will time out indicating failure.
  content::MockOverscrollController* mock_overscroll_controller =
      content::MockOverscrollController::Create(embedder_host_view);

  gfx::Point guest_scroll_location(guest_rect.width() / 2, 0);
  float gesture_distance = 15.f;
  // It's sufficient to scroll vertically, since all we need to test is that
  // the OverscrollController sees consumed scrolls.
  content::SimulateGestureScrollSequence(guest_contents, guest_scroll_location,
                                         gfx::Vector2dF(0, -gesture_distance));

  mock_overscroll_controller->WaitForConsumedScroll();
}
#endif

#if defined(USE_AURA)
// TODO(wjmaclean): when WebViewTest is re-enabled on the site-isolation
// bots, then re-enable this test class as well.
// https://crbug.com/503751
class WebViewFocusTest : public WebViewTest {
 public:
  ~WebViewFocusTest() override {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    WebViewTest::SetUpCommandLine(command_line);

    command_line->AppendSwitchASCII(
        switches::kTouchEventFeatureDetection,
        switches::kTouchEventFeatureDetectionEnabled);
  }

  void ForceCompositorFrame() {
    frame_watcher_.Observe(GetEmbedderWebContents());

    while (!RequestFrame(GetEmbedderWebContents())) {
      // RequestFrame failed because we were waiting on an ack ... wait a short
      // time and retry.
      base::RunLoop run_loop;
      base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
          FROM_HERE, run_loop.QuitClosure(),
          base::TimeDelta::FromMilliseconds(10));
      run_loop.Run();
    }
    frame_watcher_.WaitFrames(1);
  }

 private:
  content::FrameWatcher frame_watcher_;
};
INSTANTIATE_TEST_CASE_P(WebViewTests, WebViewFocusTest, testing::Values(false));

// The following test verifies that a views::WebView hosting an embedder
// gains focus on touchstart.
IN_PROC_BROWSER_TEST_P(WebViewFocusTest, TouchFocusesEmbedder) {
  LoadAppWithGuest("web_view/accept_touch_events");

  content::WebContents* web_contents = GetEmbedderWebContents();
  content::RenderViewHost* embedder_rvh = web_contents->GetRenderViewHost();

  bool embedder_has_touch_handler =
      content::RenderViewHostTester::HasTouchEventHandler(embedder_rvh);
  EXPECT_FALSE(embedder_has_touch_handler);

  SendMessageToGuestAndWait("install-touch-handler", "installed-touch-handler");

  // Note that we need to wait for the installed/registered touch handler to
  // appear in browser process before querying |embedder_rvh|.
  // In practice, since we do a roundrtip from browser process to guest and
  // back, this is sufficient.
  embedder_has_touch_handler =
      content::RenderViewHostTester::HasTouchEventHandler(embedder_rvh);
  EXPECT_TRUE(embedder_has_touch_handler);

  extensions::AppWindow* app_window = GetFirstAppWindowForBrowser(browser());
  aura::Window* window = app_window->GetNativeWindow();
  EXPECT_TRUE(app_window);
  EXPECT_TRUE(window);
  views::Widget* widget = views::Widget::GetWidgetForNativeView(window);
  EXPECT_TRUE(widget->GetRootView());
  // We only expect a single views::webview in the view hierarchy.
  views::View* aura_webview = FindWebView(widget->GetRootView());
  ASSERT_TRUE(aura_webview);
  gfx::Rect bounds(aura_webview->bounds());
  EXPECT_TRUE(aura_webview->IsFocusable());

  views::View* other_focusable_view = new views::View();
  other_focusable_view->SetBounds(bounds.x() + bounds.width(), bounds.y(), 100,
                                  100);
  other_focusable_view->SetFocusBehavior(views::View::FocusBehavior::ALWAYS);
  aura_webview->parent()->AddChildView(other_focusable_view);
  other_focusable_view->SetPosition(gfx::Point(bounds.x() + bounds.width(), 0));

  // Sync changes to compositor.
  ForceCompositorFrame();

  aura_webview->RequestFocus();
  // Verify that other_focusable_view can steal focus from aura_webview.
  EXPECT_TRUE(aura_webview->HasFocus());
  other_focusable_view->RequestFocus();
  EXPECT_TRUE(other_focusable_view->HasFocus());
  EXPECT_FALSE(aura_webview->HasFocus());

  // Compute location of guest within embedder so we can more accurately
  // target our touch event.
  gfx::Rect guest_rect = GetGuestWebContents()->GetContainerBounds();
  gfx::Point embedder_origin =
      GetEmbedderWebContents()->GetContainerBounds().origin();
  guest_rect.Offset(-embedder_origin.x(), -embedder_origin.y());

  // Generate and send synthetic touch event.
  content::SimulateTouchPressAt(GetEmbedderWebContents(),
                                guest_rect.CenterPoint());
  EXPECT_TRUE(aura_webview->HasFocus());
}
#endif

// This runs the chrome://chrome-signin page which includes an OOPIF-<webview>
// of accounts.google.com.
class ChromeSignInWebViewTest : public WebViewTestBase {
 public:
  ChromeSignInWebViewTest() {}
  ~ChromeSignInWebViewTest() override {}

 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    scoped_feature_list_.InitAndEnableFeature(
        features::kGuestViewCrossProcessFrames);
  }

  void WaitForWebViewInDom() {
    auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
    auto* script =
        "var count = 10;"
        "var interval;"
        "interval = setInterval(function(){"
        "  if (document.getElementsByTagName('webview').length) {"
        "    document.title = 'success';"
        "    console.log('FOUND webview');"
        "    clearInterval(interval);"
        "  } else if (count == 0) {"
        "    document.title = 'error';"
        "    clearInterval(interval);"
        "  } else {"
        "    count -= 1;"
        "  }"
        "}, 1000);";
    ExecuteScriptWaitForTitle(web_contents, script, "success");
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

#if (defined(OS_LINUX) && !defined(OS_CHROMEOS)) || defined(OS_MACOSX) || \
     defined(OS_WIN)
// This verifies the fix for http://crbug.com/667708.
IN_PROC_BROWSER_TEST_F(ChromeSignInWebViewTest,
                       ClosingChromeSignInShouldNotCrash) {
  GURL signin_url{"chrome://chrome-signin"};

  AddTabAtIndex(0, signin_url, ui::PAGE_TRANSITION_TYPED);
  AddTabAtIndex(1, signin_url, ui::PAGE_TRANSITION_TYPED);
  WaitForWebViewInDom();

  chrome::CloseTab(browser());
}
#endif

// This test class makes "isolated.com" an isolated origin, to be used in
// testing isolated origins inside of a WebView.
class IsolatedOriginWebViewTest : public WebViewTest {
 public:
  IsolatedOriginWebViewTest() {}
  ~IsolatedOriginWebViewTest() override {}

 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    ASSERT_TRUE(embedded_test_server()->InitializeAndListen());

    std::string origin =
        embedded_test_server()->GetURL("isolated.com", "/").spec();
    command_line->AppendSwitchASCII(switches::kIsolateOrigins, origin);
    WebViewTest::SetUpCommandLine(command_line);
  }

  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    embedded_test_server()->StartAcceptingConnections();
    WebViewTest::SetUpOnMainThread();
  }
};
INSTANTIATE_TEST_CASE_P(WebViewTests,
                        IsolatedOriginWebViewTest,
                        testing::Bool());

// Test isolated origins inside a WebView, and make sure that loading an
// isolated origin in a regular tab's subframe doesn't reuse a WebView process
// that had loaded it previously, which would result in renderer kills. See
// https://crbug.com/751916 and https://crbug.com/751920.
IN_PROC_BROWSER_TEST_P(IsolatedOriginWebViewTest, IsolatedOriginInWebview) {
  LoadAppWithGuest("web_view/simple");
  content::WebContents* guest = GetGuestWebContents();

  // Navigate <webview> to an isolated origin.
  GURL isolated_url(
      embedded_test_server()->GetURL("isolated.com", "/title1.html"));
  {
    content::TestNavigationObserver load_observer(guest);
    EXPECT_TRUE(
        ExecuteScript(guest, "location.href = '" + isolated_url.spec() + "';"));
    load_observer.Wait();
  }

  // TODO(alexmos, creis): The isolated origin currently has to use the
  // chrome-guest:// SiteInstance, rather than a SiteInstance with its own
  // meaningful site URL.  This should be fixed as part of
  // https://crbug.com/734722.
  EXPECT_TRUE(guest->GetMainFrame()->GetSiteInstance()->GetSiteURL().SchemeIs(
      content::kGuestScheme));

  // Now, navigate <webview> to a regular page with a subframe.
  GURL foo_url(embedded_test_server()->GetURL("foo.com", "/iframe.html"));
  {
    content::TestNavigationObserver load_observer(guest);
    EXPECT_TRUE(
        ExecuteScript(guest, "location.href = '" + foo_url.spec() + "';"));
    load_observer.Wait();
  }

  // Navigate subframe in <webview> to an isolated origin.
  EXPECT_TRUE(NavigateIframeToURL(guest, "test", isolated_url));

  // TODO(alexmos, creis): Unfortunately, the subframe currently has to stay in
  // the guest process.  The expectations here should change once WebViews
  // can support OOPIFs.  See https://crbug.com/614463.
  content::RenderFrameHost* webview_subframe =
      ChildFrameAt(guest->GetMainFrame(), 0);
  EXPECT_EQ(webview_subframe->GetProcess(),
            guest->GetMainFrame()->GetProcess());
  EXPECT_EQ(webview_subframe->GetSiteInstance(),
            guest->GetMainFrame()->GetSiteInstance());

  // Load a page with subframe in a regular tab.
  AddTabAtIndex(0, foo_url, ui::PAGE_TRANSITION_TYPED);
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Navigate that subframe to an isolated origin.  This should not join the
  // WebView process, which has isolated.foo.com committed in a different
  // storage partition.
  EXPECT_TRUE(NavigateIframeToURL(tab, "test", isolated_url));
  content::RenderFrameHost* subframe = ChildFrameAt(tab->GetMainFrame(), 0);
  EXPECT_NE(guest->GetMainFrame()->GetProcess(), subframe->GetProcess());

  // Check that the guest process hasn't crashed.
  EXPECT_TRUE(guest->GetMainFrame()->IsRenderFrameLive());

  // Check that accessing a foo.com cookie from the WebView doesn't result in a
  // renderer kill. This might happen if we erroneously applied an isolated.com
  // origin lock to the WebView process when committing isolated.com.
  bool cookie_is_correct = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      guest,
      "document.cookie = 'foo=bar';\n"
      "window.domAutomationController.send(document.cookie == 'foo=bar');\n",
      &cookie_is_correct));
  EXPECT_TRUE(cookie_is_correct);
}

// This test is similar to IsolatedOriginInWebview above, but loads an isolated
// origin in a <webview> subframe *after* loading the same isolated origin in a
// regular tab's subframe.  The isolated origin's subframe in the <webview>
// subframe should not reuse the regular tab's subframe process.  See
// https://crbug.com/751916 and https://crbug.com/751920.
IN_PROC_BROWSER_TEST_P(IsolatedOriginWebViewTest,
                       LoadIsolatedOriginInWebviewAfterLoadingInRegularTab) {
  LoadAppWithGuest("web_view/simple");
  content::WebContents* guest = GetGuestWebContents();

  // Load a page with subframe in a regular tab.
  GURL foo_url(embedded_test_server()->GetURL("foo.com", "/iframe.html"));
  AddTabAtIndex(0, foo_url, ui::PAGE_TRANSITION_TYPED);
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Navigate that subframe to an isolated origin.
  GURL isolated_url(
      embedded_test_server()->GetURL("isolated.com", "/title1.html"));
  EXPECT_TRUE(NavigateIframeToURL(tab, "test", isolated_url));
  content::RenderFrameHost* subframe = ChildFrameAt(tab->GetMainFrame(), 0);
  EXPECT_NE(tab->GetMainFrame()->GetProcess(), subframe->GetProcess());

  // Navigate <webview> to a regular page with an isolated origin subframe.
  {
    content::TestNavigationObserver load_observer(guest);
    EXPECT_TRUE(
        ExecuteScript(guest, "location.href = '" + foo_url.spec() + "';"));
    load_observer.Wait();
  }
  EXPECT_TRUE(NavigateIframeToURL(guest, "test", isolated_url));

  // TODO(alexmos, creis): The subframe currently has to stay in the guest
  // process.  The expectations here should change once WebViews can support
  // OOPIFs.  See https://crbug.com/614463.
  content::RenderFrameHost* webview_subframe =
      ChildFrameAt(guest->GetMainFrame(), 0);
  EXPECT_EQ(webview_subframe->GetProcess(),
            guest->GetMainFrame()->GetProcess());
  EXPECT_EQ(webview_subframe->GetSiteInstance(),
            guest->GetMainFrame()->GetSiteInstance());
  EXPECT_NE(webview_subframe->GetProcess(), subframe->GetProcess());

  // Check that the guest and regular tab processes haven't crashed.
  EXPECT_TRUE(guest->GetMainFrame()->IsRenderFrameLive());
  EXPECT_TRUE(tab->GetMainFrame()->IsRenderFrameLive());
  EXPECT_TRUE(subframe->IsRenderFrameLive());

  // Check that accessing a foo.com cookie from the WebView doesn't result in a
  // renderer kill. This might happen if we erroneously applied an isolated.com
  // origin lock to the WebView process when committing isolated.com.
  bool cookie_is_correct = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      guest,
      "document.cookie = 'foo=bar';\n"
      "window.domAutomationController.send(document.cookie == 'foo=bar');\n",
      &cookie_is_correct));
  EXPECT_TRUE(cookie_is_correct);
}
