Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
7b37cb7
Add MySQL to the deploy script
mdmintz Apr 10, 2018
dbf1822
Update MySQL deploy script
mdmintz Apr 10, 2018
2048c61
Update the mysql deploy script
mdmintz Apr 10, 2018
d8fdced
Update the mysql deploy script
mdmintz Apr 10, 2018
e1da445
Update the mysql deploy script
mdmintz Apr 10, 2018
aa530a8
Update the mysql deploy script
mdmintz Apr 10, 2018
865da0d
Update the deploy script
mdmintz Apr 10, 2018
550a540
Update the mysql deploy script
mdmintz Apr 10, 2018
d2c73cf
Update the mysql deploy script
mdmintz Apr 11, 2018
6f65c00
Update the mysql deploy script
mdmintz Apr 11, 2018
c9722fe
Update the MySQL deploy script
mdmintz Apr 11, 2018
5651699
Update the MySQL deploy script
mdmintz Apr 11, 2018
5b16954
Update the MySQL deploy script
mdmintz Apr 11, 2018
487cd39
Update the MySQL deploy script
mdmintz Apr 11, 2018
da71335
Update the MySQL deploy script
mdmintz Apr 12, 2018
23126f4
Update the MySQL deploy script
mdmintz Apr 12, 2018
8742b25
Update the MySQL deploy script
mdmintz Apr 12, 2018
5d0190f
Update the MySQL deploy script
mdmintz Apr 12, 2018
07f9bf0
Fix import for Python 3
mdmintz Apr 12, 2018
dd8d7ec
Add mysqlclient to requirements
mdmintz Apr 12, 2018
5f3e42e
Slow down the GitHub test to prevent triggering a call limit
mdmintz Apr 12, 2018
0168de4
Update the MySQL deploy script
mdmintz Apr 12, 2018
2625390
Update the MySQL deploy script
mdmintz Apr 12, 2018
0861ed0
Add a comment about changing MySQL passwords in the deploy script
mdmintz Apr 12, 2018
923abea
Update the description
mdmintz Apr 12, 2018
518594e
Improve the MySQL DB test storage feature.
mdmintz Apr 12, 2018
91953cd
Update the ReadMe
mdmintz Apr 12, 2018
b810287
Update documentation.
mdmintz Apr 12, 2018
2b8e5d5
Update the MySQL deploy script
mdmintz Apr 12, 2018
82e6219
Rename the script that creates MySQL DB tables
mdmintz Apr 12, 2018
6a62c40
Update the Google Cloud ReadMe with the updated MySQL script
mdmintz Apr 12, 2018
8ead18e
Fix a few MySQL DB naming issues
mdmintz Apr 12, 2018
8b59ce0
See if mysqlclient includes MySQL-python for the deploy script
mdmintz Apr 13, 2018
bbf3cda
Update the Google Cloud ReadMe
mdmintz Apr 13, 2018
9c94352
Version 1.9.0
mdmintz Apr 13, 2018
d389df9
Update the deploy script
mdmintz Apr 13, 2018
7ff6baf
Update the deploy script
mdmintz Apr 13, 2018
14bd125
Update naming of db methods
mdmintz Apr 14, 2018
8798dba
If you're overriding SeleniumBase's BaseCase setUp() method, you'll k…
mdmintz Apr 16, 2018
ee7306a
test_db method naming
mdmintz Apr 17, 2018
d44ec1d
Renaming a DB method file
mdmintz Apr 17, 2018
a776271
Rename a test_db table for clarity
mdmintz Apr 17, 2018
34a2078
Update naming in ReadMe
mdmintz Apr 17, 2018
476eaa9
Removing some older test_db functionality until it's ready for prime …
mdmintz Apr 17, 2018
3aceede
Update the ReadMe
mdmintz Apr 17, 2018
824f72c
Don't trigger GitHub's automation-detection system
mdmintz Apr 17, 2018
32289fc
Update the deploy script
mdmintz Apr 17, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,33 @@ language: python
sudo: false
python:
- "2.7"
- "3.6"
addons:
firefox: latest
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/create_db_tables.sql"
- "mysqladmin -u root password test"
# - "mysqladmin -u root -p'old_password' password new_password"
- "sudo service mysql restart"
install:
- "pip install --upgrade pip"
- "pip install -r requirements.txt --upgrade"
- "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"
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/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=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;'"
notifications:
email: false
48 changes: 2 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

## Automated Web-UI testing reimagined.
## Automated testing made fast, easy, and reliable.

<img src="https://cdn2.hubspot.net/hubfs/100006/images/laptop_logo.png" title="SeleniumBase" height="160">

Expand Down Expand Up @@ -610,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)
Expand All @@ -622,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, theId, theValue, theUrl):
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})
```

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.

```python
import logging
from seleniumbase.core.mysql import DatabaseManager

def get_delayed_test_data(self, testcase_address, 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})
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})
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.


### ![http://seleniumbase.com](https://cdn2.hubspot.net/hubfs/100006/images/super_logo_tiny.png "SeleniumBase") Wrap-Up

**Congratulations** on learning how to use **SeleniumBase**!
Expand Down
17 changes: 13 additions & 4 deletions examples/github_test.py
Original file line number Diff line number Diff line change
@@ -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(1)
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")
11 changes: 3 additions & 8 deletions integrations/google_cloud/ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,18 +168,13 @@ 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
#### 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":

Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 .
30 changes: 30 additions & 0 deletions seleniumbase/core/create_db_tables.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Creates test_db tables for using SeleniumBase with MySQL

# test_run_data table
# -----------------------------------
CREATE TABLE `test_run_data` (
`guid` varchar(64) NOT NULL DEFAULT '',
`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;

# test_execution table
# -----------------------------------
CREATE TABLE `test_execution` (
`guid` varchar(64) NOT NULL DEFAULT '',
`total_execution_time` int(11),
`username` varchar(255) DEFAULT NULL,
`execution_start` bigint(20) DEFAULT '0',
PRIMARY KEY (`guid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
22 changes: 10 additions & 12 deletions seleniumbase/core/mysql.py
Original file line number Diff line number Diff line change
@@ -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 database functions for easy use.
It connects to the testcase database.
This class wraps MySQL database methods for easy use.
"""

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
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:
Expand All @@ -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 then closes up 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 up 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()
Expand Down
3 changes: 1 addition & 2 deletions seleniumbase/core/mysql_conf.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading