diff --git a/index.html b/index.html index 5b24bea..09d905d 100644 --- a/index.html +++ b/index.html @@ -41,6 +41,28 @@ // Show the instructions/form when JavaScript is enabled document.querySelector(".container").style.display = "block"; }); + + // Custom validation for select elements + document.getElementById("contact-form").addEventListener("submit", function(event) { + if (!this.checkValidity()) { + // Built-in validation failed, no need to continue + return; + } + + // Custom validation for select elements + var selectElements = this.querySelectorAll("select[required]"); + for (var i = 0; i < selectElements.length; i++) { + if (selectElements[i].value === "") { + event.preventDefault(); // Prevent form submission + alert("Please select a value."); + + // Scroll to the element + selectElements[i].scrollIntoView({ behavior: "smooth", block: "center" }); + + return; + } + } + }); diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py index ababb42..f204c02 100644 --- a/tests/test_fixtures.py +++ b/tests/test_fixtures.py @@ -182,3 +182,38 @@ def test_multi_options_config_schema( assert check_config_schema( multiple_select_options_config ), "Error in multi options config fixture." + + +@pytest.mark.fixture +def test_multi_opts_config_multiple( + multiple_select_options_config: Dict[str, Any] +) -> None: + """Confirm that the multi selection options config has multiple options.""" + # get questions + question = multiple_select_options_config["questions"][0] + + # check multiple options + assert len(question["options"]) > 1 + + # check custom.multiple attr set + assert question["custom"]["multiple"] + + +@pytest.mark.fixture +def test_multi_opts_config_defaults( + multiple_select_options_config: Dict[str, Any] +) -> None: + """Check that at least one options is selected and disabled.""" + # get options + options = multiple_select_options_config["questions"][0]["options"] + + # results store + results = [] + + # loop over options + for opt in options: + # check for default + results.append(opt.get("selected", False) and opt.get("disabled", False)) + + # now check results + assert any(results) diff --git a/tests/test_website.py b/tests/test_website.py index e1460a6..6b914e8 100644 --- a/tests/test_website.py +++ b/tests/test_website.py @@ -491,7 +491,6 @@ def test_form_download_required_constraint( sb.save_screenshot_to_logs() -@pytest.mark.debug @pytest.mark.feature def test_select_multiple_options( sb: BaseCase, @@ -571,3 +570,55 @@ def test_select_multiple_options( # save screenshot for confirmation of submission sb.save_screenshot_to_logs() + + +@pytest.mark.feature +def test_select_default_submission_rejected( + sb: BaseCase, + live_function_web_app_url: str, + submit_route: str, + function_websrc_tmp_dir: Path, + function_web_app: Flask, + multiple_select_options_config: Dict[str, Any], +) -> None: + """Confirm that default select options will not pass for submission.""" + # add form backend + multiple_select_options_config["form_backend_url"] = ( + live_function_web_app_url + submit_route + ) + + # update config file for testing multi select options + write_config_file(multiple_select_options_config, function_websrc_tmp_dir) + + # open site + sb.open(live_function_web_app_url) + + # get form + form_element = sb.get_element("form") + + # get send button ... + send_button = form_element.find_element(By.ID, "send_button") + + # store page source before + page_source = {"before": sb.get_page_source()} + + # get screenshot + sb.save_screenshot_to_logs() + + # ... now click it + send_button.click() + + # switch to the alert and get its text + alert_text = sb.switch_to_alert().text + + # now accept it + sb.accept_alert() + + # make sure alert texts match + assert alert_text == "Please select a value." + + # now store it after + page_source["after"] = sb.get_page_source() + + # should NOT see contact form response + assert page_source["before"] == page_source["after"]