def test_snippets( webapp, webdriver ): """Test vehicle/ordnance snippet generation in detail.""" # initialize init_webapp( webapp, webdriver ) def do_test( vo_type ): """Run the test.""" vo_type0 = vo_type[:-1] if vo_type.endswith("s") else vo_type # test a full example add_vo( webdriver, vo_type, 1, "a german {}".format(vo_type0) ) btn = find_child( "button[data-id='ob_{}_1']".format( vo_type ) ) btn.click() caps = '"XYZ" "IR" "A1" "H2"' if vo_type == "vehicles": caps += ' "CS 5"' expected = [ '[German] ; width=', '[*] a german {}: #=1'.format( vo_type0 ), '- notes: "A" "B†"', '- capabilities: {}'.format( caps ), '- raw capabilities: {}'.format( caps ), ] wait_for_clipboard( 2, "\n".join(expected) ) delete_vo( vo_type, 1, "a german {}".format(vo_type0), webdriver ) # test a partial example add_vo( webdriver, vo_type, 1, "another german {}".format(vo_type0) ) btn = find_child( "button[data-id='ob_{}_1']".format( vo_type ) ) btn.click() caps = '"XYZ"' if vo_type == "vehicles": caps += ' "<span class=\'brewup\'>cs 4</span>"' expected = [ '[German] ; width=', '[*] another german {}: #=2'.format( vo_type0 ), '- capabilities: {}'.format( caps ), '- raw capabilities: {}'.format( caps ), ] if vo_type == "vehicles": expected.insert( 2, '- notes: "<s>b</s>" "C"' ) wait_for_clipboard( 2, "\n".join(expected) ) delete_vo( vo_type, 1, "another german {}".format(vo_type0), webdriver ) # test a minimal example add_vo( webdriver, vo_type, 1, "name only" ) btn = find_child( "button[data-id='ob_{}_1']".format( vo_type ) ) btn.click() expected = [ '[German] ; width=', '[*] name only: #=', '- capabilities:', '- raw capabilities:', ] wait_for_clipboard( 2, "\n".join(expected) ) # do the test set_player( 1, "german" ) do_test( "vehicles" ) do_test( "ordnance" )
def test_variable_capabilities( webapp, webdriver ): """Test date-based variable capabilities.""" # initialize init_webapp( webapp, webdriver ) # add a vehicle add_vo( webdriver, "vehicles", 2, "Churchill III(b)" ) # change the scenario date and check the generated snippet vehicles2 = find_child( "button.generate[data-id='ob_vehicles_2']" ) def do_test( month, year, expected ): """Set the date and check the vehicle snippet.""" select_tab( "scenario" ) set_template_params( { "SCENARIO_DATE": "{:02d}/01/{}".format(month,year) } ) select_tab( "ob2" ) vehicles2.click() def reformat( clipboard ): #pylint: disable=missing-docstring mo = re.search( r"^- capabilities: (.*)$", clipboard, re.MULTILINE ) return mo.group( 1 ) wait_for_clipboard( 2, expected, transform=reformat ) do_test( 1, 1940, '"sM8\u2020" "CS 7"' ) do_test( 1, 1943, '"sM8\u2020" "CS 7"' ) do_test( 2, 1943, '"HE7\u2020" "sM8\u2020" "CS 7"' ) do_test( 12, 1943, '"HE7\u2020" "sM8\u2020" "CS 7"' ) do_test( 1, 1944, '"HE8\u2020" "sD6" "sM8\u2020" "CS 7"' ) do_test( 5, 1944, '"HE8\u2020" "sD6" "sM8\u2020" "CS 7"' ) do_test( 6, 1944, '"D6\u2020" "HE8\u2020" "sD6" "sM8\u2020" "CS 7"' ) do_test( 12, 1944, '"D6\u2020" "HE8\u2020" "sD6" "sM8\u2020" "CS 7"' ) do_test( 1, 1945, '"D7\u2020" "HE8\u2020" "sD6" "sM8\u2020" "CS 7"' ) do_test( 12, 1945, '"D7\u2020" "HE8\u2020" "sD6" "sM8\u2020" "CS 7"' ) do_test( 1, 1946, '"HE8\u2020" "sD6" "sM8\u2020" "CS 7"' )
def _do_test_ob_entries( webapp, webdriver, ob_type ): """Test generating OB setup/notes.""" # initialize init_webapp( webapp, webdriver ) sortable1 = find_child( "#{}-sortable_1".format( ob_type ) ) sortable2 = find_child( "#{}-sortable_2".format( ob_type ) ) # generate OB setup/note snippets for both players 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.""" elems = find_children( "li img.snippet", sortable ) elems[entry_no].click() if ob_type == "ob_notes": expected = re.sub( r" \(col=.*?\)", "", expected ) assert wait_for_clipboard( 2, expected, transform=adjust_html ) select_tab( "ob1" ) check_snippet( sortable1, 0, "[German] [{} #1] (col=[OBCOL:german/OBCOL-BORDER:german])".format( ob_type ) ) check_snippet( sortable1, 1, "[German] [{} #2] (col=[OBCOL:german/OBCOL-BORDER:german]) (width=[2px])".format( ob_type ) ) select_tab( "ob2" ) check_snippet( sortable2, 0, "[Russian] [<i>{}</i> #3] (col=[OBCOL:russian/OBCOL-BORDER:russian]) (width=[3px])".format( ob_type ) ) # make some changes and check the snippets again 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/OBCOL-BORDER:russian])".format( ob_type ) ) select_tab( "ob1" ) check_snippet( sortable1, 1, "[German] [<i>updated {} #2</i>] (col=[OBCOL:german/OBCOL-BORDER:german]) (width=[200px])".format( ob_type ) ) check_snippet( sortable1, 0, "[German] [{} #1] (col=[OBCOL:german/OBCOL-BORDER:german]) (width=[100px])".format( ob_type ) ) # delete an OB setup/note by dragging it into the trash 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 edit_simple_note( sortable1, 0, "", None ) assert get_sortable_entry_count( sortable1 ) == 0
def do_test(): #pylint: disable=missing-docstring # initialize webapp.control_tests.set_data_dir("{REAL}") init_webapp(webapp, webdriver, vsav_persistence=1) load_scenario_params({ "scenario": { "SCENARIO_NAME": "Player-owned labels", "SCENARIO_DATE": "01/01/1940", "PLAYER_1": "german", "PLAYER_2": "american", }, "ob1": { "OB_SETUPS_1": [{ "caption": "german setup #1" }] }, "ob2": { "OB_SETUPS_2": [{ "caption": "american setup #1" }] }, }) # update a legacy scenario (i.e. labels have *not* been tagged with their owner player nationality) # NOTE: We expect to see 4 labels updated: # - the 2 OB setup labels (they will get the new-style ID's) # - scenario (timestamp) # - players (new American player) fname = os.path.join( os.path.split(__file__)[0], "fixtures/update-vsav/player-owned-labels-legacy.vsav") updated_vsav_dump = _update_vsav_and_dump(webapp, fname, {"updated": 4}) _check_vsav_dump(updated_vsav_dump, { "german/ob_setup_1.1": "german setup #1", "american/ob_setup_2.1": "american setup #1", }, ignore=["scenario", "players", "victory_conditions"]) # update a new-style scenario (i.e. labels *have* been tagged with their owner player nationality) # NOTE: We expect to see 1 label created: # - a new American OB setup label # and 2 labels updated: # - scenario (timestamp) # - players (new American player) # The existing Russian OB setup label should be ignored and left in-place. fname = os.path.join( os.path.split(__file__)[0], "fixtures/update-vsav/player-owned-labels.vsav") updated_vsav_dump = _update_vsav_and_dump(webapp, fname, { "created": 1, "updated": 2 }) _check_vsav_dump(updated_vsav_dump, { "german/ob_setup_1.1": "german setup #1", "american/ob_setup_2.1": "american setup #1", "russian/ob_setup_2.1": "russian setup #1", }, ignore=["scenario", "players", "victory_conditions"])
def test_time_based_comments(webapp, webdriver): """Test time-based comments.""" # initialize webapp.control_tests.set_data_dir("{REAL}") init_webapp(webapp, webdriver, scenario_persistence=1) # test a "START-" time-range _test_comments("german", "vehicles", "SPW 251/10", [ (None, "PSK, else ATR"), ("12/31/1942", "| ATR |"), ("08/31/1943", "| ATR |"), ("09/01/1943", "| PSK |"), ("01/01/1944", "| PSK |"), ]) # test a "-END" time-range _test_comments("french", "ordnance", "Canon AC de 47 SA mle 37 APX", [ (None, "En Portee<sup>41+</sup>"), ("12/31/1940", "En Portee NA"), ("01/01/1941", "En Portee (Renault AGR2)"), ]) # test a "START-END" time-range _test_comments("british", "ordnance", "OQF 6-Pounder 7-cwt", [ (None, "En Portee<sup>41-8/43</sup>"), ("12/31/1940", "En Portee NA"), ("01/01/1941", "En Portee (3-ton lorry)"), ("08/01/1943", "En Portee (3-ton lorry)"), ("09/01/1943", "En Portee NA"), ("01/01/1944", "En Portee NA"), ])
def test_zip_files(webapp, webdriver): """Test loading ZIP'ed template packs.""" # initialize webapp.control_tests.set_vo_notes_dir("{TEST}") init_webapp(webapp, webdriver, template_pack_persistence=1) set_player(1, "german") set_player(2, "russian") # upload a template pack that contains a full set of templates zip_data = make_zip_from_files("full") _, marker = upload_template_pack_zip(zip_data, False) assert get_stored_msg("_last-error_") == marker # check that the uploaded templates are being used _check_snippets(webdriver, lambda tid: "Customized {}.".format(tid.upper())) # upload only part of template pack _ = upload_template_pack_zip(zip_data[:int(len(zip_data) / 2)], True) assert get_stored_msg("_last-error_").startswith("Can't unpack the ZIP:") # try uploading an empty template pack _ = upload_template_pack_zip(b"", True) assert get_stored_msg("_last-error_").startswith("Can't unpack the ZIP:")
def test_individual_files(webapp, webdriver): """Test loading individual template files.""" # initialize webapp.control_tests.set_vo_notes_dir("{TEST}") init_webapp(webapp, webdriver, template_pack_persistence=1) set_player(1, "german") set_player(2, "russian") # try uploading a customized version of each template def test_template(template_id, orig_template_id): """Test uploading a customized version of the template.""" # upload a new template _ = upload_template_pack_file(template_id + ".j2", "UPLOADED TEMPLATE", False) # make sure generating a snippet returns the new version _ = _generate_snippet(webdriver, template_id, orig_template_id) wait_for_clipboard(2, "UPLOADED TEMPLATE") for_each_template(test_template) # try uploading a template with an incorrect filename extension _ = upload_template_pack_file("filename.xyz", "UPLOADED TEMPLATE", True) assert "Invalid template extension" in get_stored_msg("_last-error_") # try uploading a template with an unknown filename _ = upload_template_pack_file("unknown.j2", "UPLOADED TEMPLATE", True) assert "Invalid template filename" in get_stored_msg("_last-error_")
def test_nationality_data(webapp, webdriver): """Test a template pack with nationality data.""" # initialize init_webapp(webapp, webdriver, template_pack_persistence=1) # select the British as player 1 player1_sel = set_player(1, "british") tab_ob1 = find_child("a[href='#tabs-ob1']") assert tab_ob1.text.strip() == "British OB" # FUDGE! player1_sel.first_selected_option.text doesn't contain the right value # if we're using jQuery selectmenu's :-/ assert get_player_nat(1) == "british" droplist_vals = get_droplist_vals_index(player1_sel) assert droplist_vals["british"] == "British" # upload a template pack that contains nationality data zip_data = make_zip_from_files("with-nationality-data") _, marker = upload_template_pack_zip(zip_data, False) assert get_stored_msg("_last-error_") == marker # check that the UI was updated correctly assert tab_ob1.text.strip() == "Poms! OB" assert get_player_nat(1) == "british" droplist_vals2 = get_droplist_vals_index(player1_sel) assert droplist_vals2["british"] == "Poms!" # check that there is a new Korean player del droplist_vals2["korean"] droplist_vals2 = { k: "British" if v == "Poms!" else v for k, v in droplist_vals2.items() } assert droplist_vals2 == droplist_vals
def do_test(enable_user_files): #pylint: disable=missing-docstring # initialize base_url = "{}/static/images".format(_get_base_url(webapp)) if remote_app_config.get("IS_CONTAINER"): # FUDGE! We test getting a file from a remote server by requesting a file from the webapp (since we know # it will be available). However, if it's running in a container, the port it needs to use to talk # to itself is not necessarily the same as the port an outside client (e.g. us) uses to talk with it, # so we need to adjust the user files base URL to reflect that. remote_base_url = "http://localhost:{}".format( remote_app_config["FLASK_PORT_NO"]) base_url = re.sub(r"http://.+?:\d+", remote_base_url, base_url) webapp.control_tests.set_user_files_dir( base_url if enable_user_files else None) init_webapp(webapp, webdriver) # try getting a user file try: url = webapp.url_for("get_user_file", path="menu.png") with urllib.request.urlopen(url) as resp: assert enable_user_files # nb: we should only get here if user files are enabled assert resp.code == 200 assert resp.read().startswith(b"\x89PNG\r\n") assert resp.headers["Content-Type"] == "image/png" except urllib.error.HTTPError as ex: assert not enable_user_files # nb: we should only get here if user files are disabled assert ex.code == 404
def test_scenario_notes_snippets(webapp, webdriver): """Test HTML snippet generation.""" # initialize init_webapp(webapp, webdriver) select_tab("scenario") 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) == adjust_html("[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 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_simple_note(sortable, 0, "", None) assert get_sortable_entry_count(sortable) == 0 # add a scenario note with non-English content and HTML special characters sortable = find_child("#scenario_notes-sortable") add_simple_note(sortable, "japan <\u65e5\u672c>", None) assert generate_sortable_entry_snippet(sortable, 0) == "[japan <\u65e5\u672c>]"
def test_french_veh_f(webapp, webdriver): """Test French Vehicle Note F.""" # initialize webapp.control_tests.set_data_dir("{REAL}") init_webapp(webapp, webdriver, scenario_persistence=1) # test an "(a)" vehicle _test_comments("french", "vehicles", "Ac de 40 CA(a)", [ (None, "American ESB+"), (None, "Black TH#"), (None, "Captured Use (unless Free French or US)"), ]) _test_comments("french", "vehicles", "AM Dodge(a)", [ (None, "Captured Use (unless Vichy French)"), ]) # test a "(b)" vehicle _test_comments("french", "vehicles", "Valentine V(b)", [ (None, "British ESB+"), (None, "Black TH#"), (None, "Captured Use (unless Vichy French or British)"), ]) # test an "(f)" vehicle _test_comments("free-french", "vehicles", "H39(f)", [ (None, "French ESB+"), (None, "Red TH#"), (None, "Captured Use (unless Free/Vichy French)"), ])
def test_roar_matching2(webapp, webdriver): """Test matching scenarios with ROAR scenarios.""" # initialize init_webapp(webapp, webdriver) from vasl_templates.webapp.scenarios import _asa_scenarios, _match_roar_scenario def do_test(scenario_name, expected): #pylint: disable=missing-docstring scenarios = [ s for s in _asa_scenarios.index.values() #pylint: disable=no-member if s.get("title") == scenario_name ] assert len(scenarios) == 1 matches = _match_roar_scenario(scenarios[0]) if not isinstance(expected, list): expected = [expected] assert [(m["roar_id"], m["name"]) for m in matches] == expected with _asa_scenarios: # check for no match do_test("Full content scenario", []) # check for an exact match do_test("ROAR Exact Match", ("200", "!! ROAR exact-match !!")) # check for multiple matches, resolved by the scenario ID do_test("ROAR Exact Match 2", ("211", "ROAR Exact Match 2")) # check for multiple matches # NOTE: These should be sorted in descending order of number of playings. do_test("ROAR Multiple Matches", [("222", "ROAR Multiple Matches"), ("220", "ROAR Multiple Matches"), ("221", "ROAR Multiple Matches")])
def do_test(): #pylint: disable=missing-docstring # initialize init_webapp(webapp, webdriver, vlog_persistence=1, lfa_persistence=1) # analyze the log file _analyze_vlogs("download-test.vlog") # download the data marker = set_stored_msg_marker("_lfa-download_") find_child("#lfa button.download").click() wait_for(2, lambda: get_stored_msg("_lfa-download_") != marker) data = get_stored_msg("_lfa-download_") # check the results data = data.split("\n") rows = list(csv.reader(data, quoting=csv.QUOTE_NONNUMERIC)) assert rows == [[ "Log file", "Phase", "Player", "Type", "Die 1", "Die 2" ], ["download-test.vlog", "", 'Joey "The Lips" Blow', "IFT", 4, 1], ["", "", 'Joey "The Lips" Blow', "IFT", 2, 5], ["", "", 'Joey "The Lips" Blow', "RS", 2, ""], ["", "UN 1 PFPh", "\u65e5\u672c Guy", "IFT", 4, 6], ["", "", "\u65e5\u672c Guy", "IFT", 2, 6], ["", "", "\u65e5\u672c Guy", "RS", 3, ""], ["", "UN 1 MPh", 'Joey "The Lips" Blow', "IFT", 2, 6], ["", "", 'Joey "The Lips" Blow', "IFT", 2, 3], ["", "", 'Joey "The Lips" Blow', "RS", 3, ""]]
def test_ma_html_notes(webapp, webdriver): """Test how we load vehicle/ordnance notes (HTML vs. PNG).""" # initialize webapp.control_tests.set_vo_notes_dir("{TEST}") init_webapp(webapp, webdriver, scenario_persistence=1) # load the test scenario load_scenario({ "PLAYER_1": "greek", "OB_VEHICLES_1": [{ "name": "PNG note" }, { "name": "HTML note" }, { "name": "PNG + HTML notes" }], }) # check the snippets _check_vo_snippets(1, "vehicles", [ ("PNG note", "vehicles/greek/note/201"), "HTML note: <table width='500'><tr><td>\nThis is an HTML vehicle note (202).\n</table>", "PNG + HTML notes: <table width='500'><tr><td>\nThis is an HTML vehicle note (203).\n</table>", ])
def test_update_ui(webapp, webdriver): """Check that the UI is updated correctly for multi-applicable notes.""" # initialize webapp.control_tests.set_vo_notes_dir("{TEST}") init_webapp(webapp, webdriver) def do_test(nat, veh_expected, ord_expected): """Do the test.""" # set the specified player set_player(1, nat) select_tab("ob1") # check that the Multi-Applicable Notes controls are visible/hidden fieldset = find_child("#tabs-ob1 fieldset[name='ob_vehicles_1']") assert find_child(".snippets-notes", fieldset).is_displayed() == veh_expected assert find_child("label[for='ob']", fieldset).is_displayed() == veh_expected fieldset = find_child("#tabs-ob1 fieldset[name='ob_ordnance_1']") assert find_child(".snippets-notes", fieldset).is_displayed() == ord_expected assert find_child("label[for='ob']", fieldset).is_displayed() == ord_expected # the OB snippet controls should always be visible assert find_child(".snippets-ob", fieldset).is_displayed() # do the tests do_test("german", True, True) do_test("russian", True, True) do_test("british", True, False) do_test("french", False, True) do_test("finnish", False, False) do_test("dutch", True, True) # nb: because they are Allied Minor do_test("romanian", True, True) # nb: because they are Axis Minor
def test_import_scenario(webapp, webdriver): """Test importing a scenario.""" # initialize init_webapp(webapp, webdriver) # import the "full" scenario dlg = _do_scenario_search("full", [1], webdriver) find_child("button.import", dlg).click() wait_for( 2, lambda: _check_scenario(SCENARIO_NAME="Full content scenario", SCENARIO_ID="FCS-1", SCENARIO_LOCATION="Some place", PLAYER_1="dutch", PLAYER_1_DESCRIPTION="1st Dutch Army", PLAYER_2="romanian", PLAYER_2_DESCRIPTION="1st Romanian Army", THEATER="PTO")) # import the "empty" scenario _unlink_scenario() dlg = _do_scenario_search("Untitled", ["no-content"], webdriver) _import_scenario_and_confirm(dlg) # NOTE: Since there are no players defined in the scenario, what's on-screen will be left unchanged. wait_for( 2, lambda: _check_scenario(SCENARIO_NAME= "Untitled scenario (#no-content)", SCENARIO_ID="", SCENARIO_LOCATION="", PLAYER_1="dutch", PLAYER_1_DESCRIPTION="", PLAYER_2="romanian", PLAYER_2_DESCRIPTION="", THEATER="ETO"))
def test_common_vo_notes2(webapp, webdriver): """Test handling of Allied/Axis Minor common vehicles/ordnance (as images).""" # initialize webapp.control_tests.set_vo_notes_dir("{TEST}") init_webapp(webapp, webdriver, scenario_persistence=1) _enable_vo_no_notes_as_images(True) # load the test scenario load_scenario({ "PLAYER_1": "greek", "OB_VEHICLES_1": [ { "name": "HTML note" }, { "name": "common allied minor vehicle" }, ], }) # check the snippets _check_vo_snippets(1, "vehicles", [ ("HTML note", "vehicles/greek/note/202"), ("common allied minor vehicle", "vehicles/allied-minor/note/101"), ])
def test_landing_craft_notes(webapp, webdriver): """Test handling of Landing Craft notes.""" # initialize webapp.control_tests.set_vo_notes_dir("{TEST}") init_webapp(webapp, webdriver, scenario_persistence=1) # load the test scenario load_scenario({ "PLAYER_1": "japanese", "OB_VEHICLES_1": [ { "name": "japanese vehicle" }, { "name": "Daihatsu" }, ], }) # check the vehicle notes _check_vo_snippets(1, "vehicles", [ "japanese vehicle: <table width='500'><tr><td>\nJapanese Vehicle Note #2.\n</table>", "Daihatsu: <table width='500'><tr><td>\nLanding Craft Note #2.\n</table>", ])
def test_loading_ssrs(webapp, webdriver): """Test loading SSR's.""" # initialize init_webapp(webapp, webdriver, scenario_persistence=1) # initialize select_tab("scenario") sortable = find_child("#ssr-sortable") def do_test(ssrs): # pylint: disable=missing-docstring load_scenario({"SSR": 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"]) # load a scenario that has more SSR's than are currently in the UI do_test(["ssr 5", "ssr 6", "ssr 7", "ssr 8"]) # load a scenario that has fewer SSR's than are currently in the UI do_test(["ssr 10", "ssr 11"]) # load a scenario that has no SSR's into a UI that has SSR's do_test([])
def test_derived_nationalities(webapp, webdriver): """Test generating V/O notes for derived nationalities.""" # initialize webapp.control_tests.set_vo_notes_dir("{TEST}") init_webapp(webapp, webdriver, scenario_persistence=1) load_scenario({ "PLAYER_1": "chinese", "OB_VEHICLES_1": [{ "name": "a chinese vehicle" }], "OB_ORDNANCE_1": [{ "name": "a chinese ordnance" }], "PLAYER_2": "chinese~gmd", "OB_VEHICLES_2": [{ "name": "a chinese vehicle" }], "OB_ORDNANCE_2": [{ "name": "a chinese ordnance" }], }) # check the snippets for the base nationality _check_vo_snippets(1, "vehicles", [("a chinese vehicle", "vehicles/chinese/note/1")]) _check_vo_snippets(1, "ordnance", [("a chinese ordnance", "ordnance/chinese/note/1")]) # check the snippets for the derived nationality _check_vo_snippets(2, "vehicles", [("a chinese vehicle", "vehicles/chinese~gmd/note/1")]) _check_vo_snippets(2, "ordnance", [("a chinese ordnance", "ordnance/chinese~gmd/note/1")])
def do_test(): #pylint: disable=missing-docstring # initialize init_webapp(webapp, webdriver, vlog_persistence=1, lfa_persistence=1) # analyze the log file _analyze_vlogs("custom-labels.vlog") # download the data marker = set_stored_msg_marker("_lfa-download_") find_child("#lfa button.download").click() wait_for(2, lambda: get_stored_msg("_lfa-download_") != marker) data = get_stored_msg("_lfa-download_") # check the results data = data.split("\n") rows = list(csv.reader(data, quoting=csv.QUOTE_NONNUMERIC)) assert rows == [[ "Log file", "Phase", "Player", "Type", "Die 1", "Die 2" ], ["custom-labels.vlog", "", "test", "Other", 5, 3], ["", "", "test", "Other", 3, ""], ["", "Custom Label 1", "test", "Other", 6, 6], ["", "", "test", "RS", 6, ""], ["", "Axis 1 PFPh", "test", "Other", 4, 4], ["", "", "test", "RS", 6, ""], ["", "Custom label 2", "test", "Other", 2, 1], ["", "", "test", "RS", 1, ""]]
def do_test(): #pylint: disable=missing-docstring # initialize init_webapp(webapp, webdriver, vlog_persistence=1, lfa_tables=1) # analyze the log file _analyze_vlogs("3d6.vlog") # check the results # IFT 6,6 # RS 2 # 3d6 3,4,1 # IFT 6,5 # TH 6,2 # 3d6 2,4,2 lfa = _get_chart_data(1) assert lfa["timePlot"] == [["", "test (5)"], ["", "12"], ["", "7"], ["", "11"], ["", "8"], ["", "6"]] _select_roll_type("3d6 (DR)") lfa = _get_chart_data() assert lfa["timePlot"] == [["", "test (2)"], ["", "7"], ["", "6"]] _select_roll_type("3d6 (dr)") lfa = _get_chart_data() assert lfa["timePlot"] == [["", "test (2)"], ["", "1"], ["", "2"]] # close the analysis window find_child("#lfa button.ui-dialog-titlebar-close").click()
def test_jinja_in(webapp, webdriver): """Test the "in" operator in Jinja templates.""" # initialize init_webapp(webapp, webdriver, edit_template_links=1) def do_test(search_for, search_in, expected): """Test the IN operator.""" # install a new template elem = find_child( "a._edit-template-link_[data-id='victory_conditions']") webdriver.execute_script("$(arguments[0]).click();", elem) elem = find_child("#edit-template textarea") elem.clear() buf = [ "{%set HELLO_WORLD = \"Hello, world!\"%}", "{%set HELLO = \"hello\"%}", "{%if " + search_for + " in " + search_in + "%} YES {%else%} NO {%endif%}" ] template = "\n".join(buf) elem.send_keys(template) elem.send_keys(Keys.ESCAPE) # process the template elem = find_child("button.generate[data-id='victory_conditions']") elem.click() wait_for_clipboard(2, "YES" if expected else "NO") # do th tests do_test('"foo"', "HELLO_WORLD", False) do_test('"O, W"', "HELLO_WORLD", True) do_test("HELLO", "HELLO_WORLD", True) do_test("HELLO", '"hello, big guy!"', True)
def test_players_snippets(webapp, webdriver): """Test HTML snippet generation.""" # initialize init_webapp(webapp, webdriver) select_tab("scenario") btn = find_child("button.generate[data-id='players']") # generate a PLAYERS snippet _test_snippet( btn, { "PLAYER_1": "french", "PLAYER_1_ELR": "1", "PLAYER_1_SAN": "2", "PLAYER_1_DESCRIPTION": "Froggy Army", "PLAYER_2": "british", "PLAYER_2_ELR": "3", "PLAYER_2_SAN": "4", "PLAYER_2_DESCRIPTION": "Barmy Army", }, "player1=[french:French] ; ELR=[1] ; SAN=[2] ; description=[Froggy Army]" \ " | player2=[british:British] ; ELR=[3] ; SAN=[4] ; description=[Barmy Army]", None ) # generate a PLAYERS snippet with both players the same nationality _test_snippet( btn, { "PLAYER_1": "british", }, "player1=[british:British] ; ELR=[1] ; SAN=[2] ; description=[]" \ " | player2=[british:British] ; ELR=[3] ; SAN=[4] ; description=[Barmy Army]", [ "Both players have the same nationality!" ], )
def test_snippet_ids(webapp, webdriver): """Check that snippet ID's are generated correctly.""" # initialize webapp.control_tests.set_data_dir("{REAL}") init_webapp(webapp, webdriver, scenario_persistence=1) # load a scenario (so that we get some sortable's) scenario_data = { "SCENARIO_NOTES": [{ "caption": "Scenario note #1" }], "OB_SETUPS_1": [{ "caption": "OB setup note #1" }], "OB_NOTES_1": [{ "caption": "OB note #1" }], "OB_SETUPS_2": [{ "caption": "OB setup note #2" }], "OB_NOTES_2": [{ "caption": "OB note #2" }], } load_scenario(scenario_data) def check_snippet(btn): """Generate a snippet and check that it has an ID.""" btn.click() wait_for_clipboard(2, "<!-- vasl-templates:id ", contains=True) def do_test(scenario_date): """Check each generated snippet has an ID.""" # configure the scenario set_scenario_date(scenario_date) # check each snippet snippet_btns = find_snippet_buttons() for tab_id, btns in snippet_btns.items(): select_tab(tab_id) for btn in btns: check_snippet(btn) # test snippets with German/Russian do_test("") do_test("10/01/1943") do_test("01/01/1944") # test snippets with British/American new_scenario() load_scenario_params( {"scenario": { "PLAYER_1": "british", "PLAYER_2": "american" }}) do_test("") do_test("11/01/1942")
def test_duplicate_vo_entries( webapp, webdriver ): """Test adding duplicate vehicles/ordnance.""" # initialize init_webapp( webapp, webdriver ) set_player( 1, "german" ) select_tab( "ob1" ) def get_available_vo_entries(): """Get the available vehicles/ordnance for selection.""" entries = find_children( "#select-vo .select2-results li" ) return [ e.text for e in entries ] def do_test( vo_type, vo_name ): #pylint: disable=missing-docstring # start to add a vehicle/ordnance add_btn = find_child( "#ob_" + vo_type + "-add_1" ) add_btn.click() assert vo_name in get_available_vo_entries() # add the vehicle/ordnance elem = find_child( ".ui-dialog .select2-search__field" ) elem.send_keys( vo_name ) elem.send_keys( Keys.RETURN ) # make sure it was added to the player's OB sortable = find_child( "#ob_" + vo_type + "-sortable_1" ) assert get_sortable_vo_names( sortable ) == [ vo_name ] # add the vehicle/ordnance, dismiss the warning add_btn.click() elem = find_child( ".ui-dialog .select2-search__field" ) elem.send_keys( vo_name ) elem.send_keys( Keys.RETURN ) elem = find_child( "#ask" ) assert "already in the OB" in elem.text click_dialog_button( "Cancel", find_child(".ui-dialog.ask") ) click_dialog_button( "Cancel" ) # make sure the player's OB is unchanged assert get_sortable_vo_names( sortable ) == [ vo_name ] # add the vehicle/ordnance, accept the warning add_btn.click() elem = find_child( ".ui-dialog .select2-search__field" ) elem.send_keys( vo_name ) elem.send_keys( Keys.RETURN ) elem = find_child( "#ask" ) assert "already in the OB" in elem.text click_dialog_button( "OK", find_child(".ui-dialog.ask") ) # make sure the vehicle/ordnance was added to the player's OB assert get_sortable_vo_names( sortable ) == [ vo_name, vo_name ] # do the test do_test( "vehicles", "a german vehicle" ) do_test( "ordnance", "name only" )
def test_online_images(webapp, webdriver): """Test using online images in VASL scenarios.""" # initialize webapp.control_tests \ .set_data_dir( "{REAL}" ) \ .set_vasl_version( "random", None ) init_webapp(webapp, webdriver, scenario_persistence=1) # load the test scenario load_scenario({ "PLAYER_1": "german", "OB_VEHICLES_1": [{ "name": "PzKpfw IVH" }], }) # configure the user settings set_user_settings({ "include-flags-in-snippets": True, "custom-list-bullets": True, "include-vasl-images-in-snippets": True, }) def do_test(snippet_id, expected1, expected2): #pylint: disable=missing-docstring # generate the snippet with online images enabled set_user_settings( {"scenario-images-source": SCENARIO_IMAGES_SOURCE_INTERNET}) btn = find_child("button[data-id='{}']".format(snippet_id)) btn.click() wait_for_clipboard(2, expected1) # generate the snippet with online images disabled set_user_settings( {"scenario-images-source": SCENARIO_IMAGES_SOURCE_THIS_PROGRAM}) btn.click() wait_for_clipboard(2, expected2) # test player flags do_test( "players", re.compile( r'<img src="http://vasl-templates.org/.+/flags/german.png"'), re.compile(r'<img src="http://[a-z0-9.]+:\d+/flags/german"')) # test custom list bullets do_test("ssr", re.compile(r'url\("http://vasl-templates.org/.+/bullet.png"\)'), re.compile(r'url\("http://[a-z0-9.]+:\d+/.+/bullet.png"\)')) # test VASL counter images select_tab("ob1") do_test( "ob_vehicles_1", re.compile( r'<img src="https://raw.githubusercontent.com/.+/ge/veh/pzivh.gif"' ), re.compile(r'<img src="http://[a-z0-9.]+:\d+/counter/2584/front"'))
def do_test(build_info_fname, build_info, expected): #pylint: disable=missing-docstring # create the test VASL extension extn_fname = _set_test_vasl_extn(webapp, build_info, build_info_fname) # reload the webapp webapp.control_tests.set_vasl_version("random", "{TEMP_DIR}") init_webapp(webapp, webdriver) expected = expected.replace("{EXTN-FNAME}", extn_fname) _check_warning_msgs(webapp, expected)
def test_include_flags_in_snippets(webapp, webdriver): """Test including flags in snippets.""" # initialize webapp.control_tests.set_data_dir("{REAL}") init_webapp(webapp, webdriver) # prepare the scenario set_player(1, "german") select_tab("ob1") sortable = find_child("#ob_setups-sortable_1") add_simple_note(sortable, "OB setup note", None) # enable "show flags in snippets" select_menu_option("user_settings") elem = find_child( ".ui-dialog.user-settings input[name='include-flags-in-snippets']") assert not elem.is_selected() elem.click() click_dialog_button("OK") _check_cookies(webdriver, "include-flags-in-snippets", True) # make sure that it took effect ob_setup_snippet_btn = find_child("li img.snippet", sortable) ob_setup_snippet_btn.click() wait_for_clipboard(2, "/flags/german", contains=True) # make sure it also affects vehicle/ordnance snippets ob_vehicles_snippet_btn = find_child( "button.generate[data-id='ob_vehicles_1']") ob_vehicles_snippet_btn.click() wait_for_clipboard(2, "/flags/german", contains=True) ob_ordnance_snippet_btn = find_child( "button.generate[data-id='ob_ordnance_1']") ob_ordnance_snippet_btn.click() wait_for_clipboard(2, "/flags/german", contains=True) # disable "show flags in snippets" select_menu_option("user_settings") elem = find_child( ".ui-dialog.user-settings input[name='include-flags-in-snippets']") assert elem.is_selected() elem.click() click_dialog_button("OK") _check_cookies(webdriver, "include-flags-in-snippets", False) # make sure that it took effect ob_setup_snippet_btn.click() wait_for_clipboard(2, "/flags/german", contains=False) # make sure it also affects vehicle/ordnance snippets ob_vehicles_snippet_btn.click() wait_for_clipboard(2, "/flags/german", contains=False) ob_ordnance_snippet_btn.click() wait_for_clipboard(2, "/flags/german", contains=False)
def test_roar_matching(webapp, webdriver): """Test matching scenarios with ROAR scenarios.""" # initialize init_webapp(webapp, webdriver) # search for the "full" scenario _do_scenario_search("full", [1], webdriver) card = _unload_scenario_card() assert card["balances"] == { "asa": [{ "name": "Dutch", "wins": 3, "percentage": 30 }, { "name": "Romanian", "wins": 7, "percentage": 70 }] } # search for the "empty" scenario _do_scenario_search("Untitled", ["no-content"], webdriver) card = _unload_scenario_card() assert "balances" not in card # search for "Fighting Withdrawal" _do_scenario_search("Withdrawal", ["2"], webdriver) card = _unload_scenario_card() assert card["balances"] == { # NOTE: The 2 sides in the ROAR balance graph should have been swapped around # to match what's in the ASL Scenario Archive. "roar": [{ "name": "Russian", "wins": 325, "percentage": 54 }, { "name": "Finnish", "wins": 279, "percentage": 46 }], "asa": [ { "name": "Russians", "wins": 78, "percentage": 58 }, # nb: the player nationality has a trailing "s" { "name": "Finnish", "wins": 56, "percentage": 42 } ] }