Skip to content

Commit 7fddf8f

Browse files
authored
Merge pull request #145 from seleniumbase/major-upgrade
Major upgrade
2 parents d36d54e + 52b6011 commit 7fddf8f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+542
-286
lines changed

.travis.yml

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,18 @@ addons:
77
chrome: stable
88
install:
99
- "pip install --upgrade pip"
10-
- "pip install -r requirements.txt"
10+
- "pip install -r requirements.txt --upgrade"
1111
- "python setup.py develop"
1212
- "sudo rm -f /etc/boto.cfg"
1313
before_script:
14-
- "flake8 seleniumbase/*.py"
15-
- "flake8 seleniumbase/*/*.py"
16-
- "flake8 seleniumbase/*/*/*.py"
17-
- "flake8 seleniumbase/*/*/*/*.py"
18-
- "export DISPLAY=:99.0"
19-
- "sh -e /etc/init.d/xvfb start"
14+
- "flake8 seleniumbase/*.py && flake8 seleniumbase/*/*.py && flake8 seleniumbase/*/*/*.py && flake8 seleniumbase/*/*/*/*.py"
15+
- "export DISPLAY=:99.0 && sh -e /etc/init.d/xvfb start"
16+
- "wget https://chromedriver.storage.googleapis.com/2.33/chromedriver_linux64.zip && unzip chromedriver_linux64.zip && sudo cp chromedriver /usr/local/bin/ && sudo chmod +x /usr/local/bin/chromedriver"
2017
- "wget https://github.com/mozilla/geckodriver/releases/download/v0.19.0/geckodriver-v0.19.0-linux64.tar.gz -O /tmp/geckodriver.tar.gz && tar -C /opt -xzf /tmp/geckodriver.tar.gz && sudo chmod 755 /opt/geckodriver && sudo ln -fs /opt/geckodriver /usr/bin/geckodriver && sudo ln -fs /opt/geckodriver /usr/local/bin/geckodriver"
21-
- "wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2;"
22-
- "tar -xvf ./phantomjs-2.1.1-linux-x86_64.tar.bz2;"
23-
- "export PATH=$PWD/phantomjs-2.1.1-linux-x86_64/bin:$PATH;"
24-
- "phantomjs --version"
25-
- "firefox --version"
26-
- wget http://chromedriver.storage.googleapis.com/2.32/chromedriver_linux64.zip
27-
- unzip chromedriver_linux64.zip
28-
- sudo cp chromedriver /usr/local/bin/
29-
- sudo chmod +x /usr/local/bin/chromedriver
18+
# - "wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 && tar -xvf ./phantomjs-2.1.1-linux-x86_64.tar.bz2 && export PATH=$PWD/phantomjs-2.1.1-linux-x86_64/bin:$PATH"
3019
script:
31-
- "nosetests examples/my_first_test.py --browser=chrome -s"
20+
- "pytest examples/my_first_test.py --browser=chrome -s"
21+
- "nosetests examples/boilerplates/boilerplate_test.py"
3222
- "pytest examples/my_first_test.py --browser=firefox -s"
33-
- "pytest examples/my_first_test.py --browser=phantomjs"
3423
notifications:
3524
email: false

Dockerfile

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ RUN apt-get -qy --no-install-recommends install \
7676
#===================
7777
# Install PhantomJS
7878
#===================
79-
RUN cd /usr/local/share && wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
80-
RUN cd /usr/local/share && tar xjf phantomjs-2.1.1-linux-x86_64.tar.bz2
81-
RUN ln -s /usr/local/share/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/share/phantomjs
82-
RUN ln -s /usr/local/share/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin/phantomjs
83-
RUN ln -s /usr/local/share/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/bin/phantomjs
79+
# RUN cd /usr/local/share && wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
80+
# RUN cd /usr/local/share && tar xjf phantomjs-2.1.1-linux-x86_64.tar.bz2
81+
# RUN ln -s /usr/local/share/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/share/phantomjs
82+
# RUN ln -s /usr/local/share/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin/phantomjs
83+
# RUN ln -s /usr/local/share/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/bin/phantomjs
8484

