Tightened up the tests.

master
Pacman Ghost 6 years ago
parent 84ca6726b5
commit d3a2e2b5a9
  1. 156
      vasl_templates/webapp/tests/test_ob.py
  2. 39
      vasl_templates/webapp/tests/test_players.py
  3. 101
      vasl_templates/webapp/tests/test_scenario_persistence.py
  4. 182
      vasl_templates/webapp/tests/test_snippets.py
  5. 11
      vasl_templates/webapp/tests/test_ssr.py
  6. 127
      vasl_templates/webapp/tests/test_template_packs.py
  7. 11
      vasl_templates/webapp/tests/test_vehicles_ordnance.py
  8. 2
      vasl_templates/webapp/tests/test_vo_reports.py
  9. 121
      vasl_templates/webapp/tests/utils.py

@ -4,10 +4,10 @@ import re
import types import types
from selenium.webdriver.support.ui import Select from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.action_chains import ActionChains
from vasl_templates.webapp.tests.utils import get_nationalities, get_clipboard, get_stored_msg from vasl_templates.webapp.tests.utils import \
from vasl_templates.webapp.tests.utils import select_tab, find_child, find_children, click_dialog_button get_nationalities, get_clipboard, get_stored_msg, select_tab, find_child, find_children, \
add_simple_note, edit_simple_note, get_sortable_entry_count, drag_sortable_entry_to_trash
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
@ -29,51 +29,61 @@ def _do_test_ob_entries( webapp, webdriver, ob_type ):
# initialize # initialize
webdriver.get( webapp.url_for( "main" ) ) webdriver.get( webapp.url_for( "main" ) )
colors = { sortable1 = find_child( "#{}-sortable_1".format( ob_type ) )
"german": "col=[OBCOL:german/OBCOL2:german]", #.format( ob_type ) , sortable2 = find_child( "#{}-sortable_2".format( ob_type ) )
"russian": "col=[OBCOL:russian/OBCOL2:russian]" #.format( ob_type )
}
# generate OB setup/note snippets for both players # generate OB setup/note snippets for both players
def check_snippet( player_id, entry_no, expected ): select_tab( "ob1" )
add_simple_note( sortable1, "{} #1".format(ob_type), None )
add_simple_note( sortable1, "{} #2".format(ob_type), "2px" )
select_tab( "ob2" )
add_simple_note( sortable2, "<i>{}</i> #3".format(ob_type), "3px" )
# check that snippets are generated correctly
def check_snippet( sortable, entry_no, expected ):
"""Generate the snippet for an OB setup/note.""" """Generate the snippet for an OB setup/note."""
select_tab( "ob{}".format( player_id ) ) elems = find_children( "li input[type='button']", sortable )
elems = find_children( "#{}-sortable_{} li input[type='button']".format( ob_type, player_id ) )
elems[entry_no].click() elems[entry_no].click()
if ob_type == "ob_notes": if ob_type == "ob_notes":
expected = re.sub( r" \(col=.*?\)", "", expected ) expected = re.sub( r" \(col=.*?\)", "", expected )
assert get_clipboard() == expected assert get_clipboard() == expected
_do_add_ob_entry( webdriver, 1, ob_type, "{} #1".format(ob_type), None ) select_tab( "ob1" )
_do_add_ob_entry( webdriver, 1, ob_type, "{} #2".format(ob_type), "2px" ) check_snippet( sortable1, 0,
_do_add_ob_entry( webdriver, 2, ob_type, "<i>{}</i> #3".format(ob_type), "3px" ) "[German] [{} #1] (col=[OBCOL:german/OBCOL2:german])".format( ob_type )
check_snippet( 1, 0, "[German] [{} #1] ({})".format( ob_type, colors["german"] ) ) )
check_snippet( 1, 1, "[German] [{} #2] ({}) (width=[2px])".format( ob_type, colors["german"] ) ) check_snippet( sortable1, 1,
check_snippet( 2, 0, "[Russian] [<i>{}</i> #3] ({}) (width=[3px])".format( ob_type, colors["russian"] ) ) "[German] [{} #2] (col=[OBCOL:german/OBCOL2:german]) (width=[2px])".format( ob_type )
)
select_tab( "ob2" )
check_snippet( sortable2, 0,
"[Russian] [<i>{}</i> #3] (col=[OBCOL:russian/OBCOL2:russian]) (width=[3px])".format( ob_type )
)
# make some changes and check the snippets again # make some changes and check the snippets again
_do_edit_ob_entry( webdriver, 2, ob_type, 0, "updated {} #3".format(ob_type), "" ) edit_simple_note( sortable2, 0, "updated {} #3".format(ob_type), "" )
_do_edit_ob_entry( webdriver, 1, ob_type, 1, "<i>updated {} #2</i>".format(ob_type), "200px" ) select_tab( "ob1" )
_do_edit_ob_entry( webdriver, 1, ob_type, 0, None, "100px" ) edit_simple_note( sortable1, 1, "<i>updated {} #2</i>".format(ob_type), "200px" )
check_snippet( 2, 0, "[Russian] [updated {} #3] ({})".format( ob_type, colors["russian"] ) ) edit_simple_note( sortable1, 0, None, "100px" )
check_snippet( 1, 1, "[German] [<i>updated {} #2</i>] ({}) (width=[200px])".format( ob_type, colors["german"] ) ) select_tab( "ob2" )
check_snippet( 1, 0, "[German] [{} #1] ({}) (width=[100px])".format( ob_type, colors["german"] ) ) check_snippet( sortable2, 0,
"[Russian] [updated {} #3] (col=[OBCOL:russian/OBCOL2:russian])".format( ob_type )
)
select_tab( "ob1" )
check_snippet( sortable1, 1,
"[German] [<i>updated {} #2</i>] (col=[OBCOL:german/OBCOL2:german]) (width=[200px])".format( ob_type )
)
check_snippet( sortable1, 0,
"[German] [{} #1] (col=[OBCOL:german/OBCOL2:german]) (width=[100px])".format( ob_type )
)
# delete an OB setup/note by dragging it into the trash # delete an OB setup/note by dragging it into the trash
def count_entries( player_id ): assert get_sortable_entry_count( sortable1 ) == 2
"""Count the number of OB setup/notes.""" drag_sortable_entry_to_trash( sortable1, 1 )
elems = find_children( "#{}-sortable_{} li".format( ob_type, player_id ) ) assert get_sortable_entry_count( sortable1 ) == 1
return len(elems)
select_tab( "ob1" )
assert count_entries(1) == 2
elems = find_children( "#{}-sortable_1 li".format( ob_type ) )
trash = find_child( "#{}-trash_1".format( ob_type ) )
ActionChains(webdriver).drag_and_drop( elems[1], trash ).perform()
assert count_entries(1) == 1
# delete an OB setup/note by emptying its caption # delete an OB setup/note by emptying its caption
_do_edit_ob_entry( webdriver, 1, ob_type, 0, "", None ) edit_simple_note( sortable1, 0, "", None )
click_dialog_button( "OK" ) # nb: confirm the deletion assert get_sortable_entry_count( sortable1 ) == 0
assert count_entries(1) == 0
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
@ -85,22 +95,22 @@ def test_nationality_specific( webapp, webdriver ):
nationalities = get_nationalities( webapp ) nationalities = get_nationalities( webapp )
# initialize # initialize
scenario_date = find_child( "#panel-scenario input[name='SCENARIO_DATE']" )
def set_scenario_date( date ): def set_scenario_date( date ):
"""Set the scenario date.""" """Set the scenario date."""
select_tab( "scenario" ) select_tab( "scenario" )
elem = find_child( "#panel-scenario input[name='SCENARIO_DATE']" ) scenario_date.clear()
elem.clear() scenario_date.send_keys( "{:02}/01/{:04}".format( date[1], date[0] ) )
elem.send_keys( "{:02}/01/{:04}".format( date[1], date[0] ) )
# initialize # initialize
def check_pf_snippets(): def check_pf_snippets():
"""Check that the PF snippets are generated correctly.""" """Check that the PF snippets are generated correctly."""
pf_btn = find_child( "input[type='button'][data-id='pf']" )
def do_test( date, expected, warning ): #pylint: disable=missing-docstring def do_test( date, expected, warning ): #pylint: disable=missing-docstring
# test snippet generation # test snippet generation
set_scenario_date( date ) set_scenario_date( date )
select_tab( "ob1" ) select_tab( "ob1" )
elem = find_child( "input[type='button'][data-id='pf']" ) pf_btn.click()
elem.click()
assert get_clipboard() == expected assert get_clipboard() == expected
# check if a warning was issued # check if a warning was issued
last_warning = get_stored_msg( "_last-warning_" ) or "" last_warning = get_stored_msg( "_last-warning_" ) or ""
@ -120,12 +130,12 @@ def test_nationality_specific( webapp, webdriver ):
# initialize # initialize
def check_baz_snippets(): def check_baz_snippets():
"""Check that the BAZ snippets are generated correctly.""" """Check that the BAZ snippets are generated correctly."""
baz_btn = find_child( "input[type='button'][data-id='baz']" )
def do_test( date, expected ): #pylint: disable=missing-docstring def do_test( date, expected ): #pylint: disable=missing-docstring
# test snippet generation # test snippet generation
set_scenario_date( date ) set_scenario_date( date )
select_tab( "ob1" ) select_tab( "ob1" )
elem = find_child( "input[type='button'][data-id='baz']" ) baz_btn.click()
elem.click()
assert get_clipboard() == expected assert get_clipboard() == expected
# check if a warning was issued # check if a warning was issued
last_warning = get_stored_msg( "_last-warning_" ) or "" last_warning = get_stored_msg( "_last-warning_" ) or ""
@ -155,21 +165,23 @@ def test_nationality_specific( webapp, webdriver ):
"baz": [ "american", check_baz_snippets ], "baz": [ "american", check_baz_snippets ],
"piat": [ "british", "piat template ; col=[OBCOL:british]/[OBCOL2:british]" ], "piat": [ "british", "piat template ; col=[OBCOL:british]/[OBCOL2:british]" ],
} }
btn_elems = {
btn: find_child( "input[type='button'][data-id='{}']".format( btn ) )
for btn in nationality_specific_buttons
}
# iterate through each nationality # iterate through each nationality
player1_sel = Select( find_child( "select[name='PLAYER_1']" ) )
for nat in nationalities: for nat in nationalities:
# change the nationality for player 1 # change the nationality for player 1
select_tab( "scenario" ) select_tab( "scenario" )
sel = Select( player1_sel.select_by_value( nat )
find_child( "select[name='PLAYER_1']" )
)
sel.select_by_value( nat )
select_tab( "ob1" )
# check the nationality-specific buttons # check the nationality-specific buttons
select_tab( "ob1" )
for button_id,expected in nationality_specific_buttons.items(): for button_id,expected in nationality_specific_buttons.items():
elem = find_child( "input[type='button'][data-id='{}']".format( button_id ) ) elem = btn_elems[ button_id ]
if nat == expected[0]: if nat == expected[0]:
# the button should be shown for this nationality # the button should be shown for this nationality
assert elem.is_displayed() assert elem.is_displayed()
@ -184,51 +196,3 @@ def test_nationality_specific( webapp, webdriver ):
else: else:
# it should be hidden for all other nationalities # it should be hidden for all other nationalities
assert not elem.is_displayed() assert not elem.is_displayed()
# ---------------------------------------------------------------------
def add_ob_setup( webdriver, player_id, caption, width ):
"""Add a new OB setup."""
_do_add_ob_entry( webdriver, player_id, "ob_setups", caption, width )
def add_ob_note( webdriver, player_id, caption, width ):
"""Add a new OB note."""
_do_add_ob_entry( webdriver, player_id, "ob_notes", caption, width )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def _do_add_ob_entry( webdriver, player_id, ob_type, caption, width ):
"""Add a new OB setup/note."""
select_tab( "ob{}".format( player_id ) )
elem = find_child( "#{}-add_{}".format( ob_type, player_id ) )
elem.click()
_do_edit_ob_entry( webdriver, player_id, ob_type, None, caption, width )
# ---------------------------------------------------------------------
def edit_ob_setup( webdriver, player_id, entry_no, caption, width ):
"""Edit an OB setup."""
_do_edit_ob_entry( webdriver, player_id, "ob_setups", entry_no, caption, width )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def _do_edit_ob_entry( webdriver, player_id, ob_type, entry_no, caption, width ):
"""Edit an OB setup/note."""
# locate the requested entry and start editing it
if entry_no is not None:
select_tab( "ob{}".format( player_id ) )
elems = find_children( "#{}-sortable_{} li".format( ob_type, player_id ) )
elem = elems[ entry_no ]
ActionChains(webdriver).double_click( elem ).perform()
# edit the OB setup/note
if caption is not None:
elem = find_child( "#edit-simple_note textarea" )
elem.clear()
elem.send_keys( caption )
if width is not None:
elem = find_child( "#edit-simple_note input[type='text']" )
elem.clear()
elem.send_keys( width )
click_dialog_button( "OK" )

