Skip to content

Commit 681ba40

Browse files
authored
Merge pull request #426 from seleniumbase/cookie-actions
Add methods for handling cookies on web pages
2 parents b478eb3 + 8e916e1 commit 681ba40

File tree

8 files changed

+93
-9
lines changed

8 files changed

+93
-9
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ tours_exported
8484
# Images
8585
images_exported
8686

87+
# Cookies
88+
saved_cookies
89+
8790
# Automated Visual Testing
8891
visual_baseline
8992

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ All-in-one framework for web automation, end-to-end testing, and website tours.
77
* Contains reliable, smart-waiting code to prevent flaky tests.
88
* Simplifies the process of creating UI tests for any website.
99
* Includes [Plugins](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/plugins/pytest_plugin.py) for logging [test results and screenshots](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/example_logs/ReadMe.md).
10-
* Multiplies the abilities of [pytest](https://pytest.org) and [Selenium WebDriver](https://www.seleniumhq.org/).
10+
* Multiplies the abilities of [pytest](https://pytest.org) and [Selenium WebDriver](https://selenium.dev/).
1111
* Uses versatile [Python methods](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/method_summary.md) and [command-line options](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/customizing_test_runs.md).
1212
* Includes tools for [assisted-QA](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/master_qa/ReadMe.md), [visual testing](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/visual_testing/ReadMe.md), and [web tours](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/tour_examples/ReadMe.md).
1313
* Integrates with [Selenium Grid](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/utilities/selenium_grid/ReadMe.md), [Katalon Recorder](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/utilities/selenium_ide/ReadMe.md), and [MySQL](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/core/testcase_manager.py).
@@ -340,7 +340,7 @@ Here are some things you can do to setup a production environment for your testi
340340

341341
* You can setup a [Jenkins](https://jenkins.io/) build server for running tests at regular intervals. Jenkins has many plugins available, such as [the Xvfb headless browser plugin](https://wiki.jenkins-ci.org/display/JENKINS/Xvfb+Plugin) for running tests on a machine with no GUI. If you have Xvfb running in the background, you can add ``--headless`` to your run command in order to utilize it. For more info about the Xvfb plugin, [read this](https://qxf2.com/blog/xvfb-plugin-for-jenkins-selenium/). For a real-world Jenkins example of headless browser automation in action, check out [the SeleniumBase Google Cloud ReadMe](https://github.com/seleniumbase/SeleniumBase/blob/master/integrations/google_cloud/ReadMe.md).
342342

343-
* You can use [the Selenium Grid](https://github.com/SeleniumHQ/selenium/wiki/Grid2) to scale your testing by distributing tests on several machines with parallel execution. To do this, check out the SeleniumBase [selenium_grid folder](https://github.com/seleniumbase/SeleniumBase/tree/master/seleniumbase/utilities/selenium_grid), which should have everything you need. The [Selenium Grid ReadMe](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/utilities/selenium_grid/ReadMe.md) will help you get started.
343+
* You can use [the Selenium Grid](https://selenium.dev/documentation/en/grid/) to scale your testing by distributing tests on several machines with parallel execution. To do this, check out the SeleniumBase [selenium_grid folder](https://github.com/seleniumbase/SeleniumBase/tree/master/seleniumbase/utilities/selenium_grid), which should have everything you need. The [Selenium Grid ReadMe](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/utilities/selenium_grid/ReadMe.md) will help you get started.
344344

345345
* If you're using the [SeleniumBase MySQL feature](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/mysql_installation.md) to save results from tests running on a server machine, you can install [MySQL Workbench](https://dev.mysql.com/downloads/tools/workbench/) to help you read & write from your DB more easily. See [Stackoverflow](https://stackoverflow.com/questions/43102442/whats-the-difference-between-mysqldb-mysqlclient-and-mysql-connector-python) for more info.
346346

help_docs/method_summary.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,14 @@ self.save_screenshot(name, folder=None)
159159

160160
self.save_page_source(name, folder=None)
161161

162+
self.save_cookies(name="cookies.txt")
163+
164+
self.load_cookies(name="cookies.txt")
165+
166+
self.delete_all_cookies()
167+
168+
self.delete_saved_cookies(name="cookies.txt")
169+
162170
self.wait_for_ready_state_complete(timeout=None)
163171

164172
self.wait_for_angularjs(timeout=None)

requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ chardet==3.0.4
1010
urllib3==1.25.6
1111
requests>=2.22.0
1212
selenium==3.141.0
13-
pluggy>=0.13.0
13+
pluggy>=0.13.1
1414
attrs>=19.3.0
1515
pytest>=4.6.6;python_version<"3"
1616
pytest>=5.3.0;python_version>="3"
@@ -35,6 +35,6 @@ pypdf2>=1.26.0
3535
pyotp>=2.3.0
3636
boto>=2.49.0
3737
cffi>=1.13.2
38-
tqdm>=4.38.0
38+
tqdm>=4.39.0
3939
flake8>=3.7.9
4040
certifi>=2019.9.11

seleniumbase/fixtures/base_case.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,6 +1479,75 @@ def save_page_source(self, name, folder=None):
14791479
"""
14801480
return page_actions.save_page_source(self.driver, name, folder)
14811481

1482+
def save_cookies(self, name="cookies.txt"):
1483+
""" Saves the page cookies to the "saved_cookies" folder. """
1484+
cookies = self.driver.get_cookies()
1485+
json_cookies = json.dumps(cookies)
1486+
if name.endswith('/'):
1487+
raise Exception("Invalid filename for Cookies!")
1488+
if '/' in name:
1489+
name = name.split('/')[-1]
1490+
if len(name) < 1:
1491+
raise Exception("Filename for Cookies is too short!")
1492+
if not name.endswith(".txt"):
1493+
name = name + ".txt"
1494+
folder = constants.SavedCookies.STORAGE_FOLDER
1495+
abs_path = os.path.abspath('.')
1496+
file_path = abs_path + "/%s" % folder
1497+
if not os.path.exists(file_path):
1498+
os.makedirs(file_path)
1499+
cookies_file_path = "%s/%s" % (file_path, name)
1500+
cookies_file = codecs.open(cookies_file_path, "w+")
1501+
cookies_file.writelines(json_cookies)
1502+
cookies_file.close()
1503+
1504+
def load_cookies(self, name="cookies.txt"):
1505+
""" Loads the page cookies from the "saved_cookies" folder. """
1506+
if name.endswith('/'):
1507+
raise Exception("Invalid filename for Cookies!")
1508+
if '/' in name:
1509+
name = name.split('/')[-1]
1510+
if len(name) < 1:
1511+
raise Exception("Filename for Cookies is too short!")
1512+
if not name.endswith(".txt"):
1513+
name = name + ".txt"
1514+
folder = constants.SavedCookies.STORAGE_FOLDER
1515+
abs_path = os.path.abspath('.')
1516+
file_path = abs_path + "/%s" % folder
1517+
cookies_file_path = "%s/%s" % (file_path, name)
1518+
f = open(cookies_file_path, 'r')
1519+
json_cookies = f.read().strip()
1520+
f.close()
1521+
cookies = json.loads(json_cookies)
1522+
for cookie in cookies:
1523+
if 'expiry' in cookie:
1524+
del cookie['expiry']
1525+
self.driver.add_cookie(cookie)
1526+
1527+
def delete_all_cookies(self):
1528+
""" Deletes all cookies in the web browser.
1529+
Does NOT delete the saved cookies file. """
1530+
self.driver.delete_all_cookies()
1531+
1532+
def delete_saved_cookies(self, name="cookies.txt"):
1533+
""" Deletes the cookies file from the "saved_cookies" folder.
1534+
Does NOT delete the cookies from the web browser. """
1535+
if name.endswith('/'):
1536+
raise Exception("Invalid filename for Cookies!")
1537+
if '/' in name:
1538+
name = name.split('/')[-1]
1539+
if len(name) < 1:
1540+
raise Exception("Filename for Cookies is too short!")
1541+
if not name.endswith(".txt"):
1542+
name = name + ".txt"
1543+
folder = constants.SavedCookies.STORAGE_FOLDER
1544+
abs_path = os.path.abspath('.')
1545+
file_path = abs_path + "/%s" % folder
1546+
cookies_file_path = "%s/%s" % (file_path, name)
1547+
if os.path.exists(cookies_file_path):
1548+
if cookies_file_path.endswith('.txt'):
1549+
os.remove(cookies_file_path)
1550+
14821551
def wait_for_ready_state_complete(self, timeout=None):
14831552
try:
14841553
# If there's an alert, skip

seleniumbase/fixtures/constants.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ class Files:
1919
ARCHIVED_DOWNLOADS_FOLDER = "archived_files"
2020

2121

22+
class SavedCookies:
23+
STORAGE_FOLDER = "saved_cookies"
24+
25+
2226
class VisualBaseline:
2327
STORAGE_FOLDER = "visual_baseline"
2428

seleniumbase/fixtures/page_actions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ def save_screenshot(driver, name, folder=None):
467467
If the folder provided doesn't exist, it will get created.
468468
The screenshot will be in PNG format.
469469
"""
470-
if "." not in name:
470+
if not name.endswith(".png"):
471471
name = name + ".png"
472472
if folder:
473473
abs_path = os.path.abspath('.')
@@ -497,7 +497,7 @@ def save_page_source(driver, name, folder=None):
497497
name - The file name to save the current page's HTML to.
498498
folder - The folder to save the file to. (Default = current folder)
499499
"""
500-
if "." not in name:
500+
if not name.endswith(".html"):
501501
name = name + ".html"
502502
if folder:
503503
abs_path = os.path.abspath('.')

setup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545

4646
setup(
4747
name='seleniumbase',
48-
version='1.33.2',
48+
version='1.33.3',
4949
description='Fast, Easy, and Reliable Browser Automation & Testing.',
5050
long_description=long_description,
5151
long_description_content_type='text/markdown',
@@ -93,7 +93,7 @@
9393
'urllib3==1.25.6', # Must stay in sync with "requests"
9494
'requests>=2.22.0',
9595
'selenium==3.141.0',
96-
'pluggy>=0.13.0',
96+
'pluggy>=0.13.1',
9797
'attrs>=19.3.0',
9898
'pytest>=4.6.6;python_version<"3"', # For Python 2 compatibility
9999
'pytest>=5.3.0;python_version>="3"',
@@ -118,7 +118,7 @@
118118
'pyotp>=2.3.0',
119119
'boto>=2.49.0',
120120
'cffi>=1.13.2',
121-
'tqdm>=4.38.0',
121+
'tqdm>=4.39.0',
122122
'flake8>=3.7.9',
123123
'certifi>=2019.9.11',
124124
],

0 commit comments

Comments
 (0)