Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/py/selenium/webdriver/common/actions/pointer_actions.py
4012 views
1
# Licensed to the Software Freedom Conservancy (SFC) under one
2
# or more contributor license agreements. See the NOTICE file
3
# distributed with this work for additional information
4
# regarding copyright ownership. The SFC licenses this file
5
# to you under the Apache License, Version 2.0 (the
6
# "License"); you may not use this file except in compliance
7
# with the License. You may obtain a copy of the License at
8
#
9
# http://www.apache.org/licenses/LICENSE-2.0
10
#
11
# Unless required by applicable law or agreed to in writing,
12
# software distributed under the License is distributed on an
13
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
# KIND, either express or implied. See the License for the
15
# specific language governing permissions and limitations
16
# under the License.
17
18
from selenium.webdriver.common.actions import interaction
19
from selenium.webdriver.common.actions.interaction import Interaction
20
from selenium.webdriver.common.actions.mouse_button import MouseButton
21
from selenium.webdriver.common.actions.pointer_input import PointerInput
22
from selenium.webdriver.remote.webelement import WebElement
23
24
25
class PointerActions(Interaction):
26
def __init__(self, source: PointerInput | None = None, duration: int = 250):
27
"""Initialize a new PointerActions instance.
28
29
Args:
30
source: Optional PointerInput instance. If not provided, a default
31
mouse PointerInput will be created.
32
duration: Override the default 250 msecs of DEFAULT_MOVE_DURATION
33
in the source.
34
"""
35
if source is None:
36
source = PointerInput(interaction.POINTER_MOUSE, "mouse")
37
self.source = source
38
self._duration = duration
39
super().__init__(source)
40
41
def pointer_down(
42
self,
43
button=MouseButton.LEFT,
44
width=None,
45
height=None,
46
pressure=None,
47
tangential_pressure=None,
48
tilt_x=None,
49
tilt_y=None,
50
twist=None,
51
altitude_angle=None,
52
azimuth_angle=None,
53
):
54
self._button_action(
55
"create_pointer_down",
56
button=button,
57
width=width,
58
height=height,
59
pressure=pressure,
60
tangential_pressure=tangential_pressure,
61
tilt_x=tilt_x,
62
tilt_y=tilt_y,
63
twist=twist,
64
altitude_angle=altitude_angle,
65
azimuth_angle=azimuth_angle,
66
)
67
return self
68
69
def pointer_up(self, button=MouseButton.LEFT):
70
self._button_action("create_pointer_up", button=button)
71
return self
72
73
def move_to(
74
self,
75
element,
76
x=0,
77
y=0,
78
width=None,
79
height=None,
80
pressure=None,
81
tangential_pressure=None,
82
tilt_x=None,
83
tilt_y=None,
84
twist=None,
85
altitude_angle=None,
86
azimuth_angle=None,
87
):
88
if not isinstance(element, WebElement):
89
raise AttributeError("move_to requires a WebElement")
90
91
self.source.create_pointer_move(
92
origin=element,
93
duration=self._duration,
94
x=int(x),
95
y=int(y),
96
width=width,
97
height=height,
98
pressure=pressure,
99
tangential_pressure=tangential_pressure,
100
tilt_x=tilt_x,
101
tilt_y=tilt_y,
102
twist=twist,
103
altitude_angle=altitude_angle,
104
azimuth_angle=azimuth_angle,
105
)
106
return self
107
108
def move_by(
109
self,
110
x,
111
y,
112
width=None,
113
height=None,
114
pressure=None,
115
tangential_pressure=None,
116
tilt_x=None,
117
tilt_y=None,
118
twist=None,
119
altitude_angle=None,
120
azimuth_angle=None,
121
):
122
self.source.create_pointer_move(
123
origin=interaction.POINTER,
124
duration=self._duration,
125
x=int(x),
126
y=int(y),
127
width=width,
128
height=height,
129
pressure=pressure,
130
tangential_pressure=tangential_pressure,
131
tilt_x=tilt_x,
132
tilt_y=tilt_y,
133
twist=twist,
134
altitude_angle=altitude_angle,
135
azimuth_angle=azimuth_angle,
136
)
137
return self
138
139
def move_to_location(
140
self,
141
x,
142
y,
143
width=None,
144
height=None,
145
pressure=None,
146
tangential_pressure=None,
147
tilt_x=None,
148
tilt_y=None,
149
twist=None,
150
altitude_angle=None,
151
azimuth_angle=None,
152
):
153
self.source.create_pointer_move(
154
origin="viewport",
155
duration=self._duration,
156
x=int(x),
157
y=int(y),
158
width=width,
159
height=height,
160
pressure=pressure,
161
tangential_pressure=tangential_pressure,
162
tilt_x=tilt_x,
163
tilt_y=tilt_y,
164
twist=twist,
165
altitude_angle=altitude_angle,
166
azimuth_angle=azimuth_angle,
167
)
168
return self
169
170
def click(self, element: WebElement | None = None, button=MouseButton.LEFT):
171
if element:
172
self.move_to(element)
173
self.pointer_down(button)
174
self.pointer_up(button)
175
return self
176
177
def context_click(self, element: WebElement | None = None):
178
return self.click(element=element, button=MouseButton.RIGHT)
179
180
def click_and_hold(self, element: WebElement | None = None, button=MouseButton.LEFT):
181
if element:
182
self.move_to(element)
183
self.pointer_down(button=button)
184
return self
185
186
def release(self, button=MouseButton.LEFT):
187
self.pointer_up(button=button)
188
return self
189
190
def double_click(self, element: WebElement | None = None):
191
if element:
192
self.move_to(element)
193
self.pointer_down(MouseButton.LEFT)
194
self.pointer_up(MouseButton.LEFT)
195
self.pointer_down(MouseButton.LEFT)
196
self.pointer_up(MouseButton.LEFT)
197
return self
198
199
def pause(self, duration: float = 0):
200
self.source.create_pause(duration)
201
return self
202
203
def _button_action(self, action, **kwargs):
204
meth = getattr(self.source, action)
205
meth(**kwargs)
206
return self
207
208