@ -6,15 +6,6 @@ from vasl_templates.webapp.tests.utils import get_nationalities, select_tab, fin
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
def _get_player( webdriver, player_id ): #pylint: disable=unused-argument
"""Get the nationality of the specified player."""
sel = Select(
find_child( "select[name='PLAYER_{}']".format( player_id ) )
)
return sel.first_selected_option.get_attribute( "value" )
# ---------------------------------------------------------------------
def test_player_change( webapp, webdriver ): def test_player_change( webapp, webdriver ):
"""Test changing players.""" """Test changing players."""
@ -22,25 +13,25 @@ def test_player_change( webapp, webdriver ):
webdriver.get( webapp.url_for( "main" ) ) webdriver.get( webapp.url_for( "main" ) )
select_tab( "scenario" ) select_tab( "scenario" )
nationalities = get_nationalities( webapp ) nationalities = get_nationalities( webapp )
player_sel = {
1: Select( find_child( "select[name='PLAYER_1']" ) ),
2: Select( find_child( "select[name='PLAYER_2']" ) )
}
ob_tabs = {
1: find_child( "#tabs .ui-tabs-nav a[href='#tabs-ob1']" ),
2: find_child( "#tabs .ui-tabs-nav a[href='#tabs-ob2']" )
}
# make sure that the UI was updated correctly for the initial players # make sure that the UI was updated correctly for the initial players
for player_no in [1,2]: for player_no in [1,2]:
player_id = _get_player( webdriver, player_no ) player_id = player_sel[player_no].first_selected_option.get_attribute( "value" )
elem = find_child( "#tabs .ui-tabs-nav a[href='#tabs-ob{}']".format( player_no ) ) expected = "{} OB".format( nationalities[player_id]["display_name"] )
assert elem.text.strip() == "{} OB".format( nationalities[player_id]["display_name"] ) assert ob_tabs[player_no].text.strip() == expected
# change player 1 # change player 1
sel = Select( player_sel[1].select_by_value( "finnish" )
find_child( "select[name='PLAYER_1']" ) assert ob_tabs[1].text.strip() == "{} OB".format( nationalities["finnish"]["display_name"] )
)
sel.select_by_value( "finnish" )
elem = find_child( "#tabs .ui-tabs-nav a[href='#tabs-ob1']" )
assert elem.text.strip() == "{} OB".format( nationalities["finnish"]["display_name"] )
# change player 2 # change player 2
sel = Select( player_sel[2].select_by_value( "japanese" )
find_child( "select[name='PLAYER_2']" ) assert ob_tabs[2].text.strip() == "{} OB".format( nationalities["japanese"]["display_name"] )
)
sel.select_by_value( "japanese" )
elem = find_child( "#tabs .ui-tabs-nav a[href='#tabs-ob2']" )
assert elem.text.strip() == "{} OB".format( nationalities["japanese"]["display_name"] )

@ -4,24 +4,18 @@ import json
from selenium.webdriver.support.ui import Select from selenium.webdriver.support.ui import Select
from vasl_templates.webapp.tests.utils import set_template_params, select_tab, select_menu_option from vasl_templates.webapp.tests.utils import \
from vasl_templates.webapp.tests.utils import get_stored_msg, set_stored_msg, find_child, find_children set_template_params, select_tab, select_menu_option, get_sortable_entry_text, \
get_stored_msg, set_stored_msg, find_child, find_children
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
def test_scenario_persistence( webapp, webdriver ): def test_scenario_persistence( webapp, webdriver ): #pylint: disable=too-many-locals
"""Test loading/saving scenarios.""" """Test loading/saving scenarios."""
# initialize # initialize
webdriver.get( webapp.url_for( "main", scenario_persistence=1 ) ) webdriver.get( webapp.url_for( "main", scenario_persistence=1 ) )
# initialize
def load_scenario_fields( fields ):
"""Load the scenario fields."""
for tab_id in fields:
select_tab( tab_id )
set_template_params( fields[tab_id] )
# load the scenario fields # load the scenario fields
scenario_params = { scenario_params = {
"scenario": { "scenario": {
@ -57,7 +51,9 @@ def test_scenario_persistence( webapp, webdriver ):
"ORDNANCE_WIDTH_2": "303", "ORDNANCE_WIDTH_2": "303",
}, },
} }
load_scenario_fields( scenario_params ) for tab_id,fields in scenario_params.items():
select_tab( tab_id )
set_template_params( fields )
# save the scenario and check the results # save the scenario and check the results
saved_scenario = _save_scenario() saved_scenario = _save_scenario()
@ -66,10 +62,8 @@ def test_scenario_persistence( webapp, webdriver ):
} }
assert saved_scenario == expected assert saved_scenario == expected
# reset the scenario # reset the scenario and check the save results
select_menu_option( "new_scenario" ) select_menu_option( "new_scenario" )
# check the save results
data = _save_scenario() data = _save_scenario()
data2 = { k: v for k,v in data.items() if v } data2 = { k: v for k,v in data.items() if v }
assert data2 == { assert data2 == {
@ -77,27 +71,29 @@ def test_scenario_persistence( webapp, webdriver ):
"PLAYER_2": "russian", "PLAYER_2_ELR": "5", "PLAYER_2_SAN": "2", "PLAYER_2": "russian", "PLAYER_2_ELR": "5", "PLAYER_2_SAN": "2",
} }
# load a scenario # initialize
_load_scenario( saved_scenario ) ssrs = find_child( "#ssr-sortable" )
ob_setups1, ob_notes1 = find_child("#ob_setups-sortable_1"), find_child("#ob_notes-sortable_1")
ob_setups2, ob_notes2 = find_child("#ob_setups-sortable_2"), find_child("#ob_notes-sortable_2")
vehicles1, ordnance1 = find_child("#vehicle-sortable_1"), find_child("#ordnance-sortable_1")
vehicles2, ordnance2 = find_child("#vehicle-sortable_2"), find_child("#ordnance-sortable_2")
elems = {
c.get_attribute("name"): c
for elem_type in ("input","textarea","select") for c in find_children(elem_type)
}
# make sure the scenario was loaded into the UI correctly # load a scenario and make sure it was loaded into the UI correctly
_load_scenario( saved_scenario )
for tab_id in scenario_params: for tab_id in scenario_params:
select_tab( tab_id ) select_tab( tab_id )
for field,val in scenario_params[tab_id].items(): for field,val in scenario_params[tab_id].items():
if field == "SCENARIO_NOTES": if field in ("SCENARIO_NOTES","SSR"):
continue # nb: this requires special handling, we do it below continue # nb: these require special handling, we do it below
if field == "SSR": if field in ("OB_SETUPS_1","OB_SETUPS_2","OB_NOTES_1","OB_NOTES_2"):
continue # nb: this requires special handling, we do it below continue # nb: these require special handling, we do it below
if field in ("OB_SETUPS_1","OB_SETUPS_2"):
continue # nb: this requires special handling, we do it below
if field in ("OB_NOTES_1","OB_NOTES_2"):
continue # nb: this requires special handling, we do it below
if field in ("VEHICLES_1","ORDNANCE_1","VEHICLES_2","ORDNANCE_2"): if field in ("VEHICLES_1","ORDNANCE_1","VEHICLES_2","ORDNANCE_2"):
continue # nb: this requires special handling, we do it below continue # nb: these require special handling, we do it below
elem = next( c for c in ( \ elem = elems[ field ]
find_child( "{}[name='{}']".format(elem_type,field) ) \
for elem_type in ["input","textarea","select"]
) if c )
if elem.tag_name == "select": if elem.tag_name == "select":
assert Select(elem).first_selected_option.get_attribute("value") == val assert Select(elem).first_selected_option.get_attribute("value") == val
else: else:
@ -105,16 +101,17 @@ def test_scenario_persistence( webapp, webdriver ):
select_tab( "scenario" ) select_tab( "scenario" )
scenario_notes = [ c.text for c in find_children("#scenario_notes-sortable li") ] scenario_notes = [ c.text for c in find_children("#scenario_notes-sortable li") ]
assert scenario_notes == [ sn["caption"] for sn in scenario_params["scenario"]["SCENARIO_NOTES"] ] assert scenario_notes == [ sn["caption"] for sn in scenario_params["scenario"]["SCENARIO_NOTES"] ]
ssrs = _get_ssrs() assert get_sortable_entry_text(ssrs) == scenario_params["scenario"]["SSR"]
assert ssrs == scenario_params["scenario"]["SSR"] select_tab( "ob1" )
assert _get_ob_entries("ob_setups",1) == [ obs["caption"] for obs in scenario_params["ob1"]["OB_SETUPS_1"] ] assert get_sortable_entry_text(ob_setups1) == [ obs["caption"] for obs in scenario_params["ob1"]["OB_SETUPS_1"] ]
assert _get_ob_entries("ob_setups",2) == [ obs["caption"] for obs in scenario_params["ob2"]["OB_SETUPS_2"] ] assert get_sortable_entry_text(ob_notes1) == [ obs["caption"] for obs in scenario_params["ob1"]["OB_NOTES_1"] ]
assert _get_ob_entries("ob_notes",1) == [ obs["caption"] for obs in scenario_params["ob1"]["OB_NOTES_1"] ] assert get_sortable_entry_text(vehicles1) == scenario_params["ob1"]["VEHICLES_1"]
assert _get_ob_entries("ob_notes",2) == [ obs["caption"] for obs in scenario_params["ob2"]["OB_NOTES_2"] ] assert get_sortable_entry_text(ordnance1) == scenario_params["ob1"]["ORDNANCE_1"]
assert _get_vo("vehicle",1) == scenario_params["ob1"]["VEHICLES_1"] select_tab( "ob2" )
assert _get_vo("ordnance",1) == scenario_params["ob1"]["ORDNANCE_1"] assert get_sortable_entry_text(ob_setups2) == [ obs["caption"] for obs in scenario_params["ob2"]["OB_SETUPS_2"] ]
assert _get_vo("vehicle",2) == scenario_params["ob2"]["VEHICLES_2"] assert get_sortable_entry_text(ob_notes2) == [ obs["caption"] for obs in scenario_params["ob2"]["OB_NOTES_2"] ]
assert _get_vo("ordnance",2) == scenario_params["ob2"]["ORDNANCE_2"] assert get_sortable_entry_text(vehicles2) == scenario_params["ob2"]["VEHICLES_2"]
assert get_sortable_entry_text(ordnance2) == scenario_params["ob2"]["ORDNANCE_2"]
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
@ -126,9 +123,10 @@ def test_loading_ssrs( webapp, webdriver ):
_ = _save_scenario() # nb: force the "scenario-persistence" element to be created _ = _save_scenario() # nb: force the "scenario-persistence" element to be created
# initialize # initialize
sortable = find_child( "#ssr-sortable" )
def do_test( ssrs ): # pylint: disable=missing-docstring def do_test( ssrs ): # pylint: disable=missing-docstring
_load_scenario( { "SSR": ssrs } ) _load_scenario( { "SSR": ssrs } )
assert _get_ssrs() == ssrs assert get_sortable_entry_text(sortable) == ssrs
# load a scenario that has SSR's into a UI with no SSR's # load a scenario that has SSR's into a UI with no SSR's
do_test( [ "ssr 1", "ssr 2" ] ) do_test( [ "ssr 1", "ssr 2" ] )
@ -176,24 +174,3 @@ def _save_scenario():
select_menu_option( "save_scenario" ) select_menu_option( "save_scenario" )
data = get_stored_msg( "scenario_persistence" ) data = get_stored_msg( "scenario_persistence" )
return json.loads( data ) return json.loads( data )
def _get_ssrs():
"""Get the SSR's from the UI."""
select_tab( "scenario" )
return [ c.text for c in find_children("#ssr-sortable li") ]
def _get_ob_entries( ob_type, player_id ):
"""Get the OB setup/notes from the UI."""
select_tab( "ob{}".format( player_id ) )
return [
c.text
for c in find_children( "#{}-sortable_{} li".format( ob_type, player_id ) )
]
def _get_vo( vo_type, player_id ):
"""Get the vehicles/ordnance from the UI."""
select_tab( "ob{}".format( player_id ) )
return [
c.text
for c in find_children( "#{}-sortable_{} li".format( vo_type, player_id ) )
]

