wcs/tests/robot/WcsRobotFrameworkLibrary.py

128 lines
4.7 KiB
Python

# w.c.s. - web application for online forms
# Copyright (C) 2005-2013 Entr'ouvert
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
import os
import time
import urllib2
import subprocess
import shutil
import signal
import sys
WCS_SRCDIR = '../../'
WCSCTL = '../../wcsctl.py'
WCS_DATA_DIR = os.path.abspath('../../data')
from robot.libraries.BuiltIn import BuiltIn
from Selenium2Library.locators import ElementFinder as BaseElementFinder
from Selenium2Library import utils
class ElementFinder(BaseElementFinder):
def __init__(self):
BaseElementFinder.__init__(self)
self._strategies['qx'] = self._find_by_qx_field
def _find_by_qx_field(self, browser, criteria, tag, constraints):
xpath_value = utils.escape_xpath_value(criteria)
criterias = [
"//div[div[@class='title'][text()=%s]]/div[@class='content']/input" % xpath_value,
"//div[div[@class='title'][text()=%s]]/div[@class='content']/select" % xpath_value,
"//div[div[@class='title'][text()=%s]]/div[@class='content']/textarea" % xpath_value,
"//div/div[@class='content']//label[text()=%s]/input[@type='checkbox']" % xpath_value]
for criteria in criterias:
if browser.find_elements_by_xpath(criteria):
return self._find_by_xpath(browser, criteria, tag, constraints)
return []
class WcsRobotFrameworkLibrary:
def __init__(self, port=10003):
self.port = port
try:
seleniumlib = BuiltIn().get_library_instance('Selenium2Library')
except RuntimeError:
# the selenium library has not yet been loaded, monkeypatch it from
# the outside
import Selenium2Library.locators.elementfinder
import Selenium2Library.keywords._element
Selenium2Library.locators.elementfinder.ElementFinder = ElementFinder
Selenium2Library.keywords._element.ElementFinder = ElementFinder
else:
# the selenium library is already loaded, and the ElementFinder
# will therefore already have been instantiated, replace it.
seleniumlib._element_finder = ElementFinder()
def _waitforport(self, start):
while True:
if time.time() - start > 90:
raise Exception('Servers did not start in 90 seconds!!')
time.sleep(1)
try:
urllib2.urlopen('http://localhost:%s' % self.port)
except urllib2.URLError:
continue
else:
break
def start_wcs_server(self, reset=True):
if reset == 'False': reset = False
if reset and os.path.exists('/tmp/.tests'):
self.stop_wcs_server()
shutil.rmtree('/tmp/.tests')
if not os.path.exists('/tmp/.tests'):
os.mkdir('/tmp/.tests')
if not reset:
try:
urllib2.urlopen('http://localhost:%s' % self.port)
except urllib2.URLError:
pass
else:
return
wcs_command = [WCSCTL, 'start',
'--app-dir', '/tmp/.tests/',
'--data-dir', WCS_DATA_DIR,
'--port', str(self.port), '--http', '--silent']
sp = subprocess.Popen(wcs_command)
fd = open('/tmp/.tests/pid', 'w')
fd.write(str(sp.pid))
fd.close()
# Wait for the daemons to load themselves
starttime = time.time()
self._waitforport(starttime)
def stop_wcs_server(self):
if not os.path.exists('/tmp/.tests/pid'):
return
fd = open('/tmp/.tests/pid')
pid = int(fd.read())
fd.close()
try:
# valgrind seems to prefer SIGINT to SIGTERM
os.kill(pid, signal.SIGINT)
except OSError, e:
print >> sys.stderr, 'failed to kill pid %s (%s)' % (pid, e)
def reset_formdefs(self):
if os.path.exists('/tmp/.tests/localhost/formdefs'):
shutil.rmtree('/tmp/.tests/localhost/formdefs')
if os.path.exists('/tmp/.tests/localhost/formdefs-url_name'):
shutil.rmtree('/tmp/.tests/localhost/formdefs-url_name')