Skip to content
This repository was archived by the owner on Mar 25, 2025. It is now read-only.

Commit d7a9c4f

Browse files
committed
Refactored Mouse API to follow similar principles as the Wait API
- makes it much more flexible - makes it much more testable - DefaultMouseDriver is integration tested because of used Selenium classes
1 parent 46ef461 commit d7a9c4f

File tree

14 files changed

+1105
-290
lines changed

14 files changed

+1105
-290
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package info.novatec.testit.webtester.mouse;
2+
3+
import static info.novatec.testit.webtester.conditions.Conditions.visible;
4+
5+
import java.util.Arrays;
6+
import java.util.Collection;
7+
import java.util.function.BiFunction;
8+
9+
import org.openqa.selenium.TimeoutException;
10+
import org.openqa.selenium.WebElement;
11+
import org.openqa.selenium.interactions.Actions;
12+
13+
import info.novatec.testit.webtester.events.pagefragments.ClickedEvent;
14+
import info.novatec.testit.webtester.events.pagefragments.ContextClickedEvent;
15+
import info.novatec.testit.webtester.events.pagefragments.DoubleClickedEvent;
16+
import info.novatec.testit.webtester.internal.ActionTemplate;
17+
import info.novatec.testit.webtester.pagefragments.PageFragment;
18+
import info.novatec.testit.webtester.waiting.Wait;
19+
20+
21+
/**
22+
* The default implementation of a {@link MouseDriver}.
23+
*
24+
* @since 2.0
25+
*/
26+
public class DefaultMouseDriver implements MouseDriver {
27+
28+
@Override
29+
public void click(PageFragment fragment) {
30+
ActionTemplate.pageFragment(fragment)
31+
.execute((f) -> perform(f, Actions::click))
32+
.fireEvent(ClickedEvent::new)
33+
.markAsUsed();
34+
}
35+
36+
@Override
37+
public void doubleClick(PageFragment fragment) {
38+
ActionTemplate.pageFragment(fragment)
39+
.execute((f) -> perform(f, Actions::doubleClick))
40+
.fireEvent(DoubleClickedEvent::new)
41+
.markAsUsed();
42+
}
43+
44+
@Override
45+
public void contextClick(PageFragment fragment) {
46+
ActionTemplate.pageFragment(fragment)
47+
.execute((f) -> perform(f, Actions::contextClick))
48+
.fireEvent(ContextClickedEvent::new)
49+
.markAsUsed();
50+
}
51+
52+
@Override
53+
public void moveToEach(PageFragment fragment, PageFragment... fragments) throws TimeoutException {
54+
moveTo(fragment);
55+
moveToEach(Arrays.asList(fragments));
56+
}
57+
58+
@Override
59+
public void moveToEach(Collection<PageFragment> fragments) throws TimeoutException {
60+
fragments.forEach(this::moveTo);
61+
}
62+
63+
@Override
64+
public void moveTo(PageFragment fragment) throws TimeoutException {
65+
ActionTemplate.pageFragment(fragment).execute((f) -> {
66+
Wait.until(f).is(visible());
67+
perform(f, Actions::moveToElement);
68+
});
69+
}
70+
71+
private void perform(PageFragment fragment, BiFunction<Actions, WebElement, Actions> biConsumer) {
72+
biConsumer.apply(sequenceFor(fragment), fragment.webElement()).perform();
73+
}
74+
75+
private Actions sequenceFor(PageFragment fragment) {
76+
return new Actions(fragment.getBrowser().webDriver());
77+
}
78+
79+
}

webtester-core/src/main/java/info/novatec/testit/webtester/mouse/Mouse.java

Lines changed: 30 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,42 @@
11
package info.novatec.testit.webtester.mouse;
22

3-
import static info.novatec.testit.webtester.conditions.Conditions.visible;
4-
5-
import java.util.Arrays;
63
import java.util.Collection;
7-
import java.util.function.BiFunction;
4+
import java.util.function.Supplier;
85

96
import org.openqa.selenium.TimeoutException;
107
import org.openqa.selenium.WebDriver;
118
import org.openqa.selenium.WebElement;
129
import org.openqa.selenium.interactions.Actions;
1310

