Skip to content

Commit 8884811

Browse files
committed
Implemented tests for Dom monitoring, pinned scripts and initialization scripts. Implemented additional methods to pin scripts, execute pinned scripts and set attribute value. Reworked JsActions parameters resolving. Fixed removing of initialization script. Add more NetworkInterceptionTests examples.
Add tests to the test suite
1 parent 213a1d6 commit 8884811

File tree

18 files changed

+435
-32
lines changed

18 files changed

+435
-32
lines changed

src/main/java/aquality/selenium/browser/Browser.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,17 @@ public Object executeScript(final String script, Object... arguments) {
265265
return executeJavaScript(() -> getDriver().executeScript(script, arguments));
266266
}
267267

268+
/**
269+
* Executes JS (jQuery) script.
270+
*
271+
* @param script Script pinned with {@link this#javaScriptEngine()}.
272+
* @param arguments Arguments for the script (web elements, values etc.
273+
* @return Result object of script execution
274+
*/
275+
public Object executeScript(final ScriptKey script, Object... arguments) {
276+
return executeJavaScript(() -> getDriver().executeScript(script, arguments));
277+
}
278+
268279
private Object executeJavaScript(Supplier<Object> executeScriptFunc) {
269280
Object result = executeScriptFunc.get();
270281
return result instanceof Boolean ? Boolean.parseBoolean(result.toString()) : result;

src/main/java/aquality/selenium/browser/JavaScript.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public enum JavaScript {
3333
SELECT_COMBOBOX_VALUE_BY_TEXT("selectComboboxValueByText.js"),
3434
SET_FOCUS("setFocus.js"),
3535
SET_VALUE("setValue.js"),
36+
SET_ATTRIBUTE("setAttribute.js"),
3637
SCROLL_BY("scrollBy.js"),
3738
IS_PAGE_LOADED("isPageLoaded.js"),
3839
SCROLL_WINDOW_BY("scrollWindowBy.js"),

src/main/java/aquality/selenium/browser/devtools/JavaScriptHandling.java

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,22 @@
44
import aquality.selenium.core.localization.ILocalizedLogger;
55
import org.apache.commons.lang3.NotImplementedException;
66
import org.openqa.selenium.JavascriptException;
7+
import org.openqa.selenium.JavascriptExecutor;
8+
import org.openqa.selenium.ScriptKey;
79
import org.openqa.selenium.WebDriver;
810
import org.openqa.selenium.devtools.events.ConsoleEvent;
911
import org.openqa.selenium.devtools.events.DomMutationEvent;
1012
import org.openqa.selenium.devtools.idealized.Events;
1113
import org.openqa.selenium.devtools.idealized.Javascript;
1214
import org.openqa.selenium.devtools.idealized.ScriptId;
1315
import org.openqa.selenium.devtools.v85.page.Page;
16+
import org.openqa.selenium.devtools.v85.page.model.ScriptIdentifier;
1417
import org.openqa.selenium.devtools.v85.runtime.Runtime;
1518
import org.openqa.selenium.logging.EventType;
1619
import org.openqa.selenium.logging.HasLogEvents;
1720
import org.openqa.selenium.remote.Augmenter;
1821

22+
import java.lang.reflect.Field;
1923
import java.util.*;
2024
import java.util.function.Consumer;
2125

@@ -102,15 +106,28 @@ public InitializationScript addInitializationScript(String scriptName, String sc
102106
return initializationScript;
103107
}
104108

109+
private void removeInitializationScriptCore(InitializationScript script) {
110+
tools.sendCommand(Page.removeScriptToEvaluateOnNewDocument(new ScriptIdentifier(script.getScriptId().getActualId().toString())));
111+
try {
112+
final Field pinnedScripts = Javascript.class.getDeclaredField("pinnedScripts");
113+
pinnedScripts.setAccessible(true);
114+
//noinspection unchecked
115+
((Map<String, ScriptId>)pinnedScripts.get(engine)).remove(script.getScriptSource());
116+
pinnedScripts.setAccessible(false);
117+
} catch (ReflectiveOperationException e) {
118+
AqualityServices.getLogger().fatal("Error while removing initialization script", e);
119+
}
120+
initializationScripts.remove(script);
121+
removeScriptCallbackBinding(script.getScriptName());
122+
}
123+
105124
/**
106125
* Removes JavaScript from being loaded on every document load, and removes a callback binding for it.
107126
* @param script an instance of script to be removed.
108127
*/
109128
public void removeInitializationScript(InitializationScript script) {
110129
logger.info("loc.browser.javascript.initializationscript.remove", script.getScriptName());
111-
tools.sendCommand(Page.removeScriptToEvaluateOnNewDocument(script.getScriptId().getActualId()));
112-
initializationScripts.remove(script);
113-
removeScriptCallbackBinding(script.getScriptName());
130+
removeInitializationScriptCore(script);
114131
}
115132

116133
/**
@@ -127,12 +144,47 @@ public List<InitializationScript> getInitializationScripts() {
127144
*/
128145
public void clearInitializationScripts() {
129146
logger.info("loc.browser.javascript.initializationscripts.clear");
130-
initializationScripts.forEach(script -> {
131-
Page.removeScriptToEvaluateOnNewDocument(script.getScriptId().getActualId());
132-
initializationScripts.remove(script);
133-
tools.sendCommand(Runtime.removeBinding(script.getScriptName()));
134-
bindings.remove(script.getScriptName());
135-
});
147+
initializationScripts.forEach(this::removeInitializationScriptCore);
148+
}
149+
150+
private JavascriptExecutor getJavascriptExecutor() {
151+
return (JavascriptExecutor) tools.getDevToolsProvider();
152+
}
153+
154+
/**
155+
* Pins a JavaScript snippet for execution in the browser without transmitting the entire script across the wire for every execution.
156+
* @param script The JavaScript to pin.
157+
* @return object to use to execute the script.
158+
*/
159+
public ScriptKey pinScript(String script) {
160+
logger.info("loc.browser.javascript.snippet.pin");
161+
return getJavascriptExecutor().pin(script);
162+
}
163+
164+
/**
165+
* Unpins a previously pinned script from the browser.
166+
* @param pinnedScript The {@link ScriptKey} object to unpin.
167+
*/
168+
public void unpinScript(ScriptKey pinnedScript) {
169+
logger.info("loc.browser.javascript.snippet.unpin");
170+
getJavascriptExecutor().unpin(pinnedScript);
171+
}
172+
173+
/**
174+
* Gets list of previously pinned scripts.
175+
* @return a list of previously pinned scripts.
176+
*/
177+
public Set<ScriptKey> getPinnedScripts() {
178+
logger.info("loc.browser.javascript.snippets.get");
179+
return getJavascriptExecutor().getPinnedScripts();
180+
}
181+
182+
/**
183+
* Unpins previously pinned scripts from being loaded on every document load.
184+
*/
185+
public void clearPinnedScripts() {
186+
logger.info("loc.browser.javascript.snippets.clear");
187+
getJavascriptExecutor().getPinnedScripts().forEach(getJavascriptExecutor()::unpin);
136188
}
137189

138190
/**

src/main/java/aquality/selenium/elements/actions/CheckBoxJsActions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,6 @@ private void setState(boolean state) {
6060
* @return state of checkbox using .checked property of element
6161
*/
6262
private boolean getState() {
63-
return Boolean.valueOf(executeScript(JavaScript.GET_CHECKBOX_STATE, element).toString());
63+
return Boolean.parseBoolean(executeScript(JavaScript.GET_CHECKBOX_STATE).toString());
6464
}
6565
}

src/main/java/aquality/selenium/elements/actions/ComboBoxJsActions.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ public ComboBoxJsActions(IComboBox comboBox, String elementType) {
1717
*
1818
* @return texts of options from ComboBox
1919
*/
20+
@SuppressWarnings("unchecked")
2021
public List<String> getTexts() {
2122
logElementAction("loc.combobox.get.texts.js");
22-
List<String> values = (List<String>) executeScript(JavaScript.GET_COMBOBOX_TEXTS, element);
23+
List<String> values = (List<String>) executeScript(JavaScript.GET_COMBOBOX_TEXTS);
2324
logElementAction("loc.combobox.texts",
2425
values.stream().map(value -> String.format("'%s'", value)).collect(Collectors.joining(", ")));
2526
return values;
@@ -32,7 +33,7 @@ public List<String> getTexts() {
3233
*/
3334
public String getSelectedText() {
3435
logElementAction("loc.combobox.get.text.js");
35-
String text = (String) executeScript(JavaScript.GET_COMBOBOX_SELECTED_TEXT, element);
36+
String text = (String) executeScript(JavaScript.GET_COMBOBOX_SELECTED_TEXT);
3637
logElementAction("loc.combobox.selected.text", text);
3738
return text;
3839
}
@@ -44,6 +45,6 @@ public String getSelectedText() {
4445
*/
4546
public void selectValueByText(final String text) {
4647
logElementAction("loc.combobox.select.by.text.js", text);
47-
executeScript(JavaScript.SELECT_COMBOBOX_VALUE_BY_TEXT, element, text);
48+
executeScript(JavaScript.SELECT_COMBOBOX_VALUE_BY_TEXT, text);
4849
}
4950
}

src/main/java/aquality/selenium/elements/actions/JsActions.java

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
import aquality.selenium.elements.interfaces.IElement;
99
import aquality.selenium.elements.interfaces.IShadowRootExpander;
1010
import org.openqa.selenium.Point;
11+
import org.openqa.selenium.ScriptKey;
1112
import org.openqa.selenium.SearchContext;
1213

1314
import java.util.ArrayList;
15+
import java.util.Arrays;
1416
import java.util.List;
1517

1618
public class JsActions implements IShadowRootExpander {
@@ -28,7 +30,17 @@ public JsActions(IElement element, String type) {
2830
@Override
2931
public SearchContext expandShadowRoot() {
3032
logElementAction("loc.shadowroot.expand.js");
31-
return (SearchContext) executeScript(JavaScript.EXPAND_SHADOW_ROOT, element);
33+
return (SearchContext) executeScript(JavaScript.EXPAND_SHADOW_ROOT);
34+
}
35+
36+
/**
37+
* Setting attribute value.
38+
* @param name Attribute name
39+
* @param value Value to set
40+
*/
41+
public void setAttribute(String name, String value) {
42+
logElementAction("loc.el.attr.set", name, value);
43+
executeScript(JavaScript.SET_ATTRIBUTE, name, value);
3244
}
3345

3446
/**
@@ -37,7 +49,7 @@ public SearchContext expandShadowRoot() {
3749
public void click() {
3850
logElementAction("loc.clicking.js");
3951
highlightElement();
40-
executeScript(JavaScript.CLICK_ELEMENT, element);
52+
executeScript(JavaScript.CLICK_ELEMENT);
4153
}
4254

4355
/**
@@ -60,7 +72,7 @@ public void highlightElement() {
6072
*/
6173
public void highlightElement(HighlightState highlightState) {
6274
if (AqualityServices.getBrowserProfile().isElementHighlightEnabled() || highlightState.equals(HighlightState.HIGHLIGHT)) {
63-
executeScript(JavaScript.BORDER_ELEMENT, element);
75+
executeScript(JavaScript.BORDER_ELEMENT);
6476
}
6577
}
6678

@@ -69,7 +81,7 @@ public void highlightElement(HighlightState highlightState) {
6981
*/
7082
public void scrollIntoView() {
7183
logElementAction("loc.scrolling.js");
72-
executeScript(JavaScript.SCROLL_TO_ELEMENT, element, true);
84+
executeScript(JavaScript.SCROLL_TO_ELEMENT, true);
7385
}
7486

7587
/**
@@ -80,15 +92,15 @@ public void scrollIntoView() {
8092
*/
8193
public void scrollBy(int x, int y) {
8294
logElementAction("loc.scrolling.js");
83-
executeScript(JavaScript.SCROLL_BY, element, x, y);
95+
executeScript(JavaScript.SCROLL_BY, x, y);
8496
}
8597

8698
/**
8799
* Scrolling to element's center
88100
*/
89101
public void scrollToTheCenter() {
90102
logElementAction("loc.scrolling.center.js");
91-
executeScript(JavaScript.SCROLL_TO_ELEMENT_CENTER, element);
103+
executeScript(JavaScript.SCROLL_TO_ELEMENT_CENTER);
92104
}
93105

94106
/**
@@ -98,15 +110,15 @@ public void scrollToTheCenter() {
98110
*/
99111
public void setValue(final String value) {
100112
logElementAction("loc.setting.value", value);
101-
executeScript(JavaScript.SET_VALUE, element, value);
113+
executeScript(JavaScript.SET_VALUE, value);
102114
}
103115

104116
/**
105117
* Focusing element
106118
*/
107119
public void setFocus() {
108120
logElementAction("loc.focusing");
109-
executeScript(JavaScript.SET_FOCUS, element);
121+
executeScript(JavaScript.SET_FOCUS);
110122
}
111123

112124
/**
@@ -116,7 +128,7 @@ public void setFocus() {
116128
*/
117129
public boolean isElementOnScreen() {
118130
logElementAction("loc.is.present.js");
119-
boolean value = (boolean) executeScript(JavaScript.ELEMENT_IS_ON_SCREEN, element);
131+
boolean value = (boolean) executeScript(JavaScript.ELEMENT_IS_ON_SCREEN);
120132
logElementAction("loc.is.present.value", value);
121133
return value;
122134
}
@@ -128,15 +140,15 @@ public boolean isElementOnScreen() {
128140
*/
129141
public String getElementText() {
130142
logElementAction("loc.get.text.js");
131-
return (String) executeScript(JavaScript.GET_ELEMENT_TEXT, element);
143+
return (String) executeScript(JavaScript.GET_ELEMENT_TEXT);
132144
}
133145

134146
/**
135147
* Hover mouse over element
136148
*/
137149
public void hoverMouse() {
138150
logElementAction("loc.hover.js");
139-
executeScript(JavaScript.MOUSE_HOVER, element);
151+
executeScript(JavaScript.MOUSE_HOVER);
140152
}
141153

142154
/**
@@ -146,7 +158,7 @@ public void hoverMouse() {
146158
*/
147159
@SuppressWarnings("unchecked")
148160
public Point getViewPortCoordinates() {
149-
List<Number> coordinates = (ArrayList<Number>) executeScript(JavaScript.GET_VIEWPORT_COORDINATES, element);
161+
List<Number> coordinates = (ArrayList<Number>) executeScript(JavaScript.GET_VIEWPORT_COORDINATES);
150162
return new Point(Math.round(coordinates.get(0).floatValue()), Math.round(coordinates.get(1).floatValue()));
151163
}
152164

@@ -157,17 +169,38 @@ public Point getViewPortCoordinates() {
157169
*/
158170
public String getXPath() {
159171
logElementAction("loc.get.xpath.js");
160-
String value = (String) executeScript(JavaScript.GET_ELEMENT_XPATH, element);
172+
String value = (String) executeScript(JavaScript.GET_ELEMENT_XPATH);
161173
logElementAction("loc.xpath.value", value);
162174
return value;
163175
}
164176

165-
protected Object executeScript(JavaScript javaScript, IElement element) {
177+
private Object[] resolveArguments(Object... args) {
178+
List<Object> arguments = new ArrayList<>();
179+
arguments.add(element.getElement());
180+
arguments.addAll(Arrays.asList(args));
181+
return arguments.toArray();
182+
}
183+
184+
/**
185+
* Executes pinned JavaScript against the element and gets result value.
186+
* @param pinnedScript Instance of script pinned with {@link Browser#javaScriptEngine()}
187+
* @return Script execution result.
188+
*/
189+
public Object executeScript(ScriptKey pinnedScript, Object... args) {
190+
logElementAction("loc.el.execute.pinnedjs");
191+
Object result = getActionRetrier().doWithRetry(() -> getBrowser().executeScript(pinnedScript, resolveArguments(args)));
192+
if (result != null) {
193+
logElementAction("loc.el.execute.pinnedjs.result", result);
194+
}
195+
return result;
196+
}
197+
198+
protected Object executeScript(JavaScript javaScript) {
166199
return getActionRetrier().doWithRetry(() -> getBrowser().executeScript(javaScript, element.getElement()));
167200
}
168201

169-
protected Object executeScript(JavaScript javaScript, IElement element, Object... args) {
170-
return getActionRetrier().doWithRetry(() -> getBrowser().executeScript(javaScript, element.getElement(), args));
202+
protected Object executeScript(JavaScript javaScript, Object... args) {
203+
return getActionRetrier().doWithRetry(() -> getBrowser().executeScript(javaScript, resolveArguments(args)));
171204
}
172205

173206
/**
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
arguments[0].setAttribute(arguments[1], arguments[2]);

src/main/resources/localization/be.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@
4545
"loc.combobox.impossible.to.select.contain.value.or.text" : "Немагчыма выбраць опцыю, якая змяшчае значэнне/тэкст '%1$s' у камбабоксе '%2$s'",
4646
"loc.el.getattr" : "Атрымліваем атрыбут '%1$s'",
4747
"loc.el.attr.value": "Значэнне атрыбута '%1$s': [%2$s]",
48+
"loc.el.attr.set": "Задаем значэнне атрыбута '%1$s': [%2$s]",
4849
"loc.el.cssvalue" : "Атрымліваем значэнне css '%1$s'",
50+
"loc.el.execute.pinnedjs": "Выконваем замацаваны JavaScript",
51+
"loc.el.execute.pinnedjs.result": "Вынік выканання замацаванага JavaScript: [%1$s]",
4952
"loc.file.reading_exception" : "Памылка пры чытанні файла: '%s'",
5053
"loc.focusing" : "Факусуемся",
5154
"loc.get.text" : "Атрымліваем тэкст элемента",
@@ -117,6 +120,10 @@
117120
"loc.browser.javascript.scriptcallbackbinding.add": "Дадаем прывязку зваротнага выкліку JavaScript з іменем '%1$s'",
118121
"loc.browser.javascript.scriptcallbackbinding.remove": "Выдаляем прывязку зваротнага выкліку JavaScript з іменем '%1$s'",
119122
"loc.browser.javascript.scriptcallbackbindings.clear": "Выдаляем усе прывязкі зваротнага выкліку JavaScript",
123+
"loc.browser.javascript.snippet.pin": "Замацоўваем фрагмент JavaScript",
124+
"loc.browser.javascript.snippet.unpin": "Адмацоўваем фрагмент JavaScript",
125+
"loc.browser.javascript.snippets.get": "Атрымліваем замацаваныя фрагменты JavaScript",
126+
"loc.browser.javascript.snippets.clear": "Выдаляем усе замацаваныя фрагменты JavaScript",
120127
"loc.browser.javascript.clearall": "Выдаляем усе прывязкі зваротнага выкліку JavaScript і ініцыялізацыйныя скрыпты",
121128
"loc.browser.javascript.reset": "Выдаляем усе прывязкі зваротнага выкліку JavaScript і ініцыялізацыйныя скрыпты, і спыняем чаканне падзеяў",
122129
"loc.shadowroot.expand": "Разварочваем дрэва схаваных элементаў",

src/main/resources/localization/en.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@
4545
"loc.combobox.impossible.to.select.contain.value.or.text" : "It is impossible to select option that contains value/text '%1$s' from combobox '%2$s'",
4646
"loc.el.getattr" : "Getting attribute '%1$s'",
4747
"loc.el.attr.value": "Value of attribute '%1$s': [%2$s]",
48+
"loc.el.attr.set": "Setting value of attribute '%1$s': [%2$s]",
4849
"loc.el.cssvalue" : "Getting css value '%1$s'",
50+
"loc.el.execute.pinnedjs": "Executing pinned JavaScript",
51+
"loc.el.execute.pinnedjs.result": "Result of pinned JavaScript execution: [%1$s]",
4952
"loc.file.reading_exception" : "Exception while reading file: '%s'",
5053
"loc.focusing" : "Focusing",
5154
"loc.get.text" : "Getting text from element",
@@ -117,6 +120,10 @@
117120
"loc.browser.javascript.scriptcallbackbinding.add": "Adding JavaScript callback binding with the name '%1$s'",
118121
"loc.browser.javascript.scriptcallbackbinding.remove": "Removing JavaScript callback binding with the name '%1$s'",
119122
"loc.browser.javascript.scriptcallbackbindings.clear": "Removing all JavaScript callback bindings",
123+
"loc.browser.javascript.snippet.pin": "Pinning JavaScript snippet",
124+
"loc.browser.javascript.snippet.unpin": "Unpinning JavaScript snippet",
125+
"loc.browser.javascript.snippets.get": "Getting pinned JavaScript snippets",
126+
"loc.browser.javascript.snippets.clear": "Removing all pinned JavaScript snippets",
120127
"loc.browser.javascript.clearall": "Removing all JavaScript callback bindings and initialization JavaScripts",
121128
"loc.browser.javascript.reset": "Removing all JavaScript callback bindings and initialization JavaScripts, and stopping listening for events",
122129
"loc.shadowroot.expand": "Expanding the Shadow Root",

0 commit comments

Comments
 (0)