browser-toolkit 0.0.1a1__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.
- browser_toolkit/__init__.py +2 -0
- browser_toolkit/base_toolkit.py +584 -0
- browser_toolkit/camoufox.py +10 -0
- browser_toolkit/create_browser/__init__.py +0 -0
- browser_toolkit/create_browser/playwright.py +27 -0
- browser_toolkit/playwright.py +505 -0
- browser_toolkit/selenium.py +372 -0
- browser_toolkit/selenium_toolkit/__init__.py +1 -0
- browser_toolkit/selenium_toolkit/selenium_toolkit.py +408 -0
- browser_toolkit/selenium_toolkit/utils.py +10 -0
- browser_toolkit/types.py +49 -0
- browser_toolkit/utils.py +2 -0
- browser_toolkit-0.0.1a1.dist-info/METADATA +85 -0
- browser_toolkit-0.0.1a1.dist-info/RECORD +17 -0
- browser_toolkit-0.0.1a1.dist-info/WHEEL +5 -0
- browser_toolkit-0.0.1a1.dist-info/licenses/LICENSE +339 -0
- browser_toolkit-0.0.1a1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
from typing import Self
|
|
2
|
+
|
|
3
|
+
from playwright._impl._api_structures import SetCookieParam
|
|
4
|
+
from playwright.async_api import Page, Browser, TimeoutError, ElementHandle, Cookie as PlaywrightCookie
|
|
5
|
+
|
|
6
|
+
from browser_toolkit.base_toolkit import BaseBrowserToolkit, BaseWebElement
|
|
7
|
+
from browser_toolkit.types import Cookie
|
|
8
|
+
from browser_toolkit.utils import raise_not_implemented
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PlaywrightWebElement(BaseWebElement):
|
|
12
|
+
def __init__(self, web_element: ElementHandle):
|
|
13
|
+
self.web_element = web_element
|
|
14
|
+
|
|
15
|
+
async def click(self, selector: str, delay: int = 0) -> None:
|
|
16
|
+
"""
|
|
17
|
+
Clicks the element
|
|
18
|
+
|
|
19
|
+
:param selector: string - CSS selector or XPath
|
|
20
|
+
:param delay: int - time to keep the mouse button pressed in seconds (default: 0)
|
|
21
|
+
:return:
|
|
22
|
+
"""
|
|
23
|
+
await self.web_element.click(delay=delay)
|
|
24
|
+
|
|
25
|
+
async def click_js(self) -> None:
|
|
26
|
+
"""
|
|
27
|
+
Clicks the element using JavaScript
|
|
28
|
+
|
|
29
|
+
:return:
|
|
30
|
+
"""
|
|
31
|
+
await self.web_element.evaluate("element => element.click()")
|
|
32
|
+
|
|
33
|
+
async def type(self, text: str, interval: float | int, clear_before: bool) -> None:
|
|
34
|
+
"""
|
|
35
|
+
Fills the element with the text
|
|
36
|
+
|
|
37
|
+
:param text: string - text to fill
|
|
38
|
+
:param interval: float or int - time to wait between each character in seconds
|
|
39
|
+
:param clear_before: bool - whether to clear the field before filling
|
|
40
|
+
:return:
|
|
41
|
+
"""
|
|
42
|
+
if clear_before:
|
|
43
|
+
await self.clear()
|
|
44
|
+
await self.web_element.type(text, delay=interval * 1000)
|
|
45
|
+
|
|
46
|
+
async def clear(self) -> None:
|
|
47
|
+
"""
|
|
48
|
+
Clears the element
|
|
49
|
+
|
|
50
|
+
:return:
|
|
51
|
+
"""
|
|
52
|
+
await self.web_element.fill("")
|
|
53
|
+
|
|
54
|
+
async def selector(self, selector: str) -> Self | None:
|
|
55
|
+
"""
|
|
56
|
+
Queries the web_element and returns the first element matching the selector.
|
|
57
|
+
:param selector:
|
|
58
|
+
:return:
|
|
59
|
+
"""
|
|
60
|
+
element = await self.web_element.query_selector(selector=selector)
|
|
61
|
+
if element:
|
|
62
|
+
return PlaywrightWebElement(web_element=element)
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
async def selector_all(self, selector: str) -> list[Self]:
|
|
66
|
+
"""
|
|
67
|
+
Queries the web_element and returns all elements matching the selector.
|
|
68
|
+
:param selector:
|
|
69
|
+
:return:
|
|
70
|
+
"""
|
|
71
|
+
elements = await self.web_element.query_selector_all(selector=selector)
|
|
72
|
+
return [PlaywrightWebElement(web_element=element) for element in elements]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class PlaywrightTollKit(BaseBrowserToolkit):
|
|
76
|
+
def __init__(self, browser: Browser, page: Page, *args, **kwargs):
|
|
77
|
+
self.browser: Browser = browser
|
|
78
|
+
self.page: Page = page
|
|
79
|
+
|
|
80
|
+
# --------------------------- START session management ---------------------------
|
|
81
|
+
|
|
82
|
+
async def close(self) -> None:
|
|
83
|
+
"""
|
|
84
|
+
Closes the browser tab
|
|
85
|
+
:return:
|
|
86
|
+
"""
|
|
87
|
+
await self.page.close()
|
|
88
|
+
|
|
89
|
+
# --------------------------- END session management ---------------------------
|
|
90
|
+
|
|
91
|
+
# --------------------------- START selectors ---------------------------
|
|
92
|
+
|
|
93
|
+
async def selector(self, selector: str, web_element: BaseWebElement | None = None) -> BaseWebElement | None:
|
|
94
|
+
"""
|
|
95
|
+
Queries the page and returns the first element matching the selector.
|
|
96
|
+
If a web_element is provided, it queries within that element instead of the whole page.
|
|
97
|
+
:param selector:
|
|
98
|
+
:param web_element:
|
|
99
|
+
:return:
|
|
100
|
+
"""
|
|
101
|
+
element = await self.page.query_selector(selector=selector)
|
|
102
|
+
if element:
|
|
103
|
+
return PlaywrightWebElement(web_element=element)
|
|
104
|
+
return None
|
|
105
|
+
|
|
106
|
+
async def selector_all(self, selector: str, web_element: BaseWebElement | None = None) -> list[BaseWebElement]:
|
|
107
|
+
"""
|
|
108
|
+
Queries the page and returns all elements matching the selector.
|
|
109
|
+
If a web_element is provided, it queries within that element instead of the whole page.
|
|
110
|
+
:param selector:
|
|
111
|
+
:param web_element:
|
|
112
|
+
:return:
|
|
113
|
+
"""
|
|
114
|
+
elements = await self.page.query_selector_all(selector=selector)
|
|
115
|
+
return [PlaywrightWebElement(web_element=element) for element in elements]
|
|
116
|
+
|
|
117
|
+
# --------------------------- END selectors ---------------------------
|
|
118
|
+
|
|
119
|
+
# --------------------------- START Actions ---------------------------
|
|
120
|
+
|
|
121
|
+
async def goto(self, url: str, timeout: int = 30) -> None:
|
|
122
|
+
"""
|
|
123
|
+
Navigates to URL
|
|
124
|
+
|
|
125
|
+
:param url: url to navigate to
|
|
126
|
+
:param timeout: maximum time to wait for the page to load in seconds
|
|
127
|
+
:return:
|
|
128
|
+
"""
|
|
129
|
+
await self.page.goto(url=url, timeout=timeout * 1000)
|
|
130
|
+
|
|
131
|
+
async def click(self, selector: str, delay: int = 0) -> None:
|
|
132
|
+
"""
|
|
133
|
+
Clicks the element matching the selector
|
|
134
|
+
|
|
135
|
+
:param selector: string - CSS selector or XPath
|
|
136
|
+
:param delay: int - time to keep the mouse button pressed in seconds (default: 0)
|
|
137
|
+
:return:
|
|
138
|
+
"""
|
|
139
|
+
await self.page.locator(selector=selector).click(delay=delay)
|
|
140
|
+
|
|
141
|
+
async def click_js(self, selector: str) -> None:
|
|
142
|
+
"""
|
|
143
|
+
Clicks the element matching the selector using JavaScript
|
|
144
|
+
|
|
145
|
+
:param selector: string - CSS selector or XPath
|
|
146
|
+
:return:
|
|
147
|
+
"""
|
|
148
|
+
command = f"document.querySelector('{selector}').click()"
|
|
149
|
+
await self.page.evaluate(expression=command)
|
|
150
|
+
|
|
151
|
+
async def type(self, text: str, selector: str, interval: float | int, clear_before: bool) -> None:
|
|
152
|
+
"""
|
|
153
|
+
Fills the element matching the selector with the text
|
|
154
|
+
|
|
155
|
+
:param text: string - text to fill
|
|
156
|
+
:param selector: string - CSS selector or XPath
|
|
157
|
+
:param interval: float or int - time to wait between each character
|
|
158
|
+
:param clear_before: bool - whether to clear the field before filling
|
|
159
|
+
:return:
|
|
160
|
+
"""
|
|
161
|
+
if clear_before:
|
|
162
|
+
await self.clear(selector=selector)
|
|
163
|
+
await self.page.locator(selector=selector).type(text, delay=interval * 1000)
|
|
164
|
+
|
|
165
|
+
async def clear(self, selector: str) -> None:
|
|
166
|
+
"""
|
|
167
|
+
Clears the element matching the selector
|
|
168
|
+
|
|
169
|
+
:param selector: string - CSS selector or XPath
|
|
170
|
+
:return:
|
|
171
|
+
"""
|
|
172
|
+
await self.page.locator(selector).fill("")
|
|
173
|
+
|
|
174
|
+
async def scroll_to_element(self, selector: str) -> None:
|
|
175
|
+
"""
|
|
176
|
+
Scrolls to the element matching the selector
|
|
177
|
+
|
|
178
|
+
:param selector: string - CSS selector or XPath
|
|
179
|
+
:return:
|
|
180
|
+
"""
|
|
181
|
+
command = f"document.querySelector('{selector}').scrollIntoView()"
|
|
182
|
+
await self.page.evaluate(expression=command)
|
|
183
|
+
|
|
184
|
+
async def scroll_to_top(self) -> None:
|
|
185
|
+
"""
|
|
186
|
+
Scrolls to the top of the page
|
|
187
|
+
|
|
188
|
+
:return:
|
|
189
|
+
"""
|
|
190
|
+
await self.page.evaluate("window.scrollTo(0, 0);")
|
|
191
|
+
|
|
192
|
+
async def scroll_to_bottom(self) -> None:
|
|
193
|
+
"""
|
|
194
|
+
Scrolls to the bottom of the page
|
|
195
|
+
|
|
196
|
+
:return:
|
|
197
|
+
"""
|
|
198
|
+
await self.page.evaluate("window.scrollTo(0, document.body.scrollHeight);")
|
|
199
|
+
|
|
200
|
+
async def reload(self) -> None:
|
|
201
|
+
"""
|
|
202
|
+
Reloads the page
|
|
203
|
+
|
|
204
|
+
:return:
|
|
205
|
+
"""
|
|
206
|
+
await self.page.reload()
|
|
207
|
+
|
|
208
|
+
async def hard_reload(self) -> None:
|
|
209
|
+
"""
|
|
210
|
+
Hard reloads the page (ignoring cache)
|
|
211
|
+
|
|
212
|
+
:return:
|
|
213
|
+
"""
|
|
214
|
+
cmd = "window.location.reload()"
|
|
215
|
+
await self.page.evaluate(expression=cmd)
|
|
216
|
+
|
|
217
|
+
# --------------------------- END Actions ---------------------------
|
|
218
|
+
|
|
219
|
+
# --------------------------- START page data ---------------------------
|
|
220
|
+
@property
|
|
221
|
+
async def current_url(self) -> str:
|
|
222
|
+
"""
|
|
223
|
+
Gets the current URL
|
|
224
|
+
|
|
225
|
+
:return: str - current URL
|
|
226
|
+
"""
|
|
227
|
+
return self.page.url
|
|
228
|
+
|
|
229
|
+
@property
|
|
230
|
+
async def title(self) -> str:
|
|
231
|
+
"""
|
|
232
|
+
Gets the page title
|
|
233
|
+
|
|
234
|
+
:return: str - page title
|
|
235
|
+
"""
|
|
236
|
+
return await self.page.title()
|
|
237
|
+
|
|
238
|
+
@property
|
|
239
|
+
async def page_source(self) -> str:
|
|
240
|
+
"""
|
|
241
|
+
Gets the page source
|
|
242
|
+
|
|
243
|
+
:return: str - page source
|
|
244
|
+
"""
|
|
245
|
+
return await self.page.content()
|
|
246
|
+
|
|
247
|
+
async def get_text(self, selector: str) -> str:
|
|
248
|
+
"""
|
|
249
|
+
Gets the text from the element matching the selector
|
|
250
|
+
|
|
251
|
+
:param selector: string - CSS selector or XPath
|
|
252
|
+
:return: str - text of the element
|
|
253
|
+
"""
|
|
254
|
+
return await self.page.locator(selector=selector).text_content()
|
|
255
|
+
|
|
256
|
+
async def get_attribute(self, selector: str, attribute: str) -> str:
|
|
257
|
+
"""
|
|
258
|
+
Gets the attribute from the element matching the selector
|
|
259
|
+
|
|
260
|
+
:param selector: string - CSS selector or XPath
|
|
261
|
+
:param attribute: string - attribute name
|
|
262
|
+
:return: str - attribute of the element
|
|
263
|
+
"""
|
|
264
|
+
return await self.page.locator(selector=selector).get_attribute(name=attribute)
|
|
265
|
+
|
|
266
|
+
async def save_screenshot(self, file_path: str) -> None:
|
|
267
|
+
"""
|
|
268
|
+
Takes a screenshot of the current page and saves it to the exception directory if it is set
|
|
269
|
+
:param file_path:
|
|
270
|
+
:return:
|
|
271
|
+
"""
|
|
272
|
+
await self.page.screenshot(path=file_path)
|
|
273
|
+
|
|
274
|
+
# --------------------------- END page data ---------------------------
|
|
275
|
+
|
|
276
|
+
# --------------------------- START network ---------------------------
|
|
277
|
+
|
|
278
|
+
async def get_network_requests(self) -> list[dict]:
|
|
279
|
+
"""
|
|
280
|
+
Get all network Requests
|
|
281
|
+
:return:
|
|
282
|
+
"""
|
|
283
|
+
raise_not_implemented()
|
|
284
|
+
|
|
285
|
+
async def get_network_response_body(self, request_id: str) -> str:
|
|
286
|
+
"""
|
|
287
|
+
Gets the response body of the network request with the given request ID
|
|
288
|
+
|
|
289
|
+
:param request_id: string - network request ID
|
|
290
|
+
:return: str - response body of the network request
|
|
291
|
+
"""
|
|
292
|
+
raise_not_implemented()
|
|
293
|
+
|
|
294
|
+
# --------------------------- END network ---------------------------
|
|
295
|
+
|
|
296
|
+
# --------------------------- START scripts ---------------------------
|
|
297
|
+
async def execute_script(self, script: str) -> any:
|
|
298
|
+
"""
|
|
299
|
+
Executes the JavaScript script in the context of the current page
|
|
300
|
+
|
|
301
|
+
:param script: string - JavaScript code to execute
|
|
302
|
+
:return:
|
|
303
|
+
"""
|
|
304
|
+
return await self.page.evaluate(expression=script)
|
|
305
|
+
|
|
306
|
+
async def execute_cdp_cmd(self, cmd: str, params: dict) -> any:
|
|
307
|
+
"""
|
|
308
|
+
Executes the Chrome DevTools Protocol command in the context of the current page
|
|
309
|
+
|
|
310
|
+
:param cmd: string - CDP command to execute
|
|
311
|
+
:param params: dict - parameters for the CDP command
|
|
312
|
+
:return:
|
|
313
|
+
"""
|
|
314
|
+
raise_not_implemented()
|
|
315
|
+
|
|
316
|
+
# --------------------------- END scripts ---------------------------
|
|
317
|
+
|
|
318
|
+
# --------------------------- START wait ---------------------------
|
|
319
|
+
async def element_is_present(self, selector: str, timeout: int) -> bool:
|
|
320
|
+
"""
|
|
321
|
+
Checks if the element matching the selector is present
|
|
322
|
+
|
|
323
|
+
:param selector: string - CSS selector or XPath
|
|
324
|
+
:param timeout: int - seconds to wait for the element
|
|
325
|
+
:return: bool - whether the element is present
|
|
326
|
+
"""
|
|
327
|
+
try:
|
|
328
|
+
await self.page.wait_for_selector(selector=selector, timeout=timeout * 1000, state="attached")
|
|
329
|
+
return True
|
|
330
|
+
except TimeoutError:
|
|
331
|
+
return False
|
|
332
|
+
|
|
333
|
+
async def element_is_visible(self, selector: str, timeout: int) -> bool:
|
|
334
|
+
"""
|
|
335
|
+
Checks if the element matching the selector is visible
|
|
336
|
+
|
|
337
|
+
:param selector: string - CSS selector or XPath
|
|
338
|
+
:param timeout: int - seconds to wait for the element
|
|
339
|
+
:return: bool - whether the element is visible
|
|
340
|
+
"""
|
|
341
|
+
try:
|
|
342
|
+
await self.page.wait_for_selector(selector=selector, timeout=timeout * 1000, state="visible")
|
|
343
|
+
return True
|
|
344
|
+
except TimeoutError:
|
|
345
|
+
return False
|
|
346
|
+
|
|
347
|
+
async def element_is_invisible(self, selector: str, timeout: int) -> bool:
|
|
348
|
+
"""
|
|
349
|
+
Checks if the element matching the selector is invisible
|
|
350
|
+
|
|
351
|
+
:param selector: string - CSS selector or XPath
|
|
352
|
+
:param timeout: int - seconds to wait for the element
|
|
353
|
+
:return: bool - whether the element is invisible
|
|
354
|
+
"""
|
|
355
|
+
try:
|
|
356
|
+
await self.page.wait_for_selector(selector=selector, timeout=timeout * 1000, state="hidden")
|
|
357
|
+
return True
|
|
358
|
+
except TimeoutError:
|
|
359
|
+
return False
|
|
360
|
+
|
|
361
|
+
async def element_is_clickable(self, selector: str, timeout: int) -> bool:
|
|
362
|
+
"""
|
|
363
|
+
Checks if the element matching the selector is clickable
|
|
364
|
+
|
|
365
|
+
:param selector: string - CSS selector or XPath
|
|
366
|
+
:param timeout: int - seconds to wait for the element
|
|
367
|
+
:return: bool - whether the element is clickable
|
|
368
|
+
"""
|
|
369
|
+
try:
|
|
370
|
+
await self.page.locator(selector=selector).click(trial=True)
|
|
371
|
+
return True
|
|
372
|
+
except:
|
|
373
|
+
return False
|
|
374
|
+
|
|
375
|
+
async def text_is_present(self, text: str, selector: str, timeout: int) -> bool:
|
|
376
|
+
"""
|
|
377
|
+
Checks if the text is present in the element matching the selector
|
|
378
|
+
|
|
379
|
+
:param text: string - text to check
|
|
380
|
+
:param selector: string - CSS selector or XPath
|
|
381
|
+
:param timeout: int - seconds to wait for the element
|
|
382
|
+
:return: bool - whether the text is present in the element
|
|
383
|
+
"""
|
|
384
|
+
try:
|
|
385
|
+
await self.page.wait_for_selector(selector=selector, timeout=timeout * 1000, state="visible")
|
|
386
|
+
element_text = await self.page.locator(selector=selector).text_content()
|
|
387
|
+
return text in element_text
|
|
388
|
+
except TimeoutError:
|
|
389
|
+
return False
|
|
390
|
+
|
|
391
|
+
async def alert_is_present(self, timeout: int, message: str) -> bool:
|
|
392
|
+
"""
|
|
393
|
+
Checks if an alert is present
|
|
394
|
+
|
|
395
|
+
:param timeout: int - seconds to wait for the alert
|
|
396
|
+
:param message: str - alert message
|
|
397
|
+
:return: bool - whether an alert is present
|
|
398
|
+
"""
|
|
399
|
+
try:
|
|
400
|
+
await self.page.wait_for_event("dialog", timeout=timeout * 1000)
|
|
401
|
+
return True
|
|
402
|
+
except TimeoutError:
|
|
403
|
+
return False
|
|
404
|
+
|
|
405
|
+
async def page_is_loading(self, timeout: int) -> bool:
|
|
406
|
+
"""
|
|
407
|
+
Checks if the page is ready
|
|
408
|
+
|
|
409
|
+
:param timeout: int - seconds to wait for the page to be ready
|
|
410
|
+
:return: bool - whether the page is ready
|
|
411
|
+
"""
|
|
412
|
+
try:
|
|
413
|
+
await self.page.wait_for_load_state(state="load", timeout=timeout * 1000)
|
|
414
|
+
return False
|
|
415
|
+
except TimeoutError:
|
|
416
|
+
return True
|
|
417
|
+
|
|
418
|
+
# --------------------------- END wait ---------------------------
|
|
419
|
+
|
|
420
|
+
# --------------------------- START session data ---------------------------
|
|
421
|
+
async def get_all_cookies(self) -> list[Cookie]:
|
|
422
|
+
"""
|
|
423
|
+
Gets all cookies
|
|
424
|
+
:return: dict
|
|
425
|
+
"""
|
|
426
|
+
raw_cookies: list[PlaywrightCookie] = await self.page.context.cookies()
|
|
427
|
+
transformed_cookies: list[Cookie] = []
|
|
428
|
+
for raw_cookie in raw_cookies:
|
|
429
|
+
transformed_cookie = Cookie(
|
|
430
|
+
name=raw_cookie.get("name"),
|
|
431
|
+
value=raw_cookie.get("value"),
|
|
432
|
+
url=raw_cookie.get("url"),
|
|
433
|
+
domain=raw_cookie.get("domain"),
|
|
434
|
+
path=raw_cookie.get("path"),
|
|
435
|
+
expires=raw_cookie.get("expires"),
|
|
436
|
+
httpOnly=raw_cookie.get("httpOnly"),
|
|
437
|
+
secure=raw_cookie.get("secure"),
|
|
438
|
+
sameSite=raw_cookie.get("sameSite"),
|
|
439
|
+
partitionKey=raw_cookie.get("partitionKey"),
|
|
440
|
+
)
|
|
441
|
+
transformed_cookies.append(transformed_cookie)
|
|
442
|
+
|
|
443
|
+
return transformed_cookies
|
|
444
|
+
|
|
445
|
+
async def add_cookie(self, cookie: Cookie) -> None:
|
|
446
|
+
"""
|
|
447
|
+
Adds a cookie to the current session
|
|
448
|
+
|
|
449
|
+
:param cookie: Cookie - cookie to add
|
|
450
|
+
:return:
|
|
451
|
+
"""
|
|
452
|
+
transformed_cookie: SetCookieParam = SetCookieParam(
|
|
453
|
+
name=cookie.name,
|
|
454
|
+
value=cookie.value,
|
|
455
|
+
url=cookie.url,
|
|
456
|
+
domain=cookie.domain,
|
|
457
|
+
path=cookie.path,
|
|
458
|
+
expires=cookie.expires,
|
|
459
|
+
httpOnly=cookie.httpOnly,
|
|
460
|
+
secure=cookie.secure,
|
|
461
|
+
sameSite=cookie.sameSite,
|
|
462
|
+
partitionKey=cookie.partitionKey,
|
|
463
|
+
)
|
|
464
|
+
await self.page.context.add_cookies(cookies=[transformed_cookie])
|
|
465
|
+
|
|
466
|
+
async def delete_all_cookies(self) -> None:
|
|
467
|
+
"""
|
|
468
|
+
Deletes all cookies from the current session
|
|
469
|
+
:return:
|
|
470
|
+
"""
|
|
471
|
+
await self.page.context.clear_cookies()
|
|
472
|
+
|
|
473
|
+
async def delete_cookie_by_name(self, name: str) -> None:
|
|
474
|
+
"""
|
|
475
|
+
Deletes a cookie by name
|
|
476
|
+
|
|
477
|
+
:param name: string - name of the cookie to delete
|
|
478
|
+
:return:
|
|
479
|
+
"""
|
|
480
|
+
await self.page.context.clear_cookies(name=name)
|
|
481
|
+
|
|
482
|
+
async def delete_cookie_filter(
|
|
483
|
+
self, name: str | None = None, domain: str | None = None, path: str | None = None
|
|
484
|
+
) -> None:
|
|
485
|
+
"""
|
|
486
|
+
Deletes cookies by name, domain, and path
|
|
487
|
+
|
|
488
|
+
:param name:
|
|
489
|
+
:param domain:
|
|
490
|
+
:param path:
|
|
491
|
+
:return:
|
|
492
|
+
"""
|
|
493
|
+
await self.page.context.clear_cookies(name=name, domain=domain, path=path)
|
|
494
|
+
|
|
495
|
+
async def get_all_local_storage(self) -> dict:
|
|
496
|
+
"""
|
|
497
|
+
Gets all local storage
|
|
498
|
+
:return: dict
|
|
499
|
+
"""
|
|
500
|
+
local_storage = await self.page.evaluate("() => Object.fromEntries(Object.entries(localStorage))")
|
|
501
|
+
if not isinstance(local_storage, dict):
|
|
502
|
+
local_storage = {}
|
|
503
|
+
return local_storage
|
|
504
|
+
|
|
505
|
+
# --------------------------- END session data ---------------------------
|