14-
import com.google.common.annotations.Beta;
11+
import lombok.Setter;
1512

1613
import info.novatec.testit.webtester.events.pagefragments.ClickedEvent;
1714
import info.novatec.testit.webtester.events.pagefragments.ContextClickedEvent;
1815
import info.novatec.testit.webtester.events.pagefragments.DoubleClickedEvent;
19-
import info.novatec.testit.webtester.events.pagefragments.DraggedAndDroppedEvent;
20-
import info.novatec.testit.webtester.internal.ActionTemplate;
2116
import info.novatec.testit.webtester.pagefragments.PageFragment;
22-
import info.novatec.testit.webtester.waiting.Wait;
2317

2418

2519
/**
2620
* This class is used to perform a variety of mouse related actions.
2721
*
28-
* @see MouseOnAction
29-
* @see MouseDragAction
30-
* @see MouseActionSequence
22+
* @see OnPageFragment
23+
* @see Sequence
3124
* @since 2.0
3225
*/
3326
public final class Mouse {
3427

35-
/* click with mouse */
28+
/** The default {@link MouseDriver} supplier. Generates a new {@link DefaultMouseDriver} for each call. */
29+
public static final Supplier<MouseDriver> DEFAULT_MOUSE_DRIVER = DefaultMouseDriver::new;
30+
31+
/**
32+
* A supplier used to get a {@link MouseDriver} instance to use when executing any operations.
33+
* The supplier can be changed externally to customize the behavior.
34+
* Since this is a static field you should keep in mind that this will have an JVM global effect!
35+
* <p>
36+
* The default supplier is {@link #DEFAULT_MOUSE_DRIVER}.
37+
*/
38+
@Setter
39+
private static Supplier<MouseDriver> mouseDriver = DEFAULT_MOUSE_DRIVER;
3640

3741
/**
3842
* Executes a single-click on the given {@link PageFragment page fragment}.
@@ -47,11 +51,7 @@ public final class Mouse {
4751
* @since 2.0
4852
*/
4953
public static void click(PageFragment fragment) {
50-
ActionTemplate.pageFragment(fragment).execute(Mouse::doClick).fireEvent(ClickedEvent::new).markAsUsed();
51-
}
52-
53-
private static void doClick(PageFragment fragment) {
54-
perform(fragment, Actions::click);
54+
mouseDriver.get().click(fragment);
5555
}
5656

5757
/**
@@ -67,11 +67,7 @@ private static void doClick(PageFragment fragment) {
6767
* @since 2.0
6868
*/
6969
public static void doubleClick(PageFragment fragment) {
70-
ActionTemplate.pageFragment(fragment).execute(Mouse::doDoubleClick).fireEvent(DoubleClickedEvent::new).markAsUsed();
71-
}
72-
73-
private static void doDoubleClick(PageFragment fragment) {
74-
perform(fragment, Actions::doubleClick);
70+
mouseDriver.get().doubleClick(fragment);
7571
}
7672

7773
/**
@@ -87,18 +83,9 @@ private static void doDoubleClick(PageFragment fragment) {
8783
* @since 2.0
8884
*/
8985
public static void contextClick(PageFragment fragment) {
90-
ActionTemplate.pageFragment(fragment)
91-
.execute(Mouse::doContextClick)
92-
.fireEvent(ContextClickedEvent::new)
93-
.markAsUsed();
94-
}
95-
96-
private static void doContextClick(PageFragment fragment) {
97-
perform(fragment, Actions::contextClick);
86+
mouseDriver.get().contextClick(fragment);
9887
}
9988

100-
/* move mouse */
101-
10289
/**
10390
* Moves the mouse to each of the given {@link PageFragment page fragments} in the order they are given.
10491
* <p>
@@ -116,8 +103,7 @@ private static void doContextClick(PageFragment fragment) {
116103
* @since 2.0
117104
*/
118105
public static void moveToEach(PageFragment fragment, PageFragment... fragments) throws TimeoutException {
119-
moveTo(fragment);
120-
moveToEach(Arrays.asList(fragments));
106+
mouseDriver.get().moveToEach(fragment, fragments);
121107
}
122108

123109
/**
@@ -136,7 +122,7 @@ public static void moveToEach(PageFragment fragment, PageFragment... fragments)
136122
* @since 2.0
137123
*/
138124
public static void moveToEach(Collection<PageFragment> fragments) throws TimeoutException {
139-
fragments.forEach(Mouse::moveTo);
125+
mouseDriver.get().moveToEach(fragments);
140126
}
141127

142128
/**
@@ -156,83 +142,28 @@ public static void moveToEach(Collection<PageFragment> fragments) throws Timeout
156142
* @since 2.0
157143
*/
158144
public static void moveTo(PageFragment fragment) throws TimeoutException {
159-
ActionTemplate.pageFragment(fragment).execute(Mouse::doMoveTo);
160-
}
161-
162-
private static void doMoveTo(PageFragment fragment) {
163-
Wait.until(fragment).is(visible());
164-
perform(fragment, Actions::moveToElement);
165-
}
166-
167-
/* drag and drop */
168-
169-
/**
170-
* Drags the given source {@link PageFragment page fragment} onto the given target {@link PageFragment page fragment}.
171-
* Fires a {@link DraggedAndDroppedEvent}.
172-
* <p>
173-
* The actual behavior might vary between different {@link WebDriver} implementations. Some implementations might move
174-
* the actual mouse cursor, some might simulate the behavior.
175-
* <p>
176-
* This might not work with all drivers!
177-
*
178-
* @param sourceFragment the fragment being dragged
179-
* @param targetFragment the fragment the source is dragged onto
180-
* @see PageFragment
181-
* @see Actions#dragAndDrop(WebElement, WebElement)
182-
* @since 2.0
183-
*/
184-
@Beta
185-
public static void dragAndDrop(PageFragment sourceFragment, PageFragment targetFragment) {
186-
ActionTemplate.pageFragments(sourceFragment, targetFragment)
187-
.execute(Mouse::doDragAndDrop)
188-
.fireEvent(DraggedAndDroppedEvent::new)
189-
.markAsUsed();
190-
}
191-
192-
private static void doDragAndDrop(PageFragment sourceFragment, PageFragment targetFragment) {
193-
sequenceFor(sourceFragment).dragAndDrop(sourceFragment.webElement(), targetFragment.webElement()).perform();
194-
}
195-
196-
private static void perform(PageFragment fragment, BiFunction<Actions, WebElement, Actions> biConsumer) {
197-
biConsumer.apply(sequenceFor(fragment), fragment.webElement()).perform();
198-
}
199-
200-
private static Actions sequenceFor(PageFragment fragment) {
201-
return new Actions(fragment.getBrowser().webDriver());
202-
}
203-
204-
/* fluent API factories */
205-
206-
/**
207-
* Creates a new {@link MouseOnAction} for the given {@link PageFragment}.
208-
*
209-
* @param fragment the page fragment to use
210-
* @return the created action
211-
* @since 2.0
212-
*/
213-
public static MouseOnAction on(PageFragment fragment) {
214-
return new MouseOnAction(fragment);
145+
mouseDriver.get().moveTo(fragment);
215146
}
216147

217148
/**
218-
* Creates a new {@link MouseDragAction} for the given {@link PageFragment}.
149+
* Creates a new {@link OnPageFragment} for the given {@link PageFragment}.
219150
*
220151
* @param fragment the page fragment to use
221-
* @return the created action
152+
* @return the new instance
222153
* @since 2.0
223154
*/
224-
public static MouseDragAction drag(PageFragment fragment) {
225-
return new MouseDragAction(fragment);
155+
public static OnPageFragment on(PageFragment fragment) {
156+
return new OnPageFragment(mouseDriver.get(), fragment);
226157
}
227158

228159
/**
229-
* Creates a new {@link MouseActionSequence}.
160+
* Creates a new {@link Sequence}.
230161
*
231-
* @return the created action
162+
* @return the new instance
232163
* @since 2.0
233164
*/
234-
public static MouseActionSequence sequence() {
235-
return new MouseActionSequence();
165+
public static Sequence sequence() {
166+
return new Sequence(mouseDriver.get());
236167
}
237168

238169
private Mouse() {

0 commit comments

Comments
 (0)