Skip to content

Commit

Permalink
Merge pull request #1848 from emanlove/hotfix-sel-v4_10_0
Browse files Browse the repository at this point in the history
Hotfix sel v4 10 0
  • Loading branch information
emanlove committed Aug 2, 2023
2 parents 9823418 + 49fb16b commit 20f189c
Show file tree
Hide file tree
Showing 17 changed files with 391 additions and 197 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ ${event_firing_or_none} ${NONE}
Open Browser To Start Page
[Tags] NoGrid
[Documentation]
... LOG 1:20 DEBUG Wrapping driver to event_firing_webdriver.
... LOG 1:22 INFO Got driver also from SeleniumLibrary.
... LOG 1:37 DEBUG Wrapping driver to event_firing_webdriver.
... LOG 1:39 INFO Got driver also from SeleniumLibrary.
Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL}
... desired_capabilities=${DESIRED_CAPABILITIES}

Expand Down
2 changes: 1 addition & 1 deletion atest/acceptance/create_webdriver.robot
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Library Collections
Create Webdriver Creates Functioning WebDriver
[Documentation]
... LOG 1:1 INFO REGEXP: Creating an instance of the \\w+ WebDriver.
... LOG 1:8 DEBUG REGEXP: Created \\w+ WebDriver instance with session id (\\w|-)+.
... LOG 1:25 DEBUG REGEXP: Created \\w+ WebDriver instance with session id (\\w|-)+.
[Tags] Known Issue Internet Explorer Known Issue Safari
[Setup] Set Driver Variables
Create Webdriver ${DRIVER_NAME} kwargs=${KWARGS}
Expand Down
2 changes: 1 addition & 1 deletion atest/acceptance/keywords/element_focus.robot
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,6 @@ Submit Button Should Be Focused

Set Focus To Element
[Setup] Go To Page "mouse/index.html"
Set Focus To Element el_for_focus
Set Focus To Element id:el_for_focus
Textfield Value Should Be el_for_focus focus el_for_focus
Element Should Be Focused el_for_focus
12 changes: 6 additions & 6 deletions atest/acceptance/keywords/lists.robot
Original file line number Diff line number Diff line change
Expand Up @@ -112,26 +112,26 @@ Select From Single Selection List

Select Non-Existing Item From Single Selection List
Run Keyword And Expect Error
... NoSuchElementException: Message: Cannot locate option with value: not_there?
... NoSuchElementException: Message: Cannot locate option with value: not_there*
... Select From List By Value preferred_channel not_there no_way_there
Run Keyword And Expect Error
... NoSuchElementException: Message: Could not locate element with visible text: Tin Can Phone?
... NoSuchElementException: Message: Could not locate element with visible text: Tin Can Phone*
... Select From List By Label preferred_channel Tin Can Phone

Select Non-Existing Item From Multi-Selection List
Run Keyword And Expect Error
... NoSuchElementException: Message: Cannot locate option with value: TinCanPhone?
... NoSuchElementException: Message: Cannot locate option with value: TinCanPhone*
... Select From List By value possible_channels TinCanPhone SmokeSignals
Run Keyword And Expect Error
... NoSuchElementException: Message: Could not locate element with visible text: Tin Can Phone?
... NoSuchElementException: Message: Could not locate element with visible text: Tin Can Phone*
... Select From List By Label possible_channels Tin Can Phone Email Smoke Signals

Unselect Non-Existing Item From List
Run Keyword And Expect Error
... NoSuchElementException: Message: Could not locate element with value: Tin Can Phone?
... NoSuchElementException: Message: Could not locate element with value: Tin Can Phone*
... Unselect From List By Value possible_channels Tin Can Phone Smoke Signals
Run Keyword And Expect Error
... NoSuchElementException: Message: Could not locate element with visible text: Tin Can Phone?
... NoSuchElementException: Message: Could not locate element with visible text: Tin Can Phone*
... Unselect From List By Label possible_channels Tin Can Phone Smoke Signals Email

Select From Multiselect List
Expand Down
6 changes: 3 additions & 3 deletions atest/acceptance/keywords/page_load_timeout.robot
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ Test Teardown Close Browser And Reset Page Load Timeout
*** Test Cases ***
Should Open Browser With Default Page Load Timeout
[Documentation] Verify that 'Open Browser' changes the page load timeout.
... LOG 1.1.1:16 DEBUG REGEXP: POST http://localhost:\\d{2,5}/session/[a-f0-9-]+/timeouts {"pageLoad": 300000}
... LOG 1.1.1:18 DEBUG STARTS: Remote response: status=200
... LOG 1.1.1:33 DEBUG REGEXP: POST http://localhost:\\d{2,5}/session/[a-f0-9-]+/timeouts {"pageLoad": 300000}
... LOG 1.1.1:35 DEBUG STARTS: Remote response: status=200
Open Browser To Start Page

