This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
glasnost/tests/WebTests.py

455 lines
16 KiB
Python
Raw Blame History

# -*- coding: iso-8859-15 -*-
import httpsession
import re
import sgmllib
import sys
import time
import unittest
glasnostPythonDir = '/usr/local/lib/glasnost-tests'
sys.path.insert(0, glasnostPythonDir)
from GlasnostTestCase import MinimalTestCase, OneUserTestCase
httpsession.PostRequest.follow_redirects = 1
# The dict function is new in Python 2.2.
try:
dict
except NameError:
def dict(sequence):
mapping = {}
for key, value in sequence:
mapping[key] = value
return mapping
class Form:
def __init__(self, action = '', method = '', formId = '', **keywords):
self.actionUrl = action
self.method = method
self.id = formId
self.values = {}
self.buttons = []
self.selects = {}
def set(self, k, v):
if not self.values.has_key(k):
raise 'unknown key'
self.values[k] = v
def setOption(self, k, v):
if not k in self.selects.keys():
raise 'unknown key'
self.values[k] = self.selects[k][v]
def getKeywords(self, buttonClicked = None):
if not buttonClicked:
buttonClicked = self.buttons[0]
else:
buttonClicked = [x for x in self.buttons if x[0] == buttonClicked
or x[1] == buttonClicked][0]
self.values[buttonClicked[0]] = buttonClicked[1]
return self.values
class ParserForForms(sgmllib.SGMLParser):
inTextArea = None
inOption = None
def __init__(self, session, body):
sgmllib.SGMLParser.__init__(self)
self.forms = []
self.currentForm = None
self.session = session
self.feed(body)
def start_form(self, attrs):
attrs = dict(attrs) # require python >= 2.2
self.currentForm = Form(**attrs)
self.currentForm.session = self.session
def end_form(self):
if not self.currentForm:
raise 'end form while it never opened!'
self.forms.append(self.currentForm)
self.currentForm = None
def start_input(self, attrs):
attrs = dict(attrs)
if not self.currentForm:
return
if not attrs.has_key('name'):
attrs['name'] = 'undefined'
if attrs.has_key('type') and attrs['type'] == 'submit':
self.currentForm.buttons.append( (attrs['name'], attrs['value']) )
return
if attrs.has_key('type') and attrs['type'] == 'checkbox':
if attrs.has_key('checked') and attrs['checked'] == 'checked':
self.currentForm.values[attrs['name']] = 'checked'
return
self.currentForm.values[attrs['name']] = None
if attrs.has_key('value'):
self.currentForm.values[attrs['name']] = attrs['value']
def start_select(self, attrs):
attrs = dict(attrs)
if not self.currentForm:
return
self.currentForm.values[attrs['name']] = None
self.inSelect = attrs['name']
self.currentForm.selects[self.inSelect] = {}
def end_select(self):
self.inSelect = None
def start_textarea(self, attrs):
attrs = dict(attrs)
if not self.currentForm:
return
if not attrs.has_key('name'):
return
self.currentForm.values[attrs['name']] = None
self.inTextArea = attrs['name']
def end_textarea(self):
self.inTextArea = None
def handle_data(self, data):
if self.inTextArea is not None:
self.currentForm.values[self.inTextArea] = data
elif self.inOption is not None:
select = self.currentForm.selects[self.inSelect]
current = ''
if select.has_key(self.inOption):
current = select[self.inOption]
select[self.inOption] = current + ' ' + data.strip()
def start_option(self, attrs):
if self.inSelect is None:
return
attrs = dict(attrs)
if attrs.has_key('selected') or \
not self.currentForm.values[self.inSelect]:
self.currentForm.values[self.inSelect] = attrs['value']
self.inOption = attrs['value']
def end_option(self):
select = self.currentForm.selects[self.inSelect]
select[self.inOption] = select[self.inOption].strip()
select[ select[self.inOption] ] = self.inOption
del select[self.inOption]
self.inOption = None
class ParserForLinks(sgmllib.SGMLParser):
def __init__(self, body):
sgmllib.SGMLParser.__init__(self)
self.links = []
self.inLink = 0
self.feed(body)
def start_a(self, attrs):
attrs = dict(attrs) # require python >= 2.2
if not attrs.has_key('href'):
return
self.inLink = 1
self.links.append(attrs)
self.links[-1]['data'] = ''
def handle_data(self, data):
if not self.inLink:
return
self.links[-1]['data'] += data
def end_a(self):
try:
self.links[-1]['data'] = self.links[-1]['data'].strip()
except IndexError:
# when first link has not content
pass
self.inLink = 0
class WebTestCase(MinimalTestCase, httpsession.HTTPSession):
pageContent = None
path = None
replyCode = None
links = None
forms = None
def setUp(self):
MinimalTestCase.setUp(self)
httpsession.HTTPSession.__init__(self, use_cookies = 1)
self.add_header('User-Agent', 'Glasnost/0.0 (WebTesting)')
self.add_header('Accept-Language', 'fr')
self.setHost('localhost:9000')
def setHost(self, host):
self.protocol = 'http'
self.hostName = host
self.add_header('Host', self.hostName)
def get(self, path):
if path.startswith('http'):
url = path
else:
url = '%s://%s%s' % (self.protocol, self.hostName, path)
url = url.replace('&', '&') # TODO: everything
req = httpsession.HTTPSession.get(self, url)
self.handle_req(req)
def getLinkByLabel(self, label):
try:
return [x for x in self.links if x['data'] == label][0]['href']
except IndexError:
self.fail('No link with that label')
def post(self, path, keywords):
if path.startswith('http'):
url = path
else:
url = '%s://%s%s' % (self.protocol, self.hostName, path)
url = url.replace('&', '&') # TODO: everything
req = httpsession.HTTPSession.post(self, url)
for k, v in keywords.items():
req.add_param(k, v)
self.handle_req(req)
def handle_req(self, req):
req.getreply()
self.replyCode = int(req.replycode)
self.pageContent = req.getfile().read()
self.links = ParserForLinks(self.pageContent).links
self.forms = ParserForForms(self, self.pageContent).forms
self.path = req.path
class BasicTestCase(WebTestCase):
def test01_getHomepage(self):
'''Get homepage'''
self.get('/')
self.failUnless(self.replyCode == 200)
self.failUnless(self.pageContent.find('<h1>Home</h1>') > -1)
self.failUnless(self.pageContent.find('Login') > -1)
def test02_getVirtualHostsPage(self):
'''Get virtual hosts page'''
self.get('/virtualhosts')
self.failUnless(self.replyCode == 200)
self.failUnless(self.pageContent.find(
'<h1>Virtual Hosts</h1>') > -1)
def test03_getTheVirtualHostPage(self):
'''Get the virtual host page'''
self.get('/virtualhosts')
try:
link = [x for x in self.links if
x['data'] == 'Glasnost' and
re.match('/virtualhosts/\d+', x['href'])] [0]
except IndexError:
self.fail('No link to a virtual host object')
self.get(link['href'])
self.failUnless(self.replyCode == 200)
self.failUnless(self.pageContent.find(
'<h1>Virtual Host - Glasnost</h1>') > -1)
def test04_editTheVirtualHost(self):
'''Change the language of the virtual host'''
self.get('/virtualhosts')
link = [x for x in self.links if
x['data'] == 'Glasnost' and
re.match('/virtualhosts/\d+', x['href'])] [0]
self.get(link['href'])
self.get( self.getLinkByLabel('Edit') )
self.failUnless(self.replyCode == 200)
self.failUnless(self.pageContent.find(
'<h1>Editing Virtual Host - Glasnost</h1>') > -1)
try:
form = [x for x in self.forms if
x.actionUrl == '/virtualhosts/submit'][0]
except IndexError:
self.fail('No form on this page')
form.setOption('language', 'French')
self.post(form.actionUrl, form.getKeywords(buttonClicked = 'Modify'))
self.failUnless(self.replyCode == 200)
self.failUnless(self.pageContent.find(
'<h1>H<>te virtuel - Glasnost</h1>') > -1)
self.get( self.getLinkByLabel('Supprimer') )
self.failUnless(
re.match('/virtualhosts/\d+/confirmDelete', self.path) )
self.get( self.getLinkByLabel('Supprimer') )
def test05_applyEveryTemplates(self):
'''Apply every templates'''
self.get('/virtualhosts')
link = [x for x in self.links if
x['data'] == 'Glasnost' and
re.match('/virtualhosts/\d+', x['href'])] [0]
self.get(link['href'])
previousPageContent = self.pageContent
self.get( self.getLinkByLabel('Edit') )
form = [x for x in self.forms if
x.actionUrl == '/virtualhosts/submit'][0]
templateNames = form.selects['templateDirectoryName'].keys()
for templateName in templateNames + ['Glasnost 2']:
self.get(link['href'])
self.get( self.getLinkByLabel('Edit') )
form = [x for x in self.forms if
x.actionUrl == '/virtualhosts/submit'][0]
form.setOption('templateDirectoryName', templateName)
self.post(form.actionUrl, form.getKeywords(buttonClicked = 'Modify'))
self.failUnless(self.replyCode == 200)
self.failUnless(self.path == link['href'])
self.failUnless(self.pageContent.find(
'<h1>Virtual Host - Glasnost</h1>') > -1)
self.failUnless(self.pageContent != previousPageContent)
previousPageContent = self.pageContent
class AccountManipulationTestCase(WebTestCase):
def test01_buttonPresence(self):
'''Look for "New Account" button'''
self.get('/')
self.failUnless(self.replyCode == 200)
self.failUnless(self.pageContent.find('New Account') > -1)
def test02_emptyForm(self):
'''Submit empty *new account* form'''
self.get('/')
self.get( self.getLinkByLabel('New Account') )
form = [x for x in self.forms if
x.actionUrl.endswith('/newAccountSubmit')][0]
self.post(form.actionUrl, form.getKeywords(buttonClicked = 'Create'))
self.failUnless(self.replyCode == 200)
self.failUnless(self.pageContent.find('Missing value!') > -1)
def test03_userButNotUsername(self):
'''Submit *new account* form filled except the username field'''
self.get('/')
self.get( self.getLinkByLabel('New Account') )
form = [x for x in self.forms if
x.actionUrl.endswith('/newAccountSubmit')][0]
form.set('userCard_firstName', 'Test')
form.set('userCard_lastName', 'User')
form.set('userCard_email', 'test@example.com')
self.post(form.actionUrl, form.getKeywords(buttonClicked = 'Create'))
self.failUnless(self.replyCode == 200)
self.failUnless(self.pageContent.find('Missing value!') > -1)
def test04_userNameButNotUser(self):
'''Submit *new account* form with just the username field'''
self.get('/')
self.get( self.getLinkByLabel('New Account') )
form = [x for x in self.forms if
x.actionUrl.endswith('/newAccountSubmit')][0]
form.set('login', 'test')
self.post(form.actionUrl, form.getKeywords(buttonClicked = 'Create'))
self.failUnless(self.replyCode == 200)
def test05_fullForm(self):
'''Submit a correctly filled *new account* form'''
self.get('/')
self.get( self.getLinkByLabel('New Account') )
form = [x for x in self.forms if
x.actionUrl.endswith('/newAccountSubmit')][0]
form.set('userCard_firstName', 'Test')
form.set('userCard_lastName', 'User')
form.set('userCard_email', 'test@example.com')
form.set('login', 'test')
self.post(form.actionUrl, form.getKeywords(buttonClicked = 'Create'))
self.failUnless(self.replyCode == 200)
self.failUnless(
re.match('/people/\d+$', self.path))
def test06_removeUserAndAccount(self):
'''Remove the account just created'''
self.get('/authentication')
form = [x for x in self.forms if
x.actionUrl.endswith('/delete')][0]
self.post(form.actionUrl, form.getKeywords(buttonClicked = 'OK'))
self.failUnless(self.replyCode == 200)
self.failUnless(self.pageContent.find('<h1>Delete Account</h1>') > -1)
self.get( self.getLinkByLabel('Remove Both') )
self.failUnless(self.pageContent.find('<h1>Success</h1>') > -1)
self.get( self.getLinkByLabel('OK') )
self.failUnless(self.path == '/authentication')
self.failUnless(self.pageContent.find('Delete Account') == -1)
self.get('/people')
self.failUnless(self.pageContent.find('>Test User</a>') == -1)
class LoginTestCase(WebTestCase, OneUserTestCase):
def setUp(self):
OneUserTestCase.setUp(self)
WebTestCase.setUp(self)
self.get('/')
self.get( self.getLinkByLabel('Login') )
self.failUnless(self.replyCode == 200)
self.loginForm = [x for x in self.forms if
x.actionUrl.endswith('/loginSubmit')][0]
def tearDown(self):
OneUserTestCase.tearDown(self)
WebTestCase.tearDown(self)
def test01_falseUserName(self):
'''Login with false username'''
self.loginForm.set('login', 'blah')
self.post(self.loginForm.actionUrl,
self.loginForm.getKeywords(buttonClicked = 'Login'))
self.failUnless(self.replyCode == 200)
self.failUnless(self.pageContent.find('Error!') > -1)
def test02_realUserNameNoPassword(self):
'''Login with real username but no password'''
self.loginForm.set('login', 'test-user')
self.post(self.loginForm.actionUrl,
self.loginForm.getKeywords(buttonClicked = 'Login'))
self.failUnless(self.replyCode == 200)
self.failUnless(self.pageContent.find('Error!') > -1)
def test03_realUserNameFalsePassword(self):
'''Login with real username but false password'''
self.loginForm.set('login', 'test-user')
self.loginForm.set('password', 'blah')
self.post(self.loginForm.actionUrl,
self.loginForm.getKeywords(buttonClicked = 'Login'))
self.failUnless(self.replyCode == 200)
self.failUnless(self.pageContent.find('Error!') > -1)
def test04_realUserNameAndPassword(self):
'''Login with real username and real password'''
self.loginForm.set('login', 'test-user')
self.loginForm.set('password', 'test-user')
self.post(self.loginForm.actionUrl,
self.loginForm.getKeywords(buttonClicked = 'Login'))
self.failUnless(self.replyCode == 200)
self.failUnless(self.path == '/')
self.get('/authentication')
self.failUnless(self.pageContent.find('You are logged') > -1)
self.get( self.getLinkByLabel('Exit') )
self.get('/authentication')
self.failUnless(self.pageContent.find('You are not logged') > -1)
suite1 = unittest.makeSuite(BasicTestCase, 'test')
suite2 = unittest.makeSuite(AccountManipulationTestCase, 'test')
suite3 = unittest.makeSuite(LoginTestCase, 'test')
allTests = unittest.TestSuite((suite1, suite2))
if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(suite3)