| 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 "base/base64.h" | 5 #include "base/base64.h" |
| 6 #include "base/command_line.h" | 6 #include "base/command_line.h" |
| 7 #include "base/json/json_reader.h" | 7 #include "base/json/json_reader.h" |
| 8 #include "base/json/json_writer.h" | 8 #include "base/json/json_writer.h" |
| 9 #include "base/values.h" | 9 #include "base/values.h" |
| 10 #include "content/public/browser/devtools_agent_host.h" | 10 #include "content/public/browser/devtools_agent_host.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 const char kMethodParam[] = "method"; | 30 const char kMethodParam[] = "method"; |
| 31 const char kParamsParam[] = "params"; | 31 const char kParamsParam[] = "params"; |
| 32 | 32 |
| 33 } | 33 } |
| 34 | 34 |
| 35 class DevToolsProtocolTest : public ContentBrowserTest, | 35 class DevToolsProtocolTest : public ContentBrowserTest, |
| 36 public DevToolsAgentHostClient { | 36 public DevToolsAgentHostClient { |
| 37 public: | 37 public: |
| 38 DevToolsProtocolTest() | 38 DevToolsProtocolTest() |
| 39 : last_sent_id_(0), | 39 : last_sent_id_(0), |
| 40 waiting_for_notifications_count_(0), | 40 waiting_for_command_result_id_(0), |
| 41 in_dispatch_(false) { | 41 in_dispatch_(false) { |
| 42 } | 42 } |
| 43 | 43 |
| 44 protected: | 44 protected: |
| 45 void SendCommand(const std::string& method, | 45 void SendCommand(const std::string& method, |
| 46 scoped_ptr<base::DictionaryValue> params) { | 46 scoped_ptr<base::DictionaryValue> params) { |
| 47 SendCommand(method, params.Pass(), true); | 47 SendCommand(method, params.Pass(), true); |
| 48 } | 48 } |
| 49 | 49 |
| 50 void SendCommand(const std::string& method, | 50 void SendCommand(const std::string& method, |
| 51 scoped_ptr<base::DictionaryValue> params, | 51 scoped_ptr<base::DictionaryValue> params, |
| 52 bool wait) { | 52 bool wait) { |
| 53 in_dispatch_ = true; | 53 in_dispatch_ = true; |
| 54 base::DictionaryValue command; | 54 base::DictionaryValue command; |
| 55 command.SetInteger(kIdParam, ++last_sent_id_); | 55 command.SetInteger(kIdParam, ++last_sent_id_); |
| 56 command.SetString(kMethodParam, method); | 56 command.SetString(kMethodParam, method); |
| 57 if (params) | 57 if (params) |
| 58 command.Set(kParamsParam, params.release()); | 58 command.Set(kParamsParam, params.release()); |
| 59 | 59 |
| 60 std::string json_command; | 60 std::string json_command; |
| 61 base::JSONWriter::Write(command, &json_command); | 61 base::JSONWriter::Write(command, &json_command); |
| 62 agent_host_->DispatchProtocolMessage(json_command); | 62 agent_host_->DispatchProtocolMessage(json_command); |
| 63 // Some messages are dispatched synchronously. | 63 // Some messages are dispatched synchronously. |
| 64 // Only run loop if we are not finished yet. | 64 // Only run loop if we are not finished yet. |
| 65 if (in_dispatch_ && wait) | 65 if (in_dispatch_ && wait) { |
| 66 waiting_for_command_result_id_ = last_sent_id_; |
| 66 base::MessageLoop::current()->Run(); | 67 base::MessageLoop::current()->Run(); |
| 68 } |
| 67 in_dispatch_ = false; | 69 in_dispatch_ = false; |
| 68 } | 70 } |
| 69 | 71 |
| 70 bool HasValue(const std::string& path) { | 72 bool HasValue(const std::string& path) { |
| 71 base::Value* value = 0; | 73 base::Value* value = 0; |
| 72 return result_->Get(path, &value); | 74 return result_->Get(path, &value); |
| 73 } | 75 } |
| 74 | 76 |
| 75 bool HasListItem(const std::string& path_to_list, | 77 bool HasListItem(const std::string& path_to_list, |
| 76 const std::string& name, | 78 const std::string& name, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 97 agent_host_->AttachClient(this); | 99 agent_host_->AttachClient(this); |
| 98 } | 100 } |
| 99 | 101 |
| 100 void TearDownOnMainThread() override { | 102 void TearDownOnMainThread() override { |
| 101 if (agent_host_) { | 103 if (agent_host_) { |
| 102 agent_host_->DetachClient(); | 104 agent_host_->DetachClient(); |
| 103 agent_host_ = nullptr; | 105 agent_host_ = nullptr; |
| 104 } | 106 } |
| 105 } | 107 } |
| 106 | 108 |
| 107 void WaitForNotifications(int count) { | 109 void WaitForNotification(const std::string& notification) { |
| 108 waiting_for_notifications_count_ = count; | 110 waiting_for_notification_ = notification; |
| 109 RunMessageLoop(); | 111 RunMessageLoop(); |
| 110 } | 112 } |
| 111 | 113 |
| 112 scoped_ptr<base::DictionaryValue> result_; | 114 scoped_ptr<base::DictionaryValue> result_; |
| 113 scoped_refptr<DevToolsAgentHost> agent_host_; | 115 scoped_refptr<DevToolsAgentHost> agent_host_; |
| 114 int last_sent_id_; | 116 int last_sent_id_; |
| 115 std::vector<int> result_ids_; | 117 std::vector<int> result_ids_; |
| 116 std::vector<std::string> notifications_; | 118 std::vector<std::string> notifications_; |
| 117 | 119 |
| 118 private: | 120 private: |
| 119 void DispatchProtocolMessage(DevToolsAgentHost* agent_host, | 121 void DispatchProtocolMessage(DevToolsAgentHost* agent_host, |
| 120 const std::string& message) override { | 122 const std::string& message) override { |
| 121 scoped_ptr<base::DictionaryValue> root(static_cast<base::DictionaryValue*>( | 123 scoped_ptr<base::DictionaryValue> root(static_cast<base::DictionaryValue*>( |
| 122 base::JSONReader::Read(message).release())); | 124 base::JSONReader::Read(message).release())); |
| 123 int id; | 125 int id; |
| 124 if (root->GetInteger("id", &id)) { | 126 if (root->GetInteger("id", &id)) { |
| 125 result_ids_.push_back(id); | 127 result_ids_.push_back(id); |
| 126 base::DictionaryValue* result; | 128 base::DictionaryValue* result; |
| 127 EXPECT_TRUE(root->GetDictionary("result", &result)); | 129 EXPECT_TRUE(root->GetDictionary("result", &result)); |
| 128 result_.reset(result->DeepCopy()); | 130 result_.reset(result->DeepCopy()); |
| 129 in_dispatch_ = false; | 131 in_dispatch_ = false; |
| 130 if (base::MessageLoop::current()->is_running()) | 132 if (id && id == waiting_for_command_result_id_) { |
| 133 waiting_for_command_result_id_ = 0; |
| 131 base::MessageLoop::current()->QuitNow(); | 134 base::MessageLoop::current()->QuitNow(); |
| 135 } |
| 132 } else { | 136 } else { |
| 133 std::string notification; | 137 std::string notification; |
| 134 EXPECT_TRUE(root->GetString("method", ¬ification)); | 138 EXPECT_TRUE(root->GetString("method", ¬ification)); |
| 135 notifications_.push_back(notification); | 139 notifications_.push_back(notification); |
| 136 if (waiting_for_notifications_count_) { | 140 if (waiting_for_notification_ == notification) { |
| 137 waiting_for_notifications_count_--; | 141 waiting_for_notification_ = std::string(); |
| 138 if (!waiting_for_notifications_count_) | 142 base::MessageLoop::current()->QuitNow(); |
| 139 base::MessageLoop::current()->QuitNow(); | |
| 140 } | 143 } |
| 141 } | 144 } |
| 142 } | 145 } |
| 143 | 146 |
| 144 void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override { | 147 void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override { |
| 145 EXPECT_TRUE(false); | 148 EXPECT_TRUE(false); |
| 146 } | 149 } |
| 147 | 150 |
| 148 int waiting_for_notifications_count_; | 151 std::string waiting_for_notification_; |
| 152 int waiting_for_command_result_id_; |
| 149 bool in_dispatch_; | 153 bool in_dispatch_; |
| 150 }; | 154 }; |
| 151 | 155 |
| 152 class SyntheticKeyEventTest : public DevToolsProtocolTest { | 156 class SyntheticKeyEventTest : public DevToolsProtocolTest { |
| 153 protected: | 157 protected: |
| 154 void SendKeyEvent(const std::string& type, | 158 void SendKeyEvent(const std::string& type, |
| 155 int modifier, | 159 int modifier, |
| 156 int windowsKeyCode, | 160 int windowsKeyCode, |
| 157 int nativeKeyCode) { | 161 int nativeKeyCode) { |
| 158 scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue()); | 162 scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue()); |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 ASSERT_TRUE(test_server()->Start()); | 380 ASSERT_TRUE(test_server()->Start()); |
| 377 GURL test_url = test_server()->GetURL("files/devtools/navigation.html"); | 381 GURL test_url = test_server()->GetURL("files/devtools/navigation.html"); |
| 378 NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1); | 382 NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1); |
| 379 | 383 |
| 380 Shell* second = CreateBrowser(); | 384 Shell* second = CreateBrowser(); |
| 381 NavigateToURLBlockUntilNavigationsComplete(second, test_url, 1); | 385 NavigateToURLBlockUntilNavigationsComplete(second, test_url, 1); |
| 382 | 386 |
| 383 Attach(); | 387 Attach(); |
| 384 SendCommand("Runtime.enable", nullptr); | 388 SendCommand("Runtime.enable", nullptr); |
| 385 | 389 |
| 386 size_t notification_count = notifications_.size(); | |
| 387 agent_host_->DisconnectWebContents(); | 390 agent_host_->DisconnectWebContents(); |
| 388 agent_host_->ConnectWebContents(second->web_contents()); | 391 agent_host_->ConnectWebContents(second->web_contents()); |
| 389 WaitForNotifications(1); | 392 WaitForNotification("Runtime.executionContextsCleared"); |
| 393 } |
| 390 | 394 |
| 391 bool found_notification = false; | 395 IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, CrossSitePauseInBeforeUnload) { |
| 392 for (size_t i = notification_count; i < notifications_.size(); ++i) { | 396 host_resolver()->AddRule("*", "127.0.0.1"); |
| 393 if (notifications_[i] == "Runtime.executionContextsCleared") | 397 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
| 394 found_notification = true; | 398 content::SetupCrossSiteRedirector(embedded_test_server()); |
| 395 } | 399 |
| 396 EXPECT_TRUE(found_notification); | 400 NavigateToURLBlockUntilNavigationsComplete(shell(), |
| 401 embedded_test_server()->GetURL("A.com", "/devtools/navigation.html"), 1); |
| 402 Attach(); |
| 403 SendCommand("Debugger.enable", nullptr); |
| 404 |
| 405 ASSERT_TRUE(content::ExecuteScript( |
| 406 shell()->web_contents(), |
| 407 "window.onbeforeunload = function() { debugger; return ''; }")); |
| 408 |
| 409 shell()->LoadURL( |
| 410 embedded_test_server()->GetURL("B.com", "/devtools/navigation.html")); |
| 411 WaitForNotification("Debugger.paused"); |
| 412 TestNavigationObserver observer(shell()->web_contents(), 1); |
| 413 SendCommand("Debugger.resume", nullptr); |
| 414 observer.Wait(); |
| 397 } | 415 } |
| 398 | 416 |
| 399 } // namespace content | 417 } // namespace content |
| OLD | NEW |