| 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 |