OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stddef.h> | 5 #include <stddef.h> |
6 #include <utility> | 6 #include <utility> |
7 | 7 |
8 #include "base/base64.h" | 8 #include "base/base64.h" |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 #include "content/public/browser/render_view_host.h" | 32 #include "content/public/browser/render_view_host.h" |
33 #include "content/public/browser/render_widget_host_view.h" | 33 #include "content/public/browser/render_widget_host_view.h" |
34 #include "content/public/browser/ssl_status.h" | 34 #include "content/public/browser/ssl_status.h" |
35 #include "content/public/browser/web_contents.h" | 35 #include "content/public/browser/web_contents.h" |
36 #include "content/public/common/url_constants.h" | 36 #include "content/public/common/url_constants.h" |
37 #include "content/public/test/browser_test_utils.h" | 37 #include "content/public/test/browser_test_utils.h" |
38 #include "content/public/test/content_browser_test.h" | 38 #include "content/public/test/content_browser_test.h" |
39 #include "content/public/test/content_browser_test_utils.h" | 39 #include "content/public/test/content_browser_test_utils.h" |
40 #include "content/public/test/test_navigation_observer.h" | 40 #include "content/public/test/test_navigation_observer.h" |
41 #include "content/shell/browser/shell.h" | 41 #include "content/shell/browser/shell.h" |
| 42 #include "content/test/content_browser_test_utils_internal.h" |
42 #include "net/dns/mock_host_resolver.h" | 43 #include "net/dns/mock_host_resolver.h" |
43 #include "net/test/cert_test_util.h" | 44 #include "net/test/cert_test_util.h" |
44 #include "net/test/embedded_test_server/embedded_test_server.h" | 45 #include "net/test/embedded_test_server/embedded_test_server.h" |
45 #include "net/test/test_data_directory.h" | 46 #include "net/test/test_data_directory.h" |
46 #include "testing/gmock/include/gmock/gmock.h" | 47 #include "testing/gmock/include/gmock/gmock.h" |
47 #include "third_party/skia/include/core/SkBitmap.h" | 48 #include "third_party/skia/include/core/SkBitmap.h" |
48 #include "third_party/skia/include/core/SkColor.h" | 49 #include "third_party/skia/include/core/SkColor.h" |
49 #include "ui/base/layout.h" | 50 #include "ui/base/layout.h" |
50 #include "ui/compositor/compositor_switches.h" | 51 #include "ui/compositor/compositor_switches.h" |
51 #include "ui/gfx/codec/png_codec.h" | 52 #include "ui/gfx/codec/png_codec.h" |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 shell()->web_contents()->SetDelegate(this); | 224 shell()->web_contents()->SetDelegate(this); |
224 } | 225 } |
225 | 226 |
226 void TearDownOnMainThread() override { | 227 void TearDownOnMainThread() override { |
227 if (agent_host_) { | 228 if (agent_host_) { |
228 agent_host_->DetachClient(this); | 229 agent_host_->DetachClient(this); |
229 agent_host_ = nullptr; | 230 agent_host_ = nullptr; |
230 } | 231 } |
231 } | 232 } |
232 | 233 |
233 void WaitForNotification(const std::string& notification) { | 234 std::unique_ptr<base::DictionaryValue> WaitForNotification( |
| 235 const std::string& notification) { |
| 236 return WaitForNotification(notification, false); |
| 237 } |
| 238 |
| 239 std::unique_ptr<base::DictionaryValue> WaitForNotification( |
| 240 const std::string& notification, |
| 241 bool allow_existing) { |
| 242 if (allow_existing) { |
| 243 for (size_t i = 0; i < notifications_.size(); i++) { |
| 244 if (notifications_[i] == notification) { |
| 245 std::unique_ptr<base::DictionaryValue> result = |
| 246 std::move(notification_params_[i]); |
| 247 notifications_.erase(notifications_.begin() + i); |
| 248 notification_params_.erase(notification_params_.begin() + i); |
| 249 return result; |
| 250 } |
| 251 } |
| 252 } |
| 253 |
234 waiting_for_notification_ = notification; | 254 waiting_for_notification_ = notification; |
235 RunMessageLoop(); | 255 RunMessageLoop(); |
| 256 return std::move(waiting_for_notification_params_); |
| 257 } |
| 258 |
| 259 void ClearNotifications() { |
| 260 notifications_.clear(); |
| 261 notification_params_.clear(); |
236 } | 262 } |
237 | 263 |
238 struct ExpectedNavigation { | 264 struct ExpectedNavigation { |
239 std::string url; | 265 std::string url; |
240 bool is_in_main_frame; | 266 bool is_in_main_frame; |
241 bool is_redirect; | 267 bool is_redirect; |
242 std::string navigation_response; | 268 std::string navigation_response; |
243 }; | 269 }; |
244 | 270 |
245 std::string RemovePort(const GURL& url) { | 271 std::string RemovePort(const GURL& url) { |
246 GURL::Replacements remove_port; | 272 GURL::Replacements remove_port; |
247 remove_port.ClearPort(); | 273 remove_port.ClearPort(); |
248 return url.ReplaceComponents(remove_port).spec(); | 274 return url.ReplaceComponents(remove_port).spec(); |
249 } | 275 } |
250 | 276 |
251 // Waits for the expected navigations to occur in any order. If an expected | 277 // Waits for the expected navigations to occur in any order. If an expected |
252 // navigation occurs, Page.processNavigation is called with the specified | 278 // navigation occurs, Page.processNavigation is called with the specified |
253 // navigation_response to either allow it to proceed or to cancel it. | 279 // navigation_response to either allow it to proceed or to cancel it. |
254 void ProcessNavigationsAnyOrder( | 280 void ProcessNavigationsAnyOrder( |
255 std::vector<ExpectedNavigation> expected_navigations) { | 281 std::vector<ExpectedNavigation> expected_navigations) { |
256 while (!expected_navigations.empty()) { | 282 while (!expected_navigations.empty()) { |
257 WaitForNotification("Page.navigationRequested"); | 283 std::unique_ptr<base::DictionaryValue> params = |
258 ASSERT_TRUE(requested_notification_params_.get()); | 284 WaitForNotification("Page.navigationRequested"); |
259 | 285 |
260 std::string url; | 286 std::string url; |
261 ASSERT_TRUE(requested_notification_params_->GetString("url", &url)); | 287 ASSERT_TRUE(params->GetString("url", &url)); |
262 | 288 |
263 // The url will typically have a random port which we want to remove. | 289 // The url will typically have a random port which we want to remove. |
264 url = RemovePort(GURL(url)); | 290 url = RemovePort(GURL(url)); |
265 | 291 |
266 int navigation_id; | 292 int navigation_id; |
267 ASSERT_TRUE(requested_notification_params_->GetInteger("navigationId", | 293 ASSERT_TRUE(params->GetInteger("navigationId", &navigation_id)); |
268 &navigation_id)); | |
269 bool is_in_main_frame; | 294 bool is_in_main_frame; |
270 ASSERT_TRUE(requested_notification_params_->GetBoolean( | 295 ASSERT_TRUE(params->GetBoolean( "isInMainFrame", &is_in_main_frame)); |
271 "isInMainFrame", &is_in_main_frame)); | |
272 bool is_redirect; | 296 bool is_redirect; |
273 ASSERT_TRUE(requested_notification_params_->GetBoolean("isRedirect", | 297 ASSERT_TRUE(params->GetBoolean("isRedirect", &is_redirect)); |
274 &is_redirect)); | |
275 | 298 |
276 bool navigation_was_expected; | 299 bool navigation_was_expected; |
277 for (auto it = expected_navigations.begin(); | 300 for (auto it = expected_navigations.begin(); |
278 it != expected_navigations.end(); it++) { | 301 it != expected_navigations.end(); it++) { |
279 if (url != it->url || is_in_main_frame != it->is_in_main_frame || | 302 if (url != it->url || is_in_main_frame != it->is_in_main_frame || |
280 is_redirect != it->is_redirect) { | 303 is_redirect != it->is_redirect) { |
281 continue; | 304 continue; |
282 } | 305 } |
283 | 306 |
284 std::unique_ptr<base::DictionaryValue> params( | 307 std::unique_ptr<base::DictionaryValue> process_params( |
285 new base::DictionaryValue()); | 308 new base::DictionaryValue()); |
286 params->SetString("response", it->navigation_response); | 309 process_params->SetString("response", it->navigation_response); |
287 params->SetInteger("navigationId", navigation_id); | 310 process_params->SetInteger("navigationId", navigation_id); |
288 SendCommand("Page.processNavigation", std::move(params), false); | 311 SendCommand("Page.processNavigation", std::move(process_params), false); |
289 | 312 |
290 navigation_was_expected = true; | 313 navigation_was_expected = true; |
291 expected_navigations.erase(it); | 314 expected_navigations.erase(it); |
292 break; | 315 break; |
293 } | 316 } |
294 EXPECT_TRUE(navigation_was_expected) | 317 EXPECT_TRUE(navigation_was_expected) |
295 << "url = " << url << "is_in_main_frame = " << is_in_main_frame | 318 << "url = " << url << "is_in_main_frame = " << is_in_main_frame |
296 << "is_redirect = " << is_redirect; | 319 << "is_redirect = " << is_redirect; |
297 } | 320 } |
298 } | 321 } |
(...skipping 16 matching lines...) Expand all Loading... |
315 const scoped_refptr<net::X509Certificate>& expired_cert() { | 338 const scoped_refptr<net::X509Certificate>& expired_cert() { |
316 return expired_cert_; | 339 return expired_cert_; |
317 } | 340 } |
318 | 341 |
319 std::unique_ptr<base::DictionaryValue> result_; | 342 std::unique_ptr<base::DictionaryValue> result_; |
320 scoped_refptr<DevToolsAgentHost> agent_host_; | 343 scoped_refptr<DevToolsAgentHost> agent_host_; |
321 int last_sent_id_; | 344 int last_sent_id_; |
322 std::vector<int> result_ids_; | 345 std::vector<int> result_ids_; |
323 std::vector<std::string> notifications_; | 346 std::vector<std::string> notifications_; |
324 std::vector<std::string> console_messages_; | 347 std::vector<std::string> console_messages_; |
325 std::unique_ptr<base::DictionaryValue> requested_notification_params_; | 348 std::vector<std::unique_ptr<base::DictionaryValue>> notification_params_; |
326 | 349 |
327 private: | 350 private: |
328 void DispatchProtocolMessage(DevToolsAgentHost* agent_host, | 351 void DispatchProtocolMessage(DevToolsAgentHost* agent_host, |
329 const std::string& message) override { | 352 const std::string& message) override { |
330 std::unique_ptr<base::DictionaryValue> root( | 353 std::unique_ptr<base::DictionaryValue> root( |
331 static_cast<base::DictionaryValue*>( | 354 static_cast<base::DictionaryValue*>( |
332 base::JSONReader::Read(message).release())); | 355 base::JSONReader::Read(message).release())); |
333 int id; | 356 int id; |
334 if (root->GetInteger("id", &id)) { | 357 if (root->GetInteger("id", &id)) { |
335 result_ids_.push_back(id); | 358 result_ids_.push_back(id); |
336 base::DictionaryValue* result; | 359 base::DictionaryValue* result; |
337 ASSERT_TRUE(root->GetDictionary("result", &result)); | 360 ASSERT_TRUE(root->GetDictionary("result", &result)); |
338 result_.reset(result->DeepCopy()); | 361 result_.reset(result->DeepCopy()); |
339 in_dispatch_ = false; | 362 in_dispatch_ = false; |
340 if (id && id == waiting_for_command_result_id_) { | 363 if (id && id == waiting_for_command_result_id_) { |
341 waiting_for_command_result_id_ = 0; | 364 waiting_for_command_result_id_ = 0; |
342 base::MessageLoop::current()->QuitNow(); | 365 base::MessageLoop::current()->QuitNow(); |
343 } | 366 } |
344 } else { | 367 } else { |
345 std::string notification; | 368 std::string notification; |
346 EXPECT_TRUE(root->GetString("method", ¬ification)); | 369 EXPECT_TRUE(root->GetString("method", ¬ification)); |
347 notifications_.push_back(notification); | 370 notifications_.push_back(notification); |
| 371 base::DictionaryValue* params; |
| 372 if (root->GetDictionary("params", ¶ms)) { |
| 373 notification_params_.push_back(params->CreateDeepCopy()); |
| 374 } else { |
| 375 notification_params_.push_back( |
| 376 base::WrapUnique(new base::DictionaryValue())); |
| 377 } |
348 if (waiting_for_notification_ == notification) { | 378 if (waiting_for_notification_ == notification) { |
349 base::DictionaryValue* params; | |
350 if (root->GetDictionary("params", ¶ms)) { | |
351 requested_notification_params_ = params->CreateDeepCopy(); | |
352 } else { | |
353 requested_notification_params_.reset(); | |
354 } | |
355 waiting_for_notification_ = std::string(); | 379 waiting_for_notification_ = std::string(); |
| 380 waiting_for_notification_params_ = base::WrapUnique( |
| 381 notification_params_[notification_params_.size() - 1]->DeepCopy()); |
356 base::MessageLoop::current()->QuitNow(); | 382 base::MessageLoop::current()->QuitNow(); |
357 } | 383 } |
358 } | 384 } |
359 } | 385 } |
360 | 386 |
361 void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override { | 387 void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override { |
362 DCHECK(false); | 388 DCHECK(false); |
363 } | 389 } |
364 | 390 |
365 std::string waiting_for_notification_; | 391 std::string waiting_for_notification_; |
| 392 std::unique_ptr<base::DictionaryValue> waiting_for_notification_params_; |
366 int waiting_for_command_result_id_; | 393 int waiting_for_command_result_id_; |
367 bool in_dispatch_; | 394 bool in_dispatch_; |
368 scoped_refptr<net::X509Certificate> last_shown_certificate_; | 395 scoped_refptr<net::X509Certificate> last_shown_certificate_; |
369 scoped_refptr<net::X509Certificate> ok_cert_; | 396 scoped_refptr<net::X509Certificate> ok_cert_; |
370 scoped_refptr<net::X509Certificate> expired_cert_; | 397 scoped_refptr<net::X509Certificate> expired_cert_; |
371 }; | 398 }; |
372 | 399 |
373 class TestInterstitialDelegate : public InterstitialPageDelegate { | 400 class TestInterstitialDelegate : public InterstitialPageDelegate { |
374 private: | 401 private: |
375 // InterstitialPageDelegate: | 402 // InterstitialPageDelegate: |
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1210 web_contents->GetController().GetTransientEntry(); | 1237 web_contents->GetController().GetTransientEntry(); |
1211 ASSERT_TRUE(transient_entry); | 1238 ASSERT_TRUE(transient_entry); |
1212 transient_entry->GetSSL().certificate = expired_cert(); | 1239 transient_entry->GetSSL().certificate = expired_cert(); |
1213 ASSERT_TRUE(transient_entry->GetSSL().certificate); | 1240 ASSERT_TRUE(transient_entry->GetSSL().certificate); |
1214 | 1241 |
1215 std::unique_ptr<base::DictionaryValue> params2(new base::DictionaryValue()); | 1242 std::unique_ptr<base::DictionaryValue> params2(new base::DictionaryValue()); |
1216 SendCommand("Security.showCertificateViewer", std::move(params2), true); | 1243 SendCommand("Security.showCertificateViewer", std::move(params2), true); |
1217 EXPECT_EQ(transient_entry->GetSSL().certificate, last_shown_certificate()); | 1244 EXPECT_EQ(transient_entry->GetSSL().certificate, last_shown_certificate()); |
1218 } | 1245 } |
1219 | 1246 |
| 1247 class SitePerProcessDevToolsProtocolTest : public DevToolsProtocolTest { |
| 1248 public: |
| 1249 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 1250 DevToolsProtocolTest::SetUpCommandLine(command_line); |
| 1251 IsolateAllSitesForTesting(command_line); |
| 1252 }; |
| 1253 |
| 1254 void SetUpOnMainThread() override { |
| 1255 DevToolsProtocolTest::SetUpOnMainThread(); |
| 1256 host_resolver()->AddRule("*", "127.0.0.1"); |
| 1257 ASSERT_TRUE(embedded_test_server()->Start()); |
| 1258 SetupCrossSiteRedirector(embedded_test_server()); |
| 1259 } |
| 1260 }; |
| 1261 |
| 1262 IN_PROC_BROWSER_TEST_F(SitePerProcessDevToolsProtocolTest, TargetNoDiscovery) { |
| 1263 std::string temp; |
| 1264 std::string target_id; |
| 1265 std::unique_ptr<base::DictionaryValue> command_params; |
| 1266 std::unique_ptr<base::DictionaryValue> params; |
| 1267 |
| 1268 GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html")); |
| 1269 NavigateToURLBlockUntilNavigationsComplete(shell(), main_url, 1); |
| 1270 // It is safe to obtain the root frame tree node here, as it doesn't change. |
| 1271 FrameTreeNode* root = |
| 1272 static_cast<WebContentsImpl*>(shell()->web_contents())-> |
| 1273 GetFrameTree()->root(); |
| 1274 |
| 1275 // Load cross-site page into iframe. |
| 1276 GURL::Replacements replace_host; |
| 1277 GURL cross_site_url(embedded_test_server()->GetURL("/title1.html")); |
| 1278 replace_host.SetHostStr("foo.com"); |
| 1279 cross_site_url = cross_site_url.ReplaceComponents(replace_host); |
| 1280 NavigateFrameToURL(root->child_at(0), cross_site_url); |
| 1281 |
| 1282 // Enable auto-attach. |
| 1283 Attach(); |
| 1284 command_params.reset(new base::DictionaryValue()); |
| 1285 command_params->SetBoolean("autoAttach", true); |
| 1286 command_params->SetBoolean("waitForDebuggerOnStart", true); |
| 1287 SendCommand("Target.setAutoAttach", std::move(command_params), true); |
| 1288 EXPECT_TRUE(notifications_.empty()); |
| 1289 command_params.reset(new base::DictionaryValue()); |
| 1290 command_params->SetBoolean("value", true); |
| 1291 SendCommand("Target.setAttachToFrames", std::move(command_params), false); |
| 1292 params = WaitForNotification("Target.targetCreated", true); |
| 1293 EXPECT_TRUE(params->GetString("targetInfo.targetId", &target_id)); |
| 1294 EXPECT_TRUE(params->GetString("targetInfo.type", &temp)); |
| 1295 EXPECT_EQ("iframe", temp); |
| 1296 params = WaitForNotification("Target.attachedToTarget", true); |
| 1297 EXPECT_TRUE(params->GetString("targetId", &temp)); |
| 1298 EXPECT_EQ(target_id, temp); |
| 1299 |
| 1300 // Load same-site page into iframe. |
| 1301 FrameTreeNode* child = root->child_at(0); |
| 1302 GURL http_url(embedded_test_server()->GetURL("/title1.html")); |
| 1303 NavigateFrameToURL(child, http_url); |
| 1304 params = WaitForNotification("Target.detachedFromTarget", true); |
| 1305 EXPECT_TRUE(params->GetString("targetId", &temp)); |
| 1306 EXPECT_EQ(target_id, temp); |
| 1307 params = WaitForNotification("Target.targetRemoved", true); |
| 1308 EXPECT_TRUE(params->GetString("targetId", &temp)); |
| 1309 EXPECT_EQ(target_id, temp); |
| 1310 |
| 1311 // Navigate back to cross-site iframe. |
| 1312 NavigateFrameToURL(root->child_at(0), cross_site_url); |
| 1313 params = WaitForNotification("Target.targetCreated", true); |
| 1314 EXPECT_TRUE(params->GetString("targetInfo.targetId", &target_id)); |
| 1315 EXPECT_TRUE(params->GetString("targetInfo.type", &temp)); |
| 1316 EXPECT_EQ("iframe", temp); |
| 1317 params = WaitForNotification("Target.attachedToTarget", true); |
| 1318 EXPECT_TRUE(params->GetString("targetId", &temp)); |
| 1319 EXPECT_EQ(target_id, temp); |
| 1320 |
| 1321 // Disable auto-attach. |
| 1322 command_params.reset(new base::DictionaryValue()); |
| 1323 command_params->SetBoolean("autoAttach", false); |
| 1324 command_params->SetBoolean("waitForDebuggerOnStart", false); |
| 1325 SendCommand("Target.setAutoAttach", std::move(command_params), false); |
| 1326 params = WaitForNotification("Target.detachedFromTarget", true); |
| 1327 EXPECT_TRUE(params->GetString("targetId", &temp)); |
| 1328 EXPECT_EQ(target_id, temp); |
| 1329 params = WaitForNotification("Target.targetRemoved", true); |
| 1330 EXPECT_TRUE(params->GetString("targetId", &temp)); |
| 1331 EXPECT_EQ(target_id, temp); |
| 1332 } |
| 1333 |
1220 } // namespace content | 1334 } // namespace content |
OLD | NEW |