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/test_dirty_scenario_checks.py

178 lines
7.4 KiB

""" Test checks for a dirty scenario. """
import re
import pytest
from selenium.webdriver.support.ui import Select
from vasl_templates.webapp.tests.test_scenario_persistence import ALL_SCENARIO_PARAMS
from vasl_templates.webapp.tests.test_vehicles_ordnance import add_vo
from vasl_templates.webapp.tests.utils import \
init_webapp, select_tab, select_menu_option, add_simple_note, select_droplist_val, select_droplist_index, \
drag_sortable_entry_to_trash, get_sortable_entry_count, \
get_stored_msg, set_stored_msg_marker, find_child, wait_for, click_dialog_button
# ---------------------------------------------------------------------
def test_dirty_scenario_checks( webapp, webdriver ):
"""Test checking for a dirty scenario."""
# initialize
init_webapp( webapp, webdriver )
# initialize
SIMPLE_NOTES = {
"SCENARIO_NOTES": "#scenario_notes-sortable",
"SSR": "#ssr-sortable",
"OB_SETUPS_1": "#ob_setups-sortable_1",
"OB_NOTES_1": "#ob_notes-sortable_1",
"OB_SETUPS_2": "#ob_setups-sortable_2",
"OB_NOTES_2": "#ob_notes-sortable_2",
}
VEHICLE_ORDNANCE = {
"OB_VEHICLES_1": ( "#ob_vehicles-sortable_1", 1, "a german vehicle" ),
"OB_ORDNANCE_1": ( "#ob_ordnance-sortable_1", 1, "a german ordnance" ),
"OB_VEHICLES_2": ( "#ob_vehicles-sortable_2", 2, "a russian vehicle" ),
"OB_ORDNANCE_2": ( "#ob_ordnance-sortable_2", 2, "a russian ordnance" ),
}
def change_field( param ):
"""Make a change to a field."""
# make a change to the specified field
if param in SIMPLE_NOTES:
target = find_child( SIMPLE_NOTES[param] )
add_simple_note( target, "changed value", None )
return target
if param in VEHICLE_ORDNANCE:
info = VEHICLE_ORDNANCE[param]
target = find_child( info[0] )
mo = re.search( r"([a-z]+)-", info[0] )
add_vo( webdriver, mo.group(1), info[1], info[2] )
return target
target = next( e for e in [
find_child( "{}[name='{}']".format( ctype, param ) )
for ctype in ["input","select","textarea"]
] if e )
if target.tag_name in ("input","textarea"):
prev_val = target.get_attribute( "value" )
new_val = "01/01/2000" if param == "SCENARIO_DATE" else "changed value"
if target.is_displayed():
target.clear()
target.send_keys( new_val )
else:
webdriver.execute_script( "arguments[0].value = arguments[1]", target, new_val )
return target, prev_val, new_val
elif target.tag_name == "select":
sel = Select( target )
prev_val = sel.first_selected_option.get_attribute( "value" )
select_droplist_index( sel, 2 )
new_val = sel.first_selected_option.get_attribute( "value" )
return target, prev_val, new_val
assert False
return None
def check_field( param, state ):
"""Check that a change we made to a field is still there."""
if param in SIMPLE_NOTES:
assert get_sortable_entry_count( state ) == 1
elif param in VEHICLE_ORDNANCE:
assert get_sortable_entry_count( state ) == 1
elif state[0].tag_name in ("input","textarea"):
assert state[0].get_attribute("value") == state[2]
elif state[0].tag_name == "select":
assert Select(state[0]).first_selected_option.get_attribute("value") == state[2]
else:
assert False
def revert_field( param, state ):
"""Revert a change we made to a field."""
if param in SIMPLE_NOTES:
drag_sortable_entry_to_trash( state, 0 )
elif param in VEHICLE_ORDNANCE:
drag_sortable_entry_to_trash( state, 0 )
elif state[0].tag_name in ("input","textarea"):
if state[0].is_displayed():
state[0].clear()
state[0].send_keys( state[1] )
else:
webdriver.execute_script( "arguments[0].value = arguments[1]", state[0], state[1] )
elif state[0].tag_name == "select":
select_droplist_val( Select(state[0]), state[1] )
else:
assert False
def check_is_dirty( expected ):
"""Check if the scenario is being flagged as dirty."""
if expected:
func = lambda: webdriver.title.endswith( " (*)" )
else:
func = lambda: not webdriver.title.endswith( " (*)" )
# NOTE: There is a race condition here if things are not working properly. Since the window title
# is updated on a timer, if we're expecting it to be (say) not modified, but the UI thinks that
# it is modified, we could check the window title here, see that the scenario is being flagged
# as not modified and continue on. The timer then fires, updates the UI to flag the scenario
# as modified, and we will have missed the error.
# To fix this, we force the scenario status to be updated.
webdriver.execute_script( "update_scenario_status()" )
wait_for( 2, func )
def do_test( tab_id, param ):
"""Test checking for a dirty scenario."""
# change the specified field
check_is_dirty( False )
select_tab( tab_id )
state = change_field( param )
check_is_dirty( True )
# make sure we get asked to confirm a "new scenario" operation
select_menu_option( "new_scenario" )
wait_for( 2, lambda: find_child("#ask") is not None )
elem = find_child( "#ask" )
assert "This scenario has been changed" in elem.text
# cancel the confirmation request, make sure the change we made is still there
click_dialog_button( "Cancel" )
select_tab( tab_id )
check_field( param, state )
check_is_dirty( True )
# revert the change
revert_field( param, state )
check_is_dirty( False )
# we should now be able to reset the scenario without a confirmation
_ = set_stored_msg_marker( "_last-info_" )
select_menu_option( "new_scenario" )
wait_for( 2, lambda: get_stored_msg("_last-info_") == "The scenario was reset." )
# change the field again
select_tab( tab_id )
state = change_field( param )
check_is_dirty( True )
# make sure we get asked to confirm a "load scenario" operation
select_menu_option( "load_scenario" )
wait_for( 2, lambda: find_child("#ask") is not None )
elem = find_child( "#ask" )
assert "This scenario has been changed" in elem.text
# cancel the confirmation request, make sure the change we made is still there
click_dialog_button( "Cancel" )
select_tab( tab_id )
check_field( param, state )
check_is_dirty( True )
# revert the change
revert_field( param, state )
check_is_dirty( False )
# we should be able to load a scenario without a confirmation
# NOTE: We don't do this, since it will cause the OPEN FILE dialog to come up :-/
# change each parameter, then try to reset/load the scenario
for tab_id,params in ALL_SCENARIO_PARAMS.items():
for param in params:
do_test( tab_id, param )
if pytest.config.option.short_tests: #pylint: disable=no-member
break # nb: it's a bit excessive to check *every* parameter :-/