11package aquality .selenium .browser .devtools ;
22
3+ import aquality .selenium .browser .AqualityServices ;
4+ import aquality .selenium .core .localization .ILocalizedLogger ;
5+ import org .apache .commons .lang3 .NotImplementedException ;
6+ import org .openqa .selenium .chromium .ChromiumDriver ;
7+ import org .openqa .selenium .devtools .Command ;
38import org .openqa .selenium .devtools .DevTools ;
9+ import org .openqa .selenium .devtools .Event ;
410import org .openqa .selenium .devtools .HasDevTools ;
511
12+ import java .util .Map ;
13+ import java .util .function .Consumer ;
14+
15+ /**
16+ * Wrapper for Selenium {@link DevTools} functionality.
17+ */
618public class DevToolsHandling {
719 private final HasDevTools devToolsProvider ;
20+ private final ILocalizedLogger logger ;
21+
822 private DevTools session ;
23+ private NetworkHandling network ;
24+ private EmulationHandling emulation ;
925
26+ /**
27+ * Initializes an instance of {@link DevToolsHandling}
28+ * @param devToolsProvider Instance of {@link org.openqa.selenium.WebDriver} which supports CDP protocol.
29+ */
1030 public DevToolsHandling (HasDevTools devToolsProvider ) {
1131 this .devToolsProvider = devToolsProvider ;
32+ this .logger = AqualityServices .getLocalizedLogger ();
1233 }
1334
1435 private DevTools getDevTools () {
@@ -18,21 +39,130 @@ private DevTools getDevTools() {
1839 return session ;
1940 }
2041
21- public DevTools getSession () {
42+ private void logCommand (String commandName , Map <String , Object > commandParameters ) {
43+ if (!commandParameters .isEmpty ()) {
44+ logger .info ("loc.browser.devtools.command.execute.withparams" , commandName , commandParameters );
45+ }
46+ else {
47+ logger .info ("loc.browser.devtools.command.execute" , commandName );
48+ }
49+ }
50+
51+ private void logCommandResult (Object result ) {
52+ if (result != null ) {
53+ if (result instanceof Map && ((Map <?, ?>) result ).isEmpty ()) {
54+ return ;
55+ }
56+ logger .info ("loc.browser.devtools.command.execute.result" , result );
57+ }
58+ }
59+
60+ /**
61+ * Creates a session to communicate with a browser using the Chromium Developer Tools debugging protocol, if there is not one.
62+ * If the session already exist, returns existing session.
63+ * Defaults to autodetect the protocol version for Chromium, V85 for Firefox.
64+ * @return The active session to use to communicate with the Chromium Developer Tools debugging protocol.
65+ */
66+ public DevTools getDevToolsSession () {
67+ logger .info ("loc.browser.devtools.session.get" , "default" );
2268 getDevTools ().createSessionIfThereIsNotOne ();
2369 return session ;
2470 }
2571
26- public DevTools getSession (String windowHandle ) {
72+ /**
73+ * Creates a session to communicate with a browser using the Chromium Developer Tools debugging protocol, if there is not one, on given window/tab (aka target).
74+ * If the session already exist, returns existing session.
75+ * If windowHandle is null, then the first "page" type will be selected.
76+ * Pass the windowHandle if you have multiple windows/tabs opened to connect to the expected window/tab.
77+ * Defaults to autodetect the protocol version for Chromium, V85 for Firefox.
78+ * @param windowHandle result of {@link org.openqa.selenium.WebDriver#getWindowHandle()}, optional. *
79+ * @return The active session to use to communicate with the Chromium Developer Tools debugging protocol.
80+ */
81+ public DevTools getDevToolsSession (String windowHandle ) {
82+ logger .info ("loc.browser.devtools.session.get" , windowHandle );
2783 getDevTools ().createSessionIfThereIsNotOne (windowHandle );
2884 return session ;
2985 }
3086
31- public EmulationTools emulation () {
32- return new EmulationTools (getSession ());
87+ /**
88+ * Closes a DevTools session.
89+ */
90+ public void closeDevToolsSession () {
91+ logger .info ("loc.browser.devtools.session.close" );
92+ getDevTools ().disconnectSession ();
3393 }
3494
95+ /**
96+ * Executes a custom Chromium Dev Tools Protocol Command.
97+ * Note: works only if current driver is instance of {@link ChromiumDriver}.
98+ * @param commandName Name of the command to execute.
99+ * @param commandParameters Parameters of the command to execute.
100+ * @return An object representing the result of the command, if applicable.
101+ */
102+ public Map <String , Object > executeCdpCommand (String commandName , Map <String , Object > commandParameters ) {
103+ if (devToolsProvider instanceof ChromiumDriver ) {
104+ logCommand (commandName , commandParameters );
105+ ChromiumDriver driver = (ChromiumDriver ) devToolsProvider ;
106+ Map <String , Object > result = driver .executeCdpCommand (commandName , commandParameters );
107+ logCommandResult (result );
108+ return result ;
109+ }
110+ else {
111+ throw new NotImplementedException ("Execution of CDP command directly is not supported for current browser. Try sendCommand method instead." );
112+ }
113+ }
114+
115+ /**
116+ * Sends the specified command and returns the associated command response.
117+ * @param command An instance of the {@link Command} to send.
118+ * @param <X> The type of the command's result. For most commands it's {@link Void}
119+ * @return the result of the command, if applicable
120+ */
121+ public <X > X sendCommand (Command <X > command ) {
122+ logCommand (command .getMethod (), command .getParams ());
123+ X result = getDevToolsSession ().send (command );
124+ logCommandResult (result );
125+ return result ;
126+ }
127+
128+ /**
129+ * Adds a listener for a specific event with the handler for it.
130+ * @param event Event to listen for
131+ * @param handler Handler to call
132+ * @param <X> The type of the event's result.
133+ */
134+ public <X > void addListener (Event <X > event , Consumer <X > handler ) {
135+ logger .info ("loc.browser.devtools.listener.add" , event .getMethod ());
136+ getDevToolsSession ().addListener (event , handler );
137+ }
138+
139+ /**
140+ * Removes all the listeners, and disables all the domains.
141+ */
142+ public void clearListeners () {
143+ logger .info ("loc.browser.devtools.listener.clear" );
144+ getDevToolsSession ().clearListeners ();
145+ }
146+
147+ /**
148+ * Version-independent emulation DevTools commands.
149+ * @return an instance of {@link EmulationHandling}.
150+ */
151+ public EmulationHandling emulation () {
152+ if (emulation == null ) {
153+ emulation = new EmulationHandling (this );
154+ }
155+ return emulation ;
156+ }
157+
158+ /**
159+ * DevTools commands for network requests interception.
160+ * @return an instance of {@link NetworkHandling}.
161+ */
35162 public NetworkHandling network () {
36- return new NetworkHandling (getSession ());
163+ if (network == null ) {
164+ network = new NetworkHandling (this );
165+ }
166+ return network ;
37167 }
38168}
0 commit comments