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
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 select_tab, find_child, find_children, click_dialog_button
from vasl_templates.webapp.tests.utils import \
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
webdriver.get( webapp.url_for( "main" ) )
colors = {
"german": "col=[OBCOL:german/OBCOL2:german]", #.format( ob_type ) ,
"russian": "col=[OBCOL:russian/OBCOL2:russian]" #.format( ob_type )
}
sortable1 = find_child( "#{}-sortable_1".format( ob_type ) )
sortable2 = find_child( "#{}-sortable_2".format( ob_type ) )
# 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."""
select_tab( "ob{}".format( player_id ) )
elems = find_children( "#{}-sortable_{} li input[type='button']".format( ob_type, player_id ) )
elems = find_children( "li input[type='button']", sortable )
elems[entry_no].click()
if ob_type == "ob_notes":
expected = re.sub( r" \(col=.*?\)", "", expected )
assert get_clipboard() == expected
_do_add_ob_entry( webdriver, 1, ob_type, "{} #1".format(ob_type), None )
_do_add_ob_entry( webdriver, 1, ob_type, "{} #2".format(ob_type), "2px" )
_do_add_ob_entry( webdriver, 2, ob_type, "<i>{}</i> #3".format(ob_type), "3px" )
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( 2, 0, "[Russian] [<i>{}</i> #3] ({}) (width=[3px])".format( ob_type, colors["russian"] ) )
select_tab( "ob1" )
check_snippet( sortable1, 0,
"[German] [{} #1] (col=[OBCOL:german/OBCOL2:german])".format( ob_type )
)
check_snippet( sortable1, 1,
"[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
_do_edit_ob_entry( webdriver, 2, ob_type, 0, "updated {} #3".format(ob_type), "" )
_do_edit_ob_entry( webdriver, 1, ob_type, 1, "<i>updated {} #2</i>".format(ob_type), "200px" )
_do_edit_ob_entry( webdriver, 1, ob_type, 0, None, "100px" )
check_snippet( 2, 0, "[Russian] [updated {} #3] ({})".format( ob_type, colors["russian"] ) )
check_snippet( 1, 1, "[German] [<i>updated {} #2</i>] ({}) (width=[200px])".format( ob_type, colors["german"] ) )
check_snippet( 1, 0, "[German] [{} #1] ({}) (width=[100px])".format( ob_type, colors["german"] ) )
edit_simple_note( sortable2, 0, "updated {} #3".format(ob_type), "" )
select_tab( "ob1" )
edit_simple_note( sortable1, 1, "<i>updated {} #2</i>".format(ob_type), "200px" )
edit_simple_note( sortable1, 0, None, "100px" )
select_tab( "ob2" )
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
def count_entries( player_id ):
"""Count the number of OB setup/notes."""
elems = find_children( "#{}-sortable_{} li".format( ob_type, player_id ) )
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
assert get_sortable_entry_count( sortable1 ) == 2
drag_sortable_entry_to_trash( sortable1, 1 )
assert get_sortable_entry_count( sortable1 ) == 1
# delete an OB setup/note by emptying its caption
_do_edit_ob_entry( webdriver, 1, ob_type, 0, "", None )
click_dialog_button( "OK" ) # nb: confirm the deletion
assert count_entries(1) == 0
edit_simple_note( sortable1, 0, "", None )
assert get_sortable_entry_count( sortable1 ) == 0
# ---------------------------------------------------------------------
@ -85,22 +95,22 @@ def test_nationality_specific( webapp, webdriver ):
nationalities = get_nationalities( webapp )
# initialize
scenario_date = find_child( "#panel-scenario input[name='SCENARIO_DATE']" )
def set_scenario_date( date ):
"""Set the scenario date."""
select_tab( "scenario" )
elem = find_child( "#panel-scenario input[name='SCENARIO_DATE']" )
elem.clear()
elem.send_keys( "{:02}/01/{:04}".format( date[1], date[0] ) )
scenario_date.clear()
scenario_date.send_keys( "{:02}/01/{:04}".format( date[1], date[0] ) )
# initialize
def check_pf_snippets():
"""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
# test snippet generation
set_scenario_date( date )
select_tab( "ob1" )
elem = find_child( "input[type='button'][data-id='pf']" )
elem.click()
pf_btn.click()
assert get_clipboard() == expected
# check if a warning was issued
last_warning = get_stored_msg( "_last-warning_" ) or ""
@ -120,12 +130,12 @@ def test_nationality_specific( webapp, webdriver ):
# initialize
def check_baz_snippets():
"""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
# test snippet generation
set_scenario_date( date )
select_tab( "ob1" )
elem = find_child( "input[type='button'][data-id='baz']" )
elem.click()
baz_btn.click()
assert get_clipboard() == expected
# check if a warning was issued
last_warning = get_stored_msg( "_last-warning_" ) or ""
@ -155,21 +165,23 @@ def test_nationality_specific( webapp, webdriver ):
"baz": [ "american", check_baz_snippets ],
"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
player1_sel = Select( find_child( "select[name='PLAYER_1']" ) )
for nat in nationalities:
# change the nationality for player 1
select_tab( "scenario" )
sel = Select(
find_child( "select[name='PLAYER_1']" )
)
sel.select_by_value( nat )
select_tab( "ob1" )
player1_sel.select_by_value( nat )
# check the nationality-specific buttons
select_tab( "ob1" )
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]:
# the button should be shown for this nationality
assert elem.is_displayed()
@ -184,51 +196,3 @@ def test_nationality_specific( webapp, webdriver ):
else:
# it should be hidden for all other nationalities
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 ):
"""Test changing players."""
@ -22,25 +13,25 @@ def test_player_change( webapp, webdriver ):
webdriver.get( webapp.url_for( "main" ) )
select_tab( "scenario" )
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
for player_no in [1,2]:
player_id = _get_player( webdriver, player_no )
elem = find_child( "#tabs .ui-tabs-nav a[href='#tabs-ob{}']".format( player_no ) )
assert elem.text.strip() == "{} OB".format( nationalities[player_id]["display_name"] )
player_id = player_sel[player_no].first_selected_option.get_attribute( "value" )
expected = "{} OB".format( nationalities[player_id]["display_name"] )
assert ob_tabs[player_no].text.strip() == expected
# change player 1
sel = Select(
find_child( "select[name='PLAYER_1']" )
)
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"] )
player_sel[1].select_by_value( "finnish" )
assert ob_tabs[1].text.strip() == "{} OB".format( nationalities["finnish"]["display_name"] )
# change player 2
sel = Select(
find_child( "select[name='PLAYER_2']" )
)
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"] )
player_sel[2].select_by_value( "japanese" )
assert ob_tabs[2].text.strip() == "{} OB".format( nationalities["japanese"]["display_name"] )