8585
#===========================
8686
# Configure Virtual Display
@@ -109,7 +109,6 @@ RUN cd /SeleniumBase && python setup.py develop
109109
COPY integrations/docker/docker-entrypoint.sh /
110110
COPY integrations/docker/run_docker_test_in_firefox.sh /
111111
COPY integrations/docker/run_docker_test_in_chrome.sh /
112-
COPY integrations/docker/run_docker_test_in_phantomjs.sh /
113112
RUN chmod +x *.sh
114113
COPY integrations/docker/docker_config.cfg /SeleniumBase/examples/
115114
ENTRYPOINT ["/docker-entrypoint.sh"]

README.md

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
![](https://cdn2.hubspot.net/hubfs/100006/images/SB_Logo8s.png "SeleniumBase")
1+
<img src="https://cdn2.hubspot.net/hubfs/100006/images/SeleniumBase_Home.png" title="SeleniumBase" height="50">
22

33
**WebDriver automation simplified by extending Python's unittest framework.**
44

55
[![](https://img.shields.io/pypi/v/seleniumbase.svg)](https://pypi.python.org/pypi/seleniumbase) [![Build Status](https://travis-ci.org/seleniumbase/SeleniumBase.svg?branch=master)](https://travis-ci.org/seleniumbase/SeleniumBase) [![Join the chat at https://gitter.im/seleniumbase/SeleniumBase](https://badges.gitter.im/seleniumbase/SeleniumBase.svg)](https://gitter.im/seleniumbase/SeleniumBase?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
66

7-
SeleniumBase simplifies web automation & testing with WebDriver in the same way that jQuery, AnglularJS, and ReactJS simplify web development with JavaScript. All tests using SeleniumBase's BaseCase class inherit Python's unittest.TestCase class, which allows for running tests automatically with Pytest and Nosetest. This framework can use the Page Object Model for test structure, as well as all features of WebDriver and Python's unittest.
7+
SeleniumBase simplifies web automation & testing with WebDriver in the same way that jQuery, AnglularJS, and ReactJS simplify web development with JavaScript. All tests using SeleniumBase's BaseCase class inherit Python's unittest.TestCase class, allowing users to run tests automatically with Pytest and Nose. Tests can use the Page Object Model for structure, as well as all features of Python and WebDriver.
88

99
![](https://cdn2.hubspot.net/hubfs/100006/images/sb_demo.gif "SeleniumBase")
1010

@@ -101,8 +101,6 @@ cd examples/
101101
pytest my_first_test.py --browser=chrome
102102

103103
nosetests my_first_test.py --browser=firefox
104-
105-
nosetests my_first_test.py --browser=phantomjs
106104
```
107105
(<i>If no browser is specified, Chrome is used by default.</i>)
108106

@@ -147,14 +145,14 @@ Here are some other useful nosetest arguments for appending to your run commands
147145
--with-id # If -v is also used, will number the tests for easy counting.
148146
```
149147

150-
The ``--with-testing_base`` plugin gives you full logging on test failures, which saves screenshots, page source, and basic test info into the logs folder:
148+
During test failures you'll get detailed log files, which include screenshots, page source, and basic test info, which will get added to the logs folder at ``latest_logs/``. (Unless you have ARCHIVE_EXISTING_LOGS set to True in [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py), log files with be cleaned up at the start of the next test run. If the archive feature is enabled, those logs will get saved to the ``archived_logs/`` folder.) The ``my_test_suite.py`` collection contains tests that fail on purpose so that you can see how logging works.
151149

152150
```bash
153151
cd examples/
154152

155-
pytest my_first_test.py --with-testing_base --browser=chrome
153+
pytest my_test_suite.py --browser=chrome
156154

157-
pytest my_first_test.py --with-testing_base --browser=firefox
155+
pytest my_test_suite.py --browser=firefox
158156
```
159157

160158
If you want to run tests headlessly, use ``--headless``, which you'll need to do if your system lacks a GUI interface. Even if your system does have a GUI interface, it may still support headless browser automation.
@@ -165,6 +163,7 @@ For running tests outside of the SeleniumBase repo with **Nosetests**, you'll wa
165163

166164
If you want to pass additional data from the command line to your tests, you can use ``--data=STRING``. Now inside your tests, you can use ``self.data`` to access that.
167165

166+
To run Pytest multithreaded on multiple CPUs at the same time, add ``-n NUM`` on the command line, where NUM is the number of CPUs you want to use.
168167

169168
<a id="creating_visual_reports"></a>
170169
### ![http://seleniumbase.com](https://cdn2.hubspot.net/hubfs/100006/images/super_logo_tiny.png "SeleniumBase") **Creating Visual Test Suite Reports:**
@@ -179,22 +178,42 @@ Using ``--html=report.html`` gives you a fancy report of the name specified afte
179178
pytest my_test_suite.py --html=report.html
180179
```
181180

181+
You can also use ``--junitxml=report.xml`` to get an xml report instead. Jenkins can use this file to display better reporting for your tests.
182+
183+
```bash
184+
pytest my_test_suite.py --junitxml=report.xml
185+
```
186+
182187
![](https://cdn2.hubspot.net/hubfs/100006/images/PytestReport.png "Example Pytest Report")
183188

184189
#### **Nosetest Reports:**
185190

186-
The ``--report`` option gives you a fancy report after your test suite completes. (Requires ``--with-testing_base`` to also be set when ``--report`` is used because it's part of that plugin.)
191+
The ``--report`` option gives you a fancy report after your test suite completes.
187192

188193
```bash
189-
nosetests my_test_suite.py --with-testing_base --report
194+
nosetests my_test_suite.py --report
190195
```
191-
![](https://cdn2.hubspot.net/hubfs/100006/images/Test_Report_2.png "Example Nosetest Report")
196+
<img src="https://cdn2.hubspot.net/hubfs/100006/images/Test_Report_2.png" title="Example Nosetest Report" height="450">
192197

193198
(NOTE: You can add ``--show_report`` to immediately display Nosetest reports after the test suite completes. Only use ``--show_report`` when running tests locally because it pauses the test run.)
194199

195200

201+
### ![http://seleniumbase.com](https://cdn2.hubspot.net/hubfs/100006/images/super_logo_tiny.png "SeleniumBase") **Using a Proxy Server:**
202+
203+
If you wish to use a proxy server for your browser tests (Chrome and Firefox only), you can add ``--proxy=IP_ADDRESS:PORT`` as an argument on the command line.
204+
205+
```bash
206+
pytest proxy_test.py --proxy=IP_ADDRESS:PORT
207+
```
208+
209+
To make things easier, you can add your frequently-used proxies to PROXY_LIST in [proxy_list.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/proxy_list.py), and then use ``--proxy=KEY_FROM_PROXY_LIST`` to use the IP_ADDRESS:PORT of that key.
210+
211+
```bash
212+
pytest proxy_test.py --proxy=proxy1
213+
```
214+
196215
<a id="utilizing_advanced_features"></a>
197-
### ![http://seleniumbase.com](https://cdn2.hubspot.net/hubfs/100006/images/super_logo_tiny.png "SeleniumBase") **Using Production Environments & Integrations:**
216+
### ![http://seleniumbase.com](https://cdn2.hubspot.net/hubfs/100006/images/super_logo_tiny.png "SeleniumBase") **Production Environments & Integrations:**
198217

199218
Here are some things you can do to setup a production environment for your testing:
200219

@@ -217,7 +236,7 @@ pip install MySQL-python==1.2.5
217236

218237
Here's an example of running tests with additional features enabled:
219238
```bash
220-
nosetests [YOUR_TEST_FILE].py --browser=chrome --with-testing_base --with-db_reporting --with-s3_logging -s
239+
nosetests [YOUR_TEST_FILE].py --browser=chrome --with-db_reporting --with-s3_logging -s
221240
```
222241
(NOTE: If you haven't configured your MySQL or S3 connections in [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py), don't use ``--with-db_reporting`` or ``--with-s3_logging``.)
223242

@@ -237,7 +256,7 @@ If you tell nosetests to run an entire file, it will run every method in that py
237256
nosetests [YOUR_TEST_FILE].py:[SOME_CLASS_NAME].test_[SOME_TEST_NAME] --config=[MY_CONFIG_FILE].cfg
238257
```
239258

240-
Let's try an example of a test that fails. Copy the following into a file called fail_test.py:
259+
Let's try an example of a test that fails:
241260
```python
242261
""" test_fail.py """
243262
from seleniumbase import BaseCase
@@ -246,12 +265,13 @@ class MyTestClass(BaseCase):
246265

247266
def test_find_army_of_robots_on_xkcd_desert_island(self):
248267
self.open("http://xkcd.com/731/")
249-
self.assert_element("div#ARMY_OF_ROBOTS", timeout=3) # This should fail
268+
self.assert_element("div#ARMY_OF_ROBOTS", timeout=1) # This should fail
250269
```
251-
Now run it:
270+
271+
You can run it from the ``examples`` folder like this:
252272

253273
```bash
254-
nosetests test_fail.py --browser=chrome --with-testing_base
274+
nosetests test_fail.py
255275
```
256276

257277
You'll notice that a logs folder, "latest_logs", was created to hold information about the failing test, and screenshots. Take a look at what you get. Remember, this data can be saved in your MySQL DB and in S3 if you include the necessary plugins in your run command (and if you set up the neccessary connections properly). For future test runs, past test results will get stored in the archived_logs folder if you have ARCHIVE_EXISTING_LOGS set to True in [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py).
@@ -500,29 +520,29 @@ self.click("a.analytics") # Clicks the generated button
500520
```
501521
(Due to popular demand, this traffic generation example has been baked into SeleniumBase with the ``self.generate_referral(start_page, end_page)`` and the ``self.generate_traffic(start_page, end_page, loops)`` methods.)
502522

503-
#### Using non-terminating verifications:
523+
#### Using delayed asserts:
504524

505-
Let's say you want to verify multiple different elements on a web page in a single test, but you don't want the test to fail until you verified several elements at once so that you don't have to rerun the test to find more missing elements on the same page. That's where page checks come in. Here's the example:
525+
Let's say you want to verify multiple different elements on a web page in a single test, but you don't want the test to fail until you verified several elements at once so that you don't have to rerun the test to find more missing elements on the same page. That's where delayed asserts come in. Here's the example:
506526

507527
```python
508528
from seleniumbase import BaseCase
509529

510530
class MyTestClass(BaseCase):
511531

512-
def test_non_terminating_checks(self):
532+
def test_delayed_asserts(self):
513533
self.open('http://xkcd.com/993/')
514534
self.wait_for_element('#comic')
515-
self.check_assert_element('img[alt="Brand Identity"]')
516-
self.check_assert_element('img[alt="Rocket Ship"]') # Will Fail
517-
self.check_assert_element('#comicmap')
518-
self.check_assert_text('Fake Item', '#middleContainer') # Will Fail
519-
self.check_assert_text('Random', '#middleContainer')
520-
self.check_assert_element('a[name="Super Fake !!!"]') # Will Fail
521-
self.process_checks()
535+
self.delayed_assert_element('img[alt="Brand Identity"]')
536+
self.delayed_assert_element('img[alt="Rocket Ship"]') # Will Fail
537+
self.delayed_assert_element('#comicmap')
538+
self.delayed_assert_text('Fake Item', '#middleContainer') # Will Fail
539+
self.delayed_assert_text('Random', '#middleContainer')
540+
self.delayed_assert_element('a[name="Super Fake !!!"]') # Will Fail
541+
self.process_delayed_asserts()
522542
```
523543

524-
``check_assert_element()`` and ``check_assert_text()`` will save any exceptions that would be raised.
525-
To flush out all the failed checks into a single exception, make sure to call ``self.process_checks()`` at the end of your test method. If your test hits multiple pages, you can call ``self.process_checks()`` at the end of all your checks for a single page. This way, the screenshot from your log file will make the location where the checks were made.
544+
``delayed_assert_element()`` and ``delayed_assert_text()`` will save any exceptions that would be raised.
545+
To flush out all the failed delayed asserts into a single exception, make sure to call ``self.process_delayed_asserts()`` at the end of your test method. If your test hits multiple pages, you can call ``self.process_delayed_asserts()`` at the end of all your delayed asserts for a single page. This way, the screenshot from your log file will have the location where the delayed asserts were made.
526546

527547
#### Accessing raw WebDriver
528548

_config.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
theme: jekyll-theme-cayman
1+
theme: jekyll-theme-minimal
22
title: SeleniumBase
3-
description: WebDriver automation simplified by extending Python's unittest framework.
3+
description: WebDriver enhanced by Pytest extensions

examples/ReadMe.md

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ python gui_test_runner.py
1212

1313
(NOTE: You can interchange ``nosetests`` with ``pytest`` in most of these examples.)
1414

15-
![](https://cdn2.hubspot.net/hubfs/100006/images/GUI_Test_Runner_7.png "GUI Test Runner")
15+
<img src="https://cdn2.hubspot.net/hubfs/100006/images/The_GUI_Runner.png" title="GUI Test Runner" height="400">
1616

17-
If you run scripts with logging enabled, (using ``--with-testing_base``), you’ll see two folders appear: “latest_logs” and “archived_logs”. The “latest_logs” folder will contain log files from the most recent test run, but logs will only be created if the test run is failing. Afterwards, logs from the “latest_logs” folder will get pushed to the “archived_logs” folder if you have have the ``ARCHIVE_EXISTING_LOGS`` feature enabled in [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py).
17+
When you run tests, you’ll see two folders appear: “latest_logs” and “archived_logs”. The “latest_logs” folder will contain log files from the most recent test run, but logs will only be created if the test run is failing. Afterwards, logs from the “latest_logs” folder will get pushed to the “archived_logs” folder if you have have the ``ARCHIVE_EXISTING_LOGS`` feature enabled in [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py).
1818

1919
**For running scripts the usual way, here are some of the example run commands:**
2020

@@ -28,29 +28,19 @@ Run the example test in Firefox:
2828
pytest my_first_test.py --browser=firefox
2929
```
3030

31-
Run the example test in PhantomJS:
32-
```bash
33-
pytest my_first_test.py --browser=phantomjs
34-
```
35-
3631
Run the example test in Demo Mode (runs slower and adds highlights):
3732
```bash
3833
pytest my_first_test.py --browser=chrome --demo_mode
3934
```
4035

4136
Run the example test suite in Chrome and generate an html report: (nosetests-only)
4237
```bash
43-
nosetests my_test_suite.py --browser=chrome --with-testing_base --report
38+
nosetests my_test_suite.py --browser=chrome --report
4439
```
4540

4641
Run the example test suite in Firefox and generate an html report: (nosetests-only)
4742
```bash
48-
nosetests my_test_suite.py --browser=firefox --with-testing_base --report
49-
```
50-
51-
Run the example test suite in PhantomJS and generate an html report: (nosetests-only)
52-
```bash
53-
nosetests my_test_suite.py --browser=phantomjs --with-testing_base --report
43+
nosetests my_test_suite.py --browser=firefox --report
5444
```
5545

5646
Run a test with configuration specifed by a config file:
@@ -68,9 +58,9 @@ Run a failing test with pdb mode enabled: (If a test failure occurs, test enters
6858
nosetests test_fail.py --browser=chrome --pdb --pdb-failures
6959
```
7060

71-
Run a failing test with logging:
61+
Run a failing test (and then look into the ``latest_logs`` folder afterwards:
7262
```bash
73-
pytest test_fail.py --browser=chrome --with-testing_base
63+
pytest test_fail.py --browser=chrome
7464
```
7565

7666
(NOTE: If you see any ``*.pyc`` files appear as you run tests, that's perfectly normal. Compiled bytecode is a natural result of running Python code.)

examples/delayed_assert_test.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from seleniumbase import BaseCase
2+
3+
4+
class MyTestClass(BaseCase):
5+
6+
def test_delayed_asserts(self):
7+
self.open('http://xkcd.com/993/')
8+
self.wait_for_element('#comic')
9+
self.delayed_assert_element('img[alt="Brand Identity"]')
10+
self.delayed_assert_element('img[alt="Rocket Ship"]') # Will Fail
11+
self.delayed_assert_element('#comicmap')
12+
self.delayed_assert_text('Fake Item', '#middleContainer') # Will Fail
13+
self.delayed_assert_text('Random', '#middleContainer')
14+
self.delayed_assert_element('a[name="Super Fake !!!"]') # Will Fail
15+
self.process_delayed_asserts()

examples/example_config.cfg

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
[nosetests]
2-
with-selenium=1
32
with-testing_base=1
4-
with-page_source=1
5-
with-screen_shots=1
6-
with-basic_test_info=1
73
nocapture=1
84
logging-level=INFO
95
browser=chrome

0 commit comments

Comments
 (0)