Skip to content

Commit 67f6293

Browse files
authored
Merge pull request #950 from seleniumbase/reliability-and-other-improvements
Reliability and other improvements
2 parents 8a81f9e + 0f3fe8e commit 67f6293

File tree

8 files changed

+53
-38
lines changed

8 files changed

+53
-38
lines changed

README.md

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
<link rel="icon" href="https://seleniumbase.io/img/logo6.png" />
77

88
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/">
9-
<img src="https://seleniumbase.io/cdn/img/long_logo.png" alt="SeleniumBase" title="SeleniumBase" width="690" /></a></p>
9+
<img src="https://seleniumbase.io/cdn/img/logo_and_pie.png" alt="SeleniumBase" title="SeleniumBase" width="690" /></a></p>
1010
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/releases">
1111
<img src="https://img.shields.io/github/v/release/seleniumbase/SeleniumBase.svg?color=0090c0" alt="Latest Release on GitHub" /></a> <a href="https://pypi.org/project/seleniumbase/">
1212
<img src="https://img.shields.io/pypi/v/seleniumbase.svg?color=00a0e0" alt="Latest Release on PyPI" /></a></p>
1313
<p align="center">
14-
<b>Python Web UI Testing Made Easy.</b>
14+
<b>Python Web-UI Testing Made Awesome.</b>
1515
</p>
1616

1717
<!-- View on GitHub -->
@@ -20,27 +20,31 @@
2020
<img src="https://badges.gitter.im/seleniumbase/SeleniumBase.svg" alt="SeleniumBase" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/stargazers"><img src="https://img.shields.io/github/stars/seleniumbase/seleniumbase.svg?color=19A57B" title="Stargazers" /></a> <a href="https://seleniumbase.io">
2121
<img src="https://img.shields.io/badge/docs-%20seleniumbase.io-22BBAA.svg" alt="SeleniumBase.io Docs" /></a></p>
2222

23-
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_swag_labs.py"><img src="https://seleniumbase.io/cdn/gif/swag_labs_gif.gif" alt="SeleniumBase Demo Mode" title="SeleniumBase Demo Mode" /></a></p>
24-
25-
<p align="center">
26-
<b>SeleniumBase is a complete framework for automated browser testing with pytest.</b>
23+
<p align="left">
24+
✅ SeleniumBase is a Python framework for web testing.<br / >
25+
✅ Tests can be run with <b>pytest</b> from the command-line.<br / >
26+
✅ Includes code to simplify & improve WebDriver APIs.<br / >
27+
✅ Supports Chrome, Edge, Firefox, IE, Opera, and Safari.<br />
28+
✅ Includes powerful <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/example_logs/ReadMe.md">reporting and dashboard features</a>.
2729
</p>
2830

31+
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py"><img src="https://seleniumbase.io/cdn/gif/demo_page_1.gif" alt="SeleniumBase Demo Mode" title="SeleniumBase Demo Mode" width="450" /></a></p>
32+
2933
<p align="center">
3034
<a href="#python_installation">🚀 Start</a> |
31-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/features_list.md">🗂️ Features</a> |
35+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/ReadMe.md">📖 Examples</a> |
3236
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/customizing_test_runs.md">🖥️ CLI</a> |
33-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/ReadMe.md">📖 Examples</a>
34-
<br />
35-
<a href="https://github.com/seleniumbase/SeleniumBase/tree/master/examples/boilerplates">♻️ Boilerplates</a> |
36-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/locale_codes.md">🗾 Locales</a> |
37-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/js_package_manager.md">🗄️ PkgManager</a>
37+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/features_list.md">🗂️ Features</a>
3838
<br />
39-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/method_summary.md">📗 API</a> |
4039
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/example_logs/ReadMe.md">📋 Reports</a> |
40+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/method_summary.md">📗 API</a> |
4141
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/console_scripts/ReadMe.md">💻 Scripts</a> |
4242
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/mobile_testing.md">📱 Mobile</a>
4343
<br />
44+
<a href="https://github.com/seleniumbase/SeleniumBase/tree/master/examples/boilerplates">♻️ Boilerplates</a> |
45+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/locale_codes.md">🗾 Locales</a> |
46+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/js_package_manager.md">🗄️ PkgManager</a>
47+
<br />
4448
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/syntax_formats.md">🔡 SyntaxFormats</a> |
4549
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/utilities/selenium_grid/ReadMe.md">🌐 GridHub</a> |
4650
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/utilities/selenium_ide/ReadMe.md">⏺️ Recorder</a>
@@ -55,9 +59,6 @@
5559
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/master_qa/ReadMe.md">🛂 MasterQA</a>
5660
</p>
5761

