Skip to content

Commit c01c308

Browse files
authored
Simplify bootstrap form tests (#286)
1 parent c8ec533 commit c01c308

File tree

5 files changed

+30
-71
lines changed

5 files changed

+30
-71
lines changed

.github/workflows/codeql.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646

4747
# Initializes the CodeQL tools for scanning.
4848
- name: Initialize CodeQL
49-
uses: github/codeql-action/init@v2
49+
uses: github/codeql-action/init@v3
5050
with:
5151
languages: ${{ matrix.language }}
5252
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -59,7 +59,7 @@ jobs:
5959
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
6060
# If this step fails, then you should remove it and run the build manually (see below)
6161
- name: Autobuild
62-
uses: github/codeql-action/autobuild@v2
62+
uses: github/codeql-action/autobuild@v3
6363

6464
# ℹ️ Command-line programs to run using the OS shell.
6565
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -72,6 +72,6 @@ jobs:
7272
# ./location_of_script_within_repo/buildscript.sh
7373

7474
- name: Perform CodeQL Analysis
75-
uses: github/codeql-action/analyze@v2
75+
uses: github/codeql-action/analyze@v3
7676
with:
7777
category: "/language:${{matrix.language}}"

tests/test_app/forms/components.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from reactpy_django.components import django_form
44

5-
from .forms import BasicForm, DatabaseBackedForm, EventForm
5+
from .forms import BasicForm, BootstrapForm, DatabaseBackedForm, EventForm
66

77

88
@component
@@ -13,7 +13,7 @@ def basic_form():
1313
@component
1414
def bootstrap_form():
1515
return django_form(
16-
BasicForm,
16+
BootstrapForm,
1717
extra_props={"style": {"maxWidth": "600px", "margin": "auto"}},
1818
form_template="bootstrap_form_template.html",
1919
)

tests/test_app/forms/forms.py

+7
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,10 @@ class Meta:
4848

4949
class EventForm(forms.Form):
5050
char_field = forms.CharField(label="chars")
51+
52+
53+
class BootstrapForm(forms.Form):
54+
# Render a handful of Django field types
55+
boolean_field = forms.BooleanField(label="boolean")
56+
char_field = forms.CharField(label="chars")
57+
choice_field = forms.ChoiceField(label="choice", choices=[("1", "One"), ("2", "Two")])

tests/test_app/tests/test_components.py

+8-65
Original file line numberDiff line numberDiff line change
@@ -776,10 +776,10 @@ def test_form_basic(self):
776776
model_choice_field_values[2],
777777
])
778778

779+
# Submit and wait for one of the error messages to disappear (indicating that the form has been re-rendered)
780+
invalid_feedback = self.page.locator(".errorlist").all()[0]
779781
self.page.wait_for_selector("input[type=submit]").click(delay=CLICK_DELAY)
780-
781-
# Wait for one of the error messages to disappear (indicating that the form has been re-rendered)
782-
expect(self.page.locator(".errorlist").all()[0]).not_to_be_attached()
782+
expect(invalid_feedback).not_to_be_attached()
783783
# Make sure no errors remain
784784
assert len(self.page.query_selector_all(".errorlist")) == 0
785785

@@ -801,82 +801,25 @@ def test_form_bootstrap(self):
801801
self.page.wait_for_selector("#id_boolean_field")
802802
self.page.wait_for_selector("#id_char_field")
803803
self.page.wait_for_selector("#id_choice_field")
804-
self.page.wait_for_selector("#id_date_field")
805-
self.page.wait_for_selector("#id_date_time_field")
806-
self.page.wait_for_selector("#id_decimal_field")
807-
self.page.wait_for_selector("#id_duration_field")
808-
self.page.wait_for_selector("#id_email_field")
809-
self.page.wait_for_selector("#id_file_path_field")
810-
self.page.wait_for_selector("#id_float_field")
811-
self.page.wait_for_selector("#id_generic_ip_address_field")
812-
self.page.wait_for_selector("#id_integer_field")
813-
self.page.wait_for_selector("#id_float_field")
814-
self.page.wait_for_selector("#id_json_field")
815-
self.page.wait_for_selector("#id_multiple_choice_field")
816-
self.page.wait_for_selector("#id_null_boolean_field")
817-
self.page.wait_for_selector("#id_regex_field")
818-
self.page.wait_for_selector("#id_slug_field")
819-
self.page.wait_for_selector("#id_time_field")
820-
self.page.wait_for_selector("#id_typed_choice_field")
821-
self.page.wait_for_selector("#id_typed_multiple_choice_field")
822-
self.page.wait_for_selector("#id_url_field")
823-
self.page.wait_for_selector("#id_uuid_field")
824-
self.page.wait_for_selector("#id_combo_field")
825-
self.page.wait_for_selector("#id_password_field")
826-
self.page.wait_for_selector("#id_model_choice_field")
827-
self.page.wait_for_selector("#id_model_multiple_choice_field")
828804

829805
sleep(1)
830806
self.page.wait_for_selector("button[type=submit]").click(delay=CLICK_DELAY)
831807
self.page.wait_for_selector(".invalid-feedback")
832808

