Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/py/selenium/webdriver/common/actions/action_builder.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
18
19
from typing import Any, Optional, Union
20
21
from selenium.webdriver.remote.command import Command
22
23
from . import interaction
24
from .key_actions import KeyActions
25
from .key_input import KeyInput
26
from .pointer_actions import PointerActions
27
from .pointer_input import PointerInput
28
from .wheel_actions import WheelActions
29
from .wheel_input import WheelInput
30
31
32
class ActionBuilder:
33
def __init__(
34
self,
35
driver,
36
mouse: Optional[PointerInput] = None,
37
wheel: Optional[WheelInput] = None,
38
keyboard: Optional[KeyInput] = None,
39
duration: int = 250,
40
) -> None:
41
mouse = mouse or PointerInput(interaction.POINTER_MOUSE, "mouse")
42
keyboard = keyboard or KeyInput(interaction.KEY)
43
wheel = wheel or WheelInput(interaction.WHEEL)
44
self.devices: list[Union[PointerInput, KeyInput, WheelInput]] = [mouse, keyboard, wheel]
45
self._key_action = KeyActions(keyboard)
46
self._pointer_action = PointerActions(mouse, duration=duration)
47
self._wheel_action = WheelActions(wheel)
48
self.driver = driver
49
50
def get_device_with(self, name: str) -> Optional[Union["WheelInput", "PointerInput", "KeyInput"]]:
51
"""Get the device with the given name.
52
53
Parameters:
54
-----------
55
name : str
56
The name of the device to get.
57
58
Returns:
59
--------
60
Optional[Union[WheelInput, PointerInput, KeyInput]] : The device with the given name.
61
"""
62
return next(filter(lambda x: x == name, self.devices), None)
63
64
@property
65
def pointer_inputs(self) -> list[PointerInput]:
66
return [device for device in self.devices if isinstance(device, PointerInput)]
67
68
@property
69
def key_inputs(self) -> list[KeyInput]:
70
return [device for device in self.devices if isinstance(device, KeyInput)]
71
72
@property
73
def key_action(self) -> KeyActions:
74
return self._key_action
75
76
@property
77
def pointer_action(self) -> PointerActions:
78
return self._pointer_action
79
80
@property
81
def wheel_action(self) -> WheelActions:
82
return self._wheel_action
83
84
def add_key_input(self, name: str) -> KeyInput:
85
"""Add a new key input device to the action builder.
86
87
Parameters:
88
-----------
89
name : str
90
The name of the key input device.
91
92
Returns:
93
--------
94
KeyInput : The newly created key input device.
95
96
Example:
97
--------
98
>>> action_builder = ActionBuilder(driver)
99
>>> action_builder.add_key_input(name="keyboard2")
100
"""
101
new_input = KeyInput(name)
102
self._add_input(new_input)
103
return new_input
104
105
def add_pointer_input(self, kind: str, name: str) -> PointerInput:
106
"""Add a new pointer input device to the action builder.
107
108
Parameters:
109
-----------
110
kind : str
111
The kind of pointer input device.
112
- "mouse"
113
- "touch"
114
- "pen"
115
116
name : str
117
The name of the pointer input device.
118
119
Returns:
120
--------
121
PointerInput : The newly created pointer input device.
122
123
Example:
124
--------
125
>>> action_builder = ActionBuilder(driver)
126
>>> action_builder.add_pointer_input(kind="mouse", name="mouse")
127
"""
128
new_input = PointerInput(kind, name)
129
self._add_input(new_input)
130
return new_input
131
132
def add_wheel_input(self, name: str) -> WheelInput:
133
"""Add a new wheel input device to the action builder.
134
135
Parameters:
136
-----------
137
name : str
138
The name of the wheel input device.
139
140
Returns:
141
--------
142
WheelInput : The newly created wheel input device.
143
144
Example:
145
--------
146
>>> action_builder = ActionBuilder(driver)
147
>>> action_builder.add_wheel_input(name="wheel2")
148
"""
149
new_input = WheelInput(name)
150
self._add_input(new_input)
151
return new_input
152
153
def perform(self) -> None:
154
"""Performs all stored actions.
155
156
Example:
157
--------
158
>>> action_builder = ActionBuilder(driver)
159
>>> keyboard = action_builder.key_input
160
>>> el = driver.find_element(id: "some_id")
161
>>> action_builder.click(el).pause(keyboard).pause(keyboard).pause(keyboard).send_keys("keys").perform()
162
"""
163
enc: dict[str, list[Any]] = {"actions": []}
164
for device in self.devices:
165
encoded = device.encode()
166
if encoded["actions"]:
167
enc["actions"].append(encoded)
168
device.actions = []
169
self.driver.execute(Command.W3C_ACTIONS, enc)
170
171
def clear_actions(self) -> None:
172
"""Clears actions that are already stored on the remote end.
173
174
Example:
175
--------
176
>>> action_builder = ActionBuilder(driver)
177
>>> keyboard = action_builder.key_input
178
>>> el = driver.find_element(By.ID, "some_id")
179
>>> action_builder.click(el).pause(keyboard).pause(keyboard).pause(keyboard).send_keys("keys")
180
>>> action_builder.clear_actions()
181
"""
182
self.driver.execute(Command.W3C_CLEAR_ACTIONS)
183
184
def _add_input(self, new_input: Union[KeyInput, PointerInput, WheelInput]) -> None:
185
"""Add a new input device to the action builder.
186
187
Parameters:
188
-----------
189
new_input : Union[KeyInput, PointerInput, WheelInput]
190
The new input device to add.
191
"""
192
self.devices.append(new_input)
193
194