58-
✅ Chrome/Edge/Firefox/IE/Opera/Safari.<br />
59-
✅ Includes [reporting and dashboard tools](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/example_logs/ReadMe.md).
60-
6162
--------
6263

6364
<p align="left">Example: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py">my_first_test.py</a> (<code>--demo</code> mode)</p>
@@ -191,7 +192,7 @@ pytest test_demo_site.py
191192
192193
> (Chrome is the default browser if not specified with ``--browser=BROWSER``. On Linux, ``--headless`` is the default behavior. You can also run in headless mode on any OS. If your Linux machine has a GUI and you want to see the web browser as tests run, add ``--headed`` or ``--gui``.)
193194
194-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py"><img src="https://seleniumbase.io/cdn/gif/demo_page_1.gif" title="SeleniumBase Demo Page" /></a><br />
195+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py"><img src="https://seleniumbase.io/cdn/gif/demo_page_1.gif" title="SeleniumBase Demo Page" width="450" /></a><br />
195196
196197
🔵 <b>Here are more examples that you can run:</b>
197198

examples/example_logs/ReadMe.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<h3><img src="https://seleniumbase.io/img/logo6.png" title="SeleniumBase" width="32" /> Logging, Dashboards, and Reports:</h3>
22

33
[<img src="http://img.youtube.com/vi/XpuJCjJhJwQ/0.jpg" title="SeleniumBase Features" width="285">](https://www.youtube.com/watch?v=XpuJCjJhJwQ)
4-
<p>(<b><a href="https://www.youtube.com/watch?v=XpuJCjJhJwQ">SBase Dashboard Tutorial on YouTube</a></b>)</p>
4+
<p>(<b><a href="https://www.youtube.com/watch?v=XpuJCjJhJwQ">The Dashboard Tutorial on YouTube</a></b>)</p>
55

66
🔵 During test failures, logs and screenshots from the most recent test run will get saved to the ``latest_logs/`` folder. If ``--archive-logs`` is specified (or if ARCHIVE_EXISTING_LOGS is set to True in [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py)), test logs will also get archived to the ``archived_logs/`` folder. Otherwise, the log files will be cleaned out when the next test run begins (by default).
77

examples/test_chinese_pdf.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# -*- coding: utf-8 -*-
2-
import sys
32
from seleniumbase import BaseCase
43

54

@@ -13,10 +12,7 @@ def test_chinese_pdf(self):
1312

1413
# Get and print PDF text
1514
pdf_text = self.get_pdf_text(pdf, page=2)
16-
if sys.version_info[0] >= 3:
17-
print("\n" + pdf_text, file=sys.stderr) # noqa
18-
else:
19-
print("\n" + pdf_text) # Use older print()
15+
self._print("\n" + pdf_text)
2016

2117
# Assert PDF contains the expected text on Page 2
2218
self.assert_pdf_text(pdf, "个测试类", page=2)

examples/test_get_pdf_text.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import sys
21
from seleniumbase import BaseCase
32

43

@@ -9,7 +8,4 @@ def test_get_pdf_text(self):
98
"Automate_the_Boring_Stuff_sample_ch17.pdf"
109
)
1110
pdf_text = self.get_pdf_text(pdf, page=1)
12-
if sys.version_info[0] >= 3:
13-
print("\n" + pdf_text, file=sys.stderr) # noqa
14-
else:
15-
print("\n" + pdf_text) # Use older print()
11+
self._print("\n" + pdf_text)

requirements.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
pip>=20.3.4;python_version<"3.6"
2-
pip>=21.1.3;python_version>="3.6"
2+
pip>=21.2.1;python_version>="3.6"
33
packaging>=20.9;python_version<"3.6"
44
packaging>=21.0;python_version>="3.6"
55
typing-extensions>=3.10.0.0
@@ -82,7 +82,8 @@ ipython==7.16.1;python_version>="3.6" and python_version<"3.7"
8282
ipython==7.25.0;python_version>="3.7"
8383
matplotlib-inline==0.1.2;python_version>="3.7"
8484
colorama==0.4.4
85-
platformdirs==2.0.2
85+
platformdirs==2.0.2;python_version<"3.6"
86+
platformdirs==2.2.0;python_version>="3.6"
8687
pathlib2==2.3.5;python_version<"3.5"
8788
importlib-metadata==2.0.0;python_version<"3.6"
8889
virtualenv>=20.6.0

