Commit cdaf852c authored by Jérome Perrin's avatar Jérome Perrin

wip ERP5 seleniumserver

parent 69589a28
...@@ -34,6 +34,8 @@ import time ...@@ -34,6 +34,8 @@ import time
import re import re
import subprocess import subprocess
import shutil import shutil
import json
import tempfile
import transaction import transaction
import logging import logging
from ZPublisher.HTTPResponse import HTTPResponse from ZPublisher.HTTPResponse import HTTPResponse
...@@ -42,10 +44,14 @@ from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase ...@@ -42,10 +44,14 @@ from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.Utils import stopProcess, PR_SET_PDEATHSIG from Products.ERP5Type.Utils import stopProcess, PR_SET_PDEATHSIG
from lxml import etree from lxml import etree
from lxml.html import builder as E from lxml.html import builder as E
import certifi
import urllib3
from selenium import webdriver from selenium import webdriver
from selenium.webdriver.common.by import By from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.remote.remote_connection import RemoteConnection
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -162,54 +168,88 @@ class FunctionalTestRunner: ...@@ -162,54 +168,88 @@ class FunctionalTestRunner:
# There is no test that can take more than 6 hours # There is no test that can take more than 6 hours
timeout = 6.0 * 3600 timeout = 6.0 * 3600
def __init__(self, host, port, portal, run_only=''): def __init__(self, host, port, testcase):
self.instance_home = os.environ['INSTANCE_HOME'] self.instance_home = os.environ['INSTANCE_HOME']
# Such information should be automatically loaded # Such information should be automatically loaded
self.user = 'ERP5TypeTestCase' self.user = 'ERP5TypeTestCase'
self.password = '' self.password = ''
self.run_only = run_only self.testcase = testcase
profile_dir = os.path.join(self.instance_home, 'profile') profile_dir = os.path.join(self.instance_home, 'profile')
self.portal = portal
def getStatus(self): def getStatus(self):
transaction.begin() transaction.begin()
return self.portal.portal_tests.TestTool_getResults(self.run_only) return self.testcase.portal.portal_tests.TestTool_getResults(self.testcase.run_only)
def _getTestBaseURL(self): def _getTestBaseURL(self):
# Access the https proxy in front of runUnitTest's zserver # Access the https proxy in front of runUnitTest's zserver
base_url = os.getenv('zserver_frontend_url') base_url = os.getenv('zserver_frontend_url')
if base_url: if base_url:
return '%s%s' % (base_url, self.portal.getId()) return '%s%s' % (base_url, self.testcase.portal.getId())
return self.portal.portal_url() return self.testcase.portal_url()
def _getTestURL(self): def _getTestURL(self):
return ZELENIUM_BASE_URL % ( return ZELENIUM_BASE_URL % (
self._getTestBaseURL(), self._getTestBaseURL(),
self.run_only, self.testcase.run_only,
) )
def test(self, debug=0): def test(self, debug=0):
xvfb = Xvfb(self.instance_home) xvfb = None
use_local_firefox = True
selenium_test_runner_configuration = {}
test_runner_configuration_file = os.environ.get('ERP5_TESTRUNNER_CONFIGURATION')
if test_runner_configuration_file and os.path.exists(test_runner_configuration_file):
with open(test_runner_configuration_file) as f:
test_runner_configuration = json.load(f)
selenium_test_runner_configuration = test_runner_configuration.get('selenium', {})
use_local_firefox = selenium_test_runner_configuration.get('server-url') is None
try: try:
if not (debug and os.getenv('DISPLAY')): if use_local_firefox:
logger.debug("You can set 'erp5_debug_mode' environment variable to 1 to use your existing display instead of Xvfb.") xvfb = Xvfb(self.instance_home)
xvfb.run() if not (debug and os.getenv('DISPLAY')):
capabilities = webdriver.common.desired_capabilities \ logger.debug("You can set 'erp5_debug_mode' environment variable to 1 to use your existing display instead of Xvfb.")
.DesiredCapabilities.FIREFOX.copy() xvfb.run()
capabilities['marionette'] = True capabilities = webdriver.common.desired_capabilities \
# Zope is accessed through apache with a certificate not trusted by firefox .DesiredCapabilities.FIREFOX.copy()
capabilities['acceptInsecureCerts'] = True capabilities['marionette'] = True
# Service workers are disabled on Firefox 52 ESR: # Zope is accessed through apache with a certificate not trusted by firefox
# https://bugzilla.mozilla.org/show_bug.cgi?id=1338144 capabilities['acceptInsecureCerts'] = True
options = webdriver.FirefoxOptions() # Service workers are disabled on Firefox 52 ESR:
options.set_preference('dom.serviceWorkers.enabled', True) # https://bugzilla.mozilla.org/show_bug.cgi?id=1338144
kw = dict(capabilities=capabilities, options=options) options = webdriver.FirefoxOptions()
firefox_bin = os.environ.get('firefox_bin') options.set_preference('dom.serviceWorkers.enabled', True)
if firefox_bin: kw = dict(capabilities=capabilities, options=options)
geckodriver = os.path.join(os.path.dirname(firefox_bin), 'geckodriver') firefox_bin = os.environ.get('firefox_bin')
kw.update(firefox_binary=firefox_bin, executable_path=geckodriver) if firefox_bin:
browser = webdriver.Firefox(**kw) geckodriver = os.path.join(os.path.dirname(firefox_bin), 'geckodriver')
kw.update(firefox_binary=firefox_bin, executable_path=geckodriver)
browser = webdriver.Firefox(**kw)
else:
executor = RemoteConnection(
selenium_test_runner_configuration['server-url'],
keep_alive=True)
cert_reqs = 'CERT_REQUIRED'
ca_certs = certifi.where()
if not selenium_test_runner_configuration.get('verify-server-certificate', True):
cert_reqs = 'CERT_NONE'
ca_certs = None
# TODO caucase
if selenium_test_runner_configuration.get('server-ca-certificate'):
ca_certs_tempfile = tempfile.NamedTemporaryFile(suffix="-cacerts.pem", mode="w", delete=False)
ca_certs = ca_certs_tempfile.name
self.testcase.addCleanup(os.unlink, ca_certs_tempfile)
with open(ca_certs, 'w') as f:
f.write(selenium_test_runner_configuration['server-ca-certificate'])
executor._conn = urllib3.PoolManager(cert_reqs=cert_reqs, ca_certs=ca_certs)
browser = webdriver.Remote(
command_executor=executor,
desired_capabilities=selenium_test_runner_configuration['desired-capabilities'],
)
start_time = time.time() start_time = time.time()
logger.info("Running with browser: %s", browser) logger.info("Running with browser: %s", browser)
logger.info("Reported user agent: %s", browser.execute_script("return navigator.userAgent")) logger.info("Reported user agent: %s", browser.execute_script("return navigator.userAgent"))
...@@ -262,7 +302,8 @@ class FunctionalTestRunner: ...@@ -262,7 +302,8 @@ class FunctionalTestRunner:
) )
browser.quit() browser.quit()
finally: finally:
xvfb.quit() if xvfb is not None:
xvfb.quit()
return iframe return iframe
def processResult(self, iframe): def processResult(self, iframe):
...@@ -305,6 +346,7 @@ class FunctionalTestRunner: ...@@ -305,6 +346,7 @@ class FunctionalTestRunner:
return detail, sucess_amount, failure_amount, expected_failure_amount, \ return detail, sucess_amount, failure_amount, expected_failure_amount, \
error_title_list error_title_list
class ERP5TypeFunctionalTestCase(ERP5TypeTestCase): class ERP5TypeFunctionalTestCase(ERP5TypeTestCase):
run_only = "" run_only = ""
foreground = 0 foreground = 0
...@@ -325,8 +367,7 @@ class ERP5TypeFunctionalTestCase(ERP5TypeTestCase): ...@@ -325,8 +367,7 @@ class ERP5TypeFunctionalTestCase(ERP5TypeTestCase):
self.portal.portal_tests.TestTool_cleanUpTestResults(self.run_only or None) self.portal.portal_tests.TestTool_cleanUpTestResults(self.run_only or None)
self.tic() self.tic()
host, port = self.startZServer() host, port = self.startZServer()
self.runner = FunctionalTestRunner(host, port, self.runner = FunctionalTestRunner(host, port, self)
self.portal, self.run_only)
def setSystemPreference(self): def setSystemPreference(self):
self.portal.Zuite_setPreference( self.portal.Zuite_setPreference(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment