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
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
    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" )
        )
Exemplo n.º 6
0
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")
Exemplo n.º 7
0
    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, ""]]
Exemplo n.º 8
0
    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, ""]]
Exemplo n.º 9
0
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.")
Exemplo n.º 10
0
 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"))
Exemplo n.º 13
0
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
Exemplo n.º 14
0
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 )
Exemplo n.º 15
0
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
Exemplo n.º 17
0
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
Exemplo n.º 18
0
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
Exemplo n.º 22
0
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)
Exemplo n.º 23
0
    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
Exemplo n.º 24
0
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
Exemplo n.º 26
0
    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"
Exemplo n.º 28
0
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"