Should Run Into Timeout Exception
[Documentation]
... FAIL REGEXP: TimeoutException: Message: (timeout: Timed out receiving message from renderer|TimedPromise timed out).*
... FAIL REGEXP: TimeoutException: Message: (timeout: Timed out receiving message from renderer|TimedPromise timed out|Navigation timed out after).*
Open Browser To Start Page
Set Selenium Page Load Timeout 1 ms
Reload Page
Expand Down
24 changes: 12 additions & 12 deletions atest/acceptance/multiple_browsers_options.robot
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,32 @@ Documentation Creating test which would work on all browser is not possible.
*** Test Cases ***
Chrome Browser With Selenium Options As String
[Documentation]
... LOG 1:3 DEBUG GLOB: *"goog:chromeOptions"*
... LOG 1:3 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?*
... LOG 1:20 DEBUG GLOB: *"goog:chromeOptions"*
... LOG 1:20 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?*
Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL}
... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument("--disable-dev-shm-usage")

Chrome Browser With Selenium Options As String With Attirbute As True
[Documentation]
... LOG 1:3 DEBUG GLOB: *"goog:chromeOptions"*
... LOG 1:3 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?*
... LOG 1:3 DEBUG GLOB: *"--headless"*
... LOG 1:20 DEBUG GLOB: *"goog:chromeOptions"*
... LOG 1:20 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?*
... LOG 1:20 DEBUG GLOB: *"--headless"*
Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL}
... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument ( "--disable-dev-shm-usage" ) ; headless = True

Chrome Browser With Selenium Options With Complex Object
[Tags] NoGrid
[Documentation]
... LOG 1:3 DEBUG GLOB: *"goog:chromeOptions"*
... LOG 1:3 DEBUG GLOB: *"mobileEmulation": {"deviceName": "Galaxy S5"*
... LOG 1:3 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?*
... LOG 1:20 DEBUG GLOB: *"goog:chromeOptions"*
... LOG 1:20 DEBUG GLOB: *"mobileEmulation": {"deviceName": "Galaxy S5"*
... LOG 1:20 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?*
Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL}
... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument ( "--disable-dev-shm-usage" ) ; add_experimental_option( "mobileEmulation" , { 'deviceName' : 'Galaxy S5'})

Chrome Browser With Selenium Options Object
[Documentation]
... LOG 2:3 DEBUG GLOB: *"goog:chromeOptions"*
... LOG 2:3 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?*
... LOG 2:20 DEBUG GLOB: *"goog:chromeOptions"*
... LOG 2:20 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?*
${options} = Get Chrome Options
Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL}
... desired_capabilities=${DESIRED_CAPABILITIES} options=${options}
Expand All @@ -47,7 +47,7 @@ Chrome Browser With Selenium Options Invalid Method

