Skip to content

Commit 70e54e6

Browse files
titusfortnerdiemol
andauthored
[java] implement event support for pointer device actions (#10198)
Co-authored-by: Diego Molina <[email protected]>
1 parent 5fc8b53 commit 70e54e6

2 files changed

Lines changed: 155 additions & 5 deletions

File tree

java/src/org/openqa/selenium/interactions/PointerInput.java

Lines changed: 145 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717

1818
package org.openqa.selenium.interactions;
1919

20-
import static org.openqa.selenium.internal.Require.nonNegative;
21-
2220
import org.openqa.selenium.WebElement;
2321
import org.openqa.selenium.WrapsElement;
2422
import org.openqa.selenium.internal.Require;
@@ -29,6 +27,8 @@
2927
import java.util.Optional;
3028
import java.util.UUID;
3129

30+
import static org.openqa.selenium.internal.Require.nonNegative;
31+
3232
/**
3333
* Models a <a href="https://www.w3.org/TR/webdriver/#dfn-pointer-input-source">pointer input
3434
* source</a>.
@@ -71,18 +71,31 @@ public Interaction createPointerMove(Duration duration, Origin origin, int x, in
7171
return new Move(this, duration, origin, x, y);
7272
}
7373

74+
public Interaction createPointerMove(Duration duration, Origin origin, int x, int y, PointerEventProperties eventProperties) {
75+
return new Move(this, duration, origin, x, y, eventProperties);
76+
}
77+
7478
public Interaction createPointerDown(int button) {
7579
return new PointerPress(this, PointerPress.Direction.DOWN, button);
7680
}
7781

82+
public Interaction createPointerDown(PointerEventProperties eventProperties) {
83+
return new PointerPress(this, PointerPress.Direction.DOWN, eventProperties);
84+
}
85+
7886
public Interaction createPointerUp(int button) {
7987
return new PointerPress(this, PointerPress.Direction.UP, button);
8088
}
8189

90+
public Interaction createPointerUp(PointerEventProperties eventProperties) {
91+
return new PointerPress(this, PointerPress.Direction.UP, eventProperties);
92+
}
93+
8294
private static class PointerPress extends Interaction implements Encodable {
8395

8496
private final Direction direction;
8597
private final int button;
98+
private final PointerEventProperties eventProperties;
8699

87100
public PointerPress(InputSource source, Direction direction, int button) {
88101
super(source);
@@ -94,11 +107,19 @@ public PointerPress(InputSource source, Direction direction, int button) {
94107

95108
this.direction = Require.nonNull("Direction of move", direction);
96109
this.button = button;
110+
this.eventProperties = new PointerEventProperties();
111+
}
112+
113+
public PointerPress(InputSource source, Direction direction, PointerEventProperties eventProperties) {
114+
super(source);
115+
this.button = 0;
116+
this.eventProperties = Require.nonNull("pointer event properties", eventProperties);
117+
this.direction = Require.nonNull("Direction of press", direction);
97118
}
98119

99120
@Override
100121
public Map<String, Object> encode() {
101-
Map<String, Object> toReturn = new HashMap<>();
122+
Map<String, Object> toReturn = eventProperties.encode();
102123

103124
toReturn.put("type", direction.getType());
104125
toReturn.put("button", button);
@@ -128,19 +149,26 @@ private static class Move extends Interaction implements Encodable {
128149
private final int x;
129150
private final int y;
130151
private final Duration duration;
152+
private final PointerEventProperties eventProperties;
131153

132154
protected Move(
133155
InputSource source,
134156
Duration duration,
135157
Origin origin,
136158
int x,
137-
int y) {
159+
int y,
160+
PointerEventProperties eventProperties) {
138161
super(source);
139162

140163
this.origin = Require.nonNull("Origin of move", origin);
141164
this.x = x;
142165
this.y = y;
143166
this.duration = nonNegative(duration);
167+
this.eventProperties = Require.nonNull("pointer event properties", eventProperties);
168+
}
169+
170+
protected Move(PointerInput source, Duration duration, Origin origin, int x, int y) {
171+
this(source, duration, origin, x, y, new PointerEventProperties());
144172
}
145173

146174
@Override
@@ -150,7 +178,7 @@ protected boolean isValidFor(SourceType sourceType) {
150178

151179
@Override
152180
public Map<String, Object> encode() {
153-
Map<String, Object> toReturn = new HashMap<>();
181+
Map<String, Object> toReturn = eventProperties.encode();
154182

155183
toReturn.put("type", "pointerMove");
156184
toReturn.put("duration", duration.toMillis());
@@ -225,4 +253,116 @@ public static Origin fromElement(WebElement element) {
225253
}
226254
}
227255

256+
public static PointerEventProperties eventProperties() {
257+
return new PointerEventProperties();
258+
}
259+
260+
public static class PointerEventProperties implements Encodable {
261+
private Float width = null;
262+
private Float height = null;
263+
private Float pressure = null;
264+
private Float tangentialPressure = null;
265+
private Integer tiltX = null;
266+
private Integer tiltY = null;
267+
private Integer twist = null;
268+
private Float altitudeAngle = null;
269+
private Float azimuthAngle = null;
270+
271+
public PointerEventProperties setWidth(float width) {
272+
Require.nonNull("width", width);
273+
if (width < 0) {
274+
throw new IllegalArgumentException("Width must be a positive Number");
275+
}
276+
this.width = width;
277+
return this;
278+
}
279+
280+
public PointerEventProperties setHeight(float height) {
281+
Require.nonNull("height", height);
282+
if (height < 0) {
283+
throw new IllegalArgumentException("Height must be a positive Number");
284+
}
285+
this.height = height;
286+
return this;
287+
}
288+
289+
public PointerEventProperties setPressure(float pressure) {
290+
Require.nonNull("pressure", pressure);
291+
if (pressure < 0 || pressure > 1) {
292+
throw new IllegalArgumentException("pressure must be a number between 0 and 1");
293+
}
294+
this.pressure = pressure;
295+
return this;
296+
}
297+
298+
public PointerEventProperties setTangentialPressure(float tangentialPressure) {
299+
Require.nonNull("tangentialPressure", tangentialPressure);
300+
if (tangentialPressure < -1 || tangentialPressure > 1) {
301+
throw new IllegalArgumentException("tangentialPressure must be a Number between -1 and 1");
302+
}
303+
this.tangentialPressure = tangentialPressure;
304+
return this;
305+
}
306+
307+
public PointerEventProperties setTiltX(int tiltX) {
308+
Require.nonNull("tiltX", tiltX);
309+
if (tiltX < -90 || tiltX > 90) {
310+
throw new IllegalArgumentException("tiltX must be an integer between -90 and 90");
311+
}
312+
this.tiltX = tiltX;
313+
return this;
314+
}
315+
316+
public PointerEventProperties setTiltY(int tiltY) {
317+
Require.nonNull("tiltY", tiltY);
318+
if (tiltY < -90 || tiltY > 90) {
319+
throw new IllegalArgumentException("tiltY must be an integer between -90 and 90");
320+
}
321+
this.tiltY = tiltY;
322+
return this;
323+
}
324+
325+
public PointerEventProperties setTwist(int twist) {
326+
Require.nonNull("twist", twist);
327+
if (twist < 0 || twist > 359) {
328+
throw new IllegalArgumentException("twist must be an integer between 0 and 359");
329+
}
330+
this.twist = twist;
331+
return this;
332+
}
333+
334+
public PointerEventProperties setAltitudeAngle(float altitudeAngle) {
335+
Require.nonNull("altitudeAngle", altitudeAngle);
336+
if (altitudeAngle < 0 || altitudeAngle > Math.PI / 2) {
337+
throw new IllegalArgumentException("altitudeAngle must be a number between 0 and π/2");
338+
}
339+
this.altitudeAngle = altitudeAngle;
340+
return this;
341+
}
342+
343+
public PointerEventProperties setAzimuthAngle(float azimuthAngle) {
344+
Require.nonNull("azimuthAngle", azimuthAngle);
345+
if (azimuthAngle < 0 || azimuthAngle > Math.PI * 2) {
346+
throw new IllegalArgumentException("azimuthAngle must be a number between 0 and 2π");
347+
}
348+
this.azimuthAngle = azimuthAngle;
349+
return this;
350+
}
351+
352+
@Override
353+
public Map<String, Object> encode() {
354+
Map<String, Object> toReturn = new HashMap<>();
355+
Optional.ofNullable(width).ifPresent(v -> toReturn.put("width", v));
356+
Optional.ofNullable(height).ifPresent(v -> toReturn.put("height", v));
357+
Optional.ofNullable(pressure).ifPresent(v -> toReturn.put("pressure", v));
358+
Optional.ofNullable(tangentialPressure).ifPresent(v -> toReturn.put("tangentialPressure", v));
359+
Optional.ofNullable(tiltX).ifPresent(v -> toReturn.put("tiltX", v));
360+
Optional.ofNullable(tiltY).ifPresent(v -> toReturn.put("tiltY", v));
361+
Optional.ofNullable(twist).ifPresent(v -> toReturn.put("twist", v));
362+
Optional.ofNullable(altitudeAngle).ifPresent(v -> toReturn.put("altitudeAngle", v));
363+
Optional.ofNullable(azimuthAngle).ifPresent(v -> toReturn.put("azimuthAngle", v));
364+
365+
return toReturn;
366+
}
367+
}
228368
}

java/test/org/openqa/selenium/interactions/PointerInputTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@ public void encodesWrappedElementInMoveOrigin() {
6060
assertThat(firstAction.origin).containsEntry(W3C.getEncodedElementKey(), "12345");
6161
}
6262

63+
@Test
64+
public void acceptsPointerEventProperties() {
65+
PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "my pen");
66+
Interaction pointerDown = pen.createPointerDown(PointerInput.eventProperties().setHeight(12).setTiltX(30));
67+
68+
Map<String, Object> encode = ((Encodable) pointerDown).encode();
69+
70+
assertThat(encode.get("height")).isEqualTo((float) 12);
71+
}
72+
6373
private static class ActionSequenceJson {
6474
List<ActionJson> actions;
6575
}

0 commit comments

Comments
 (0)