Skip to content

Commit f44d705

Browse files
Merge pull request #73 from kayqueGovetri/ENH/selenium-4
ENH: Implement selenium 4
2 parents 629b5e1 + 7f2838b commit f44d705

File tree

10 files changed

+94
-33
lines changed

10 files changed

+94
-33
lines changed

botcity/web/__init__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
from .bot import WebBot, Browser, BROWSER_CONFIGS, By, PageLoadStrategy # noqa: F401, F403
2-
from .parsers import table_to_dict, data_from_row, sanitize_header # noqa: F401, F403
3-
from .util import element_as_select # noqa: F401, F403
1+
# PATCH Selenium for compat
2+
from .compat import patch_selenium # noqa: F401, F403, E402
3+
patch_selenium() # noqa: F401, F403, E402
44

5-
from botcity.web._version import get_versions
5+
from .bot import WebBot, Browser, BROWSER_CONFIGS, By, PageLoadStrategy # noqa: F401, F403, E402
6+
from .parsers import table_to_dict, data_from_row, sanitize_header # noqa: F401, F403, E402
7+
from .util import element_as_select # noqa: F401, F403, E402
8+
9+
from botcity.web._version import get_versions # noqa: F401, F403, E402
610
__version__ = get_versions()['version']
711
del get_versions

botcity/web/bot.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from selenium.webdriver.support.wait import WebDriverWait, TimeoutException, NoSuchElementException
2727
from selenium.webdriver.support import expected_conditions as EC
2828

29-
from . import config, cv2find
29+
from . import config, cv2find, compat
3030
from .browsers import BROWSER_CONFIGS, Browser, PageLoadStrategy
3131

3232
try:
@@ -235,7 +235,6 @@ def start_browser(self):
235235
"""
236236
Starts the selected browser.
237237
"""
238-
239238
def check_driver():
240239
# Look for driver
241240
driver_name = BROWSER_CONFIGS.get(self.browser).get("driver")
@@ -260,8 +259,14 @@ def check_driver():
260259
self.capabilities = cap
261260
driver_path = self.driver_path or check_driver()
262261
self.driver_path = driver_path
262+
if compat.version_selenium_is_larger_than_four():
263+
service = BROWSER_CONFIGS.get(self.browser).get("service")
264+
service = service(executable_path=self.driver_path)
265+
service.desired_capabilities = cap
263266

264-
self._driver = driver_class(options=opt, desired_capabilities=cap, executable_path=driver_path)
267+
self._driver = driver_class(options=opt, service=service)
268+
else:
269+
self._driver = driver_class(options=opt, desired_capabilities=cap, executable_path=driver_path)
265270
self.set_screen_resolution()
266271

267272
def stop_browser(self):
@@ -1368,14 +1373,14 @@ def mouse_move(self, x, y):
13681373
if self.browser == Browser.FIREFOX:
13691374
# Reset coordinates if the page has gone stale. Only required for Firefox
13701375
if self._html_elem is None:
1371-
self._html_elem = self._driver.find_element_by_tag_name('body')
1376+
self._html_elem = self._driver.find_element(By.TAG_NAME, 'body')
13721377
self._x = 0
13731378
self._y = 0
13741379
else:
13751380
try:
13761381
self._html_elem.is_enabled()
13771382
except StaleElementReferenceException:
1378-
self._html_elem = self._driver.find_element_by_tag_name('body')
1383+
self._html_elem = self._driver.find_element(By.TAG_NAME, 'body')
13791384
self._x = 0
13801385
self._y = 0
13811386

botcity/web/browsers/__init__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,27 +44,31 @@ class PageLoadStrategy(str, enum.Enum):
4444
"class": chrome.Chrome,
4545
"options": chrome.default_options,
4646
"capabilities": chrome.default_capabilities,
47-
"wait_for_downloads": chrome.wait_for_downloads
47+
"wait_for_downloads": chrome.wait_for_downloads,
48+
"service": chrome.ChromeService,
4849
},
4950
Browser.FIREFOX: {
5051
"driver": "geckodriver",
5152
"class": firefox.Firefox,
5253
"options": firefox.default_options,
5354
"capabilities": firefox.default_capabilities,
54-
"wait_for_downloads": firefox.wait_for_downloads
55+
"wait_for_downloads": firefox.wait_for_downloads,
56+
"service": firefox.FirefoxService
5557
},
5658
Browser.EDGE: {
5759
"driver": "msedgedriver",
5860
"class": edge.Edge,
5961
"options": edge.default_options,
6062
"capabilities": edge.default_capabilities,
61-
"wait_for_downloads": edge.wait_for_downloads
63+
"wait_for_downloads": edge.wait_for_downloads,
64+
"service": edge.EdgeService
6265
},
6366
Browser.IE: {
6467
"driver": "IEDriverServer",
6568
"class": ie.Ie,
6669
"options": ie.default_options,
6770
"capabilities": ie.default_capabilities,
68-
"wait_for_downloads": ie.wait_for_downloads
71+
"wait_for_downloads": ie.wait_for_downloads,
72+
"service": ie.IeService
6973
},
7074
}

botcity/web/browsers/chrome.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from selenium.webdriver import Chrome # noqa: F401, F403
88
from selenium.webdriver.chrome.options import Options as ChromeOptions
99
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
10-
10+
from selenium.webdriver.chrome.service import Service as ChromeService # noqa: F401, F403
1111
from ..util import cleanup_temp_dir
1212

1313

botcity/web/browsers/edge.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
import time
66
from typing import Dict
77

8-
from msedge.selenium_tools import Edge, EdgeOptions # noqa: F401, F403
98
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
10-
9+
from selenium.webdriver import Edge, EdgeOptions # noqa: F401, F403
10+
from selenium.webdriver.edge.service import Service as EdgeService # noqa: F401, F403
1111
from ..util import cleanup_temp_dir
1212

