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.
794 lines
32 KiB
794 lines
32 KiB
""" Test generating vehicle/ordnance snippets. """
|
|
|
|
import os
|
|
import re
|
|
import json
|
|
|
|
import pytest
|
|
from selenium.webdriver.common.action_chains import ActionChains
|
|
from selenium.webdriver.common.keys import Keys
|
|
|
|
from vasl_templates.webapp.tests import pytest_options
|
|
from vasl_templates.webapp.tests.test_scenario_persistence import load_scenario, save_scenario
|
|
from vasl_templates.webapp.tests.utils import \
|
|
init_webapp, get_nationalities, select_tab, set_template_params, find_child, find_children, \
|
|
wait_for_clipboard, click_dialog_button, select_menu_option, set_player, \
|
|
set_stored_msg_marker, get_stored_msg, get_sortable_vo_names
|
|
from vasl_templates.webapp.config.constants import DATA_DIR
|
|
|
|
# ---------------------------------------------------------------------
|
|
|
|
def test_crud( webapp, webdriver ):
|
|
"""Test basic create/read/update/delete of vehicles/ordnance."""
|
|
|
|
# initialize
|
|
init_webapp( webapp, webdriver )
|
|
|
|
# initialize
|
|
_expected = {
|
|
("vehicles",1): [], ("ordnance",1): [],
|
|
("vehicles",2): [], ("ordnance",2): []
|
|
}
|
|
_width = {
|
|
("vehicles",1): None, ("ordnance",1): None,
|
|
("vehicles",2): None, ("ordnance",2): None
|
|
}
|
|
|
|
def _add_vo( vo_type, player_no, name ):
|
|
"""Add a vehicle/ordnance."""
|
|
# check the hint
|
|
select_tab( "ob{}".format( player_no ) )
|
|
_check_hint( vo_type, player_no )
|
|
# add the vehicle/ordnance
|
|
add_vo( webdriver, vo_type, player_no, name )
|
|
_expected[ (vo_type,player_no) ].append( name )
|
|
# check the snippet and hint
|
|
_check_snippet( vo_type, player_no )
|
|
_check_hint( vo_type, player_no )
|
|
|
|
def _delete_vo( vo_type, player_no, name, webdriver ):
|
|
"""Delete a vehicle/ordnance."""
|
|
# check the hint
|
|
select_tab( "ob{}".format( player_no ) )
|
|
_check_hint( vo_type, player_no )
|
|
# delete the vehicle/ordnance
|
|
delete_vo( vo_type, player_no, name, webdriver )
|
|
_expected[ (vo_type,player_no) ].remove( name )
|
|
# check the snippet and hint
|
|
_check_snippet( vo_type, player_no )
|
|
_check_hint( vo_type, player_no )
|
|
|
|
def _set_width( vo_type, player_no, width ):
|
|
"""Set the snippet width."""
|
|
select_tab( "ob{}".format( player_no ) )
|
|
elem = find_child( "input[name='OB_{}_WIDTH_{}']".format( vo_type.upper(), player_no ) )
|
|
elem.clear()
|
|
if width is not None:
|
|
elem.send_keys( str(width) )
|
|
_width[ (vo_type,player_no) ] = width
|
|
|
|
def _check_snippet( vo_type, player_no ):
|
|
"""Check the generated vehicle/ordnance snippet."""
|
|
# check the snippet
|
|
select_tab( "ob{}".format( player_no ) )
|
|
btn = find_child( "button[data-id='ob_{}_{}']".format( vo_type, player_no ) )
|
|
btn.click()
|
|
def reformat( clipboard ): #pylint: disable=missing-docstring
|
|
return [
|
|
mo.group(1)
|
|
for mo in re.finditer( r"^\[\*\] (.*):" , clipboard, re.MULTILINE )
|
|
]
|
|
clipboard = wait_for_clipboard( 2, _expected[(vo_type,player_no)], transform=reformat )
|
|
# check the snippet width
|
|
expected = _width[ (vo_type,player_no) ]
|
|
mo = re.search(
|
|
r"width={}$".format( expected if expected else "" ),
|
|
clipboard,
|
|
re.MULTILINE
|
|
)
|
|
assert mo
|
|
|
|
def _check_hint( vo_type, player_no ):
|
|
"""Check the hint visibility."""
|
|
hint = find_child( "#ob_{}-hint_{}".format( vo_type, player_no ) )
|
|
expected = "none" if _expected[(vo_type,player_no)] else "block"
|
|
assert hint.value_of_css_property("display") == expected
|
|
|
|
def do_test( vo_type ):
|
|
"""Run the test."""
|
|
vo_type0 = vo_type[:-1] if vo_type.endswith("s") else vo_type
|
|
# add a German vehicle/ordnance
|
|
_add_vo( vo_type, 1, "a german {}".format(vo_type0) )
|
|
# generate a Russian vehicle/ordnance snippet
|
|
_check_snippet( vo_type, 2 )
|
|
# add a Russian vehicle/ordnance
|
|
_add_vo( vo_type, 2, "another russian {}".format(vo_type0) )
|
|
# go back and check the German snippet again
|
|
_check_snippet( vo_type, 1 )
|
|
# add another Russian vehicle/ordnance
|
|
_set_width( vo_type, 2, "200px" )
|
|
_add_vo( vo_type, 2, "name only" )
|
|
# delete the German vehicle/ordnance
|
|
_set_width( vo_type, 1, "100px" )
|
|
_delete_vo( vo_type, 1, "a german {}".format(vo_type0), webdriver )
|
|
_set_width( vo_type, 1, None )
|
|
_check_snippet( vo_type, 1 )
|
|
# go back and check the Russian snippet again
|
|
_check_snippet( vo_type, 2 )
|
|
# delete the Russian vehicles/ordnance
|
|
_delete_vo( vo_type, 2, "another russian {}".format(vo_type0), webdriver )
|
|
_set_width( vo_type, 2, None )
|
|
_delete_vo( vo_type, 2, "name only", webdriver )
|
|
# check the final state
|
|
assert not _expected[ (vo_type,1) ]
|
|
assert not _expected[ (vo_type,2) ]
|
|
|
|
# do the test
|
|
do_test( "vehicles" )
|
|
do_test( "ordnance" )
|
|
|
|
# ---------------------------------------------------------------------
|
|
|
|
def test_snippets( webapp, webdriver ):
|
|
"""Test vehicle/ordnance snippet generation in detail."""
|
|
|
|
# initialize
|
|
init_webapp( webapp, webdriver )
|
|
|
|
def do_test( vo_type ):
|
|
"""Run the test."""
|
|
vo_type0 = vo_type[:-1] if vo_type.endswith("s") else vo_type
|
|
# test a full example
|
|
add_vo( webdriver, vo_type, 1, "a german {}".format(vo_type0) )
|
|
btn = find_child( "button[data-id='ob_{}_1']".format( vo_type ) )
|
|
btn.click()
|
|
caps = '"XYZ" "IR" "A1" "H2"'
|
|
if vo_type == "vehicles":
|
|
caps += ' "CS 5"'
|
|
expected = [
|
|
'[German] ; width=',
|
|
'[*] a german {}: #=1'.format( vo_type0 ),
|
|
'- notes: "A" "B†"',
|
|
'- capabilities: {}'.format( caps ),
|
|
'- raw capabilities: {}'.format( caps ),
|
|
]
|
|
wait_for_clipboard( 2, "\n".join(expected) )
|
|
delete_vo( vo_type, 1, "a german {}".format(vo_type0), webdriver )
|
|
|
|
# test a partial example
|
|
add_vo( webdriver, vo_type, 1, "another german {}".format(vo_type0) )
|
|
btn = find_child( "button[data-id='ob_{}_1']".format( vo_type ) )
|
|
btn.click()
|
|
caps = '"XYZ"'
|
|
if vo_type == "vehicles":
|
|
caps += ' "<span class=\'brewup\'>cs 4</span>"'
|
|
expected = [
|
|
'[German] ; width=',
|
|
'[*] another german {}: #=2'.format( vo_type0 ),
|
|
'- capabilities: {}'.format( caps ),
|
|
'- raw capabilities: {}'.format( caps ),
|
|
]
|
|
if vo_type == "vehicles":
|
|
expected.insert( 2, '- notes: "<s>b</s>" "C"' )
|
|
wait_for_clipboard( 2, "\n".join(expected) )
|
|
delete_vo( vo_type, 1, "another german {}".format(vo_type0), webdriver )
|
|
|
|
# test a minimal example
|
|
add_vo( webdriver, vo_type, 1, "name only" )
|
|
btn = find_child( "button[data-id='ob_{}_1']".format( vo_type ) )
|
|
btn.click()
|
|
expected = [
|
|
'[German] ; width=',
|
|
'[*] name only: #=',
|
|
'- capabilities:',
|
|
'- raw capabilities:',
|
|
]
|
|
wait_for_clipboard( 2, "\n".join(expected) )
|
|
|
|
# do the test
|
|
set_player( 1, "german" )
|
|
do_test( "vehicles" )
|
|
do_test( "ordnance" )
|
|
|
|
# ---------------------------------------------------------------------
|
|
|
|
def test_variable_capabilities( webapp, webdriver ):
|
|
"""Test date-based variable capabilities."""
|
|
|
|
# initialize
|
|
init_webapp( webapp, webdriver )
|
|
|
|
# add a vehicle
|
|
add_vo( webdriver, "vehicles", 2, "Churchill III(b)" )
|
|
|
|
# change the scenario date and check the generated snippet
|
|
vehicles2 = find_child( "button.generate[data-id='ob_vehicles_2']" )
|
|
def do_test( month, year, expected ):
|
|
"""Set the date and check the vehicle snippet."""
|
|
select_tab( "scenario" )
|
|
set_template_params( { "SCENARIO_DATE": "{:02d}/01/{}".format(month,year) } )
|
|
select_tab( "ob2" )
|
|
vehicles2.click()
|
|
def reformat( clipboard ): #pylint: disable=missing-docstring
|
|
mo = re.search( r"^- capabilities: (.*)$", clipboard, re.MULTILINE )
|
|
return mo.group( 1 )
|
|
wait_for_clipboard( 2, expected, transform=reformat )
|
|
do_test( 1, 1940, '"sM8\u2020" "CS 7"' )
|
|
do_test( 1, 1943, '"sM8\u2020" "CS 7"' )
|
|
do_test( 2, 1943, '"HE7\u2020" "sM8\u2020" "CS 7"' )
|
|
do_test( 12, 1943, '"HE7\u2020" "sM8\u2020" "CS 7"' )
|
|
do_test( 1, 1944, '"HE8\u2020" "sD6" "sM8\u2020" "CS 7"' )
|
|
do_test( 5, 1944, '"HE8\u2020" "sD6" "sM8\u2020" "CS 7"' )
|
|
do_test( 6, 1944, '"D6\u2020" "HE8\u2020" "sD6" "sM8\u2020" "CS 7"' )
|
|
do_test( 12, 1944, '"D6\u2020" "HE8\u2020" "sD6" "sM8\u2020" "CS 7"' )
|
|
do_test( 1, 1945, '"D7\u2020" "HE8\u2020" "sD6" "sM8\u2020" "CS 7"' )
|
|
do_test( 12, 1945, '"D7\u2020" "HE8\u2020" "sD6" "sM8\u2020" "CS 7"' )
|
|
do_test( 1, 1946, '"HE8\u2020" "sD6" "sM8\u2020" "CS 7"' )
|
|
|
|
# ---------------------------------------------------------------------
|
|
|
|
def test_html_names( webapp, webdriver ):
|
|
"""Test handling of vehicles/ordnance that have HTML in their name."""
|
|
|
|
# initialize
|
|
webapp.control_tests.set_data_dir( "{REAL}" )
|
|
init_webapp( webapp, webdriver )
|
|
|
|
def get_available_ivfs():
|
|
"""Get the PzKw IVF's available for selection."""
|
|
entries = find_children( "#select-vo .select2-results li" )
|
|
entries = [ e.text for e in entries ]
|
|
return [ e for e in entries if "IVF" in e ]
|
|
|
|
# start to add a vehicle - make sure the two PzKw IVF's are available
|
|
set_player( 1, "german" )
|
|
select_tab( "ob1" )
|
|
add_vehicle_btn = find_child( "#ob_vehicles-add_1" )
|
|
add_vehicle_btn.click()
|
|
assert get_available_ivfs() == [ "PzKpfw IVF1 (MT)", "PzKpfw IVF2 (MT)" ]
|
|
|
|
# add the PzKw IVF2
|
|
elem = find_child( ".ui-dialog .select2-search__field" )
|
|
elem.send_keys( "IVF2" )
|
|
elem.send_keys( Keys.RETURN )
|
|
|
|
# make sure it was added to the player's OB
|
|
vehicles_sortable = find_child( "#ob_vehicles-sortable_1" )
|
|
assert get_sortable_vo_names( vehicles_sortable ) == [ "PzKpfw IVF2" ]
|
|
|
|
# start to add another vehicle - make sure both PzKw IVF's are still available
|
|
add_vehicle_btn.click()
|
|
assert get_available_ivfs() == [ "PzKpfw IVF1 (MT)", "PzKpfw IVF2 (MT)" ]
|
|
|
|
# add the PzKw IVF1
|
|
elem = find_child( ".ui-dialog .select2-search__field" )
|
|
elem.send_keys( "IVF1" )
|
|
elem.send_keys( Keys.RETURN )
|
|
|
|
# make sure it was added to the player's OB
|
|
assert get_sortable_vo_names( vehicles_sortable ) == [ "PzKpfw IVF2", "PzKpfw IVF1" ]
|
|
|
|
# start to add another vehicle - make sure both PzKw IVF's are still available
|
|
add_vehicle_btn.click()
|
|
assert get_available_ivfs() == [ "PzKpfw IVF1 (MT)", "PzKpfw IVF2 (MT)" ]
|
|
elem = find_child( ".ui-dialog .select2-search__field" )
|
|
elem.send_keys( Keys.ESCAPE )
|
|
|
|
# delete the PzKw IVF2
|
|
delete_vo( "vehicles", 1, "PzKpfw IVF2" , webdriver )
|
|
|
|
# start to add another vehicle - make sure both PzKw IVF's are still available
|
|
add_vehicle_btn.click()
|
|
assert get_available_ivfs() == [ "PzKpfw IVF1 (MT)", "PzKpfw IVF2 (MT)" ]
|
|
|
|
# ---------------------------------------------------------------------
|
|
|
|
def test_duplicate_vo_entries( webapp, webdriver ):
|
|
"""Test adding duplicate vehicles/ordnance."""
|
|
|
|
# initialize
|
|
init_webapp( webapp, webdriver )
|
|
set_player( 1, "german" )
|
|
select_tab( "ob1" )
|
|
|
|
def get_available_vo_entries():
|
|
"""Get the available vehicles/ordnance for selection."""
|
|
entries = find_children( "#select-vo .select2-results li" )
|
|
return [ e.text for e in entries ]
|
|
|
|
def do_test( vo_type, vo_name ): #pylint: disable=missing-docstring
|
|
|
|
# start to add a vehicle/ordnance
|
|
add_btn = find_child( "#ob_" + vo_type + "-add_1" )
|
|
add_btn.click()
|
|
assert vo_name in get_available_vo_entries()
|
|
|
|
# add the vehicle/ordnance
|
|
elem = find_child( ".ui-dialog .select2-search__field" )
|
|
elem.send_keys( vo_name )
|
|
elem.send_keys( Keys.RETURN )
|
|
|
|
# make sure it was added to the player's OB
|
|
sortable = find_child( "#ob_" + vo_type + "-sortable_1" )
|
|
assert get_sortable_vo_names( sortable ) == [ vo_name ]
|
|
|
|
# add the vehicle/ordnance, dismiss the warning
|
|
add_btn.click()
|
|
elem = find_child( ".ui-dialog .select2-search__field" )
|
|
elem.send_keys( vo_name )
|
|
elem.send_keys( Keys.RETURN )
|
|
elem = find_child( "#ask" )
|
|
assert "already in the OB" in elem.text
|
|
click_dialog_button( "Cancel", find_child(".ui-dialog.ask") )
|
|
click_dialog_button( "Cancel" )
|
|
|
|
# make sure the player's OB is unchanged
|
|
assert get_sortable_vo_names( sortable ) == [ vo_name ]
|
|
|
|
# add the vehicle/ordnance, accept the warning
|
|
add_btn.click()
|
|
elem = find_child( ".ui-dialog .select2-search__field" )
|
|
elem.send_keys( vo_name )
|
|
elem.send_keys( Keys.RETURN )
|
|
elem = find_child( "#ask" )
|
|
assert "already in the OB" in elem.text
|
|
click_dialog_button( "OK", find_child(".ui-dialog.ask") )
|
|
|
|
# make sure the vehicle/ordnance was added to the player's OB
|
|
assert get_sortable_vo_names( sortable ) == [ vo_name, vo_name ]
|
|
|
|
# do the test
|
|
do_test( "vehicles", "a german vehicle" )
|
|
do_test( "ordnance", "name only" )
|
|
|
|
# ---------------------------------------------------------------------
|
|
|
|
@pytest.mark.skipif( pytest_options.short_tests, reason="--short-tests specified" )
|
|
def test_common_vo( webapp, webdriver ): #pylint: disable=too-many-locals
|
|
"""Test loading of common vehicles/ordnance and landing craft."""
|
|
|
|
# initialize
|
|
webapp.control_tests.set_data_dir( "{REAL}" )
|
|
init_webapp( webapp, webdriver )
|
|
|
|
# initialize
|
|
ALLIED_MINOR = [ "belgian", "danish", "dutch", "greek", "polish", "yugoslavian" ]
|
|
AXIS_MINOR = [ "bulgarian", "croatian", "hungarian", "romanian", "slovakian" ]
|
|
|
|
# get the common vehicles/ordnance
|
|
def get_common_vo( fname ):
|
|
"""Get the vehicle/ordnance information from the specified file."""
|
|
fname = os.path.join( DATA_DIR, fname )
|
|
data = json.load( open( fname, "r" ) )
|
|
def get_gpid( val ): #pylint: disable=missing-docstring
|
|
if isinstance( val, list ):
|
|
val = val[0]
|
|
assert isinstance(val,int) or val is None
|
|
return val
|
|
return [ ( vo["name"], get_gpid(vo["gpid"]) ) for vo in data ]
|
|
common_vo = {
|
|
"vehicles": {
|
|
"allied": get_common_vo( "vehicles/allied-minor/common.json" ),
|
|
"axis": get_common_vo( "vehicles/axis-minor/common.json" ),
|
|
},
|
|
"ordnance": {
|
|
"allied": get_common_vo( "ordnance/allied-minor/common.json" ),
|
|
"axis": get_common_vo( "ordnance/axis-minor/common.json" ),
|
|
},
|
|
}
|
|
landing_craft = get_common_vo( "vehicles/landing-craft.json" )
|
|
|
|
tidy_vo_name_regex = re.compile( r" \([A-Za-z]+\)$" ) # nb: removes the trailing vehicle/ordnance type
|
|
gpid_regex = re.compile( r"/counter/(\d+)/front" )
|
|
def get_vo_entry( elem ):
|
|
"""Get the vehicle/ordnance information from the Selenium element."""
|
|
vo_name = tidy_vo_name_regex.sub( "", elem.text )
|
|
image_url = find_child( "img", elem ).get_attribute( "src" )
|
|
mo = gpid_regex.search( image_url )
|
|
return ( vo_name, int(mo.group(1)) if mo else None )
|
|
|
|
def is_valid_vo_entry( vo_entry ):
|
|
"""Check if a V/O entry is valid."""
|
|
return isinstance( vo_entry, tuple ) and len(vo_entry) == 2 \
|
|
and isinstance( vo_entry[0], str ) \
|
|
and isinstance( vo_entry[1], (int,type(None)) )
|
|
def is_same_vo( lhs, rhs ):
|
|
"""Check if two V/O entries are the same."""
|
|
assert is_valid_vo_entry(lhs) and is_valid_vo_entry(rhs)
|
|
return lhs == rhs
|
|
def is_vo_entry_in_list( vo_entry, vo_entries ):
|
|
"""Check if a V/O entry appears in a list of V/O entries."""
|
|
assert is_valid_vo_entry( vo_entry )
|
|
return any( is_same_vo(vo_entry,e) for e in vo_entries )
|
|
|
|
# check the vehicles/ordnance for each nationality
|
|
nationalities = get_nationalities( webapp )
|
|
for nat in nationalities: #pylint: disable=too-many-nested-blocks
|
|
|
|
# select the next nationality
|
|
set_player( 1, nat )
|
|
|
|
select_tab( "ob1" )
|
|
for vo_type in ("vehicles","ordnance"):
|
|
|
|
# check if the nationality has any vehicles/ordnance
|
|
elem = find_child( "#ob_{}-add_1".format( vo_type ) )
|
|
if nat in ["thai","indonesian","anzac","burmese","filipino"]: # nb: these are in the BFP extension
|
|
assert not elem.is_enabled()
|
|
continue
|
|
if nat == "kfw-cpva" and vo_type == "vehicles":
|
|
assert not elem.is_enabled()
|
|
continue
|
|
elem.click()
|
|
|
|
# get the vehicles/ordnance
|
|
vo_entries = find_children( "#select-vo .select2-results li" )
|
|
vo_entries = [ get_vo_entry(e) for e in vo_entries ]
|
|
click_dialog_button( "Cancel" )
|
|
|
|
# check that the common vehicles/ordnance are present/absent
|
|
if nat in ALLIED_MINOR:
|
|
assert all(
|
|
is_vo_entry_in_list( vo_entry, vo_entries )
|
|
for vo_entry in common_vo[vo_type]["allied"]
|
|
)
|
|
elif nat in AXIS_MINOR:
|
|
assert all(
|
|
is_vo_entry_in_list( vo_entry, vo_entries )
|
|
for vo_entry in common_vo[vo_type]["axis"]
|
|
)
|
|
else:
|
|
assert all(
|
|
not is_vo_entry_in_list( vo_entry, vo_entries )
|
|
for vo_entry in common_vo[vo_type]["allied"]
|
|
)
|
|
assert all(
|
|
not is_vo_entry_in_list( vo_entry, vo_entries )
|
|
for vo_entry in common_vo[vo_type]["axis"]
|
|
)
|
|
|
|
# check that the landing craft are present/absent
|
|
if vo_type == "vehicles":
|
|
if nat in ("british","american"):
|
|
for vo_entry in landing_craft:
|
|
if vo_entry[0] in ("Daihatsu","Shohatsu"):
|
|
assert not is_vo_entry_in_list( vo_entry, vo_entries )
|
|
else:
|
|
assert is_vo_entry_in_list( vo_entry, vo_entries )
|
|
elif nat == "japanese":
|
|
for vo_entry in landing_craft:
|
|
if vo_entry[0] in ("Daihatsu","Shohatsu"):
|
|
assert is_vo_entry_in_list( vo_entry, vo_entries )
|
|
else:
|
|
assert not is_vo_entry_in_list( vo_entry, vo_entries )
|
|
else:
|
|
assert all(
|
|
not is_vo_entry_in_list( vo_entry, vo_entries )
|
|
for vo_entry in landing_craft
|
|
)
|
|
|
|
# ---------------------------------------------------------------------
|
|
|
|
def test_vo_images( webapp, webdriver ): #pylint: disable=too-many-statements
|
|
"""Test handling of vehicles/ordnance that have multiple images."""
|
|
|
|
# initialize
|
|
webapp.control_tests \
|
|
.set_data_dir( "{REAL}" ) \
|
|
.set_vasl_version( "random", None )
|
|
init_webapp( webapp, webdriver, scenario_persistence=1 )
|
|
|
|
def check_sortable2_entries( player_no, expected ):
|
|
"""Check the settings on the player's vehicles."""
|
|
entries = find_children( "#ob_vehicles-sortable_{} li".format( player_no ) )
|
|
for i,entry in enumerate(entries):
|
|
# check the displayed image
|
|
elem = find_child( "img", entry )
|
|
assert elem.get_attribute( "src" ).endswith( expected[i][0] )
|
|
# check the attached data
|
|
data = webdriver.execute_script( "return $(arguments[0]).data('sortable2-data')", entry )
|
|
assert data["vo_entry"]["id"] == expected[i][1]
|
|
assert data["vo_image_id"] == expected[i][2]
|
|
|
|
def check_save_scenario( player_no, expected ):
|
|
"""Check the vo_entry and vo_image_id fields are saved correctly."""
|
|
data = save_scenario()
|
|
assert data[ "OB_VEHICLES_{}".format(player_no) ] == expected
|
|
return data
|
|
|
|
# start to add a PzKw VIB
|
|
set_player( 1, "german" )
|
|
select_tab( "ob1" )
|
|
add_vehicle_btn = find_child( "#ob_vehicles-add_1" )
|
|
add_vehicle_btn.click()
|
|
search_field = find_child( ".ui-dialog .select2-search__field" )
|
|
search_field.send_keys( "VIB" )
|
|
|
|
# make sure there is only 1 image available
|
|
elem = find_child( "#select-vo .select2-results li img[class='vasl-image']" )
|
|
assert elem.get_attribute( "src" ).endswith( "/counter/2602/front" )
|
|
vo_images = webdriver.execute_script( "return $(arguments[0]).data('vo-images')", elem )
|
|
assert vo_images is None
|
|
assert not find_child( "#select-vo .select2-results li input.select-vo-image" )
|
|
|
|
# add the PzKw VIB, make sure the sortable2 entry has its data set correctly
|
|
search_field.send_keys( Keys.RETURN )
|
|
check_sortable2_entries( 1, [
|
|
( "/counter/2602/front", "ge/v:035", None )
|
|
] )
|
|
|
|
# check that the vehicles are saved correctly
|
|
check_save_scenario( 1, [
|
|
{ "id": "ge/v:035", "name": "PzKpfw VIB", "seq_id": 1 },
|
|
] )
|
|
|
|
# start to add a PzKw IVH (this has multiple GPID's)
|
|
add_vehicle_btn.click()
|
|
search_field = find_child( ".ui-dialog .select2-search__field" )
|
|
search_field.send_keys( "IVH" )
|
|
|
|
# make sure multiple images are available
|
|
elem = find_child( "#select-vo .select2-results li img[class='vasl-image']" )
|
|
assert elem.get_attribute( "src" ).endswith( "/counter/2584/front" )
|
|
vo_images = webdriver.execute_script( "return $(arguments[0]).data('vo-images')", elem )
|
|
assert vo_images == [ [2584,0], [2586,0], [2807,0], [2809,0] ]
|
|
assert find_child( "#select-vo .select2-results li input.select-vo-image" )
|
|
|
|
# add the PzKw IVH, make sure the sortable2 entry has its data set correctly
|
|
search_field.send_keys( Keys.RETURN )
|
|
check_sortable2_entries( 1, [
|
|
( "/counter/2602/front", "ge/v:035", None ),
|
|
( "/counter/2584/front", "ge/v:027", None ) # nb: there is no V/O image ID if it's not necessary
|
|
] )
|
|
|
|
# check that the vehicles are saved correctly
|
|
check_save_scenario( 1, [
|
|
{ "id": "ge/v:035", "name": "PzKpfw VIB", "seq_id": 1 },
|
|
{ "id": "ge/v:027", "name": "PzKpfw IVH", "seq_id": 2 }, # nb: there is no V/O image ID if it's not necessary
|
|
] )
|
|
|
|
# delete the PzKw IVH
|
|
delete_vo( "vehicles", 1, "PzKpfw IVH", webdriver )
|
|
|
|
# add the PzKw IVH, with a different image, make sure the sortable2 entry has its data set correctly
|
|
add_vehicle_btn.click()
|
|
search_field = find_child( ".ui-dialog .select2-search__field" )
|
|
search_field.send_keys( "IVH" )
|
|
elem = find_child( "#select-vo .select2-results li img[class='vasl-image']" )
|
|
assert elem.get_attribute( "src" ).endswith( "/counter/2584/front" )
|
|
btn = find_child( "#select-vo .select2-results li input.select-vo-image" )
|
|
btn.click()
|
|
images = find_children( ".ui-dialog.select-vo-image .vo-images img" )
|
|
assert len(images) == 4
|
|
images[2].click()
|
|
check_sortable2_entries( 1, [
|
|
( "/counter/2602/front", "ge/v:035", None ),
|
|
( "/counter/2807/front/0", "ge/v:027", [2807,0] )
|
|
] )
|
|
|
|
# check that the vehicles are saved correctly
|
|
check_save_scenario( 1, [
|
|
{ "id": "ge/v:035", "name": "PzKpfw VIB", "seq_id": 1 },
|
|
{ "id": "ge/v:027", "image_id": "2807/0", "name": "PzKpfw IVH", "seq_id": 2 },
|
|
] )
|
|
|
|
# set the British as player 2
|
|
set_player( 2, "british" )
|
|
|
|
# start to add a 2pdr Portee (this has multiple images for a single GPID)
|
|
select_tab( "ob2" )
|
|
add_vehicle_btn = find_child( "#ob_vehicles-add_2" )
|
|
add_vehicle_btn.click()
|
|
search_field = find_child( ".ui-dialog .select2-search__field" )
|
|
search_field.send_keys( "2pdr" )
|
|
|
|
# make sure multiple images are available
|
|
elem = find_child( "#select-vo .select2-results li img[class='vasl-image']" )
|
|
assert elem.get_attribute( "src" ).endswith( "/counter/1555/front" )
|
|
vo_images = webdriver.execute_script( "return $(arguments[0]).data('vo-images')", elem )
|
|
assert vo_images == [ [1555,0], [1555,1] ]
|
|
assert find_child( "#select-vo .select2-results li input.select-vo-image" )
|
|
|
|
# add the 2pdr Portee, make sure the sortable2 entry has its data set correctly
|
|
search_field.send_keys( Keys.RETURN )
|
|
check_sortable2_entries( 2, [
|
|
( "/counter/1555/front", "br/v:115", None ) # nb: there is no V/O image ID if it's not necessary
|
|
] )
|
|
|
|
# check that the vehicles are saved correctly
|
|
check_save_scenario( 2, [
|
|
{ "id": "br/v:115", "name": "2pdr Portee", "seq_id": 1 }, # nb: there is no V/O image ID if it's not necessary
|
|
] )
|
|
|
|
# delete the 2pdr Portee
|
|
delete_vo( "vehicles", 2, "2pdr Portee", webdriver )
|
|
|
|
# add the 2pdr Portee, with a different image, make sure the sortable2 entry has its data set correctly
|
|
add_vehicle_btn.click()
|
|
search_field = find_child( ".ui-dialog .select2-search__field" )
|
|
search_field.send_keys( "2pdr" )
|
|
elem = find_child( "#select-vo .select2-results li img[class='vasl-image']" )
|
|
assert elem.get_attribute( "src" ).endswith( "/counter/1555/front" )
|
|
btn = find_child( "#select-vo .select2-results li input.select-vo-image" )
|
|
btn.click()
|
|
images = find_children( ".ui-dialog.select-vo-image .vo-images img" )
|
|
assert len(images) == 2
|
|
images[1].click()
|
|
check_sortable2_entries( 2, [
|
|
( "/counter/1555/front/1", "br/v:115", [1555,1] )
|
|
] )
|
|
|
|
# check that the vehicles are saved correctly
|
|
saved_scenario = check_save_scenario( 2, [
|
|
{ "id": "br/v:115", "image_id": "1555/1", "name": "2pdr Portee", "seq_id": 1 },
|
|
] )
|
|
|
|
# reset the scenario
|
|
select_menu_option( "new_scenario" )
|
|
check_sortable2_entries( 1, [] )
|
|
check_sortable2_entries( 2, [] )
|
|
|
|
# load the last saved scenario, make sure the correct images are displayed
|
|
load_scenario( saved_scenario )
|
|
check_sortable2_entries( 1, [
|
|
( "/counter/2602/front", "ge/v:035", None ),
|
|
( "/counter/2807/front/0", "ge/v:027", ["2807",0] )
|
|
] )
|
|
check_sortable2_entries( 2, [
|
|
( "/counter/1555/front/1", "br/v:115", ["1555",1] )
|
|
] )
|
|
|
|
# ---------------------------------------------------------------------
|
|
|
|
def test_change_vo_image( webapp, webdriver ):
|
|
"""Test changing a V/O image."""
|
|
|
|
# initialize
|
|
webapp.control_tests \
|
|
.set_data_dir( "{REAL}" ) \
|
|
.set_vasl_version( "random", None )
|
|
init_webapp( webapp, webdriver, scenario_persistence=1 )
|
|
|
|
# add an ISU-152
|
|
set_player( 2, "russian" )
|
|
add_vo( webdriver, "vehicles", 2, "ISU-152" )
|
|
|
|
# save the scenario
|
|
saved_scenario = save_scenario()
|
|
assert saved_scenario["OB_VEHICLES_2"] == [ { "id": "ru/v:049", "name": "ISU-152", "seq_id": 1 } ]
|
|
|
|
# change the vehicle's image
|
|
vehicles_sortable = find_child( "#ob_vehicles-sortable_2" )
|
|
elems = find_children( "li", vehicles_sortable )
|
|
assert len(elems) == 1
|
|
ActionChains(webdriver).double_click( elems[0] ).perform()
|
|
img = find_child( "#edit-vo img.vasl-image" )
|
|
assert img.get_attribute( "src" ).endswith( "/counter/657/front" )
|
|
btn = find_child( "#edit-vo input.select-vo-image" )
|
|
btn.click()
|
|
images = find_children( ".ui-dialog.select-vo-image .vo-images img" )
|
|
assert len(images) == 2
|
|
images[1].click()
|
|
assert img.get_attribute( "src" ).endswith( "/counter/659/front/0" )
|
|
click_dialog_button( "OK" )
|
|
elems = find_children( "img.vasl-image", vehicles_sortable )
|
|
assert len(elems) == 1
|
|
assert elems[0].get_attribute( "src" ).endswith( "/counter/659/front/0" )
|
|
|
|
# save the scenario
|
|
saved_scenario = save_scenario()
|
|
assert saved_scenario["OB_VEHICLES_2"] == [
|
|
{ "id": "ru/v:049", "image_id": "659/0", "name": "ISU-152", "seq_id": 1 }
|
|
]
|
|
|
|
# reload the scenario, and check the vehicle's image
|
|
select_menu_option( "new_scenario" )
|
|
load_scenario( saved_scenario )
|
|
select_tab( "ob2" )
|
|
elems = find_children( "img.vasl-image", vehicles_sortable )
|
|
assert len(elems) == 1
|
|
assert elems[0].get_attribute( "src" ).endswith( "/counter/659/front/0" )
|
|
|
|
# change the vehicle's image back to the default
|
|
elems = find_children( "li", vehicles_sortable )
|
|
assert len(elems) == 1
|
|
ActionChains(webdriver).double_click( elems[0] ).perform()
|
|
img = find_child( "#edit-vo img.vasl-image" )
|
|
assert img.get_attribute( "src" ).endswith( "/counter/659/front/0" )
|
|
btn = find_child( "#edit-vo input.select-vo-image" )
|
|
btn.click()
|
|
images = find_children( ".ui-dialog.select-vo-image .vo-images img" )
|
|
assert len(images) == 2
|
|
images[0].click()
|
|
assert img.get_attribute( "src" ).endswith( "/counter/657/front/0" )
|
|
click_dialog_button( "OK" )
|
|
elems = find_children( "img.vasl-image", vehicles_sortable )
|
|
assert len(elems) == 1
|
|
assert elems[0].get_attribute( "src" ).endswith( "/counter/657/front/0" )
|
|
|
|
# save the scenario
|
|
saved_scenario = save_scenario()
|
|
assert saved_scenario["OB_VEHICLES_2"] == [
|
|
{ "id": "ru/v:049", "image_id": "657/0", "name": "ISU-152", "seq_id": 1 }
|
|
]
|
|
|
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
def test_change_vo_image2( webapp, webdriver ):
|
|
"""Test changing the image for a V/O that has no alternative images."""
|
|
|
|
# initialize
|
|
webapp.control_tests.set_data_dir( "{REAL}" )
|
|
init_webapp( webapp, webdriver, scenario_persistence=1 )
|
|
|
|
# add an 107mm GVPM
|
|
set_player( 2, "russian" )
|
|
add_vo( webdriver, "ordnance", 2, "107mm GVPM obr. 38" )
|
|
|
|
# make sure the "change image" button is not present
|
|
ordnance_sortable = find_child( "#ob_ordnance-sortable_2" )
|
|
elems = find_children( "li", ordnance_sortable )
|
|
assert len(elems) == 1
|
|
ActionChains(webdriver).double_click( elems[0] ).perform()
|
|
btn = find_child( "#edit-vo input.select-vo-image" )
|
|
assert btn is None
|
|
|
|
# ---------------------------------------------------------------------
|
|
|
|
def test_invalid_vo_image_ids( webapp, webdriver ):
|
|
"""Test loading scenarios that contain invalid V/O image ID's."""
|
|
|
|
# initialize
|
|
init_webapp( webapp, webdriver, scenario_persistence=1 )
|
|
|
|
# test each save file
|
|
dname = os.path.join( os.path.split(__file__)[0], "fixtures/invalid-vo-image-ids" )
|
|
for root,_,fnames in os.walk(dname):
|
|
for fname in fnames:
|
|
fname = os.path.join( root, fname )
|
|
if os.path.splitext( fname )[1] != ".json":
|
|
continue
|
|
|
|
# load the next scenario, make sure a warning was issued for the V/O image ID
|
|
data = json.load( open(fname,"r") )
|
|
set_stored_msg_marker( "_last-warning_" )
|
|
load_scenario( data )
|
|
last_warning = get_stored_msg( "_last-warning_" )
|
|
assert "Invalid V/O image ID" in last_warning
|
|
|
|
# ---------------------------------------------------------------------
|
|
|
|
def add_vo( webdriver, vo_type, player_no, name ): #pylint: disable=unused-argument
|
|
"""Add a vehicle/ordnance."""
|
|
|
|
# add the vehicle/ordnance
|
|
select_tab( "ob{}".format( player_no ) )
|
|
elem = find_child( "#ob_{}-add_{}".format( vo_type, player_no ) )
|
|
elem.click()
|
|
# FUDGE! Locating the vehicle/ordnance by name and selecting it is finicky, I suspect
|
|
# because select2 is sensitive about where the mouse is, and we sometimes end up
|
|
# selecting the wrong item :-/ Selecting by name won't work if there are multiple items
|
|
# that start with the same thing, but that shouldn't be a problem.
|
|
dlg = find_child( "#select-vo" )
|
|
elem = find_child( "input", dlg )
|
|
elem.send_keys( name )
|
|
entries = find_children( ".select2-results li", dlg )
|
|
assert len(entries) == 1
|
|
click_dialog_button( "OK" )
|
|
|
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
def delete_vo( vo_type, player_no, name, webdriver ):
|
|
"""Delete a vehicle/ordnance."""
|
|
|
|
# delete the vehicle/ordnance
|
|
select_tab( "ob{}".format( player_no ) )
|
|
sortable = find_child( "#ob_{}-sortable_{}".format( vo_type, player_no ) )
|
|
elems = [
|
|
c for c in find_children( "li .vo-name", sortable )
|
|
if c.text == name
|
|
]
|
|
assert len(elems) == 1
|
|
elem = elems[0]
|
|
trash = find_child( "#ob_{}-trash_{}".format( vo_type, player_no ) )
|
|
ActionChains(webdriver).drag_and_drop( elem, trash ).perform()
|
|
|