Chrome Browser With Selenium Options Argument With Semicolon
[Documentation]
... LOG 1:3 DEBUG GLOB: *"goog:chromeOptions"*
... LOG 1:3 DEBUG GLOB: *["has;semicolon"*
... LOG 1:20 DEBUG GLOB: *"goog:chromeOptions"*
... LOG 1:20 DEBUG GLOB: *["has;semicolon"*
Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL}
... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument("has;semicolon")
4 changes: 2 additions & 2 deletions atest/acceptance/open_and_close.robot
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ Close Browser Does Nothing When No Browser Is Opened

Browser Open With Not Well-Formed URL Should Close
[Documentation] Verify after incomplete 'Open Browser' browser closes
... LOG 1.1:24 DEBUG STARTS: Opened browser with session id
... LOG 1.1:24 DEBUG REGEXP: .*but failed to open url.*
... LOG 1.1:41 DEBUG STARTS: Opened browser with session id
... LOG 1.1:41 DEBUG REGEXP: .*but failed to open url.*
... LOG 2:2 DEBUG STARTS: DELETE
... LOG 2:5 DEBUG STARTS: Finished Request
Run Keyword And Expect Error * Open Browser bad.url.bad ${BROWSER}
Expand Down
4 changes: 2 additions & 2 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
invoke >= 1.4.1
mockito >= 1.2.2
robotstatuschecker >= 2.0.3
approvaltests == 3.1.0
approvaltests == 8.4.1
empty_files >= 0.0.3
pytest >= 6.0.2
pytest-mockito >= 0.0.4
pytest-approvaltests >= 0.1.0
pytest-approvaltests >= 0.2.0
requests >= 2.24.0
robotframework-pabot >= 1.10.0
black >= 20.8b1
Expand Down
2 changes: 1 addition & 1 deletion src/SeleniumLibrary/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
from SeleniumLibrary.utils import LibraryListener, is_truthy, _convert_timeout, _convert_delay


__version__ = "6.2.0.dev1"
__version__ = "6.1.1.dev1"


class SeleniumLibrary(DynamicCore):
Expand Down
13 changes: 5 additions & 8 deletions src/SeleniumLibrary/keywords/browsermanagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,9 @@ def open_browser(
Optional ``remote_url`` is the URL for a
[https://github.com/SeleniumHQ/selenium/wiki/Grid2|Selenium Grid].
Optional ``desired_capabilities`` can be used to configure, for example,
logging preferences for a browser or a browser and operating system
when using [http://saucelabs.com|Sauce Labs]. Desired capabilities can
be given either as a Python dictionary or as a string in the format
``key1:value1,key2:value2``.
[https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities|
Selenium documentation] lists possible capabilities that can be
enabled.
Optional ``desired_capabilities`` is deprecated and will be ignored. Capabilities of each
individual browser is now done through options or services. Please refer to those arguments
for configuring specific browsers.
Optional ``ff_profile_dir`` is the path to the Firefox profile
directory if you wish to overwrite the default profile Selenium
Expand Down Expand Up @@ -288,6 +283,8 @@ def open_browser(
if url:
self.go_to(url)
return index
if desired_capabilities:
self.warn("desired_capabilities has been deprecated and removed. Please use options to configure browsers as per documentation.")
return self._make_new_browser(
url,
browser,
Expand Down
119 changes: 85 additions & 34 deletions src/SeleniumLibrary/keywords/webdrivertools/webdrivertools.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@
from selenium import webdriver
from selenium.webdriver import FirefoxProfile

from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.edge.service import Service as EdgeService
from selenium.webdriver.firefox.service import Service as FirefoxService
from selenium.webdriver.ie.service import Service as IeService
from selenium.webdriver.safari.service import Service as SafariService

from SeleniumLibrary.keywords.webdrivertools.sl_file_detector import (
SelLibLocalFileDetector,
)
Expand Down Expand Up @@ -57,6 +63,7 @@ class WebDriverCreator:
def __init__(self, log_dir):
self.log_dir = log_dir
self.selenium_options = SeleniumOptions()
#self.selenium_service = SeleniumService()

def create_driver(
self,
Expand Down Expand Up @@ -144,12 +151,11 @@ def create_chrome(
)
return self._remote(desired_capabilities, remote_url, options=options)
if not executable_path:
executable_path = self._get_executable_path(webdriver.Chrome)
executable_path = self._get_executable_path(webdriver.chrome.service.Service)
service = ChromeService(executable_path=executable_path, log_path=service_log_path)
return webdriver.Chrome(
options=options,
service_log_path=service_log_path,
executable_path=executable_path,
**desired_capabilities,
service=service,
)

def create_headless_chrome(
Expand Down Expand Up @@ -185,6 +191,15 @@ def create_firefox(
executable_path="geckodriver",
):
profile = self._get_ff_profile(ff_profile_dir)
if not options:
options = webdriver.FirefoxOptions()
options.profile = profile # <- moved to here :)

# Something I question here is/was whether or not we should create the option, not
# only on whether it exists, but if there is a profile provided. That is previously we just pass
# None along as options if there were none. But now no matter what we create an Options class so
# as to attach the profile to it. If there a scenario in which we don't want to do this???

if remote_url:
default_caps = webdriver.DesiredCapabilities.FIREFOX.copy()
desired_capabilities = self._remote_capabilities_resolver(
Expand All @@ -195,13 +210,13 @@ def create_firefox(
service_log_path if service_log_path else self._geckodriver_log
)
if not executable_path:
executable_path = self._get_executable_path(webdriver.Firefox)
executable_path = self._get_executable_path(webdriver.firefox.service.Service)
service = FirefoxService(executable_path=executable_path, log_path=service_log_path)
return webdriver.Firefox(
options=options,
firefox_profile=profile,
service_log_path=service_log_path,
executable_path=executable_path,
**desired_capabilities,
#firefox_profile=profile, # need to move
service=service,
#**desired_capabilities,
)

def _get_ff_profile(self, ff_profile_dir):
Expand All @@ -222,7 +237,7 @@ def _get_ff_profile(self, ff_profile_dir):
else:
setattr(ff_profile, key, *option[key])
return ff_profile

@property
def _geckodriver_log(self):
log_file = self._get_log_path(
Expand Down Expand Up @@ -267,12 +282,12 @@ def create_ie(
)
return self._remote(desired_capabilities, remote_url, options=options)
if not executable_path:
executable_path = self._get_executable_path(webdriver.Ie)
executable_path = self._get_executable_path(webdriver.ie.service.Service)
service = IeService(executable_path=executable_path, log_path=service_log_path)
return webdriver.Ie(
options=options,
service_log_path=service_log_path,
executable_path=executable_path,
**desired_capabilities,
service=service,
#**desired_capabilities,
)

def _has_options(self, web_driver):
Expand All @@ -294,20 +309,12 @@ def create_edge(
)
return self._remote(desired_capabilities, remote_url)
if not executable_path:
executable_path = self._get_executable_path(webdriver.Edge)
if self._has_options(webdriver.Edge):
# options is supported from Selenium 4.0 onwards
# If can be removed when minimum Selenium version is 4.0 or greater
return webdriver.Edge(
options=options,
service_log_path=service_log_path,
executable_path=executable_path,
**desired_capabilities,
)
executable_path = self._get_executable_path(webdriver.edge.service.Service)
service = EdgeService(executable_path=executable_path, log_path=service_log_path)
return webdriver.Edge(
service_log_path=service_log_path,
executable_path=executable_path,
**desired_capabilities,
options=options,
service=service,
#**desired_capabilities,
)

def create_safari(
Expand All @@ -324,13 +331,10 @@ def create_safari(
desired_capabilities, defaul_caps
)
return self._remote(desired_capabilities, remote_url)
if options or service_log_path:
logger.warn(
"Safari browser does not support Selenium options or service_log_path."
)
if not executable_path:
executable_path = self._get_executable_path(webdriver.Safari)
return webdriver.Safari(executable_path=executable_path, **desired_capabilities)
service = SafariService(executable_path=executable_path, log_path=service_log_path)
return webdriver.Safari(options=options, service=service)

def create_phantomjs(
self,
Expand Down Expand Up @@ -437,10 +441,10 @@ def _remote(self, desired_capabilities, remote_url, profile_dir=None, options=No
file_detector = self._get_sl_file_detector()
return webdriver.Remote(
command_executor=remote_url,
browser_profile=profile_dir,
# browser_profile=profile_dir,
options=options,
file_detector=file_detector,
**desired_capabilities,
# **desired_capabilities,
)

def _get_sl_file_detector(self):
Expand Down Expand Up @@ -549,6 +553,53 @@ def _get_index(self, alias_or_index):
except ValueError:
return None

# Temporarily removing as not going to use with initial 4.10.0 hotfixq
# class SeleniumService:
# """ executable_path: str = DEFAULT_EXECUTABLE_PATH,
# port: int = 0,
# log_path: typing.Optional[str] = None,
# service_args: typing.Optional[typing.List[str]] = None,
# env: typing.Optional[typing.Mapping[str, str]] = None,
# **kwargs,

# executable_path = None, port, service_log_path, service_args, env
# """
# def create(self, browser,
# executable_path=None,
# port=0,
# service_log_path=None,
# service_args=None,
# env=None,
# start_error_message=None, # chromium, chrome, edge
# quiet=False, reuse_service=False, # safari
# ):
# selenium_service = self._import_service(browser)
# # chrome, chromium, firefox, edge
# if any(chromium_based in browser.lower() for chromium_based in ('chromium', 'chrome', 'edge')):
# service = selenium_service(executable_path=executable_path, port=port,log_path=service_log_path,
# service_args=service_args,env=env,start_error_message=start_error_message
# )
# return service
# elif 'safari' in browser.lower():
# service = selenium_service(executable_path=executable_path, port=port,log_path=service_log_path,
# service_args=service_args,env=env,quiet=quiet,reuse_service=reuse_service
# )
# return service
# elif 'firefox' in browser.lower():
# service = selenium_service(executable_path=executable_path, port=port,log_path=service_log_path,
# service_args=service_args,env=env
# )
# return service
# else:
# service = selenium_service(executable_path=executable_path, port=port,log_path=service_log_path,
# service_args=service_args,env=env
# )
# return service

# def _import_service(self, browser):
# browser = browser.replace("headless_", "", 1)
# service = importlib.import_module(f"selenium.webdriver.{browser}.service")
# return service.Service

class SeleniumOptions:
def create(self, browser, options):
Expand Down

0 comments on commit 20f189c

Please sign in to comment.