pydoll-python 1.3.0__tar.gz → 1.3.2__tar.gz

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.
Files changed (36) hide show
  1. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/PKG-INFO +1 -1
  2. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/browser/base.py +50 -6
  3. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/browser/chrome.py +10 -5
  4. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/browser/managers.py +7 -5
  5. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/browser/page.py +2 -1
  6. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/commands/browser.py +19 -0
  7. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pyproject.toml +1 -1
  8. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/LICENSE +0 -0
  9. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/README.md +0 -0
  10. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/__init__.py +0 -0
  11. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/browser/__init__.py +0 -0
  12. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/browser/options.py +0 -0
  13. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/commands/__init__.py +0 -0
  14. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/commands/dom.py +0 -0
  15. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/commands/fetch.py +0 -0
  16. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/commands/input.py +0 -0
  17. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/commands/network.py +0 -0
  18. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/commands/page.py +0 -0
  19. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/commands/runtime.py +0 -0
  20. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/commands/storage.py +0 -0
  21. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/commands/target.py +0 -0
  22. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/connection/__init__.py +0 -0
  23. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/connection/connection.py +0 -0
  24. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/connection/managers.py +0 -0
  25. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/constants.py +0 -0
  26. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/element.py +0 -0
  27. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/events/__init__.py +0 -0
  28. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/events/browser.py +0 -0
  29. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/events/dom.py +0 -0
  30. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/events/fetch.py +0 -0
  31. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/events/network.py +0 -0
  32. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/events/page.py +0 -0
  33. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/exceptions.py +0 -0
  34. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/mixins/__init__.py +0 -0
  35. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/mixins/find_elements.py +0 -0
  36. {pydoll_python-1.3.0 → pydoll_python-1.3.2}/pydoll/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pydoll-python
3
- Version: 1.3.0
3
+ Version: 1.3.2
4
4
  Summary:
5
5
  Author: Thalison Fernandes
6
6
  Author-email: thalissfernandes99@gmail.com
@@ -77,7 +77,9 @@ class Browser(ABC): # noqa: PLR0904
77
77
  exc_val: The exception value, if raised.
78
78
  exc_tb: The traceback, if an exception was raised.
79
79
  """
80
- await self.stop()
80
+ if await self._is_browser_running():
81
+ await self.stop()
82
+
81
83
  await self._connection_handler.close()
82
84
 
83
85
  async def start(self) -> None:
@@ -137,6 +139,7 @@ class Browser(ABC): # noqa: PLR0904
137
139
  page_id = (
138
140
  await self.new_page() if not self._pages else self._pages.pop()
139
141
  )
142
+
140
143
  return Page(self._connection_port, page_id)
141
144
 
142
145
  async def delete_all_cookies(self):
@@ -243,10 +246,25 @@ class Browser(ABC): # noqa: PLR0904
243
246
  Retrieves the ID of the current browser window.
244
247
 
245
248
  Returns:
246
- str: The ID of the current browser window.
249
+ int: The ID of the current browser window.
250
+
251
+ Raises:
252
+ RuntimeError: If unable to retrieve the window ID.
247
253
  """
248
- response = await self._execute_command(BrowserCommands.get_window_id())
249
- return response['result']['windowId']
254
+ command = BrowserCommands.get_window_id()
255
+ response = await self._execute_command(command)
256
+
257
+ if response.get('error'):
258
+ pages = await self.get_targets()
259
+ target_id = await self._get_valid_target_id(pages)
260
+ response = await self._execute_command(
261
+ BrowserCommands.get_window_id_by_target(target_id)
262
+ )
263
+
264
+ if window_id := response.get('result', {}).get('windowId'):
265
+ return window_id
266
+
267
+ raise RuntimeError(response.get('error', {}))
250
268
 
251
269
  async def set_window_bounds(self, bounds: dict):
252
270
  """
@@ -519,7 +537,7 @@ class Browser(ABC): # noqa: PLR0904
519
537
  'url', ''
520
538
  )
521
539
 
522
- async def _get_valid_page(self, pages) -> str:
540
+ async def _get_valid_page(self, pages: list) -> str:
523
541
  """
524
542
  Gets the ID of a valid page or creates a new one.
525
543
 
@@ -541,6 +559,31 @@ class Browser(ABC): # noqa: PLR0904
541
559
 
542
560
  return await self.new_page()
543
561
 
562
+ @staticmethod
563
+ async def _get_valid_target_id(pages: list) -> str:
564
+ """
565
+ Retrieves the target ID of a valid attached browser page.
566
+
567
+ Returns:
568
+ str: The target ID of a valid page.
569
+
570
+ """
571
+
572
+ valid_page = next(
573
+ (page for page in pages
574
+ if page.get('type') == 'page' and page.get('attached')),
575
+ None
576
+ )
577
+
578
+ if not valid_page:
579
+ raise RuntimeError("No valid attached browser page found.")
580
+
581
+ target_id = valid_page.get('targetId')
582
+ if not target_id:
583
+ raise RuntimeError("Valid page found but missing 'targetId'.")
584
+
585
+ return target_id
586
+
544
587
  async def _is_browser_running(self, timeout: int = 10) -> bool:
