From 7b37cb77396e3429f0da65c131c2c54af97be2c4 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 10 Apr 2018 02:08:54 -0400 Subject: [PATCH 01/47] Add MySQL to the deploy script --- .travis.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.travis.yml b/.travis.yml index a25cb5574f8..0eeb5b4390c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,11 +8,17 @@ addons: install: - "pip install --upgrade pip" - "pip install -r requirements.txt --upgrade" + - "pip install MySQL-python==1.2.5" - "python setup.py develop" - "sudo rm -f /etc/boto.cfg" before_script: - "flake8 seleniumbase/*.py && flake8 seleniumbase/*/*.py && flake8 seleniumbase/*/*/*.py && flake8 seleniumbase/*/*/*/*.py" # - "export DISPLAY=:99.0 && sh -e /etc/init.d/xvfb start" + - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" + - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" + - "sudo mysql -e use mysql; update user set authentication_string=PASSWORD('test') where User='root'; update user set plugin='mysql_native_password';FLUSH PRIVILEGES;" + - "sudo mysql_upgrade" + - "sudo service mysql restart" - "wget https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip && unzip chromedriver_linux64.zip && sudo cp chromedriver /usr/local/bin/ && sudo chmod +x /usr/local/bin/chromedriver" - "wget https://github.com/mozilla/geckodriver/releases/download/v0.20.0/geckodriver-v0.20.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" # - "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" @@ -21,5 +27,7 @@ script: - "nosetests examples/boilerplates/boilerplate_test.py --headless" - "pytest examples/my_first_test.py --browser=firefox -s --headless" - "pytest examples/github_test.py --browser=chrome -s --headless" +after_script: + - "sudo mysql -e 'DROP DATABASE test_db;'" notifications: email: false From dbf18223419bcf20327866e3db54cbeff2ef46e8 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 10 Apr 2018 02:19:00 -0400 Subject: [PATCH 02/47] Update MySQL deploy script --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0eeb5b4390c..60db36e2e60 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ before_script: # - "export DISPLAY=:99.0 && sh -e /etc/init.d/xvfb start" - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" - - "sudo mysql -e use mysql; update user set authentication_string=PASSWORD('test') where User='root'; update user set plugin='mysql_native_password';FLUSH PRIVILEGES;" + - "sudo mysql -e use mysql; ALTER USER 'root'@'localhost' IDENTIFIED BY 'test'; update user set plugin='mysql_native_password';FLUSH PRIVILEGES;" - "sudo mysql_upgrade" - "sudo service mysql restart" - "wget https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip && unzip chromedriver_linux64.zip && sudo cp chromedriver /usr/local/bin/ && sudo chmod +x /usr/local/bin/chromedriver" From 2048c61f9222777f1ea9f6214d086eddcdfb3b55 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 10 Apr 2018 02:23:20 -0400 Subject: [PATCH 03/47] Update the mysql deploy script --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 60db36e2e60..bf658b9bd2a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ before_script: # - "export DISPLAY=:99.0 && sh -e /etc/init.d/xvfb start" - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" - - "sudo mysql -e use mysql; ALTER USER 'root'@'localhost' IDENTIFIED BY 'test'; update user set plugin='mysql_native_password';FLUSH PRIVILEGES;" + - "sudo mysql -e use mysql; SET PASSWORD FOR 'root'@'localhost' = PASSWORD('test'); update user set plugin='mysql_native_password';FLUSH PRIVILEGES;" - "sudo mysql_upgrade" - "sudo service mysql restart" - "wget https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip && unzip chromedriver_linux64.zip && sudo cp chromedriver /usr/local/bin/ && sudo chmod +x /usr/local/bin/chromedriver" From d8fdced4904cbcf48d7cf0e447a1d1bd107e85a5 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 10 Apr 2018 02:27:37 -0400 Subject: [PATCH 04/47] Update the mysql deploy script --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index bf658b9bd2a..96b96260688 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,9 +16,6 @@ before_script: # - "export DISPLAY=:99.0 && sh -e /etc/init.d/xvfb start" - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" - - "sudo mysql -e use mysql; SET PASSWORD FOR 'root'@'localhost' = PASSWORD('test'); update user set plugin='mysql_native_password';FLUSH PRIVILEGES;" - - "sudo mysql_upgrade" - - "sudo service mysql restart" - "wget https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip && unzip chromedriver_linux64.zip && sudo cp chromedriver /usr/local/bin/ && sudo chmod +x /usr/local/bin/chromedriver" - "wget https://github.com/mozilla/geckodriver/releases/download/v0.20.0/geckodriver-v0.20.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" # - "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" From e1da445bc0634a4b2a6db97370938c17aa75acbd Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 10 Apr 2018 02:33:23 -0400 Subject: [PATCH 05/47] Update the mysql deploy script --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 96b96260688..cc9ea6b2e68 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ script: - "pytest examples/my_first_test.py --browser=chrome -s --headless" - "nosetests examples/boilerplates/boilerplate_test.py --headless" - "pytest examples/my_first_test.py --browser=firefox -s --headless" - - "pytest examples/github_test.py --browser=chrome -s --headless" + - "pytest examples/github_test.py --browser=chrome -s --headless --with-db_reporting" after_script: - "sudo mysql -e 'DROP DATABASE test_db;'" notifications: From aa530a8f0a887562ebcd6602acfffdc46d35f25d Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 10 Apr 2018 02:40:55 -0400 Subject: [PATCH 06/47] Update the mysql deploy script --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index cc9ea6b2e68..d7beae1efc8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,9 @@ before_script: # - "export DISPLAY=:99.0 && sh -e /etc/init.d/xvfb start" - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" + - "sudo mysql -e use mysql; SET PASSWORD FOR 'root'@'localhost' = 'test'; update user set plugin='mysql_native_password'; FLUSH PRIVILEGES;" + - "sudo mysql_upgrade" + - "sudo service mysql restart" - "wget https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip && unzip chromedriver_linux64.zip && sudo cp chromedriver /usr/local/bin/ && sudo chmod +x /usr/local/bin/chromedriver" - "wget https://github.com/mozilla/geckodriver/releases/download/v0.20.0/geckodriver-v0.20.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" # - "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" From 865da0de5d365384565904f24c36a1610f420e46 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 10 Apr 2018 15:26:04 -0400 Subject: [PATCH 07/47] Update the deploy script --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d7beae1efc8..a660411d4e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ before_script: # - "export DISPLAY=:99.0 && sh -e /etc/init.d/xvfb start" - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" - - "sudo mysql -e use mysql; SET PASSWORD FOR 'root'@'localhost' = 'test'; update user set plugin='mysql_native_password'; FLUSH PRIVILEGES;" + - "sudo mysql -e use mysql; SET PASSWORD FOR 'root'@'localhost' = test; FLUSH PRIVILEGES;" - "sudo mysql_upgrade" - "sudo service mysql restart" - "wget https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip && unzip chromedriver_linux64.zip && sudo cp chromedriver /usr/local/bin/ && sudo chmod +x /usr/local/bin/chromedriver" From 550a5409017732f2252300519e6ddaca90cfe63c Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 10 Apr 2018 15:32:39 -0400 Subject: [PATCH 08/47] Update the mysql deploy script --- .travis.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index a660411d4e0..bd95b4f7348 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,9 +16,10 @@ before_script: # - "export DISPLAY=:99.0 && sh -e /etc/init.d/xvfb start" - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" - - "sudo mysql -e use mysql; SET PASSWORD FOR 'root'@'localhost' = test; FLUSH PRIVILEGES;" - - "sudo mysql_upgrade" - - "sudo service mysql restart" + - "sudo mysql -e SET PASSWORD FOR 'root'@'localhost' = 'test';" + - "sudo mysql -e 'FLUSH PRIVILEGES;'" + # - "sudo mysql_upgrade" + # - "sudo service mysql restart" - "wget https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip && unzip chromedriver_linux64.zip && sudo cp chromedriver /usr/local/bin/ && sudo chmod +x /usr/local/bin/chromedriver" - "wget https://github.com/mozilla/geckodriver/releases/download/v0.20.0/geckodriver-v0.20.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" # - "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" From d2c73cfe340f4a1dc9459cb98357b8001ed2ec96 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Wed, 11 Apr 2018 01:15:42 -0400 Subject: [PATCH 09/47] Update the mysql deploy script --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bd95b4f7348..522e3204b7d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ before_script: # - "export DISPLAY=:99.0 && sh -e /etc/init.d/xvfb start" - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" - - "sudo mysql -e SET PASSWORD FOR 'root'@'localhost' = 'test';" + - "sudo mysql -e 'SET PASSWORD FOR root@localhost = test;'" - "sudo mysql -e 'FLUSH PRIVILEGES;'" # - "sudo mysql_upgrade" # - "sudo service mysql restart" From 6f65c00b9f2538ff163f891b5c9f2adedf1b3b6e Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Wed, 11 Apr 2018 01:20:20 -0400 Subject: [PATCH 10/47] Update the mysql deploy script --- .travis.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 522e3204b7d..1150c1ffb97 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,10 @@ python: addons: firefox: latest chrome: stable +before_install: + - sudo mysql -e "use mysql; update user set authentication_string=PASSWORD('test') where User='root'; update user set plugin='mysql_native_password';FLUSH PRIVILEGES;" + - sudo mysql_upgrade + - sudo service mysql restart install: - "pip install --upgrade pip" - "pip install -r requirements.txt --upgrade" @@ -16,8 +20,8 @@ before_script: # - "export DISPLAY=:99.0 && sh -e /etc/init.d/xvfb start" - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" - - "sudo mysql -e 'SET PASSWORD FOR root@localhost = test;'" - - "sudo mysql -e 'FLUSH PRIVILEGES;'" + # - "sudo mysql -e 'SET PASSWORD FOR root@localhost = test;'" + # - "sudo mysql -e 'FLUSH PRIVILEGES;'" # - "sudo mysql_upgrade" # - "sudo service mysql restart" - "wget https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip && unzip chromedriver_linux64.zip && sudo cp chromedriver /usr/local/bin/ && sudo chmod +x /usr/local/bin/chromedriver" From c9722fe410af7576a2a7c0c7d8b31a944c01e2b4 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Wed, 11 Apr 2018 01:23:43 -0400 Subject: [PATCH 11/47] Update the MySQL deploy script --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1150c1ffb97..131b4eab394 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,6 @@ addons: chrome: stable before_install: - sudo mysql -e "use mysql; update user set authentication_string=PASSWORD('test') where User='root'; update user set plugin='mysql_native_password';FLUSH PRIVILEGES;" - - sudo mysql_upgrade - sudo service mysql restart install: - "pip install --upgrade pip" From 5651699088eb88236de01ddc0d2338bae8e2f776 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Wed, 11 Apr 2018 02:02:52 -0400 Subject: [PATCH 12/47] Update the MySQL deploy script --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 131b4eab394..860c121b9bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ before_script: - "flake8 seleniumbase/*.py && flake8 seleniumbase/*/*.py && flake8 seleniumbase/*/*/*.py && flake8 seleniumbase/*/*/*/*.py" # - "export DISPLAY=:99.0 && sh -e /etc/init.d/xvfb start" - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" + - "sudo mysql -h 127.0.0.1 -u root test_db -p test < seleniumbase/core/testcaserepository.sql" # - "sudo mysql -e 'SET PASSWORD FOR root@localhost = test;'" # - "sudo mysql -e 'FLUSH PRIVILEGES;'" # - "sudo mysql_upgrade" From 5b16954a362c6466e0e1fbab8bcdcda57ef03964 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Wed, 11 Apr 2018 02:08:14 -0400 Subject: [PATCH 13/47] Update the MySQL deploy script --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 860c121b9bc..72ba10923a0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,8 @@ addons: chrome: stable before_install: - sudo mysql -e "use mysql; update user set authentication_string=PASSWORD('test') where User='root'; update user set plugin='mysql_native_password';FLUSH PRIVILEGES;" + # - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" + - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" - sudo service mysql restart install: - "pip install --upgrade pip" @@ -17,8 +19,6 @@ install: before_script: - "flake8 seleniumbase/*.py && flake8 seleniumbase/*/*.py && flake8 seleniumbase/*/*/*.py && flake8 seleniumbase/*/*/*/*.py" # - "export DISPLAY=:99.0 && sh -e /etc/init.d/xvfb start" - - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - - "sudo mysql -h 127.0.0.1 -u root test_db -p test < seleniumbase/core/testcaserepository.sql" # - "sudo mysql -e 'SET PASSWORD FOR root@localhost = test;'" # - "sudo mysql -e 'FLUSH PRIVILEGES;'" # - "sudo mysql_upgrade" From 487cd39f673cabfcf92db4e65e55f69a96c76194 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Wed, 11 Apr 2018 02:11:24 -0400 Subject: [PATCH 14/47] Update the MySQL deploy script --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 72ba10923a0..be090d3a269 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,9 +7,9 @@ addons: chrome: stable before_install: - sudo mysql -e "use mysql; update user set authentication_string=PASSWORD('test') where User='root'; update user set plugin='mysql_native_password';FLUSH PRIVILEGES;" - # - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" + - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" - - sudo service mysql restart + - "sudo service mysql restart" install: - "pip install --upgrade pip" - "pip install -r requirements.txt --upgrade" From da713358aa2d9d43510150f7b22591f2ace28977 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Wed, 11 Apr 2018 20:06:13 -0400 Subject: [PATCH 15/47] Update the MySQL deploy script --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index be090d3a269..2504d4d6aa1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ addons: firefox: latest chrome: stable before_install: - - sudo mysql -e "use mysql; update user set authentication_string=PASSWORD('test') where User='root'; update user set plugin='mysql_native_password';FLUSH PRIVILEGES;" + - sudo mysql -e "use mysql; update user set authentication_string=PASSWORD('test') where user='root'; update user set plugin='mysql_native_password';FLUSH PRIVILEGES;" - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" - "sudo service mysql restart" From 23126f45c48bd6e4447c75dde2cb0574ba52f1e6 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Wed, 11 Apr 2018 21:06:06 -0400 Subject: [PATCH 16/47] Update the MySQL deploy script --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2504d4d6aa1..5e96d8feb05 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,9 @@ addons: firefox: latest chrome: stable before_install: - - sudo mysql -e "use mysql; update user set authentication_string=PASSWORD('test') where user='root'; update user set plugin='mysql_native_password';FLUSH PRIVILEGES;" - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" + - sudo mysql -e "use mysql; update user set authentication_string=PASSWORD('test') where user='root'; update user set plugin='mysql_native_password'; FLUSH PRIVILEGES;" - "sudo service mysql restart" install: - "pip install --upgrade pip" From 8742b2593cfdc60590af9129aa04058e1e5e6a5f Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Wed, 11 Apr 2018 21:36:51 -0400 Subject: [PATCH 17/47] Update the MySQL deploy script --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5e96d8feb05..543092c9785 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,8 @@ addons: before_install: - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" - - sudo mysql -e "use mysql; update user set authentication_string=PASSWORD('test') where user='root'; update user set plugin='mysql_native_password'; FLUSH PRIVILEGES;" + - "mysqladmin -u root password test" + - "sudo mysql -e 'FLUSH PRIVILEGES;'" - "sudo service mysql restart" install: - "pip install --upgrade pip" From 5d0190ff82b4e957a270c7d621c6a383f669c6c5 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Wed, 11 Apr 2018 21:40:33 -0400 Subject: [PATCH 18/47] Update the MySQL deploy script --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 543092c9785..0cdd22413aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,6 @@ before_install: - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" - "mysqladmin -u root password test" - - "sudo mysql -e 'FLUSH PRIVILEGES;'" - "sudo service mysql restart" install: - "pip install --upgrade pip" From 07f9bf04c55fc8545bf1ac27897a806f333a4e5d Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Wed, 11 Apr 2018 22:43:46 -0400 Subject: [PATCH 19/47] Fix import for Python 3 --- seleniumbase/core/mysql.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seleniumbase/core/mysql.py b/seleniumbase/core/mysql.py index fda7a4351ea..0c0b47cbab1 100755 --- a/seleniumbase/core/mysql.py +++ b/seleniumbase/core/mysql.py @@ -16,7 +16,7 @@ def __init__(self, database_env='test', conf_creds=None): """ Gets database information from mysql_conf.py and creates a connection. """ - import mysql_conf as conf # This had problems when using Python 3 + from seleniumbase.core import mysql_conf as conf import MySQLdb db_server, db_user, db_pass, db_schema = \ conf.APP_CREDS[conf.Apps.TESTCASE_REPOSITORY][database_env] From dd8d7ec51e3bcd64d217cce2fbda30168c9a00d2 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Wed, 11 Apr 2018 22:44:12 -0400 Subject: [PATCH 20/47] Add mysqlclient to requirements --- requirements.txt | 3 ++- setup.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 34aa40bb565..e935866f4a1 100755 --- a/requirements.txt +++ b/requirements.txt @@ -10,9 +10,10 @@ six==1.10.0 flake8==3.5.0 requests==2.18.4 beautifulsoup4==4.6.0 +mysqlclient==1.3.12 unittest2==1.1.0 chardet==3.0.4 boto==2.48.0 ipdb==0.11 -pyvirtualdisplay==0.2.1 +PyVirtualDisplay==0.2.1 -e . diff --git a/setup.py b/setup.py index f8b1500312e..0227a04b1ac 100755 --- a/setup.py +++ b/setup.py @@ -29,11 +29,12 @@ 'flake8==3.5.0', 'requests==2.18.4', 'beautifulsoup4==4.6.0', + 'mysqlclient==1.3.12', 'unittest2==1.1.0', 'chardet==3.0.4', 'boto==2.48.0', 'ipdb==0.11', - 'pyvirtualdisplay==0.2.1', + 'PyVirtualDisplay==0.2.1', ], packages=['seleniumbase', 'seleniumbase.core', From 5f3e42e4b70e0145c91ff6769129a0cc9f2ffc1d Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Wed, 11 Apr 2018 23:17:29 -0400 Subject: [PATCH 21/47] Slow down the GitHub test to prevent triggering a call limit --- examples/github_test.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/examples/github_test.py b/examples/github_test.py index 7f568a5f137..0404a068021 100755 --- a/examples/github_test.py +++ b/examples/github_test.py @@ -1,15 +1,24 @@ from seleniumbase import BaseCase +import time class GitHubTests(BaseCase): + # Selenium can trigger GitHub's abuse detection mechanism: + # "You have triggered an abuse detection mechanism." + # "Please wait a few minutes before you try again." + # To avoid this, slow down Selenium actions. + def slow_click(self, css_selector): + time.sleep(0.75) + self.click(css_selector) + def test_github(self): self.open("https://github.com/") self.update_text("input.header-search-input", "SeleniumBase\n") - self.click('a[href="/seleniumbase/SeleniumBase"]') + self.slow_click('a[href="/seleniumbase/SeleniumBase"]') self.assert_element("div.repository-content") self.assert_text("SeleniumBase", "h1") - self.click('a[title="seleniumbase"]') - self.click('a[title="fixtures"]') - self.click('a[title="base_case.py"]') + self.slow_click('a[title="seleniumbase"]') + self.slow_click('a[title="fixtures"]') + self.slow_click('a[title="base_case.py"]') self.assert_text("Code", "nav a.selected") From 0168de448b495a5099856913b9343a18dbfdf295 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Wed, 11 Apr 2018 23:46:26 -0400 Subject: [PATCH 22/47] Update the MySQL deploy script --- .travis.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0cdd22413aa..1cffda1c8c2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,10 +19,6 @@ install: before_script: - "flake8 seleniumbase/*.py && flake8 seleniumbase/*/*.py && flake8 seleniumbase/*/*/*.py && flake8 seleniumbase/*/*/*/*.py" # - "export DISPLAY=:99.0 && sh -e /etc/init.d/xvfb start" - # - "sudo mysql -e 'SET PASSWORD FOR root@localhost = test;'" - # - "sudo mysql -e 'FLUSH PRIVILEGES;'" - # - "sudo mysql_upgrade" - # - "sudo service mysql restart" - "wget https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip && unzip chromedriver_linux64.zip && sudo cp chromedriver /usr/local/bin/ && sudo chmod +x /usr/local/bin/chromedriver" - "wget https://github.com/mozilla/geckodriver/releases/download/v0.20.0/geckodriver-v0.20.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" # - "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" @@ -31,6 +27,7 @@ script: - "nosetests examples/boilerplates/boilerplate_test.py --headless" - "pytest examples/my_first_test.py --browser=firefox -s --headless" - "pytest examples/github_test.py --browser=chrome -s --headless --with-db_reporting" + - "sudo mysql --password=test -e 'select testcaseAddress from test_db.testcaseRunData'" after_script: - "sudo mysql -e 'DROP DATABASE test_db;'" notifications: From 26253909aabfc9c8f1a3a9c677233d0ac56bc1ad Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 12 Apr 2018 03:06:21 -0400 Subject: [PATCH 23/47] Update the MySQL deploy script --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1cffda1c8c2..07176150804 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,7 +27,7 @@ script: - "nosetests examples/boilerplates/boilerplate_test.py --headless" - "pytest examples/my_first_test.py --browser=firefox -s --headless" - "pytest examples/github_test.py --browser=chrome -s --headless --with-db_reporting" - - "sudo mysql --password=test -e 'select testcaseAddress from test_db.testcaseRunData'" + - "sudo mysql --password=test -e 'select testcaseAddress,browser,state,runtime from test_db.testcaseRunData'" after_script: - "sudo mysql -e 'DROP DATABASE test_db;'" notifications: From 0861ed0e8185bfb8e7c2315b0f34690a400cc5c1 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 12 Apr 2018 03:24:43 -0400 Subject: [PATCH 24/47] Add a comment about changing MySQL passwords in the deploy script --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 07176150804..d552e664b0d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ before_install: - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" - "mysqladmin -u root password test" + # - "mysqladmin -u root -p'old_password' password new_password" - "sudo service mysql restart" install: - "pip install --upgrade pip" From 923abead5645127d386fbe4f4fd2567e3356bd77 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 12 Apr 2018 03:25:10 -0400 Subject: [PATCH 25/47] Update the description --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index b4b2b1ae01b..f538f29e21e 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ - -## Automated Web-UI testing reimagined. +## Automated testing made fast, easy, and reliable. From 518594e9abd60caf9d38f503e9801f2bdc567f7d Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 12 Apr 2018 15:54:21 -0400 Subject: [PATCH 26/47] Improve the MySQL DB test storage feature. --- seleniumbase/core/mysql.py | 8 +-- seleniumbase/core/mysql_conf.py | 3 +- seleniumbase/core/testcase_manager.py | 70 +++++++------------ seleniumbase/core/testcaserepository.sql | 54 +++++++------- seleniumbase/fixtures/delayed_data_manager.py | 65 +++++++++-------- seleniumbase/plugins/db_reporting_plugin.py | 15 ++-- 6 files changed, 98 insertions(+), 117 deletions(-) diff --git a/seleniumbase/core/mysql.py b/seleniumbase/core/mysql.py index 0c0b47cbab1..6715514aa99 100755 --- a/seleniumbase/core/mysql.py +++ b/seleniumbase/core/mysql.py @@ -8,7 +8,7 @@ class DatabaseManager(): """ - This class wraps database functions for easy use. + This class wraps MySQL database methods for easy use. It connects to the testcase database. """ @@ -40,7 +40,7 @@ def __init__(self, database_env='test', conf_creds=None): def fetchall_query_and_close(self, query, values): """ - Executes a query, gets all the values and then closes up the connection + Executes a query, gets all the values, and closes the connection. """ self.cursor.execute(query, values) retval = self.cursor.fetchall() @@ -49,7 +49,7 @@ def fetchall_query_and_close(self, query, values): def fetchone_query_and_close(self, query, values): """ - Executes a query, gets the first value, and closes up the connection + Executes a query, gets the first value, and closes the connection. """ self.cursor.execute(query, values) retval = self.cursor.fetchone() @@ -58,7 +58,7 @@ def fetchone_query_and_close(self, query, values): def execute_query_and_close(self, query, values): """ - Executes a query and closes the connection + Executes a query and closes the connection. """ retval = self.cursor.execute(query, values) self.__close_db() diff --git a/seleniumbase/core/mysql_conf.py b/seleniumbase/core/mysql_conf.py index 7682c11d4e8..07c0206e585 100755 --- a/seleniumbase/core/mysql_conf.py +++ b/seleniumbase/core/mysql_conf.py @@ -1,6 +1,5 @@ """ -This file contains database credentials for the various databases -that the tests need to access +This file organizes connection details to the Testcase Database. """ from seleniumbase.config import settings diff --git a/seleniumbase/core/testcase_manager.py b/seleniumbase/core/testcase_manager.py index 633d4e676ae..adf872e2cb9 100755 --- a/seleniumbase/core/testcase_manager.py +++ b/seleniumbase/core/testcase_manager.py @@ -1,24 +1,17 @@ -""" -Testcase database related methods -""" - from seleniumbase.core.mysql import DatabaseManager class TestcaseManager: - """ - Helper for Testcase related DB stuff - """ def __init__(self, database_env): self.database_env = database_env def insert_execution_data(self, execution_query_payload): - """ Inserts an execution into the database. + """ Inserts a test execution row into the database. Returns the execution guid. """ query = """INSERT INTO execution - (guid, executionStart, totalExecutionTime, username) + (guid, execution_start, total_execution_time, username) VALUES (%(guid)s,%(execution_start_time)s, %(total_execution_time)s,%(username)s)""" DatabaseManager(self.database_env).execute_query_and_close( @@ -27,10 +20,9 @@ def insert_execution_data(self, execution_query_payload): return execution_query_payload.guid def update_execution_data(self, execution_guid, execution_time): - """updates an existing execution in the database""" - + """ Updates an existing test execution row in the database. """ query = """UPDATE execution - SET totalExecutionTime=%(execution_time)s + SET total_execution_time=%(execution_time)s WHERE guid=%(execution_guid)s """ DatabaseManager(self.database_env).execute_query_and_close( query, @@ -38,11 +30,10 @@ def update_execution_data(self, execution_guid, execution_time): "execution_time": execution_time}) def insert_testcase_data(self, testcase_run_payload): - """inserts all data for the test case, returns the new row guid""" - - query = """INSERT INTO testcaseRunData - (guid, browser, state, execution_guid, env, start_time, - testcaseAddress, runtime, retryCount, message, stackTrace) + """ Inserts all data for the test in the DB. Returns new row guid. """ + query = """INSERT INTO test_run_data( + guid, browser, state, execution_guid, env, start_time, + test_address, runtime, retry_count, message, stack_trace) VALUES ( %(guid)s, %(browser)s, @@ -50,39 +41,35 @@ def insert_testcase_data(self, testcase_run_payload): %(execution_guid)s, %(env)s, %(start_time)s, - %(testcaseAddress)s, + %(test_address)s, %(runtime)s, - %(retryCount)s, + %(retry_count)s, %(message)s, - %(stackTrace)s) """ + %(stack_trace)s) """ DatabaseManager(self.database_env).execute_query_and_close( query, testcase_run_payload.get_params()) def update_testcase_data(self, testcase_payload): - """updates an existing testcase run in the database""" - - query = """UPDATE testcaseRunData SET - runtime=%(runtime)s, - state=%(state)s, - retryCount=%(retryCount)s, - stackTrace=%(stackTrace)s, - message=%(message)s - WHERE guid=%(guid)s """ + """ Updates an existing test run in the database. """ + query = """UPDATE test_run_data SET + runtime=%(runtime)s, + state=%(state)s, + retry_count=%(retry_count)s, + stack_trace=%(stack_trace)s, + message=%(message)s + WHERE guid=%(guid)s """ DatabaseManager(self.database_env).execute_query_and_close( query, testcase_payload.get_params()) def update_testcase_log_url(self, testcase_payload): - """updates an existing testcase run's logging URL in the database""" - - query = """UPDATE testcaseRunData - SET logURL=%(logURL)s + query = """UPDATE test_run_data + SET log_url=%(log_url)s WHERE guid=%(guid)s """ DatabaseManager(self.database_env).execute_query_and_close( query, testcase_payload.get_params()) class ExecutionQueryPayload: - """ Helper class for containing the execution query data """ def __init__(self): self.execution_start_time = None self.total_execution_time = -1 @@ -90,7 +77,6 @@ def __init__(self): self.guid = None def get_params(self): - """ Returns a params object for use with the pool """ return { "execution_start_time": self.execution_start_time, "total_execution_time": self.total_execution_time, @@ -100,10 +86,9 @@ def get_params(self): class TestcaseDataPayload: - """ Helper class for containing all the testcase query data """ def __init__(self): self.guid = None - self.testcaseAddress = None + self.test_address = None self.browser = None self.state = None self.execution_guid = None @@ -113,21 +98,20 @@ def __init__(self): self.retry_count = 0 self.stack_trace = None self.message = None - self.logURL = None + self.log_url = None def get_params(self): - """ Returns a params object for use with the pool """ return { "guid": self.guid, - "testcaseAddress": self.testcaseAddress, + "test_address": self.test_address, "browser": self.browser, "state": self.state, "execution_guid": self.execution_guid, "env": self.env, "start_time": self.start_time, "runtime": self.runtime, - "retryCount": self.retry_count, - "stackTrace": self.stack_trace, + "retry_count": self.retry_count, + "stack_trace": self.stack_trace, "message": self.message, - "logURL": self.logURL + "log_url": self.log_url } diff --git a/seleniumbase/core/testcaserepository.sql b/seleniumbase/core/testcaserepository.sql index e8bb2d612ae..9a0a6d64426 100755 --- a/seleniumbase/core/testcaserepository.sql +++ b/seleniumbase/core/testcaserepository.sql @@ -1,41 +1,41 @@ -# table delayedTestData +# test_run_data table # ----------------------------------- -CREATE TABLE `delayedTestData` ( +CREATE TABLE `test_run_data` ( `guid` varchar(64) NOT NULL DEFAULT '', - `testcaseAddress` varchar(255) NOT NULL DEFAULT '', - `insertedAt` bigint(20) NOT NULL, - `expectedResult` text, - `done` tinyint(1) DEFAULT '0', - `expiresAt` bigint(20) DEFAULT NULL, - PRIMARY KEY (`guid`), - UNIQUE KEY `uuid` (`guid`) + `test_address` varchar(255) DEFAULT NULL, + `env` varchar(64) DEFAULT NULL, + `start_time` varchar(64) DEFAULT NULL, + `execution_guid` varchar(64) DEFAULT NULL, + `runtime` int(11), + `state` varchar(64) DEFAULT NULL, + `browser` varchar(64) DEFAULT NULL, + `message` text, + `stack_trace` text, + `retry_count` int(11) DEFAULT '0', + `exception_map_guid` varchar(64) DEFAULT NULL, + `log_url` text, + PRIMARY KEY (`guid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -# table execution +# execution table # ----------------------------------- CREATE TABLE `execution` ( `guid` varchar(64) NOT NULL DEFAULT '', - `totalExecutionTime` int(11), + `total_execution_time` int(11), `username` varchar(255) DEFAULT NULL, - `executionStart` bigint(20) DEFAULT '0', + `execution_start` bigint(20) DEFAULT '0', PRIMARY KEY (`guid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -# table testcaseRunData +# delayed_test_data table # ----------------------------------- -CREATE TABLE `testcaseRunData` ( +CREATE TABLE `delayed_test_data` ( `guid` varchar(64) NOT NULL DEFAULT '', - `testcaseAddress` varchar(255) DEFAULT NULL, - `env` varchar(64) DEFAULT NULL, - `start_time` varchar(64) DEFAULT NULL, - `execution_guid` varchar(64) DEFAULT NULL, - `runtime` int(11), - `state` varchar(64) DEFAULT NULL, - `browser` varchar(64) DEFAULT NULL, - `message` text, - `stackTrace` text, - `retryCount` int(11) DEFAULT '0', - `exceptionMap_guid` varchar(64) DEFAULT NULL, - `logURL` text, - PRIMARY KEY (`guid`) + `test_address` varchar(255) NOT NULL DEFAULT '', + `inserted_at` bigint(20) NOT NULL, + `expected_result` text, + `is_done` tinyint(1) DEFAULT '0', + `expires_at` bigint(20) DEFAULT NULL, + PRIMARY KEY (`guid`), + UNIQUE KEY `uuid` (`guid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/seleniumbase/fixtures/delayed_data_manager.py b/seleniumbase/fixtures/delayed_data_manager.py index be995c2c07a..2aba00a20e0 100755 --- a/seleniumbase/fixtures/delayed_data_manager.py +++ b/seleniumbase/fixtures/delayed_data_manager.py @@ -4,82 +4,81 @@ import uuid from seleniumbase.core.mysql import DatabaseManager -DEFAULT_EXPIRATION = 1000 * 60 * 60 * 48 +DEFAULT_EXPIRATION = 1000 * 60 * 60 * 24 # A day later (in milliseconds) class DelayedTestStorage: - """ The database-calling methods of the Delayed Test Framework """ @classmethod - def get_delayed_test_data(self, testcase_address, done=0): - """ This method queries the delayedTestData table in the DB and + def get_delayed_test_data(self, test_address, is_done=0): + """ This method queries the delayed_test_data table in the DB and then returns a list of rows with the matching parameters. - :param testcase_address: The ID (address) of the test case. - :param done: (0 for test not done or 1 for test done) - :returns: A list of rows found with the matching testcase_address. + :param test_address: The ID (address) of the test case. + :param is_done: (0 for test not done or 1 for test done) + :returns: A list of rows found with the matching test_address. """ db = DatabaseManager() - query = """SELECT guid,testcaseAddress,insertedAt,expectedResult,done - FROM delayedTestData - WHERE testcaseAddress=%(testcase_address)s - AND done=%(done)s""" + query = """SELECT guid,test_address,inserted_at,expected_result,is_done + FROM delayed_test_data + WHERE test_address=%(test_address)s + AND is_done=%(is_done)s""" data = db.fetchall_query_and_close( - query, {"testcase_address": testcase_address, - "done": done}) + query, {"test_address": test_address, + "is_done": is_done}) if data: return data else: - logging.debug("Could not find any rows in delayedTestData.") + logging.debug("Could not find any rows in delayed_test_data.") logging.debug("DB Query = " + query % - {"testcase_address": testcase_address, "done": done}) + {"test_address": test_address, "is_done": is_done}) return [] @classmethod - def insert_delayed_test_data(self, guid_, testcase_address, - expected_result, done=0, + def insert_delayed_test_data(self, guid_, test_address, + expected_result, is_done=0, expires_at=DEFAULT_EXPIRATION): - """ This method inserts rows into the delayedTestData table + """ This method inserts rows into the delayed_test_data table in the DB based on the given parameters where inserted_at (Date format) is automatically set in this method. :param guid_: The guid that is provided by the test case. (Format: str(uuid.uuid4())) - :param testcase_address: The ID (address) of the test case. + :param test_address: The ID (address) of the test case. :param expected_result: The result string of persistent data that will be stored in the DB. - :param done: (0 for test not done or 1 for test done) + :param is_done: (0 for test not done or 1 for test done) :returns: True (when no exceptions or errors occur) """ inserted_at = int(time.time() * 1000) db = DatabaseManager() - query = """INSERT INTO delayedTestData( - guid,testcaseAddress,insertedAt, - expectedResult,done,expiresAt) - VALUES (%(guid)s,%(testcaseAddress)s,%(inserted_at)s, - %(expected_result)s,%(done)s,%(expires_at)s)""" + query = """INSERT INTO delayed_test_data( + guid,test_address,inserted_at, + expected_result,is_done,expires_at) + VALUES (%(guid)s,%(test_address)s,%(inserted_at)s, + %(expected_result)s,%(is_done)s,%(expires_at)s)""" db.execute_query_and_close( query, {"guid": guid_, - "testcaseAddress": testcase_address, + "test_address": test_address, "inserted_at": inserted_at, "expected_result": expected_result, - "done": done, + "is_done": is_done, "expires_at": inserted_at + expires_at}) return True @classmethod def set_delayed_test_to_done(self, guid_): - """ This method updates the delayedTestData table in the DB + """ This method updates the delayed_test_data table in the DB to set the test with the selected guid to done. :param guid_: The guid that is provided by the test case. (Format: str(uuid.uuid4())) :returns: True (when no exceptions or errors occur) """ db = DatabaseManager() - query = """UPDATE delayedTestData - SET done=TRUE + query = """UPDATE delayed_test_data + SET is_done=TRUE WHERE guid=%(guid)s - AND done=FALSE""" + AND is_done=FALSE""" db.execute_query_and_close(query, {"guid": guid_}) return True @@ -94,7 +93,7 @@ def get_delayed_results(self, test_id, seconds, set_done=True): in the DB to done. The results is a list of dicts where each list item contains item[0] = guid - item[1] = testcaseAddress + item[1] = test_address item[2] = seconds from epoch item[3] = expected results dict encoded in json :param test_id: the self.id() of the test @@ -102,7 +101,7 @@ def get_delayed_results(self, test_id, seconds, set_done=True): :returns: the results for a specific test where enough time has passed """ delayed_test_data = DelayedTestStorage.get_delayed_test_data( - testcase_address=test_id) + test_address=test_id) now = int(time.time() * 1000) results_to_check = [] if delayed_test_data is None: diff --git a/seleniumbase/plugins/db_reporting_plugin.py b/seleniumbase/plugins/db_reporting_plugin.py index 506473b5b53..23ad760fad6 100755 --- a/seleniumbase/plugins/db_reporting_plugin.py +++ b/seleniumbase/plugins/db_reporting_plugin.py @@ -1,6 +1,5 @@ """ -This is the Database test reporting plugin for -recording all test run data in the database. +This plugin is for recording test results in the Testcase Database. """ import getpass @@ -19,7 +18,7 @@ class DBReporting(Plugin): """ - The plugin for reporting test results in the database. + This plugin records test results in the Testcase Database. """ name = 'db_reporting' # Usage: --with-db_reporting @@ -48,8 +47,8 @@ def configure(self, options, conf): self.testcase_manager = TestcaseManager(self.options.database_env) def begin(self): - """At the start of the run, we want to record the test - execution information in the database.""" + """ At the start of the run, we want to record the test + execution information in the database. """ exec_payload = ExecutionQueryPayload() exec_payload.execution_start_time = int(time.time() * 1000) self.execution_start_time = exec_payload.execution_start_time @@ -58,7 +57,7 @@ def begin(self): self.testcase_manager.insert_execution_data(exec_payload) def startTest(self, test): - """At the start of the test, set the testcase details.""" + """ At the start of the test, set the testcase details. """ data_payload = TestcaseDataPayload() self.testcase_guid = str(uuid.uuid4()) data_payload.guid = self.testcase_guid @@ -78,8 +77,8 @@ def startTest(self, test): test.testcase_guid = self.testcase_guid def finalize(self, result): - """At the end of the run, we want to - update the DB row with the execution time.""" + """ At the end of the run, we want to + update the DB row with the execution time. """ runtime = int(time.time() * 1000) - self.execution_start_time self.testcase_manager.update_execution_data(self.execution_guid, runtime) From 91953cd436c53ef6eb3c76a130c95c53f90d3338 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 12 Apr 2018 15:54:28 -0400 Subject: [PATCH 27/47] Update the ReadMe --- README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index f538f29e21e..845b777ee99 100755 --- a/README.md +++ b/README.md @@ -626,36 +626,36 @@ Let's say you have a test that needs to access the database. First make sure you ```python from seleniumbase.core.mysql import DatabaseManager -def write_data_to_db(self, theId, theValue, theUrl): +def write_data_to_db(self, the_id, the_value, the_url): db = DatabaseManager() - query = """INSERT INTO myTable(theId,theValue,theUrl) - VALUES (%(theId)s,%(theValue)s,%(theUrl)s)""" - db.execute_query_and_close(query, {"theId":theId, - "theValue":theValue, - "theUrl":theUrl}) + query = """INSERT INTO myTable(the_id,the_value,the_url) + VALUES (%(the_id)s,%(the_value)s,%(the_url)s)""" + db.execute_query_and_close(query, {"the_id":the_id, + "the_value":the_value, + "the_url":the_url}) ``` Access credentials are stored in [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py) for your convenience (you have to add them first). -The following example below (taken from the Delayed Data Manager) shows how data can be pulled from the database. +The following example below (taken from the Delayed Test Data Manager) shows how data can be pulled from the database. ```python import logging from seleniumbase.core.mysql import DatabaseManager -def get_delayed_test_data(self, testcase_address, done=0): +def get_delayed_test_data(self, test_address, is_done=0): """ Returns a list of rows """ db = DatabaseManager() - query = """SELECT guid,testcaseAddress,insertedAt,expectedResult,done - FROM delayedTestData - WHERE testcaseAddress=%(testcase_address)s - AND done=%(done)s""" - data = db.fetchall_query_and_close(query, {"testcase_address":testcase_address, "done":done}) + query = """SELECT guid,test_address,inserted_at,expected_result,is_done + FROM delayed_test_data + WHERE test_address=%(test_address)s + AND is_done=%(is_done)s""" + data = db.fetchall_query_and_close(query, {"test_address":test_address, "is_done":is_done}) if data: return data else: - logging.debug("Could not find any rows in delayedTestData.") - logging.debug("DB Query = " + query % {"testcase_address":testcase_address, "done":done}) + logging.debug("Could not find any rows in delayed_test_data.") + logging.debug("DB Query = " + query % {"test_address":test_address, "is_done":is_done}) return [] ``` From b810287adcbca364ca7c36958be1f32221ad2c6b Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 12 Apr 2018 16:01:46 -0400 Subject: [PATCH 28/47] Update documentation. --- seleniumbase/core/testcase_manager.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/seleniumbase/core/testcase_manager.py b/seleniumbase/core/testcase_manager.py index adf872e2cb9..f7475eaf182 100755 --- a/seleniumbase/core/testcase_manager.py +++ b/seleniumbase/core/testcase_manager.py @@ -8,7 +8,9 @@ def __init__(self, database_env): def insert_execution_data(self, execution_query_payload): """ Inserts a test execution row into the database. - Returns the execution guid. """ + Returns the execution guid. + "execution_start_time" is defined by milliseconds since the Epoch. + (See https://currentmillis.com to convert that to a real date.) """ query = """INSERT INTO execution (guid, execution_start, total_execution_time, username) From 2b8e5d5ba29f6d3301be2376128c840c3239b3a1 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 12 Apr 2018 16:24:15 -0400 Subject: [PATCH 29/47] Update the MySQL deploy script --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d552e664b0d..0e422f8a60a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,7 @@ script: - "nosetests examples/boilerplates/boilerplate_test.py --headless" - "pytest examples/my_first_test.py --browser=firefox -s --headless" - "pytest examples/github_test.py --browser=chrome -s --headless --with-db_reporting" - - "sudo mysql --password=test -e 'select testcaseAddress,browser,state,runtime from test_db.testcaseRunData'" + - "sudo mysql --password=test -e 'select test_address,browser,state,start_time,runtime from test_db.test_run_data'" after_script: - "sudo mysql -e 'DROP DATABASE test_db;'" notifications: From 82e6219f2c0543e6124d3ff20b6ed6785f184078 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 12 Apr 2018 16:25:50 -0400 Subject: [PATCH 30/47] Rename the script that creates MySQL DB tables --- .travis.yml | 2 +- .../core/{testcaserepository.sql => create_db_tables.sql} | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) rename seleniumbase/core/{testcaserepository.sql => create_db_tables.sql} (95%) diff --git a/.travis.yml b/.travis.yml index 0e422f8a60a..69e37bff982 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ addons: chrome: stable before_install: - "sudo mysql -e 'CREATE DATABASE IF NOT EXISTS test_db;'" - - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/testcaserepository.sql" + - "sudo mysql -h 127.0.0.1 -u root test_db < seleniumbase/core/create_db_tables.sql" - "mysqladmin -u root password test" # - "mysqladmin -u root -p'old_password' password new_password" - "sudo service mysql restart" diff --git a/seleniumbase/core/testcaserepository.sql b/seleniumbase/core/create_db_tables.sql similarity index 95% rename from seleniumbase/core/testcaserepository.sql rename to seleniumbase/core/create_db_tables.sql index 9a0a6d64426..5844353e7cf 100755 --- a/seleniumbase/core/testcaserepository.sql +++ b/seleniumbase/core/create_db_tables.sql @@ -1,3 +1,5 @@ +# Creates test_db tables for using SeleniumBase with MySQL + # test_run_data table # ----------------------------------- CREATE TABLE `test_run_data` ( From 6a62c40d22b753aac805e534fb9e9de41e0b75e2 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 12 Apr 2018 16:26:44 -0400 Subject: [PATCH 31/47] Update the Google Cloud ReadMe with the updated MySQL script --- integrations/google_cloud/ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/google_cloud/ReadMe.md b/integrations/google_cloud/ReadMe.md index 14f1afc126e..7306860a72e 100755 --- a/integrations/google_cloud/ReadMe.md +++ b/integrations/google_cloud/ReadMe.md @@ -168,7 +168,7 @@ If you have a web application that you want to test, you'll be able to create Se #### Step 26. Create the necessary tables in your MySQL database/schema -* Run a SQL script in your MySQL database/schema using [testcaserepository.sql](https://raw.githubusercontent.com/seleniumbase/SeleniumBase/master/seleniumbase/core/testcaserepository.sql) +* Run the [create_db_tables.sql](https://raw.githubusercontent.com/seleniumbase/SeleniumBase/master/seleniumbase/core/create_db_tables.sql) script in your MySQL database/schema to create all the required DB tables. #### Step 27. Have your local clone of SeleniumBase connect to your MySQL Instance From 8ead18eb37398533248d028b1a6c684a6667e6dd Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Thu, 12 Apr 2018 16:41:31 -0400 Subject: [PATCH 32/47] Fix a few MySQL DB naming issues --- seleniumbase/fixtures/base_case.py | 2 +- seleniumbase/plugins/db_reporting_plugin.py | 2 +- seleniumbase/plugins/s3_logging_plugin.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index 5ad7725d312..6754374b67e 100755 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -2062,7 +2062,7 @@ def setUp(self): data_payload.browser = self.browser else: data_payload.browser = "N/A" - data_payload.testcaseAddress = test_id + data_payload.test_address = test_id application = ApplicationManager.generate_application_string( self._testMethodName) data_payload.env = application.split('.')[0] diff --git a/seleniumbase/plugins/db_reporting_plugin.py b/seleniumbase/plugins/db_reporting_plugin.py index 23ad760fad6..aa113f9113e 100755 --- a/seleniumbase/plugins/db_reporting_plugin.py +++ b/seleniumbase/plugins/db_reporting_plugin.py @@ -66,7 +66,7 @@ def startTest(self, test): data_payload.browser = test.browser else: data_payload.browser = "N/A" - data_payload.testcaseAddress = test.id() + data_payload.test_address = test.id() application = ApplicationManager.generate_application_string(test) data_payload.env = application.split('.')[0] data_payload.start_time = application.split('.')[1] diff --git a/seleniumbase/plugins/s3_logging_plugin.py b/seleniumbase/plugins/s3_logging_plugin.py index 881a4a720f1..28d991c6063 100755 --- a/seleniumbase/plugins/s3_logging_plugin.py +++ b/seleniumbase/plugins/s3_logging_plugin.py @@ -47,5 +47,5 @@ def afterTest(self, test): self.testcase_manager = TestcaseManager(self.options.database_env) data_payload = TestcaseDataPayload() data_payload.guid = test.test.testcase_guid - data_payload.logURL = index_file + data_payload.log_url = index_file self.testcase_manager.update_testcase_log_url(data_payload) From 8b59ce0322ffd93fe233fe4aaf8dcb8e22294541 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 13 Apr 2018 00:56:02 -0400 Subject: [PATCH 33/47] See if mysqlclient includes MySQL-python for the deploy script --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 69e37bff982..eb9a7e458dc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ before_install: install: - "pip install --upgrade pip" - "pip install -r requirements.txt --upgrade" - - "pip install MySQL-python==1.2.5" + # - "pip install MySQL-python==1.2.5" - "python setup.py develop" - "sudo rm -f /etc/boto.cfg" before_script: From bbf3cdad55e50c7c714579eb7fe7f49042df10be Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 13 Apr 2018 01:19:16 -0400 Subject: [PATCH 34/47] Update the Google Cloud ReadMe --- integrations/google_cloud/ReadMe.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/integrations/google_cloud/ReadMe.md b/integrations/google_cloud/ReadMe.md index 7306860a72e..db2ab359413 100755 --- a/integrations/google_cloud/ReadMe.md +++ b/integrations/google_cloud/ReadMe.md @@ -170,16 +170,11 @@ If you have a web application that you want to test, you'll be able to create Se * Run the [create_db_tables.sql](https://raw.githubusercontent.com/seleniumbase/SeleniumBase/master/seleniumbase/core/create_db_tables.sql) script in your MySQL database/schema to create all the required DB tables. -#### Step 27. Have your local clone of SeleniumBase connect to your MySQL Instance +#### Step 27. Have your local clone of SeleniumBase connect to your MySQL DB Instance * Update the MySQL connection details in your [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py) file to use the credentials that you saved in Step 21. -* If you haven't already installed the MySQL-Python connector, run the following command below: -```bash -pip install MySQL-python==1.2.5 -``` - -#### Step 28. Have your SeleniumBase Jenkins jobs use your MySQL Instance +#### Step 28. Have your SeleniumBase Jenkins jobs use your MySQL DB Instance * For the "Execute shell", use the following as your updated "Command": From 9c943525e19a3d77e3b839ab9869a1c229eb2a72 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 13 Apr 2018 01:29:06 -0400 Subject: [PATCH 35/47] Version 1.9.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 0227a04b1ac..3183603381b 100755 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setup( name='seleniumbase', - version='1.8.7', + version='1.9.0', description='Web Automation & Testing Framework - http://seleniumbase.com', long_description='Web Automation and Testing Framework - seleniumbase.com', platforms='Mac * Windows * Linux * Docker', From d389df91ba6c5d88db441baca1646395b92d7b7d Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 13 Apr 2018 01:35:00 -0400 Subject: [PATCH 36/47] Update the deploy script --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index eb9a7e458dc..1e3145f7f90 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,7 @@ before_script: script: - "pytest examples/my_first_test.py --browser=chrome -s --headless" - "nosetests examples/boilerplates/boilerplate_test.py --headless" - - "pytest examples/my_first_test.py --browser=firefox -s --headless" + - "pytest examples/my_first_test.py --browser=firefox -s --headless --with-db_reporting" - "pytest examples/github_test.py --browser=chrome -s --headless --with-db_reporting" - "sudo mysql --password=test -e 'select test_address,browser,state,start_time,runtime from test_db.test_run_data'" after_script: From 7ff6bafa10d9df824149833c291a837267d94a18 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 13 Apr 2018 01:53:51 -0400 Subject: [PATCH 37/47] Update the deploy script --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1e3145f7f90..5d88a9fa830 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: python sudo: false python: - "2.7" + - "3.6" addons: firefox: latest chrome: stable @@ -14,12 +15,10 @@ before_install: install: - "pip install --upgrade pip" - "pip install -r requirements.txt --upgrade" - # - "pip install MySQL-python==1.2.5" - "python setup.py develop" - "sudo rm -f /etc/boto.cfg" before_script: - "flake8 seleniumbase/*.py && flake8 seleniumbase/*/*.py && flake8 seleniumbase/*/*/*.py && flake8 seleniumbase/*/*/*/*.py" - # - "export DISPLAY=:99.0 && sh -e /etc/init.d/xvfb start" - "wget https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip && unzip chromedriver_linux64.zip && sudo cp chromedriver /usr/local/bin/ && sudo chmod +x /usr/local/bin/chromedriver" - "wget https://github.com/mozilla/geckodriver/releases/download/v0.20.0/geckodriver-v0.20.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" # - "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" From 14bd12582720b830023d083dca97258185975b25 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Sat, 14 Apr 2018 19:19:27 -0400 Subject: [PATCH 38/47] Update naming of db methods --- README.md | 8 ++++---- seleniumbase/core/mysql.py | 20 +++++++++---------- seleniumbase/core/testcase_manager.py | 10 +++++----- seleniumbase/fixtures/delayed_data_manager.py | 6 +++--- 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 845b777ee99..a51239a1063 100755 --- a/README.md +++ b/README.md @@ -630,9 +630,9 @@ def write_data_to_db(self, the_id, the_value, the_url): db = DatabaseManager() query = """INSERT INTO myTable(the_id,the_value,the_url) VALUES (%(the_id)s,%(the_value)s,%(the_url)s)""" - db.execute_query_and_close(query, {"the_id":the_id, - "the_value":the_value, - "the_url":the_url}) + db.execute_query(query, {"the_id":the_id, + "the_value":the_value, + "the_url":the_url}) ``` Access credentials are stored in [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py) for your convenience (you have to add them first). @@ -650,7 +650,7 @@ def get_delayed_test_data(self, test_address, is_done=0): FROM delayed_test_data WHERE test_address=%(test_address)s AND is_done=%(is_done)s""" - data = db.fetchall_query_and_close(query, {"test_address":test_address, "is_done":is_done}) + data = db.fetchall_query(query, {"test_address":test_address, "is_done":is_done}) if data: return data else: diff --git a/seleniumbase/core/mysql.py b/seleniumbase/core/mysql.py index 6715514aa99..b7305df20ea 100755 --- a/seleniumbase/core/mysql.py +++ b/seleniumbase/core/mysql.py @@ -1,27 +1,25 @@ """ -Wrapper for MySQL functions to make life easier -Due to compatibility issues, might only work for Python 2.7 right now +Wrapper for MySQL DB functions to make life easier. """ import time +from seleniumbase.core import mysql_conf as conf class DatabaseManager(): """ This class wraps MySQL database methods for easy use. - It connects to the testcase database. """ def __init__(self, database_env='test', conf_creds=None): """ Gets database information from mysql_conf.py and creates a connection. """ - from seleniumbase.core import mysql_conf as conf import MySQLdb db_server, db_user, db_pass, db_schema = \ conf.APP_CREDS[conf.Apps.TESTCASE_REPOSITORY][database_env] retry_count = 3 - backoff = 1.2 # Time to wait (in seconds) between retries + backoff = 1.2 # Time to wait (in seconds) between retries. count = 0 while count < retry_count: try: @@ -38,27 +36,27 @@ def __init__(self, database_env='test', conf_creds=None): if retry_count == 3: raise Exception("Unable to connect to Database after 3 retries.") - def fetchall_query_and_close(self, query, values): + def query_fetch_all(self, query, values): """ - Executes a query, gets all the values, and closes the connection. + Executes a db query, gets all the values, and closes the connection. """ self.cursor.execute(query, values) retval = self.cursor.fetchall() self.__close_db() return retval - def fetchone_query_and_close(self, query, values): + def query_fetch_one(self, query, values): """ - Executes a query, gets the first value, and closes the connection. + Executes a db query, gets the first value, and closes the connection. """ self.cursor.execute(query, values) retval = self.cursor.fetchone() self.__close_db() return retval - def execute_query_and_close(self, query, values): + def execute_query(self, query, values): """ - Executes a query and closes the connection. + Executes a query to the test_db and closes the connection afterwards. """ retval = self.cursor.execute(query, values) self.__close_db() diff --git a/seleniumbase/core/testcase_manager.py b/seleniumbase/core/testcase_manager.py index f7475eaf182..46f0501f4ab 100755 --- a/seleniumbase/core/testcase_manager.py +++ b/seleniumbase/core/testcase_manager.py @@ -16,7 +16,7 @@ def insert_execution_data(self, execution_query_payload): (guid, execution_start, total_execution_time, username) VALUES (%(guid)s,%(execution_start_time)s, %(total_execution_time)s,%(username)s)""" - DatabaseManager(self.database_env).execute_query_and_close( + DatabaseManager(self.database_env).execute_query( query, execution_query_payload.get_params()) return execution_query_payload.guid @@ -26,7 +26,7 @@ def update_execution_data(self, execution_guid, execution_time): query = """UPDATE execution SET total_execution_time=%(execution_time)s WHERE guid=%(execution_guid)s """ - DatabaseManager(self.database_env).execute_query_and_close( + DatabaseManager(self.database_env).execute_query( query, {"execution_guid": execution_guid, "execution_time": execution_time}) @@ -48,7 +48,7 @@ def insert_testcase_data(self, testcase_run_payload): %(retry_count)s, %(message)s, %(stack_trace)s) """ - DatabaseManager(self.database_env).execute_query_and_close( + DatabaseManager(self.database_env).execute_query( query, testcase_run_payload.get_params()) def update_testcase_data(self, testcase_payload): @@ -60,14 +60,14 @@ def update_testcase_data(self, testcase_payload): stack_trace=%(stack_trace)s, message=%(message)s WHERE guid=%(guid)s """ - DatabaseManager(self.database_env).execute_query_and_close( + DatabaseManager(self.database_env).execute_query( query, testcase_payload.get_params()) def update_testcase_log_url(self, testcase_payload): query = """UPDATE test_run_data SET log_url=%(log_url)s WHERE guid=%(guid)s """ - DatabaseManager(self.database_env).execute_query_and_close( + DatabaseManager(self.database_env).execute_query( query, testcase_payload.get_params()) diff --git a/seleniumbase/fixtures/delayed_data_manager.py b/seleniumbase/fixtures/delayed_data_manager.py index 2aba00a20e0..fbb723613c9 100755 --- a/seleniumbase/fixtures/delayed_data_manager.py +++ b/seleniumbase/fixtures/delayed_data_manager.py @@ -22,7 +22,7 @@ def get_delayed_test_data(self, test_address, is_done=0): FROM delayed_test_data WHERE test_address=%(test_address)s AND is_done=%(is_done)s""" - data = db.fetchall_query_and_close( + data = db.query_fetch_all( query, {"test_address": test_address, "is_done": is_done}) if data: @@ -57,7 +57,7 @@ def insert_delayed_test_data(self, guid_, test_address, VALUES (%(guid)s,%(test_address)s,%(inserted_at)s, %(expected_result)s,%(is_done)s,%(expires_at)s)""" - db.execute_query_and_close( + db.execute_query( query, {"guid": guid_, "test_address": test_address, "inserted_at": inserted_at, @@ -79,7 +79,7 @@ def set_delayed_test_to_done(self, guid_): SET is_done=TRUE WHERE guid=%(guid)s AND is_done=FALSE""" - db.execute_query_and_close(query, {"guid": guid_}) + db.execute_query(query, {"guid": guid_}) return True From 8798dba3d19eba4bb023408782d4fd41e4a541b8 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Mon, 16 Apr 2018 16:00:32 -0400 Subject: [PATCH 39/47] If you're overriding SeleniumBase's BaseCase setUp() method, you'll know. --- seleniumbase/fixtures/base_case.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index 6754374b67e..77cbe473361 100755 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -2176,7 +2176,34 @@ def tearDown(self): test_id = "%s.%s.%s" % (self.__class__.__module__, self.__class__.__name__, self._testMethodName) - if self.with_selenium: + try: + with_selenium = self.with_selenium + except Exception: + sub_class_name = str( + self.__class__.__bases__[0]).split('.')[-1].split("'")[0] + sub_file_name = str(self.__class__.__bases__[0]).split('.')[-2] + sub_file_name = sub_file_name + ".py" + class_name = str(self.__class__).split('.')[-1].split("'")[0] + file_name = str(self.__class__).split('.')[-2] + ".py" + class_name_used = sub_class_name + file_name_used = sub_file_name + if sub_class_name == "BaseCase": + class_name_used = class_name + file_name_used = file_name + fix_setup = "super(%s, self).setUp()" % class_name_used + fix_teardown = "super(%s, self).tearDown()" % class_name_used + message = ("You're overriding SeleniumBase's BaseCase setUp() " + "method with your own setUp() method, which breaks " + "SeleniumBase. You can fix this by going to your " + "%s class located in your %s file and adding the " + "following line of code AT THE BEGINNING of your " + "setUp() method:\n%s\n\nAlso make sure " + "you have added the following line of code AT THE " + "END of your tearDown() method:\n%s\n" + % (class_name_used, file_name_used, + fix_setup, fix_teardown)) + raise Exception(message) + if with_selenium: # Save a screenshot if logging is on when an exception occurs if has_exception: self._add_pytest_html_extra() From ee7306a1aeeabdeb46730cb71ef11caa7f28ada7 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 17 Apr 2018 02:17:50 -0400 Subject: [PATCH 40/47] test_db method naming --- README.md | 10 +- seleniumbase/core/create_db_tables.sql | 8 +- seleniumbase/fixtures/delayed_data_manager.py | 91 +++++++++++-------- 3 files changed, 60 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index a51239a1063..0ec4acb97fa 100755 --- a/README.md +++ b/README.md @@ -643,25 +643,25 @@ The following example below (taken from the Delayed Test Data Manager) shows how import logging from seleniumbase.core.mysql import DatabaseManager -def get_delayed_test_data(self, test_address, is_done=0): +def get_divided_test_data(self, test_address, is_done=0): """ Returns a list of rows """ db = DatabaseManager() - query = """SELECT guid,test_address,inserted_at,expected_result,is_done - FROM delayed_test_data + query = """SELECT guid,test_address,inserted_at,test_data,is_done + FROM divided_test_data WHERE test_address=%(test_address)s AND is_done=%(is_done)s""" data = db.fetchall_query(query, {"test_address":test_address, "is_done":is_done}) if data: return data else: - logging.debug("Could not find any rows in delayed_test_data.") + logging.debug("Could not find any rows in divided_test_data.") logging.debug("DB Query = " + query % {"test_address":test_address, "is_done":is_done}) return [] ``` Now you know how to pull data from your MySQL DB. -Delayed Data usage example: If you scheduled an email to go out 3 hours from now and you wanted to check that the email gets received (but you don't want your test sitting idle for 3 hours) you can store the email credentials as a unique time-stamp for the email subject in the DB (along with a time for when it's safe for the email to be searched for) and then a later-running test can do the checking after the right amount of time has passed. +Divided Test usage example: If you scheduled an email to go out 3 hours from now and you wanted to check that the email gets received (but you don't want your test sitting idle for 3 hours) you can store the email credentials as a unique time-stamp for the email subject in the DB (along with a time for when it's safe for the email to be searched for) and then a later-running test can do the checking after the right amount of time has passed. ### ![http://seleniumbase.com](https://cdn2.hubspot.net/hubfs/100006/images/super_logo_tiny.png "SeleniumBase") Wrap-Up diff --git a/seleniumbase/core/create_db_tables.sql b/seleniumbase/core/create_db_tables.sql index 5844353e7cf..37bb6ac387f 100755 --- a/seleniumbase/core/create_db_tables.sql +++ b/seleniumbase/core/create_db_tables.sql @@ -29,15 +29,15 @@ CREATE TABLE `execution` ( PRIMARY KEY (`guid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -# delayed_test_data table +# divided_test_data table # ----------------------------------- -CREATE TABLE `delayed_test_data` ( +CREATE TABLE `divided_test_data` ( `guid` varchar(64) NOT NULL DEFAULT '', `test_address` varchar(255) NOT NULL DEFAULT '', `inserted_at` bigint(20) NOT NULL, - `expected_result` text, + `test_data` text, `is_done` tinyint(1) DEFAULT '0', - `expires_at` bigint(20) DEFAULT NULL, + `wait_time` bigint(20) DEFAULT NULL, PRIMARY KEY (`guid`), UNIQUE KEY `uuid` (`guid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/seleniumbase/fixtures/delayed_data_manager.py b/seleniumbase/fixtures/delayed_data_manager.py index fbb723613c9..d916968fab3 100755 --- a/seleniumbase/fixtures/delayed_data_manager.py +++ b/seleniumbase/fixtures/delayed_data_manager.py @@ -4,22 +4,34 @@ import uuid from seleniumbase.core.mysql import DatabaseManager -DEFAULT_EXPIRATION = 1000 * 60 * 60 * 24 # A day later (in milliseconds) +DEFAULT_WAIT_TIME = 1000 * 60 * 60 * 24 # A day later (in milliseconds) -class DelayedTestStorage: +class DividedTestStorage: + """ + When you need a large time delay between two parts of a test, you can break + the test up into two tests, and use the divided_test_data table of the + MySQL DB to hold onto important information until the second part of the + divided test is ready to complete the remainder of the test. + + *** Example ***: + You've created an email-marketing tool that sends out a follow-up email in + exactly 24 hours. The first part of the test can schedule the follow-up + email while the second part of the test verifies that the follow-up email + was sent and received successfully after enough time has passed. + """ @classmethod - def get_delayed_test_data(self, test_address, is_done=0): - """ This method queries the delayed_test_data table in the DB and + def get_divided_test_data(self, test_address, is_done=0): + """ This method queries the divided_test_data table in the test_db and then returns a list of rows with the matching parameters. :param test_address: The ID (address) of the test case. :param is_done: (0 for test not done or 1 for test done) :returns: A list of rows found with the matching test_address. """ db = DatabaseManager() - query = """SELECT guid,test_address,inserted_at,expected_result,is_done - FROM delayed_test_data + query = """SELECT guid,test_address,inserted_at,test_data,is_done + FROM divided_test_data WHERE test_address=%(test_address)s AND is_done=%(is_done)s""" data = db.query_fetch_all( @@ -28,54 +40,53 @@ def get_delayed_test_data(self, test_address, is_done=0): if data: return data else: - logging.debug("Could not find any rows in delayed_test_data.") + logging.debug("Could not find any rows in divided_test_data.") logging.debug("DB Query = " + query % {"test_address": test_address, "is_done": is_done}) return [] @classmethod - def insert_delayed_test_data(self, guid_, test_address, - expected_result, is_done=0, - expires_at=DEFAULT_EXPIRATION): - """ This method inserts rows into the delayed_test_data table + def insert_divided_test_data(self, guid_, test_address, + test_data, is_done=0, + wait_time=DEFAULT_WAIT_TIME): + """ This method inserts rows into the divided_test_data table in the DB based on the given parameters where inserted_at (Date format) is automatically set in this method. :param guid_: The guid that is provided by the test case. (Format: str(uuid.uuid4())) :param test_address: The ID (address) of the test case. - :param expected_result: The result string of persistent data - that will be stored in the DB. + :param test_data: Additional data to store for the test. :param is_done: (0 for test not done or 1 for test done) :returns: True (when no exceptions or errors occur) """ inserted_at = int(time.time() * 1000) db = DatabaseManager() - query = """INSERT INTO delayed_test_data( + query = """INSERT INTO divided_test_data( guid,test_address,inserted_at, - expected_result,is_done,expires_at) + test_data,is_done,wait_time) VALUES (%(guid)s,%(test_address)s,%(inserted_at)s, - %(expected_result)s,%(is_done)s,%(expires_at)s)""" + %(test_data)s,%(is_done)s,%(wait_time)s)""" db.execute_query( query, {"guid": guid_, "test_address": test_address, "inserted_at": inserted_at, - "expected_result": expected_result, + "test_data": test_data, "is_done": is_done, - "expires_at": inserted_at + expires_at}) + "wait_time": inserted_at + wait_time}) return True @classmethod - def set_delayed_test_to_done(self, guid_): - """ This method updates the delayed_test_data table in the DB + def set_divided_test_to_done(self, guid_): + """ This method updates the divided_test_data table in the DB to set the test with the selected guid to done. :param guid_: The guid that is provided by the test case. (Format: str(uuid.uuid4())) :returns: True (when no exceptions or errors occur) """ db = DatabaseManager() - query = """UPDATE delayed_test_data + query = """UPDATE divided_test_data SET is_done=TRUE WHERE guid=%(guid)s AND is_done=FALSE""" @@ -83,58 +94,58 @@ def set_delayed_test_to_done(self, guid_): return True -class DelayedTestAssistant: +class DividedTestAssistant: """ Some methods for assisting tests (that don't call the DB directly) """ @classmethod - def get_delayed_results(self, test_id, seconds, set_done=True): + def get_divided_test_results(self, test_id, seconds, set_done=True): """ - This method gets the delayed_test_data and sets the applicable rows + This method gets the divided_test data and sets the applicable rows in the DB to done. The results is a list of dicts where each list item contains item[0] = guid item[1] = test_address - item[2] = seconds from epoch - item[3] = expected results dict encoded in json + item[2] = time (in seconds from Epoch) + item[3] = test data dict encoded in json :param test_id: the self.id() of the test :param seconds: the wait period until the data can be checked :returns: the results for a specific test where enough time has passed """ - delayed_test_data = DelayedTestStorage.get_delayed_test_data( + divided_test_data = DividedTestStorage.get_divided_test_data( test_address=test_id) now = int(time.time() * 1000) results_to_check = [] - if delayed_test_data is None: + if divided_test_data is None: return results_to_check - for item in delayed_test_data: + for item in divided_test_data: if item[2] < now - (seconds * 1000): results_to_check.append(item) if set_done: - DelayedTestStorage.set_delayed_test_to_done(item[0]) + DividedTestStorage.set_divided_test_to_done(item[0]) return results_to_check @classmethod - def store_delayed_data(self, test_id, expected_result_dict, - expires_at=DEFAULT_EXPIRATION): + def store_divided_test_data(self, test_id, test_data_dict, + wait_time=DEFAULT_WAIT_TIME): """ - Loads the dictionary of information into the delayed test database + Loads the dictionary of information into the divided_test_data table :param test_id: the self.id() of the test - :param expected_result_dict: a dictionary of what's to be checked later + :param test_data_dict: a dictionary of data to store for later """ - expected_result_json = json.JSONEncoder().encode(expected_result_dict) - DelayedTestStorage.insert_delayed_test_data(str(uuid.uuid4()), + test_data_json = json.JSONEncoder().encode(test_data_dict) + DividedTestStorage.insert_divided_test_data(str(uuid.uuid4()), test_id, - expected_result_json, + test_data_json, 0, - expires_at) + wait_time) @classmethod def set_test_done(self, test_guid): - """ This method calls set_delayed_test_to_done to set a + """ This method calls set_divided_test_to_done to set a row in the db to done. :param test_guid: The guid that is provided by the test. (Format: str(uuid.uuid4())) :returns: True (when no exceptions or errors occur) """ - DelayedTestStorage.set_delayed_test_to_done(test_guid) + DividedTestStorage.set_divided_test_to_done(test_guid) return True From d44ec1d8856c7baf6fa2a9d3f11be606fbaa6a9c Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 17 Apr 2018 02:28:01 -0400 Subject: [PATCH 41/47] Renaming a DB method file --- .../fixtures/{delayed_data_manager.py => divided_test_manager.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename seleniumbase/fixtures/{delayed_data_manager.py => divided_test_manager.py} (100%) diff --git a/seleniumbase/fixtures/delayed_data_manager.py b/seleniumbase/fixtures/divided_test_manager.py similarity index 100% rename from seleniumbase/fixtures/delayed_data_manager.py rename to seleniumbase/fixtures/divided_test_manager.py From a7762711661ea2f15058edd3ffcd693c586728dc Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 17 Apr 2018 02:36:46 -0400 Subject: [PATCH 42/47] Rename a test_db table for clarity --- seleniumbase/core/create_db_tables.sql | 4 ++-- seleniumbase/core/testcase_manager.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/seleniumbase/core/create_db_tables.sql b/seleniumbase/core/create_db_tables.sql index 37bb6ac387f..bd3de9840f6 100755 --- a/seleniumbase/core/create_db_tables.sql +++ b/seleniumbase/core/create_db_tables.sql @@ -19,9 +19,9 @@ CREATE TABLE `test_run_data` ( PRIMARY KEY (`guid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -# execution table +# test_execution table # ----------------------------------- -CREATE TABLE `execution` ( +CREATE TABLE `test_execution` ( `guid` varchar(64) NOT NULL DEFAULT '', `total_execution_time` int(11), `username` varchar(255) DEFAULT NULL, diff --git a/seleniumbase/core/testcase_manager.py b/seleniumbase/core/testcase_manager.py index 46f0501f4ab..83faf598a59 100755 --- a/seleniumbase/core/testcase_manager.py +++ b/seleniumbase/core/testcase_manager.py @@ -12,7 +12,7 @@ def insert_execution_data(self, execution_query_payload): "execution_start_time" is defined by milliseconds since the Epoch. (See https://currentmillis.com to convert that to a real date.) """ - query = """INSERT INTO execution + query = """INSERT INTO test_execution (guid, execution_start, total_execution_time, username) VALUES (%(guid)s,%(execution_start_time)s, %(total_execution_time)s,%(username)s)""" @@ -23,7 +23,7 @@ def insert_execution_data(self, execution_query_payload): def update_execution_data(self, execution_guid, execution_time): """ Updates an existing test execution row in the database. """ - query = """UPDATE execution + query = """UPDATE test_execution SET total_execution_time=%(execution_time)s WHERE guid=%(execution_guid)s """ DatabaseManager(self.database_env).execute_query( From 34a2078e7d583fa5d6aa17b86b6a78209d8015d9 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 17 Apr 2018 02:43:54 -0400 Subject: [PATCH 43/47] Update naming in ReadMe --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0ec4acb97fa..812ebb368a0 100755 --- a/README.md +++ b/README.md @@ -637,7 +637,7 @@ def write_data_to_db(self, the_id, the_value, the_url): Access credentials are stored in [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py) for your convenience (you have to add them first). -The following example below (taken from the Delayed Test Data Manager) shows how data can be pulled from the database. +The following example below (taken from the Divided Test Data Manager) shows how data can be pulled from the database. ```python import logging From 476eaa9ee3297a0b5f294f18309439d9e332ea49 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 17 Apr 2018 02:53:24 -0400 Subject: [PATCH 44/47] Removing some older test_db functionality until it's ready for prime time --- README.md | 43 ----- seleniumbase/core/create_db_tables.sql | 13 -- seleniumbase/fixtures/divided_test_manager.py | 151 ------------------ 3 files changed, 207 deletions(-) delete mode 100755 seleniumbase/fixtures/divided_test_manager.py diff --git a/README.md b/README.md index 812ebb368a0..a960f92123a 100755 --- a/README.md +++ b/README.md @@ -621,49 +621,6 @@ self.assertTrue(num_email_results) # true if not zero Now you can parse through the email if you're looking for specific text or want to navigate to a link listed there. -#### Database Powers: -Let's say you have a test that needs to access the database. First make sure you already have a table ready. Then try this example: - -```python -from seleniumbase.core.mysql import DatabaseManager -def write_data_to_db(self, the_id, the_value, the_url): - db = DatabaseManager() - query = """INSERT INTO myTable(the_id,the_value,the_url) - VALUES (%(the_id)s,%(the_value)s,%(the_url)s)""" - db.execute_query(query, {"the_id":the_id, - "the_value":the_value, - "the_url":the_url}) -``` - -Access credentials are stored in [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py) for your convenience (you have to add them first). - -The following example below (taken from the Divided Test Data Manager) shows how data can be pulled from the database. - -```python -import logging -from seleniumbase.core.mysql import DatabaseManager - -def get_divided_test_data(self, test_address, is_done=0): - """ Returns a list of rows """ - db = DatabaseManager() - query = """SELECT guid,test_address,inserted_at,test_data,is_done - FROM divided_test_data - WHERE test_address=%(test_address)s - AND is_done=%(is_done)s""" - data = db.fetchall_query(query, {"test_address":test_address, "is_done":is_done}) - if data: - return data - else: - logging.debug("Could not find any rows in divided_test_data.") - logging.debug("DB Query = " + query % {"test_address":test_address, "is_done":is_done}) - return [] -``` - -Now you know how to pull data from your MySQL DB. - -Divided Test usage example: If you scheduled an email to go out 3 hours from now and you wanted to check that the email gets received (but you don't want your test sitting idle for 3 hours) you can store the email credentials as a unique time-stamp for the email subject in the DB (along with a time for when it's safe for the email to be searched for) and then a later-running test can do the checking after the right amount of time has passed. - - ### ![http://seleniumbase.com](https://cdn2.hubspot.net/hubfs/100006/images/super_logo_tiny.png "SeleniumBase") Wrap-Up **Congratulations** on learning how to use **SeleniumBase**! diff --git a/seleniumbase/core/create_db_tables.sql b/seleniumbase/core/create_db_tables.sql index bd3de9840f6..71f27ae04dd 100755 --- a/seleniumbase/core/create_db_tables.sql +++ b/seleniumbase/core/create_db_tables.sql @@ -28,16 +28,3 @@ CREATE TABLE `test_execution` ( `execution_start` bigint(20) DEFAULT '0', PRIMARY KEY (`guid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -# divided_test_data table -# ----------------------------------- -CREATE TABLE `divided_test_data` ( - `guid` varchar(64) NOT NULL DEFAULT '', - `test_address` varchar(255) NOT NULL DEFAULT '', - `inserted_at` bigint(20) NOT NULL, - `test_data` text, - `is_done` tinyint(1) DEFAULT '0', - `wait_time` bigint(20) DEFAULT NULL, - PRIMARY KEY (`guid`), - UNIQUE KEY `uuid` (`guid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/seleniumbase/fixtures/divided_test_manager.py b/seleniumbase/fixtures/divided_test_manager.py deleted file mode 100755 index d916968fab3..00000000000 --- a/seleniumbase/fixtures/divided_test_manager.py +++ /dev/null @@ -1,151 +0,0 @@ -import json -import logging -import time -import uuid -from seleniumbase.core.mysql import DatabaseManager - -DEFAULT_WAIT_TIME = 1000 * 60 * 60 * 24 # A day later (in milliseconds) - - -class DividedTestStorage: - """ - When you need a large time delay between two parts of a test, you can break - the test up into two tests, and use the divided_test_data table of the - MySQL DB to hold onto important information until the second part of the - divided test is ready to complete the remainder of the test. - - *** Example ***: - You've created an email-marketing tool that sends out a follow-up email in - exactly 24 hours. The first part of the test can schedule the follow-up - email while the second part of the test verifies that the follow-up email - was sent and received successfully after enough time has passed. - """ - - @classmethod - def get_divided_test_data(self, test_address, is_done=0): - """ This method queries the divided_test_data table in the test_db and - then returns a list of rows with the matching parameters. - :param test_address: The ID (address) of the test case. - :param is_done: (0 for test not done or 1 for test done) - :returns: A list of rows found with the matching test_address. - """ - db = DatabaseManager() - query = """SELECT guid,test_address,inserted_at,test_data,is_done - FROM divided_test_data - WHERE test_address=%(test_address)s - AND is_done=%(is_done)s""" - data = db.query_fetch_all( - query, {"test_address": test_address, - "is_done": is_done}) - if data: - return data - else: - logging.debug("Could not find any rows in divided_test_data.") - logging.debug("DB Query = " + query % - {"test_address": test_address, "is_done": is_done}) - return [] - - @classmethod - def insert_divided_test_data(self, guid_, test_address, - test_data, is_done=0, - wait_time=DEFAULT_WAIT_TIME): - """ This method inserts rows into the divided_test_data table - in the DB based on the given parameters where - inserted_at (Date format) is automatically set in this method. - :param guid_: The guid that is provided by the test case. - (Format: str(uuid.uuid4())) - :param test_address: The ID (address) of the test case. - :param test_data: Additional data to store for the test. - :param is_done: (0 for test not done or 1 for test done) - :returns: True (when no exceptions or errors occur) - """ - inserted_at = int(time.time() * 1000) - - db = DatabaseManager() - query = """INSERT INTO divided_test_data( - guid,test_address,inserted_at, - test_data,is_done,wait_time) - VALUES (%(guid)s,%(test_address)s,%(inserted_at)s, - %(test_data)s,%(is_done)s,%(wait_time)s)""" - - db.execute_query( - query, {"guid": guid_, - "test_address": test_address, - "inserted_at": inserted_at, - "test_data": test_data, - "is_done": is_done, - "wait_time": inserted_at + wait_time}) - return True - - @classmethod - def set_divided_test_to_done(self, guid_): - """ This method updates the divided_test_data table in the DB - to set the test with the selected guid to done. - :param guid_: The guid that is provided by the test case. - (Format: str(uuid.uuid4())) - :returns: True (when no exceptions or errors occur) - """ - db = DatabaseManager() - query = """UPDATE divided_test_data - SET is_done=TRUE - WHERE guid=%(guid)s - AND is_done=FALSE""" - db.execute_query(query, {"guid": guid_}) - return True - - -class DividedTestAssistant: - """ Some methods for assisting tests (that don't call the DB directly) """ - - @classmethod - def get_divided_test_results(self, test_id, seconds, set_done=True): - """ - This method gets the divided_test data and sets the applicable rows - in the DB to done. - The results is a list of dicts where each list item contains - item[0] = guid - item[1] = test_address - item[2] = time (in seconds from Epoch) - item[3] = test data dict encoded in json - :param test_id: the self.id() of the test - :param seconds: the wait period until the data can be checked - :returns: the results for a specific test where enough time has passed - """ - divided_test_data = DividedTestStorage.get_divided_test_data( - test_address=test_id) - now = int(time.time() * 1000) - results_to_check = [] - if divided_test_data is None: - return results_to_check - for item in divided_test_data: - if item[2] < now - (seconds * 1000): - results_to_check.append(item) - if set_done: - DividedTestStorage.set_divided_test_to_done(item[0]) - return results_to_check - - @classmethod - def store_divided_test_data(self, test_id, test_data_dict, - wait_time=DEFAULT_WAIT_TIME): - """ - Loads the dictionary of information into the divided_test_data table - :param test_id: the self.id() of the test - :param test_data_dict: a dictionary of data to store for later - """ - test_data_json = json.JSONEncoder().encode(test_data_dict) - DividedTestStorage.insert_divided_test_data(str(uuid.uuid4()), - test_id, - test_data_json, - 0, - wait_time) - - @classmethod - def set_test_done(self, test_guid): - """ This method calls set_divided_test_to_done to set a - row in the db to done. - :param test_guid: The guid that is provided by the test. - (Format: str(uuid.uuid4())) - :returns: True (when no exceptions or errors occur) - """ - DividedTestStorage.set_divided_test_to_done(test_guid) - return True From 3aceede4fbe20047c522afe5379c3c5f2218bb53 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 17 Apr 2018 02:58:53 -0400 Subject: [PATCH 45/47] Update the ReadMe --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a960f92123a..1a9d835cd32 100755 --- a/README.md +++ b/README.md @@ -609,7 +609,7 @@ Let's say you have a test that sends an email, and now you want to check that th from seleniumbase.fixtures.email_manager import EmailManager, EmailException num_email_results = 0 email_subject = "This is the subject to search for (maybe include a timestamp)" -email_manager = EmailManager("[YOUR SELENIUM GMAIL EMAIL ADDRESS]") # the password for this is elsewhere (in the library) because this is a default email account +email_manager = EmailManager("{YOUR SELENIUM GMAIL ACCOUNT EMAIL ADDRESS}") # the password for this would be stored in seleniumbase/config/settings.py try: html_text = email_manager.search(SUBJECT="%s" % email_subject, timeout=300) num_email_results = len(html_text) From 824f72cf7a714f5683b51be711a34c99c478a078 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 17 Apr 2018 03:08:28 -0400 Subject: [PATCH 46/47] Don't trigger GitHub's automation-detection system --- examples/github_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/github_test.py b/examples/github_test.py index 0404a068021..562bffaf779 100755 --- a/examples/github_test.py +++ b/examples/github_test.py @@ -9,7 +9,7 @@ class GitHubTests(BaseCase): # "Please wait a few minutes before you try again." # To avoid this, slow down Selenium actions. def slow_click(self, css_selector): - time.sleep(0.75) + time.sleep(1) self.click(css_selector) def test_github(self): From 32289fc6e79e84caf88898b78b75512dcd751a89 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 17 Apr 2018 03:19:25 -0400 Subject: [PATCH 47/47] Update the deploy script --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5d88a9fa830..3dfe945f9a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,10 +23,10 @@ before_script: - "wget https://github.com/mozilla/geckodriver/releases/download/v0.20.0/geckodriver-v0.20.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" # - "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" script: - - "pytest examples/my_first_test.py --browser=chrome -s --headless" - - "nosetests examples/boilerplates/boilerplate_test.py --headless" + - "pytest examples/my_first_test.py --browser=chrome -s --headless --with-db_reporting" + - "nosetests examples/boilerplates/boilerplate_test.py --browser=chrome --headless" - "pytest examples/my_first_test.py --browser=firefox -s --headless --with-db_reporting" - - "pytest examples/github_test.py --browser=chrome -s --headless --with-db_reporting" + - "pytest examples/github_test.py --browser=firefox -s --headless --with-db_reporting --demo_mode --demo_sleep=0.2" - "sudo mysql --password=test -e 'select test_address,browser,state,start_time,runtime from test_db.test_run_data'" after_script: - "sudo mysql -e 'DROP DATABASE test_db;'"