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_comments(nat, vo_type, vo_name, vals): """Generate and check comments for a series of dates.""" # load the specified vehicle/ordnance new_scenario() load_scenario({ "PLAYER_1": nat, "OB_{}_1".format(vo_type.upper()): [{ "name": vo_name }] }) # check the generated comments for each specified date for date, expected in vals: set_scenario_date(date) select_tab("ob1") btn = find_child("button[data-id='ob_{}_1']".format(vo_type)) btn.click() if expected.startswith("!"): expected, contains = expected[1:].strip(), False else: contains = True wait_for_clipboard(2, expected, transform=_extract_comments, contains=contains)
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 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_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_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_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 test_extensions(webapp, webdriver): """Test handling of VASL counters in extensions.""" # initialize webapp.control_tests \ .set_data_dir( "{REAL}" ) \ .set_vasl_version( "random", "{REAL}" ) init_webapp(webapp, webdriver, scenario_persistence=1) # load the test scenario load_scenario({ "PLAYER_1": "russian", "OB_VEHICLES_1": [ { "id": "ru/v:078", "image_id": "f97:178/0" }, # Matilda II(b) (4FP variant) { "id": "ru/v:078", "image_id": "f97:184/0" }, # Matilda II(b) (6FP variant) { "id": "ru/v:004", "image_id": "547/0" }, # T-60 M40 (core module) { "id": "ru/v:004", "image_id": "f97:186/0" }, # T-60 M40 (KGS variant) ], }) # configure the user settings set_user_settings({ "scenario-images-source": SCENARIO_IMAGES_SOURCE_INTERNET, "include-vasl-images-in-snippets": True, }) # generate a snippet for the vehicles select_tab("ob1") btn = find_child("button[data-id='ob_vehicles_1']") btn.click() wait_for_clipboard( 2, re.compile( '<img src="http://vasl-templates.org/.+/f97/matii2-4cmg.gif"' '.+' '<img src="http://vasl-templates.org/.+/f97/matii2-6cmg.gif"' '.+' '<img src="https://raw.githubusercontent.com/.+/ru/veh/T60M40.gif"' '.+' '<img src="http://vasl-templates.org/.+/f97/T60M40.gif"', re.DOTALL))
def test_multiple_images(webapp, webdriver): """Test handling of VASL counters that have multiple images.""" # 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": "british", "OB_VEHICLES_1": [{ "name": "2pdr Portee" }], }) # configure the user settings set_user_settings({ "scenario-images-source": SCENARIO_IMAGES_SOURCE_INTERNET, "include-vasl-images-in-snippets": True, }) # generate a snippet for the vehicle (using the default image) select_tab("ob1") btn = find_child("button[data-id='ob_vehicles_1']") btn.click() wait_for_clipboard( 2, re.compile( r'<img src="https://raw.githubusercontent.com/.+/br/vehicles/portee.gif"' )) # select the second image for the vehicle sortable = find_child("#ob_vehicles-sortable_1") elems = find_children("li", sortable) assert len(elems) == 1 ActionChains(webdriver).double_click(elems[0]).perform() btn = wait_for_elem(2, "#edit-vo input.select-vo-image") btn.click() images = find_children(".ui-dialog.select-vo-image .vo-images img") assert len(images) == 2 images[1].click() click_dialog_button("OK") # generate a snippet for the vehicle (using the new image) btn = find_child("button[data-id='ob_vehicles_1']") btn.click() wait_for_clipboard( 2, re.compile( r'<img src="https://raw.githubusercontent.com/.+/br/vehicles/portee0.gif"' ))
def test_common_vo_notes(webapp, webdriver): """Test handling of Allied/Axis Minor common vehicles/ordnance.""" # initialize webapp.control_tests.set_vo_notes_dir("{TEST}") init_webapp(webapp, webdriver, scenario_persistence=1) # load the test scenario load_scenario({ "PLAYER_1": "dutch", "OB_VEHICLES_1": [{ "name": "dutch vehicle" }, { "name": "common allied minor vehicle" }], "OB_ORDNANCE_1": [{ "name": "dutch ordnance" }, { "name": "common allied minor ordnance" }], "PLAYER_2": "romanian", "OB_VEHICLES_2": [{ "name": "romanian vehicle" }, { "name": "common axis minor vehicle" }], "OB_ORDNANCE_2": [{ "name": "romanian ordnance" }, { "name": "common axis minor ordnance" }], }) # check the snippets _check_vo_snippets(1, "vehicles", [ ("dutch vehicle", "vehicles/dutch/note/1"), ("common allied minor vehicle", "vehicles/allied-minor/note/101"), ]) _check_vo_snippets(1, "ordnance", [ ("dutch ordnance", "ordnance/dutch/note/2"), ("common allied minor ordnance", "ordnance/allied-minor/note/102"), ]) _check_vo_snippets(2, "vehicles", [ ("romanian vehicle", "vehicles/romanian/note/3"), ("common axis minor vehicle", "vehicles/axis-minor/note/103"), ]) _check_vo_snippets(2, "ordnance", [ ("romanian ordnance", "ordnance/romanian/note/4"), ("common axis minor ordnance", "ordnance/axis-minor/note/104"), ])
def test_vo_notes_as_images(webapp, webdriver): """Test showing vehicle/ordnance notes as HTML/images.""" # initialize webapp.control_tests.set_vo_notes_dir("{TEST}") init_webapp(webapp, webdriver, scenario_persistence=1) # load the test vehicle load_scenario({ "PLAYER_1": "greek", "OB_VEHICLES_1": [{ "name": "HTML note" }], }) select_tab("ob1") def check_snippet(expected): """Generate and check the vehicle note snippet.""" sortable = find_child("#ob_vehicles-sortable_1") elems = find_children("li", sortable) assert len(elems) == 1 btn = find_child("img.snippet", elems[0]) btn.click() contains = True if isinstance(expected, str) else None wait_for_clipboard(2, expected, contains=contains) # generate the vehicle snippet (should get the raw HTML) check_snippet("This is an HTML vehicle note (202).") # enable "show vehicle/ordnance notes as images" select_menu_option("user_settings") elem = find_child( ".ui-dialog.user-settings input[name='vo-notes-as-images']") assert not elem.is_selected() elem.click() click_dialog_button("OK") _check_cookies(webdriver, "vo-notes-as-images", True) # generate the vehicle snippet (should get a link to return an image) check_snippet(re.compile(r"http://.+?:\d+/vehicles/greek/note/202")) # disable "show vehicle/ordnance notes as images" select_menu_option("user_settings") elem = find_child( ".ui-dialog.user-settings input[name='vo-notes-as-images']") assert elem.is_selected() elem.click() click_dialog_button("OK") _check_cookies(webdriver, "vo-notes-as-images", False) # generate the vehicle snippet (should get the raw HTML) check_snippet("This is an HTML vehicle note (202).")
def init_test(): # initialize the webapp init_webapp(webapp, webdriver, scenario_persistence=1) _enable_vo_no_notes_as_images(True) # load the test scenario load_scenario({ "PLAYER_1": "japanese", "OB_VEHICLES_1": [ { "name": "japanese vehicle" }, ], })
def do_test(player_no, nat, vo_type, vo_entries, expected): """Load the specified vehicles and check the resulting snippet.""" load_scenario({ "PLAYER_{}".format(player_no): nat, "OB_{}_{}".format(vo_type.upper(), player_no): [{ "name": v } for v in vo_entries], }) select_tab("ob{}".format(player_no)) btn = find_child("button.generate[data-id='ob_{}_ma_notes_{}']".format( vo_type, player_no)) btn.click() wait_for_clipboard(2, expected, transform=extract_ma_note_keys)
def test_hide_unavailable_ma_notes(webapp, webdriver): """Test showing/hiding unavailable multi-applicable notes.""" # initialize webapp.control_tests.set_vo_notes_dir("{TEST}") init_webapp(webapp, webdriver, scenario_persistence=1) # load the test vehicle load_scenario({ "PLAYER_1": "german", "OB_VEHICLES_1": [{ "name": "missing multi-applicable note" }] }) select_tab("ob1") def test_ma_notes(ma_note_q_present): #pylint: disable=missing-docstring expected = [("A", 'German Multi-Applicable Vehicle Note "A".')] if ma_note_q_present: expected.append(("Q", "Unavailable.")) btn = find_child("button[data-id='ob_vehicles_ma_notes_1']") btn.click() wait_for_clipboard(2, expected, transform=extract_ma_notes) # generate the multi-applicable notes test_ma_notes(True) # enable "hide unavailable multi-applicable notes" select_menu_option("user_settings") elem = find_child( ".ui-dialog.user-settings input[name='hide-unavailable-ma-notes']") assert not elem.is_selected() elem.click() click_dialog_button("OK") _check_cookies(webdriver, "hide-unavailable-ma-notes", True) # generate the multi-applicable notes test_ma_notes(False) # disable "hide unavailable multi-applicable notes" select_menu_option("user_settings") elem = find_child( ".ui-dialog.user-settings input[name='hide-unavailable-ma-notes']") assert elem.is_selected() elem.click() click_dialog_button("OK") _check_cookies(webdriver, "hide-unavailable-ma-notes", False) # generate the multi-applicable notes test_ma_notes(True)
def test_vo_notes(webapp, webdriver): """Test generating snippets for vehicle/ordnance 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": "german", "OB_VEHICLES_1": [{ "name": "a german vehicle" }, { "name": "another german vehicle" }], "OB_ORDNANCE_1": [{ "name": "a german ordnance" }, { "name": "another german ordnance" }], "PLAYER_2": "russian", "OB_VEHICLES_2": [{ "name": "a russian vehicle" }, { "name": "another russian vehicle" }], "OB_ORDNANCE_2": [{ "name": "a russian ordnance" }, { "name": "another russian ordnance" }], }) # check the snippets _check_vo_snippets(1, "vehicles", [("a german vehicle", "vehicles/german/note/1"), None]) _check_vo_snippets(1, "ordnance", [("a german ordnance", "ordnance/german/note/1"), None]) _check_vo_snippets( 2, "vehicles", [("a russian vehicle", "vehicles/russian/note/1"), None]) _check_vo_snippets( 2, "ordnance", [("a russian ordnance", "ordnance/russian/note/1"), None])
def check(asa_id): """Check the current state of the scenario.""" # check that the ASL Scenario Archive scenario ID has been set wait_for(2, lambda: get_asa_id() == asa_id) # check that the ASL Scenario Archive scenario ID is saved correctly saved_scenario = save_scenario() assert saved_scenario["ASA_ID"] == asa_id # reset the scenario new_scenario() assert get_asa_id() == "" # check that the ASL Scenario Archive scenario ID is loaded correctly load_scenario(saved_scenario) assert get_asa_id() == asa_id
def do_test(vasl_version, valid_images): """Do the test.""" # initialize (using the specified version of VASL) webapp.control_tests \ .set_data_dir( "{REAL}" ) \ .set_vasl_version( vasl_version, None ) init_webapp(webapp, webdriver, scenario_persistence=1) load_scenario(scenario_data) # check that the German vehicles loaded correctly select_tab("ob1") vehicles_sortable = find_child("#ob_vehicles-sortable_1") entries = find_children("li", vehicles_sortable) assert len(entries) == 2 check_entry(entries[0], "/counter/2542/front", True) check_entry(entries[1], "/counter/7124/front/0", valid_images) # check that the American ordnance loaded correctly select_tab("ob2") vehicles_sortable = find_child("#ob_ordnance-sortable_2") entries = find_children("li", vehicles_sortable) assert len(entries) == 1 check_entry(entries[0], "/counter/879/front", valid_images)
def test_invalid_vo_image_ids( webapp, webdriver ): """Test loading scenarios that contain invalid V/O image ID's.""" # initialize init_webapp( webapp, webdriver, scenario_persistence=1 ) # test each save file dname = os.path.join( os.path.split(__file__)[0], "fixtures/invalid-vo-image-ids" ) for root,_,fnames in os.walk(dname): for fname in fnames: fname = os.path.join( root, fname ) if os.path.splitext( fname )[1] != ".json": continue # load the next scenario, make sure a warning was issued for the V/O image ID with open( fname, "r", encoding="utf-8" ) as fp: data = json.load( fp ) set_stored_msg_marker( "_last-warning_" ) load_scenario( data ) last_warning = get_stored_msg( "_last-warning_" ) assert "Invalid V/O image ID" in last_warning
def test_special_cases(webapp, webdriver): """Test special cases.""" # initialize webapp.control_tests.set_vo_notes_dir("{TEST}") init_webapp(webapp, webdriver, scenario_persistence=1) # check that Italian Multi-Applicable Ordnance (only) Note R has a line-through load_scenario({ "PLAYER_1": "italian", "OB_ORDNANCE_1": [{ "name": "Cannone-aa da 90/53" }], "OB_VEHICLES_1": [{ "name": "SMV L40 47/32" }], }) select_tab("ob1") btn = find_child("button.generate[data-id='ob_ordnance_ma_notes_1']") btn.click() wait_for_clipboard(2, ["N", "<s>R</s>"], transform=extract_ma_note_keys) btn = find_child("button.generate[data-id='ob_vehicles_ma_notes_1']") btn.click() wait_for_clipboard(2, ["N", "R"], transform=extract_ma_note_keys)
def test_elite( webapp, webdriver ): #pylint: disable=too-many-statements """Test elite vehicles/ordnance.""" # initialize webapp.control_tests.set_data_dir( "{REAL}" ) init_webapp( webapp, webdriver, scenario_persistence=1 ) def get_sortable_elem(): """Find the sortable element for the test vehicle.""" sortable = find_child( "#ob_vehicles-sortable_1" ) elems = find_children( "li", sortable ) assert len(elems) == 1 return elems[0] def check_elite( expected, custom ): """Check the elite status of the vehicle in the main UI.""" vo_name = find_child( ".vo-name", get_sortable_elem() ).text caps = [ c.text for c in find_children(".vo-capability",get_sortable_elem()) ] if expected: assert vo_name.endswith( "\u24ba" ) expected = [ "H9", "s10", "sD7", "CS 5" ] if custom: expected.append( "HE11" ) assert caps == expected else: assert "\u24ba" not in vo_name expected = [ "H8", "s9", "sD7", "CS 5" ] if custom: expected.append( "HE10" ) assert caps == expected def check_elite2( expected, custom ): """Check the elite status of the vehicle in the edit dialog.""" vo_name = find_child( "#edit-vo .header .vo-name" ).text caps = [ c.get_attribute("value") for c in find_children("#vo_capabilities-sortable input[type='text']") ] if expected: assert vo_name.endswith( "\u24ba" ) expected = [ "H9", "s10", "sD7", "CS 5" ] if custom: expected.append( "HE11" ) assert caps == expected else: assert "\u24ba" not in vo_name expected = [ "H8", "s9", "sD7", "CS 5" ] if custom: expected.append( "HE10" ) assert caps == expected # load the scenario scenario_data = { "PLAYER_1": "german", "OB_VEHICLES_1": [ { "name": "PSW 233" } ], # H8 s9 sD7 CS 5 } load_scenario( scenario_data ) select_tab( "ob1" ) # check that the vehicle was loaded non-elite check_elite( False, False ) # add a custom capability ActionChains( webdriver ).double_click( get_sortable_elem() ).perform() elem = find_child( "#vo_capabilities-add" ) elem.click() elems = find_children( "#vo_capabilities-sortable input[type='text']" ) assert len(elems) == 5 elems[4].send_keys( "HE10" ) click_dialog_button( "OK" ) # make the vehicle elite ActionChains( webdriver ).double_click( get_sortable_elem() ).perform() check_elite2( False, True ) elem = find_child( "#edit-vo .capabilities .elite" ) elem.click() check_elite2( True, True ) click_dialog_button( "OK" ) check_elite( True, True ) # save the scenario, then reload it saved_scenario = save_scenario() assert len(saved_scenario["OB_VEHICLES_1"]) == 1 assert saved_scenario["OB_VEHICLES_1"][0]["elite"] assert saved_scenario["OB_VEHICLES_1"][0]["custom_capabilities"] == \ [ "H9", "s10", "sD7", "CS 5", "HE11" ] select_menu_option( "new_scenario" ) load_scenario( saved_scenario ) select_tab( "ob1" ) check_elite( True, True ) # make the vehicle non-elite ActionChains( webdriver ).double_click( get_sortable_elem() ).perform() check_elite2( True, True ) elem = find_child( "#edit-vo .capabilities .elite" ) elem.click() check_elite2( False, True ) click_dialog_button( "OK" ) check_elite( False, True ) # save the scenario saved_scenario = save_scenario() assert len(saved_scenario["OB_VEHICLES_1"]) == 1 assert "elite" not in saved_scenario["OB_VEHICLES_1"][0] assert saved_scenario["OB_VEHICLES_1"][0]["custom_capabilities"] == \ [ "H8", "s9", "sD7", "CS 5", "HE10" ] # make the vehicle elite, remove the custom capability ActionChains( webdriver ).double_click( get_sortable_elem() ).perform() check_elite2( False, True ) elem = find_child( "#edit-vo .capabilities .elite" ) elem.click() check_elite2( True, True ) elems = find_children( "#vo_capabilities-sortable li" ) webdriver.execute_script( "arguments[0].scrollIntoView(true);", elems[4] ) ActionChains( webdriver ).key_down( Keys.CONTROL ).click( elems[4] ).perform() ActionChains( webdriver ).key_up( Keys.CONTROL ).perform() click_dialog_button( "OK" ) check_elite( True, False ) # save the scenario, then reload it saved_scenario = save_scenario() assert len(saved_scenario["OB_VEHICLES_1"]) == 1 assert saved_scenario["OB_VEHICLES_1"][0]["elite"] assert saved_scenario["OB_VEHICLES_1"][0]["custom_capabilities"] == [ "H9", "s10", "sD7", "CS 5" ] select_menu_option( "new_scenario" ) load_scenario( saved_scenario ) select_tab( "ob1" ) check_elite( True, False ) # make the vehicle non-elite ActionChains( webdriver ).double_click( get_sortable_elem() ).perform() check_elite2( True, False ) elem = find_child( "#edit-vo .capabilities .elite" ) elem.click() check_elite2( False, False ) click_dialog_button( "OK" ) check_elite( False, False ) # save the scenario saved_scenario = save_scenario() assert len(saved_scenario["OB_VEHICLES_1"]) == 1 assert "elite" not in saved_scenario["OB_VEHICLES_1"][0] assert "custom_capabilities" not in saved_scenario["OB_VEHICLES_1"][0]
def test_capability_updates_in_ui( webapp, webdriver ): """Check that capabilities are updated in the UI correctly.""" # initialize webapp.control_tests.set_data_dir( "{REAL}" ) init_webapp( webapp, webdriver, scenario_persistence=1 ) # load the scenario scenario_data = { "PLAYER_1": "german", "OB_VEHICLES_1": [ { "name": "PzKpfw 38(t)A" } ], # A4[1]/5[2] ; sD6 ; CS 4 "OB_ORDNANCE_1": [ { "name": "3.7cm PaK 35/36" } ], # NT ; A4[1]/5[2]/4[3]/3[4] ; H6[9]† "PLAYER_2": "russian", "OB_VEHICLES_2": [ { "name": "Churchill III(b)" } ], # D6[J4]/7[5]† ; HE7[F3]/8[4+]† ; sD6[4+] ; sM8† ; CS 7 "OB_ORDNANCE_2": [ { "name": "45mm PTP obr. 32" } ], # NT ; A4[2]/5[3]/6[4]/7[5] } scenario_data["OB_VEHICLES_1"].append( { "name": "PzJg I" } ) # A5[1]/6[2]/5[3]; HE7 ; CS 3 load_scenario( scenario_data ) sortables = [ find_child( "#ob_vehicles-sortable_1" ), find_child( "#ob_ordnance-sortable_1" ), find_child( "#ob_vehicles-sortable_2" ), find_child( "#ob_ordnance-sortable_2" ), ] def check_capabilities( scenario_date, expected ): """Get the vehicle/ordnance capabilities from the UI.""" # set the scenario date set_scenario_date( scenario_date ) # check the vehicle/ordnance capabilities results = [] for sortable in sortables: results.append( [] ) vo_entries = find_children( "li", sortable ) for vo_entry in vo_entries: capabilities = find_children( "span.vo-capability", vo_entry ) results[-1].append( [ c.get_attribute("innerHTML") for c in capabilities ] ) for row in expected: for i,entries in enumerate(row): row[i] = [ e for e in entries if e not in _IGNORE_CAPABILITIES ] assert results == expected # no scenario date => we should be showing the raw capabilities check_capabilities( None, [ [ [ "A4<sup>1</sup>5<sup>2</sup>", "sD6", "CS 4" ], [ "A5<sup>1</sup>6<sup>2</sup>5<sup>3</sup>", "HE7", "CS 3" ] ], [ [ "NT", "A4<sup>1</sup>5<sup>2</sup>4<sup>3</sup>3<sup>4</sup>", "H6[9]\u2020" ] ], [ [ "D6<sup>J4</sup>7<sup>5</sup>†", "HE7<sup>F3</sup>8<sup>4+</sup>\u2020", "sD6<sup>4+</sup>", "sM8\u2020", "CS 7" ] ], #pylint: disable=line-too-long [ [ "NT", "A4<sup>2</sup>5<sup>3</sup>6<sup>4</sup>7<sup>5</sup>" ] ] ] ) # edit the PzJg I's capabilities (nb: this locks them in, and they should not change # regardless of what the scenario date is set to) select_tab( "ob1" ) vehicles_sortable = find_child( "#ob_vehicles-sortable_1" ) elems = find_children( "li", vehicles_sortable ) assert len(elems) == 2 ActionChains( webdriver ).double_click( elems[1] ).perform() elem = find_child( "#vo_capabilities-add" ) elem.click() elems = find_children( "#vo_capabilities-sortable input[type='text']" ) assert len(elems) == 4 elems[3].send_keys( "foo!" ) click_dialog_button( "OK" ) # change the scenario date, check the capabilities select_tab( "scenario" ) check_capabilities( "01/01/1940", [ [ [ "sD6", "CS 4" ], [ "A5<sup>1</sup>6<sup>2</sup>5<sup>3</sup>", "HE7", "CS 3", "foo!" ] ], [ [ "NT", "H6[9]\u2020" ] ], [ [ "sM8\u2020", "CS 7" ] ], [ [ "NT" ] ] ] ) check_capabilities( "01/01/1941", [ [ [ "A4", "sD6", "CS 4" ] , [ "A5<sup>1</sup>6<sup>2</sup>5<sup>3</sup>", "HE7", "CS 3", "foo!" ] ], [ [ "NT", "A4", "H6[9]\u2020" ] ], [ [ "sM8\u2020", "CS 7" ] ], [ [ "NT" ] ] ] ) check_capabilities( "01/01/1942", [ [ [ "A5", "sD6", "CS 4" ], [ "A5<sup>1</sup>6<sup>2</sup>5<sup>3</sup>", "HE7", "CS 3", "foo!" ] ], [ [ "NT", "A5", "H6[9]\u2020" ] ], [ [ "sM8\u2020", "CS 7" ] ], [ [ "NT", "A4" ] ] ] ) check_capabilities( "01/01/1943", [ [ [ "sD6", "CS 4" ], [ "A5<sup>1</sup>6<sup>2</sup>5<sup>3</sup>", "HE7", "CS 3", "foo!" ] ], [ [ "NT", "A4", "H6[9]\u2020" ] ], [ [ "sM8\u2020", "CS 7" ] ], [ [ "NT", "A5" ] ] ] ) check_capabilities( "01/01/1944", [ [ [ "sD6", "CS 4" ], [ "A5<sup>1</sup>6<sup>2</sup>5<sup>3</sup>", "HE7", "CS 3", "foo!" ] ], [ [ "NT", "A3", "H6[9]\u2020" ] ], [ [ "HE8\u2020", "sD6", "sM8\u2020", "CS 7" ] ], [ [ "NT", "A6" ] ] ] ) check_capabilities( "01/01/1945", [ [ [ "sD6", "CS 4" ], [ "A5<sup>1</sup>6<sup>2</sup>5<sup>3</sup>", "HE7", "CS 3", "foo!" ] ], [ [ "NT", "H6[9]\u2020" ] ], [ [ "D7\u2020", "HE8\u2020", "sD6", "sM8\u2020", "CS 7" ] ], [ [ "NT", "A7" ] ] ] )
def test_custom_comments( webapp, webdriver ): #pylint: disable=too-many-statements """Test custom comments.""" # NOTE: Vehicle/ordnance comments are not capabilities, but they are managed in the same place # and the code is virtually identical, so it makes sense to put the test code here. # initialize init_webapp( webapp, webdriver, scenario_persistence=1 ) # add a vehicle add_vo( webdriver, "vehicles", 1, "a commented german vehicle" ) snippet_btn = find_child( "button[data-id='ob_vehicles_1']" ) def extract_comments( clipboard ): """Extract the comments.""" mo = re.search( r"^- comments: (.*)$", clipboard, re.MULTILINE ) return mo.group(1) if mo else "" def check_snippet( expected ): """Check the vehicle's snippet.""" snippet_btn.click() wait_for_clipboard( 2, expected, transform=extract_comments ) def check_comments_in_dialog( expected ): """Check the vehicle's comments.""" elems = find_children( "#vo_comments-sortable li" ) elems2 = [ find_child("input[type='text']",c) for c in elems ] assert [ e.get_attribute("value") for e in elems2 ] == expected return elems # check the vehicle's snippet check_snippet( '"a comment" "another comment"' ) # edit the vehicle's comments vehicles_sortable = find_child( "#ob_vehicles-sortable_1" ) elems = find_children( "li", vehicles_sortable ) assert len(elems) == 1 ActionChains( webdriver ).double_click( elems[0] ).perform() elems = check_comments_in_dialog( [ "a comment", "another comment" ] ) # edit one of the comments elem = find_child( "input[type='text']", elems[0] ) elem.clear() elem.send_keys( "a comment (modified)" ) # delete a comment ActionChains( webdriver ).key_down( Keys.CONTROL ).click( elems[1] ).perform() ActionChains( webdriver ).key_up( Keys.CONTROL ).perform() # add a new comment elem = find_child( "#vo_comments-add" ) elem.click() elems = find_children( "#vo_comments-sortable input[type='text']" ) assert len(elems) == 2 elems[1].send_keys( "a <i>new</i> comment" ) # save the changes and check the vehicle's snippet click_dialog_button( "OK" ) check_snippet( '"a comment (modified)" "a <i>new</i> comment"' ) # save the scenario saved_scenario = save_scenario() assert len(saved_scenario["OB_VEHICLES_1"]) == 1 assert saved_scenario["OB_VEHICLES_1"][0]["custom_comments"] == [ "a comment (modified)", "a <i>new</i> comment" ] # reload the scenario, and check the vehicle's snippet select_menu_option( "new_scenario" ) load_scenario( saved_scenario ) select_tab( "ob1" ) check_snippet( '"a comment (modified)" "a <i>new</i> comment"' ) # make sure the comments are loaded correcly when editing the vehicle elems = find_children( "li", vehicles_sortable ) assert len(elems) == 1 ActionChains( webdriver ).double_click( elems[0] ).perform() elems = check_comments_in_dialog( [ "a comment (modified)", "a <i>new</i> comment" ] ) # delete all comments for elem in elems: ActionChains( webdriver ).key_down( Keys.CONTROL ).click( elem ).perform() ActionChains( webdriver ).key_up( Keys.CONTROL ).perform() click_dialog_button( "OK" ) check_snippet( "" ) # save the scenario saved_scenario2 = save_scenario() assert len(saved_scenario2["OB_VEHICLES_1"]) == 1 assert saved_scenario2["OB_VEHICLES_1"][0]["custom_comments"] == [] # reload the scenario, and reset the vehicle's comments back to the default load_scenario( saved_scenario ) select_tab( "ob1" ) elems = find_children( "li", vehicles_sortable ) assert len(elems) == 1 ActionChains( webdriver ).double_click( elems[0] ).perform() btn = find_child( "#vo_comments-reset" ) btn.click() click_dialog_button( "OK" ) check_snippet( '"a comment" "another comment"' ) # make sure the custom comments are no longer saved in the scenario saved_scenario2 = save_scenario() assert len(saved_scenario2["OB_VEHICLES_1"]) == 1 assert "custom_comments" not in saved_scenario2["OB_VEHICLES_1"][0] # reload the scenario, and manually set the vehicle's comments to be the same as the default load_scenario( saved_scenario ) select_tab( "ob1" ) elems = find_children( "li", vehicles_sortable ) assert len(elems) == 1 ActionChains( webdriver ).double_click( elems[0] ).perform() elems = find_children( "#vo_comments-sortable input[type='text']" ) assert len(elems) == 2 elems[0].clear() elems[0].send_keys( "a comment" ) elems[1].clear() elems[1].send_keys( "another comment" ) click_dialog_button( "OK" ) # make sure the custom comments are no longer saved in the scenario saved_scenario = save_scenario() assert len(saved_scenario["OB_VEHICLES_1"]) == 1 assert "custom_comments" not in saved_scenario["OB_VEHICLES_1"][0]
def update_vsav_thread(webapp_url, vsav_fname, vsav_data): """Test updating VASL scenario files.""" # initialize vsav_data_b64 = base64.b64encode(vsav_data).decode("utf-8") with WebDriver() as webdriver: # initialize webdriver = webdriver.driver init_webapp(webdriver, webapp_url, ["vsav_persistence", "scenario_persistence"]) # load a test scenario fname = os.path.join( os.path.split(__file__)[0], "../webapp/tests/fixtures/update-vsav/full.json") with open(fname, "r", encoding="utf-8") as fp: saved_scenario = json.load(fp) load_scenario(saved_scenario, webdriver) while not shutdown_event.is_set(): try: # send the VSAV data to the front-end to be updated log("Updating VSAV: {}", vsav_fname) set_stored_msg("_vsav-persistence_", vsav_data_b64, webdriver) select_menu_option("update_vsav", webdriver) start_time = time.time() # wait for the front-end to receive the data wait_for( 2 * thread_count, lambda: get_stored_msg( "_vsav-persistence_", webdriver) == "") # wait for the updated data to arrive wait_for( 60 * thread_count, lambda: get_stored_msg( "_vsav-persistence_", webdriver) != "") elapsed_time = time.time() - start_time # get the updated VSAV data updated_vsav_data = get_stored_msg("_vsav-persistence_", webdriver) if updated_vsav_data.startswith("ERROR: "): raise RuntimeError(updated_vsav_data) updated_vsav_data = base64.b64decode(updated_vsav_data) # check the updated VSAV log("Received updated VSAV data: #bytes={}", len(updated_vsav_data)) assert updated_vsav_data[:2] == b"PK" # update the stats with stats_lock: stats["update vsav"][0] += 1 stats["update vsav"][1] += elapsed_time except (ConnectionRefusedError, ConnectionResetError, http.client.RemoteDisconnected): if shutdown_event.is_set(): break raise
def snippet_images_thread(webapp_url): """Test generating snippet images.""" with WebDriver() as webdriver: # initialize webdriver = webdriver.driver init_webapp(webdriver, webapp_url, ["snippet_image_persistence", "scenario_persistence"]) # 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, webdriver) # locate all the "generate snippet" buttons snippet_btns = find_snippet_buttons(webdriver) tab_ids = list(snippet_btns.keys()) while not shutdown_event.is_set(): try: # clear the return buffer ret_buffer = find_child("#_snippet-image-persistence_", webdriver) assert ret_buffer.tag_name == "textarea" webdriver.execute_script("arguments[0].value = arguments[1]", ret_buffer, "") # generate a snippet tab_id = random.choice(tab_ids) btn = random.choice(snippet_btns[tab_id]) log("Getting snippet image: {}", btn.get_attribute("data-id")) select_tab(tab_id, webdriver) start_time = time.time() ActionChains( webdriver ) \ .key_down( Keys.SHIFT ) \ .click( btn ) \ .key_up( Keys.SHIFT ) \ .perform() # wait for the snippet image to be generated wait_for(10 * thread_count, lambda: ret_buffer.get_attribute("value")) _, img_data = ret_buffer.get_attribute("value").split("|", 1) elapsed_time = time.time() - start_time # update the stats with stats_lock: stats["snippet image"][0] += 1 stats["snippet image"][1] += elapsed_time # FUDGE! Generating the snippet image for a sortable entry is sometimes interpreted as # a request to edit the entry (Selenium problem?) - we dismiss the dialog here and continue. dlg = find_child(".ui-dialog", webdriver) if dlg and dlg.is_displayed(): click_dialog_button("Cancel", webdriver) except (ConnectionRefusedError, ConnectionResetError, http.client.RemoteDisconnected): if shutdown_event.is_set(): break raise # check the generated snippet img_data = base64.b64decode(img_data) log("Received snippet image: #bytes={}", len(img_data)) assert img_data[:6] == b"\x89PNG\r\n"
def test_date_format(webapp, webdriver): """Test changing the date format.""" # initialize init_webapp(webapp, webdriver, template_pack_persistence=1, scenario_persistence=1) # customize the SCENARIO template upload_template_pack_file( "scenario.j2", "{{SCENARIO_YEAR}}-{{SCENARIO_MONTH}}-{{SCENARIO_DAY_OF_MONTH}}", False) scenario_date = find_child("input[name='SCENARIO_DATE']") snippet_btn = find_child("button.generate[data-id='scenario']") def set_scenario_date(date_string): """Set the scenario date.""" scenario_date.clear() scenario_date.send_keys(date_string) scenario_date.send_keys(Keys.TAB) assert scenario_date.get_attribute("value") == date_string def check_scenario_date(expected): """Check the scenario date is being interpreted correctly.""" assert isinstance(expected, tuple) and len(expected) == 3 assert 1 <= expected[0] <= 31 and 1 <= expected[ 1] <= 12 and 1940 <= expected[2] <= 1945 # check the snippet snippet_btn.click() wait_for_clipboard( 2, "{}-{}-{}".format(expected[2], expected[0], expected[1])) # check the save file (should always be ISO-8601 format) saved_scenario = save_scenario() assert saved_scenario["SCENARIO_DATE"] == "{:04}-{:02}-{:02}".format( expected[2], expected[0], expected[1]) # check the default format (MM/DD/YYYY) set_scenario_date("01/02/1940") check_scenario_date((1, 2, 1940)) saved_scenario = save_scenario() # change the date format to YYYY-MM-DD select_menu_option("user_settings") date_format_sel = Select( find_child(".ui-dialog.user-settings select[name='date-format']")) select_droplist_val(date_format_sel, "yy-mm-dd") click_dialog_button("OK") _check_cookies(webdriver, "date-format", "yy-mm-dd") # make sure that it took effect assert scenario_date.get_attribute("value") == "1940-01-02" check_scenario_date((1, 2, 1940)) # clear the scenario date, set the date format to DD-MM-YYY set_scenario_date("") select_menu_option("user_settings") select_droplist_val(date_format_sel, "dd/mm/yy") click_dialog_button("OK") _check_cookies(webdriver, "date-format", "dd/mm/yy") # set the scenario date set_scenario_date( "03/04/1945") # nb: this will be interpreted as DD/MM/YYYY check_scenario_date((4, 3, 1945)) # load the scenario we saved before and check the date load_scenario(saved_scenario) check_scenario_date((1, 2, 1940)) assert scenario_date.get_attribute("value") == "02/01/1940"
def test_import_warnings(webapp, webdriver): #pylint: disable=too-many-statements """Test warnings when importing a scenario.""" # initialize init_webapp(webapp, webdriver, scenario_persistence=1) # import a scenario on top of an empty scenario dlg = _do_scenario_search("full", [1], webdriver) find_child("button.import", dlg).click() wait_for(2, lambda: not dlg.is_displayed()) def check_warnings(expected): #pylint: disable=missing-docstring warnings = find_children(".warnings input[type='checkbox']", dlg) return [w.get_attribute("name") for w in warnings] == expected def do_test(param_name, expected_warning, expected_val, curr_val="CURR-VAL"): #pylint: disable=missing-docstring # start with a new scenario new_scenario() # set the scenario parameter set_template_params({param_name: curr_val}) # import a scenario _do_scenario_search("full", [1], webdriver) _click_import_button(find_child("#scenario-search")) # check if any warnings were expected elem = find_child("[name='{}']".format(param_name)) if expected_warning: # yup - make sure they are being shown wait_for(2, lambda: check_warnings([expected_warning])) # cancel the import find_child("button.cancel-import", dlg).click() wait_for(2, lambda: not find_child(".warnings", dlg).is_displayed()) # do the import again, and accept it _import_scenario_and_confirm(dlg) assert elem.get_attribute("value") == expected_val else: # nope - check that the import was done wait_for(2, lambda: not dlg.is_displayed()) # assert not dlg.is_displayed() assert elem.get_attribute("value") == expected_val # do the tests do_test("SCENARIO_NAME", "scenario_name", "Full content scenario") do_test("SCENARIO_ID", "scenario_display_id", "FCS-1") do_test("SCENARIO_LOCATION", "scenario_location", "Some place") do_test("SCENARIO_DATE", "scenario_date_iso", "12/31/1945", curr_val="01/02/1940") do_test("SCENARIO_THEATER", None, "PTO", curr_val="Burma") do_test("PLAYER_1", None, "dutch", curr_val="german") do_test("PLAYER_1_DESCRIPTION", "defender_desc", "1st Dutch Army") do_test("PLAYER_2", None, "romanian", curr_val="german") do_test("PLAYER_2_DESCRIPTION", "attacker_desc", "1st Romanian Army") # test importing a scenario on top of existing OB owned by the same nationality new_scenario() load_scenario({ "PLAYER_1": "dutch", }) dlg = _do_scenario_search("full", [1], webdriver) find_child("button.import", dlg).click() check_warnings([]) wait_for(2, lambda: not dlg.is_displayed()) # test importing a scenario on top of existing OB owned by the same nationality new_scenario() load_scenario({ "PLAYER_1": "dutch", "OB_SETUPS_1": [{ "caption": "Dutch setup note" }] }) dlg = _do_scenario_search("full", [1], webdriver) find_child("button.import", dlg).click() wait_for(2, lambda: not dlg.is_displayed()) # test importing a scenario on top of existing OB owned by the different nationality new_scenario() load_scenario({ "PLAYER_1": "german", "OB_SETUPS_1": [{ "caption": "German setup note" }] }) dlg = _do_scenario_search("full", [1], webdriver) find_child("button.import", dlg).click() warnings = wait_for( 2, lambda: find_children(".warnings input[type='checkbox']", dlg)) assert [w.get_attribute("name") for w in warnings] == ["defender_name"] assert not warnings[0].is_selected() wait_for(2, lambda: warnings[0].is_displayed) time.sleep(0.1) # nb: wait for the slide to finish :-/ warnings[0].click() find_child("button.confirm-import", dlg).click() assert not dlg.is_displayed() assert get_player_nat(1) == "dutch"
def do_test(expected): #pylint: disable=missing-docstring # initialize webapp.control_tests.set_data_dir("{REAL}") init_webapp(webapp, webdriver, scenario_persistence=1) # enable images set_user_settings({ "scenario-images-source": SCENARIO_IMAGES_SOURCE_THIS_PROGRAM, "include-vasl-images-in-snippets": True, "include-flags-in-snippets": True, "custom-list-bullets": True, "vo-notes-as-images": True, }) # load the scenario load_scenario({ "SCENARIO_NAME": "test scenario", "SCENARIO_DATE": "01/01/1940", "VICTORY_CONDITIONS": "Just do it!", "SCENARIO_NOTES": [{ "caption": "Scenario note #1" }], "SSR": ["SSR #1", "SSR #2", "SSR #3"], "PLAYER_1": "german", "OB_SETUPS_1": [{ "caption": "OB setup note 1" }], "OB_NOTES_1": [{ "caption": "OB note 1" }], "OB_VEHICLES_1": [{ "name": "PzKpfw VG" }], "OB_ORDNANCE_1": [{ "name": "8.8cm PaK 43" }], "PLAYER_2": "russian", "OB_SETUPS_2": [{ "caption": "OB setup note 2" }], "OB_NOTES_2": [{ "caption": "OB note 2" }], "OB_VEHICLES_2": [{ "name": "T-34/85" }], "OB_ORDNANCE_2": [{ "name": "82mm BM obr. 37" }], }) # generate each snippet snippet_btns = find_snippet_buttons() for tab_id, btns in snippet_btns.items(): select_tab(tab_id) for btn in btns: snippet_id = btn.get_attribute("data-id") btn.click() buf = wait_for_clipboard( 2, re.compile("<!-- vasl-templates:id (german/|russian/)?" + snippet_id)) # check each URL for mo in re.finditer(r"<img .*?src=[\"'](.*?)[\"']", buf): url = mo.group(1) assert url.startswith(expected)
def test_seq_ids(webapp, webdriver): """Test handling of vehicle/ordnance sequence ID's.""" # initialize init_webapp(webapp, webdriver, scenario_persistence=1) # load the test scenario load_scenario({ "PLAYER_1": "german", "OB_VEHICLES_1": [{ "name": "a german vehicle" }, { "name": "another german vehicle" }] }) select_tab("ob1") sortable = find_child("#ob_vehicles-sortable_1") def check_seq_ids(expected): #pylint: disable=missing-docstring entries = find_children("li", sortable) assert len(entries) == len(expected) for i, entry in enumerate(entries): data = webdriver.execute_script( "return $(arguments[0]).data('sortable2-data')", entry) assert expected[i] == (data["caption"], data["id"]) # check the initial seq ID's (nb: they weren't in the loaded scenario, so they should have been auto-assigned) check_seq_ids([ ("a german vehicle", 1), ("another german vehicle", 2), ]) # add another vehicle add_vo(webdriver, "vehicles", 1, "one more german vehicle") check_seq_ids([ ("a german vehicle", 1), ("another german vehicle", 2), ("one more german vehicle", 3), ]) # delete the 2nd vehicle delete_vo("vehicles", 1, "another german vehicle", webdriver) check_seq_ids([ ("a german vehicle", 1), ("one more german vehicle", 3), ]) # add another vehicle add_vo(webdriver, "vehicles", 1, "name only") check_seq_ids([ ("a german vehicle", 1), ("one more german vehicle", 3), ("name only", 2), # nb: this seq ID gets re-used ]) # make sure the seq ID's are saved out saved_scenario = save_scenario() entries = [(veh["name"], veh.get("seq_id")) for veh in saved_scenario["OB_VEHICLES_1"]] assert entries == [ ("a german vehicle", 1), ("one more german vehicle", 3), ("name only", 2), ]
def do_test(enable_vo_notes): #pylint: disable=missing-docstring # initialize webapp.control_tests \ .set_data_dir( "{REAL}" ) \ .set_vo_notes_dir( "{TEST}" if enable_vo_notes else None ) init_webapp(webapp, webdriver, vsav_persistence=1, scenario_persistence=1) # dump the VASL scenario # NOTE: We implemented snippet ID's in v0.5, this scenario is the "Hill 621" example from v0.4. fname = os.path.join( os.path.split(__file__)[0], "fixtures/update-vsav/hill621-legacy.vsav") vsav_dump = _dump_vsav(webapp, fname) labels = _get_vsav_labels(vsav_dump) assert len([lbl for lbl in labels if "vasl-templates:id" not in lbl]) == 20 assert len([lbl for lbl in labels if "vasl-templates:id" in lbl]) == 0 #pylint: disable=len-as-condition # load the scenario into the UI and update the VSAV fname2 = change_extn(fname, ".json") with open(fname2, "r", encoding="utf-8") as fp: saved_scenario = json.load(fp) load_scenario(saved_scenario) expected = 5 if enable_vo_notes else 1 updated_vsav_dump = _update_vsav_and_dump(webapp, fname, { "created": expected, "updated": 20 }) # check the results # nb: the update process should create 1 new label (the "Download from MMP" scenario note) labels = _get_vsav_labels(updated_vsav_dump) assert len([lbl for lbl in labels if "vasl-templates:id" not in lbl]) == 0 #pylint: disable=len-as-condition assert len([lbl for lbl in labels if "vasl-templates:id" in lbl ]) == 25 if enable_vo_notes else 21 expected = { "scenario": "Near Minsk", "players": re.compile(r"Russian:.*German:"), "victory_conditions": "five Level 3 hill hexes", "ssr": re.compile(r"no wind at start.*must take a TC"), "scenario_note.1": "Download the scenario card", "russian/ob_setup_1.1": "whole hex of Board 3", "russian/ob_setup_1.2": "Enter on Turn 2", "russian/ob_setup_1.3": "Enter on Turn 5", "russian/ob_vehicles_1": re.compile(r"T-34 M43.*SU-152.*SU-122.*ZIS-5"), "german/ob_setup_2.1": "whole hex of Board 4", "german/ob_setup_2.2": "Enter on Turn 1", "german/ob_setup_2.3": "Enter on Turn 2", "german/ob_setup_2.4": "Enter on Turn 4", "german/ob_setup_2.5": "Enter on Turn 5", "german/ob_setup_2.6": "Enter on Turn 8", "german/ob_note_2.1": "80+mm Battalion Mortar", "german/ob_note_2.2": "100+mm OBA", "german/ob_vehicles_2": re.compile( r"PzKpfw IVH.*PzKpfw IIIN.*StuG IIIG \(L\).*StuH 42.*SPW 250/1.*SPW 251/1.*SPW 251/sMG" ), "german/ob_ordnance_2": re.compile(r"7.5cm PaK 40.*5cm PaK 38"), "german/pf": "Panzerfaust", "german/atmm": "Anti-Tank Magnetic Mines", } if enable_vo_notes: expected["russian/ob_vehicle_note_1.1"] = re.compile( r'T-34 M43.*<img src="http://[^/]+/vehicles/russian/note/16">') expected["german/ob_ordnance_note_2.2"] = re.compile( r'5cm PaK 38.*<img src="http://[^/]+/ordnance/german/note/8">') expected[ "german/ob_vehicles_ma_notes_2" ] = re.compile( r"<span class='key'>B:</span> German Multi-Applicable Vehicle Note \"B\"." + ".*" \ r"<span class='key'>C:</span> German Multi-Applicable Vehicle Note \"C\"." + ".*" \ r"<span class='key'>J:</span> Unavailable." + ".*" \ r"<span class='key'>N:</span> Unavailable." + ".*" \ r"<span class='key'>O:</span> Unavailable." + ".*" \ r"<span class='key'>P:</span> Unavailable." + ".*" \ r"<span class='key'>Q:</span> Unavailable." + ".*" \ r"<span class='key'>S:</span> Unavailable." + ".*" ) expected[ "german/ob_ordnance_ma_notes_2"] = r"<span class='key'>N:</span> Unavailable." _check_vsav_dump(updated_vsav_dump, expected)
def test_extra_ma_notes(webapp, webdriver): """Test handling of Landing Craft and Allied/Axis Minor common vehicles/ordnance.""" # initialize webapp.control_tests.set_vo_notes_dir("{TEST}") init_webapp(webapp, webdriver, scenario_persistence=1) # load the test scenario load_scenario({ "PLAYER_1": "dutch", "OB_VEHICLES_1": [{ "name": "dutch vehicle" }, { "name": "common allied minor vehicle" }], "OB_ORDNANCE_1": [{ "name": "dutch ordnance" }, { "name": "common allied minor ordnance" }], "PLAYER_2": "romanian", "OB_VEHICLES_2": [{ "name": "romanian vehicle" }, { "name": "common axis minor vehicle" }], "OB_ORDNANCE_2": [{ "name": "romanian ordnance" }, { "name": "common axis minor ordnance" }], }) # test Allied Minor vehicles/ordnance select_tab("ob1") btn = find_child("button.generate[data-id='ob_vehicles_ma_notes_1']") btn.click() wait_for_clipboard(2, [ ("A", 'Dutch Multi-Applicable Vehicle Note "A".'), ("Du", 'Allied Minor Multi-Applicable Vehicle Note "Du".'), ], transform=extract_ma_notes) btn = find_child("button.generate[data-id='ob_ordnance_ma_notes_1']") btn.click() wait_for_clipboard(2, [ ("A", 'Dutch Multi-Applicable Ordnance Note "A".'), ("Du", 'Allied Minor Multi-Applicable Ordnance Note "Du".'), ], transform=extract_ma_notes) # test Axis Minor vehicles/ordnance select_tab("ob2") btn = find_child("button.generate[data-id='ob_vehicles_ma_notes_2']") btn.click() wait_for_clipboard(2, [ ("A", 'Romanian Multi-Applicable Vehicle Note "A".'), ("Ro", 'Axis Minor Multi-Applicable Vehicle Note "Ro".'), ], transform=extract_ma_notes) btn = find_child("button.generate[data-id='ob_ordnance_ma_notes_2']") btn.click() wait_for_clipboard(2, [ ("A", 'Romanian Multi-Applicable Ordnance Note "A".'), ("Ro", 'Axis Minor Multi-Applicable Ordnance Note "Ro".'), ], transform=extract_ma_notes) # test Landing Craft load_scenario({ "PLAYER_1": "american", "OB_VEHICLES_1": [{ "name": "M10 GMC" }, { "name": "landing craft" }], "PLAYER_2": "japanese", "OB_VEHICLES_2": [{ "name": "japanese vehicle" }, { "name": "Daihatsu" }], }) select_tab("ob1") btn = find_child("button.generate[data-id='ob_vehicles_ma_notes_1']") btn.click() wait_for_clipboard(2, [ ("A", 'American Multi-Applicable Vehicle Note "A".'), ("N", "Unavailable."), ("Y", "Unavailable."), "Landing Craft", ("A", 'Landing Craft Multi-Applicable Note "A".'), ], transform=extract_ma_notes) select_tab("ob2") btn = find_child("button.generate[data-id='ob_vehicles_ma_notes_2']") btn.click() wait_for_clipboard(2, [ ("A", 'Japanese Multi-Applicable Vehicle Note "A".'), "Landing Craft", ("B", 'Landing Craft Multi-Applicable Note "B".'), ], transform=extract_ma_notes)