Skip to content

Commit c8e86cf

Browse files
authored
Merge pull request #195 from j0j1j2/feat/verify-timeout
Add start_timeout property in ChromiumOptions
2 parents 9858a67 + 88b3046 commit c8e86cf

File tree

6 files changed

+91
-1
lines changed

6 files changed

+91
-1
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ async def custom_automation():
188188
options.add_argument('--proxy-server=username:password@ip:port')
189189
options.add_argument('--window-size=1920,1080')
190190
options.binary_location = '/path/to/your/browser'
191+
options.start_timeout = 20
191192

192193
async with Chrome(options=options) as browser:
193194
tab = await browser.start()
@@ -311,6 +312,17 @@ options.binary_location = '/path/to/your/chrome'
311312
browser = Chrome(options=options)
312313
```
313314

315+
**Browser starts after a FailedToStartBrowser error?**
316+
```python
317+
from pydoll.browser import Chrome
318+
from pydoll.browser.options import ChromiumOptions
319+
320+
options = ChromiumOptions()
321+
options.start_timeout = 20 # default is 10 seconds
322+
323+
browser = Chrome(options=options)
324+
```
325+
314326
**Need a proxy?**
315327
```python
316328
options.add_argument('--proxy-server=your-proxy:port')

pydoll/browser/chromium/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ async def _verify_browser_running(self):
509509
Raises:
510510
FailedToStartBrowser: If the browser failed to start.
511511
"""
512-
if not await self._is_browser_running():
512+
if not await self._is_browser_running(self.options.start_timeout):
513513
raise FailedToStartBrowser()
514514

515515
async def _configure_proxy(

pydoll/browser/interfaces.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ def arguments(self) -> list[str]:
1212
def binary_location(self) -> str:
1313
pass
1414

15+
@property
16+
@abstractmethod
17+
def start_timeout(self) -> int:
18+
pass
19+
1520
@abstractmethod
1621
def add_argument(self, argument: str):
1722
pass

pydoll/browser/options.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def __init__(self):
1919
"""
2020
self._arguments = []
2121
self._binary_location = ''
22+
self._start_timeout = 10
2223

2324
@property
2425
def arguments(self) -> list[str]:
@@ -60,6 +61,26 @@ def binary_location(self, location: str):
6061
"""
6162
self._binary_location = location
6263

64+
@property
65+
def start_timeout(self) -> int:
66+
"""
67+
Gets the timeout to verify the browser's running state.
68+
69+
Returns:
70+
int: The timeout in seconds.
71+
"""
72+
return self._start_timeout
73+
74+
@start_timeout.setter
75+
def start_timeout(self, timeout: int):
76+
"""
77+
Sets the timeout to verify the browser's running state.
78+
79+
Args:
80+
timeout (int): The timeout in seconds.
81+
"""
82+
self._start_timeout = timeout
83+
6384
def add_argument(self, argument: str):
6485
"""
6586
Adds a command-line argument to the options.

tests/test_browser/test_browser_base.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import asyncio
12
import base64
23
from unittest.mock import ANY, AsyncMock, MagicMock, patch
34

@@ -110,6 +111,53 @@ async def test_start_browser_failure(mock_browser):
110111
with pytest.raises(exceptions.FailedToStartBrowser):
111112
await mock_browser.start()
112113

114+
@pytest.mark.asyncio
115+
async def test_start_browser_failure_with_start_timeout(mock_browser):
116+
browser_launched = False
117+
118+
async def launch_browser_later():
119+
nonlocal browser_launched
120+
await asyncio.sleep(2)
121+
browser_launched = True
122+
123+
def start_browser_process_side_effect(*args, **kwargs):
124+
asyncio.create_task(launch_browser_later())
125+
126+
async def ping_side_effect():
127+
nonlocal browser_launched
128+
return browser_launched
129+
130+
mock_browser.options.start_timeout = 1
131+
mock_browser._get_valid_tab_id = AsyncMock(return_value='page1')
132+
mock_browser._browser_process_manager.start_browser_process.side_effect = start_browser_process_side_effect
133+
mock_browser._connection_handler.ping = AsyncMock(side_effect=ping_side_effect)
134+
135+
with pytest.raises(exceptions.FailedToStartBrowser):
136+
await mock_browser.start()
137+
138+
@pytest.mark.asyncio
139+
async def test_start_browser_success_with_start_timeout(mock_browser):
140+
browser_launched = False
141+
142+
async def launch_browser_later():
143+
nonlocal browser_launched
144+
await asyncio.sleep(2)
145+
browser_launched = True
146+
147+
def start_browser_process_side_effect(*args, **kwargs):
148+
asyncio.create_task(launch_browser_later())
149+
150+
async def ping_side_effect():
151+
nonlocal browser_launched
152+
return browser_launched
153+
154+
mock_browser.options.start_timeout = 3
155+
mock_browser._get_valid_tab_id = AsyncMock(return_value='page1')
156+
mock_browser._browser_process_manager.start_browser_process.side_effect = start_browser_process_side_effect
157+
mock_browser._connection_handler.ping = AsyncMock(side_effect=ping_side_effect)
158+
159+
await mock_browser.start()
160+
113161
@pytest.mark.asyncio
114162
async def test_proxy_configuration(mock_browser):
115163
mock_browser._proxy_manager.get_proxy_credentials = MagicMock(

tests/test_browser/test_browser_options.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ def test_set_binary_location():
1919
options.binary_location = '/path/to/browser'
2020
assert options.binary_location == '/path/to/browser'
2121

22+
def test_set_start_timeout():
23+
options = Options()
24+
options.start_timeout = 30
25+
assert options.start_timeout == 30
2226

2327
def test_add_argument():
2428
options = Options()

0 commit comments

Comments
 (0)