Skip to content

Commit e59afe5

Browse files
authored
Implement native scroll actions (#142) +semver: feature
- cover with tests - replace js references with native actions in pre-existing methods - add localization values for scrolling actions - refactor MouseActions - Update to Selenium 4.23.0
1 parent e9892f6 commit e59afe5

File tree

15 files changed

+167
-34
lines changed

15 files changed

+167
-34
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
<dependency>
8383
<groupId>com.github.aquality-automation</groupId>
8484
<artifactId>aquality-selenium-core</artifactId>
85-
<version>4.0.3</version>
85+
<version>4.0.4</version>
8686
</dependency>
8787
<dependency>
8888
<groupId>org.apache.commons</groupId>

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import org.openqa.selenium.*;
1313
import org.openqa.selenium.WebDriver.Navigation;
1414
import org.openqa.selenium.devtools.HasDevTools;
15+
import org.openqa.selenium.interactions.Actions;
16+
import org.openqa.selenium.interactions.WheelInput.ScrollOrigin;
1517
import org.openqa.selenium.logging.LogEntries;
1618
import org.openqa.selenium.remote.Augmenter;
1719
import org.openqa.selenium.remote.RemoteWebDriver;
@@ -352,9 +354,32 @@ public void handlePromptAlert(AlertActions alertAction, String text) {
352354
* @param y coordinate y
353355
*/
354356
public void scrollWindowBy(int x, int y) {
357+
localizedLogger.info("loc.scrolling.by", x, y);
358+
new Actions(getDriver()).scrollByAmount(x, y).perform();
359+
}
360+
361+
/**
362+
* Executes scrolling of the page to given coordinates x and y using JavaScript.
363+
*
364+
* @param x coordinate x
365+
* @param y coordinate y
366+
*/
367+
public void scrollWindowByViaJs(int x, int y) {
368+
localizedLogger.info("loc.scrolling.by.js", x, y);
355369
executeScript(JavaScript.SCROLL_WINDOW_BY.getScript(), x, y);
356370
}
357371

372+
/**
373+
* Scrolls portion of screen from specified origin.
374+
*
375+
* @param scrollOrigin Origination point (either viewport or element, with possible offset)
376+
* @param x coordinate x
377+
* @param y coordinate y
378+
*/
379+
public void scrollFromOrigin(ScrollOrigin scrollOrigin, int x, int y) {
380+
new Actions(getDriver()).scrollFromOrigin(scrollOrigin, x, y).perform();
381+
}
382+
358383
/**
359384
* Sets given window size
360385
*

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public void scrollIntoView() {
9292
* @param y vertical coordinate
9393
*/
9494
public void scrollBy(int x, int y) {
95-
logElementAction("loc.scrolling.js");
95+
logElementAction("loc.scrolling.by.js", x, y);
9696
executeScript(JavaScript.SCROLL_BY, x, y);
9797
}
9898

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,123 @@
11
package aquality.selenium.elements.actions;
22

33
import aquality.selenium.browser.AqualityServices;
4+
import aquality.selenium.core.localization.ILocalizedLogger;
45
import aquality.selenium.core.utilities.IElementActionRetrier;
56
import aquality.selenium.elements.interfaces.IElement;
7+
import org.openqa.selenium.WebElement;
68
import org.openqa.selenium.interactions.Actions;
9+
import org.openqa.selenium.interactions.WheelInput.ScrollOrigin;
710

8-
import java.util.function.UnaryOperator;
11+
import java.util.function.BiFunction;
912

1013
import static aquality.selenium.browser.AqualityServices.getBrowser;
1114

1215
public class MouseActions {
1316
private final IElement element;
1417
private final String type;
1518
private final String name;
19+
private final ILocalizedLogger logger;
20+
private final IElementActionRetrier elementActionRetrier;
1621

1722
public MouseActions(IElement element, String type) {
1823
this.element = element;
1924
this.type = type;
2025
this.name = element.getName();
26+
this.logger = AqualityServices.getLocalizedLogger();
27+
this.elementActionRetrier = AqualityServices.get(IElementActionRetrier.class);
2128
}
2229

2330
/**
2431
* Click via Action.
2532
*/
2633
public void click() {
27-
infoLoc("loc.clicking");
34+
logElementAction("loc.clicking");
2835
new JsActions(element, type).highlightElement();
29-
performAction(Actions::click);
36+
performActionAfterMove((elem, actions) -> actions.click());
3037
}
3138

3239
/**
3340
* Click Right (calls context menu) on the element
3441
*/
3542
public void rightClick() {
36-
infoLoc("loc.clicking.right");
37-
performAction(actions -> actions.contextClick(element.getElement()));
43+
logElementAction("loc.clicking.right");
44+
performActionAfterMove((elem, actions) -> actions.contextClick(elem));
45+
}
46+
47+
/**
48+
* Scrolling to element
49+
*/
50+
public void scrollToElement() {
51+
logElementAction("loc.scrolling");
52+
performAction((elem, actions) -> actions.scrollToElement(elem));
53+
}
54+
55+
/**
56+
* Scrolling by coordinates
57+
*
58+
* @param x horizontal coordinate
59+
* @param y vertical coordinate
60+
*/
61+
public void scrollFromOrigin(int x, int y) {
62+
scrollFromOrigin(x, y, 0, 0);
63+
}
64+
65+
/**
66+
* Scrolling by coordinates
67+
*
68+
* @param x horizontal coordinate
69+
* @param y vertical coordinate
70+
* @param xOffset horizontal offset
71+
* @param yOffset vertical offset
72+
*/
73+
public void scrollFromOrigin(int x, int y, int xOffset, int yOffset)
74+
{
75+
logElementAction("loc.scrolling.by", x, y);
76+
elementActionRetrier.doWithRetry(() -> {
77+
ScrollOrigin scrollOrigin = ScrollOrigin.fromElement(element.getElement(), xOffset, yOffset);
78+
getBrowser().scrollFromOrigin(scrollOrigin, x, y);
79+
});
3880
}
3981

4082
/**
4183
* Move mouse to this element.
4284
*/
4385
public void moveMouseToElement() {
44-
infoLoc("loc.moving");
45-
performAction(actions -> actions);
86+
logElementAction("loc.moving");
87+
performActionAfterMove((elem, actions) -> actions);
4688
}
4789

4890
/**
4991
* Move mouse from this element.
5092
*/
5193
public void moveMouseFromElement() {
52-
infoLoc("loc.movingFrom");
53-
AqualityServices.get(IElementActionRetrier.class).doWithRetry(() ->
54-
new Actions(getBrowser().getDriver())
55-
.moveToElement(element.getElement(), -element.getElement().getSize().width, -element.getElement().getSize().height)
56-
.build().perform());
94+
logElementAction("loc.movingFrom");
95+
performAction(((elem, actions) -> actions.moveToElement(elem, elem.getSize().width, elem.getSize().height)));
5796
}
5897

5998
/**
6099
* Performs double-click on the element.
61100
*/
62101
public void doubleClick() {
63-
infoLoc("loc.clicking.double");
64-
performAction(actions -> actions.doubleClick(element.getElement()));
102+
logElementAction("loc.clicking.double");
103+
performActionAfterMove((elem, actions) -> actions.doubleClick(elem));
104+
}
105+
106+
private void performActionAfterMove(BiFunction<WebElement, Actions, Actions> function) {
107+
performAction((elem, actions) -> function.apply(elem, actions.moveToElement(elem)));
65108
}
66109

67-
private void performAction(UnaryOperator<Actions> function) {
68-
Actions actions = new Actions(getBrowser().getDriver()).moveToElement(element.getElement());
69-
AqualityServices.get(IElementActionRetrier.class).doWithRetry(() ->
70-
function.apply(actions).build().perform());
110+
private void performAction(BiFunction<WebElement, Actions, Actions> action) {
111+
elementActionRetrier.doWithRetry(() -> action.apply(element.getElement(), new Actions(getBrowser().getDriver())).perform());
71112
}
72113

73114
/**
74115
* The implementation of a method for logging of MouseActions
75116
*
76-
* @param key key in localization resource of message to display in the log.
117+
* @param key key in localization resource of message to display in the log.
118+
* @param args Arguments, which will be provided to template of localized message.
77119
*/
78-
private void infoLoc(String key) {
79-
AqualityServices.getLocalizedLogger().infoElementAction(type, name, key);
120+
private void logElementAction(String key, Object... args) {
121+
logger.infoElementAction(type, name, key, args);
80122
}
81123
}

src/main/java/aquality/selenium/forms/Form.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ public IElementStateProvider state() {
7171
* @param y vertical coordinate
7272
*/
7373
public void scrollBy(int x, int y) {
74+
getFormLabel().getMouseActions().scrollFromOrigin(x, y);
75+
}
76+
77+
/**
78+
* Scroll form via JavaScript without scrolling entire page
79+
*
80+
* @param x horizontal coordinate
81+
* @param y vertical coordinate
82+
*/
83+
public void scrollByJs(int x, int y) {
7484
getFormLabel().getJsActions().scrollBy(x, y);
7585
}
7686

src/main/resources/localization/be.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@
7070
"loc.movingFrom": "Адводзім курсор мышы ад элемента",
7171
"loc.radio": "Радыёкнопка",
7272
"loc.scrolling.center.js": "Пракручваем старонку да цэнтра элемента праз JavaScript",
73-
"loc.scrolling.js": "Пракручваем старонку праз JavaScript",
73+
"loc.scrolling.js": "Пракручваем старонку да элемента праз JavaScript",
74+
"loc.scrolling": "Пракручваем старонку да элемента",
75+
"loc.scrolling.by": "Пракручваем на (%s,%s)",
76+
"loc.scrolling.by.js": "Пракручваем на (%s,%s) праз JavaScript",
7477
"loc.selecting.value": "Выбіраем значэнне - '%s'",
7578
"loc.deselecting.value": "Адмяняем выбар значэння - '%s'",
7679
"loc.send.text": "Задаем тэкст - '%s'",

src/main/resources/localization/en.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@
7070
"loc.movingFrom": "Moving mouse from element",
7171
"loc.radio": "RadioButton",
7272
"loc.scrolling.center.js": "Scrolling to the center via JavaScript",
73-
"loc.scrolling.js": "Scrolling via JavaScript",
73+
"loc.scrolling.js": "Scrolling to element via JavaScript",
74+
"loc.scrolling": "Scrolling to element",
75+
"loc.scrolling.by": "Scrolling by (%s,%s)",
76+
"loc.scrolling.by.js": "Scrolling by (%s,%s) via JavaScript",
7477
"loc.selecting.value": "Selecting value - '%s'",
7578
"loc.deselecting.value": "Deselecting value - '%s'",
7679
"loc.send.text": "Setting text - '%s'",

src/main/resources/localization/pl.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@
7070
"loc.movingFrom": "Przesuwanie myszy z elementu",
7171
"loc.radio": "RadioButton",
7272
"loc.scrolling.center.js": "Przewijanie do centrum przez JavaScript",
73-
"loc.scrolling.js": "Przewijanie przez JavaScript",
73+
"loc.scrolling.js": "Przewijanie do elementu przez JavaScript",
74+
"loc.scrolling": "Przewijanie do elementu",
75+
"loc.scrolling.by": "Przewijanie o (%s,%s)",
76+
"loc.scrolling.by.js": "Przewijanie o (%s,%s) przez JavaScript",
7477
"loc.selecting.value": "Wybieranie wartości - '%s'",
7578
"loc.deselecting.value": "Anulowanie wybierania wartości - '%s'",
7679
"loc.send.text": "Ustawianie tekstu - '%s'",

src/main/resources/localization/ru.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@
7070
"loc.movingFrom": "Сдвиг курсора с элемента",
7171
"loc.radio": "Радиокнопка",
7272
"loc.scrolling.center.js": "Скроллинг в центр (посредством JavaScript)",
73-
"loc.scrolling.js": "Скроллинг посредством JavaScript",
73+
"loc.scrolling.js": "Скроллинг к элементу (посредством JavaScript)",
74+
"loc.scrolling": "Скроллинг к элементу",
75+
"loc.scrolling.by": "Скроллинг на (%s,%s)",
76+
"loc.scrolling.by.js": "Скроллинг на (%s,%s) посредством JavaScript",
7477
"loc.selecting.value": "Выбор значения - '%s'",
7578
"loc.deselecting.value": "Отмена выбора значения - '%s'",
7679
"loc.send.text": "Ввод текста - '%s'",

src/main/resources/localization/uk.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@
7070
"loc.movingFrom": "Переміщення миші від елемента",
7171
"loc.radio": "Радіокнопка",
7272
"loc.scrolling.center.js": "Прокрутка до центру за допомогою JavaScript",
73-
"loc.scrolling.js": "Прокрутка за допомогою JavaScript",
73+
"loc.scrolling.js": "Прокрутка до елемента за допомогою JavaScript",
74+
"loc.scrolling": "Прокрутка до елемента",
75+
"loc.scrolling.by": "Прокрутка на (%s,%s)",
76+
"loc.scrolling.by.js": "Прокрутка на (%s,%s) за допомогою JavaScript",
7477
"loc.selecting.value": "Вибір значення - '%s'",
7578
"loc.deselecting.value": "Скасування выбору значення - '%s'",
7679
"loc.send.text": "Встановлення тексту - '%s'",

0 commit comments

Comments
 (0)