seleniumbase/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# seleniumbase package
2-
__version__ = "1.63.17"
2+
__version__ = "1.63.18"

seleniumbase/fixtures/base_case.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,6 +1424,7 @@ def click_nth_visible_element(
14241424
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
14251425
timeout = self.__get_new_timeout(timeout)
14261426
selector, by = self.__recalculate_selector(selector, by)
1427+
self.wait_for_ready_state_complete()
14271428
self.wait_for_element_present(selector, by=by, timeout=timeout)
14281429
elements = self.find_visible_elements(selector, by=by)
14291430
if len(elements) < number:
@@ -1435,14 +1436,23 @@ def click_nth_visible_element(
14351436
if number < 0:
14361437
number = 0
14371438
element = elements[number]
1438-
self.wait_for_ready_state_complete()
14391439
try:
14401440
self.__scroll_to_element(element)
14411441
element.click()
14421442
except (StaleElementReferenceException, ENI_Exception):
1443-
self.wait_for_ready_state_complete()
14441443
time.sleep(0.12)
1445-
self.__scroll_to_element(element)
1444+
self.wait_for_ready_state_complete()
1445+
self.wait_for_element_present(selector, by=by, timeout=timeout)
1446+
elements = self.find_visible_elements(selector, by=by)
1447+
if len(elements) < number:
1448+
raise Exception(
1449+
"Not enough matching {%s} elements of type {%s} to "
1450+
"click number %s!" % (selector, by, number)
1451+
)
1452+
number = number - 1
1453+
if number < 0:
1454+
number = 0
1455+
element = elements[number]
14461456
element.click()
14471457

14481458
def click_if_visible(self, selector, by=By.CSS_SELECTOR):
@@ -4083,6 +4093,8 @@ def set_value(self, selector, text, by=By.CSS_SELECTOR, timeout=None):
40834093
if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT:
40844094
timeout = self.__get_new_timeout(timeout)
40854095
selector, by = self.__recalculate_selector(selector, by, xp_ok=False)
4096+
self.wait_for_ready_state_complete()
4097+
self.wait_for_element_present(selector, by=by, timeout=timeout)
40864098
orginal_selector = selector
40874099
css_selector = self.convert_to_css_selector(selector, by=by)
40884100
self.__demo_mode_highlight_if_active(orginal_selector, by)
@@ -4853,8 +4865,16 @@ def block_ads(self):
48534865
self.ad_block()
48544866

48554867
def _print(self, msg):
4856-
""" Same as Python's print() """
4857-
print(msg)
4868+
"""Same as Python's print(), but won't print during multithreaded runs
4869+
because overlapping print() commands may lead to unexpected output.
4870+
In most cases, the print() command won't print for multithreaded tests,
4871+
but there are some exceptions, and this will take care of those.
4872+
Here's an example of running tests multithreaded: "pytest -n=4".
4873+
To force a print during multithreaded tests, use: "sys.stderr.write()".
4874+
To print without the new-line character end, use: "sys.stdout.write()".
4875+
"""
4876+
if not sb_config._multithreaded:
4877+
print(msg)
48584878

48594879
def start_tour(self, name=None, interval=0):
48604880
self.play_tour(name=name, interval=interval)

setup.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@
114114
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*",
115115
install_requires=[
116116
'pip>=20.3.4;python_version<"3.6"',
117-
'pip>=21.1.3;python_version>="3.6"',
117+
'pip>=21.2.1;python_version>="3.6"',
118118
'packaging>=20.9;python_version<"3.6"',
119119
'packaging>=21.0;python_version>="3.6"',
120120
"typing-extensions>=3.10.0.0",
@@ -197,7 +197,8 @@
197197
'ipython==7.25.0;python_version>="3.7"',
198198
'matplotlib-inline==0.1.2;python_version>="3.7"',
199199
"colorama==0.4.4",
200-
"platformdirs==2.0.2",
200+
'platformdirs==2.0.2;python_version<"3.6"',
201+
'platformdirs==2.2.0;python_version>="3.6"',
201202
'pathlib2==2.3.5;python_version<"3.5"', # Sync with "virtualenv"
202203
'importlib-metadata==2.0.0;python_version<"3.6"', # Sync "virtualenv"
203204
"virtualenv>=20.6.0", # Sync with importlib-metadata and pathlib2

0 commit comments

Comments
 (0)