1313

botcity/web/browsers/firefox.py

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
import tempfile
44
from typing import Dict
55

6-
from selenium import webdriver
76
from selenium.webdriver import Firefox # noqa: F401, F403
87
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
98
from selenium.webdriver.firefox.options import Options as FirefoxOptions
9+
from selenium.webdriver.firefox.service import Service as FirefoxService # noqa: F401, F403
1010

1111
from ..util import cleanup_temp_dir
1212

@@ -362,23 +362,19 @@ def default_options(headless=False, download_folder_path=None, user_data_dir=Non
362362
temp_dir = tempfile.TemporaryDirectory(prefix="botcity_")
363363
user_data_dir = temp_dir.name
364364
atexit.register(cleanup_temp_dir, temp_dir)
365-
firefox_profile = webdriver.FirefoxProfile(user_data_dir)
366-
firefox_profile.set_preference("security.default_personal_cert", "Select Automatically")
367-
firefox_profile.set_preference('browser.download.folderList', 2)
368-
firefox_profile.set_preference('browser.download.manager.showWhenStarting', False)
365+
firefox_options.set_preference("profile", user_data_dir)
366+
firefox_options.set_preference("security.default_personal_cert", "Select Automatically")
367+
firefox_options.set_preference('browser.download.folderList', 2)
368+
firefox_options.set_preference('browser.download.manager.showWhenStarting', False)
369369
if not download_folder_path:
370370
download_folder_path = os.getcwd()
371-
firefox_profile.set_preference('browser.download.dir', download_folder_path)
372-
firefox_profile.set_preference('general.warnOnAboutConfig', False)
371+
firefox_options.set_preference('browser.download.dir', download_folder_path)
372+
firefox_options.set_preference('general.warnOnAboutConfig', False)
373373

374374
mimetypes_to_download = ",".join(FIREFOX_MIMETYPES_TO_DOWNLOAD)
375-
firefox_profile.set_preference("pdfjs.disabled", True)
376-
firefox_profile.set_preference("plugin.disable_full_page_plugin_for_types", mimetypes_to_download)
377-
firefox_profile.set_preference('browser.helperApps.neverAsk.saveToDisk', mimetypes_to_download)
378-
379-
firefox_profile.update_preferences()
380-
firefox_options.profile = firefox_profile
381-
375+
firefox_options.set_preference("pdfjs.disabled", True)
376+
firefox_options.set_preference("plugin.disable_full_page_plugin_for_types", mimetypes_to_download)
377+
firefox_options.set_preference('browser.helperApps.neverAsk.saveToDisk', mimetypes_to_download)
382378
return firefox_options
383379

384380

botcity/web/browsers/ie.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from selenium.webdriver import Ie # noqa: F401, F403
44
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
55
from selenium.webdriver.ie.options import Options
6+
from selenium.webdriver.ie.service import Service as IeService # noqa: F401, F403
67

78

89
def default_options(headless=False, download_folder_path=None, user_data_dir=None,

botcity/web/compat.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import warnings
2+
3+
4+
def patch_selenium():
5+
if version_selenium_is_larger_than_four():
6+
from selenium import webdriver
7+
8+
web_element = webdriver.remote.webelement.WebElement
9+
10+
remote_driver = webdriver.remote.webdriver.WebDriver
11+
12+
bys = ['id', 'class name', 'xpath', 'link text', 'partial link text', 'name', 'css selector', 'tag name']
13+
for by in bys:
14+
name = '_'.join(by.split(' '))
15+
find_element_by_function_name = f"find_element_by_{name}"
16+
find_elements_by_function_name = f"find_elements_by_{name}"
17+
setattr(web_element, find_element_by_function_name, find_element_by(by))
18+
setattr(web_element, find_elements_by_function_name, find_elements_by(by))
19+
setattr(remote_driver, find_element_by_function_name, find_element_by(by))
20+
setattr(remote_driver, find_elements_by_function_name, find_elements_by(by))
21+
22+
23+
def find_element_by(by):
24+
def func(self, value):
25+
warnings.warn("This function is deprecated in version 4, please review the usage for find_element.",
26+
category=DeprecationWarning, stacklevel=2)
27+
return self.find_element(by=by, value=value)
28+
return func
29+
30+
31+
def find_elements_by(by):
32+
def func(self, value):
33+
warnings.warn("This function is deprecated in version 4, please review the usage for find_elements.",
34+
category=DeprecationWarning, stacklevel=2)
35+
return self.find_elements(by=by, value=value)
36+
return func
37+
38+
39+
def version_selenium_is_larger_than_four():
40+
import selenium
41+
from packaging import version
42+
se_version = version.parse(selenium.__version__)
43+
44+
needs_patch = se_version >= version.parse("4.0")
45+
return needs_patch

conftest.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,14 @@ def setup_edge(headless: bool, tmp_folder: str, download_driver: str) -> WebBot:
4949
web.driver_path = download_driver
5050
web.download_folder_path = tmp_folder
5151
opt = browsers.edge.default_options(headless=headless, download_folder_path=tmp_folder)
52-
opt.set_capability('platform', 'ANY')
52+
platforms = {
53+
"Linux": "linux",
54+
"Darwin": "mac",
55+
"Windows": "windows"
56+
}
57+
platform_name = platforms.get(platform.system())
58+
59+
opt.platform_name = platform_name
5360

5461
web.options = opt
5562
return web

requirements.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
botcity-framework-base>=0.2.2
22
beautifulsoup4
3-
msedge-selenium-tools==3.141.3
43
numpy
54
opencv-python
65
pillow
7-
selenium==3.141
6+
selenium==4.6.1

0 commit comments

Comments
 (0)