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
1864 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
from typing import Optional
18
19
from selenium.webdriver.remote.webelement import WebElement
20
21
from . import interaction
22
from .interaction import Interaction
23
from .mouse_button import MouseButton
24
from .pointer_input import PointerInput
25
26
27
class PointerActions(Interaction):
28
def __init__(self, source: Optional[PointerInput] = None, duration: int = 250):
29
"""
30
Args:
31
- source: PointerInput instance
32
- duration: override the default 250 msecs of DEFAULT_MOVE_DURATION in source
33
"""
34
if source is None:
35
source = PointerInput(interaction.POINTER_MOUSE, "mouse")
36
self.source = source
37
self._duration = duration
38
super().__init__(source)
39
40
def pointer_down(
41
self,
42
button=MouseButton.LEFT,
43
width=None,
44
height=None,
45
pressure=None,
46
tangential_pressure=None,
47
tilt_x=None,
48
tilt_y=None,
49
twist=None,
50
altitude_angle=None,
51
azimuth_angle=None,
52
):
53
self._button_action(
54
"create_pointer_down",
55
button=button,
56
width=width,
57
height=height,
58
pressure=pressure,
59
tangential_pressure=tangential_pressure,
60
tilt_x=tilt_x,
61
tilt_y=tilt_y,
62
twist=twist,
63
altitude_angle=altitude_angle,
64
azimuth_angle=azimuth_angle,
65
)
66
return self
67
68
def pointer_up(self, button=MouseButton.LEFT):
69
self._button_action("create_pointer_up", button=button)
70
return self
71
72
def move_to(
73
self,
74
element,
75
x=0,
76
y=0,
77
width=None,
78
height=None,
79
pressure=None,
80
tangential_pressure=None,
81
tilt_x=None,
82
tilt_y=None,
83
twist=None,
84
altitude_angle=None,
85
azimuth_angle=None,
86
):
87
if not isinstance(element, WebElement):
88
raise AttributeError("move_to requires a WebElement")
89
90
self.source.create_pointer_move(
91
origin=element,
92
duration=self._duration,
93
x=int(x),
94
y=int(y),
95
width=width,
96
height=height,
97
pressure=pressure,
98
tangential_pressure=tangential_pressure,
99
tilt_x=tilt_x,
100
tilt_y=tilt_y,
101
twist=twist,
102
altitude_angle=altitude_angle,
103
azimuth_angle=azimuth_angle,
104
)
105
return self
106
107
def move_by(
108
self,
109
x,
110
y,
111
width=None,
112
height=None,
113
pressure=None,
114
tangential_pressure=None,
115
tilt_x=None,
116
tilt_y=None,
117
twist=None,
118
altitude_angle=None,
119
azimuth_angle=None,
120
):
121
self.source.create_pointer_move(
122
origin=interaction.POINTER,
123
duration=self._duration,
124
x=int(x),
125
y=int(y),
126
width=width,
127
height=height,
128
pressure=pressure,
129
tangential_pressure=tangential_pressure,
130
tilt_x=tilt_x,
131
tilt_y=tilt_y,
132
twist=twist,
133
altitude_angle=altitude_angle,
134
azimuth_angle=azimuth_angle,
135
)
136
return self
137
138
def move_to_location(
139
self,
140
x,
141
y,
142
width=None,
143
height=None,
144
pressure=None,
145
tangential_pressure=None,
146
tilt_x=None,
147
tilt_y=None,
148
twist=None,
149
altitude_angle=None,
150
azimuth_angle=None,
151
):
152
self.source.create_pointer_move(
153
origin="viewport",
154
duration=self._duration,
155
x=int(x),
156
y=int(y),
157
width=width,
158
height=height,
159
pressure=pressure,
160
tangential_pressure=tangential_pressure,
161
tilt_x=tilt_x,
162
tilt_y=tilt_y,
163
twist=twist,
164
altitude_angle=altitude_angle,
165
azimuth_angle=azimuth_angle,
166
)
167
return self
168
169
def click(self, element: Optional[WebElement] = None, button=MouseButton.LEFT):
170
if element:
171
self.move_to(element)
172
self.pointer_down(button)
173
self.pointer_up(button)
174
return self
175
176
def context_click(self, element: Optional[WebElement] = None):
177
return self.click(element=element, button=MouseButton.RIGHT)
178
179
def click_and_hold(self, element: Optional[WebElement] = None, button=MouseButton.LEFT):
180
if element:
181
self.move_to(element)
182
self.pointer_down(button=button)
183
return self
184
185
def release(self, button=MouseButton.LEFT):
186
self.pointer_up(button=button)
187
return self
188
189
def double_click(self, element: Optional[WebElement] = None):
190
if element:
191
self.move_to(element)
192
self.pointer_down(MouseButton.LEFT)
193
self.pointer_up(MouseButton.LEFT)
194
self.pointer_down(MouseButton.LEFT)
195
self.pointer_up(MouseButton.LEFT)
196
return self
197
198
def pause(self, duration: float = 0):
199
self.source.create_pause(duration)
200
return self
201
202
def _button_action(self, action, **kwargs):
203
meth = getattr(self.source, action)
204
meth(**kwargs)
205
return self
206
207