Create attractive VASL scenarios, with loads of useful information embedded to assist with game play. https://vasl-templates.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vasl-templates/vasl_templates/webapp/tests/utils.py

186 lines
6.1 KiB

""" Helper utilities. """
import os
import urllib.request
import json
import time
from PyQt5.QtWidgets import QApplication
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException
# standard templates
_STD_TEMPLATES = {
"scenario": [ "scenario", "players", "victory_conditions", "ssr" ],
"ob1": [ "ob_setup_1" ],
"ob2": [ "ob_setup_2" ],
}
# nationality-specific templates
_NAT_TEMPLATES = {
"german": [ "pf", "psk", "atmm" ],
"russian": [ "mol", "mol-p" ],
"american": [ "baz" ],
"british": [ "piat" ],
}
_webdriver = None
# ---------------------------------------------------------------------
def for_each_template( func ):
"""Test each template."""
# generate a list of all the templates we need to test
templates_to_test = set()
dname = os.path.join( os.path.split(__file__)[0], "../data/default-templates" )
for fname in os.listdir(dname):
fname,extn = os.path.splitext( fname )
if extn != ".j2":
continue
templates_to_test.add( fname )
# test the standard templates
for tab_id,template_ids in _STD_TEMPLATES.items():
select_tab( tab_id )
for template_id in template_ids:
template_id2 = "ob_setup" if template_id.startswith("ob_setup_") else template_id
func( template_id2, template_id )
if template_id != "ob_setup_2":
templates_to_test.remove( template_id2 )
# test the nationality-specific templates
# NOTE: The buttons are the same on the OB1 and OB2 tabs, so we only test for player 1.
for nat,template_ids in _NAT_TEMPLATES.items():
select_tab( "scenario" )
sel = Select( find_child( "select[name='PLAYER_1']" ) )
sel.select_by_value( nat )
select_tab( "ob1" )
for template_id in template_ids:
func( template_id, template_id )
templates_to_test.remove( template_id )
# make sure we tested everything
assert not templates_to_test
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def select_tab( tab_id ):
"""Select a tab in the main page."""
elem = find_child( "#tabs .ui-tabs-nav a[href='#tabs-{}']".format( tab_id ) )
elem.click()
def select_menu_option( menu_id ):
"""Select a menu option."""
elem = find_child( "#menu" )
elem.click()
elem = find_child( "a.PopMenu-Link[data-name='{}']".format( menu_id ) )
elem.click()
wait_for( 5, lambda: find_child("#menu .PopMenu-Container") is None ) # nb: wait for the menu to go away
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def set_template_params( params ):
"""Set template parameters."""
for key,val in params.items():
# check for SSR's (these require special handling)
if key == "SSR":
# add them in (nb: we don't consider any existing SSR's)
from vasl_templates.webapp.tests.test_ssr import add_ssr #pylint: disable=cyclic-import
for ssr in val:
add_ssr( _webdriver, ssr )
continue
# locate the next parameter
elem = next( c for c in ( \
find_child( "{}[name='{}']".format(elem_type,key) ) \
for elem_type in ["input","textarea","select"]
) if c )
# set the parameter value
if elem.tag_name == "select":
Select(elem).select_by_value( val )
else:
elem.clear()
if val:
elem.send_keys( val )
if key == "SCENARIO_DATE":
elem.send_keys( Keys.ESCAPE ) # nb: force the calendar popup to close :-/
wait_for( 5, lambda: find_child("#ui-datepicker-div").value_of_css_property("display") == "none" )
time.sleep( 0.25 )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def get_nationalities( webapp ):
"""Get the nationalities table."""
url = webapp.url_for( "get_nationalities" )
return json.load( urllib.request.urlopen( url ) )
# ---------------------------------------------------------------------
def get_stored_msg( msg_id ):
"""Get a message stored for us by the front-end."""
elem = find_child( "#"+msg_id )
if not elem:
return None
if elem.tag_name == "div":
return elem.text
assert elem.tag_name == "textarea"
return elem.get_attribute( "value" )
def set_stored_msg( msg_id, val ):
"""Set a message for the front-end."""
elem = find_child( "#"+msg_id )
assert elem.tag_name == "textarea"
_webdriver.execute_script( "arguments[0].value = arguments[1]", elem, val )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def find_child( sel, parent=None ):
"""Find a single child element."""
try:
return (parent if parent else _webdriver).find_element_by_css_selector( sel )
except NoSuchElementException:
return None
def find_children( sel, parent=None ):
"""Find child elements."""
try:
return (parent if parent else _webdriver).find_elements_by_css_selector( sel )
except NoSuchElementException:
return None
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def dismiss_notifications():
"""Dismiss all notifications."""
while True:
elem = find_child( ".growl-close" )
if not elem:
break
try:
elem.click()
time.sleep( 0.25 )
except StaleElementReferenceException:
pass # nb: the notification had already auto-closed
# ---------------------------------------------------------------------
def get_clipboard() :
"""Get the contents of the clipboard."""
app = QApplication( [] ) #pylint: disable=unused-variable
clipboard = QApplication.clipboard()
return clipboard.text()
def wait_for( timeout, func ):
"""Wait for a condition to become true."""
start_time = time.time()
while True:
if func():
break
assert time.time() - start_time < timeout
time.sleep( 0.1 )