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_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_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_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 do_test(vehicles, expected): #pylint: disable=missing-docstring # add the specified vehicles new_scenario() set_player(1, "japanese") for veh in vehicles: add_vo(webdriver, "vehicles", 1, veh) # get the multi-applicable notes btn = find_child("button.generate[data-id='ob_vehicles_ma_notes_1']") btn.click() wait_for_clipboard(2, expected, transform=_extract_extn_ma_notes)
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_html_names( webapp, webdriver ): """Test handling of vehicles/ordnance that have HTML in their name.""" # initialize webapp.control_tests.set_data_dir( "{REAL}" ) init_webapp( webapp, webdriver ) def get_available_ivfs(): """Get the PzKw IVF's available for selection.""" entries = find_children( "#select-vo .select2-results li" ) entries = [ e.text for e in entries ] return [ e for e in entries if "IVF" in e ] # start to add a vehicle - make sure the two PzKw IVF's are available set_player( 1, "german" ) select_tab( "ob1" ) add_vehicle_btn = find_child( "#ob_vehicles-add_1" ) add_vehicle_btn.click() assert get_available_ivfs() == [ "PzKpfw IVF1 (MT)", "PzKpfw IVF2 (MT)" ] # add the PzKw IVF2 elem = find_child( ".ui-dialog .select2-search__field" ) elem.send_keys( "IVF2" ) elem.send_keys( Keys.RETURN ) # make sure it was added to the player's OB vehicles_sortable = find_child( "#ob_vehicles-sortable_1" ) assert get_sortable_vo_names( vehicles_sortable ) == [ "PzKpfw IVF2" ] # start to add another vehicle - make sure both PzKw IVF's are still available add_vehicle_btn.click() assert get_available_ivfs() == [ "PzKpfw IVF1 (MT)", "PzKpfw IVF2 (MT)" ] # add the PzKw IVF1 elem = find_child( ".ui-dialog .select2-search__field" ) elem.send_keys( "IVF1" ) elem.send_keys( Keys.RETURN ) # make sure it was added to the player's OB assert get_sortable_vo_names( vehicles_sortable ) == [ "PzKpfw IVF2", "PzKpfw IVF1" ] # start to add another vehicle - make sure both PzKw IVF's are still available add_vehicle_btn.click() assert get_available_ivfs() == [ "PzKpfw IVF1 (MT)", "PzKpfw IVF2 (MT)" ] elem = find_child( ".ui-dialog .select2-search__field" ) elem.send_keys( Keys.ESCAPE ) # delete the PzKw IVF2 delete_vo( "vehicles", 1, "PzKpfw IVF2" , webdriver ) # start to add another vehicle - make sure both PzKw IVF's are still available add_vehicle_btn.click() assert get_available_ivfs() == [ "PzKpfw IVF1 (MT)", "PzKpfw IVF2 (MT)" ]
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_extns): #pylint: disable=missing-docstring # initialize webapp.control_tests \ .set_data_dir( "{REAL}" ) \ .set_vasl_version( "random", "{REAL}" if enable_extns else None ) init_webapp(webapp, webdriver) set_player(2, "russian") # check the Matilda II(b) check_counter_images( "Matilda II(b)", ["7150", "f97:178", "f97:184"] if enable_extns else ["7150"]) # check the T60-M40 check_counter_images("T-60 M40", ["547", "f97:186"] if enable_extns else ["547"])
def test_unknown_nats(webapp, webdriver): """Test importing scenarios with unknown player nationalities.""" # initialize init_webapp(webapp, webdriver) # test importing a scenario with 2 completely unknown player nationalities set_player(1, "french") set_player(2, "italian") dlg = _do_scenario_search("Unknown players", ["4a"], webdriver) _click_import_button(dlg) _check_warnings([], ["Unknown player: Eastasia", "Unknown player: Oceania"]) expected_bgraphs = { "asa": [{ "name": "Eastasia", "wins": 2, "percentage": 67 }, { "name": "Oceania", "wins": 1, "percentage": 33 }] } assert _unload_balance_graphs(dlg) == expected_bgraphs find_child("button.confirm-import", dlg).click() wait_for(2, lambda: not find_child("#scenario-search").is_displayed()) assert get_player_nat(1) == "french" assert get_player_nat(2) == "italian" # test matching nationalities (partial name matches) new_scenario() dlg = _do_scenario_search("partial nationality matches", ["4b"], webdriver) find_child("button.import", dlg).click() wait_for(2, lambda: not find_child("#scenario-search").is_displayed()) assert get_player_nat(1) == "russian" assert get_player_nat(2) == "japanese" # test nationality mapping new_scenario() dlg = _do_scenario_search("nationality mapping", ["4c"], webdriver) find_child("button.import", dlg).click() wait_for(2, lambda: not find_child("#scenario-search").is_displayed()) assert get_player_nat(1) == "british" assert get_player_nat(2) == "british~canadian"
def test_change_vo_image2( webapp, webdriver ): """Test changing the image for a V/O that has no alternative images.""" # initialize webapp.control_tests.set_data_dir( "{REAL}" ) init_webapp( webapp, webdriver, scenario_persistence=1 ) # add an 107mm GVPM set_player( 2, "russian" ) add_vo( webdriver, "ordnance", 2, "107mm GVPM obr. 38" ) # make sure the "change image" button is not present ordnance_sortable = find_child( "#ob_ordnance-sortable_2" ) elems = find_children( "li", ordnance_sortable ) assert len(elems) == 1 ActionChains(webdriver).double_click( elems[0] ).perform() btn = find_child( "#edit-vo input.select-vo-image" ) assert btn is None
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()
def do_test(): #pylint: disable=missing-docstring # initialize webapp.control_tests.set_data_dir("{REAL}") init_webapp(webapp, webdriver, vsav_persistence=1, scenario_persistence=1) # do the test new_scenario() set_player(1, "american") set_player(2, "croatian") analyze_vsav("reverse-remapped-gpids-650.vsav", [["am/v:044"], ["am/o:002", "am/o:021"]], [["cr/v:002", "cr/v:003"], ["cr/o:000"]], [ "Imported 1 American vehicle and 2 ordnance.", "Imported 2 Croatian vehicles and 1 ordnance." ])
def test_include_vasl_images_in_snippets(webapp, webdriver): """Test including VASL counter images in snippets.""" # initialize webapp.control_tests.set_data_dir("{REAL}") init_webapp(webapp, webdriver) set_user_settings( {"scenario-images-source": SCENARIO_IMAGES_SOURCE_THIS_PROGRAM}) # add a vehicle set_player(1, "german") add_vo(webdriver, "vehicles", 1, "PzKpfw IB") # enable "show VASL images in snippets" select_menu_option("user_settings") elem = find_child( ".ui-dialog.user-settings input[name='include-vasl-images-in-snippets']" ) assert not elem.is_selected() elem.click() click_dialog_button("OK") _check_cookies(webdriver, "include-vasl-images-in-snippets", True) # make sure that it took effect snippet_btn = find_child("button[data-id='ob_vehicles_1']") snippet_btn.click() wait_for_clipboard(2, "/counter/2524/front", contains=True) # disable "show VASL images in snippets" select_menu_option("user_settings") elem = find_child( ".ui-dialog.user-settings input[name='include-vasl-images-in-snippets']" ) assert elem.is_selected() elem.click() click_dialog_button("OK") _check_cookies(webdriver, "include-vasl-images-in-snippets", False) # make sure that it took effect snippet_btn.click() wait_for_clipboard(2, "/counter/2524/front", contains=False)
def test_nationality_specific( webapp, webdriver ): #pylint: disable=too-many-locals """Check that nationality-specific buttons are shown/hidden correctly.""" # initialize init_webapp( webapp, webdriver ) nationalities = get_nationalities( webapp ) def do_check_snippets( btn, date, expected, warning ): """Check that snippets are being generated correctly.""" # change the scenario date, check that the button is displayed correctly set_scenario_date( "{:02}/01/{:04}".format( date[1], date[0] ) ) select_tab( "ob1" ) classes = btn.get_attribute( "class" ) classes = classes.split() if classes else [] if warning: assert "inactive" in classes else: assert "inactive" not in classes # test snippet generation marker = set_stored_msg_marker( "_last-warning_" ) btn.click() wait_for_clipboard( 2, expected ) # check if a warning was issued last_warning = get_stored_msg( "_last-warning_" ) if warning: assert "are only available" in last_warning expected_image_url = "snippet-disabled.png" else: assert last_warning == marker expected_image_url = "snippet.png" wait_for( 2, lambda: expected_image_url in find_child( "img", btn ).get_attribute( "src" ) ) # initialize def check_pf_snippets(): """Check that the PF snippets are generated correctly.""" btn = find_child( "button[data-id='pf']" ) col = "[OBCOL:german]/[OBCOL-BORDER:german]" do_check_snippets( btn, (1942,1), "PF: range=[1] ; check=[3] ; col={}".format(col), True ) do_check_snippets( btn, (1943,9), "PF: range=[1] ; check=[3] ; col={}".format(col), True ) do_check_snippets( btn, (1943,10), "PF: range=[1] ; check=[3] ; col={}".format(col), False ) do_check_snippets( btn, (1944,5), "PF: range=[1] ; check=[3] ; col={}".format(col), False ) do_check_snippets( btn, (1944,6), "PF: range=[2] ; check=[3] ; col={}".format(col), False ) do_check_snippets( btn, (1944,12), "PF: range=[2] ; check=[3] ; col={}".format(col), False ) do_check_snippets( btn, (1945,1), "PF: range=[3] ; check=[4] ; col={}".format(col), False ) do_check_snippets( btn, (1946,1), "PF: range=[3] ; check=[4] ; col={}".format(col), False ) # initialize def check_psk_snippets(): """Check that the PSK snippets are generated correctly.""" btn = find_child( "button[data-id='psk']" ) expected = "====> whoosh! ; col=[OBCOL:german]/[OBCOL-BORDER:german]" do_check_snippets( btn, (1942,1), expected, True ) do_check_snippets( btn, (1943,8), expected, True ) do_check_snippets( btn, (1943,9), expected, False ) do_check_snippets( btn, (1944,1), expected, False ) # initialize def check_baz_snippets(): """Check that the BAZ snippets are generated correctly.""" btn = find_child( "button[data-id='baz']" ) do_check_snippets( btn, (1941,1), "BAZ: none", True ) do_check_snippets( btn, (1942,10), "BAZ: none", True ) col = "[OBCOL:american]/[OBCOL-BORDER:american]" do_check_snippets( btn, (1942,11), "BAZ: '43 ; range=[4] ; X#=[10] ; TK#=[13] ; col={}".format(col), False ) do_check_snippets( btn, (1943,1), "BAZ: '43 ; range=[4] ; X#=[10] ; TK#=[13] ; col={}".format(col), False ) do_check_snippets( btn, (1944,1), "BAZ: '44 ; range=[4] ; X#=[11] ; TK#=[16] ; col={}".format(col), False ) do_check_snippets( btn, (1945,1), "BAZ: '45 ; range=[5] ; X#=[11] ; TK#=[16] ; WP#=[6] ; col={}".format(col), False ) do_check_snippets( btn, (1946,1), "BAZ: '45 ; range=[5] ; X#=[11] ; TK#=[16] ; WP#=[6] ; col={}".format(col), False ) # initialize def check_atmm_snippets(): """Check that the ATMM snippets are generated correctly.""" btn = find_child( "button[data-id='atmm']" ) expected = "Kaboom!!! ; col=[OBCOL:german]/[OBCOL-BORDER:german]" do_check_snippets( btn, (1943,12), expected, True ) do_check_snippets( btn, (1944,1), expected, False ) do_check_snippets( btn, (1944,12), expected, False ) do_check_snippets( btn, (1945,1), expected, False ) # initialize nationality_specific_buttons = { "mol": [ "russian", "Burn, baby, burn! ; col=[OBCOL:russian]/[OBCOL-BORDER:russian]" ], "mol-p": [ "russian", "mol-p template ; col=[OBCOL:russian]/[OBCOL-BORDER:russian]" ], "pf": [ "german", check_pf_snippets ], "psk": [ "german", check_psk_snippets ], "atmm": [ "german", check_atmm_snippets ], "baz": [ "american", check_baz_snippets ], "baz45": [ ("american","Korea"), "BAZ 45 (from K:FW)" ], "baz50": [ ("american","Korea"), "BAZ 50 (from K:FW)" ], "baz-cpva16": [ "kfw-cpva", "BAZ 44 (from K:FW)" ], "baz-cpva17": [ "kfw-cpva", "BAZ Type 51 (from K:FW)" ], "piat": [ "british", "piat template ; col=[OBCOL:british]/[OBCOL-BORDER:british]" ], "thh": [ "japanese", "Banzai!!!" ], } btn_elems = { btn: find_child( "button[data-id='{}']".format( btn ) ) for btn in nationality_specific_buttons } # iterate through each nationality for nat in nationalities: # change the nationality for player 1 set_player( 1, nat ) # check the nationality-specific buttons select_tab( "ob1" ) for button_id,expected in nationality_specific_buttons.items(): elem = btn_elems[ button_id ] if isinstance( expected[0], str ): nat2 = expected[0] else: nat2 = expected[0][0] set_theater( expected[0][1] ) if nat == nat2: # the button should be shown for this nationality assert elem.is_displayed() # make sure that the template works elem.click() if isinstance( expected[1], str ): wait_for_clipboard( 2, expected[1] ) elif isinstance( expected[1], types.FunctionType ): expected[1]() #pylint: disable=not-callable else: assert False else: # it should be hidden for all other nationalities assert not elem.is_displayed()
def do_test(): #pylint: disable=missing-docstring # initialize webapp.control_tests.set_data_dir("{REAL}") init_webapp(webapp, webdriver, vsav_persistence=1, scenario_persistence=1) # analyze a basic scenario new_scenario() set_player(1, "german") set_player(2, "russian") analyze_vsav("basic.vsav", [["ge/v:033", "ge/v:066"], ["ge/o:029"]], [["ru/v:064"], ["ru/o:002", "ru/o:006"]], [ "Imported 2 German vehicles and 1 ordnance.", "Imported 1 Russian vehicle and 2 ordnance." ]) # try again with different nationalities new_scenario() set_player(1, "french") set_player(2, "british") analyze_vsav("basic.vsav", [[], []], [[], []], ["No vehicles/ordnance were imported."]) # analyze a scenario with landing craft new_scenario() set_player(1, "american") set_player(2, "japanese") analyze_vsav( "landing-craft.vsav", [[("sh/v:000", "397/0"), ("sh/v:000", "399/0"), ("sh/v:006", "413/0"), ("sh/v:006", "415/0")], []], [["sh/v:007", "sh/v:008"], []], ["Imported 4 American vehicles.", "Imported 2 Japanese vehicles."]) # analyze a scenario with common vehicles/ordnance new_scenario() set_player(1, "belgian") set_player(2, "romanian") analyze_vsav("common-vo.vsav", [["be/v:000", "alc/v:011"], ["be/o:001", "alc/o:012"]], [["ro/v:000", "axc/v:027"], ["ro/o:003", "axc/o:002"]], [ "Imported 2 Belgian vehicles and 2 ordnance.", "Imported 2 Romanian vehicles and 2 ordnance." ]) # try again with the Yugoslavians/Croatians new_scenario() set_player(1, "yugoslavian") set_player(2, "croatian") analyze_vsav("common-vo.vsav", [["alc/v:011"], ["alc/o:012"]], [["axc/v:027"], ["axc/o:002"]], [ "Imported 1 Yugoslavian vehicle and 1 ordnance.", "Imported 1 Croatian vehicle and 1 ordnance." ]) # try again with the Germans/Russians new_scenario() analyze_vsav("common-vo.vsav", [[], []], [[], []], ["No vehicles/ordnance were imported."]) # analyze a scenario using counters from an extension new_scenario() set_player(1, "american") set_player(2, "japanese") analyze_vsav("extensions-bfp.vsav", [["am/v:906"], ["am/o:900"]], [["ja/v:902"], ["ja/o:902"]], [ "Imported 1 American vehicle and 1 ordnance.", "Imported 1 Japanese vehicle and 1 ordnance." ])
def test_common_vo( webapp, webdriver ): #pylint: disable=too-many-locals """Test loading of common vehicles/ordnance and landing craft.""" # initialize webapp.control_tests.set_data_dir( "{REAL}" ) init_webapp( webapp, webdriver ) # initialize ALLIED_MINOR = [ "belgian", "danish", "dutch", "greek", "polish", "yugoslavian" ] AXIS_MINOR = [ "bulgarian", "croatian", "hungarian", "romanian", "slovakian" ] # get the common vehicles/ordnance def get_common_vo( fname ): """Get the vehicle/ordnance information from the specified file.""" fname = os.path.join( DATA_DIR, fname ) with open( fname, "r", encoding="utf-8" ) as fp: data = json.load( fp ) def get_gpid( val ): #pylint: disable=missing-docstring if isinstance( val, list ): val = val[0] assert isinstance(val,int) or val is None return val return [ ( vo["name"], get_gpid(vo["gpid"]) ) for vo in data ] common_vo = { "vehicles": { "allied": get_common_vo( "vehicles/allied-minor/common.json" ), "axis": get_common_vo( "vehicles/axis-minor/common.json" ), }, "ordnance": { "allied": get_common_vo( "ordnance/allied-minor/common.json" ), "axis": get_common_vo( "ordnance/axis-minor/common.json" ), }, } landing_craft = get_common_vo( "vehicles/landing-craft.json" ) tidy_vo_name_regex = re.compile( r" \([A-Za-z]+\)$" ) # nb: removes the trailing vehicle/ordnance type gpid_regex = re.compile( r"/counter/(\d+)/front" ) def get_vo_entry( elem ): """Get the vehicle/ordnance information from the Selenium element.""" vo_name = tidy_vo_name_regex.sub( "", elem.text ) image_url = find_child( "img", elem ).get_attribute( "src" ) mo = gpid_regex.search( image_url ) return ( vo_name, int(mo.group(1)) if mo else None ) def is_valid_vo_entry( vo_entry ): """Check if a V/O entry is valid.""" return isinstance( vo_entry, tuple ) and len(vo_entry) == 2 \ and isinstance( vo_entry[0], str ) \ and isinstance( vo_entry[1], (int,type(None)) ) def is_same_vo( lhs, rhs ): """Check if two V/O entries are the same.""" assert is_valid_vo_entry(lhs) and is_valid_vo_entry(rhs) return lhs == rhs def is_vo_entry_in_list( vo_entry, vo_entries ): """Check if a V/O entry appears in a list of V/O entries.""" assert is_valid_vo_entry( vo_entry ) return any( is_same_vo(vo_entry,e) for e in vo_entries ) # check the vehicles/ordnance for each nationality nationalities = get_nationalities( webapp ) for nat in nationalities: #pylint: disable=too-many-nested-blocks # select the next nationality set_player( 1, nat ) select_tab( "ob1" ) for vo_type in ("vehicles","ordnance"): # check if the nationality has any vehicles/ordnance elem = find_child( "#ob_{}-add_1".format( vo_type ) ) if nat in ["thai","indonesian","anzac","burmese","filipino"]: # nb: these are in the BFP extension assert not elem.is_enabled() continue if nat == "kfw-cpva" and vo_type == "vehicles": assert not elem.is_enabled() continue elem.click() # get the vehicles/ordnance vo_entries = find_children( "#select-vo .select2-results li" ) vo_entries = [ get_vo_entry(e) for e in vo_entries ] click_dialog_button( "Cancel" ) # check that the common vehicles/ordnance are present/absent if nat in ALLIED_MINOR: assert all( is_vo_entry_in_list( vo_entry, vo_entries ) for vo_entry in common_vo[vo_type]["allied"] ) elif nat in AXIS_MINOR: assert all( is_vo_entry_in_list( vo_entry, vo_entries ) for vo_entry in common_vo[vo_type]["axis"] ) else: assert all( not is_vo_entry_in_list( vo_entry, vo_entries ) for vo_entry in common_vo[vo_type]["allied"] ) assert all( not is_vo_entry_in_list( vo_entry, vo_entries ) for vo_entry in common_vo[vo_type]["axis"] ) # check that the landing craft are present/absent if vo_type == "vehicles": if nat in ("british","american"): for vo_entry in landing_craft: if vo_entry[0] in ("Daihatsu","Shohatsu"): assert not is_vo_entry_in_list( vo_entry, vo_entries ) else: assert is_vo_entry_in_list( vo_entry, vo_entries ) elif nat == "japanese": for vo_entry in landing_craft: if vo_entry[0] in ("Daihatsu","Shohatsu"): assert is_vo_entry_in_list( vo_entry, vo_entries ) else: assert not is_vo_entry_in_list( vo_entry, vo_entries ) else: assert all( not is_vo_entry_in_list( vo_entry, vo_entries ) for vo_entry in landing_craft )
def test_vo_images( webapp, webdriver ): #pylint: disable=too-many-statements """Test handling of vehicles/ordnance that have multiple images.""" # initialize webapp.control_tests \ .set_data_dir( "{REAL}" ) \ .set_vasl_version( "random", None ) init_webapp( webapp, webdriver, scenario_persistence=1 ) def check_sortable2_entries( player_no, expected ): """Check the settings on the player's vehicles.""" entries = find_children( "#ob_vehicles-sortable_{} li".format( player_no ) ) for i,entry in enumerate(entries): # check the displayed image elem = find_child( "img", entry ) assert elem.get_attribute( "src" ).endswith( expected[i][0] ) # check the attached data data = webdriver.execute_script( "return $(arguments[0]).data('sortable2-data')", entry ) assert data["vo_entry"]["id"] == expected[i][1] assert data["vo_image_id"] == expected[i][2] def check_save_scenario( player_no, expected ): """Check the vo_entry and vo_image_id fields are saved correctly.""" data = save_scenario() assert data[ "OB_VEHICLES_{}".format(player_no) ] == expected return data # start to add a PzKw VIB set_player( 1, "german" ) select_tab( "ob1" ) add_vehicle_btn = find_child( "#ob_vehicles-add_1" ) add_vehicle_btn.click() search_field = find_child( ".ui-dialog .select2-search__field" ) search_field.send_keys( "VIB" ) # make sure there is only 1 image available elem = find_child( "#select-vo .select2-results li img[class='vasl-image']" ) assert elem.get_attribute( "src" ).endswith( "/counter/2602/front" ) vo_images = webdriver.execute_script( "return $(arguments[0]).data('vo-images')", elem ) assert vo_images is None assert not find_child( "#select-vo .select2-results li input.select-vo-image" ) # add the PzKw VIB, make sure the sortable2 entry has its data set correctly search_field.send_keys( Keys.RETURN ) check_sortable2_entries( 1, [ ( "/counter/2602/front", "ge/v:035", None ) ] ) # check that the vehicles are saved correctly check_save_scenario( 1, [ { "id": "ge/v:035", "name": "PzKpfw VIB", "seq_id": 1 }, ] ) # start to add a PzKw IVH (this has multiple GPID's) add_vehicle_btn.click() search_field = find_child( ".ui-dialog .select2-search__field" ) search_field.send_keys( "IVH" ) # make sure multiple images are available elem = find_child( "#select-vo .select2-results li img[class='vasl-image']" ) assert elem.get_attribute( "src" ).endswith( "/counter/2584/front" ) vo_images = webdriver.execute_script( "return $(arguments[0]).data('vo-images')", elem ) assert vo_images == [ [2584,0], [2586,0], [2807,0], [2809,0] ] assert find_child( "#select-vo .select2-results li input.select-vo-image" ) # add the PzKw IVH, make sure the sortable2 entry has its data set correctly search_field.send_keys( Keys.RETURN ) check_sortable2_entries( 1, [ ( "/counter/2602/front", "ge/v:035", None ), ( "/counter/2584/front", "ge/v:027", None ) # nb: there is no V/O image ID if it's not necessary ] ) # check that the vehicles are saved correctly check_save_scenario( 1, [ { "id": "ge/v:035", "name": "PzKpfw VIB", "seq_id": 1 }, { "id": "ge/v:027", "name": "PzKpfw IVH", "seq_id": 2 }, # nb: there is no V/O image ID if it's not necessary ] ) # delete the PzKw IVH delete_vo( "vehicles", 1, "PzKpfw IVH", webdriver ) # add the PzKw IVH, with a different image, make sure the sortable2 entry has its data set correctly add_vehicle_btn.click() search_field = find_child( ".ui-dialog .select2-search__field" ) search_field.send_keys( "IVH" ) elem = find_child( "#select-vo .select2-results li img[class='vasl-image']" ) assert elem.get_attribute( "src" ).endswith( "/counter/2584/front" ) btn = find_child( "#select-vo .select2-results li input.select-vo-image" ) btn.click() images = find_children( ".ui-dialog.select-vo-image .vo-images img" ) assert len(images) == 4 images[2].click() check_sortable2_entries( 1, [ ( "/counter/2602/front", "ge/v:035", None ), ( "/counter/2807/front/0", "ge/v:027", [2807,0] ) ] ) # check that the vehicles are saved correctly check_save_scenario( 1, [ { "id": "ge/v:035", "name": "PzKpfw VIB", "seq_id": 1 }, { "id": "ge/v:027", "image_id": "2807/0", "name": "PzKpfw IVH", "seq_id": 2 }, ] ) # set the British as player 2 set_player( 2, "british" ) # start to add a 2pdr Portee (this has multiple images for a single GPID) select_tab( "ob2" ) add_vehicle_btn = find_child( "#ob_vehicles-add_2" ) add_vehicle_btn.click() search_field = find_child( ".ui-dialog .select2-search__field" ) search_field.send_keys( "2pdr" ) # make sure multiple images are available elem = find_child( "#select-vo .select2-results li img[class='vasl-image']" ) assert elem.get_attribute( "src" ).endswith( "/counter/1555/front" ) vo_images = webdriver.execute_script( "return $(arguments[0]).data('vo-images')", elem ) assert vo_images == [ [1555,0], [1555,1] ] assert find_child( "#select-vo .select2-results li input.select-vo-image" ) # add the 2pdr Portee, make sure the sortable2 entry has its data set correctly search_field.send_keys( Keys.RETURN ) check_sortable2_entries( 2, [ ( "/counter/1555/front", "br/v:115", None ) # nb: there is no V/O image ID if it's not necessary ] ) # check that the vehicles are saved correctly check_save_scenario( 2, [ { "id": "br/v:115", "name": "2pdr Portee", "seq_id": 1 }, # nb: there is no V/O image ID if it's not necessary ] ) # delete the 2pdr Portee delete_vo( "vehicles", 2, "2pdr Portee", webdriver ) # add the 2pdr Portee, with a different image, make sure the sortable2 entry has its data set correctly add_vehicle_btn.click() search_field = find_child( ".ui-dialog .select2-search__field" ) search_field.send_keys( "2pdr" ) elem = find_child( "#select-vo .select2-results li img[class='vasl-image']" ) assert elem.get_attribute( "src" ).endswith( "/counter/1555/front" ) btn = find_child( "#select-vo .select2-results li input.select-vo-image" ) btn.click() images = find_children( ".ui-dialog.select-vo-image .vo-images img" ) assert len(images) == 2 images[1].click() check_sortable2_entries( 2, [ ( "/counter/1555/front/1", "br/v:115", [1555,1] ) ] ) # check that the vehicles are saved correctly saved_scenario = check_save_scenario( 2, [ { "id": "br/v:115", "image_id": "1555/1", "name": "2pdr Portee", "seq_id": 1 }, ] ) # reset the scenario select_menu_option( "new_scenario" ) check_sortable2_entries( 1, [] ) check_sortable2_entries( 2, [] ) # load the last saved scenario, make sure the correct images are displayed load_scenario( saved_scenario ) check_sortable2_entries( 1, [ ( "/counter/2602/front", "ge/v:035", None ), ( "/counter/2807/front/0", "ge/v:027", ["2807",0] ) ] ) check_sortable2_entries( 2, [ ( "/counter/1555/front/1", "br/v:115", ["1555",1] ) ] )
def test_change_vo_image( webapp, webdriver ): """Test changing a V/O image.""" # initialize webapp.control_tests \ .set_data_dir( "{REAL}" ) \ .set_vasl_version( "random", None ) init_webapp( webapp, webdriver, scenario_persistence=1 ) # add an ISU-152 set_player( 2, "russian" ) add_vo( webdriver, "vehicles", 2, "ISU-152" ) # save the scenario saved_scenario = save_scenario() assert saved_scenario["OB_VEHICLES_2"] == [ { "id": "ru/v:049", "name": "ISU-152", "seq_id": 1 } ] # change the vehicle's image vehicles_sortable = find_child( "#ob_vehicles-sortable_2" ) elems = find_children( "li", vehicles_sortable ) assert len(elems) == 1 ActionChains(webdriver).double_click( elems[0] ).perform() img = find_child( "#edit-vo img.vasl-image" ) assert img.get_attribute( "src" ).endswith( "/counter/657/front" ) btn = find_child( "#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() assert img.get_attribute( "src" ).endswith( "/counter/659/front/0" ) click_dialog_button( "OK" ) elems = find_children( "img.vasl-image", vehicles_sortable ) assert len(elems) == 1 assert elems[0].get_attribute( "src" ).endswith( "/counter/659/front/0" ) # save the scenario saved_scenario = save_scenario() assert saved_scenario["OB_VEHICLES_2"] == [ { "id": "ru/v:049", "image_id": "659/0", "name": "ISU-152", "seq_id": 1 } ] # reload the scenario, and check the vehicle's image select_menu_option( "new_scenario" ) load_scenario( saved_scenario ) select_tab( "ob2" ) elems = find_children( "img.vasl-image", vehicles_sortable ) assert len(elems) == 1 assert elems[0].get_attribute( "src" ).endswith( "/counter/659/front/0" ) # change the vehicle's image back to the default elems = find_children( "li", vehicles_sortable ) assert len(elems) == 1 ActionChains(webdriver).double_click( elems[0] ).perform() img = find_child( "#edit-vo img.vasl-image" ) assert img.get_attribute( "src" ).endswith( "/counter/659/front/0" ) btn = find_child( "#edit-vo input.select-vo-image" ) btn.click() images = find_children( ".ui-dialog.select-vo-image .vo-images img" ) assert len(images) == 2 images[0].click() assert img.get_attribute( "src" ).endswith( "/counter/657/front/0" ) click_dialog_button( "OK" ) elems = find_children( "img.vasl-image", vehicles_sortable ) assert len(elems) == 1 assert elems[0].get_attribute( "src" ).endswith( "/counter/657/front/0" ) # save the scenario saved_scenario = save_scenario() assert saved_scenario["OB_VEHICLES_2"] == [ { "id": "ru/v:049", "image_id": "657/0", "name": "ISU-152", "seq_id": 1 } ]
def test_ffs_extensions(webapp, webdriver): """Test the Fight For Seoul extension.""" # check if the remote webapp server supports this test if not webapp.control_tests.has_capability("chapter-h"): return # analyze a VASL scenario that has the FfS counters webapp.control_tests \ .set_vassal_version( "random" ) \ .set_vasl_version( "random", None ) # nb: we don't load the extension init_webapp(webapp, webdriver, vsav_persistence=1, scenario_persistence=1) set_player(1, "american") analyze_vsav("ffs.vsav", [[], []], [[], []], ["No vehicles/ordnance were imported."]) # analyze the same VASL scenario with the FfS extension loaded webapp.control_tests \ .set_data_dir( "{REAL}" ) \ .set_vassal_version( "random" ) \ .set_vasl_version( "random", "{REAL}" ) \ .set_vo_notes_dir( "{REAL}" ) init_webapp(webapp, webdriver, vsav_persistence=1, scenario_persistence=1) set_player(1, "american") analyze_vsav("ffs.vsav", [["ffs/v:000"], ["ffs/o:000"]], [[], []], ["Imported 1 American vehicle and 1 ordnance."]) # NOTE: All the vehicle/ordnance and multi-applicable notes in the FfS extension # actually refer to K:FW, so we want to make sure we get the correct ones. select_tab("ob1") # check the vehicle's OB snippet btn = find_child("button.generate[data-id='ob_vehicles_1']") btn.click() wait_for_clipboard( 2, re.compile( 'POA-CWS-H5' '.+<div class="note"' '.+❖' '.+5\u2020, C, M', re.DOTALL)) # check the vehicle's multi-applicable notes btn = find_child("button.generate[data-id='ob_vehicles_ma_notes_1']") btn.click() clipboard = wait_for_clipboard(2, [ (True, "C", "37mm canister has 12"), (True, "M", "Used by the U.S.M.C."), ], transform=_extract_extn_ma_notes) # make sure we haven't incorrectly got the *American* multi-applicable notes assert "and is available in all theaters" not in clipboard # check the vehicle's Chapter H note sortable = find_child("#ob_vehicles-sortable_1") snippet = generate_sortable_entry_snippet(sortable, 0) assert "U.S.M.C. tankers gave the H5 the nickname" in snippet # check the ordnance's OB snippet btn = find_child("button.generate[data-id='ob_ordnance_1']") btn.click() wait_for_clipboard( 2, re.compile( r'M20\(L\) 75mm Recoilless Rifle' '.+<div class="note"' '.+❖' '.+25\u2020, K, M, O, P, R', re.DOTALL)) # check the ordnance's multi-applicable notes btn = find_child("button.generate[data-id='ob_ordnance_ma_notes_1']") btn.click() clipboard = wait_for_clipboard(2, [ (True, "K", "Used by ROK Army for"), (True, "M", "Used by the U.S.M.C."), (True, "O", "Used by one or more "), (True, "P", "Used by the Korean M"), (True, "R", "Used by Royal Marine"), ], transform=_extract_extn_ma_notes) # check the ordnance's Chapter H note sortable = find_child("#ob_ordnance-sortable_1") snippet = generate_sortable_entry_snippet(sortable, 0) assert "The KMC received their M20's in August 1951." in snippet
def test_player_change( webapp, webdriver ): """Test changing players.""" # initialize init_webapp( webapp, webdriver ) select_tab( "scenario" ) 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_nat = get_player_nat( player_no ) expected = "{} OB".format( get_nationality_display_name( player_nat ) ) assert ob_tabs[ player_no ].text.strip() == expected # check that we can change the player nationalities without being asked to confirm # nb: the frontend ignores the vehicle/ordnance snippet widths when deciding if to ask for confirmation VO_WIDTHS = { "ob1": { "OB_VEHICLES_WIDTH_1": 123 }, "ob2": { "OB_ORDNANCE_WIDTH_2": 456 }, } load_scenario_params( VO_WIDTHS ) set_player( 1, "russian" ) assert ob_tabs[1].text.strip() == "{} OB".format( get_nationality_display_name("russian") ) set_player( 2, "german" ) assert ob_tabs[2].text.strip() == "{} OB".format( get_nationality_display_name("german") ) # load the OB tabs SCENARIO_PARAMS = { "ob1": { "OB_SETUPS_1": [ { "caption": "an ob setup", "width": "" } ], }, "ob2": { "OB_VEHICLES_2": [ "a german vehicle" ], }, } load_scenario_params( SCENARIO_PARAMS ) def get_sortable_counts( player_no ): """Get the contents of the player's OB tab.""" sortables = [ find_child( "#{}-sortable_{}".format( key, player_no ) ) for key in ["ob_setups","ob_notes","ob_vehicles","ob_ordnance"] ] return [ get_sortable_entry_count(s) for s in sortables ] for player_no in [1,2]: # try to change the player's nationality set_player( player_no, "finnish" ) wait_for( 2, lambda: find_child("#ask") ) # cancel the confirmation request and make sure nothing changed click_dialog_button( "Cancel" ) nat_id = "russian" if player_no == 1 else "german" assert ob_tabs[player_no].text.strip() == "{} OB".format( get_nationality_display_name(nat_id) ) assert get_sortable_counts( player_no ) == \ [1,0,0,0] if player_no == 1 else [0,0,1,0] # try to change the player's nationality set_player( player_no, "finnish" ) wait_for( 2, lambda: find_child("#ask") ) # confirm the request and make sure the OB tab was cleared click_dialog_button( "OK" ) assert ob_tabs[player_no].text.strip() == "{} OB".format( get_nationality_display_name("finnish") ) assert get_sortable_counts( player_no ) == [0,0,0,0]
def _do_test_default_template_pack(webdriver): """Check that the default template pack is being used.""" set_player(1, "german") set_player(2, "russian") _check_snippets(webdriver, lambda tid: "New default {}.".format(tid.upper()))
def test_count_remaining_hilites( webapp, webdriver ): """Test highlighting in the "count remaining" extras template.""" # initialize webapp.control_tests.set_data_dir( "{REAL}" ) init_webapp( webapp, webdriver ) def do_test( month, year, expected ): #pylint: disable=missing-docstring # set the specified year set_template_params( { "SCENARIO_DATE": "{}/01/{}".format( month, year ) if year else "" } ) # select the "count remaining" template and check what's been highlighted select_tab( "extras" ) _select_extras_template( webdriver, "extras/count-remaining" ) for count_type in expected: table = find_child( "table.{}".format( count_type ) ) cells = [] for row in find_children( "tr", table ): row = list( find_children( "td", row ) ) assert len(row) == 2 bgd_col = row[1].value_of_css_property( "background-color" ) assert bgd_col.startswith( ( "rgb(", "rgba(" ) ) cells.append( bgd_col != "rgba(0, 0, 0, 0)" ) assert cells == expected[count_type] # do the tests set_player( 1, "german" ) set_player( 2, "japanese" ) do_test( None, None, { "pf": [ False, False, False, False, False, False, False ], "thh": [ False, False, False, False ] } ) do_test( 1, 1940, { "pf": [ True, False, False, False, False, False, False ], "thh": [ True, False, False, False ] } ) do_test( 1, 1941, { "pf": [ True, False, False, False, False, False, False ], "thh": [ True, False, False, False ] } ) do_test( 1, 1942, { "pf": [ True, False, False, False, False, False, False ], "thh": [ True, False, False, False ] } ) do_test( 1, 1943, { "pf": [ True, False, False, False, False, False, False ], "thh": [ False, True, False, False ] } ) do_test( 1, 1944, { "pf": [ False, True, False, False, False, False, False ], "thh": [ False, False, True, False ] } ) do_test( 1, 1945, { "pf": [ False, False, True, False, False, False, False ], "thh": [ False, False, False, True ] } ) do_test( 1, 1946, { "pf": [ False, False, False, False, False, False, False ], "thh": [ False, False, False, False ] } ) # do the tests set_player( 1, "finnish" ) set_player( 2, "russian" ) do_test( 6, 1944, { "pf": [ False, False, False, False, False, False, False ], "thh": [ False, False, False, False ] } ) do_test( 7, 1944, { "pf": [ False, False, False, True, False, False, False ], "thh": [ False, False, False, False ] } ) # do the tests set_player( 1, "hungarian" ) do_test( 5, 1944, { "pf": [ False, False, False, False, False, False, False ], "thh": [ False, False, False, False ] } ) do_test( 6, 1944, { "pf": [ False, False, False, False, True, False, False ], "thh": [ False, False, False, False ] } ) do_test( 1, 1945, { "pf": [ False, False, False, False, True, False, False ], "thh": [ False, False, False, False ] } ) # do the tests set_player( 1, "romanian" ) do_test( 2, 1944, { "pf": [ False, False, False, False, False, False, False ], "thh": [ False, False, False, False ] } ) do_test( 3, 1944, { "pf": [ False, False, False, False, False, True, False ], "thh": [ False, False, False, False ] } ) do_test( 1, 1945, { "pf": [ False, False, False, False, False, False, True ], "thh": [ False, False, False, False ] } )