web_contents_impl_browsertest.cc revision 116680a4aac90f2aa7413d9095a592090648e557
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/strings/utf_string_conversions.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/values.h"
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/frame_host/navigation_entry_impl.h"
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/browser/web_contents/web_contents_impl.h"
9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/browser/web_contents/web_contents_view.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/load_notification_details.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/navigation_controller.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/notification_details.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/notification_observer.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/notification_types.h"
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/render_view_host.h"
16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "content/public/browser/render_widget_host_view.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/web_contents_observer.h"
1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/common/content_paths.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/test/browser_test_utils.h"
20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/test/content_browser_test.h"
21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/test/content_browser_test_utils.h"
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/test/test_utils.h"
233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/shell/browser/shell.h"
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/dns/mock_host_resolver.h"
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/test/embedded_test_server/embedded_test_server.h"
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace content {
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ResizeWebContentsView(Shell* shell, const gfx::Size& size,
30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                           bool set_start_page) {
31424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Shell::SizeTo is not implemented on Aura; WebContentsView::SizeContents
32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // works on Win and ChromeOS but not Linux - we need to resize the shell
33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // window on Linux because if we don't, the next layout of the unchanged shell
34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // window will resize WebContentsView back to the previous size.
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // SizeContents is a hack and should not be relied on.
36a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_MACOSX)
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  shell->SizeTo(size);
38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // If |set_start_page| is true, start with blank page to make sure resize
39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // takes effect.
40424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (set_start_page)
41424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    NavigateToURL(shell, GURL("about://blank"));
42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#else
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  static_cast<WebContentsImpl*>(shell->web_contents())->GetView()->
44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      SizeContents(size);
45a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#endif  // defined(OS_MACOSX)
46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class WebContentsImplBrowserTest : public ContentBrowserTest {
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  WebContentsImplBrowserTest() {}
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WebContentsImplBrowserTest);
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Keeps track of data from LoadNotificationDetails so we can later verify that
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// they are correct, after the LoadNotificationDetails object is deleted.
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class LoadStopNotificationObserver : public WindowedNotificationObserver {
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LoadStopNotificationObserver(NavigationController* controller)
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : WindowedNotificationObserver(NOTIFICATION_LOAD_STOP,
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     Source<NavigationController>(controller)),
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        session_index_(-1),
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        controller_(NULL) {
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void Observe(int type,
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       const NotificationSource& source,
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       const NotificationDetails& details) OVERRIDE {
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (type == NOTIFICATION_LOAD_STOP) {
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const Details<LoadNotificationDetails> load_details(details);
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      url_ = load_details->url;
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_index_ = load_details->session_index;
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      controller_ = load_details->controller;
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    WindowedNotificationObserver::Observe(type, source, details);
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GURL url_;
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int session_index_;
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigationController* controller_;
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Starts a new navigation as soon as the current one commits, but does not
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// wait for it to complete.  This allows us to observe DidStopLoading while
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// a pending entry is present.
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class NavigateOnCommitObserver : public WebContentsObserver {
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigateOnCommitObserver(Shell* shell, GURL url)
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : WebContentsObserver(shell->web_contents()),
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        shell_(shell),
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        url_(url),
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        done_(false) {
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // WebContentsObserver:
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void NavigationEntryCommitted(
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const LoadCommittedDetails& load_details) OVERRIDE {
98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!done_) {
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      done_ = true;
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      shell_->Stop();
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      shell_->LoadURL(url_);
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Shell* shell_;
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GURL url_;
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool done_;
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
110424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)class RenderViewSizeDelegate : public WebContentsDelegate {
111424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) public:
112424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void set_size_insets(const gfx::Size& size_insets) {
113424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    size_insets_ = size_insets;
114424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
115424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
116424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // WebContentsDelegate:
117424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual gfx::Size GetSizeForNewRenderView(
118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      WebContents* web_contents) const OVERRIDE {
119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    gfx::Size size(web_contents->GetContainerBounds().size());
120424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    size.Enlarge(size_insets_.width(), size_insets_.height());
121424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return size;
122424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
123424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
124424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private:
125424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::Size size_insets_;
126424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
127424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)class RenderViewSizeObserver : public WebContentsObserver {
129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) public:
130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RenderViewSizeObserver(Shell* shell, const gfx::Size& wcv_new_size)
131424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      : WebContentsObserver(shell->web_contents()),
132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        shell_(shell),
133424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        wcv_new_size_(wcv_new_size) {
134424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
135424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
136424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // WebContentsObserver:
137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void RenderViewCreated(RenderViewHost* rvh) OVERRIDE {
138424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    rwhv_create_size_ = rvh->GetView()->GetViewBounds().size();
139424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
140424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void DidStartNavigationToPendingEntry(
142424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      const GURL& url,
143424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      NavigationController::ReloadType reload_type) OVERRIDE {
144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ResizeWebContentsView(shell_, wcv_new_size_, false);
145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
147424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::Size rwhv_create_size() const { return rwhv_create_size_; }
148424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
149424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private:
150424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  Shell* shell_;  // Weak ptr.
151424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::Size wcv_new_size_;
152424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::Size rwhv_create_size_;
153424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)};
154424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass LoadingStateChangedDelegate : public WebContentsDelegate {
156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch public:
157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  LoadingStateChangedDelegate()
158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      : loadingStateChangedCount_(0)
159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      , loadingStateToDifferentDocumentCount_(0) {
160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // WebContentsDelegate:
163effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void LoadingStateChanged(WebContents* contents,
164effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                   bool to_different_document) OVERRIDE {
165effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      loadingStateChangedCount_++;
166effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      if (to_different_document)
167effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        loadingStateToDifferentDocumentCount_++;
168effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int loadingStateChangedCount() const { return loadingStateChangedCount_; }
171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int loadingStateToDifferentDocumentCount() const {
172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return loadingStateToDifferentDocumentCount_;
173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
174effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
175effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch private:
176effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int loadingStateChangedCount_;
177effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int loadingStateToDifferentDocumentCount_;
178effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch};
179effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// See: http://crbug.com/298193
18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_WIN)
18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#define MAYBE_DidStopLoadingDetails DISABLED_DidStopLoadingDetails
18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#else
18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#define MAYBE_DidStopLoadingDetails DidStopLoadingDetails
18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test that DidStopLoading includes the correct URL in the details.
18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                       MAYBE_DidStopLoadingDetails) {
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LoadStopNotificationObserver load_observer(
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &shell()->web_contents()->GetController());
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  load_observer.Wait();
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ("/title1.html", load_observer.url_.path());
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, load_observer.session_index_);
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(&shell()->web_contents()->GetController(),
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            load_observer.controller_);
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// See: http://crbug.com/298193
20468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_WIN)
20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#define MAYBE_DidStopLoadingDetailsWithPending \
20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DISABLED_DidStopLoadingDetailsWithPending
20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#else
20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#define MAYBE_DidStopLoadingDetailsWithPending DidStopLoadingDetailsWithPending
20968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test that DidStopLoading includes the correct URL in the details when a
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// pending entry is present.
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                       MAYBE_DidStopLoadingDetailsWithPending) {
21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GURL url("data:text/html,<div>test</div>");
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Listen for the first load to stop.
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LoadStopNotificationObserver load_observer(
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &shell()->web_contents()->GetController());
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Start a new pending navigation as soon as the first load commits.
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We will hear a DidStopLoading from the first load as the new load
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // is started.
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigateOnCommitObserver commit_observer(
22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      shell(), embedded_test_server()->GetURL("/title2.html"));
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NavigateToURL(shell(), url);
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  load_observer.Wait();
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(url, load_observer.url_);
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, load_observer.session_index_);
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(&shell()->web_contents()->GetController(),
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            load_observer.controller_);
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Test that a renderer-initiated navigation to an invalid URL does not leave
23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// around a pending entry that could be used in a URL spoof.  We test this in
23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// a browser test because our unit test framework incorrectly calls
23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// DidStartProvisionalLoadForFrame for in-page navigations.
23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// See http://crbug.com/280512.
23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
24058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       ClearNonVisiblePendingOnFail) {
24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
24258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
24358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));
24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Navigate to an invalid URL and make sure it doesn't leave a pending entry.
24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  LoadStopNotificationObserver load_observer1(
24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      &shell()->web_contents()->GetController());
24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(ExecuteScript(shell()->web_contents(),
24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                            "window.location.href=\"nonexistent:12121\";"));
25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  load_observer1.Wait();
25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_FALSE(shell()->web_contents()->GetController().GetPendingEntry());
25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  LoadStopNotificationObserver load_observer2(
25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      &shell()->web_contents()->GetController());
25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(ExecuteScript(shell()->web_contents(),
25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                            "window.location.href=\"#foo\";"));
25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  load_observer2.Wait();
25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ(embedded_test_server()->GetURL("/title1.html#foo"),
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            shell()->web_contents()->GetVisibleURL());
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Crashes under ThreadSanitizer, http://crbug.com/356758.
263a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_WIN) || defined(OS_ANDROID) \
264effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    || defined(THREAD_SANITIZER)
265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#define MAYBE_GetSizeForNewRenderView DISABLED_GetSizeForNewRenderView
266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#else
267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#define MAYBE_GetSizeForNewRenderView GetSizeForNewRenderView
268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif
269424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Test that RenderViewHost is created and updated at the size specified by
270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// WebContentsDelegate::GetSizeForNewRenderView().
271424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                       MAYBE_GetSizeForNewRenderView) {
273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
274d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Create a new server with a different site.
275d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  net::SpawnedTestServer https_server(
276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
278d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL("content/test/data")));
279d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ASSERT_TRUE(https_server.Start());
280d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
281424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  scoped_ptr<RenderViewSizeDelegate> delegate(new RenderViewSizeDelegate());
282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  shell()->web_contents()->SetDelegate(delegate.get());
283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ASSERT_TRUE(shell()->web_contents()->GetDelegate() == delegate.get());
284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // When no size is set, RenderWidgetHostView adopts the size of
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // WebContentsView.
287d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  NavigateToURL(shell(), embedded_test_server()->GetURL("/title2.html"));
288010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(shell()->web_contents()->GetContainerBounds().size(),
289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)            shell()->web_contents()->GetRenderWidgetHostView()->GetViewBounds().
290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                size());
291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // When a size is set, RenderWidgetHostView and WebContentsView honor this
293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // size.
294424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::Size size(300, 300);
295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gfx::Size size_insets(10, 15);
296424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ResizeWebContentsView(shell(), size, true);
297424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  delegate->set_size_insets(size_insets);
298d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  NavigateToURL(shell(), https_server.GetURL("/"));
299424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  size.Enlarge(size_insets.width(), size_insets.height());
300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  EXPECT_EQ(size,
301424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)            shell()->web_contents()->GetRenderWidgetHostView()->GetViewBounds().
302424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                size());
303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The web_contents size is set by the embedder, and should not depend on the
304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // rwhv size. The behavior is correct on OSX, but incorrect on other
305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // platforms.
306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gfx::Size exp_wcv_size(300, 300);
307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(OS_MACOSX)
308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  exp_wcv_size.Enlarge(size_insets.width(), size_insets.height());
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(exp_wcv_size,
312010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            shell()->web_contents()->GetContainerBounds().size());
313424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
314424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // If WebContentsView is resized after RenderWidgetHostView is created but
315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // before pending navigation entry is committed, both RenderWidgetHostView and
316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // WebContentsView use the new size of WebContentsView.
317424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::Size init_size(200, 200);
318424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  gfx::Size new_size(100, 100);
319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  size_insets = gfx::Size(20, 30);
320424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ResizeWebContentsView(shell(), init_size, true);
321424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  delegate->set_size_insets(size_insets);
322424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RenderViewSizeObserver observer(shell(), new_size);
323d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));
324424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // RenderWidgetHostView is created at specified size.
325424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  init_size.Enlarge(size_insets.width(), size_insets.height());
326424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  EXPECT_EQ(init_size, observer.rwhv_create_size());
327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Once again, the behavior is correct on OSX. The embedder explicitly sets
329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// the size to (100,100) during navigation. Both the wcv and the rwhv should
330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// take on that size.
331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(OS_MACOSX)
332424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  new_size.Enlarge(size_insets.width(), size_insets.height());
333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gfx::Size actual_size = shell()->web_contents()->GetRenderWidgetHostView()->
335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GetViewBounds().size();
336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(new_size, actual_size);
338010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(new_size, shell()->web_contents()->GetContainerBounds().size());
339424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
340424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, OpenURLSubframe) {
342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Navigate with FrameTreeNode ID 4.
344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL url("http://foo");
345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  OpenURLParams params(url, Referrer(), 4, CURRENT_TAB, PAGE_TRANSITION_LINK,
346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       true);
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  shell()->web_contents()->OpenURL(params);
348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Make sure the NavigationEntry ends up with the FrameTreeNode ID.
350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NavigationController* controller = &shell()->web_contents()->GetController();
351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(controller->GetPendingEntry());
352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(4, NavigationEntryImpl::FromNavigationEntry(
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                controller->GetPendingEntry())->frame_tree_node_id());
354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Observer class to track the creation of RenderFrameHost objects. It is used
357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// in subsequent tests.
358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class RenderFrameCreatedObserver : public WebContentsObserver {
359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RenderFrameCreatedObserver(Shell* shell)
361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      : WebContentsObserver(shell->web_contents()),
362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        last_rfh_(NULL) {
363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void RenderFrameCreated(RenderFrameHost* render_frame_host) OVERRIDE {
366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    last_rfh_ = render_frame_host;
367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RenderFrameHost* last_rfh() const { return last_rfh_; }
370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RenderFrameHost* last_rfh_;
373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RenderFrameCreatedObserver);
375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Test that creation of new RenderFrameHost objects sends the correct object
378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// to the WebContentObservers. See http://crbug.com/347339.
379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       RenderFrameCreatedCorrectProcessForObservers) {
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string foo_com("foo.com");
382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GURL::Replacements replace_host;
383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  net::HostPortPair foo_host_port;
384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GURL cross_site_url;
385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Setup the server to allow serving separate sites, so we can perform
387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // cross-process navigation.
388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  host_resolver()->AddRule("*", "127.0.0.1");
389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(test_server()->Start());
390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  foo_host_port = test_server()->host_port_pair();
392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  foo_host_port.set_host(foo_com);
393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GURL initial_url(test_server()->GetURL("/title1.html"));
395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  cross_site_url = test_server()->GetURL("/title2.html");
397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  replace_host.SetHostStr(foo_com);
398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  cross_site_url = cross_site_url.ReplaceComponents(replace_host);
399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Navigate to the initial URL and capture the RenderFrameHost for later
401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // comparison.
402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NavigateToURL(shell(), initial_url);
403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RenderFrameHost* orig_rfh = shell()->web_contents()->GetMainFrame();
404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Install the observer and navigate cross-site.
406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RenderFrameCreatedObserver observer(shell());
407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NavigateToURL(shell(), cross_site_url);
408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The observer should've seen a RenderFrameCreated call for the new frame
410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // and not the old one.
411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_NE(observer.last_rfh(), orig_rfh);
412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(observer.last_rfh(), shell()->web_contents()->GetMainFrame());
413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
415effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochIN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
416effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                       LoadingStateChangedForSameDocumentNavigation) {
417effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
418effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<LoadingStateChangedDelegate> delegate(
419effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      new LoadingStateChangedDelegate());
420effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  shell()->web_contents()->SetDelegate(delegate.get());
421effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
422effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  LoadStopNotificationObserver load_observer(
423effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      &shell()->web_contents()->GetController());
424effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  TitleWatcher title_watcher(shell()->web_contents(),
425effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                             base::ASCIIToUTF16("pushState"));
426effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  NavigateToURL(shell(), embedded_test_server()->GetURL("/push_state.html"));
427effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  load_observer.Wait();
428effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::string16 title = title_watcher.WaitAndGetTitle();
429effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ASSERT_EQ(title, base::ASCIIToUTF16("pushState"));
430effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
431effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // LoadingStateChanged should be called 4 times: start and stop for the
432effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // initial load of push_state.html, and start and stop for the "navigation"
433effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // triggered by history.pushState(). However, the start notification for the
434effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // history.pushState() navigation should set to_different_document to false.
435effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ("pushState", shell()->web_contents()->GetURL().ref());
436effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(4, delegate->loadingStateChangedCount());
437effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(3, delegate->loadingStateToDifferentDocumentCount());
438effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
439effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       RenderViewCreatedForChildWindow) {
442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NavigateToURL(shell(),
445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                embedded_test_server()->GetURL("/title1.html"));
446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  WebContentsAddedObserver new_web_contents_observer;
448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(ExecuteScript(shell()->web_contents(),
449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            "var a = document.createElement('a');"
450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            "a.href='./title2.html';"
451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            "a.target = '_blank';"
452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            "document.body.appendChild(a);"
453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            "a.click();"));
454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  WebContents* new_web_contents = new_web_contents_observer.GetWebContents();
455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  WaitForLoadStop(new_web_contents);
456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(new_web_contents_observer.RenderViewCreatedCalled());
457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)struct LoadProgressDelegateAndObserver : public WebContentsDelegate,
460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                         public WebContentsObserver {
461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  LoadProgressDelegateAndObserver(Shell* shell)
462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : WebContentsObserver(shell->web_contents()),
463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        did_start_loading(false),
464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        did_stop_loading(false) {
465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    web_contents()->SetDelegate(this);
466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // WebContentsDelegate:
469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void LoadProgressChanged(WebContents* source,
470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   double progress) OVERRIDE {
471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_TRUE(did_start_loading);
472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_FALSE(did_stop_loading);
473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    progresses.push_back(progress);
474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // WebContentsObserver:
477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void DidStartLoading(RenderViewHost* render_view_host) OVERRIDE {
478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_FALSE(did_start_loading);
479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(0U, progresses.size());
480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_FALSE(did_stop_loading);
481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    did_start_loading = true;
482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
484cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE {
485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_TRUE(did_start_loading);
486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_GE(progresses.size(), 1U);
487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_FALSE(did_stop_loading);
488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    did_stop_loading = true;
489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool did_start_loading;
492cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<double> progresses;
493cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool did_stop_loading;
494cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
495cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, LoadProgress) {
497cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
498cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<LoadProgressDelegateAndObserver> delegate(
499cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new LoadProgressDelegateAndObserver(shell()));
500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
501cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));
502cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
503cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const std::vector<double>& progresses = delegate->progresses;
504cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // All updates should be in order ...
505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (std::adjacent_find(progresses.begin(),
506cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         progresses.end(),
507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         std::greater<double>()) != progresses.end()) {
508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ADD_FAILURE() << "Progress values should be in order: "
509cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  << ::testing::PrintToString(progresses);
510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
511cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
512cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // ... and the last one should be 1.0, meaning complete.
513cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_GE(progresses.size(), 1U)
514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      << "There should be at least one progress update";
515cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(1.0, *progresses.rbegin());
516cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
517cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace content
5195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
520