def test_import_scenario(webapp, webdriver): """Test importing a scenario.""" # initialize init_webapp(webapp, webdriver) # import the "full" scenario dlg = _do_scenario_search("full", [1], webdriver) find_child("button.import", dlg).click() wait_for( 2, lambda: _check_scenario(SCENARIO_NAME="Full content scenario", SCENARIO_ID="FCS-1", SCENARIO_LOCATION="Some place", PLAYER_1="dutch", PLAYER_1_DESCRIPTION="1st Dutch Army", PLAYER_2="romanian", PLAYER_2_DESCRIPTION="1st Romanian Army", THEATER="PTO")) # import the "empty" scenario _unlink_scenario() dlg = _do_scenario_search("Untitled", ["no-content"], webdriver) _import_scenario_and_confirm(dlg) # NOTE: Since there are no players defined in the scenario, what's on-screen will be left unchanged. wait_for( 2, lambda: _check_scenario(SCENARIO_NAME= "Untitled scenario (#no-content)", SCENARIO_ID="", SCENARIO_LOCATION="", PLAYER_1="dutch", PLAYER_1_DESCRIPTION="", PLAYER_2="romanian", PLAYER_2_DESCRIPTION="", THEATER="ETO"))
def init_webapp(webdriver, webapp_url, options): """Initialize the webapp.""" log("Initializing the webapp.") url = webapp_url + "?" + "&".join("{}=1".format(opt) for opt in options) url += "&store_msgs=1" # nb: stop notification balloons from building up webdriver.get(url) wait_for(5, lambda: find_child("#_page-loaded_", webdriver) is not None)
def do_upload(prep_upload, expect_ask): """Upload the scenario to our test endpoint.""" # show the scenario card find_child("button.scenario-search").click() wait_for(2, _find_scenario_card) # open the upload dialog find_child(".ui-dialog.scenario-info button.upload").click() dlg = wait_for_elem(2, ".ui-dialog.scenario-upload") if prep_upload: prep_upload(dlg) # start the upload webapp.control_tests.reset_last_asa_upload() find_child("button.upload", dlg).click() if expect_ask: dlg = wait_for_elem(2, ".ui-dialog.ask") find_child("button.ok", dlg).click() # wait for the upload to be processed last_asa_upload = wait_for(5, webapp.control_tests.get_last_asa_upload) assert last_asa_upload["user"] == user_name assert last_asa_upload["token"] == api_token return last_asa_upload
def save_scenario(): """Save the scenario.""" marker = set_stored_msg_marker("_scenario-persistence_") select_menu_option("save_scenario") wait_for(2, lambda: get_stored_msg("_scenario-persistence_") != marker) data = get_stored_msg("_scenario-persistence_") return json.loads(data)
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" ) )
def _analyze_vlogs(fnames): """Analyze log file(s).""" # initialize if isinstance(fnames, str): fnames = [fnames] select_menu_option("analyze_vlog") dlg = wait_for_elem(2, ".ui-dialog.lfa-upload") # add each log file for fno, fname in enumerate(fnames): fname = os.path.join( os.path.split(__file__)[0], "fixtures/analyze-vlog/" + fname) with open(fname, "rb") as fp: vlog_data = fp.read() set_stored_msg( "_vlog-persistence_", "{}|{}".format( os.path.split(fname)[1], base64.b64encode(vlog_data).decode("utf-8"))) find_child("#lfa-upload .{}".format("hint" if fno == 0 else "files"), dlg).click() wait_for(2, lambda: get_stored_msg("_vlog-persistence_") == "") # start the analysis find_child("button.ok", dlg).click() wait_for_elem(30, "#lfa")
def do_test(): #pylint: disable=missing-docstring # initialize init_webapp(webapp, webdriver, vlog_persistence=1, lfa_persistence=1) # analyze the log file _analyze_vlogs("custom-labels.vlog") # download the data marker = set_stored_msg_marker("_lfa-download_") find_child("#lfa button.download").click() wait_for(2, lambda: get_stored_msg("_lfa-download_") != marker) data = get_stored_msg("_lfa-download_") # check the results data = data.split("\n") rows = list(csv.reader(data, quoting=csv.QUOTE_NONNUMERIC)) assert rows == [[ "Log file", "Phase", "Player", "Type", "Die 1", "Die 2" ], ["custom-labels.vlog", "", "test", "Other", 5, 3], ["", "", "test", "Other", 3, ""], ["", "Custom Label 1", "test", "Other", 6, 6], ["", "", "test", "RS", 6, ""], ["", "Axis 1 PFPh", "test", "Other", 4, 4], ["", "", "test", "RS", 6, ""], ["", "Custom label 2", "test", "Other", 2, 1], ["", "", "test", "RS", 1, ""]]
def do_test(): #pylint: disable=missing-docstring # initialize init_webapp(webapp, webdriver, vlog_persistence=1, lfa_persistence=1) # analyze the log file _analyze_vlogs("download-test.vlog") # download the data marker = set_stored_msg_marker("_lfa-download_") find_child("#lfa button.download").click() wait_for(2, lambda: get_stored_msg("_lfa-download_") != marker) data = get_stored_msg("_lfa-download_") # check the results data = data.split("\n") rows = list(csv.reader(data, quoting=csv.QUOTE_NONNUMERIC)) assert rows == [[ "Log file", "Phase", "Player", "Type", "Die 1", "Die 2" ], ["download-test.vlog", "", 'Joey "The Lips" Blow', "IFT", 4, 1], ["", "", 'Joey "The Lips" Blow', "IFT", 2, 5], ["", "", 'Joey "The Lips" Blow', "RS", 2, ""], ["", "UN 1 PFPh", "\u65e5\u672c Guy", "IFT", 4, 6], ["", "", "\u65e5\u672c Guy", "IFT", 2, 6], ["", "", "\u65e5\u672c Guy", "RS", 3, ""], ["", "UN 1 MPh", 'Joey "The Lips" Blow', "IFT", 2, 6], ["", "", 'Joey "The Lips" Blow', "IFT", 2, 3], ["", "", 'Joey "The Lips" Blow', "RS", 3, ""]]
def load_scenario(scenario, webdriver=None): """Load a scenario into the UI.""" set_stored_msg("_scenario-persistence_", json.dumps(scenario), webdriver) _ = set_stored_msg_marker("_last-info_", webdriver) select_menu_option("load_scenario", webdriver) wait_for( 2, lambda: get_stored_msg("_last-info_", webdriver) == "The scenario was loaded.")
def check_is_dirty(expected): """Check if the scenario is being flagged as dirty.""" if expected: func = lambda: webdriver.title.endswith(" (*)") else: func = lambda: not webdriver.title.endswith(" (*)") # NOTE: There is a race condition here if things are not working properly. Since the window title # is updated on a timer, if we're expecting it to be (say) not modified, but the UI thinks that # it is modified, we could check the window title here, see that the scenario is being flagged # as not modified and continue on. The timer then fires, updates the UI to flag the scenario # as modified, and we will have missed the error. # To fix this, we force the scenario status to be updated. webdriver.execute_script("update_scenario_status()") wait_for(2, func)
def _check_warnings(expected, expected2): """Check any import warnings being shown.""" def do_check_warnings(): #pylint: """Get import warnings.""" warnings = [ c.get_attribute("name") for c in find_children( "#scenario-search .warnings input[type='checkbox']") ] warnings2 = [ c.text for c in find_children("#scenario-search .warnings .warning2") ] return warnings == expected and warnings2 == expected2 wait_for(2, do_check_warnings)
def prep_upload2(dlg): """Prepare the upload.""" assert asa_upload["user"] == user_name assert asa_upload["token"] == api_token # send the VSAV data to the front-end fname = os.path.join(os.path.dirname(__file__), "fixtures/update-vsav/full.vsav") with open(fname, "rb") as fp: vsav_data = fp.read() set_stored_msg("_vsav-persistence_", base64.b64encode(vsav_data).decode("utf-8")) find_child(".vsav-container", dlg).click() # wait for the files to be prepared wait_for( 60, lambda: "loader.gif" not in find_child( ".screenshot-container .preview img").get_attribute("src"))
def _update_vsav(fname, expected): """Update a VASL scenario.""" # read the VSAV data with open(fname, "rb") as fp: vsav_data = fp.read() # send the VSAV data to the front-end to be updated set_stored_msg("_vsav-persistence_", base64.b64encode(vsav_data).decode("utf-8")) _ = set_stored_msg_marker("_last-info_") _ = set_stored_msg_marker("_last-warning_") select_menu_option("update_vsav") # wait for the front-end to receive the data def check_response(): # NOTE: If something is misconfigured, the error response can get stored in the persistence buffer # really quickly i.e. before we get a chance to detect it here being cleared first. resp = get_stored_msg("_vsav-persistence_") return resp == "" or resp.startswith("ERROR:") wait_for(2, check_response) # wait for the updated data to come back timeout = 120 if os.name == "nt" else 60 wait_for(timeout, lambda: get_stored_msg("_vsav-persistence_") != "") updated_vsav_data = get_stored_msg("_vsav-persistence_") if updated_vsav_data.startswith("ERROR: "): raise RuntimeError(updated_vsav_data) updated_vsav_data = base64.b64decode(updated_vsav_data) # parse the VASSAL shim report if expected: report = {} msg = get_stored_msg("_last-warning_" if "deleted" in expected else "_last-info_") assert "The VASL scenario was updated:" in msg for mo2 in re.finditer("<li>([^<]+)", msg): mo3 = re.search(r"^(\d+) labels? (were|was) ([a-z]+)", mo2.group(1)) report[mo3.group(3)] = int(mo3.group(1)) assert report == expected else: assert "No changes were made" in get_stored_msg("_last-info_") return updated_vsav_data
def _select_extras_template( webdriver, template_id ): """Select the specified extras template.""" # find the specified template in the index elems = [ e for e in _get_extras_templates() if webdriver.execute_script( "return $(arguments[0]).data('template_id')", e ) == template_id ] assert len(elems) == 1 template_name = find_child( ".name", elems[0] ).text # select the template and wait for it to load elems[0].click() def is_template_loaded(): #pylint: disable=missing-docstring elem = find_child( "#tabs-extras .right-panel .name" ) return elem and elem.text == template_name wait_for( 2, is_template_loaded )
def _do_upload_template_pack(data, error_expected): """Upload a template pack.""" # upload the template pack set_stored_msg("_template-pack-persistence_", data) info_marker = set_stored_msg_marker("_last-info_") error_marker = set_stored_msg_marker("_last-error_") select_menu_option("template_pack") # wait for the front-end to finish if error_expected: func = lambda: get_stored_msg("_last-error_") != error_marker else: func = lambda: "was loaded" in get_stored_msg("_last-info_") wait_for(2, func) return info_marker, error_marker
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 get_vo_notes_report(webapp, webdriver, nat, vo_type): """Get a vehicle/ordnance notes report. NOTE: We can't get the report to return its results as, say, plain-text, for easy checking, since it's all done in Javascript, asynchronously i.e. we need something that will wait until the results are ready i.e. Selenium, not wget :-/ """ # initialize url = webapp.url_for("get_vo_notes_report", nat=nat, vo_type=vo_type) webdriver.get(url) wait_for(2, lambda: find_child("#results").is_displayed()) # parse the report vo_notes, ma_notes, keys = _parse_report(webdriver.page_source) return vo_notes, ma_notes, keys
def test_help(webapp, webdriver): """Test the help page.""" # initialize init_webapp(webapp, webdriver) # make sure the HELP tab is not visible def get_tabs(): """Get the visible tabs.""" return [ c.get_attribute("aria-controls") for c in find_children("#tabs .ui-tabs-tab") if c.is_displayed() ] assert "tabs-help" not in get_tabs() # show the help select_menu_option("show_help") # make sure that the HELP tab is now visible assert "tabs-help" in get_tabs() # check what's in the help iframe try: # switch to the frame webdriver.switch_to.frame(find_child("#tabs-help iframe")) # check that the content loaded OK assert "everyone's favorite scenario" in webdriver.page_source # check that the license loaded OK elem = wait_for_elem(2, "a.ui-tabs-anchor[href='#helptabs-license']") assert elem.is_displayed() wait_for( 2, lambda: "GNU AFFERO GENERAL PUBLIC LICENSE" in webdriver. page_source) assert "Version 3" in webdriver.page_source finally: # switch back to the main window webdriver.switch_to.default_content()
def test_oba_info(webapp, webdriver): """Test showing OBA info in the scenario card.""" # initialize init_webapp(webapp, webdriver) def check_oba_info(card, expected): """Check the OBA info.""" assert card["oba"] == expected assert "oba.png" in card["icons"] # search for the "OBA test" scenario dlg = _do_scenario_search("OBA test", ["5a"], webdriver) expected = [["Finnish", "6B", "3R", "Plentiful Ammo included"], ["German", "1B", "2R", "a comment", "another comment"]] check_oba_info(_unload_scenario_card(), expected) # import the scenario and check the OBA info find_child("button.import", dlg).click() wait_for(2, lambda: not dlg.is_displayed()) check_oba_info(_get_scenario_info(), expected) # change the scenario date and check the OBA info set_scenario_date("01/02/1943") check_oba_info(_get_scenario_info(), [["Finnish", "8B", "3R", "Plentiful Ammo included"], ["German", "1B", "2R", "a comment", "another comment"], "Based on a scenario date of 1/43."]) # change the scenario date and check the OBA info set_scenario_date("") check_oba_info(_get_scenario_info(), expected) # check a scenario where only the defender has OBA _do_scenario_search("Defender OBA", ["5b"], webdriver) check_oba_info(_unload_scenario_card(), [["Burmese", "-", "-"], None]) # check a scenario where the attacker has OBA, the defender is an unknwon nationality _do_scenario_search("Attacker OBA", ["5c"], webdriver) check_oba_info(_unload_scenario_card(), [["The Other Guy", "?", "?"], ["Russian", "3B", "4R"]])
def test_unknown_theaters(webapp, webdriver): """Test importing scenarios with unknown theaters.""" # initialize init_webapp(webapp, webdriver) # search for the "MTO" scenario (this has a theater mapping) set_theater("Korea") dlg = _do_scenario_search("MTO", ["3a"], webdriver) _click_import_button(dlg) wait_for(2, lambda: not dlg.is_displayed()) assert get_theater() == "ETO" # search for the "Africa" scenario (this has no theater mapping) new_scenario() set_theater("Korea") dlg = _do_scenario_search("Africa", ["3b"], webdriver) _click_import_button(dlg) _check_warnings([], ["Unknown theater: Africa"]) find_child("button.confirm-import", dlg).click() assert get_theater() == "other"
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
def analyze_vsav(fname, expected_ob1, expected_ob2, expected_report): """Analyze a VASL scenario.""" # read the VSAV data fname = os.path.join( os.path.split(__file__)[0], "fixtures/analyze-vsav/" + fname) with open(fname, "rb") as fp: vsav_data = fp.read() # send the VSAV data to the front-end to be analyzed set_stored_msg("_vsav-persistence_", base64.b64encode(vsav_data).decode("utf-8")) prev_info_msg = set_stored_msg_marker("_last-info_") set_stored_msg_marker("_last-warning_") select_menu_option("analyze_vsav") # wait for the analysis to finish wait_for(2, lambda: find_child("#please-wait").is_displayed()) wait_for(60, lambda: not find_child("#please-wait").is_displayed()) # check the results saved_scenario = save_scenario() def get_ids(key): #pylint: disable=missing-docstring return set( (v["id"], v.get("image_id")) for v in saved_scenario.get(key, [])) def adjust_expected(vals): #pylint: disable=missing-docstring return set(v if isinstance(v, tuple) else (v, None) for v in vals) assert get_ids("OB_VEHICLES_1") == adjust_expected(expected_ob1[0]) assert get_ids("OB_ORDNANCE_1") == adjust_expected(expected_ob1[1]) assert get_ids("OB_VEHICLES_2") == adjust_expected(expected_ob2[0]) assert get_ids("OB_ORDNANCE_2") == adjust_expected(expected_ob2[1]) # check the report msg = get_stored_msg("_last-info_") if msg == prev_info_msg: msg = get_stored_msg("_last-warning_") assert all(e in msg for e in expected_report)
def do_test(snippet_btn, expected_fname): #pylint: disable=missing-docstring # clear the return buffer ret_buffer = find_child("#_snippet-image-persistence_") assert ret_buffer.tag_name == "textarea" webdriver.execute_script("arguments[0].value = arguments[1]", ret_buffer, "") # shift-click the snippet button ActionChains(webdriver).key_down( Keys.SHIFT).click(snippet_btn).perform() ActionChains(webdriver).key_up(Keys.SHIFT).perform() # wait for the snippet image to be generated wait_for(20, lambda: ret_buffer.get_attribute("value")) fname, img_data = ret_buffer.get_attribute("value").split("|", 1) img_data = base64.b64decode(img_data) # check the results assert fname == expected_fname last_snippet_image = webapp.control_tests.get_last_snippet_image() assert img_data == last_snippet_image
def get_vo_report(webapp, webdriver, vo_type, nat, theater, year, month, name=None, merge_common=False): #pylint: disable=too-many-arguments,too-many-locals """Get a vehicle/ordnance report. NOTE: We can't get the V/O report to return its results as, say, plain-text, for easy checking, since it's all done in Javascript, asynchronously i.e. we need something that will wait until the results are ready i.e. Selenium, not wget :-/ """ # nb: in case the caller hasn't called init_webapp() test_utils._webdriver = webdriver #pylint: disable=protected-access # initialize url = webapp.url_for("get_vo_report", vo_type=vo_type, nat=nat, theater=theater, year=year, month=month) assert "?" in url if name: url += "&name={}".format(name) if merge_common: url += "&merge_common=1" webdriver.get(url) wait_for(2, lambda: find_child("#results").is_displayed()) # parse the report results = _parse_report(webdriver.page_source) return results
def _do_scenario_search(query, expected, webdriver): """Do a scenario search.""" # find the dialog dlg = find_child("#scenario-search") if not dlg.is_displayed(): select_tab("scenario") btn = find_child("button.scenario-search") ActionChains(webdriver).key_down(Keys.SHIFT).click(btn).perform() dlg = wait_for_elem(2, "#scenario-search") ActionChains(webdriver).key_up(Keys.SHIFT).perform() # initialize card = find_child(".scenario-card", dlg) seq_no = card.get_attribute("data-seqNo") # do the search and check the results elem = find_child("input.select2-search__field", dlg) elem.clear() # IMPORTANT: We can't use send_keys() here because it simulates a key-press for each character in the query, # and the incremental search feature means that we will constantly be loading scenario cards as the results # change, which makes it difficult for us to be able to tell when everything's stopped and it's safe to unload # the scenario card. Instead, we manually load the text box and trigger an event to update the UI. webdriver.execute_script( "arguments[0].value = arguments[1] ; $(arguments[0]).trigger('input')", elem, query) def check_search_results(): #pylint: disable=missing-docstring results = _unload_search_results() return [r[0] for r in results] == [str(e) for e in expected] wait_for(2, check_search_results) # wait for the scenario card to finish loading # NOTE: We do this here since the typical use case is to search for something, then check what was found. wait_for(2, lambda: card.get_attribute("data-seqNo") != seq_no) return dlg
def do_test(tab_id, param): """Test checking for a dirty scenario.""" # change the specified field check_is_dirty(False) select_tab(tab_id) state = change_field(param) check_is_dirty(True) # make sure we get asked to confirm a "new scenario" operation select_menu_option("new_scenario") wait_for(2, lambda: find_child("#ask") is not None) elem = find_child("#ask") assert "This scenario has been changed" in elem.text # cancel the confirmation request, make sure the change we made is still there click_dialog_button("Cancel") select_tab(tab_id) check_field(param, state) check_is_dirty(True) # revert the change revert_field(param, state) check_is_dirty(False) # we should now be able to reset the scenario without a confirmation _ = set_stored_msg_marker("_last-info_") select_menu_option("new_scenario") wait_for( 2, lambda: get_stored_msg("_last-info_") == "The scenario was reset.") # change the field again select_tab(tab_id) state = change_field(param) check_is_dirty(True) # make sure we get asked to confirm a "load scenario" operation select_menu_option("load_scenario") wait_for(2, lambda: find_child("#ask") is not None) elem = find_child("#ask") assert "This scenario has been changed" in elem.text # cancel the confirmation request, make sure the change we made is still there click_dialog_button("Cancel") select_tab(tab_id) check_field(param, state) check_is_dirty(True) # revert the change revert_field(param, state) check_is_dirty(False)
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_default_scenario(webapp, webdriver): """Test loading the default scenario.""" # initialize webapp.control_tests.set_default_scenario("new-default-scenario.json") init_webapp(webapp, webdriver) # wait for the scenario to load elem = find_child("input[name='SCENARIO_NAME']") wait_for(5, lambda: elem.get_attribute("value") != "") def check_textbox(field_name, expected): """Check that a field has been loaded correctly.""" elem = find_child("input[name='{}']".format(field_name)) assert elem.get_attribute("value") == expected def check_textarea(field_name, expected): """Check that a field has been loaded correctly.""" elem = find_child("textarea[name='{}']".format(field_name)) assert elem.get_attribute("value") == expected def check_droplist(field_name, expected): """Check that a field has been loaded correctly.""" elem = find_child("select[name='{}']".format(field_name)) assert Select(elem).first_selected_option.get_attribute( "value") == expected select_tab("scenario") # check the scenario fields check_textbox("SCENARIO_NAME", "default scenario name") check_textbox("SCENARIO_LOCATION", "default location") check_textbox("SCENARIO_DATE", "12/25/2000") check_textbox("SCENARIO_WIDTH", "1px") # check the player fields check_droplist("PLAYER_1", "american") check_droplist("PLAYER_1_ELR", "1") check_droplist("PLAYER_1_SAN", "2") check_droplist("PLAYER_2", "japanese") check_droplist("PLAYER_2_ELR", "3") check_droplist("PLAYER_2_SAN", "4") check_textbox("PLAYERS_WIDTH", "") # check the victory conditions check_textarea("VICTORY_CONDITIONS", "default victory conditions") check_textbox("VICTORY_CONDITIONS_WIDTH", "123px") # check the scenario notes assert get_sortable_entry_text( find_child( "#scenario_notes-sortable" ) ) \ == [ "default scenario note #{}".format(i) for i in [1,2,3] ] # nb: should check the snippet widths as well (not really important for a default scenario) # check the SSR's assert get_sortable_entry_text( find_child( "#ssr-sortable" ) ) \ == [ "default SSR #{}".format(i) for i in [1,2,3] ] check_textbox("SSR_WIDTH", "999px") select_tab("ob1") # check the OB setups/notes (player 1) assert get_sortable_entry_text( find_child( "#ob_setups-sortable_1" ) ) \ == [ "default american OB setup #{}".format(i) for i in [1,2] ] assert get_sortable_entry_text( find_child( "#ob_notes-sortable_1" ) ) \ == [ "default american OB note #{}".format(i) for i in [1,2] ] # nb: should check the snippet widths as well (not really important for a default scenario) # check the vehicles/ordnance (player 1) assert get_sortable_entry_text(find_child("#ob_vehicles-sortable_1")) == [] check_textbox("OB_VEHICLES_WIDTH_1", "110px") assert get_sortable_entry_text(find_child("#ob_ordnance-sortable_1")) == [] check_textbox("OB_ORDNANCE_WIDTH_1", "120px") select_tab("ob2") # check the OB setups/notes (player 2) assert get_sortable_entry_text( find_child( "#ob_setups-sortable_2" ) ) \ == [ "default japanese OB setup #{}".format(i) for i in [1,2] ] assert get_sortable_entry_text( find_child( "#ob_notes-sortable_2" ) ) \ == [ "default japanese OB note #{}".format(i) for i in [1,2] ] # nb: should check the snippet widths as well (not really important for a default scenario) # check the vehicles/ordnance (player 2) assert get_sortable_entry_text(find_child("#ob_vehicles-sortable_2")) == [] check_textbox("OB_VEHICLES_WIDTH_2", "210px") assert get_sortable_entry_text(find_child("#ob_ordnance-sortable_2")) == [] check_textbox("OB_ORDNANCE_WIDTH_2", "211px") # check that the default OB setup/note width is being used elem = find_child("#ob_setups-add_2") elem.click() elem = find_child(".ui-dialog-buttonpane input[name='width']") assert elem.get_attribute("value") == "900px" elem.send_keys(Keys.ESCAPE) elem = find_child("#ob_notes-add_2") elem.click() elem = find_child(".ui-dialog-buttonpane input[name='width']") assert elem.get_attribute("value") == "901px"
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"