import os
import sys
import time
import random
import string
import logging
from junit_xml import TestSuite, TestCase # supports more generic conversion than unittest-xml-reporting
from SeleniumTest import SeleniumTest # separate the low level driver details
class IntegrationTests( object ):
def __init__( self, fqdn, selenium_wrapper ):
self.selenium_wrapper = selenium_wrapper
self.fqdn = fqdn
self.base_url = 'https://' + self.fqdn
self.group_name = str( int( time.time() ) )
self.users = list() # list of tuples (email, user name)
self.admin_email = 'admin-' + self.group_name + '@' + self.fqdn # must be unique
self.admin_password = 'mypassword'
self.emoticon_file_name = 'shelby-emoticon.png'
def test_sign_up( self ):
logging.debug( 'DEBUG: creating account: ' + self.group_name ) # must be unique
logging.debug( 'DEBUG: creating first user: ' + self.admin_email + ' with password: ' + self.admin_password )
self.selenium_wrapper.sign_up( self.base_url, self.group_name, email=self.admin_email, password=self.admin_password )
self.selenium_wrapper.assert_name_is_present( 'email[0]' )
self.selenium_wrapper.assert_name_is_present( 'name[0]' )
self.selenium_wrapper.assert_id_is_present( 'invite_link' )
self.selenium_wrapper.assert_link_text_is_present( 'Skip this step' )
self.selenium_wrapper.assert_id_is_present( 'next' )
self.users.append( (self.admin_email, 'admin user') )
def test_sign_in_admin( self ):
# Assumes account and user are created
self.selenium_wrapper.sign_out( self.base_url )
self.selenium_wrapper.sign_in( self.base_url, self.admin_email, self.admin_password )
self.selenium_wrapper.assert_is_equal( self.base_url + '/home' , self.selenium_wrapper.show_current_url() )
self.selenium_wrapper.assert_link_text_is_present( 'Launch the web app' )
self.selenium_wrapper.assert_css_selector_is_present( 'a.admin > span' ) # admin tab == privileges
def test_add_user( self ):
# Assumes account and user are created
self.selenium_wrapper.sign_out( self.base_url )
self.selenium_wrapper.sign_in( self.base_url, self.admin_email, self.admin_password )
self.selenium_wrapper.assert_css_selector_is_present( 'a.admin > span' ) # admin tab == privileges
self.selenium_wrapper.find_by_css_selector( 'a.admin > span' ).click( )
self.selenium_wrapper.assert_is_equal( self.base_url + '/admin', self.selenium_wrapper.show_current_url() )
self.selenium_wrapper.assert_link_text_is_present( 'Users' )
logging.debug( 'DEBUG: listing users, asserting the admin is present' )
self.selenium_wrapper.find_by_link_text( 'Users' ).click()
self.selenium_wrapper.assert_is_equal( self.base_url + '/admin/users', self.selenium_wrapper.show_current_url() )
self.selenium_wrapper.assert_css_selector_is_present( 'span[title="' + self.admin_email + '"]' )
new_user_lastname = str( int( time.time( ) ) )
new_user_name = 'user ' + new_user_lastname
new_user_email = new_user_lastname + '@' + self.fqdn
logging.debug( 'DEBUG: adding a user: ' + new_user_name + ' ' + new_user_email )
self.selenium_wrapper.assert_is_equal( '+ Add user', self.selenium_wrapper.find_by_css_selector( 'input.silver' ).get_attribute( 'value' ) )
self.selenium_wrapper.find_by_css_selector( 'input.silver' ).click()
self.selenium_wrapper.assert_is_equal( self.base_url + '/admin/user', self.selenium_wrapper.show_current_url() )
self.selenium_wrapper.add_user( new_user_name, new_user_email )
self.selenium_wrapper.assert_is_equal( 'Added user ' + new_user_name + ' and sent them an email with activation instructions.',
self.selenium_wrapper.find_by_css_selector( 'p.flash' ).text )
# WARNING: if the p.flash sent activation message does not appear check that cookies are cleared correctly
logging.debug( 'DEBUG: listing users, asserting the new user {} is present'.format( new_user_email ) )
self.selenium_wrapper.get_url( self.base_url + '/admin/users' )
self.selenium_wrapper.assert_is_equal( self.base_url + '/admin/users', self.selenium_wrapper.show_current_url() )
self.selenium_wrapper.assert_css_selector_is_present( 'span[title="' + new_user_email + '"]' )
self.selenium_wrapper.assert_link_text_is_present( new_user_name )
self.users.append( (new_user_email, new_user_name) )
def test_delete_user( self ):
# Assumes account and user are created
if len( self.users ) < 2:
raise AssertionError( 'ERROR: must have at least 2 users in order to delete a user' )
self.selenium_wrapper.sign_out( self.base_url )
self.selenium_wrapper.sign_in( self.base_url, self.admin_email, self.admin_password )
self.selenium_wrapper.get_url( self.base_url + '/admin/users' )
self.selenium_wrapper.assert_is_equal( self.base_url + '/admin/users', self.selenium_wrapper.show_current_url() )
target_user_email = self.users[1][0]
target_user_name = self.users[1][1]
logging.debug( 'DEBUG: delete user, first click on and show user profile for {} {}'.format( target_user_name, target_user_email ) )
self.selenium_wrapper.delete_user( target_user_name )
flash_text = self.selenium_wrapper.find_by_css_selector( 'p.flash' ).text
logging.debug( 'DEBUG: found text: {}'.format( flash_text ) )
self.selenium_wrapper.assert_is_equal( flash_text, "User " + target_user_name + " deleted.", )
def test_add_emoticon( self ):
# Assumes account and user are created, signed in as admin
emoticon_shortcut_text = ''.join( random.choice( string.ascii_lowercase ) for a in range(3) ) # random 3 letters
current_file_path = os.path.realpath( __file__ )
current_directory_path = os.path.dirname( current_file_path )
emoticon_file_path = os.path.join( current_directory_path, self.emoticon_file_name )
if not os.path.isfile( emoticon_file_path ):
raise AssertionError( "ERROR {} does not exist".format( emoticon_file_path ) )
logging.debug( 'DEBUG: navigating to emoticon menu' )
self.selenium_wrapper.find_by_css_selector( 'a.admin > span' ).click( )
self.selenium_wrapper.find_by_link_text( 'Emoticons' ).click( )
css_text = self.selenium_wrapper.find_by_css_selector( 'h3.inner_box_header' ).text
self.selenium_wrapper.assert_is_equal( 'Add new emoticon' , css_text )
logging.debug( 'DEBUG: filling in form with {} and {}'.format( emoticon_shortcut_text, emoticon_file_path ) )
self.selenium_wrapper.add_emoticon( emoticon_shortcut_text, emoticon_file_path )
logging.debug( 'DEBUG: asserting emoticon is uploaded' )
flash_text = self.selenium_wrapper.find_by_css_selector( 'p.flash' ).text
self.selenium_wrapper.assert_is_equal( flash_text, 'Successfully uploaded emoticon' )
if __name__ == '__main__':
if len( sys.argv ) < 2:
print "usage: python {} server.com [/directory-with-binary/browserbinary] [9134]".format( sys.argv[0] )
sys.exit( 1 )
logging_level = logging.DEBUG
logging_output_filename = 'selenium-integration-test.log'
logging_output = os.path.join( os.path.normpath( '/tmp' ) , logging_output_filename )
logging.basicConfig(
name = 'seleniumIntegration' ,
level = logging_level ,
format = '%(asctime)s %(levelname)s %(message)s',
filename = logging_output,
filemode = 'w' )
fqdn_param = sys.argv[1] # server.com
browser_binary = None # Firefox default
port = None
if len( sys.argv ) == 3: # Firefox with specified binary path
browser_binary = sys.argv[2]
elif len( sys.argv ) > 3:
browser_binary = sys.argv[2]
port = int( sys.argv[3] )
if port:
if not SeleniumTest.is_valid_connection( 'localhost', port ):
logging.error( "ERROR: unable to connect to localhost on port {}".format( port ) )
sys.exit( 1 )
selenium_wrapper_param = SeleniumTest( executable_path=browser_binary, port=port )
integration_tests = IntegrationTests( fqdn_param, selenium_wrapper_param )
test_case_names = [ 'test_sign_up', 'test_sign_in_admin', 'test_add_user', 'test_delete_user', 'test_add_emoticon' ]
test_case_results = list()
for test_name in test_case_names:
test_error = None
if hasattr( integration_tests, test_name ):
method_to_call = getattr( integration_tests, test_name )
starttime = time.time()
try:
method_to_call()
except AssertionError as error:
logging.debug( "Assertion ERROR {}".format( error ) )
test_error = error
elapsed_time = time.time() - starttime
result = TestCase( name=test_name, elapsed_sec=elapsed_time )
if test_error:
result.add_failure_info( 'ERROR: {}'.format( test_error ) )
else:
result = TestCase( name=test_name )
result.add_failure_info( 'ERROR: test {} not implemented'.format( test_name ) )
test_case_results.append( result )
test_suite = list()
test_suite.append( TestSuite( "Integration Test", test_case_results ) )
print( TestSuite.to_xml_string( test_suite ) ) # TODO: to file?
selenium_wrapper_param.quit()