Skip to content

Commit a0adefd

Browse files
authored
Merge pull request #189 from seleniumbase/fix-ie-browser-usage
Fix compatibility with IE Browser
2 parents d558b9a + 27f34ce commit a0adefd

File tree

5 files changed

+76
-33
lines changed

5 files changed

+76
-33
lines changed

README.md

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
[<img src="https://cdn2.hubspot.net/hubfs/100006/images/SB_Logo3g.png" title="SeleniumBase" height="50">](https://github.com/seleniumbase/SeleniumBase/blob/master/README.md)
1+
[<img src="https://cdn2.hubspot.net/hubfs/100006/images/SB_Logo3g4.png" title="SeleniumBase" height="45">](https://github.com/seleniumbase/SeleniumBase/blob/master/README.md)
22

33
[<img src="https://img.shields.io/pypi/v/seleniumbase.svg" alt="Version" />](https://pypi.python.org/pypi/seleniumbase) [<img src="https://img.shields.io/github/stars/seleniumbase/seleniumbase.svg" alt="GitHub Stars" />](https://github.com/seleniumbase/SeleniumBase/stargazers) [<img src="https://travis-ci.org/seleniumbase/SeleniumBase.svg?branch=master" alt="Build Status" />](https://travis-ci.org/seleniumbase/SeleniumBase) [<img src="https://badges.gitter.im/seleniumbase/SeleniumBase.svg" alt="Join the Gitter Chat" />](https://gitter.im/seleniumbase/SeleniumBase)<br />
44

5-
A reliable solution for fast & simple browser automation and testing with [WebDriver](https://docs.microsoft.com/en-us/microsoft-edge/webdriver) & [Pytest](https://github.com/pytest-dev/pytest).
5+
SeleniumBase extends [WebDriver](https://docs.microsoft.com/en-us/microsoft-edge/webdriver) into a complete framework for end-to-end testing with [Pytest](https://github.com/pytest-dev/pytest).
66

7-
**Why SeleniumBase?** WebDriver automates browsers, but it's not a stand-alone test framework. SeleniumBase saves you time by providing you with a complete framework for end-to-end testing.
7+
## Quick Start
88

9-
**Why Python?** Python is the [fastest growing programming language according to Stack Overflow](https://stackoverflow.blog/2017/09/06/incredible-growth-python/). Python's structure makes it optimal for scripting and quickly building things.
10-
11-
**Quick Start in a few steps:** (Requires [Python](https://www.python.org/downloads/), [Git](https://git-scm.com/), and an optional [Python virtual env](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/virtualenv_instructions.md).)
9+
(Requires [Python](https://www.python.org/downloads/), [Git](https://git-scm.com/), and an optional [Python virtual environment](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/virtualenv_instructions.md).)
1210

1311
```
1412
python -m pip install --upgrade pip
@@ -56,16 +54,16 @@ For more detailed steps on getting started, see the [**Detailed Instructions**](
5654

5755
### Learn More:
5856

59-
**No more repetitive WebDriver code:**<br />
57+
#### **No more repetitive WebDriver code:**<br />
6058
SeleniumBase automatically handles common WebDriver actions such as spinning up web browsers, waiting for page objects to load, saving screenshots during test failures, using a proxy server, and more. (<i>[Read about customizing test runs](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/customizing_test_runs.md).</i>)
6159

62-
**Simple Python syntax makes coding easy:**<br />
60+
#### **Simple Python syntax makes coding easy:**<br />
6361

6462
<img src="https://cdn2.hubspot.net/hubfs/100006/images/my_first_test_image.png" title="SeleniumBase Python Code" height="280">
6563

6664
(<i>By default, [CSS Selectors](https://www.w3schools.com/cssref/css_selectors.asp) are used for finding page elements.</i>)
6765

68-
**Run tests with Pytest or Nose in any browser:**<br />
66+
#### **Run tests with Pytest or Nose in any browser:**<br />
6967
(<i>Using **Pytest** is strongly recommended</i>)
7068

7169
```
@@ -76,7 +74,7 @@ nosetests my_test_suite.py --browser=firefox
7674

7775
Python methods that start with ``test_`` will automatically be run when using ``pytest`` or ``nosetests`` on a Python file, (<i>or on folders containing Python files</i>).
7876

79-
**No more messy code:**<br />
77+
#### **No more messy code:**<br />
8078
This long line of standard WebDriver code,
8179
```python
8280
self.driver.find_element_by_css_selector("textarea").send_keys("text")
@@ -87,26 +85,26 @@ self.update_text("textarea", "text")
8785
```
8886
(<i>You can still use ``self.driver`` in your code.</i>)
8987

90-
**No more flaky tests:**<br />
88+
#### **No more flaky tests:**<br />
9189
SeleniumBase methods automatically wait for page elements to finish loading before interacting with them (*up to a timeout limit*). This means you no longer need random ``time.sleep()`` statements in your code.
9290

93-
**Assist manual QA with automation:**<br />
91+
#### **Assist manual QA with automation:**<br />
9492
SeleniumBase includes an automated/manual hybrid solution called **[MasterQA](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/masterqa/ReadMe.md)**, which speeds up manual testing by having automation perform all the web browser actions while the manual tester only validates what is seen.
9593

96-
**Integrate with your favorite tools:**<br />
94+
#### **Integrate with your favorite tools:**<br />
9795
SeleniumBase is compatible with [Selenium Grid](https://github.com/seleniumbase/SeleniumBase/tree/master/seleniumbase/utilities/selenium_grid), [MySQL](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/core/testcase_manager.py), [Docker](https://github.com/seleniumbase/SeleniumBase/blob/master/integrations/docker/ReadMe.md), [NodeJS](https://github.com/seleniumbase/SeleniumBase/tree/master/integrations/node_js), [Google Cloud](https://github.com/seleniumbase/SeleniumBase/tree/master/integrations/google_cloud/ReadMe.md), and [AWS](#amazon_section).
9896

99-
**Comes with a business mindset:**<br />
100-
SeleniumBase makes it easy to automate tedious business tasks. (*To learn about businesses using SeleniumBase, [Click Here](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/happy_customers.md).*)
97+
#### **Automate tedious business tasks:**<br />
98+
Beyond test automation, SeleniumBase is perfect for automating tedious business tasks that you would perform in a web browser.
10199

102-
**Extensively tested and made with love:**<br />
103-
SeleniumBase was originally built for [testing HubSpot's platform](https://product.hubspot.com/blog/bid/88880/Automated-Integration-Testing-with-Selenium-at-HubSpot) and automating business processes. In 2014, SeleniumBase was open-sourced and spun off as its own independent entity to benefit users everywhere.
100+
#### **Lots of Happy Customers:**<br />
101+
(*To learn about businesses using SeleniumBase, [Click Here](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/happy_customers.md).*)
104102

105-
**Feature-Rich:**<br />
103+
#### **Feature-Rich:**<br />
106104
([Read more about SeleniumBase features here](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/features_list.md))
107105

108106
<a id="seleniumbase_installation"></a>
109-
<img src="https://cdn2.hubspot.net/hubfs/100006/images/SB_Logo3g.png" title="SeleniumBase" height="48">
107+
<img src="https://cdn2.hubspot.net/hubfs/100006/images/SB_Logo3g4.png" title="SeleniumBase" height="45">
110108

111109
## Detailed Instructions:
112110

@@ -256,6 +254,8 @@ Now you can install webdrivers by doing this:
256254
seleniumbase install chromedriver
257255
seleniumbase install geckodriver
258256
seleniumbase install edgedriver
257+
seleniumbase install iedriver
258+
seleniumbase install operadriver
259259
```
260260

261261
Remember, you'll need chromedriver if you want to run automation on Chrome, geckodriver if you want to run automation on Firefox, edgedriver for Microsoft Edge, etc.
@@ -696,4 +696,4 @@ Congratulations on getting started with SeleniumBase!
696696

697697
[https://github.com/mdmintz](https://github.com/mdmintz)<br />
698698

699-
[<img src="https://cdn2.hubspot.net/hubfs/100006/images/SB_Logo3g.png" title="SeleniumBase" height="60">](https://github.com/seleniumbase/SeleniumBase/blob/master/README.md) <br /> <img src="https://cdn2.hubspot.net/hubfs/100006/images/logo_base_4b.png" title="SeleniumBase" height="150">
699+
[<img src="https://cdn2.hubspot.net/hubfs/100006/images/SB_Logo3g4.png" title="SeleniumBase" height="45">](https://github.com/seleniumbase/SeleniumBase/blob/master/README.md) <br /> <img src="https://cdn2.hubspot.net/hubfs/100006/images/logo_base_4b.png" title="SeleniumBase" height="150">

help_docs/virtualenv_instructions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export WORKON_HOME=$HOME/.virtualenvs
1111
source /usr/local/bin/virtualenvwrapper.sh
1212
```
1313

14-
If you add ``source /usr/local/bin/virtualenvwrapper.sh`` to your local bash file (``~/.bash_profile`` on a Mac, or ``~/.bashrc`` on Linux), virtualenvwrapper commands will be available whenever you open a new command prompt. Use the ``source`` command on those files to activate any changes you make.
14+
If you add ``source /usr/local/bin/virtualenvwrapper.sh`` to your local bash file (``~/.bash_profile`` on a Mac, or ``~/.bashrc`` on Linux), virtualenvwrapper commands will be available whenever you open a new command prompt.
1515

1616
### WINDOWS:
1717

seleniumbase/core/browser_launcher.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,20 @@
1313
from seleniumbase import drivers # webdriver storage folder for SeleniumBase
1414
DRIVER_DIR = os.path.dirname(os.path.realpath(drivers.__file__))
1515
PLATFORM = sys.platform
16+
IS_WINDOWS = False
1617
LOCAL_CHROMEDRIVER = None
1718
LOCAL_GECKODRIVER = None
1819
LOCAL_EDGEDRIVER = None
20+
LOCAL_IEDRIVER = None
1921
LOCAL_OPERADRIVER = None
2022
if "darwin" in PLATFORM or "linux" in PLATFORM:
2123
LOCAL_CHROMEDRIVER = DRIVER_DIR + '/chromedriver'
2224
LOCAL_GECKODRIVER = DRIVER_DIR + '/geckodriver'
2325
LOCAL_OPERADRIVER = DRIVER_DIR + '/operadriver'
2426
elif "win32" in PLATFORM or "win64" in PLATFORM or "x64" in PLATFORM:
27+
IS_WINDOWS = True
2528
LOCAL_EDGEDRIVER = DRIVER_DIR + '/MicrosoftWebDriver.exe'
29+
LOCAL_IEDRIVER = DRIVER_DIR + '/IEDriverServer.exe'
2630
LOCAL_CHROMEDRIVER = DRIVER_DIR + '/chromedriver.exe'
2731
LOCAL_GECKODRIVER = DRIVER_DIR + '/geckodriver.exe'
2832
LOCAL_OPERADRIVER = DRIVER_DIR + '/operadriver.exe'
@@ -279,8 +283,27 @@ def get_local_driver(browser_name, headless, proxy_string):
279283
raise Exception(e)
280284
return webdriver.Firefox()
281285
elif browser_name == constants.Browser.INTERNET_EXPLORER:
282-
return webdriver.Ie()
286+
if not IS_WINDOWS:
287+
raise Exception(
288+
"IE Browser is for Windows-based operating systems only!")
289+
ie_caps = DesiredCapabilities.INTERNETEXPLORER.copy()
290+
ie_caps['ignoreProtectedModeSettings'] = True
291+
ie_caps['IntroduceInstabilityByIgnoringProtectedModeSettings'] = True
292+
ie_caps['nativeEvents'] = True
293+
ie_caps['ignoreZoomSetting'] = True
294+
ie_caps['requireWindowFocus'] = True
295+
ie_caps['INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS'] = True
296+
if LOCAL_IEDRIVER and os.path.exists(LOCAL_IEDRIVER):
297+
make_driver_executable_if_not(LOCAL_IEDRIVER)
298+
return webdriver.Ie(
299+
capabilities=ie_caps,
300+
executable_path=LOCAL_IEDRIVER)
301+
else:
302+
return webdriver.Ie(capabilities=ie_caps)
283303
elif browser_name == constants.Browser.EDGE:
304+
if not IS_WINDOWS:
305+
raise Exception(
306+
"Edge Browser is for Windows-based operating systems only!")
284307
edge_capabilities = DesiredCapabilities.EDGE.copy()
285308
if LOCAL_EDGEDRIVER and os.path.exists(LOCAL_EDGEDRIVER):
286309
make_driver_executable_if_not(LOCAL_EDGEDRIVER)

seleniumbase/fixtures/base_case.py

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def test_anything(self):
4848
from seleniumbase.fixtures import page_utils
4949
from seleniumbase.fixtures import xpath_to_css
5050
from selenium.common.exceptions import (StaleElementReferenceException,
51+
MoveTargetOutOfBoundsException,
5152
WebDriverException)
5253
from selenium.common import exceptions as selenium_exceptions
5354
try:
@@ -115,24 +116,30 @@ def click(self, selector, by=By.CSS_SELECTOR,
115116
self.__scroll_to_element(element)
116117
pre_action_url = self.driver.current_url
117118
try:
118-
element.click()
119+
if self.browser == 'ie' and by == By.LINK_TEXT:
120+
# An issue with clicking Link Text on IE means using jquery
121+
self.__jquery_click(selector, by=by)
122+
else:
123+
# Normal click
124+
element.click()
119125
except (StaleElementReferenceException, ENI_Exception):
120126
self.wait_for_ready_state_complete()
121127
time.sleep(0.05)
122128
element = page_actions.wait_for_element_visible(
123129
self.driver, selector, by, timeout=timeout)
124130
element.click()
125-
except WebDriverException:
131+
except (WebDriverException, MoveTargetOutOfBoundsException):
126132
self.wait_for_ready_state_complete()
127-
if not by == By.LINK_TEXT:
128-
# Only use a JavaScript click if not clicking by Link Text
133+
try:
129134
self.__js_click(selector, by=by)
130-
else:
131-
# One more attempt to click on the element
132-
element = page_actions.wait_for_element_visible(
133-
self.driver, selector, by, timeout=timeout)
134-
element.click()
135-
135+
except Exception:
136+
try:
137+
self.__jquery_click(selector, by=by)
138+
except Exception:
139+
# One more attempt to click on the element
140+
element = page_actions.wait_for_element_visible(
141+
self.driver, selector, by, timeout=timeout)
142+
element.click()
136143
if settings.WAIT_FOR_RSC_ON_CLICKS:
137144
self.wait_for_ready_state_complete()
138145
if self.demo_mode:
@@ -2431,6 +2438,18 @@ def __js_click(self, selector, by=By.CSS_SELECTOR):
24312438
% css_selector)
24322439
self.execute_script(script)
24332440

2441+
def __jquery_click(self, selector, by=By.CSS_SELECTOR):
2442+
""" Clicks an element using jQuery. Different from using pure JS. """
2443+
selector, by = self.__recalculate_selector(selector, by)
2444+
self.wait_for_element_present(
2445+
selector, by=by, timeout=settings.SMALL_TIMEOUT)
2446+
if self.is_element_visible(selector, by=by):
2447+
self.__demo_mode_highlight_if_active(selector, by)
2448+
selector = self.convert_to_css_selector(selector, by=by)
2449+
selector = self.__make_css_match_first_element_only(selector)
2450+
click_script = """jQuery('%s')[0].click()""" % selector
2451+
self.safe_execute_script(click_script)
2452+
24342453
def __get_href_from_link_text(self, link_text, hard_fail=True):
24352454
href = self.get_link_attribute(link_text, "href", hard_fail)
24362455
if not href:
@@ -2587,6 +2606,7 @@ def __post_messenger_success_message(self, message, duration=None):
25872606
else:
25882607
duration = self.message_duration
25892608
try:
2609+
self.set_messenger_theme(theme="future", location="bottom_right")
25902610
self.post_message(message, style="success", duration=duration)
25912611
time.sleep(duration)
25922612
except Exception:

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
setup(
99
name='seleniumbase',
10-
version='1.14.0',
10+
version='1.14.1',
1111
description='Web Automation & Testing Framework - http://seleniumbase.com',
1212
long_description='Web Automation and Testing Framework - seleniumbase.com',
1313
platforms='Mac * Windows * Linux * Docker',

0 commit comments

Comments
 (0)