833-
# Submitting an empty form should result in 22 error elements.
809+
# Submitting an empty form should result in 2 error elements.
834810
# The number of errors may change if/when new test form elements are created.
835-
assert len(self.page.query_selector_all(".invalid-feedback")) == 22
811+
assert len(self.page.query_selector_all(".invalid-feedback")) == 2
836812

837813
# Fill out the form
838814
self.page.wait_for_selector("#id_boolean_field").click(delay=CLICK_DELAY)
839815
expect(self.page.locator("#id_boolean_field")).to_be_checked()
840-
841816
self.page.locator("#id_char_field").type("test", delay=CLICK_DELAY)
842817
self.page.locator("#id_choice_field").select_option("2")
843-
self.page.locator("#id_date_field").type("2021-01-01", delay=CLICK_DELAY)
844-
self.page.locator("#id_date_time_field").type("2021-01-01 01:01:00", delay=CLICK_DELAY)
845-
self.page.locator("#id_decimal_field").type("0.123", delay=CLICK_DELAY)
846-
self.page.locator("#id_duration_field").type("1", delay=CLICK_DELAY)
847-
self.page.locator("#id_email_field").type("[email protected]", delay=CLICK_DELAY)
848-
file_path_field_options = self.page.query_selector_all("#id_file_path_field option")
849-
file_path_field_values: list[str] = [option.get_attribute("value") for option in file_path_field_options]
850-
self.page.locator("#id_file_path_field").select_option(file_path_field_values[1])
851-
self.page.locator("#id_float_field").type("1.2345", delay=CLICK_DELAY)
852-
self.page.locator("#id_generic_ip_address_field").type("127.0.0.1", delay=CLICK_DELAY)
853-
self.page.locator("#id_integer_field").type("123", delay=CLICK_DELAY)
854-
self.page.locator("#id_json_field").clear()
855-
self.page.locator("#id_json_field").type('{"key": "value"}', delay=CLICK_DELAY)
856-
self.page.locator("#id_multiple_choice_field").select_option(["2", "3"])
857-
self.page.locator("#id_null_boolean_field").select_option("false")
858-
self.page.locator("#id_regex_field").type("12", delay=CLICK_DELAY)
859-
self.page.locator("#id_slug_field").type("my-slug-text", delay=CLICK_DELAY)
860-
self.page.locator("#id_time_field").type("01:01:00", delay=CLICK_DELAY)
861-
self.page.locator("#id_typed_choice_field").select_option("2")
862-
self.page.locator("#id_typed_multiple_choice_field").select_option(["1", "2"])
863-
self.page.locator("#id_url_field").type("http://example.com", delay=CLICK_DELAY)
864-
self.page.locator("#id_uuid_field").type("550e8400-e29b-41d4-a716-446655440000", delay=CLICK_DELAY)
865-
self.page.locator("#id_combo_field").type("[email protected]", delay=CLICK_DELAY)
866-
self.page.locator("#id_password_field").type("password", delay=CLICK_DELAY)
867-
868-
model_choice_field_options = self.page.query_selector_all("#id_model_multiple_choice_field option")
869-
model_choice_field_values: list[str] = [option.get_attribute("value") for option in model_choice_field_options]
870-
self.page.locator("#id_model_choice_field").select_option(model_choice_field_values[0])
871-
self.page.locator("#id_model_multiple_choice_field").select_option([
872-
model_choice_field_values[1],
873-
model_choice_field_values[2],
874-
])
875818

819+
# Submit and wait for one of the error messages to disappear (indicating that the form has been re-rendered)
820+
invalid_feedback = self.page.locator(".invalid-feedback").all()[0]
876821
self.page.wait_for_selector("button[type=submit]").click(delay=CLICK_DELAY)
877-
878-
# Wait for one of the error messages to disappear (indicating that the form has been re-rendered)
879-
expect(self.page.locator(".invalid-feedback").all()[0]).not_to_be_attached()
822+
expect(invalid_feedback).not_to_be_attached()
880823
# Make sure no errors remain
881824
assert len(self.page.query_selector_all(".invalid-feedback")) == 0
882825

tests/test_app/tests/utils.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,16 @@ def start_playwright_client(cls):
117117
cls.browser = cls.playwright.chromium.launch(headless=bool(headless))
118118
cls.page = cls.browser.new_page()
119119
cls.page.set_default_timeout(10000)
120-
cls.page.on("console", lambda msg: _logger.error("error: %s", msg.text) if msg.type == "error" else None)
120+
cls.page.on("console", cls.playwright_logging)
121+
122+
@staticmethod
123+
def playwright_logging(msg):
124+
if msg.type == "error":
125+
_logger.error(msg.text)
126+
elif msg.type == "warning":
127+
_logger.warning(msg.text)
128+
elif msg.type == "info":
129+
_logger.info(msg.text)
121130

122131
@classmethod
123132
def shutdown_playwright_client(cls):

0 commit comments

Comments
 (0)