545
588
  """
546
589
  Checks if the browser process is currently running.
@@ -553,9 +596,10 @@ class Browser(ABC): # noqa: PLR0904
553
596
  if await self._connection_handler.ping():
554
597
  return True
555
598
  await asyncio.sleep(1)
599
+
556
600
  return False
557
601
 
558
- async def _execute_command(self, command: str):
602
+ async def _execute_command(self, command: dict):
559
603
  """
560
604
  Executes a command through the connection handler.
561
605
 
@@ -46,13 +46,18 @@ class Chrome(Browser):
46
46
  the browser executable is not found at the default location.
47
47
  """
48
48
  os_name = platform.system()
49
+
49
50
  browser_paths = {
50
- 'Windows':
51
+ 'Windows': [
51
52
  r'C:\Program Files\Google\Chrome\Application\chrome.exe',
52
- 'Linux':
53
+ r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe',
54
+ ],
55
+ 'Linux': [
53
56
  '/usr/bin/google-chrome',
54
- 'Darwin':
55
- '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
57
+ ],
58
+ 'Darwin': [
59
+ '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
60
+ ]
56
61
  }
57
62
 
58
63
  browser_path = browser_paths.get(os_name)
@@ -60,6 +65,6 @@ class Chrome(Browser):
60
65
  if not browser_path:
61
66
  raise ValueError('Unsupported OS')
62
67
 
63
- return BrowserOptionsManager.validate_browser_path(
68
+ return BrowserOptionsManager.validate_browser_paths(
64
69
  browser_path
65
70
  )
@@ -275,7 +275,7 @@ class BrowserOptionsManager:
275
275
  options.arguments.append('--no-default-browser-check')
276
276
 
277
277
  @staticmethod
278
- def validate_browser_path(path: str) -> str:
278
+ def validate_browser_paths(paths: list[str]) -> str:
279
279
  """
280
280
  Validates the provided browser executable path.
281
281
 
@@ -283,7 +283,8 @@ class BrowserOptionsManager:
283
283
  the specified path.
284
284
 
285
285
  Args:
286
- path (str): The path to the browser executable.
286
+ paths (list[str]): Lista de caminhos possíveis do navegador.
287
+
287
288
 
288
289
  Returns:
289
290
  str: The validated browser path if it exists.
@@ -291,6 +292,7 @@ class BrowserOptionsManager:
291
292
  Raises:
292
293
  ValueError: If the browser executable is not found at the path.
293
294
  """
294
- if not os.path.exists(path):
295
- raise ValueError(f'Browser not found: {path}')
296
- return path
295
+ for path in paths:
296
+ if os.path.exists(path) and os.access(path, os.X_OK):
297
+ return path
298
+ raise ValueError(f"No valid browser path found in: {paths}")
@@ -157,6 +157,7 @@ class Page(FindElementsMixin): # noqa: PLR0904
157
157
  """
158
158
  if self._connection_handler.dialog:
159
159
  return True
160
+
160
161
  return False
161
162
 
162
163
  async def get_dialog_message(self) -> str:
@@ -256,7 +257,7 @@ class Page(FindElementsMixin): # noqa: PLR0904
256
257
  # TODO: remove the duplicated logic
257
258
  """
258
259
  response = await self._execute_command(PageCommands.screenshot())
259
- return response['result']['data'].encode('utf-8')
260
+ return response['result']['data']
260
261
 
261
262
  async def set_download_path(self, path: str):
262
263
  """
@@ -17,6 +17,10 @@ class BrowserCommands:
17
17
 
18
18
  CLOSE = {'method': 'Browser.close'}
19
19
  GET_WINDOW_ID = {'method': 'Browser.WindowID'}
20
+ GET_WINDOW_ID_BY_TARGET = {
21
+ 'method': 'Browser.getWindowForTarget',
22
+ 'params': {},
23
+ }
20
24
  SET_WINDOW_BOUNDS_TEMPLATE = {
21
25
  'method': 'Browser.setWindowBounds',
22
26
  'params': {},
@@ -62,6 +66,21 @@ class BrowserCommands:
62
66
  """
63
67
  return cls.GET_WINDOW_ID
64
68
 
69
+ @classmethod
70
+ def get_window_id_by_target(cls, target_id: str) -> dict:
71
+ """
72
+ Generates the command to get the ID of the current window.
73
+
74
+ Args:
75
+ target_id (str): The target_id to set for the window.
76
+
77
+ Returns:
78
+ dict: The command to be sent to the browser.
79
+ """
80
+ command = cls.GET_WINDOW_ID_BY_TARGET.copy()
81
+ command['params']['targetId'] = target_id
82
+ return command
83
+
65
84
  @classmethod
66
85
  def set_window_bounds(cls, window_id: int, bounds: dict) -> dict:
67
86
  """
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pydoll-python"
3
- version = "1.3.0"
3
+ version = "1.3.2"
4
4
  description = ""
5
5
  authors = ["Thalison Fernandes <thalissfernandes99@gmail.com>"]
6
6
  readme = "README.md"
File without changes
File without changes