1 // Copyright 2018 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 #ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_TEST_SUPPORT_H_
6 #define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_TEST_SUPPORT_H_
7 
8 #include <memory>
9 #include <string>
10 #include "base/callback.h"
11 #include "base/values.h"
12 #include "content/public/browser/devtools_agent_host.h"
13 #include "content/public/browser/web_contents_delegate.h"
14 #include "content/public/test/content_browser_test.h"
15 #include "net/test/cert_test_util.h"
16 
17 namespace content {
18 
19 class DevToolsProtocolTest : public ContentBrowserTest,
20                              public DevToolsAgentHostClient,
21                              public WebContentsDelegate {
22  public:
23   typedef base::RepeatingCallback<bool(base::DictionaryValue*)>
24       NotificationMatcher;
25 
26   DevToolsProtocolTest();
27   ~DevToolsProtocolTest() override;
28 
29   void SetUpOnMainThread() override;
30 
31  protected:
32   // WebContentsDelegate methods:
33   bool DidAddMessageToConsole(WebContents* source,
34                               blink::mojom::ConsoleMessageLevel log_level,
35                               const base::string16& message,
36                               int32_t line_no,
37                               const base::string16& source_id) override;
38 
39   blink::SecurityStyle GetSecurityStyle(
40       content::WebContents* web_contents,
41       content::SecurityStyleExplanations* security_style_explanations) override;
42 
SendCommand(const std::string & method,std::unique_ptr<base::Value> params)43   base::DictionaryValue* SendCommand(const std::string& method,
44                                      std::unique_ptr<base::Value> params) {
45     return SendCommand(method, std::move(params), true);
46   }
47 
SendCommand(const std::string & method,std::unique_ptr<base::Value> params,bool wait)48   base::DictionaryValue* SendCommand(const std::string& method,
49                                      std::unique_ptr<base::Value> params,
50                                      bool wait) {
51     return SendSessionCommand(method, std::move(params), std::string(), wait);
52   }
53 
SendSessionCommand(const std::string & method,std::unique_ptr<base::Value> params,const std::string & session_id)54   base::DictionaryValue* SendSessionCommand(const std::string& method,
55                                             std::unique_ptr<base::Value> params,
56                                             const std::string& session_id) {
57     return SendSessionCommand(method, std::move(params), session_id, true);
58   }
59 
60   base::DictionaryValue* SendSessionCommand(const std::string& method,
61                                             std::unique_ptr<base::Value> params,
62                                             const std::string& session_id,
63                                             bool wait);
64 
65   void WaitForResponse();
66 
67   bool HasValue(const std::string& path);
68 
69   bool HasListItem(const std::string& path_to_list,
70                    const std::string& name,
71                    const std::string& value);
72 
73   void Attach();
74 
75   void AttachToBrowserTarget();
76 
Detach()77   void Detach() {
78     if (agent_host_) {
79       agent_host_->DetachClient(this);
80       agent_host_ = nullptr;
81     }
82   }
83 
84   void TearDownOnMainThread() override;
85 
WaitForNotification(const std::string & notification)86   std::unique_ptr<base::DictionaryValue> WaitForNotification(
87       const std::string& notification) {
88     return WaitForNotification(notification, false);
89   }
90 
91   std::unique_ptr<base::DictionaryValue> WaitForNotification(
92       const std::string& notification,
93       bool allow_existing);
94 
95   // Waits for a notification whose params, when passed to |matcher|, returns
96   // true. Existing notifications are allowed.
97   std::unique_ptr<base::DictionaryValue> WaitForMatchingNotification(
98       const std::string& notification,
99       const NotificationMatcher& matcher);
100 
ClearNotifications()101   void ClearNotifications() {
102     notifications_.clear();
103     notification_params_.clear();
104   }
105 
106   struct ExpectedNavigation {
107     std::string url;
108     bool is_redirect;
109     bool abort;
110   };
111 
RemovePort(const GURL & url)112   std::string RemovePort(const GURL& url) {
113     GURL::Replacements remove_port;
114     remove_port.ClearPort();
115     return url.ReplaceComponents(remove_port).spec();
116   }
117 
118   // Waits for the expected navigations to occur in any order. If an expected
119   // navigation occurs, Network.continueInterceptedRequest is called with the
120   // specified navigation_response to either allow it to proceed or to cancel
121   // it.
122   void ProcessNavigationsAnyOrder(
123       std::vector<ExpectedNavigation> expected_navigations);
124 
125   std::vector<std::string> GetAllFrameUrls();
126 
set_agent_host_can_close()127   void set_agent_host_can_close() { agent_host_can_close_ = true; }
128 
SetSecurityExplanationCert(const scoped_refptr<net::X509Certificate> & cert)129   void SetSecurityExplanationCert(
130       const scoped_refptr<net::X509Certificate>& cert) {
131     cert_ = cert;
132   }
133 
134   std::unique_ptr<base::DictionaryValue> result_;
135   scoped_refptr<DevToolsAgentHost> agent_host_;
136   int last_sent_id_;
137   std::vector<int> result_ids_;
138   std::vector<std::string> notifications_;
139   std::vector<std::string> console_messages_;
140   std::vector<std::unique_ptr<base::DictionaryValue>> notification_params_;
141 
142  private:
143   void RunLoopUpdatingQuitClosure();
144   void DispatchProtocolMessage(DevToolsAgentHost* agent_host,
145                                base::span<const uint8_t> message) override;
146 
147   void AgentHostClosed(DevToolsAgentHost* agent_host) override;
148 
149   std::string waiting_for_notification_;
150   NotificationMatcher waiting_for_notification_matcher_;
151   std::unique_ptr<base::DictionaryValue> waiting_for_notification_params_;
152   int waiting_for_command_result_id_;
153   bool in_dispatch_;
154   bool agent_host_can_close_;
155   scoped_refptr<net::X509Certificate> cert_;
156   base::OnceClosure run_loop_quit_closure_;
157 };
158 
159 }  // namespace content
160 
161 #endif  // CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_TEST_SUPPORT_H_
162