def _generate_snippet(webdriver, template_id, orig_template_id): """Generate a snippet for the specified template.""" if template_id == "scenario_note": # create a scenario note and generate a snippet for it sortable = find_child("#scenario_notes-sortable") add_simple_note(sortable, "test scenario note", None) elems = find_children("li img.snippet", sortable) elem = elems[0] elif template_id in ("ob_setup", "ob_note"): # create a OB setup/note and generate a snippet for it select_tab("ob1") sortable = find_child("#{}s-sortable_1".format(template_id)) add_simple_note(sortable, "test {}".format(template_id), None) elems = find_children( "#{}s-sortable_1 li img.snippet".format(template_id)) elem = elems[0] elif template_id in ("ob_vehicle_note", "ob_ordnance_note"): # create a vehicle/ordnance and generate a snippet for its note mo = re.search(r"^ob_([a-z]+)_note_(\d)$", orig_template_id) vo_type, player_no = mo.group(1), int(mo.group(2)) vo_type0 = "vehicles" if vo_type == "vehicle" else vo_type player_nat = "german" if player_no == 1 else "russian" sortable = find_child("#ob_{}-sortable_{}".format(vo_type0, player_no)) add_vo(webdriver, vo_type0, player_no, "a {} {}".format(player_nat, vo_type)) elems = find_children("li img.snippet", sortable) elem = elems[0] else: # generate a snippet for the specified template elem = find_child( "button.generate[data-id='{}']".format(orig_template_id)) elem.click() return elem
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
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_extras_templates( webapp, webdriver ): """Test the extras templates.""" # initialize init_webapp( webapp, webdriver ) select_tab( "extras" ) # check that the extras templates were loaded correctly assert _get_extras_template_index() == [ ( "extras/minimal", None ), ( "Full template", "This is the caption." ), ( "select", None ), ] # check that the "full" template was loaded correctly _select_extras_template( webdriver, "extras/full" ) content = find_child( "#tabs-extras .right-panel" ) assert find_child( "div.name", content ).text == "Full template" assert find_child( "div.caption", content ).text == "This is the caption." assert find_child( "div.description", content ).text == "This is the description." params = find_children( "tr", content ) assert len(params) == 1 assert find_child( "td.caption", params[0] ).text == "The parameter:" textbox = find_child( "td.value input", params[0] ) assert textbox.get_attribute( "value" ) == "default-val" assert textbox.get_attribute( "size" ) == "10" assert textbox.get_attribute( "title" ) == "This is the parameter description." # generate the snippet snippet_btn = find_child( "button.generate", content ) snippet_btn.click() clipboard = wait_for_clipboard( 2, "param = default-val", contains=True ) assert "vasl-templates:comment" not in clipboard # nb: check that the comment was removed # check that the "minimal" template was loaded correctly _select_extras_template( webdriver, "extras/minimal" ) assert find_child( "div.name", content ).text == "extras/minimal" assert find_child( "div.caption", content ) is None assert find_child( "div.description", content ) is None params = find_children( "tr", content ) assert len(params) == 1 assert find_child( "td.caption", params[0] ).text == "PARAM:" textbox = find_child( "td.value input", params[0] ) assert textbox.get_attribute( "value" ) == "" # generate the snippet textbox.send_keys( "boo!" ) snippet_btn = find_child( "button.generate", content ) snippet_btn.click() clipboard = wait_for_clipboard( 2, "param = boo!", contains=True )
def check_buttons(fname, sel, is_snippet_control): #pylint: disable=missing-docstring for btn in find_children(sel): # check the UI state of the next button template_id = adjust_template_id(btn.get_attribute("data-id")) if fname == "national-capabilities.json": expected = False # nb: this is the JSON file, not the template file, and so doesn't effect buttons elif fname == "nat_caps.j2": expected = template_id.startswith("nat_caps_") else: expected = os.path.splitext(fname)[0] == template_id disabled = webdriver.execute_script( "return $(arguments[0]).button('option','disabled')", btn) assert expected == disabled # check that snippet control groups have been enabled/disabled correctly parent = btn.find_element_by_xpath("..") parent_classes = get_css_classes(parent) if is_snippet_control: assert "snippet-control" in parent_classes elem = find_child(".ui-selectmenu-button", parent) elem_classes = get_css_classes(elem) if expected: assert "ui-selectmenu-disabled" in elem_classes else: assert "ui-selectmenu-disabled" not in elem_classes else: assert "snippet-control" not in parent_classes
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"])
def _unlink_scenario(): """Unlink the scenario from the ASL Scenario Archive.""" find_child("button.scenario-search").click() wait_for_elem(2, "#scenario-info-dialog") btn = find_children(".ui-dialog .ui-dialog-buttonpane button")[1] assert btn.text == "Unlink" btn.click()
def _unload_search_results(): """Unload the current search results.""" results = [] for sr in find_children( "#scenario-search .select2-results .search-result"): results.append((sr.get_attribute("data-id"), sr)) return results
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
def check_snippet( sortable, entry_no, expected ): """Generate the snippet for an OB setup/note.""" elems = find_children( "li img.snippet", sortable ) elems[entry_no].click() if ob_type == "ob_notes": expected = re.sub( r" \(col=.*?\)", "", expected ) assert wait_for_clipboard( 2, expected, transform=adjust_html )
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)
def check_color_pickers(expected): """Check which color pickers are being presented to the user.""" find_child("#lfa .options button.player-colors").click() popup = wait_for_elem(2, "#lfa .player-colors-popup") player_names = [ e.text for e in find_children(".row .caption", popup) if e.text ] assert player_names.pop() == "expected results" assert player_names == expected
def _select_log_file(fname): """Select one of the log files being analyzed.""" find_child("#lfa .banner .select-file").click() popup = wait_for_elem(2, "#lfa .select-file-popup") for row in find_children(".row", popup): if find_child("label", row).text == fname: find_child("input[type='radio']", row).click() return assert False, "Couldn't find file: " + fname
def test_vo_notes_image_cache(webapp, webdriver): """Test the vehicle/ordnance notes image cache.""" 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" }, ], }) # initialize webapp.control_tests.set_vo_notes_dir("{TEST}") init_test() # get the vehicle note snippet select_tab("ob1") elems = find_children("#ob_vehicles-sortable_1 li") assert len(elems) == 1 btn = find_child("img.snippet", elems[0]) btn.click() expected = ("japanese vehicle", "vehicles/japanese/note/2") snippet = wait_for_clipboard(2, expected, transform=_extract_vo_note) mo = re.search(r"<img src=\"(.+?)\">", snippet) url = mo.group(1) # get the vehicle note image (should be created) with urllib.request.urlopen(url) as resp: assert not resp.headers.get("X-WasCached") image_data = resp.read() # get the vehicle note image (should be re-created) with urllib.request.urlopen(url) as resp: assert not resp.headers.get("X-WasCached") assert resp.read() == image_data # enable image caching webapp.control_tests.set_app_config_val("VO_NOTES_IMAGE_CACHE_DIR", "{{TEMP_DIR}}") init_test() # get the vehicle note image (should be re-created) with urllib.request.urlopen(url) as resp: assert not resp.headers.get("X-WasCached") assert resp.read() == image_data # get the vehicle note image (should be cached) with urllib.request.urlopen(url) as resp: assert resp.headers.get("X-WasCached") assert resp.read() == image_data
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]
def _get_scenario_info(): """Open the scenario info and unload the information.""" btn = find_child("button.scenario-search") assert find_child("img", btn).get_attribute("src").endswith("/info.gif") btn.click() wait_for_elem(2, "#scenario-info-dialog") card = _unload_scenario_card() btn = find_children(".ui-dialog .ui-dialog-buttonpane button")[0] assert btn.text == "OK" btn.click() return card
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 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 _unload_balance_graphs(parent): """Unload balance graph(s).""" def get_player_no(elem): """Figure out what player an element belongs to.""" # FUDGE! Selenium doesn't seem to let us select elements using things like ".wins.player1", # so we have to iterate over all ".wins" elements, and figure out which player each one belongs to :-/ classes = elem.get_attribute("class") if "player1" in classes: return 0 elif "player2" in classes: return 1 else: assert False return -1 # unload the balance graphs balances = {} balance_graphs = find_children(".balance-graph", parent) or [] for bgraph in balance_graphs: if not bgraph.is_displayed(): continue balance = [{}, {}] for elem in find_children(".player", bgraph): balance[get_player_no(elem)]["name"] = elem.text for elem in find_children(".wins", bgraph): wins = elem.text assert wins.startswith("(") and wins.endswith(")") balance[get_player_no(elem)]["wins"] = int(wins[1:-1]) for elem in find_children(".progressbar", bgraph): percentage = int(elem.get_attribute("aria-valuenow")) player_no = get_player_no(elem) if player_no == 0: percentage = 100 - percentage balance[player_no]["percentage"] = percentage classes = [c for c in get_css_classes(bgraph) if c != "balance-graph"] assert len(classes) == 1 balances[classes[0]] = balance return balances
def _check_vo_snippets(player_no, vo_type, expected): """Generate and check vehicle/ordnance snippets.""" select_tab("ob{}".format(player_no)) sortable = find_child("#ob_{}-sortable_{}".format(vo_type, player_no)) elems = find_children("li", sortable) assert len(elems) == len(expected) for i, elem in enumerate(elems): btn = find_child("img.snippet", elem) if expected[i]: btn.click() wait_for_clipboard(2, expected[i], transform=_extract_vo_note) else: assert btn is None
def delete_vo( vo_type, player_no, name, webdriver ): """Delete a vehicle/ordnance.""" # delete the vehicle/ordnance select_tab( "ob{}".format( player_no ) ) sortable = find_child( "#ob_{}-sortable_{}".format( vo_type, player_no ) ) elems = [ c for c in find_children( "li .vo-name", sortable ) if c.text == name ] assert len(elems) == 1 elem = elems[0] trash = find_child( "#ob_{}-trash_{}".format( vo_type, player_no ) ) ActionChains(webdriver).drag_and_drop( elem, trash ).perform()
def check_counter_images(veh_name, expected): """Check the counter images available for the specified vehicle.""" # add the specified vehicle add_vo(webdriver, "vehicles", 2, veh_name) # edit the vehicle vehicles_sortable = find_child("#ob_vehicles-sortable_2") elems = find_children("li", vehicles_sortable) ActionChains(webdriver).double_click(elems[-1]).perform() dlg = find_child(".ui-dialog.edit-vo") # check the currently-selected counter image_url = find_child("img.vasl-image", dlg).get_attribute("src") if expected: assert image_url.endswith("/counter/{}/front".format(expected[0])) else: assert image_url.endswith("/missing-image.png") # check the available counters btn = find_child("input.select-vo-image", dlg) if expected and len(expected) > 1: btn.click() dlg2 = find_child(".ui-dialog.select-vo-image") image_urls = [ elem.get_attribute("src") for elem in find_children(".vo-images img", dlg2) ] assert len(image_urls) == len(expected) for image_url, piece_id in zip(image_urls, expected): assert image_url.endswith( "/counter/{}/front/0".format(piece_id)) dlg2.send_keys(Keys.ESCAPE) else: assert btn is None dlg.send_keys(Keys.ESCAPE)
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
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 add_vo( webdriver, vo_type, player_no, name ): #pylint: disable=unused-argument """Add a vehicle/ordnance.""" # add the vehicle/ordnance select_tab( "ob{}".format( player_no ) ) elem = find_child( "#ob_{}-add_{}".format( vo_type, player_no ) ) elem.click() # FUDGE! Locating the vehicle/ordnance by name and selecting it is finicky, I suspect # because select2 is sensitive about where the mouse is, and we sometimes end up # selecting the wrong item :-/ Selecting by name won't work if there are multiple items # that start with the same thing, but that shouldn't be a problem. dlg = find_child( "#select-vo" ) elem = find_child( "input", dlg ) elem.send_keys( name ) entries = find_children( ".select2-results li", dlg ) assert len(entries) == 1 click_dialog_button( "OK" )
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 _unload_aslrb2_urls(base_url): """Unload the URL's to the asl-rulebook2 vehicle/ordnance notes.""" urls = [[[], []], [[], []]] for player_no in (1, 2): for vo_type_index, vo_type in enumerate(["vehicles", "ordnance"]): sortable = find_child("#ob_{}-sortable_{}".format( vo_type, player_no)) urls2 = urls[player_no - 1][vo_type_index] for vo_entry in find_children(".vo-entry", sortable): link = find_child("a.aslrb2", vo_entry) if link: url = link.get_attribute("href") if url.startswith(base_url): url = url[len(base_url):] else: url = None urls2.append(url) return urls
def test_edit_extras_template( webapp, webdriver ): """Test editing an extras templates.""" # initialize init_webapp( webapp, webdriver ) select_tab( "extras" ) # edit the "minimal" template _select_extras_template( webdriver, "extras/minimal" ) content = find_child( "#tabs-extras .right-panel" ) assert find_child( "div.caption", content ) is None webdriver.execute_script( "edit_template('extras/minimal')", content ) textarea = find_child( "#edit-template textarea" ) template = textarea.get_attribute( "value" ) \ .replace( "<html>", "<html>\n<!-- vasl-templates:caption Modified minimal. -->" ) \ .replace( "<div>", "<div>\nadded = {{ADDED:added-val}}" ) textarea.clear() textarea.send_keys( template ) textarea.send_keys( Keys.ESCAPE ) # generate the template (we should still be using the old template) snippet_btn = find_child( "button.generate", content ) snippet_btn.click() wait_for_clipboard( 2, "param =", contains=True ) # switch to another template, then back again _select_extras_template( webdriver, "extras/full" ) _select_extras_template( webdriver, "extras/minimal" ) # make sure the new template was loaded assert find_child( "div.caption", content ).text == "Modified minimal." params = find_children( "tr", content ) assert len(params) == 2 assert find_child( "td.caption", params[0] ).text == "ADDED:" textbox = find_child( "td.value input", params[0] ) assert textbox.get_attribute( "value" ) == "added-val" # generate the template (we should be using the new template) snippet_btn = find_child( "button.generate", content ) snippet_btn.click() wait_for_clipboard( 2, "added = added-val\nparam =", contains=True )
def test_template_pack( webapp, webdriver ): """Test uploading a template pack that contains extras templates.""" # initialize init_webapp( webapp, webdriver, template_pack_persistence=1 ) select_tab( "extras" ) # check that the extras templates were loaded correctly assert _get_extras_template_index() == [ ( "extras/minimal", None ), ( "Full template", "This is the caption." ), ( "select", None ), ] # upload the template pack zip_data = make_zip_from_files( "extras" ) upload_template_pack_zip( zip_data, False ) # check that the templates were updated correctly assert _get_extras_template_index() == [ ( "extras/minimal", None ), ( "Full template (modified)", "This is the caption (modified)." ), ( "New template", None ), ( "select", None ), ] # check that the modified "full" template is being used _select_extras_template( webdriver, "extras/full" ) content = find_child( "#tabs-extras .right-panel" ) assert find_child( "div.name", content ).text == "Full template (modified)" assert find_child( "div.caption", content ).text == "This is the caption (modified)." params = find_children( "tr", content ) assert len(params) == 2 assert find_child( "td.caption", params[0] ).text == "The modified parameter:" textbox = find_child( "td.value input", params[0] ) assert textbox.get_attribute( "value" ) == "modified-default-val" assert textbox.get_attribute( "size" ) == "10" assert textbox.get_attribute( "title" ) == "This is the modified parameter description." assert find_child( "td.caption", params[1] ).text == "NEW-PARAM:" textbox = find_child( "td.value input", params[1] )
def test_droplists( webapp, webdriver ): """Test droplist's in extras templates.""" # initialize init_webapp( webapp, webdriver ) select_tab( "extras" ) # load the "droplist" template _select_extras_template( webdriver, "extras/droplist" ) content = find_child( "#tabs-extras .right-panel" ) params = find_children( "tr", content ) assert len(params) == 1 sel = Select( find_child( "td.value select", params[0] ) ) vals = get_droplist_vals( sel ) assert vals == [ ("item 1","item 1"), ("item 2","item 2"), ("item 3","item 3") ] # generate the snippet for each droplist choice for i in range(1,3+1): select_droplist_val( sel, "item {}".format(i) ) snippet_btn = find_child( "button.generate", content ) snippet_btn.click() wait_for_clipboard( 2, "Selected: item {}".format(i) )