datatracker/ietf/utils/jstest.py
Jennifer Richards c5f86b3834 Merged in [19979] from 7.40.1.dev0
Make the js a bit less noisy and adjust the tests accordingly.
 - Legacy-Id: 19984
Note: SVN reference [19979] has been migrated to Git commit f61ddb4b60
2022-02-24 17:26:46 +00:00

125 lines
4.4 KiB
Python

# Copyright The IETF Trust 2014-2021, All Rights Reserved
# -*- coding: utf-8 -*-
import re
from django.conf import settings
from django.urls import reverse as urlreverse
from unittest import skipIf
skip_selenium = False
skip_message = ""
try:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
except ImportError as e:
skip_selenium = True
skip_message = "Skipping selenium tests: %s" % e
from ietf.utils.pipe import pipe
from ietf.utils.test_runner import IetfLiveServerTestCase
executable_name = 'chromedriver'
code, out, err = pipe('{} --version'.format(executable_name))
if code != 0:
skip_selenium = True
skip_message = "Skipping selenium tests: '{}' executable not found.".format(executable_name)
if skip_selenium:
print(" "+skip_message)
def start_web_driver():
service = Service(executable_path="chromedriver",
log_path=settings.TEST_GHOSTDRIVER_LOG_PATH)
service.start()
options = Options()
options.add_argument("headless")
options.add_argument("disable-extensions")
options.add_argument("disable-gpu") # headless needs this
options.add_argument("no-sandbox") # docker needs this
dc = DesiredCapabilities.CHROME
dc["goog:loggingPrefs"] = {"browser": "ALL"}
# For selenium 3:
return webdriver.Chrome("chromedriver", options=options, desired_capabilities=dc)
# For selenium 4:
# return webdriver.Chrome(service=service, options=options, desired_capabilities=dc)
def selenium_enabled():
"""Are Selenium tests enabled?"""
return not skip_selenium
def ifSeleniumEnabled(func):
"""Only run test if Selenium testing is enabled"""
return skipIf(skip_selenium, skip_message)(func)
class IetfSeleniumTestCase(IetfLiveServerTestCase):
login_view = 'ietf.ietfauth.views.login'
def setUp(self):
super(IetfSeleniumTestCase, self).setUp()
self.driver = start_web_driver()
self.driver.set_window_size(1024,768)
def tearDown(self):
msg = ""
for type in ["browser", "driver"]:
log = self.driver.get_log(type)
if not log:
continue
for entry in log:
line = entry["message"]
# suppress a bunch of benign/expected messages
if (
re.search(r"JQMIGRATE: Migrate is installed", line)
or re.search(r"No color for (farfut|acronym\d+):", line)
or re.search(r"Could not find parent \d+", line)
or re.search(r"/materials/.*mars.*status of 404", line)
):
continue
msg += f"{entry['level']}: {line}\n"
super(IetfSeleniumTestCase, self).tearDown()
self.driver.close()
self.maxDiff = None
self.assertEqual("", msg)
def absreverse(self,*args,**kwargs):
return '%s%s'%(self.live_server_url, urlreverse(*args, **kwargs))
def debug_snapshot(self,filename='debug_this.png'):
self.driver.execute_script("document.body.bgColor = 'white';")
self.driver.save_screenshot(filename)
def login(self, username='plain'):
url = self.absreverse(self.login_view)
password = '%s+password' % username
self.driver.get(url)
self.driver.find_element(By.NAME, 'username').send_keys(username)
self.driver.find_element(By.NAME, 'password').send_keys(password)
self.driver.find_element(By.XPATH, '//button[@type="submit"]').click()
def scroll_to_element(self, element):
"""Scroll an element into view"""
actions = ActionChains(self.driver)
actions.move_to_element(element).perform()
class presence_of_element_child_by_css_selector:
"""Wait for presence of a child of a WebElement matching a CSS selector
This is a condition class for use with WebDriverWait.
"""
def __init__(self, element, child_selector):
self.element = element
self.child_selector = child_selector
def __call__(self, driver):
child = self.element.find_element(By.CSS_SELECTOR, self.child_selector)
return child if child is not None else False