Skip to content

Commit dce845e

Browse files
authored
Merge pull request #211 from seleniumbase/multi-factor-auth
Add ability to handle time-based Google Authenticator logins
2 parents 5edf702 + cc0fcbf commit dce845e

File tree

7 files changed

+46
-10
lines changed

7 files changed

+46
-10
lines changed

help_docs/features_list.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* Uses a [global config file](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py) for configuring SeleniumBase to your specific needs.
1212
* Backwards-compatible with [WebDriver](http://www.seleniumhq.org/projects/webdriver/). (Use ``self.driver`` anywhere.)
1313
* Can run tests through a proxy server. (Use ``--proxy=IP_ADDRESS:PORT``)
14+
* Can handle Google Authenticator logins by using the [Python one-time password library](https://pyotp.readthedocs.io/en/latest/).
1415
* Includes a hybrid-automation solution called **[MasterQA](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/masterqa/ReadMe.md)** to speed up manual testing.
1516
* Includes integrations with [MySQL](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/core/testcase_manager.py), [Selenium Grid](https://github.com/seleniumbase/SeleniumBase/tree/master/seleniumbase/utilities/selenium_grid), [Google Cloud](https://github.com/seleniumbase/SeleniumBase/tree/master/integrations/google_cloud/ReadMe.md), [Amazon S3](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/plugins/s3_logging_plugin.py), and [NodeJS](https://github.com/seleniumbase/SeleniumBase/tree/master/integrations/node_js).
1617
* Includes a [tool to convert Selenium IDE recordings](https://github.com/seleniumbase/SeleniumBase/tree/master/seleniumbase/utilities/selenium_ide) into clean, robust SeleniumBase scripts.

help_docs/install_python_pip_git.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ If you're having any trouble getting pip, you can [GET PIP HERE](https://pip.pyp
3232

3333
When done, make sure the location of pip is on your path, which is `$PATH` for Mac/Linux. (On Windows, it's the System Variables `Path` within System Environment Variables. Ex: Add "C:/Python27/Scripts/" to the end of the `Path` variable.)
3434

35+
You can also get pip (or fix pip) by using:
36+
```bash
37+
curl https://bootstrap.pypa.io/get-pip.py | python
38+
```
39+
40+
(If you get SSL errors while trying to install packages with pip, see [this Stackoverflow post](https://stackoverflow.com/questions/49768770/not-able-to-install-python-packages-ssl-tlsv1-alert-protocol-version), which tells you to run the above command.)
41+
3542
### [Homebrew](http://brew.sh/) (MAC-ONLY) (OPTIONAL)
3643

3744
The Homebrew package manager allows you to install things more easily on MacOS, such as Git and Chromedriver.

help_docs/method_summary.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ self.is_downloaded_file_present(file)
162162

163163
self.assert_downloaded_file(file)
164164

165+
self.get_google_auth_password(totp_key=None)
166+
165167
self.convert_xpath_to_css(xpath)
166168

167169
self.convert_to_css_selector(selector, by)

requirements.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
pip
2+
ipython
23
setuptools
34
selenium==3.14.1
4-
ipython==5.6.0
55
pytest>=3.8.1
6-
pytest-html>=1.19.0
7-
pytest-xdist>=1.23.0
86
pytest-cov>=2.6.0
7+
pytest-html>=1.19.0
98
pytest-rerunfailures>=4.1
9+
pytest-xdist>=1.23.0
1010
parameterized==0.6.1
1111
six>=1.11.0
12+
pyotp>=2.2.6
1213
requests>=2.19.1
1314
beautifulsoup4==4.6.3
1415
unittest2==1.1.0

seleniumbase/config/settings.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,14 @@
8888

8989

9090
# #####>>>>>----- RECOMMENDED SETTINGS -----<<<<<#####
91-
# ##### (For database reporting, saving test logs, and password encryption)
91+
# ##### (For multi-factor auth, DB/cloud logging, and password encryption)
92+
93+
# Google Authenticator
94+
# (For 2-factor authentication using a time-based one-time password algorithm)
95+
# (See https://github.com/pyotp/pyotp and https://pypi.org/project/pyotp/ )
96+
# (Also works with Authy and other compatible apps.)
97+
TOTP_KEY = "base32secretABCD"
98+
9299

93100
# MySQL DB Credentials
94101
# (For saving data from tests)

seleniumbase/fixtures/base_case.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ def test_anything(self):
2121
Code becomes greatly simplified and easier to maintain.
2222
"""
2323

24-
import getpass
2524
import logging
2625
import math
2726
import os
@@ -30,7 +29,6 @@ def test_anything(self):
3029
import requests
3130
import sys
3231
import time
33-
import traceback
3432
import unittest
3533
import uuid
3634
from bs4 import BeautifulSoup
@@ -1863,6 +1861,18 @@ def assert_downloaded_file(self, file):
18631861
""" Asserts that the file exists in the Downloads Folder. """
18641862
assert os.path.exists(self.get_path_of_downloaded_file(file))
18651863

1864+
def get_google_auth_password(self, totp_key=None):
1865+
""" Returns a time-based one-time password based on the
1866+
Google Authenticator password algorithm. Works with Authy.
1867+
If "totp_key" is not specified, will default to using
1868+
the one provided in seleniumbase/config/settings.py
1869+
(See https://pyotp.readthedocs.io/en/latest/ for details.) """
1870+
import pyotp
1871+
if not totp_key:
1872+
totp_key = settings.TOTP_KEY
1873+
totp = pyotp.TOTP(totp_key)
1874+
return str(totp.now())
1875+
18661876
def convert_xpath_to_css(self, xpath):
18671877
return xpath_to_css.convert_xpath_to_css(xpath)
18681878

@@ -3033,6 +3043,7 @@ def setUp(self):
30333043
# Use Selenium Grid (Use --server=127.0.0.1 for localhost Grid)
30343044
self.use_grid = True
30353045
if self.with_db_reporting:
3046+
import getpass
30363047
self.execution_guid = str(uuid.uuid4())
30373048
self.testcase_guid = None
30383049
self.execution_start_time = 0
@@ -3096,6 +3107,7 @@ def __insert_test_result(self, state, err):
30963107
data_payload.execution_guid = self.execution_guid
30973108
data_payload.state = state
30983109
if err:
3110+
import traceback
30993111
tb_string = traceback.format_exc()
31003112
if "Message: " in tb_string:
31013113
data_payload.message = "Message: " + tb_string.split(

setup.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
setup(
1919
name='seleniumbase',
20-
version='1.15.11',
20+
version='1.15.12',
2121
description='All-In-One Test Automation Framework',
2222
long_description=long_description,
2323
long_description_content_type='text/markdown',
@@ -33,6 +33,11 @@
3333
"Topic :: Internet",
3434
"Topic :: Scientific/Engineering",
3535
"Topic :: Software Development",
36+
"Topic :: Software Development :: Quality Assurance",
37+
"Topic :: Software Development :: Testing",
38+
"Topic :: Software Development :: Testing :: Acceptance",
39+
"Topic :: Software Development :: Testing :: Traffic Generation",
40+
"Topic :: Utilities",
3641
"Operating System :: Microsoft :: Windows",
3742
"Operating System :: Unix",
3843
"Operating System :: MacOS",
@@ -46,16 +51,17 @@
4651
],
4752
install_requires=[
4853
'pip',
54+
'ipython',
4955
'setuptools',
5056
'selenium==3.14.1',
51-
'ipython==5.6.0',
5257
'pytest>=3.8.1',
53-
'pytest-html>=1.19.0',
54-
'pytest-xdist>=1.23.0',
5558
'pytest-cov>=2.6.0',
59+
'pytest-html>=1.19.0',
5660
'pytest-rerunfailures>=4.1',
61+
'pytest-xdist>=1.23.0',
5762
'parameterized==0.6.1',
5863
'six>=1.11.0',
64+
'pyotp>=2.2.6',
5965
'requests>=2.19.1',
6066
'beautifulsoup4==4.6.3',
6167
'unittest2==1.1.0',

0 commit comments

Comments
 (0)