Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / content / browser / devtools / devtools_manager_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/basictypes.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/time/time.h"
8 #include "content/browser/devtools/devtools_manager_impl.h"
9 #include "content/browser/devtools/render_view_devtools_agent_host.h"
10 #include "content/common/view_messages.h"
11 #include "content/public/browser/content_browser_client.h"
12 #include "content/public/browser/devtools_agent_host.h"
13 #include "content/public/browser/devtools_client_host.h"
14 #include "content/public/browser/devtools_external_agent_proxy.h"
15 #include "content/public/browser/devtools_external_agent_proxy_delegate.h"
16 #include "content/public/browser/web_contents_delegate.h"
17 #include "content/test/test_content_browser_client.h"
18 #include "content/test/test_render_view_host.h"
19 #include "content/test/test_web_contents.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 using base::TimeDelta;
23
24 namespace content {
25 namespace {
26
27 class TestDevToolsClientHost : public DevToolsClientHost {
28  public:
29   TestDevToolsClientHost()
30       : last_sent_message(NULL),
31         closed_(false) {
32   }
33
34   virtual ~TestDevToolsClientHost() {
35     EXPECT_TRUE(closed_);
36   }
37
38   virtual void Close(DevToolsManager* manager) {
39     EXPECT_FALSE(closed_);
40     close_counter++;
41     manager->ClientHostClosing(this);
42     closed_ = true;
43   }
44   virtual void InspectedContentsClosing() OVERRIDE {
45     FAIL();
46   }
47
48   virtual void DispatchOnInspectorFrontend(
49       const std::string& message) OVERRIDE {
50     last_sent_message = &message;
51   }
52
53   virtual void ReplacedWithAnotherClient() OVERRIDE {
54   }
55
56   static void ResetCounters() {
57     close_counter = 0;
58   }
59
60   static int close_counter;
61
62   const std::string* last_sent_message;
63
64  private:
65   bool closed_;
66
67   DISALLOW_COPY_AND_ASSIGN(TestDevToolsClientHost);
68 };
69
70 int TestDevToolsClientHost::close_counter = 0;
71
72
73 class TestWebContentsDelegate : public WebContentsDelegate {
74  public:
75   TestWebContentsDelegate() : renderer_unresponsive_received_(false) {}
76
77   // Notification that the contents is hung.
78   virtual void RendererUnresponsive(WebContents* source) OVERRIDE {
79     renderer_unresponsive_received_ = true;
80   }
81
82   bool renderer_unresponsive_received() const {
83     return renderer_unresponsive_received_;
84   }
85
86  private:
87   bool renderer_unresponsive_received_;
88 };
89
90 }  // namespace
91
92 class DevToolsManagerTest : public RenderViewHostImplTestHarness {
93  protected:
94   virtual void SetUp() OVERRIDE {
95     RenderViewHostImplTestHarness::SetUp();
96     TestDevToolsClientHost::ResetCounters();
97   }
98 };
99
100 TEST_F(DevToolsManagerTest, OpenAndManuallyCloseDevToolsClientHost) {
101   DevToolsManager* manager = DevToolsManager::GetInstance();
102
103   scoped_refptr<DevToolsAgentHost> agent(
104       DevToolsAgentHost::GetOrCreateFor(web_contents()));
105   EXPECT_FALSE(agent->IsAttached());
106
107   TestDevToolsClientHost client_host;
108   manager->RegisterDevToolsClientHostFor(agent.get(), &client_host);
109   // Test that the connection is established.
110   EXPECT_TRUE(agent->IsAttached());
111   EXPECT_EQ(agent, manager->GetDevToolsAgentHostFor(&client_host));
112   EXPECT_EQ(0, TestDevToolsClientHost::close_counter);
113
114   client_host.Close(manager);
115   EXPECT_EQ(1, TestDevToolsClientHost::close_counter);
116   EXPECT_FALSE(agent->IsAttached());
117 }
118
119 TEST_F(DevToolsManagerTest, ForwardMessageToClient) {
120   DevToolsManagerImpl* manager = DevToolsManagerImpl::GetInstance();
121
122   TestDevToolsClientHost client_host;
123   scoped_refptr<DevToolsAgentHost> agent_host(
124       DevToolsAgentHost::GetOrCreateFor(web_contents()));
125   manager->RegisterDevToolsClientHostFor(agent_host.get(), &client_host);
126   EXPECT_EQ(0, TestDevToolsClientHost::close_counter);
127
128   std::string m = "test message";
129   agent_host = DevToolsAgentHost::GetOrCreateFor(web_contents());
130   manager->DispatchOnInspectorFrontend(agent_host.get(), m);
131   EXPECT_TRUE(&m == client_host.last_sent_message);
132
133   client_host.Close(manager);
134   EXPECT_EQ(1, TestDevToolsClientHost::close_counter);
135 }
136
137 TEST_F(DevToolsManagerTest, NoUnresponsiveDialogInInspectedContents) {
138   TestRenderViewHost* inspected_rvh = test_rvh();
139   inspected_rvh->set_render_view_created(true);
140   EXPECT_FALSE(contents()->GetDelegate());
141   TestWebContentsDelegate delegate;
142   contents()->SetDelegate(&delegate);
143
144   TestDevToolsClientHost client_host;
145   scoped_refptr<DevToolsAgentHost> agent_host(DevToolsAgentHost::GetOrCreateFor(
146       WebContents::FromRenderViewHost(inspected_rvh)));
147   DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(
148       agent_host.get(), &client_host);
149
150   // Start with a short timeout.
151   inspected_rvh->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
152   // Wait long enough for first timeout and see if it fired.
153   base::MessageLoop::current()->PostDelayedTask(
154       FROM_HERE,
155       base::MessageLoop::QuitClosure(),
156       TimeDelta::FromMilliseconds(10));
157   base::MessageLoop::current()->Run();
158   EXPECT_FALSE(delegate.renderer_unresponsive_received());
159
160   // Now close devtools and check that the notification is delivered.
161   client_host.Close(DevToolsManager::GetInstance());
162   // Start with a short timeout.
163   inspected_rvh->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
164   // Wait long enough for first timeout and see if it fired.
165   base::MessageLoop::current()->PostDelayedTask(
166       FROM_HERE,
167       base::MessageLoop::QuitClosure(),
168       TimeDelta::FromMilliseconds(10));
169   base::MessageLoop::current()->Run();
170   EXPECT_TRUE(delegate.renderer_unresponsive_received());
171
172   contents()->SetDelegate(NULL);
173 }
174
175 TEST_F(DevToolsManagerTest, ReattachOnCancelPendingNavigation) {
176   // Navigate to URL.  First URL should use first RenderViewHost.
177   const GURL url("http://www.google.com");
178   controller().LoadURL(
179       url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
180   contents()->TestDidNavigate(
181       contents()->GetMainFrame(), 1, url, PAGE_TRANSITION_TYPED);
182   EXPECT_FALSE(contents()->cross_navigation_pending());
183
184   TestDevToolsClientHost client_host;
185   DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
186   devtools_manager->RegisterDevToolsClientHostFor(
187       DevToolsAgentHost::GetOrCreateFor(web_contents()).get(), &client_host);
188
189   // Navigate to new site which should get a new RenderViewHost.
190   const GURL url2("http://www.yahoo.com");
191   controller().LoadURL(
192       url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
193   EXPECT_TRUE(contents()->cross_navigation_pending());
194   EXPECT_EQ(devtools_manager->GetDevToolsAgentHostFor(&client_host),
195             DevToolsAgentHost::GetOrCreateFor(web_contents()));
196
197   // Interrupt pending navigation and navigate back to the original site.
198   controller().LoadURL(
199       url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
200   contents()->TestDidNavigate(
201       contents()->GetMainFrame(), 1, url, PAGE_TRANSITION_TYPED);
202   EXPECT_FALSE(contents()->cross_navigation_pending());
203   EXPECT_EQ(devtools_manager->GetDevToolsAgentHostFor(&client_host),
204             DevToolsAgentHost::GetOrCreateFor(web_contents()));
205   client_host.Close(DevToolsManager::GetInstance());
206 }
207
208 class TestExternalAgentDelegate: public DevToolsExternalAgentProxyDelegate {
209   std::map<std::string,int> event_counter_;
210
211   void recordEvent(const std::string& name) {
212     if (event_counter_.find(name) == event_counter_.end())
213       event_counter_[name] = 0;
214     event_counter_[name] = event_counter_[name] + 1;
215   }
216
217   void expectEvent(int count, const std::string& name) {
218     EXPECT_EQ(count, event_counter_[name]);
219   }
220
221   virtual void Attach(DevToolsExternalAgentProxy* proxy) OVERRIDE {
222     recordEvent("Attach");
223   };
224
225   virtual void Detach() OVERRIDE {
226     recordEvent("Detach");
227   };
228
229   virtual void SendMessageToBackend(const std::string& message) OVERRIDE {
230     recordEvent(std::string("SendMessageToBackend.") + message);
231   };
232
233  public :
234   virtual ~TestExternalAgentDelegate() {
235     expectEvent(1, "Attach");
236     expectEvent(1, "Detach");
237     expectEvent(0, "SendMessageToBackend.message0");
238     expectEvent(1, "SendMessageToBackend.message1");
239     expectEvent(2, "SendMessageToBackend.message2");
240   }
241 };
242
243 TEST_F(DevToolsManagerTest, TestExternalProxy) {
244   TestExternalAgentDelegate* delegate = new TestExternalAgentDelegate();
245
246   scoped_refptr<DevToolsAgentHost> agent_host =
247       DevToolsAgentHost::Create(delegate);
248   EXPECT_EQ(agent_host, DevToolsAgentHost::GetForId(agent_host->GetId()));
249
250   DevToolsManager* manager = DevToolsManager::GetInstance();
251
252   TestDevToolsClientHost client_host;
253   manager->RegisterDevToolsClientHostFor(agent_host.get(), &client_host);
254
255   manager->DispatchOnInspectorBackend(&client_host, "message1");
256   manager->DispatchOnInspectorBackend(&client_host, "message2");
257   manager->DispatchOnInspectorBackend(&client_host, "message2");
258
259   client_host.Close(manager);
260 }
261
262 }  // namespace content