@ -1,12 +1,12 @@
""" Test HTML snippet generation. """ """ Test HTML snippet generation. """
from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
from vasl_templates.webapp.tests.test_ob import add_ob_setup, add_ob_note
from vasl_templates.webapp.tests.utils import select_tab, set_template_params, get_clipboard from vasl_templates.webapp.tests.utils import select_tab, set_template_params, get_clipboard
from vasl_templates.webapp.tests.utils import get_stored_msg, dismiss_notifications, find_child, find_children from vasl_templates.webapp.tests.utils import \
from vasl_templates.webapp.tests.utils import for_each_template, wait_for, click_dialog_button get_stored_msg, dismiss_notifications, find_child, \
for_each_template, wait_for, add_simple_note, edit_simple_note, \
get_sortable_entry_count, generate_sortable_entry_snippet, drag_sortable_entry_to_trash
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
@ -16,9 +16,10 @@ def test_scenario_snippets( webapp, webdriver ):
# initialize # initialize
webdriver.get( webapp.url_for( "main", store_msgs=1 ) ) webdriver.get( webapp.url_for( "main", store_msgs=1 ) )
select_tab( "scenario" ) select_tab( "scenario" )
btn = find_child( "input.generate[data-id='scenario']" )
# generate a SCENARIO snippet # generate a SCENARIO snippet
_test_snippet( webdriver, "scenario", { _test_snippet( btn, {
"SCENARIO_NAME": "my <i>cool</i> scenario", "SCENARIO_NAME": "my <i>cool</i> scenario",
"SCENARIO_LOCATION": "right <u>here</u>", "SCENARIO_LOCATION": "right <u>here</u>",
"SCENARIO_DATE": "01/02/1942", "SCENARIO_DATE": "01/02/1942",
@ -28,7 +29,7 @@ def test_scenario_snippets( webapp, webdriver ):
) )
# generate a SCENARIO snippet with some fields missing # generate a SCENARIO snippet with some fields missing
_test_snippet( webdriver, "scenario", { _test_snippet( btn, {
"SCENARIO_NAME": "my scenario", "SCENARIO_NAME": "my scenario",
"SCENARIO_LOCATION": None, "SCENARIO_LOCATION": None,
"SCENARIO_DATE": None, "SCENARIO_DATE": None,
@ -38,7 +39,7 @@ def test_scenario_snippets( webapp, webdriver ):
) )
# generate a SCENARIO snippet with all fields missing # generate a SCENARIO snippet with all fields missing
_test_snippet( webdriver, "scenario", { _test_snippet( btn, {
"SCENARIO_NAME": None, "SCENARIO_NAME": None,
"SCENARIO_LOCATION": None, "SCENARIO_LOCATION": None,
"SCENARIO_DATE": None, "SCENARIO_DATE": None,
@ -48,7 +49,7 @@ def test_scenario_snippets( webapp, webdriver ):
) )
# generate a SCENARIO snippet with a snippet width # generate a SCENARIO snippet with a snippet width
_test_snippet( webdriver, "scenario", { _test_snippet( btn, {
"SCENARIO_NAME": "test", "SCENARIO_NAME": "test",
"SCENARIO_LOCATION": "here", "SCENARIO_LOCATION": "here",
"SCENARIO_DATE": "01/02/1942", "SCENARIO_DATE": "01/02/1942",
@ -58,7 +59,7 @@ def test_scenario_snippets( webapp, webdriver ):
None None
) )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ---------------------------------------------------------------------
def test_vc_snippets( webapp, webdriver ): def test_vc_snippets( webapp, webdriver ):
"""Test HTML snippet generation.""" """Test HTML snippet generation."""
@ -66,9 +67,10 @@ def test_vc_snippets( webapp, webdriver ):
# initialize # initialize
webdriver.get( webapp.url_for( "main", store_msgs=1 ) ) webdriver.get( webapp.url_for( "main", store_msgs=1 ) )
select_tab( "scenario" ) select_tab( "scenario" )
btn = find_child( "input.generate[data-id='victory_conditions']" )
# generate a VC snippet # generate a VC snippet
_test_snippet( webdriver, "victory_conditions", { _test_snippet( btn, {
"VICTORY_CONDITIONS": "Kill 'Em <i>All</i>!", "VICTORY_CONDITIONS": "Kill 'Em <i>All</i>!",
}, },
"VC: [Kill 'Em <i>All</i>!]", "VC: [Kill 'Em <i>All</i>!]",
@ -76,7 +78,7 @@ def test_vc_snippets( webapp, webdriver ):
) )
# generate an empty VC snippet # generate an empty VC snippet
_test_snippet( webdriver, "victory_conditions", { _test_snippet( btn, {
"VICTORY_CONDITIONS": "", "VICTORY_CONDITIONS": "",
}, },
"VC: []", "VC: []",
@ -84,7 +86,7 @@ def test_vc_snippets( webapp, webdriver ):
) )
# generate a VC snippet with a width # generate a VC snippet with a width
_test_snippet( webdriver, "victory_conditions", { _test_snippet( btn, {
"VICTORY_CONDITIONS": "Kill 'Em All!", "VICTORY_CONDITIONS": "Kill 'Em All!",
"VICTORY_CONDITIONS_WIDTH": "100px", "VICTORY_CONDITIONS_WIDTH": "100px",
}, },
@ -92,7 +94,7 @@ def test_vc_snippets( webapp, webdriver ):
None None
) )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ---------------------------------------------------------------------
def test_scenario_notes_snippets( webapp, webdriver ): def test_scenario_notes_snippets( webapp, webdriver ):
"""Test HTML snippet generation.""" """Test HTML snippet generation."""
@ -102,59 +104,22 @@ def test_scenario_notes_snippets( webapp, webdriver ):
select_tab( "scenario" ) select_tab( "scenario" )
# add some scenario notes and check their snippets # add some scenario notes and check their snippets
def check_snippet( entry_no, expected ): sortable = find_child( "#scenario_notes-sortable" )
"""Check the snippet for a scenario note.""" add_simple_note( sortable, "scenario <i>note</i> #1", None )
elems = find_children( "#scenario_notes-sortable li input[type='button']" ) add_simple_note( sortable, "scenario note #2", "100px" )
elems[entry_no].click() assert generate_sortable_entry_snippet( sortable, 0 ) == "[scenario <i>note</i> #1]"
assert get_clipboard() == expected assert generate_sortable_entry_snippet( sortable, 1 ) == "[scenario note #2] (width=[100px])"
_add_scenario_note( webdriver, "scenario <i>note</i> #1", None )
_add_scenario_note( webdriver, "scenario note #2", "100px" )
check_snippet( 0, "[scenario <i>note</i> #1]" )
check_snippet( 1, "[scenario note #2] (width=[100px])" )
# delete a scenario note by dragging it into the trash # delete a scenario note by dragging it into the trash
def count_entries(): assert get_sortable_entry_count( sortable ) == 2
"""Count the number of scenario notes.""" drag_sortable_entry_to_trash( sortable, 0 )
elems = find_children( "#scenario_notes-sortable li" ) assert get_sortable_entry_count( sortable ) == 1
return len(elems)
assert count_entries() == 2
elems = find_children( "#scenario_notes-sortable li" )
trash = find_child( "#scenario_notes-trash" )
ActionChains(webdriver).drag_and_drop( elems[0], trash ).perform()
assert count_entries() == 1
# delete scenario note by emptying its caption # delete scenario note by emptying its caption
_edit_scenario_note( webdriver, 0, "", None ) edit_simple_note( sortable, 0, "", None )
click_dialog_button( "OK" ) # nb: confirm the deletion assert get_sortable_entry_count( sortable ) == 0
assert count_entries() == 0
def _add_scenario_note( webdriver, caption, width ): #FIXME! move to utils
"""Add a new scenario note."""
elem = find_child( "#scenario_notes-add" )
elem.click()
_edit_scenario_note( webdriver, None, caption, width )
def _edit_scenario_note( webdriver, entry_no, caption, width ): #FIXME! move to utils
"""Edit a scenario note."""
# locate the requested entry and start editing it
if entry_no is not None:
elems = find_children( "#scenario_notes-sortable li" )
elem = elems[ entry_no ]
ActionChains(webdriver).double_click( elem ).perform()
# edit the scenario note
if caption is not None:
elem = find_child( "#edit-simple_note textarea" )
elem.clear()
elem.send_keys( caption )
if width is not None:
elem = find_child( "#edit-simple_note input[type='text']" )
elem.clear()
elem.send_keys( width )
click_dialog_button( "OK" )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ---------------------------------------------------------------------
def test_players_snippets( webapp, webdriver ): def test_players_snippets( webapp, webdriver ):
"""Test HTML snippet generation.""" """Test HTML snippet generation."""
@ -162,9 +127,10 @@ def test_players_snippets( webapp, webdriver ):
# initialize # initialize
webdriver.get( webapp.url_for( "main", store_msgs=1 ) ) webdriver.get( webapp.url_for( "main", store_msgs=1 ) )
select_tab( "scenario" ) select_tab( "scenario" )
btn = find_child( "input.generate[data-id='players']" )
# generate a PLAYERS snippet # generate a PLAYERS snippet
_test_snippet( webdriver, "players", { _test_snippet( btn, {
"PLAYER_1": "french", "PLAYER_1": "french",
"PLAYER_1_ELR": "1", "PLAYER_1_ELR": "1",
"PLAYER_1_SAN": "2", "PLAYER_1_SAN": "2",
@ -177,47 +143,13 @@ def test_players_snippets( webapp, webdriver ):
) )
# generate a PLAYERS snippet with both players the same nationality # generate a PLAYERS snippet with both players the same nationality
_test_snippet( webdriver, "players", { _test_snippet( btn, {
"PLAYER_1": "british", "PLAYER_1": "british",
}, },
"player1=[british:British] ; ELR=[1] ; SAN=[2] | player2=[british:British] ; ELR=[3] ; SAN=[4]", "player1=[british:British] ; ELR=[1] ; SAN=[2] | player2=[british:British] ; ELR=[3] ; SAN=[4]",
[ "Both players have the same nationality!" ], [ "Both players have the same nationality!" ],
) )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def _test_snippet( webdriver, template_id, params, expected, expected2 ): #pylint: disable=unused-argument
"""Do a single test."""
# set the template parameters
set_template_params( params )
# generate the snippet
submit = find_child( "input.generate[data-id='{}']".format(template_id) )
submit.click()
snippet = get_clipboard()
lines = [ l.strip() for l in snippet.split("\n") ]
snippet = " | ".join( l for l in lines if l )
assert snippet == expected
# check warnings for mandatory parameters
last_warning = get_stored_msg( "_last-warning_" ) or ""
if isinstance( expected2, list):
# check for mandatory parameters
param_names = [ "scenario name", "scenario location", "scenario date" ]
for pname in param_names:
if pname in expected2:
assert pname in last_warning
else:
assert pname not in last_warning
elif isinstance(expected2, str):
# check for a specific error message
assert expected2 == last_warning
else:
# make sure there was no warning message
assert expected2 is None
assert not last_warning
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
def test_edit_templates( webapp, webdriver ): def test_edit_templates( webapp, webdriver ):
@ -225,6 +157,14 @@ def test_edit_templates( webapp, webdriver ):
# initialize # initialize
webdriver.get( webapp.url_for( "main", edit_template_links=1 ) ) webdriver.get( webapp.url_for( "main", edit_template_links=1 ) )
ob_setups = {
1: find_child( "#ob_setups-sortable_1" ),
2: find_child( "#ob_setups-sortable_2" )
}
ob_notes = {
1: find_child( "#ob_notes-sortable_1" ),
2: find_child( "#ob_notes-sortable_2" )
}
# try uploading a customized version of each template # try uploading a customized version of each template
def edit_template( template_id ): def edit_template( template_id ):
@ -257,8 +197,9 @@ def test_edit_templates( webapp, webdriver ):
edit_template( "scenario_note" ) edit_template( "scenario_note" )
# check that the new template is being used # check that the new template is being used
_add_scenario_note( webdriver, "scenario note (ignored)", None ) sortable = find_child( "#scenario_notes-sortable" )
elem = find_child( "#scenario_notes-sortable li input[type='button']" ) add_simple_note( sortable, "scenario note (ignored)", None )
elem = find_child( "li input[type='button']", sortable )
elem.click() elem.click()
assert get_clipboard() == "EDITED TEMPLATE: scenario_note" assert get_clipboard() == "EDITED TEMPLATE: scenario_note"
@ -270,8 +211,10 @@ def test_edit_templates( webapp, webdriver ):
# check that the new template is being used # check that the new template is being used
for player_id in range(1,2+1): for player_id in range(1,2+1):
add_ob_setup( webdriver, player_id, "ob setup (ignored)", None ) select_tab( "ob{}".format( player_id ) )
elem = find_child( "#ob_setups-sortable_{} li input[type='button']".format( player_id ) ) sortable = ob_setups[ player_id ]
add_simple_note( sortable, "ob setup (ignored)", None )
elem = find_child( "li input[type='button']", sortable )
elem.click() elem.click()
assert get_clipboard() == "EDITED TEMPLATE: ob_setup" assert get_clipboard() == "EDITED TEMPLATE: ob_setup"
@ -283,7 +226,40 @@ def test_edit_templates( webapp, webdriver ):
# check that the new template is being used # check that the new template is being used
for player_id in range(1,2+1): for player_id in range(1,2+1):
add_ob_note( webdriver, player_id, "ob note (ignored)", None ) select_tab( "ob{}".format( player_id ) )
elem = find_child( "#ob_notes-sortable_{} li input[type='button']".format( player_id ) ) sortable = ob_notes[ player_id ]
add_simple_note( sortable, "ob note (ignored)", None )
elem = find_child( "li input[type='button']", sortable )
elem.click() elem.click()
assert get_clipboard() == "EDITED TEMPLATE: ob_note" assert get_clipboard() == "EDITED TEMPLATE: ob_note"
# ---------------------------------------------------------------------
def _test_snippet( btn, params, expected, expected2 ):
"""Do a single test."""
# set the template parameters and generate the snippet
set_template_params( params )
btn.click()
snippet = get_clipboard()
lines = [ l.strip() for l in snippet.split("\n") ]
snippet = " | ".join( l for l in lines if l )
assert snippet == expected
# check warnings for mandatory parameters
last_warning = get_stored_msg( "_last-warning_" ) or ""
if isinstance( expected2, list):
# check for mandatory parameters
param_names = [ "scenario name", "scenario location", "scenario date" ]
for pname in param_names:
if pname in expected2:
assert pname in last_warning
else:
assert pname not in last_warning
elif isinstance(expected2, str):
# check for a specific error message
assert expected2 == last_warning
else:
# make sure there was no warning message
assert expected2 is None
assert not last_warning

@ -4,8 +4,8 @@ import html
from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.action_chains import ActionChains
from vasl_templates.webapp.tests.utils import select_tab, find_child, find_children from vasl_templates.webapp.tests.utils import \
from vasl_templates.webapp.tests.utils import get_clipboard, dismiss_notifications, click_dialog_button select_tab, find_child, find_children, get_clipboard, dismiss_notifications, click_dialog_button
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
@ -18,6 +18,7 @@ def test_ssr( webapp, webdriver ):
# initialize # initialize
expected = [] expected = []
generate_snippet_btn = find_child( "input[type='button'][data-id='ssr']" )
def _add_ssr( val ): def _add_ssr( val ):
expected.append( val ) expected.append( val )
add_ssr( webdriver, val ) add_ssr( webdriver, val )
@ -28,8 +29,7 @@ def test_ssr( webapp, webdriver ):
check_snippet() check_snippet()
def check_snippet( width=None ): def check_snippet( width=None ):
"""Check the generated SSR snippet.""" """Check the generated SSR snippet."""
btn = find_child( "input[type='button'][data-id='ssr']" ) generate_snippet_btn.click()
btn.click()
val = "\n".join( "(*) [{}]".format(e) for e in expected ) val = "\n".join( "(*) [{}]".format(e) for e in expected )
if width: if width:
val += "\nwidth = [{}]".format( width ) val += "\nwidth = [{}]".format( width )
@ -77,7 +77,8 @@ def edit_ssr( webdriver, ssr_no, val ):
# locate the requested SSR and start editing it # locate the requested SSR and start editing it
if ssr_no is not None: if ssr_no is not None:
elems = find_children( "#ssr-sortable li" ) sortable = find_child( "#ssr-sortable" )
elems = find_children( "li", sortable )
elem = elems[ ssr_no ] elem = elems[ ssr_no ]
ActionChains(webdriver).double_click( elem ).perform() ActionChains(webdriver).double_click( elem ).perform()

@ -8,10 +8,9 @@ import base64
from selenium.webdriver.support.ui import Select from selenium.webdriver.support.ui import Select
from vasl_templates.webapp import snippets from vasl_templates.webapp import snippets
from vasl_templates.webapp.tests import test_ob from vasl_templates.webapp.tests.utils import \
from vasl_templates.webapp.tests.utils import select_tab, select_menu_option, dismiss_notifications select_tab, select_menu_option, dismiss_notifications, get_clipboard, \
from vasl_templates.webapp.tests.utils import get_clipboard, get_stored_msg, set_stored_msg get_stored_msg, set_stored_msg, add_simple_note, for_each_template, find_child, find_children
from vasl_templates.webapp.tests.utils import for_each_template, find_child, find_children
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
@ -26,22 +25,8 @@ def test_individual_files( webapp, webdriver ):
"""Test uploading a customized version of the template.""" """Test uploading a customized version of the template."""
# make sure generating a snippet returns something # make sure generating a snippet returns something
dismiss_notifications() dismiss_notifications()
if template_id == "scenario_note": elem, clipboard = _generate_snippet( template_id, orig_template_id )
from vasl_templates.webapp.tests.test_snippets import _add_scenario_note assert clipboard != ""
select_tab( "scenario" )
_add_scenario_note( webdriver, "test scenario note", None )
elems = find_children( "#scenario_notes-sortable li input[type='button']" )
elem = elems[0]
elif template_id in ("ob_setup","ob_note"):
select_tab( "ob1" )
func = getattr( test_ob, "add_"+template_id )
func( webdriver, 1, "test {}".format(template_id), None )
elems = find_children( "#{}s-sortable_1 li input[type='button']".format( template_id ) )
elem = elems[0]
else:
elem = find_child( "input.generate[data-id='{}']".format( orig_template_id ) )
elem.click()
assert get_clipboard() != ""
# upload a new template # upload a new template
fname = template_id + ".j2" fname = template_id + ".j2"
set_stored_msg( "template_pack_persistence", set_stored_msg( "template_pack_persistence",
@ -84,9 +69,7 @@ def test_zip_files( webapp, webdriver ):
assert get_stored_msg("_last-error_") is None assert get_stored_msg("_last-error_") is None
# check that the uploaded templates are being used # check that the uploaded templates are being used
_check_snippets( webdriver, _check_snippets( lambda tid: "Customized {}.".format( tid.upper() ) )
lambda tid: "Customized {}.".format( tid.upper() )
)
# upload only part of template pack # upload only part of template pack
_upload_template_pack( zip_data[ : int(len(zip_data)/2) ] ) _upload_template_pack( zip_data[ : int(len(zip_data)/2) ] )
@ -100,7 +83,7 @@ def test_zip_files( webapp, webdriver ):
# "open file" dialog has finished, but before we read the file data (i.e. we don't execute # "open file" dialog has finished, but before we read the file data (i.e. we don't execute
# that bit of code since we're using the "template_pack_persistence" hack). # that bit of code since we're using the "template_pack_persistence" hack).
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ---------------------------------------------------------------------
def test_new_default_template_pack( webapp, webdriver, monkeypatch ): def test_new_default_template_pack( webapp, webdriver, monkeypatch ):
"""Test changing the default template pack.""" """Test changing the default template pack."""
@ -113,11 +96,9 @@ def test_new_default_template_pack( webapp, webdriver, monkeypatch ):
webdriver.get( webapp.url_for( "main" ) ) webdriver.get( webapp.url_for( "main" ) )
# check that the new templates are being used # check that the new templates are being used
_check_snippets( webdriver, _check_snippets( lambda tid: "New default {}.".format( tid.upper() ) )
lambda tid: "New default {}.".format( tid.upper() )
)
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ---------------------------------------------------------------------
def test_nationality_data( webapp, webdriver ): def test_nationality_data( webapp, webdriver ):
"""Test a template pack with nationality data.""" """Test a template pack with nationality data."""
@ -127,15 +108,12 @@ def test_nationality_data( webapp, webdriver ):
select_tab( "scenario" ) select_tab( "scenario" )
# select the British as player 1 # select the British as player 1
sel = Select( player1_sel = Select( find_child( "select[name='PLAYER_1']" ) )
find_child( "select[name='PLAYER_1']" ) player1_sel.select_by_value( "british" )
) tab_ob1 = find_child( "a[href='#tabs-ob1']" )
sel.select_by_value( "british" ) assert tab_ob1.text.strip() == "British OB"
elem = find_child( "a[href='#tabs-ob1']" ) assert player1_sel.first_selected_option.text == "British"
assert elem.text.strip() == "British OB" players = [ o.text for o in player1_sel.options ]
sel = Select( find_child( "select[name='PLAYER_1']" ) )
assert sel.first_selected_option.text == "British"
players = [ o.text for o in sel.options ]
# upload a template pack that contains nationality data # upload a template pack that contains nationality data
zip_data = _make_zip_from_files( "with-nationality-data" ) zip_data = _make_zip_from_files( "with-nationality-data" )
@ -143,45 +121,16 @@ def test_nationality_data( webapp, webdriver ):
assert get_stored_msg("_last-error_") is None assert get_stored_msg("_last-error_") is None
# check that the UI was updated correctly # check that the UI was updated correctly
elem = find_child( "a[href='#tabs-ob1']" ) assert tab_ob1.text.strip() == "Poms! OB"
assert elem.text.strip() == "Poms! OB" assert player1_sel.first_selected_option.text == "Poms!"
elem = find_child( "select[name='PLAYER_1']" )
assert Select(elem).first_selected_option.text == "Poms!"
# check that there is a new Korean player # check that there is a new Korean player
players2 = [ o.text for o in sel.options ] players2 = [ o.text for o in player1_sel.options ]
players2.remove( "Korean" ) players2.remove( "Korean" )
players2 = [ "British" if o == "Poms!" else o for o in players2 ] players2 = [ "British" if o == "Poms!" else o for o in players2 ]
assert players2 == players assert players2 == players
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ---------------------------------------------------------------------
def _check_snippets( webdriver, expected ):
"""Check that snippets are being generated as expected."""
def test_template( template_id, orig_template_id ):
"""Test each template."""
dismiss_notifications()
# FIXME! this code is duplicated above
if template_id == "scenario_note":
from vasl_templates.webapp.tests.test_snippets import _add_scenario_note
select_tab( "scenario" )
_add_scenario_note( webdriver, "test scenario note", None )
elems = find_children( "#scenario_notes-sortable li input[type='button']" )
elem = elems[0]
elif template_id in ("ob_setup","ob_note"):
select_tab( "ob1" )
func = getattr( test_ob, "add_"+template_id )
func( webdriver, 1, "test {}".format(template_id), None )
elems = find_children( "#{}s-sortable_1 li input[type='button']".format( template_id ) )
elem = elems[0]
else:
elem = find_child( "input.generate[data-id='{}']".format( orig_template_id ) )
elem.click()
assert get_clipboard() == expected( template_id )
for_each_template( test_template )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def _make_zip( files ): def _make_zip( files ):
"""Generate a ZIP file.""" """Generate a ZIP file."""
@ -205,6 +154,44 @@ def _make_zip_from_files( dname ):
files[fname2] = fp.read() files[fname2] = fp.read()
return _make_zip( files ) return _make_zip( files )
# ---------------------------------------------------------------------
def _check_snippets( expected ):
"""Check that snippets are being generated as expected."""
def test_template( template_id, orig_template_id ):
"""Test each template."""
dismiss_notifications()
_, clipboard = _generate_snippet( template_id, orig_template_id )
assert clipboard == expected( template_id )
for_each_template( test_template )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def _generate_snippet( template_id, orig_template_id ):
"""Generate a snippet for the specified template."""
if template_id == "scenario_note":
# create a scenario note and generate a snippet for it
sortable = find_child( "#scenario_notes-sortable" )
add_simple_note( sortable, "test scenario note", None )
elems = find_children( "li input[type='button']", sortable )
elem = elems[0]
elif template_id in ("ob_setup","ob_note"):
# create a OB setup/note and generate a snippet for it
select_tab( "ob1" )
sortable = find_child( "#{}s-sortable_1".format( template_id ) )
add_simple_note( sortable, "test {}".format(template_id), None )
elems = find_children( "#{}s-sortable_1 li input[type='button']".format( template_id ) )
elem = elems[0]
else:
# generate a snippet for the specified template
elem = find_child( "input.generate[data-id='{}']".format( orig_template_id ) )
elem.click()
return elem, get_clipboard()
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def _upload_template_pack( zip_data ): def _upload_template_pack( zip_data ):
"""Upload a template pack.""" """Upload a template pack."""
set_stored_msg( "template_pack_persistence", set_stored_msg( "template_pack_persistence",

@ -5,8 +5,9 @@ import re
from selenium.webdriver.support.ui import Select from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.action_chains import ActionChains
from vasl_templates.webapp.tests.utils import select_tab, set_template_params, find_child, find_children from vasl_templates.webapp.tests.utils import \
from vasl_templates.webapp.tests.utils import get_clipboard, click_dialog_button, dismiss_notifications select_tab, set_template_params, find_child, find_children, \
get_clipboard, click_dialog_button, dismiss_notifications
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
@ -189,18 +190,18 @@ def test_variable_capabilities( webapp, webdriver ):
# add a vehicle # add a vehicle
add_vo( "vehicle", 2, "Churchill III(b)" ) add_vo( "vehicle", 2, "Churchill III(b)" )
# change the scenario date and check the generated snippet
vehicles2 = find_child( "input.generate[data-id='vehicles_2']" )
def do_test( month, year, expected ): def do_test( month, year, expected ):
"""Set the date and check the vehicle snippet.""" """Set the date and check the vehicle snippet."""
dismiss_notifications() dismiss_notifications()
select_tab( "scenario" ) select_tab( "scenario" )
set_template_params( { "SCENARIO_DATE": "{:02d}/01/{}".format(month,year) } ) set_template_params( { "SCENARIO_DATE": "{:02d}/01/{}".format(month,year) } )
select_tab( "ob2" ) select_tab( "ob2" )
submit = find_child( "input.generate[data-id='vehicles_2']" ) vehicles2.click()
submit.click()
buf = get_clipboard() buf = get_clipboard()
mo = re.search( r"^- capabilities: (.*)$", buf, re.MULTILINE ) mo = re.search( r"^- capabilities: (.*)$", buf, re.MULTILINE )
assert mo.group(1) == expected assert mo.group(1) == expected
do_test( 1, 1940, '"sM8\u2020"' ) do_test( 1, 1940, '"sM8\u2020"' )
do_test( 1, 1943, '"sM8\u2020"' ) do_test( 1, 1943, '"sM8\u2020"' )
do_test( 2, 1943, '"HE7" "sM8\u2020"' ) do_test( 2, 1943, '"HE7" "sM8\u2020"' )

@ -75,7 +75,7 @@ def test_vo_reports( webapp, webdriver ):
fname = os.path.join( check_dir, fname ) fname = os.path.join( check_dir, fname )
assert open(fname,"r",encoding="utf-8").read() == report assert open(fname,"r",encoding="utf-8").read() == report
# --------------------------------------------------------------------- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def get_vo_report( webapp, webdriver, nat, vo_type, year ): def get_vo_report( webapp, webdriver, nat, vo_type, year ):
"""Get a vehicle/ordnance report. """Get a vehicle/ordnance report.

@ -4,10 +4,12 @@ import os
import urllib.request import urllib.request
import json import json
import time import time
import re
from PyQt5.QtWidgets import QApplication from PyQt5.QtWidgets import QApplication
from selenium.webdriver.support.ui import Select from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException
# standard templates # standard templates
@ -45,28 +47,27 @@ def for_each_template( func ): #pylint: disable=too-many-branches
for tab_id,template_ids in _STD_TEMPLATES.items(): for tab_id,template_ids in _STD_TEMPLATES.items():
for template_id in template_ids: for template_id in template_ids:
select_tab( tab_id ) select_tab( tab_id )
orig_template_id = template_id
if template_id == "scenario_notes": if template_id == "scenario_notes":
template_id2 = "scenario_note" template_id = "scenario_note"
elif template_id.startswith( "ob_setup_" ): elif template_id.startswith( "ob_setup_" ):
template_id2 = "ob_setup" template_id = "ob_setup"
elif template_id.startswith( "ob_note_" ): elif template_id.startswith( "ob_note_" ):
template_id2 = "ob_note" template_id = "ob_note"
elif template_id.startswith( "vehicles_" ): elif template_id.startswith( "vehicles_" ):
template_id2 = "vehicles" template_id = "vehicles"
elif template_id.startswith( "ordnance_" ): elif template_id.startswith( "ordnance_" ):
template_id2 = "ordnance" template_id = "ordnance"
else: func( template_id, orig_template_id )
template_id2 = template_id if orig_template_id not in ("ob_setup_2","ob_note_2","vehicles_2","ordnance_2"):
func( template_id2, template_id ) templates_to_test.remove( template_id )
if template_id not in ("ob_setup_2","ob_note_2","vehicles_2","ordnance_2"):
templates_to_test.remove( template_id2 )
# test the nationality-specific templates # test the nationality-specific templates
# NOTE: The buttons are the same on the OB1 and OB2 tabs, so we only test for player 1. # NOTE: The buttons are the same on the OB1 and OB2 tabs, so we only test for player 1.
player1_sel = Select( find_child( "select[name='PLAYER_1']" ) )
for nat,template_ids in _NAT_TEMPLATES.items(): for nat,template_ids in _NAT_TEMPLATES.items():
select_tab( "scenario" ) select_tab( "scenario" )
sel = Select( find_child( "select[name='PLAYER_1']" ) ) player1_sel.select_by_value( nat )
sel.select_by_value( nat )
select_tab( "ob1" ) select_tab( "ob1" )
for template_id in template_ids: for template_id in template_ids:
func( template_id, template_id ) func( template_id, template_id )
@ -95,14 +96,17 @@ def select_menu_option( menu_id ):
def set_template_params( params ): #pylint: disable=too-many-branches def set_template_params( params ): #pylint: disable=too-many-branches
"""Set template parameters.""" """Set template parameters."""
def add_sortable_entries( sortable, entries ):
"""Add simple notes to a sortable."""
for entry in entries:
add_simple_note( sortable, entry.get("caption",""), entry.get("width","") )
for key,val in params.items(): for key,val in params.items():
# check for scenario notes (these require special handling) # check for scenario notes (these require special handling)
if key == "SCENARIO_NOTES": if key == "SCENARIO_NOTES":
# add them in (nb: we don't consider any existing scenario notes) # add them in (nb: we don't consider any existing scenario notes)
from vasl_templates.webapp.tests.test_snippets import _add_scenario_note #pylint: disable=cyclic-import add_sortable_entries( find_child("#scenario_notes-sortable"), val )
for entry in val:
_add_scenario_note( _webdriver, entry.get("caption",""), entry.get("width","") )
continue continue
# check for SSR's (these require special handling) # check for SSR's (these require special handling)
@ -113,22 +117,12 @@ def set_template_params( params ): #pylint: disable=too-many-branches
add_ssr( _webdriver, ssr ) add_ssr( _webdriver, ssr )
continue continue
# check for OB setups (these require special handling) # check for OB setups/notes (these require special handling)
if key in ("OB_SETUPS_1","OB_SETUPS_2"): if key in ("OB_SETUPS_1","OB_SETUPS_2","OB_NOTES_1","OB_NOTES_2"):
# add them in (nb: we don't consider any existing OB setup's) # add them in (nb: we don't consider any existing OB setup/note's)
from vasl_templates.webapp.tests.test_ob import add_ob_setup #pylint: disable=cyclic-import mo = re.search( r"^(.*)_(\d)$", key )
player_id = int( key[-1] ) sortable = find_child( "#{}-sortable_{}".format( mo.group(1).lower(), mo.group(2) ) )
for entry in val: add_sortable_entries( sortable, val )
add_ob_setup( _webdriver, player_id, entry.get("caption",""), entry.get("width","") )
continue
# check for OB notes (these require special handling)
if key in ("OB_NOTES_1","OB_NOTES_2"):
from vasl_templates.webapp.tests.test_ob import add_ob_note #pylint: disable=cyclic-import
# add them in (nb: we don't consider any existing OB notes)
player_id = int( key[-1] )
for entry in val:
add_ob_note( _webdriver, player_id, entry.get("caption",""), entry.get("width","") )
continue continue
# check for vehicles/ordnance (these require special handling) # check for vehicles/ordnance (these require special handling)
@ -168,6 +162,70 @@ def get_nationalities( webapp ):
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
def add_simple_note( sortable, caption, width ):
"""Add a new simple note to a sortable."""
edit_simple_note( sortable, None, caption, width )
def edit_simple_note( sortable, entry_no, caption, width ):
"""Edit a simple note in a sortable."""
# figure out if we're creating a new entry, or editing an existing one
if entry_no is None:
# create a new entry
add_button = find_sortable_helper( sortable, "add" )
add_button.click()
else:
# edit an existing entry
elems = find_children( "li", sortable )
ActionChains(_webdriver).double_click( elems[entry_no] ).perform()
# edit the note
if caption is not None:
elem = find_child( "#edit-simple_note textarea" )
elem.clear()
elem.send_keys( caption )
if width is not None:
elem = find_child( "#edit-simple_note input[type='text']" )
elem.clear()
elem.send_keys( width )
click_dialog_button( "OK" )
if caption == "":
# an empty caption will delete the entry - confirm the deletion
click_dialog_button( "OK" )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def get_sortable_entry_text( sortable ):
"""Get the text for each entry in a sortable."""
return [ c.text for c in find_children("li", sortable) ]
def get_sortable_entry_count( sortable ):
"""Return the number of entries in a sortable."""
return len( find_children( "li", sortable ) )
def generate_sortable_entry_snippet( sortable, entry_no ):
"""Generate the snippet for a sortable entry."""
elems = find_children( "li input[type='button']", sortable )
elems[entry_no].click()
return get_clipboard()
def drag_sortable_entry_to_trash( sortable, entry_no ):
"""Draw a sortable entry to the trash."""
trash = find_sortable_helper( sortable, "trash" )
elems = find_children( "li", sortable )
ActionChains(_webdriver).drag_and_drop( elems[entry_no], trash ).perform()
def find_sortable_helper( sortable, tag ):
"""Find a sortable's helper element."""
sortable_id = sortable.get_attribute( "id" )
mo = re.search( r"^(.+)-sortable(_\d)?$", sortable_id )
helper_id = "#{}-{}".format( mo.group(1), tag )
if mo.group(2):
helper_id += mo.group(2)
return find_child( helper_id )
# ---------------------------------------------------------------------
def get_stored_msg( msg_id ): def get_stored_msg( msg_id ):
"""Get a message stored for us by the front-end.""" """Get a message stored for us by the front-end."""
elem = find_child( "#"+msg_id ) elem = find_child( "#"+msg_id )
@ -189,6 +247,7 @@ def set_stored_msg( msg_id, val ):
def find_child( sel, parent=None ): def find_child( sel, parent=None ):
"""Find a single child element.""" """Find a single child element."""
try: try:
# NOTE: I tried caching these results, but it didn't help the tests run any faster :-(
return (parent if parent else _webdriver).find_element_by_css_selector( sel ) return (parent if parent else _webdriver).find_element_by_css_selector( sel )
except NoSuchElementException: except NoSuchElementException:
return None return None

Loading…
Cancel
Save