pydoll-python 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pydoll/__init__.py +0 -0
- pydoll/browser/__init__.py +0 -0
- pydoll/browser/base.py +524 -0
- pydoll/browser/chrome.py +31 -0
- pydoll/browser/managers.py +154 -0
- pydoll/browser/options.py +62 -0
- pydoll/browser/page.py +433 -0
- pydoll/commands/__init__.py +18 -0
- pydoll/commands/browser.py +108 -0
- pydoll/commands/dom.py +212 -0
- pydoll/commands/fetch.py +308 -0
- pydoll/commands/input.py +106 -0
- pydoll/commands/network.py +334 -0
- pydoll/commands/page.py +187 -0
- pydoll/commands/runtime.py +45 -0
- pydoll/commands/storage.py +18 -0
- pydoll/commands/target.py +35 -0
- pydoll/connection/__init__.py +0 -0
- pydoll/connection/connection.py +232 -0
- pydoll/connection/managers.py +136 -0
- pydoll/constants.py +125 -0
- pydoll/element.py +313 -0
- pydoll/events/__init__.py +13 -0
- pydoll/events/browser.py +26 -0
- pydoll/events/dom.py +108 -0
- pydoll/events/fetch.py +29 -0
- pydoll/events/network.py +160 -0
- pydoll/events/page.py +144 -0
- pydoll/exceptions.py +82 -0
- pydoll/mixins/__init__.py +0 -0
- pydoll/mixins/find_elements.py +180 -0
- pydoll/utils.py +50 -0
- pydoll_python-1.2.0.dist-info/LICENSE +9 -0
- pydoll_python-1.2.0.dist-info/METADATA +200 -0
- pydoll_python-1.2.0.dist-info/RECORD +36 -0
- pydoll_python-1.2.0.dist-info/WHEEL +4 -0
pydoll/element.py
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
import aiofiles
|
|
5
|
+
from bs4 import BeautifulSoup
|
|
6
|
+
|
|
7
|
+
from pydoll import exceptions
|
|
8
|
+
from pydoll.commands.dom import DomCommands
|
|
9
|
+
from pydoll.commands.input import InputCommands
|
|
10
|
+
from pydoll.commands.page import PageCommands
|
|
11
|
+
from pydoll.commands.runtime import RuntimeCommands
|
|
12
|
+
from pydoll.connection.connection import ConnectionHandler
|
|
13
|
+
from pydoll.constants import Scripts
|
|
14
|
+
from pydoll.mixins.find_elements import FindElementsMixin
|
|
15
|
+
from pydoll.utils import decode_image_to_bytes
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class WebElement(FindElementsMixin):
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
object_id: str,
|
|
22
|
+
connection_handler: ConnectionHandler,
|
|
23
|
+
method: str = None,
|
|
24
|
+
selector: str = None,
|
|
25
|
+
attributes_list: list = [],
|
|
26
|
+
):
|
|
27
|
+
"""
|
|
28
|
+
Initializes the WebElement instance.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
node (dict): The node description from the browser.
|
|
32
|
+
connection_handler (ConnectionHandler): The connection instance.
|
|
33
|
+
"""
|
|
34
|
+
self._object_id = object_id
|
|
35
|
+
self._search_method = method
|
|
36
|
+
self._selector = selector
|
|
37
|
+
self._connection_handler = connection_handler
|
|
38
|
+
self._attributes = {}
|
|
39
|
+
self._def_attributes(attributes_list)
|
|
40
|
+
|
|
41
|
+
def __repr__(self):
|
|
42
|
+
attrs = ', '.join(f'{k}={v!r}' for k, v in self._attributes.items())
|
|
43
|
+
return (
|
|
44
|
+
f'{self.__class__.__name__}({attrs})(object_id={self._object_id})'
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def _def_attributes(self, attributes_list: list):
|
|
48
|
+
for i in range(0, len(attributes_list), 2):
|
|
49
|
+
key = attributes_list[i]
|
|
50
|
+
key = key if key != 'class' else 'class_name'
|
|
51
|
+
value = attributes_list[i + 1]
|
|
52
|
+
self._attributes[key] = value
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def value(self) -> str:
|
|
56
|
+
"""
|
|
57
|
+
Retrieves the value of the element.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
str: The value of the element.
|
|
61
|
+
"""
|
|
62
|
+
return self._attributes.get('value')
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def class_name(self) -> str:
|
|
66
|
+
"""
|
|
67
|
+
Retrieves the class name of the
|
|
68
|
+
element.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
str: The class name of the
|
|
72
|
+
element.
|
|
73
|
+
|
|
74
|
+
"""
|
|
75
|
+
return self._attributes.get('class_name')
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def id(self) -> str:
|
|
79
|
+
"""
|
|
80
|
+
Retrieves the id of the element.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
str: The id of the element.
|
|
84
|
+
"""
|
|
85
|
+
return self._attributes.get('id')
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def is_enabled(self) -> bool:
|
|
89
|
+
"""
|
|
90
|
+
Retrieves the enabled status of the element.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
bool: The enabled status of the element.
|
|
94
|
+
"""
|
|
95
|
+
return bool('disabled' not in self._attributes.keys())
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
async def bounds(self) -> list:
|
|
99
|
+
"""
|
|
100
|
+
Asynchronously retrieves the bounding box of the element.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
dict: The bounding box of the element.
|
|
104
|
+
"""
|
|
105
|
+
command = DomCommands.box_model(object_id=self._object_id)
|
|
106
|
+
response = await self._execute_command(command)
|
|
107
|
+
return response['result']['model']['content']
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
async def inner_html(self) -> str:
|
|
111
|
+
"""
|
|
112
|
+
Retrieves the inner HTML of the element.
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
str: The inner HTML of the element.
|
|
116
|
+
"""
|
|
117
|
+
command = DomCommands.get_outer_html(self._object_id)
|
|
118
|
+
response = await self._execute_command(command)
|
|
119
|
+
return response['result']['outerHTML']
|
|
120
|
+
|
|
121
|
+
async def get_bounds_using_js(self) -> list:
|
|
122
|
+
"""
|
|
123
|
+
Retrieves the bounding box of the element using JavaScript.
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
list: The bounding box of the element.
|
|
127
|
+
"""
|
|
128
|
+
response = await self._execute_script(
|
|
129
|
+
Scripts.BOUNDS, return_by_value=True
|
|
130
|
+
)
|
|
131
|
+
return json.loads(response['result']['result']['value'])
|
|
132
|
+
|
|
133
|
+
async def _execute_script(
|
|
134
|
+
self, script: str, return_by_value: bool = False
|
|
135
|
+
):
|
|
136
|
+
"""
|
|
137
|
+
Executes a JavaScript script on the element.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
script (str): The JavaScript script to execute.
|
|
141
|
+
"""
|
|
142
|
+
return await self._execute_command(
|
|
143
|
+
RuntimeCommands.call_function_on(
|
|
144
|
+
self._object_id, script, return_by_value
|
|
145
|
+
)
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
async def _is_element_visible(self):
|
|
149
|
+
"""
|
|
150
|
+
Verifies if the element is visible using JavaScript.
|
|
151
|
+
It uses the getBoundingClientRect method to check if the element is
|
|
152
|
+
within the viewport and the width and height are greater than 0.
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
bool: True if the element is visible, False otherwise.
|
|
156
|
+
"""
|
|
157
|
+
result = await self._execute_script(
|
|
158
|
+
Scripts.ELEMENT_VISIBLE, return_by_value=True
|
|
159
|
+
)
|
|
160
|
+
return result['result']['result']['value']
|
|
161
|
+
|
|
162
|
+
async def _is_element_on_top(self):
|
|
163
|
+
"""
|
|
164
|
+
Verifies if the element is on top of the page using JavaScript.
|
|
165
|
+
It uses the elementFromPoint method to check if the element is the
|
|
166
|
+
topmost element at the center of its bounding box.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
bool: True if the element is on top of the page, False otherwise.
|
|
170
|
+
"""
|
|
171
|
+
result = await self._execute_script(
|
|
172
|
+
Scripts.ELEMENT_ON_TOP, return_by_value=True
|
|
173
|
+
)
|
|
174
|
+
return result['result']['result']['value']
|
|
175
|
+
|
|
176
|
+
async def get_screenshot(self, path: str):
|
|
177
|
+
"""
|
|
178
|
+
Takes a screenshot of the element.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
path (str): The path where the screenshot will be saved.
|
|
182
|
+
"""
|
|
183
|
+
bounds = await self.get_bounds_using_js()
|
|
184
|
+
clip = {
|
|
185
|
+
'x': bounds['x'],
|
|
186
|
+
'y': bounds['y'],
|
|
187
|
+
'width': bounds['width'],
|
|
188
|
+
'height': bounds['height'],
|
|
189
|
+
'scale': 1,
|
|
190
|
+
}
|
|
191
|
+
screenshot = await self._connection_handler.execute_command(
|
|
192
|
+
PageCommands.screenshot(format='jpeg', clip=clip)
|
|
193
|
+
)
|
|
194
|
+
async with aiofiles.open(path, 'wb') as file:
|
|
195
|
+
image_bytes = decode_image_to_bytes(screenshot['result']['data'])
|
|
196
|
+
await file.write(image_bytes)
|
|
197
|
+
|
|
198
|
+
async def get_element_text(self) -> str:
|
|
199
|
+
"""
|
|
200
|
+
Retrieves the text of the element.
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
str: The text of the element.
|
|
204
|
+
"""
|
|
205
|
+
outer_html = await self.inner_html
|
|
206
|
+
soup = BeautifulSoup(outer_html, 'html.parser')
|
|
207
|
+
text_inside = soup.get_text(strip=True)
|
|
208
|
+
return text_inside
|
|
209
|
+
|
|
210
|
+
def get_attribute(self, name: str) -> str:
|
|
211
|
+
"""
|
|
212
|
+
Retrieves the attribute value of the element.
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
name (str): The name of the attribute.
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
str: The value of the attribute.
|
|
219
|
+
"""
|
|
220
|
+
return self._attributes.get(name)
|
|
221
|
+
|
|
222
|
+
async def scroll_into_view(self):
|
|
223
|
+
"""
|
|
224
|
+
Scrolls the element into view.
|
|
225
|
+
"""
|
|
226
|
+
command = DomCommands.scroll_into_view(object_id=self._object_id)
|
|
227
|
+
await self._execute_command(command)
|
|
228
|
+
|
|
229
|
+
async def click_using_js(self):
|
|
230
|
+
if self._is_option_tag():
|
|
231
|
+
return await self.click_option_tag()
|
|
232
|
+
|
|
233
|
+
await self.scroll_into_view()
|
|
234
|
+
|
|
235
|
+
if not await self._is_element_visible():
|
|
236
|
+
raise exceptions.ElementNotVisible(
|
|
237
|
+
'Element is not visible on the page.'
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
result = await self._execute_script(
|
|
241
|
+
Scripts.CLICK, return_by_value=True
|
|
242
|
+
)
|
|
243
|
+
clicked = result['result']['result']['value']
|
|
244
|
+
if not clicked:
|
|
245
|
+
raise exceptions.ElementNotInteractable(
|
|
246
|
+
'Element is not interactable.'
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
async def click(self, x_offset: int = 0, y_offset: int = 0):
|
|
250
|
+
if self._is_option_tag():
|
|
251
|
+
return await self.click_option_tag()
|
|
252
|
+
|
|
253
|
+
if not await self._is_element_visible():
|
|
254
|
+
raise exceptions.ElementNotVisible(
|
|
255
|
+
'Element is not visible on the page.'
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
await self.scroll_into_view()
|
|
259
|
+
|
|
260
|
+
try:
|
|
261
|
+
element_bounds = await self.bounds
|
|
262
|
+
position_to_click = self._calculate_center(element_bounds)
|
|
263
|
+
position_to_click = (
|
|
264
|
+
position_to_click[0] + x_offset,
|
|
265
|
+
position_to_click[1] + y_offset,
|
|
266
|
+
)
|
|
267
|
+
except KeyError:
|
|
268
|
+
element_bounds = await self.get_bounds_using_js()
|
|
269
|
+
position_to_click = (
|
|
270
|
+
element_bounds['x'] + element_bounds['width'] / 2,
|
|
271
|
+
element_bounds['y'] + element_bounds['height'] / 2,
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
press_command = InputCommands.mouse_press(*position_to_click)
|
|
275
|
+
release_command = InputCommands.mouse_release(*position_to_click)
|
|
276
|
+
await self._connection_handler.execute_command(press_command)
|
|
277
|
+
await asyncio.sleep(0.1)
|
|
278
|
+
await self._connection_handler.execute_command(release_command)
|
|
279
|
+
|
|
280
|
+
async def click_option_tag(self):
|
|
281
|
+
script = Scripts.CLICK_OPTION_TAG.replace('{self.value}', self.value)
|
|
282
|
+
await self._execute_command(RuntimeCommands.evaluate_script(script))
|
|
283
|
+
|
|
284
|
+
async def send_keys(self, text: str):
|
|
285
|
+
"""
|
|
286
|
+
Sends a sequence of keys to the element.
|
|
287
|
+
|
|
288
|
+
Args:
|
|
289
|
+
text (str): The text to send to the element.
|
|
290
|
+
"""
|
|
291
|
+
await self._execute_command(InputCommands.insert_text(text))
|
|
292
|
+
|
|
293
|
+
async def type_keys(self, text: str):
|
|
294
|
+
"""
|
|
295
|
+
Types in a realistic manner by sending keys one by one.
|
|
296
|
+
|
|
297
|
+
Args:
|
|
298
|
+
text (str): The text to send to the element.
|
|
299
|
+
"""
|
|
300
|
+
for char in text:
|
|
301
|
+
await self._execute_command(InputCommands.key_press(char))
|
|
302
|
+
await asyncio.sleep(0.1)
|
|
303
|
+
|
|
304
|
+
def _is_option_tag(self):
|
|
305
|
+
return self._attributes['tag_name'].lower() == 'option'
|
|
306
|
+
|
|
307
|
+
@staticmethod
|
|
308
|
+
def _calculate_center(bounds: list) -> tuple:
|
|
309
|
+
x_values = [bounds[i] for i in range(0, len(bounds), 2)]
|
|
310
|
+
y_values = [bounds[i] for i in range(1, len(bounds), 2)]
|
|
311
|
+
x_center = sum(x_values) / len(x_values)
|
|
312
|
+
y_center = sum(y_values) / len(y_values)
|
|
313
|
+
return x_center, y_center
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from pydoll.events.browser import BrowserEvents
|
|
2
|
+
from pydoll.events.dom import DomEvents
|
|
3
|
+
from pydoll.events.fetch import FetchEvents
|
|
4
|
+
from pydoll.events.network import NetworkEvents
|
|
5
|
+
from pydoll.events.page import PageEvents
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
'BrowserEvents',
|
|
9
|
+
'DomEvents',
|
|
10
|
+
'FetchEvents',
|
|
11
|
+
'NetworkEvents',
|
|
12
|
+
'PageEvents',
|
|
13
|
+
]
|
pydoll/events/browser.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class BrowserEvents:
|
|
2
|
+
"""
|
|
3
|
+
A class to define the browser events available through the
|
|
4
|
+
Chrome DevTools Protocol (CDP). These events allow for monitoring
|
|
5
|
+
specific actions and states within the browser, such as downloads.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
DOWNLOAD_PROGRESS = 'Browser.downloadProgress'
|
|
9
|
+
"""
|
|
10
|
+
Event triggered when the download progress updates.
|
|
11
|
+
|
|
12
|
+
This event provides details about the ongoing download,
|
|
13
|
+
including the amount downloaded and the total size.
|
|
14
|
+
It is part of the CDP's capabilities for monitoring
|
|
15
|
+
download activities in the browser.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
DOWNLOAD_WILL_BEGIN = 'Browser.downloadWillBegin'
|
|
19
|
+
"""
|
|
20
|
+
Event triggered when a download is about to start.
|
|
21
|
+
|
|
22
|
+
This event notifies listeners before the download begins,
|
|
23
|
+
providing an opportunity to handle or react to download events.
|
|
24
|
+
This is part of the CDP's support for download management
|
|
25
|
+
in the browser.
|
|
26
|
+
"""
|
pydoll/events/dom.py
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
class DomEvents:
|
|
2
|
+
"""
|
|
3
|
+
A class to define the DOM events available through the
|
|
4
|
+
Chrome DevTools Protocol (CDP). These events allow for monitoring
|
|
5
|
+
changes and updates within the Document Object Model (DOM)
|
|
6
|
+
of a web page, enabling developers to react to specific
|
|
7
|
+
modifications and interactions with the DOM elements.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
ATTRIBUTE_MODIFIED = 'DOM.attributeModified'
|
|
11
|
+
"""
|
|
12
|
+
Event triggered when an attribute of a DOM node is modified.
|
|
13
|
+
|
|
14
|
+
This event provides information about the node affected and the
|
|
15
|
+
attribute that was changed. It is part of the CDP's capabilities
|
|
16
|
+
for tracking DOM changes and allows developers to respond
|
|
17
|
+
to attribute modifications in real time.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
ATTRIBUTE_REMOVED = 'DOM.attributeRemoved'
|
|
21
|
+
"""
|
|
22
|
+
Event triggered when an attribute of a DOM node is removed.
|
|
23
|
+
|
|
24
|
+
This event indicates that an attribute has been deleted from a
|
|
25
|
+
node, allowing developers to manage state or perform cleanup
|
|
26
|
+
based on the changes. It is supported by the CDP to ensure
|
|
27
|
+
developers can monitor DOM manipulations effectively.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
CHARACTER_DATA_MODIFIED = 'DOM.characterDataModified'
|
|
31
|
+
"""
|
|
32
|
+
Event triggered when the character data of a DOM node is modified.
|
|
33
|
+
|
|
34
|
+
This event informs listeners about changes in the text content
|
|
35
|
+
of a node, which is essential for applications that need to
|
|
36
|
+
reflect real-time updates in the UI based on data changes.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
CHILD_NODE_COUNT_UPDATED = 'DOM.childNodeCountUpdated'
|
|
40
|
+
"""
|
|
41
|
+
Event triggered when the number of child nodes of a DOM node is updated.
|
|
42
|
+
|
|
43
|
+
This event alerts developers when the number of children changes,
|
|
44
|
+
allowing them to react to structural changes in the DOM tree.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
CHILD_NODE_INSERTED = 'DOM.childNodeInserted'
|
|
48
|
+
"""
|
|
49
|
+
Event triggered when a new child node is inserted into a DOM node.
|
|
50
|
+
|
|
51
|
+
This event notifies listeners of new additions to the DOM,
|
|
52
|
+
enabling actions such as updating UI components or handling
|
|
53
|
+
related data.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
CHILD_NODE_REMOVED = 'DOM.childNodeRemoved'
|
|
57
|
+
"""
|
|
58
|
+
Event triggered when a child node is removed from a DOM node.
|
|
59
|
+
|
|
60
|
+
This event indicates that a child has been deleted, allowing
|
|
61
|
+
developers to manage their state or trigger updates based on
|
|
62
|
+
the removal of elements in the DOM.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
DOCUMENT_UPDATED = 'DOM.documentUpdated'
|
|
66
|
+
"""
|
|
67
|
+
Event triggered when the DOM document is updated.
|
|
68
|
+
|
|
69
|
+
This event signifies that changes have occurred at the document
|
|
70
|
+
level, prompting developers to refresh or update their views
|
|
71
|
+
accordingly.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
SCROLLABLE_FLAG_UPDATED = 'DOM.scrollableFlagUpdated'
|
|
75
|
+
"""
|
|
76
|
+
Event triggered when the scrollable flag of a DOM node is updated.
|
|
77
|
+
|
|
78
|
+
This event is useful for determining which elements in the DOM
|
|
79
|
+
can be scrolled, allowing for enhanced user interactions and
|
|
80
|
+
responsive designs.
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
SHADOW_ROOT_POPPED = 'DOM.shadowRootPopped'
|
|
84
|
+
"""
|
|
85
|
+
Event triggered when a shadow root is popped from the stack.
|
|
86
|
+
|
|
87
|
+
This event indicates that a shadow DOM context has been removed,
|
|
88
|
+
which is relevant for applications utilizing shadow DOM features
|
|
89
|
+
for encapsulated styling and markup.
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
SHADOW_ROOT_PUSHED = 'DOM.shadowRootPushed'
|
|
93
|
+
"""
|
|
94
|
+
Event triggered when a shadow root is pushed onto the stack.
|
|
95
|
+
|
|
96
|
+
This event signifies that a new shadow DOM context has been
|
|
97
|
+
created, allowing developers to manage and respond to changes
|
|
98
|
+
in encapsulated DOM structures.
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
TOP_LAYER_ELEMENTS_UPDATED = 'DOM.topLayerElementsUpdated'
|
|
102
|
+
"""
|
|
103
|
+
Event triggered when the top layer elements in the DOM are updated.
|
|
104
|
+
|
|
105
|
+
This event allows for monitoring changes in the most visible
|
|
106
|
+
elements in the DOM, which is essential for managing UI states
|
|
107
|
+
and rendering updates.
|
|
108
|
+
"""
|
pydoll/events/fetch.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
class FetchEvents:
|
|
2
|
+
"""
|
|
3
|
+
A class to define the Fetch events available through the
|
|
4
|
+
Chrome DevTools Protocol (CDP). These events are related to
|
|
5
|
+
the management of network requests, allowing developers to
|
|
6
|
+
intercept, modify, and monitor HTTP requests and responses
|
|
7
|
+
made by the browser.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
AUTH_REQUIRED = 'Fetch.authRequired'
|
|
11
|
+
"""
|
|
12
|
+
Event triggered when authentication is required for a network
|
|
13
|
+
request.
|
|
14
|
+
|
|
15
|
+
This event allows developers to respond to authentication
|
|
16
|
+
challenges, enabling them to provide credentials or take
|
|
17
|
+
appropriate actions when the requested resource requires
|
|
18
|
+
authentication.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
REQUEST_PAUSED = 'Fetch.requestPaused'
|
|
22
|
+
"""
|
|
23
|
+
Event triggered when a network request is paused.
|
|
24
|
+
|
|
25
|
+
This event is particularly useful for developers who want to
|
|
26
|
+
analyze or modify requests before they are sent. When a request
|
|
27
|
+
is paused, it gives the opportunity to inspect the request data
|
|
28
|
+
or alter headers before resuming it.
|
|
29
|
+
"""
|
pydoll/events/network.py
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
class NetworkEvents:
|
|
2
|
+
"""
|
|
3
|
+
A class that defines constants for various network-related events.
|
|
4
|
+
|
|
5
|
+
These constants can be used to identify and handle network interactions in
|
|
6
|
+
applications, particularly in event-driven architectures or APIs that
|
|
7
|
+
monitor network activity.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
DATA_RECEIVED = 'Network.dataReceived'
|
|
11
|
+
"""
|
|
12
|
+
Event triggered when data is received over the network.
|
|
13
|
+
|
|
14
|
+
This can include responses from HTTP requests, incoming WebSocket messages,
|
|
15
|
+
or data from other network interactions. Useful for tracking incoming data
|
|
16
|
+
flow.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
EVENT_SOURCE_MESSAGE_RECEIVED = 'Network.eventSourceMessageReceived'
|
|
20
|
+
"""
|
|
21
|
+
Event fired when a message is received from an EventSource.
|
|
22
|
+
|
|
23
|
+
Typically used for server-sent events (SSE), this event indicates that a
|
|
24
|
+
new message has been sent from the server to the client, enabling real-time
|
|
25
|
+
updates.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
LOADING_FAILED = 'Network.loadingFailed'
|
|
29
|
+
"""
|
|
30
|
+
Event that indicates a failure in loading a network resource.
|
|
31
|
+
|
|
32
|
+
This can occur due to various reasons, such as network errors, resource
|
|
33
|
+
not found, or permission issues. This event is critical for error handling
|
|
34
|
+
and debugging.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
LOADING_FINISHED = 'Network.loadingFinished'
|
|
38
|
+
"""
|
|
39
|
+
Event fired when a network loading operation is completed.
|
|
40
|
+
|
|
41
|
+
This event is triggered regardless of whether the loading was successful
|
|
42
|
+
or failed, making it useful for cleaning up or updating the user interface
|
|
43
|
+
after loading operations.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
REQUEST_SERVED_FROM_CACHE = 'Network.requestServedFromCache'
|
|
47
|
+
"""
|
|
48
|
+
Event indicating that a network request was fulfilled from the cache.
|
|
49
|
+
|
|
50
|
+
This helps identify when data is being retrieved from cache instead of
|
|
51
|
+
making a new network request, which can improve performance and reduce
|
|
52
|
+
latency.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
REQUEST_WILL_BE_SENT = 'Network.requestWillBeSent'
|
|
56
|
+
"""
|
|
57
|
+
Event triggered just before a network request is sent.
|
|
58
|
+
|
|
59
|
+
This is useful for logging, modifying request headers, or performing
|
|
60
|
+
actions before the actual request is made. It allows developers to
|
|
61
|
+
intercept and examine requests.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
RESPONSE_RECEIVED = 'Network.responseReceived'
|
|
65
|
+
"""
|
|
66
|
+
Event that indicates a response has been received from a network request.
|
|
67
|
+
|
|
68
|
+
This event contains details about the response, such as status codes,
|
|
69
|
+
headers, and the body of the response. It's crucial for processing the
|
|
70
|
+
results of network requests.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
WEB_SOCKET_CLOSED = 'Network.webSocketClosed'
|
|
74
|
+
"""
|
|
75
|
+
Event that occurs when a WebSocket connection has been closed.
|
|
76
|
+
|
|
77
|
+
This can happen due to normal closure, errors, or network interruptions.
|
|
78
|
+
Handling this event is important for managing WebSocket connections and
|
|
79
|
+
reconnection logic.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
WEB_SOCKET_CREATED = 'Network.webSocketCreated'
|
|
83
|
+
"""
|
|
84
|
+
Event fired when a new WebSocket connection is established.
|
|
85
|
+
|
|
86
|
+
This indicates that a WebSocket connection is active and ready for
|
|
87
|
+
communication, allowing developers to set up message handlers or perform
|
|
88
|
+
other initialization tasks.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
WEB_SOCKET_FRAME_ERROR = 'Network.webSocketFrameError'
|
|
92
|
+
"""
|
|
93
|
+
Event indicating that there was an error with a frame in a WebSocket
|
|
94
|
+
communication.
|
|
95
|
+
|
|
96
|
+
This can be used to handle specific frame-related errors and improve the
|
|
97
|
+
robustness of WebSocket implementations by allowing for error logging and
|
|
98
|
+
corrective actions.
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
WEB_SOCKET_FRAME_RECEIVED = 'Network.webSocketFrameReceived'
|
|
102
|
+
"""
|
|
103
|
+
Event fired when a frame is received through a WebSocket.
|
|
104
|
+
|
|
105
|
+
This is essential for processing incoming messages and performing actions
|
|
106
|
+
based on the content of those messages.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
WEB_SOCKET_FRAME_SENT = 'Network.webSocketFrameSent'
|
|
110
|
+
"""
|
|
111
|
+
Event representing a frame that has been sent through a WebSocket.
|
|
112
|
+
|
|
113
|
+
This event can be used for logging sent messages, monitoring communication,
|
|
114
|
+
or performing actions after a message has been sent.
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
WEB_TRANSPORT_CLOSED = 'Network.webTransportClosed'
|
|
118
|
+
"""
|
|
119
|
+
Event indicating that a web transport connection has been closed.
|
|
120
|
+
|
|
121
|
+
Web transport connections are often used for low-latency communication.
|
|
122
|
+
Handling this event is vital for ensuring that resources are properly
|
|
123
|
+
released and that the application can react to disconnections.
|
|
124
|
+
"""
|
|
125
|
+
|
|
126
|
+
WEB_TRANSPORT_CONNECTION_ESTABLISHED = (
|
|
127
|
+
'Network.webTransportConnectionEstablished'
|
|
128
|
+
)
|
|
129
|
+
"""
|
|
130
|
+
Event fired when a web transport connection is successfully established.
|
|
131
|
+
|
|
132
|
+
This signifies that the connection is ready for use, allowing for
|
|
133
|
+
immediate data transmission and interaction.
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
WEB_TRANSPORT_CREATED = 'Network.webTransportCreated'
|
|
137
|
+
"""
|
|
138
|
+
Event that signifies that a new web transport connection has been created.
|
|
139
|
+
|
|
140
|
+
This is useful for setting up communication channels and initializing
|
|
141
|
+
necessary resources for the newly created transport.
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
POLICY_UPDATED = 'Network.policyUpdated'
|
|
145
|
+
"""
|
|
146
|
+
Event that indicates that the network policy has been updated.
|
|
147
|
+
|
|
148
|
+
This might relate to security, access controls, or other network-related
|
|
149
|
+
policies that affect how requests and responses are handled. It’s important
|
|
150
|
+
for maintaining compliance and security in applications.
|
|
151
|
+
"""
|
|
152
|
+
|
|
153
|
+
REQUEST_INTERCEPTED = 'Network.requestIntercepted'
|
|
154
|
+
"""
|
|
155
|
+
Event fired when a network request has been intercepted.
|
|
156
|
+
|
|
157
|
+
This is often used in service workers or other intermediary layers to
|
|
158
|
+
modify or block requests before they reach the network. Handling this event
|
|
159
|
+
is crucial for implementing custom request logic or caching strategies.
|
|
160
|
+
"""
|