@ -4,24 +4,18 @@ import json
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 get_stored_msg, set_stored_msg, find_child, find_children
from vasl_templates.webapp.tests.utils import \
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."""
# initialize
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
scenario_params = {
"scenario": {
@ -57,7 +51,9 @@ def test_scenario_persistence( webapp, webdriver ):
"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
saved_scenario = _save_scenario()
@ -66,10 +62,8 @@ def test_scenario_persistence( webapp, webdriver ):
}
assert saved_scenario == expected
# reset the scenario
# reset the scenario and check the save results
select_menu_option( "new_scenario" )
# check the save results
data = _save_scenario()
data2 = { k: v for k,v in data.items() if v }
assert data2 == {
@ -77,27 +71,29 @@ def test_scenario_persistence( webapp, webdriver ):
"PLAYER_2": "russian", "PLAYER_2_ELR": "5", "PLAYER_2_SAN": "2",
}
# load a scenario
_load_scenario( saved_scenario )
# initialize
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:
select_tab( tab_id )
for field,val in scenario_params[tab_id].items():
if field == "SCENARIO_NOTES":
continue # nb: this requires special handling, we do it below
if field == "SSR":
continue # nb: this requires 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 ("SCENARIO_NOTES","SSR"):
continue # nb: these require special handling, we do it below
if field in ("OB_SETUPS_1","OB_SETUPS_2","OB_NOTES_1","OB_NOTES_2"):
continue # nb: these require special handling, we do it below
if field in ("VEHICLES_1","ORDNANCE_1","VEHICLES_2","ORDNANCE_2"):
continue # nb: this requires special handling, we do it below
elem = next( c for c in ( \
find_child( "{}[name='{}']".format(elem_type,field) ) \
for elem_type in ["input","textarea","select"]
) if c )
continue # nb: these require special handling, we do it below
elem = elems[ field ]
if elem.tag_name == "select":
assert Select(elem).first_selected_option.get_attribute("value") == val
else:
@ -105,16 +101,17 @@ def test_scenario_persistence( webapp, webdriver ):
select_tab( "scenario" )
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"] ]
ssrs = _get_ssrs()
assert ssrs == scenario_params["scenario"]["SSR"]
assert _get_ob_entries("ob_setups",1) == [ 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_ob_entries("ob_notes",1) == [ obs["caption"] for obs in scenario_params["ob1"]["OB_NOTES_1"] ]
assert _get_ob_entries("ob_notes",2) == [ obs["caption"] for obs in scenario_params["ob2"]["OB_NOTES_2"] ]
assert _get_vo("vehicle",1) == scenario_params["ob1"]["VEHICLES_1"]
assert _get_vo("ordnance",1) == scenario_params["ob1"]["ORDNANCE_1"]
assert _get_vo("vehicle",2) == scenario_params["ob2"]["VEHICLES_2"]
assert _get_vo("ordnance",2) == scenario_params["ob2"]["ORDNANCE_2"]
assert get_sortable_entry_text(ssrs) == scenario_params["scenario"]["SSR"]
select_tab( "ob1" )
assert get_sortable_entry_text(ob_setups1) == [ obs["caption"] for obs in scenario_params["ob1"]["OB_SETUPS_1"] ]
assert get_sortable_entry_text(ob_notes1) == [ obs["caption"] for obs in scenario_params["ob1"]["OB_NOTES_1"] ]
assert get_sortable_entry_text(vehicles1) == scenario_params["ob1"]["VEHICLES_1"]
assert get_sortable_entry_text(ordnance1) == scenario_params["ob1"]["ORDNANCE_1"]
select_tab( "ob2" )
assert get_sortable_entry_text(ob_setups2) == [ obs["caption"] for obs in scenario_params["ob2"]["OB_SETUPS_2"] ]
assert get_sortable_entry_text(ob_notes2) == [ obs["caption"] for obs in scenario_params["ob2"]["OB_NOTES_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
# initialize
sortable = find_child( "#ssr-sortable" )
def do_test( ssrs ): # pylint: disable=missing-docstring
_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
do_test( [ "ssr 1", "ssr 2" ] )
@ -176,24 +174,3 @@ def _save_scenario():
select_menu_option( "save_scenario" )
data = get_stored_msg( "scenario_persistence" )
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. """
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 get_stored_msg, dismiss_notifications, find_child, find_children
from vasl_templates.webapp.tests.utils import for_each_template, wait_for, click_dialog_button
from vasl_templates.webapp.tests.utils import \
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
webdriver.get( webapp.url_for( "main", store_msgs=1 ) )
select_tab( "scenario" )
btn = find_child( "input.generate[data-id='scenario']" )
# generate a SCENARIO snippet
_test_snippet( webdriver, "scenario", {
_test_snippet( btn, {
"SCENARIO_NAME": "my <i>cool</i> scenario",
"SCENARIO_LOCATION": "right <u>here</u>",
"SCENARIO_DATE": "01/02/1942",
@ -28,7 +29,7 @@ def test_scenario_snippets( webapp, webdriver ):
)
# generate a SCENARIO snippet with some fields missing
_test_snippet( webdriver, "scenario", {
_test_snippet( btn, {
"SCENARIO_NAME": "my scenario",
"SCENARIO_LOCATION": None,
"SCENARIO_DATE": None,
@ -38,7 +39,7 @@ def test_scenario_snippets( webapp, webdriver ):
)
# generate a SCENARIO snippet with all fields missing
_test_snippet( webdriver, "scenario", {
_test_snippet( btn, {
"SCENARIO_NAME": None,
"SCENARIO_LOCATION": None,
"SCENARIO_DATE": None,
@ -48,7 +49,7 @@ def test_scenario_snippets( webapp, webdriver ):
)
# generate a SCENARIO snippet with a snippet width
_test_snippet( webdriver, "scenario", {
_test_snippet( btn, {
"SCENARIO_NAME": "test",
"SCENARIO_LOCATION": "here",
"SCENARIO_DATE": "01/02/1942",
@ -58,7 +59,7 @@ def test_scenario_snippets( webapp, webdriver ):
None
)
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# ---------------------------------------------------------------------
def test_vc_snippets( webapp, webdriver ):
"""Test HTML snippet generation."""
@ -66,9 +67,10 @@ def test_vc_snippets( webapp, webdriver ):
# initialize
webdriver.get( webapp.url_for( "main", store_msgs=1 ) )
select_tab( "scenario" )
btn = find_child( "input.generate[data-id='victory_conditions']" )
# generate a VC snippet
_test_snippet( webdriver, "victory_conditions", {
_test_snippet( btn, {
"VICTORY_CONDITIONS": "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
_test_snippet( webdriver, "victory_conditions", {
_test_snippet( btn, {
"VICTORY_CONDITIONS": "",
},
"VC: []",
@ -84,7 +86,7 @@ def test_vc_snippets( webapp, webdriver ):
)
# generate a VC snippet with a width
_test_snippet( webdriver, "victory_conditions", {
_test_snippet( btn, {
"VICTORY_CONDITIONS": "Kill 'Em All!",
"VICTORY_CONDITIONS_WIDTH": "100px",
},
@ -92,7 +94,7 @@ def test_vc_snippets( webapp, webdriver ):
None
)
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# ---------------------------------------------------------------------
def test_scenario_notes_snippets( webapp, webdriver ):
"""Test HTML snippet generation."""
@ -102,59 +104,22 @@ def test_scenario_notes_snippets( webapp, webdriver ):
select_tab( "scenario" )
# add some scenario notes and check their snippets
def check_snippet( entry_no, expected ):
"""Check the snippet for a scenario note."""
elems = find_children( "#scenario_notes-sortable li input[type='button']" )
elems[entry_no].click()
assert get_clipboard() == expected
_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])" )
sortable = find_child( "#scenario_notes-sortable" )
add_simple_note( sortable, "scenario <i>note</i> #1", None )
add_simple_note( sortable, "scenario note #2", "100px" )
assert generate_sortable_entry_snippet( sortable, 0 ) == "[scenario <i>note</i> #1]"
assert generate_sortable_entry_snippet( sortable, 1 ) == "[scenario note #2] (width=[100px])"
# delete a scenario note by dragging it into the trash
def count_entries():
"""Count the number of scenario notes."""
elems = find_children( "#scenario_notes-sortable li" )
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
assert get_sortable_entry_count( sortable ) == 2
drag_sortable_entry_to_trash( sortable, 0 )
assert get_sortable_entry_count( sortable ) == 1
# delete scenario note by emptying its caption
_edit_scenario_note( webdriver, 0, "", None )
click_dialog_button( "OK" ) # nb: confirm the deletion
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" )
edit_simple_note( sortable, 0, "", None )
assert get_sortable_entry_count( sortable ) == 0
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# ---------------------------------------------------------------------
def test_players_snippets( webapp, webdriver ):
"""Test HTML snippet generation."""
@ -162,9 +127,10 @@ def test_players_snippets( webapp, webdriver ):
# initialize
webdriver.get( webapp.url_for( "main", store_msgs=1 ) )
select_tab( "scenario" )
btn = find_child( "input.generate[data-id='players']" )
# generate a PLAYERS snippet
_test_snippet( webdriver, "players", {
_test_snippet( btn, {
"PLAYER_1": "french",
"PLAYER_1_ELR": "1",
"PLAYER_1_SAN": "2",
@ -177,47 +143,13 @@ def test_players_snippets( webapp, webdriver ):
)
# generate a PLAYERS snippet with both players the same nationality
_test_snippet( webdriver, "players", {
_test_snippet( btn, {
"PLAYER_1": "british",
},
"player1=[british:British] ; ELR=[1] ; SAN=[2] | player2=[british:British] ; ELR=[3] ; SAN=[4]",
[ "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 ):
@ -225,6 +157,14 @@ def test_edit_templates( webapp, webdriver ):
# initialize
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
def edit_template( template_id ):
@ -257,8 +197,9 @@ def test_edit_templates( webapp, webdriver ):
edit_template( "scenario_note" )
# check that the new template is being used
_add_scenario_note( webdriver, "scenario note (ignored)", None )
elem = find_child( "#scenario_notes-sortable li input[type='button']" )
sortable = find_child( "#scenario_notes-sortable" )
add_simple_note( sortable, "scenario note (ignored)", None )
elem = find_child( "li input[type='button']", sortable )
elem.click()
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
for player_id in range(1,2+1):
add_ob_setup( webdriver, player_id, "ob setup (ignored)", None )
elem = find_child( "#ob_setups-sortable_{} li input[type='button']".format( player_id ) )
select_tab( "ob{}".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()
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
for player_id in range(1,2+1):
add_ob_note( webdriver, player_id, "ob note (ignored)", None )
elem = find_child( "#ob_notes-sortable_{} li input[type='button']".format( player_id ) )
select_tab( "ob{}".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()
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 vasl_templates.webapp.tests.utils import select_tab, find_child, find_children
from vasl_templates.webapp.tests.utils import get_clipboard, dismiss_notifications, click_dialog_button
from vasl_templates.webapp.tests.utils import \
select_tab, find_child, find_children, get_clipboard, dismiss_notifications, click_dialog_button
# ---------------------------------------------------------------------
@ -18,6 +18,7 @@ def test_ssr( webapp, webdriver ):
# initialize
expected = []
generate_snippet_btn = find_child( "input[type='button'][data-id='ssr']" )
def _add_ssr( val ):
expected.append( val )
add_ssr( webdriver, val )
@ -28,8 +29,7 @@ def test_ssr( webapp, webdriver ):
check_snippet()
def check_snippet( width=None ):
"""Check the generated SSR snippet."""
btn = find_child( "input[type='button'][data-id='ssr']" )
btn.click()
generate_snippet_btn.click()
val = "\n".join( "(*) [{}]".format(e) for e in expected )
if width:
val += "\nwidth = [{}]".format( width )
@ -77,7 +77,8 @@ def edit_ssr( webdriver, ssr_no, val ):
# locate the requested SSR and start editing it
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 ]
ActionChains(webdriver).double_click( elem ).perform()

@ -8,10 +8,9 @@ import base64
from selenium.webdriver.support.ui import Select
from vasl_templates.webapp import snippets
from vasl_templates.webapp.tests import test_ob
from vasl_templates.webapp.tests.utils import select_tab, select_menu_option, dismiss_notifications
from vasl_templates.webapp.tests.utils import get_clipboard, get_stored_msg, set_stored_msg
from vasl_templates.webapp.tests.utils import for_each_template, find_child, find_children
from vasl_templates.webapp.tests.utils import \
select_tab, select_menu_option, dismiss_notifications, get_clipboard, \
get_stored_msg, set_stored_msg, add_simple_note, 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."""
# make sure generating a snippet returns something
dismiss_notifications()
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() != ""
elem, clipboard = _generate_snippet( template_id, orig_template_id )
assert clipboard != ""
# upload a new template
fname = template_id + ".j2"
set_stored_msg( "template_pack_persistence",
@ -84,9 +69,7 @@ def test_zip_files( webapp, webdriver ):
assert get_stored_msg("_last-error_") is None
# check that the uploaded templates are being used
_check_snippets( webdriver,
lambda tid: "Customized {}.".format( tid.upper() )
)
_check_snippets( lambda tid: "Customized {}.".format( tid.upper() ) )
# upload only part of template pack
_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
# that bit of code since we're using the "template_pack_persistence" hack).
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# ---------------------------------------------------------------------
def test_new_default_template_pack( webapp, webdriver, monkeypatch ):
"""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" ) )
# check that the new templates are being used
_check_snippets( webdriver,
lambda tid: "New default {}.".format( tid.upper() )
)
_check_snippets( lambda tid: "New default {}.".format( tid.upper() ) )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# ---------------------------------------------------------------------
def test_nationality_data( webapp, webdriver ):
"""Test a template pack with nationality data."""
@ -127,15 +108,12 @@ def test_nationality_data( webapp, webdriver ):
select_tab( "scenario" )
# select the British as player 1
sel = Select(
find_child( "select[name='PLAYER_1']" )
)
sel.select_by_value( "british" )
elem = find_child( "a[href='#tabs-ob1']" )
assert elem.text.strip() == "British OB"
sel = Select( find_child( "select[name='PLAYER_1']" ) )
assert sel.first_selected_option.text == "British"
players = [ o.text for o in sel.options ]
player1_sel = Select( find_child( "select[name='PLAYER_1']" ) )
player1_sel.select_by_value( "british" )
tab_ob1 = find_child( "a[href='#tabs-ob1']" )
assert tab_ob1.text.strip() == "British OB"
assert player1_sel.first_selected_option.text == "British"
players = [ o.text for o in player1_sel.options ]
# upload a template pack that contains 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
# check that the UI was updated correctly
elem = find_child( "a[href='#tabs-ob1']" )
assert elem.text.strip() == "Poms! OB"
elem = find_child( "select[name='PLAYER_1']" )
assert Select(elem).first_selected_option.text == "Poms!"
assert tab_ob1.text.strip() == "Poms! OB"
assert player1_sel.first_selected_option.text == "Poms!"
# 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 = [ "British" if o == "Poms!" else o for o in players2 ]
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 ):
"""Generate a ZIP file."""
@ -205,6 +154,44 @@ def _make_zip_from_files( dname ):
files[fname2] = fp.read()
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 ):
"""Upload a template pack."""
set_stored_msg( "template_pack_persistence",

@ -5,8 +5,9 @@ import re
from selenium.webdriver.support.ui import Select
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 get_clipboard, click_dialog_button, dismiss_notifications
from vasl_templates.webapp.tests.utils import \
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_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 ):
"""Set the date and check the vehicle snippet."""
dismiss_notifications()
select_tab( "scenario" )
set_template_params( { "SCENARIO_DATE": "{:02d}/01/{}".format(month,year) } )
select_tab( "ob2" )
submit = find_child( "input.generate[data-id='vehicles_2']" )
submit.click()
vehicles2.click()
buf = get_clipboard()
mo = re.search( r"^- capabilities: (.*)$", buf, re.MULTILINE )
assert mo.group(1) == expected
do_test( 1, 1940, '"sM8\u2020"' )
do_test( 1, 1943, '"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 )
assert open(fname,"r",encoding="utf-8").read() == report
# ---------------------------------------------------------------------
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def get_vo_report( webapp, webdriver, nat, vo_type, year ):
"""Get a vehicle/ordnance report.

@ -4,10 +4,12 @@ import os
import urllib.request
import json
import time
import re
from PyQt5.QtWidgets import QApplication
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException
# 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 template_id in template_ids:
select_tab( tab_id )
orig_template_id = template_id
if template_id == "scenario_notes":
template_id2 = "scenario_note"
template_id = "scenario_note"
elif template_id.startswith( "ob_setup_" ):
template_id2 = "ob_setup"
template_id = "ob_setup"
elif template_id.startswith( "ob_note_" ):
template_id2 = "ob_note"
template_id = "ob_note"
elif template_id.startswith( "vehicles_" ):
template_id2 = "vehicles"
template_id = "vehicles"
elif template_id.startswith( "ordnance_" ):
template_id2 = "ordnance"
else:
template_id2 = template_id
func( template_id2, template_id )
if template_id not in ("ob_setup_2","ob_note_2","vehicles_2","ordnance_2"):
templates_to_test.remove( template_id2 )
template_id = "ordnance"
func( template_id, orig_template_id )
if orig_template_id not in ("ob_setup_2","ob_note_2","vehicles_2","ordnance_2"):
templates_to_test.remove( template_id )
# test the nationality-specific templates
# 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():
select_tab( "scenario" )
sel = Select( find_child( "select[name='PLAYER_1']" ) )
sel.select_by_value( nat )
player1_sel.select_by_value( nat )
select_tab( "ob1" )
for template_id in template_ids:
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
"""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():
# check for scenario notes (these require special handling)
if key == "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
for entry in val:
_add_scenario_note( _webdriver, entry.get("caption",""), entry.get("width","") )
add_sortable_entries( find_child("#scenario_notes-sortable"), val )
continue
# 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 )
continue
# check for OB setups (these require special handling)
if key in ("OB_SETUPS_1","OB_SETUPS_2"):
# add them in (nb: we don't consider any existing OB setup's)
from vasl_templates.webapp.tests.test_ob import add_ob_setup #pylint: disable=cyclic-import
player_id = int( key[-1] )
for entry in 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","") )
# check for OB setups/notes (these require special handling)
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/note's)
mo = re.search( r"^(.*)_(\d)$", key )
sortable = find_child( "#{}-sortable_{}".format( mo.group(1).lower(), mo.group(2) ) )
add_sortable_entries( sortable, val )
continue
# 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 ):
"""Get a message stored for us by the front-end."""
elem = find_child( "#"+msg_id )
@ -189,6 +247,7 @@ def set_stored_msg( msg_id, val ):
def find_child( sel, parent=None ):
"""Find a single child element."""
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 )
except NoSuchElementException:
return None

Loading…
Cancel
Save