Pen actions
A representation of a pen stylus kind of pointer input for interacting with a web page.
A Pen is a type of pointer input that has most of the same behavior as a mouse, but can also have event properties unique to a stylus. Additionally, while a mouse has 5 buttons, a pen has 3 equivalent button states:
- 0 — Touch Contact (the default; equivalent to a left click)
- 2 — Barrel Button (equivalent to a right click)
- 5 — Eraser Button (currently unsupported by drivers)
Using a Pen
WebElement pointerArea = driver.findElement(By.id("pointerArea"));
new Actions(driver)
.setActivePointer(PointerInput.Kind.PEN, "default pen")
.moveToElement(pointerArea)
.clickAndHold()
.moveByOffset(2, 2)
.release()
.perform();
Show full example
package dev.selenium.actions_api;
import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class PenTest extends BaseChromeTest {
@Test
public void usePen() {
driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");
WebElement pointerArea = driver.findElement(By.id("pointerArea"));
new Actions(driver)
.setActivePointer(PointerInput.Kind.PEN, "default pen")
.moveToElement(pointerArea)
.clickAndHold()
.moveByOffset(2, 2)
.release()
.perform();
List<WebElement> moves = driver.findElements(By.className("pointermove"));
Map<String, String> moveTo = getPropertyInfo(moves.get(0));
Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
Map<String, String> moveBy = getPropertyInfo(moves.get(1));
Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));
Rectangle rect = pointerArea.getRect();
int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
Assertions.assertEquals("-1", moveTo.get("button"));
Assertions.assertEquals("pen", moveTo.get("pointerType"));
Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
Assertions.assertEquals("0", down.get("button"));
Assertions.assertEquals("pen", down.get("pointerType"));
Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
Assertions.assertEquals("-1", moveBy.get("button"));
Assertions.assertEquals("pen", moveBy.get("pointerType"));
Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
Assertions.assertEquals("0", up.get("button"));
Assertions.assertEquals("pen", up.get("pointerType"));
Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
}
@Test
public void setPointerEventProperties() {
driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");
WebElement pointerArea = driver.findElement(By.id("pointerArea"));
PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
.setTiltX(-72)
.setTiltY(9)
.setTwist(86);
PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);
Sequence actionListPen = new Sequence(pen, 0)
.addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
.addAction(pen.createPointerDown(0))
.addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
.addAction(pen.createPointerUp(0));
((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));
List<WebElement> moves = driver.findElements(By.className("pointermove"));
Map<String, String> moveTo = getPropertyInfo(moves.get(0));
Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
Map<String, String> moveBy = getPropertyInfo(moves.get(1));
Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));
Rectangle rect = pointerArea.getRect();
int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
Assertions.assertEquals("-1", moveTo.get("button"));
Assertions.assertEquals("pen", moveTo.get("pointerType"));
Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
Assertions.assertEquals("0", down.get("button"));
Assertions.assertEquals("pen", down.get("pointerType"));
Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
Assertions.assertEquals("-1", moveBy.get("button"));
Assertions.assertEquals("pen", moveBy.get("pointerType"));
Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
Assertions.assertEquals("-72", moveBy.get("tiltX"));
Assertions.assertEquals("9", moveBy.get("tiltY"));
Assertions.assertEquals("86", moveBy.get("twist"));
Assertions.assertEquals("0", up.get("button"));
Assertions.assertEquals("pen", up.get("pointerType"));
Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
}
private Map<String, String> getPropertyInfo(WebElement element) {
String text = element.getText();
text = text.substring(text.indexOf(' ') + 1);
return Arrays.stream(text.split(", "))
.map(s -> s.split(": "))
.collect(Collectors.toMap(
a -> a[0],
a -> a[1]
));
}
}
pointer_area = driver.find_element(By.ID, "pointerArea")
pen_input = PointerInput(POINTER_PEN, "default pen")
action = ActionBuilder(driver, mouse=pen_input)
action.pointer_action\
.move_to(pointer_area)\
.pointer_down()\
.move_by(2, 2)\
.pointer_up()
action.perform()
Show full example
import math
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By
def test_use_pen(driver):
driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')
pointer_area = driver.find_element(By.ID, "pointerArea")
pen_input = PointerInput(POINTER_PEN, "default pen")
action = ActionBuilder(driver, mouse=pen_input)
action.pointer_action\
.move_to(pointer_area)\
.pointer_down()\
.move_by(2, 2)\
.pointer_up()
action.perform()
moves = driver.find_elements(By.CLASS_NAME, "pointermove")
move_to = properties(moves[0])
down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
move_by = properties(moves[1])
up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))
rect = pointer_area.rect
center_x = rect["x"] + rect["width"] / 2
center_y = rect["y"] + rect["height"] / 2
assert move_to["button"] == "-1"
assert move_to["pointerType"] == "pen"
assert move_to["pageX"] == str(math.floor(center_x))
assert move_to["pageY"] == str(math.floor(center_y))
assert down["button"] == "0"
assert down["pointerType"] == "pen"
assert down["pageX"] == str(math.floor(center_x))
assert down["pageY"] == str(math.floor(center_y))
assert move_by["button"] == "-1"
assert move_by["pointerType"] == "pen"
assert move_by["pageX"] == str(math.floor(center_x + 2))
assert move_by["pageY"] == str(math.floor(center_y + 2))
assert up["button"] == "0"
assert up["pointerType"] == "pen"
assert up["pageX"] == str(math.floor(center_x + 2))
assert up["pageY"] == str(math.floor(center_y + 2))
def test_set_pointer_event_properties(driver):
driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')
pointer_area = driver.find_element(By.ID, "pointerArea")
pen_input = PointerInput(POINTER_PEN, "default pen")
action = ActionBuilder(driver, mouse=pen_input)
action.pointer_action\
.move_to(pointer_area)\
.pointer_down()\
.move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
.pointer_up(0)
action.perform()
moves = driver.find_elements(By.CLASS_NAME, "pointermove")
move_to = properties(moves[0])
down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
move_by = properties(moves[1])
up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))
rect = pointer_area.rect
center_x = rect["x"] + rect["width"] / 2
center_y = rect["y"] + rect["height"] / 2
assert move_to["button"] == "-1"
assert move_to["pointerType"] == "pen"
assert move_to["pageX"] == str(math.floor(center_x))
assert move_to["pageY"] == str(math.floor(center_y))
assert down["button"] == "0"
assert down["pointerType"] == "pen"
assert down["pageX"] == str(math.floor(center_x))
assert down["pageY"] == str(math.floor(center_y))
assert move_by["button"] == "-1"
assert move_by["pointerType"] == "pen"
assert move_by["pageX"] == str(math.floor(center_x + 2))
assert move_by["pageY"] == str(math.floor(center_y + 2))
assert move_by["tiltX"] == "-72"
assert move_by["tiltY"] == "9"
assert move_by["twist"] == "86"
assert up["button"] == "0"
assert up["pointerType"] == "pen"
assert up["pageX"] == str(math.floor(center_x + 2))
assert up["pageY"] == str(math.floor(center_y + 2))
def properties(element):
kv = element.text.split(' ', 1)[1].split(', ')
return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
ActionBuilder actionBuilder = new ActionBuilder();
PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
2, 2, TimeSpan.Zero));
actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
Show full example
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;
namespace SeleniumDocs.ActionsAPI
{
[TestClass]
public class PenTest : BaseChromeTest
{
[TestMethod]
public void UsePen()
{
driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";
IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
ActionBuilder actionBuilder = new ActionBuilder();
PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
2, 2, TimeSpan.Zero));
actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
var moves = driver.FindElements(By.ClassName("pointermove"));
var moveTo = getProperties(moves.ElementAt(0));
var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
var moveBy = getProperties(moves.ElementAt(1));
var up = getProperties(driver.FindElement(By.ClassName("pointerup")));
Point location = pointerArea.Location;
Size size = pointerArea.Size;
decimal centerX = location.X + size.Width / 2;
decimal centerY = location.Y + size.Height / 2;
Assert.AreEqual("-1", moveTo["button"]);
Assert.AreEqual("pen", moveTo["pointerType"]);
Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
Assert.AreEqual("0", down["button"]);
Assert.AreEqual("pen", down["pointerType"]);
Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
Assert.AreEqual("-1", moveBy["button"]);
Assert.AreEqual("pen", moveBy["pointerType"]);
Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
Assert.AreEqual("0", up["button"]);
Assert.AreEqual("pen", up["pointerType"]);
Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
}
[TestMethod]
public void SetPointerEventProperties()
{
driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";
IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
ActionBuilder actionBuilder = new ActionBuilder();
PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
TiltX = -72,
TiltY = 9,
Twist = 86,
};
actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
2, 2, TimeSpan.Zero, properties));
actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
var moves = driver.FindElements(By.ClassName("pointermove"));
var moveTo = getProperties(moves.ElementAt(0));
var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
var moveBy = getProperties(moves.ElementAt(1));
var up = getProperties(driver.FindElement(By.ClassName("pointerup")));
Point location = pointerArea.Location;
Size size = pointerArea.Size;
decimal centerX = location.X + size.Width / 2;
decimal centerY = location.Y + size.Height / 2;
Assert.AreEqual("-1", moveTo["button"]);
Assert.AreEqual("pen", moveTo["pointerType"]);
Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
Assert.AreEqual("0", down["button"]);
Assert.AreEqual("pen", down["pointerType"]);
Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
Assert.AreEqual("-1", moveBy["button"]);
Assert.AreEqual("pen", moveBy["pointerType"]);
Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
Assert.AreEqual((86).ToString(), moveBy["twist"]);
Assert.AreEqual("0", up["button"]);
Assert.AreEqual("pen", up["pointerType"]);
Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
}
private Dictionary<string, string> getProperties(IWebElement element)
{
var str = element.Text;
str = str[(str.Split()[0].Length + 1)..];
IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
}
private bool VerifyEquivalent(decimal expected, string actual)
{
var absolute = Math.Abs(expected - decimal.Parse(actual));
if (absolute <= 1)
{
return true;
}
throw new Exception("Expected: " + expected + "; but received: " + actual);
}
}
}
pointer_area = driver.find_element(id: 'pointerArea')
driver.action(devices: :pen)
.move_to(pointer_area)
.pointer_down
.move_by(2, 2)
.pointer_up
.perform
Show full example
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Pen' do
let(:driver) { start_session }
it 'uses a pen' do
driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'
pointer_area = driver.find_element(id: 'pointerArea')
driver.action(devices: :pen)
.move_to(pointer_area)
.pointer_down
.move_by(2, 2)
.pointer_up
.perform
moves = driver.find_elements(class: 'pointermove')
move_to = properties(moves[0])
down = properties(driver.find_element(class: 'pointerdown'))
move_by = properties(moves[1])
up = properties(driver.find_element(class: 'pointerup'))
rect = pointer_area.rect
center_x = rect.x + (rect.width / 2)
center_y = rect.y + (rect.height / 2)
expect(move_to).to include('button' => '-1',
'pointerType' => 'pen',
'pageX' => center_x.to_s,
'pageY' => center_y.floor.to_s)
expect(down).to include('button' => '0',
'pointerType' => 'pen',
'pageX' => center_x.to_s,
'pageY' => center_y.floor.to_s)
expect(move_by).to include('button' => '-1',
'pointerType' => 'pen',
'pageX' => (center_x + 2).to_s,
'pageY' => (center_y + 2).floor.to_s)
expect(up).to include('button' => '0',
'pointerType' => 'pen',
'pageX' => (center_x + 2).to_s,
'pageY' => (center_y + 2).floor.to_s)
end
it 'sets pointer event attributes' do
driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'
pointer_area = driver.find_element(id: 'pointerArea')
driver.action(devices: :pen)
.move_to(pointer_area)
.pointer_down
.move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
.pointer_up
.perform
moves = driver.find_elements(class: 'pointermove')
move_to = properties(moves[0])
down = properties(driver.find_element(class: 'pointerdown'))
move_by = properties(moves[1])
up = properties(driver.find_element(class: 'pointerup'))
rect = pointer_area.rect
center_x = rect.x + (rect.width / 2)
center_y = rect.y + (rect.height / 2)
expect(move_to).to include('button' => '-1',
'pointerType' => 'pen',
'pageX' => center_x.to_s,
'pageY' => center_y.floor.to_s)
expect(down).to include('button' => '0',
'pointerType' => 'pen',
'pageX' => center_x.to_s,
'pageY' => center_y.floor.to_s)
expect(move_by).to include('button' => '-1',
'pointerType' => 'pen',
'pageX' => (center_x + 2).to_s,
'pageY' => (center_y + 2).floor.to_s,
'tiltX' => -72.to_s,
'tiltY' => 9.to_s,
'twist' => 86.to_s)
expect(up).to include('button' => '0',
'pointerType' => 'pen',
'pageX' => (center_x + 2).to_s,
'pageY' => (center_y + 2).floor.to_s)
end
def properties(element)
element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
end
end
val pointerArea = driver.findElement(By.id("pointerArea"))
Actions(driver)
.setActivePointer(PointerInput.Kind.PEN, "default pen")
.moveToElement(pointerArea)
.clickAndHold()
.moveByOffset(2, 2)
.release()
.perform()
Show full example
package dev.selenium.actions_api
import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Rectangle
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver
import kotlin.collections.Map
import java.time.Duration
class PenTest : BaseTest() {
@Test
fun usePen() {
driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
val pointerArea = driver.findElement(By.id("pointerArea"))
Actions(driver)
.setActivePointer(PointerInput.Kind.PEN, "default pen")
.moveToElement(pointerArea)
.clickAndHold()
.moveByOffset(2, 2)
.release()
.perform()
val moves = driver.findElements(By.className("pointermove"))
val moveTo = getPropertyInfo(moves.get(0))
val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
val moveBy = getPropertyInfo(moves.get(1))
val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
val rect = pointerArea.getRect()
val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
Assertions.assertEquals("-1", moveTo.get("button"))
Assertions.assertEquals("pen", moveTo.get("pointerType"))
Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
Assertions.assertEquals("0", down.get("button"))
Assertions.assertEquals("pen", down.get("pointerType"))
Assertions.assertEquals(centerX.toString(), down.get("pageX"))
Assertions.assertEquals(centerY.toString(), down.get("pageY"))
Assertions.assertEquals("-1", moveBy.get("button"))
Assertions.assertEquals("pen", moveBy.get("pointerType"))
Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
Assertions.assertEquals("0", up.get("button"))
Assertions.assertEquals("pen", up.get("pointerType"))
Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
}
@Test
fun setPointerEventProperties() {
driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
val pointerArea = driver.findElement(By.id("pointerArea"))
val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
val eventProperties = PointerInput.eventProperties()
.setTiltX(-72)
.setTiltY(9)
.setTwist(86)
val origin = PointerInput.Origin.fromElement(pointerArea)
val actionListPen = Sequence(pen, 0)
.addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
.addAction(pen.createPointerDown(0))
.addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
.addAction(pen.createPointerUp(0))
(driver as RemoteWebDriver).perform(listOf(actionListPen))
val moves = driver.findElements(By.className("pointermove"))
val moveTo = getPropertyInfo(moves.get(0))
val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
val moveBy = getPropertyInfo(moves.get(1))
val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
val rect = pointerArea.getRect()
val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
Assertions.assertEquals("-1", moveTo.get("button"))
Assertions.assertEquals("pen", moveTo.get("pointerType"))
Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
Assertions.assertEquals("0", down.get("button"))
Assertions.assertEquals("pen", down.get("pointerType"))
Assertions.assertEquals(centerX.toString(), down.get("pageX"))
Assertions.assertEquals(centerY.toString(), down.get("pageY"))
Assertions.assertEquals("-1", moveBy.get("button"))
Assertions.assertEquals("pen", moveBy.get("pointerType"))
Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
Assertions.assertEquals("0", up.get("button"))
Assertions.assertEquals("pen", up.get("pointerType"))
Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
Assertions.assertEquals("-72", moveBy.get("tiltX"))
Assertions.assertEquals("9", moveBy.get("tiltY"))
Assertions.assertEquals("86", moveBy.get("twist"))
}
fun getPropertyInfo(element: WebElement): Map<String, String> {
var text = element.getText()
text = text.substring(text.indexOf(" ")+1)
return text.split(", ")
.map { it.split(": ") }
.map { it.first() to it.last() }
.toMap()
}
}
Adding Pointer Event Attributes
WebElement pointerArea = driver.findElement(By.id("pointerArea"));
PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
.setTiltX(-72)
.setTiltY(9)
.setTwist(86);
PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);
Sequence actionListPen = new Sequence(pen, 0)
.addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
.addAction(pen.createPointerDown(0))
.addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
.addAction(pen.createPointerUp(0));
((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));
Show full example
package dev.selenium.actions_api;
import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class PenTest extends BaseChromeTest {
@Test
public void usePen() {
driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");
WebElement pointerArea = driver.findElement(By.id("pointerArea"));
new Actions(driver)
.setActivePointer(PointerInput.Kind.PEN, "default pen")
.moveToElement(pointerArea)
.clickAndHold()
.moveByOffset(2, 2)
.release()
.perform();
List<WebElement> moves = driver.findElements(By.className("pointermove"));
Map<String, String> moveTo = getPropertyInfo(moves.get(0));
Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
Map<String, String> moveBy = getPropertyInfo(moves.get(1));
Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));
Rectangle rect = pointerArea.getRect();
int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
Assertions.assertEquals("-1", moveTo.get("button"));
Assertions.assertEquals("pen", moveTo.get("pointerType"));
Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
Assertions.assertEquals("0", down.get("button"));
Assertions.assertEquals("pen", down.get("pointerType"));
Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
Assertions.assertEquals("-1", moveBy.get("button"));
Assertions.assertEquals("pen", moveBy.get("pointerType"));
Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
Assertions.assertEquals("0", up.get("button"));
Assertions.assertEquals("pen", up.get("pointerType"));
Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
}
@Test
public void setPointerEventProperties() {
driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");
WebElement pointerArea = driver.findElement(By.id("pointerArea"));
PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
.setTiltX(-72)
.setTiltY(9)
.setTwist(86);
PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);
Sequence actionListPen = new Sequence(pen, 0)
.addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
.addAction(pen.createPointerDown(0))
.addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
.addAction(pen.createPointerUp(0));
((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));
List<WebElement> moves = driver.findElements(By.className("pointermove"));
Map<String, String> moveTo = getPropertyInfo(moves.get(0));
Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
Map<String, String> moveBy = getPropertyInfo(moves.get(1));
Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));
Rectangle rect = pointerArea.getRect();
int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
Assertions.assertEquals("-1", moveTo.get("button"));
Assertions.assertEquals("pen", moveTo.get("pointerType"));
Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
Assertions.assertEquals("0", down.get("button"));
Assertions.assertEquals("pen", down.get("pointerType"));
Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
Assertions.assertEquals("-1", moveBy.get("button"));
Assertions.assertEquals("pen", moveBy.get("pointerType"));
Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
Assertions.assertEquals("-72", moveBy.get("tiltX"));
Assertions.assertEquals("9", moveBy.get("tiltY"));
Assertions.assertEquals("86", moveBy.get("twist"));
Assertions.assertEquals("0", up.get("button"));
Assertions.assertEquals("pen", up.get("pointerType"));
Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
}
private Map<String, String> getPropertyInfo(WebElement element) {
String text = element.getText();
text = text.substring(text.indexOf(' ') + 1);
return Arrays.stream(text.split(", "))
.map(s -> s.split(": "))
.collect(Collectors.toMap(
a -> a[0],
a -> a[1]
));
}
}
pointer_area = driver.find_element(By.ID, "pointerArea")
pen_input = PointerInput(POINTER_PEN, "default pen")
action = ActionBuilder(driver, mouse=pen_input)
action.pointer_action\
.move_to(pointer_area)\
.pointer_down()\
.move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
.pointer_up(0)
action.perform()
Show full example
import math
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By
def test_use_pen(driver):
driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')
pointer_area = driver.find_element(By.ID, "pointerArea")
pen_input = PointerInput(POINTER_PEN, "default pen")
action = ActionBuilder(driver, mouse=pen_input)
action.pointer_action\
.move_to(pointer_area)\
.pointer_down()\
.move_by(2, 2)\
.pointer_up()
action.perform()
moves = driver.find_elements(By.CLASS_NAME, "pointermove")
move_to = properties(moves[0])
down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
move_by = properties(moves[1])
up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))
rect = pointer_area.rect
center_x = rect["x"] + rect["width"] / 2
center_y = rect["y"] + rect["height"] / 2
assert move_to["button"] == "-1"
assert move_to["pointerType"] == "pen"
assert move_to["pageX"] == str(math.floor(center_x))
assert move_to["pageY"] == str(math.floor(center_y))
assert down["button"] == "0"
assert down["pointerType"] == "pen"
assert down["pageX"] == str(math.floor(center_x))
assert down["pageY"] == str(math.floor(center_y))
assert move_by["button"] == "-1"
assert move_by["pointerType"] == "pen"
assert move_by["pageX"] == str(math.floor(center_x + 2))
assert move_by["pageY"] == str(math.floor(center_y + 2))
assert up["button"] == "0"
assert up["pointerType"] == "pen"
assert up["pageX"] == str(math.floor(center_x + 2))
assert up["pageY"] == str(math.floor(center_y + 2))
def test_set_pointer_event_properties(driver):
driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')
pointer_area = driver.find_element(By.ID, "pointerArea")
pen_input = PointerInput(POINTER_PEN, "default pen")
action = ActionBuilder(driver, mouse=pen_input)
action.pointer_action\
.move_to(pointer_area)\
.pointer_down()\
.move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
.pointer_up(0)
action.perform()
moves = driver.find_elements(By.CLASS_NAME, "pointermove")
move_to = properties(moves[0])
down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
move_by = properties(moves[1])
up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))
rect = pointer_area.rect
center_x = rect["x"] + rect["width"] / 2
center_y = rect["y"] + rect["height"] / 2
assert move_to["button"] == "-1"
assert move_to["pointerType"] == "pen"
assert move_to["pageX"] == str(math.floor(center_x))
assert move_to["pageY"] == str(math.floor(center_y))
assert down["button"] == "0"
assert down["pointerType"] == "pen"
assert down["pageX"] == str(math.floor(center_x))
assert down["pageY"] == str(math.floor(center_y))
assert move_by["button"] == "-1"
assert move_by["pointerType"] == "pen"
assert move_by["pageX"] == str(math.floor(center_x + 2))
assert move_by["pageY"] == str(math.floor(center_y + 2))
assert move_by["tiltX"] == "-72"
assert move_by["tiltY"] == "9"
assert move_by["twist"] == "86"
assert up["button"] == "0"
assert up["pointerType"] == "pen"
assert up["pageX"] == str(math.floor(center_x + 2))
assert up["pageY"] == str(math.floor(center_y + 2))
def properties(element):
kv = element.text.split(' ', 1)[1].split(', ')
return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
ActionBuilder actionBuilder = new ActionBuilder();
PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
TiltX = -72,
TiltY = 9,
Twist = 86,
};
actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
2, 2, TimeSpan.Zero, properties));
actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
Show full example
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;
namespace SeleniumDocs.ActionsAPI
{
[TestClass]
public class PenTest : BaseChromeTest
{
[TestMethod]
public void UsePen()
{
driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";
IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
ActionBuilder actionBuilder = new ActionBuilder();
PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
2, 2, TimeSpan.Zero));
actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
var moves = driver.FindElements(By.ClassName("pointermove"));
var moveTo = getProperties(moves.ElementAt(0));
var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
var moveBy = getProperties(moves.ElementAt(1));
var up = getProperties(driver.FindElement(By.ClassName("pointerup")));
Point location = pointerArea.Location;
Size size = pointerArea.Size;
decimal centerX = location.X + size.Width / 2;
decimal centerY = location.Y + size.Height / 2;
Assert.AreEqual("-1", moveTo["button"]);
Assert.AreEqual("pen", moveTo["pointerType"]);
Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
Assert.AreEqual("0", down["button"]);
Assert.AreEqual("pen", down["pointerType"]);
Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
Assert.AreEqual("-1", moveBy["button"]);
Assert.AreEqual("pen", moveBy["pointerType"]);
Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
Assert.AreEqual("0", up["button"]);
Assert.AreEqual("pen", up["pointerType"]);
Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
}
[TestMethod]
public void SetPointerEventProperties()
{
driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";
IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
ActionBuilder actionBuilder = new ActionBuilder();
PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
TiltX = -72,
TiltY = 9,
Twist = 86,
};
actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
2, 2, TimeSpan.Zero, properties));
actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
var moves = driver.FindElements(By.ClassName("pointermove"));
var moveTo = getProperties(moves.ElementAt(0));
var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
var moveBy = getProperties(moves.ElementAt(1));
var up = getProperties(driver.FindElement(By.ClassName("pointerup")));
Point location = pointerArea.Location;
Size size = pointerArea.Size;
decimal centerX = location.X + size.Width / 2;
decimal centerY = location.Y + size.Height / 2;
Assert.AreEqual("-1", moveTo["button"]);
Assert.AreEqual("pen", moveTo["pointerType"]);
Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
Assert.AreEqual("0", down["button"]);
Assert.AreEqual("pen", down["pointerType"]);
Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
Assert.AreEqual("-1", moveBy["button"]);
Assert.AreEqual("pen", moveBy["pointerType"]);
Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
Assert.AreEqual((86).ToString(), moveBy["twist"]);
Assert.AreEqual("0", up["button"]);
Assert.AreEqual("pen", up["pointerType"]);
Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
}
private Dictionary<string, string> getProperties(IWebElement element)
{
var str = element.Text;
str = str[(str.Split()[0].Length + 1)..];
IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
}
private bool VerifyEquivalent(decimal expected, string actual)
{
var absolute = Math.Abs(expected - decimal.Parse(actual));
if (absolute <= 1)
{
return true;
}
throw new Exception("Expected: " + expected + "; but received: " + actual);
}
}
}
pointer_area = driver.find_element(id: 'pointerArea')
driver.action(devices: :pen)
.move_to(pointer_area)
.pointer_down
.move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
.pointer_up
.perform
Show full example
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Pen' do
let(:driver) { start_session }
it 'uses a pen' do
driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'
pointer_area = driver.find_element(id: 'pointerArea')
driver.action(devices: :pen)
.move_to(pointer_area)
.pointer_down
.move_by(2, 2)
.pointer_up
.perform
moves = driver.find_elements(class: 'pointermove')
move_to = properties(moves[0])
down = properties(driver.find_element(class: 'pointerdown'))
move_by = properties(moves[1])
up = properties(driver.find_element(class: 'pointerup'))
rect = pointer_area.rect
center_x = rect.x + (rect.width / 2)
center_y = rect.y + (rect.height / 2)
expect(move_to).to include('button' => '-1',
'pointerType' => 'pen',
'pageX' => center_x.to_s,
'pageY' => center_y.floor.to_s)
expect(down).to include('button' => '0',
'pointerType' => 'pen',
'pageX' => center_x.to_s,
'pageY' => center_y.floor.to_s)
expect(move_by).to include('button' => '-1',
'pointerType' => 'pen',
'pageX' => (center_x + 2).to_s,
'pageY' => (center_y + 2).floor.to_s)
expect(up).to include('button' => '0',
'pointerType' => 'pen',
'pageX' => (center_x + 2).to_s,
'pageY' => (center_y + 2).floor.to_s)
end
it 'sets pointer event attributes' do
driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'
pointer_area = driver.find_element(id: 'pointerArea')
driver.action(devices: :pen)
.move_to(pointer_area)
.pointer_down
.move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
.pointer_up
.perform
moves = driver.find_elements(class: 'pointermove')
move_to = properties(moves[0])
down = properties(driver.find_element(class: 'pointerdown'))
move_by = properties(moves[1])
up = properties(driver.find_element(class: 'pointerup'))
rect = pointer_area.rect
center_x = rect.x + (rect.width / 2)
center_y = rect.y + (rect.height / 2)
expect(move_to).to include('button' => '-1',
'pointerType' => 'pen',
'pageX' => center_x.to_s,
'pageY' => center_y.floor.to_s)
expect(down).to include('button' => '0',
'pointerType' => 'pen',
'pageX' => center_x.to_s,
'pageY' => center_y.floor.to_s)
expect(move_by).to include('button' => '-1',
'pointerType' => 'pen',
'pageX' => (center_x + 2).to_s,
'pageY' => (center_y + 2).floor.to_s,
'tiltX' => -72.to_s,
'tiltY' => 9.to_s,
'twist' => 86.to_s)
expect(up).to include('button' => '0',
'pointerType' => 'pen',
'pageX' => (center_x + 2).to_s,
'pageY' => (center_y + 2).floor.to_s)
end
def properties(element)
element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
end
end
val pointerArea = driver.findElement(By.id("pointerArea"))
val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
val eventProperties = PointerInput.eventProperties()
.setTiltX(-72)
.setTiltY(9)
.setTwist(86)
val origin = PointerInput.Origin.fromElement(pointerArea)
val actionListPen = Sequence(pen, 0)
.addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
.addAction(pen.createPointerDown(0))
.addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
.addAction(pen.createPointerUp(0))
(driver as RemoteWebDriver).perform(listOf(actionListPen))
Show full example
package dev.selenium.actions_api
import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Rectangle
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver
import kotlin.collections.Map
import java.time.Duration
class PenTest : BaseTest() {
@Test
fun usePen() {
driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
val pointerArea = driver.findElement(By.id("pointerArea"))
Actions(driver)
.setActivePointer(PointerInput.Kind.PEN, "default pen")
.moveToElement(pointerArea)
.clickAndHold()
.moveByOffset(2, 2)
.release()
.perform()
val moves = driver.findElements(By.className("pointermove"))
val moveTo = getPropertyInfo(moves.get(0))
val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
val moveBy = getPropertyInfo(moves.get(1))
val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
val rect = pointerArea.getRect()
val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
Assertions.assertEquals("-1", moveTo.get("button"))
Assertions.assertEquals("pen", moveTo.get("pointerType"))
Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
Assertions.assertEquals("0", down.get("button"))
Assertions.assertEquals("pen", down.get("pointerType"))
Assertions.assertEquals(centerX.toString(), down.get("pageX"))
Assertions.assertEquals(centerY.toString(), down.get("pageY"))
Assertions.assertEquals("-1", moveBy.get("button"))
Assertions.assertEquals("pen", moveBy.get("pointerType"))
Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
Assertions.assertEquals("0", up.get("button"))
Assertions.assertEquals("pen", up.get("pointerType"))
Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
}
@Test
fun setPointerEventProperties() {
driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
val pointerArea = driver.findElement(By.id("pointerArea"))
val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
val eventProperties = PointerInput.eventProperties()
.setTiltX(-72)
.setTiltY(9)
.setTwist(86)
val origin = PointerInput.Origin.fromElement(pointerArea)
val actionListPen = Sequence(pen, 0)
.addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
.addAction(pen.createPointerDown(0))
.addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
.addAction(pen.createPointerUp(0))
(driver as RemoteWebDriver).perform(listOf(actionListPen))
val moves = driver.findElements(By.className("pointermove"))
val moveTo = getPropertyInfo(moves.get(0))
val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
val moveBy = getPropertyInfo(moves.get(1))
val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
val rect = pointerArea.getRect()
val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
Assertions.assertEquals("-1", moveTo.get("button"))
Assertions.assertEquals("pen", moveTo.get("pointerType"))
Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
Assertions.assertEquals("0", down.get("button"))
Assertions.assertEquals("pen", down.get("pointerType"))
Assertions.assertEquals(centerX.toString(), down.get("pageX"))
Assertions.assertEquals(centerY.toString(), down.get("pageY"))
Assertions.assertEquals("-1", moveBy.get("button"))
Assertions.assertEquals("pen", moveBy.get("pointerType"))
Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
Assertions.assertEquals("0", up.get("button"))
Assertions.assertEquals("pen", up.get("pointerType"))
Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
Assertions.assertEquals("-72", moveBy.get("tiltX"))
Assertions.assertEquals("9", moveBy.get("tiltY"))
Assertions.assertEquals("86", moveBy.get("twist"))
}
fun getPropertyInfo(element: WebElement): Map<String, String> {
var text = element.getText()
text = text.substring(text.indexOf(" ")+1)
return text.split(", ")
.map { it.split(": ") }
.map { it.first() to it.last() }
.toMap()
}
}