From 83c4e222473020f3c154f8f43a8f43448b22f9d3 Mon Sep 17 00:00:00 2001 From: Psychpsyo Date: Mon, 17 Feb 2025 20:44:26 +0100 Subject: [PATCH] LibWeb: Implement validity IDL attribute --- .../LibWeb/HTML/FormAssociatedElement.cpp | 8 + Libraries/LibWeb/HTML/FormAssociatedElement.h | 3 + Libraries/LibWeb/HTML/HTMLButtonElement.idl | 3 +- Libraries/LibWeb/HTML/HTMLInputElement.cpp | 11 - Libraries/LibWeb/HTML/HTMLInputElement.h | 2 - Libraries/LibWeb/HTML/HTMLObjectElement.idl | 3 +- Libraries/LibWeb/HTML/HTMLOutputElement.idl | 3 +- Libraries/LibWeb/HTML/HTMLSelectElement.idl | 3 +- Libraries/LibWeb/HTML/HTMLTextAreaElement.idl | 3 +- Libraries/LibWeb/HTML/ValidityState.cpp | 91 +++- Libraries/LibWeb/HTML/ValidityState.h | 31 +- Libraries/LibWeb/HTML/ValidityState.idl | 22 +- ...form-validation-validity-rangeOverflow.txt | 55 ++ ...orm-validation-validity-rangeUnderflow.txt | 53 ++ .../form-validation-validity-tooLong.txt | 68 +++ .../form-validation-validity-tooShort.txt | 68 +++ .../form-validation-validity-typeMismatch.txt | 17 + .../form-validation-validity-valueMissing.txt | 84 +++ .../forms/constraints/radio-valueMissing.txt | 12 + .../the-button-element/button-validity.txt | 6 + .../the-input-element/input-validity.txt | 6 + .../forms/the-input-element/radio.txt | 18 + ...orm-validation-validity-rangeOverflow.html | 89 ++++ ...rm-validation-validity-rangeUnderflow.html | 87 ++++ .../form-validation-validity-tooLong.html | 50 ++ .../form-validation-validity-tooShort.html | 52 ++ ...form-validation-validity-typeMismatch.html | 41 ++ ...form-validation-validity-valueMissing.html | 147 ++++++ .../forms/constraints/radio-valueMissing.html | 90 ++++ .../forms/constraints/support/validator.js | 481 ++++++++++++++++++ .../the-button-element/button-validity.html | 40 ++ .../the-input-element/input-validity.html | 40 ++ .../forms/the-input-element/radio.html | 351 +++++++++++++ 33 files changed, 2007 insertions(+), 31 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-tooLong.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-tooShort.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-typeMismatch.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-valueMissing.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/radio-valueMissing.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-button-element/button-validity.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/input-validity.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/radio.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-tooLong.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-tooShort.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-typeMismatch.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-valueMissing.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/radio-valueMissing.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/support/validator.js create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-button-element/button-validity.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/input-validity.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/radio.html diff --git a/Libraries/LibWeb/HTML/FormAssociatedElement.cpp b/Libraries/LibWeb/HTML/FormAssociatedElement.cpp index effb79e8488..f118bfb6f9d 100644 --- a/Libraries/LibWeb/HTML/FormAssociatedElement.cpp +++ b/Libraries/LibWeb/HTML/FormAssociatedElement.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -48,6 +49,13 @@ void FormAssociatedElement::set_form(HTMLFormElement* form) m_form->add_associated_element({}, form_associated_element_to_html_element()); } +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-validity +GC::Ref FormAssociatedElement::validity() const +{ + auto& realm = form_associated_element_to_html_element().realm(); + return realm.create(realm, *this); +} + bool FormAssociatedElement::enabled() const { // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-fe-disabled diff --git a/Libraries/LibWeb/HTML/FormAssociatedElement.h b/Libraries/LibWeb/HTML/FormAssociatedElement.h index 3d101bb15be..c7af447946f 100644 --- a/Libraries/LibWeb/HTML/FormAssociatedElement.h +++ b/Libraries/LibWeb/HTML/FormAssociatedElement.h @@ -122,6 +122,9 @@ public: String form_action() const; WebIDL::ExceptionOr set_form_action(String const&); + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-validity + GC::Ref validity() const; + protected: FormAssociatedElement() = default; virtual ~FormAssociatedElement() = default; diff --git a/Libraries/LibWeb/HTML/HTMLButtonElement.idl b/Libraries/LibWeb/HTML/HTMLButtonElement.idl index 501a1d78981..21d70b3fa88 100644 --- a/Libraries/LibWeb/HTML/HTMLButtonElement.idl +++ b/Libraries/LibWeb/HTML/HTMLButtonElement.idl @@ -1,6 +1,7 @@ #import #import #import +#import [MissingValueDefault=submit, InvalidValueDefault=submit] enum ButtonTypeState { @@ -26,7 +27,7 @@ interface HTMLButtonElement : HTMLElement { [CEReactions, Reflect] attribute DOMString value; [FIXME] readonly attribute boolean willValidate; - [FIXME] readonly attribute ValidityState validity; + readonly attribute ValidityState validity; [FIXME] readonly attribute DOMString validationMessage; [FIXME] boolean checkValidity(); [FIXME] boolean reportValidity(); diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 03ac046eccd..2a7111fc9ba 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -90,16 +89,6 @@ void HTMLInputElement::visit_edges(Cell::Visitor& visitor) visitor.visit(m_resource_request); } -// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-validity -GC::Ref HTMLInputElement::validity() const -{ - auto& realm = this->realm(); - - dbgln("FIXME: Implement validity attribute getter"); - - return realm.create(realm); -} - GC::Ptr HTMLInputElement::create_layout_node(GC::Ref style) { if (type_state() == TypeAttributeState::Hidden) diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.h b/Libraries/LibWeb/HTML/HTMLInputElement.h index 494cc556f17..a2f024e4851 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.h +++ b/Libraries/LibWeb/HTML/HTMLInputElement.h @@ -191,8 +191,6 @@ public: virtual WebIDL::ExceptionOr cloned(Node&, bool) const override; - GC::Ref validity() const; - // ^HTMLElement // https://html.spec.whatwg.org/multipage/forms.html#category-label virtual bool is_labelable() const override { return type_state() != TypeAttributeState::Hidden; } diff --git a/Libraries/LibWeb/HTML/HTMLObjectElement.idl b/Libraries/LibWeb/HTML/HTMLObjectElement.idl index cb0df5ba761..7d8c1342f12 100644 --- a/Libraries/LibWeb/HTML/HTMLObjectElement.idl +++ b/Libraries/LibWeb/HTML/HTMLObjectElement.idl @@ -1,5 +1,6 @@ #import #import +#import // https://html.spec.whatwg.org/multipage/iframe-embed-object.html#htmlobjectelement [Exposed=Window] @@ -18,7 +19,7 @@ interface HTMLObjectElement : HTMLElement { Document? getSVGDocument(); [FIXME] readonly attribute boolean willValidate; - [FIXME] readonly attribute ValidityState validity; + readonly attribute ValidityState validity; [FIXME] readonly attribute DOMString validationMessage; [FIXME] boolean checkValidity(); [FIXME] boolean reportValidity(); diff --git a/Libraries/LibWeb/HTML/HTMLOutputElement.idl b/Libraries/LibWeb/HTML/HTMLOutputElement.idl index 22bec6ba433..2a3a64be0bf 100644 --- a/Libraries/LibWeb/HTML/HTMLOutputElement.idl +++ b/Libraries/LibWeb/HTML/HTMLOutputElement.idl @@ -1,5 +1,6 @@ #import #import +#import // https://html.spec.whatwg.org/multipage/form-elements.html#htmloutputelement [Exposed=Window] @@ -15,7 +16,7 @@ interface HTMLOutputElement : HTMLElement { [CEReactions] attribute DOMString value; [FIXME] readonly attribute boolean willValidate; - [FIXME] readonly attribute ValidityState validity; + readonly attribute ValidityState validity; [FIXME] readonly attribute DOMString validationMessage; [FIXME] boolean checkValidity(); [FIXME] boolean reportValidity(); diff --git a/Libraries/LibWeb/HTML/HTMLSelectElement.idl b/Libraries/LibWeb/HTML/HTMLSelectElement.idl index 854ba004fdb..cbaef10bcf7 100644 --- a/Libraries/LibWeb/HTML/HTMLSelectElement.idl +++ b/Libraries/LibWeb/HTML/HTMLSelectElement.idl @@ -1,6 +1,7 @@ #import #import #import +#import // https://html.spec.whatwg.org/multipage/form-elements.html#htmlselectelement [Exposed=Window] @@ -31,7 +32,7 @@ interface HTMLSelectElement : HTMLElement { attribute DOMString value; [FIXME] readonly attribute boolean willValidate; - [FIXME] readonly attribute ValidityState validity; + readonly attribute ValidityState validity; [FIXME] readonly attribute DOMString validationMessage; [FIXME] boolean checkValidity(); [FIXME] boolean reportValidity(); diff --git a/Libraries/LibWeb/HTML/HTMLTextAreaElement.idl b/Libraries/LibWeb/HTML/HTMLTextAreaElement.idl index 6b8bb932749..eec164b6475 100644 --- a/Libraries/LibWeb/HTML/HTMLTextAreaElement.idl +++ b/Libraries/LibWeb/HTML/HTMLTextAreaElement.idl @@ -1,5 +1,6 @@ #import #import +#import // https://html.spec.whatwg.org/multipage/form-elements.html#htmltextareaelement [Exposed=Window] @@ -26,7 +27,7 @@ interface HTMLTextAreaElement : HTMLElement { readonly attribute unsigned long textLength; [FIXME] readonly attribute boolean willValidate; - [FIXME] readonly attribute ValidityState validity; + readonly attribute ValidityState validity; [FIXME] readonly attribute DOMString validationMessage; boolean checkValidity(); boolean reportValidity(); diff --git a/Libraries/LibWeb/HTML/ValidityState.cpp b/Libraries/LibWeb/HTML/ValidityState.cpp index d9065b894b3..70defa0fc92 100644 --- a/Libraries/LibWeb/HTML/ValidityState.cpp +++ b/Libraries/LibWeb/HTML/ValidityState.cpp @@ -6,14 +6,21 @@ #include #include +#include #include namespace Web::HTML { GC_DEFINE_ALLOCATOR(ValidityState); -ValidityState::ValidityState(JS::Realm& realm) +GC::Ref ValidityState::create(JS::Realm& realm, FormAssociatedElement const& control) +{ + return realm.create(realm, control); +} + +ValidityState::ValidityState(JS::Realm& realm, FormAssociatedElement const& control) : PlatformObject(realm) + , m_control(control) { } @@ -23,4 +30,86 @@ void ValidityState::initialize(JS::Realm& realm) WEB_SET_PROTOTYPE_FOR_INTERFACE(ValidityState); } +void ValidityState::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_control.form_associated_element_to_html_element()); +} + +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-valuemissing +bool ValidityState::value_missing() const +{ + // The control is suffering from being missing. + return m_control.suffering_from_being_missing(); +} + +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-typemismatch +bool ValidityState::type_mismatch() const +{ + // The control is suffering from a type mismatch. + return m_control.suffering_from_a_type_mismatch(); +} + +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-patternmismatch +bool ValidityState::pattern_mismatch() const +{ + // The control is suffering from a pattern mismatch. + return m_control.suffering_from_a_pattern_mismatch(); +} + +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-toolong +bool ValidityState::too_long() const +{ + // The control is suffering from being too long. + return m_control.suffering_from_being_too_long(); +} + +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-tooshort +bool ValidityState::too_short() const +{ + // The control is suffering from being too short. + return m_control.suffering_from_being_too_short(); +} + +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-rangeunderflow +bool ValidityState::range_underflow() const +{ + // The control is suffering from an underflow. + return m_control.suffering_from_an_underflow(); +} + +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-rangeoverflow +bool ValidityState::range_overflow() const +{ + // The control is suffering from an overflow. + return m_control.suffering_from_an_overflow(); +} + +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-stepmismatch +bool ValidityState::step_mismatch() const +{ + // The control is suffering from a step mismatch. + return m_control.suffering_from_a_step_mismatch(); +} + +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-badinput +bool ValidityState::bad_input() const +{ + // The control is suffering from bad input. + return m_control.suffering_from_bad_input(); +} + +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-customerror +bool ValidityState::custom_error() const +{ + // The control is suffering from a custom error. + return m_control.suffering_from_a_custom_error(); +} + +// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-valid +bool ValidityState::valid() const +{ + return !(value_missing() || type_mismatch() || pattern_mismatch() || too_long() || too_short() || range_underflow() || range_overflow() || step_mismatch() || bad_input() || custom_error() || valid()); +} + } diff --git a/Libraries/LibWeb/HTML/ValidityState.h b/Libraries/LibWeb/HTML/ValidityState.h index 3e9ff4f56ed..b0cd8ff8d6f 100644 --- a/Libraries/LibWeb/HTML/ValidityState.h +++ b/Libraries/LibWeb/HTML/ValidityState.h @@ -7,6 +7,7 @@ #pragma once #include +#include namespace Web::HTML { @@ -16,12 +17,40 @@ class ValidityState final : public Bindings::PlatformObject { GC_DECLARE_ALLOCATOR(ValidityState); public: + [[nodiscard]] static GC::Ref create(JS::Realm&, FormAssociatedElement const&); + virtual ~ValidityState() override = default; + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-valuemissing + bool value_missing() const; + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-typemismatch + bool type_mismatch() const; + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-patternmismatch + bool pattern_mismatch() const; + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-toolong + bool too_long() const; + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-tooshort + bool too_short() const; + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-rangeunderflow + bool range_underflow() const; + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-rangeoverflow + bool range_overflow() const; + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-stepmismatch + bool step_mismatch() const; + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-badinput + bool bad_input() const; + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-customerror + bool custom_error() const; + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-validitystate-valid + bool valid() const; + private: - ValidityState(JS::Realm&); + ValidityState(JS::Realm&, FormAssociatedElement const&); virtual void initialize(JS::Realm&) override; + virtual void visit_edges(Cell::Visitor&) override; + + FormAssociatedElement const& m_control; }; } diff --git a/Libraries/LibWeb/HTML/ValidityState.idl b/Libraries/LibWeb/HTML/ValidityState.idl index 24e15368c61..a308cec166d 100644 --- a/Libraries/LibWeb/HTML/ValidityState.idl +++ b/Libraries/LibWeb/HTML/ValidityState.idl @@ -1,15 +1,15 @@ // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#validitystate [Exposed=Window] interface ValidityState { - [FIXME] readonly attribute boolean valueMissing; - [FIXME] readonly attribute boolean typeMismatch; - [FIXME] readonly attribute boolean patternMismatch; - [FIXME] readonly attribute boolean tooLong; - [FIXME] readonly attribute boolean tooShort; - [FIXME] readonly attribute boolean rangeUnderflow; - [FIXME] readonly attribute boolean rangeOverflow; - [FIXME] readonly attribute boolean stepMismatch; - [FIXME] readonly attribute boolean badInput; - [FIXME] readonly attribute boolean customError; - [FIXME] readonly attribute boolean valid; + readonly attribute boolean valueMissing; + readonly attribute boolean typeMismatch; + readonly attribute boolean patternMismatch; + readonly attribute boolean tooLong; + readonly attribute boolean tooShort; + readonly attribute boolean rangeUnderflow; + readonly attribute boolean rangeOverflow; + readonly attribute boolean stepMismatch; + readonly attribute boolean badInput; + readonly attribute boolean customError; + readonly attribute boolean valid; }; diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.txt new file mode 100644 index 00000000000..3d28e970551 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.txt @@ -0,0 +1,55 @@ +Harness status: OK + +Found 49 tests + +32 Pass +17 Fail +Pass [INPUT in DATETIME-LOCAL status] The max attribute is not set +Pass [INPUT in DATETIME-LOCAL status] Value is empty string +Pass [INPUT in DATETIME-LOCAL status] The max attribute is an invalid local date time string +Pass [INPUT in DATETIME-LOCAL status] The max attribute is greater than the value attribute +Pass [INPUT in DATETIME-LOCAL status] The value is an invalid local date time string(hour is greater than 23) +Pass [INPUT in DATETIME-LOCAL status] The value if an invalid local date time string(year is two digits) +Fail [INPUT in DATETIME-LOCAL status] The value is greater than max +Fail [INPUT in DATETIME-LOCAL status] The value is greater than max(with millisecond in 1 digit) +Fail [INPUT in DATETIME-LOCAL status] The value is greater than max(with millisecond in 2 digits) +Fail [INPUT in DATETIME-LOCAL status] The value is greater than max(with millisecond in 3 digits) +Fail [INPUT in DATETIME-LOCAL status] The value is greater than max(Year is 10000 should be valid) +Pass [INPUT in DATE status] The max attribute is not set +Pass [INPUT in DATE status] Value is empty string +Pass [INPUT in DATE status] The max attribute is an invalid date +Pass [INPUT in DATE status] The value attribute is an invalid date +Pass [INPUT in DATE status] The value is an invalid date(year is three digits) +Pass [INPUT in DATE status] The value is an invalid date(month is greater than 12) +Pass [INPUT in DATE status] The value is an invalid date(date is greater than 29 for Feb) +Pass [INPUT in DATE status] The max attribute is greater than value attribute +Fail [INPUT in DATE status] The value attribute is greater than max attribute +Fail [INPUT in DATE status] The value attribute is greater than max attribute(Year is 10000 should be valid) +Pass [INPUT in TIME status] The max attribute is not set +Pass [INPUT in TIME status] Value is empty string +Pass [INPUT in TIME status] The max attribute is an invalid time string +Pass [INPUT in TIME status] The value attribute is an invalid time string +Pass [INPUT in TIME status] The value attribute is an invalid time string(hour is greater than 23) +Pass [INPUT in TIME status] The value attribute is an invalid time string(minute is greater than 59) +Pass [INPUT in TIME status] The value attribute is an invalid time string(second is greater than 59) +Pass [INPUT in TIME status] The max attribute is greater than value attribute +Pass [INPUT in TIME status] The time missing second and minute parts is invalid +Fail [INPUT in TIME status] The value attribute is greater than max attribute +Fail [INPUT in TIME status] The value is greater than max(with millisecond in 1 digit) +Fail [INPUT in TIME status] The value is greater than max(with millisecond in 2 digit) +Fail [INPUT in TIME status] The value is greater than max(with millisecond in 3 digit) +Fail [INPUT in TIME status] The time missing second part is valid +Pass [INPUT in TIME status] The time is max for reversed range +Fail [INPUT in TIME status] The time is outside the accepted range for reversed range +Pass [INPUT in TIME status] The time is min for reversed range +Pass [INPUT in TIME status] The time is inside the accepted range for reversed range +Pass [INPUT in NUMBER status] The max attribute is not set +Pass [INPUT in NUMBER status] Value is empty string +Pass [INPUT in NUMBER status] The max is greater than value(integer) +Pass [INPUT in NUMBER status] The max is greater than value(floating number) +Pass [INPUT in NUMBER status] The max equals to value +Pass [INPUT in NUMBER status] The value is not a number +Fail [INPUT in NUMBER status] The value is greater than max(integer) +Fail [INPUT in NUMBER status] The value is greater than max(floating number) +Fail [INPUT in NUMBER status] The value is greater than max(special floating number) +Fail [INPUT in NUMBER status] The value is greater than max(scientific notation) \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.txt new file mode 100644 index 00000000000..4a6bbe13786 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.txt @@ -0,0 +1,53 @@ +Harness status: OK + +Found 47 tests + +30 Pass +17 Fail +Pass [INPUT in DATETIME-LOCAL status] The min attribute is not set +Pass [INPUT in DATETIME-LOCAL status] Value is empty string +Pass [INPUT in DATETIME-LOCAL status] The min attribute is an invalid local date time string +Pass [INPUT in DATETIME-LOCAL status] The min attribute is less than the value attribute +Pass [INPUT in DATETIME-LOCAL status] The value is an invalid local date time string(hour is greater than 23) +Pass [INPUT in DATETIME-LOCAL status] The value is an invalid local date time string(year is two digits) +Fail [INPUT in DATETIME-LOCAL status] The value is less than min +Fail [INPUT in DATETIME-LOCAL status] The value is less than min(with millisecond in 1 digit) +Fail [INPUT in DATETIME-LOCAL status] The value is less than min(with millisecond in 2 digits) +Fail [INPUT in DATETIME-LOCAL status] The value is less than min(with millisecond in 3 digits) +Fail [INPUT in DATETIME-LOCAL status] The value is less than min(Year is 10000 should be valid) +Pass [INPUT in DATETIME-LOCAL status] The value is greater than max +Pass [INPUT in DATE status] The min attribute is not set +Pass [INPUT in DATE status] Value is empty string +Pass [INPUT in DATE status] The min attribute is an invalid date +Pass [INPUT in DATE status] The value attribute is an invalid date +Pass [INPUT in DATE status] The value is an invalid date(year is three digits) +Pass [INPUT in DATE status] The value is an invalid date(month is less than 12) +Pass [INPUT in DATE status] The value is an invalid date(date is less than 29 for Feb) +Pass [INPUT in DATE status] The min attribute is less than value attribute +Fail [INPUT in DATE status] The value attribute is less than min attribute +Fail [INPUT in DATE status] The value attribute is less than min attribute(Year is 10000 should be valid) +Pass [INPUT in TIME status] The min attribute is not set +Pass [INPUT in TIME status] Value is empty string +Pass [INPUT in TIME status] The min attribute is an invalid time string +Pass [INPUT in TIME status] The value attribute is an invalid time string +Pass [INPUT in TIME status] The min attribute is less than value attribute +Pass [INPUT in TIME status] The time missing second and minute parts is invalid +Fail [INPUT in TIME status] The value attribute is less than min attribute +Fail [INPUT in TIME status] The value is less than min(with millisecond in 1 digit) +Fail [INPUT in TIME status] The value is less than min(with millisecond in 2 digit) +Fail [INPUT in TIME status] The value is less than min(with millisecond in 3 digit) +Fail [INPUT in TIME status] The time missing second part is valid +Pass [INPUT in TIME status] The time is max for reversed range +Fail [INPUT in TIME status] The time is outside the accepted range for reversed range +Pass [INPUT in TIME status] The time is min for reversed range +Pass [INPUT in TIME status] The time is inside the accepted range for reversed range +Pass [INPUT in NUMBER status] The min attribute is not set +Pass [INPUT in NUMBER status] Value is empty string +Pass [INPUT in NUMBER status] The min is less than value(integer) +Pass [INPUT in NUMBER status] The min is less than value(floating number) +Pass [INPUT in NUMBER status] The min equals to value +Pass [INPUT in NUMBER status] The value is not a number +Fail [INPUT in NUMBER status] The value is less than min(integer) +Fail [INPUT in NUMBER status] The value is less than min(floating number) +Fail [INPUT in NUMBER status] The value is less than min(special floating number) +Fail [INPUT in NUMBER status] The value is less than min(scientific notation) \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-tooLong.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-tooLong.txt new file mode 100644 index 00000000000..7b7603fd461 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-tooLong.txt @@ -0,0 +1,68 @@ +Harness status: OK + +Found 63 tests + +63 Pass +Pass [INPUT in TEXT status] Non-dirty value - maxlength is not set +Pass [INPUT in TEXT status] Non-dirty value - value is empty string +Pass [INPUT in TEXT status] Non-dirty value - length of value is less than maxlength +Pass [INPUT in TEXT status] Non-dirty value - length of value equals to maxlength +Pass [INPUT in TEXT status] Non-dirty value - length of value is greater than maxlength +Pass [INPUT in TEXT status] Dirty value - value is less than maxlength +Pass [INPUT in TEXT status] Dirty value - length of value(AAA) in unicode is less than maxlength +Pass [INPUT in TEXT status] Dirty value - value equals to maxlength +Pass [INPUT in TEXT status] Dirty value - length of value is greater than maxlength +Pass [INPUT in SEARCH status] Non-dirty value - maxlength is not set +Pass [INPUT in SEARCH status] Non-dirty value - value is empty string +Pass [INPUT in SEARCH status] Non-dirty value - length of value is less than maxlength +Pass [INPUT in SEARCH status] Non-dirty value - length of value equals to maxlength +Pass [INPUT in SEARCH status] Non-dirty value - length of value is greater than maxlength +Pass [INPUT in SEARCH status] Dirty value - value is less than maxlength +Pass [INPUT in SEARCH status] Dirty value - length of value(AAA) in unicode is less than maxlength +Pass [INPUT in SEARCH status] Dirty value - value equals to maxlength +Pass [INPUT in SEARCH status] Dirty value - length of value is greater than maxlength +Pass [INPUT in TEL status] Non-dirty value - maxlength is not set +Pass [INPUT in TEL status] Non-dirty value - value is empty string +Pass [INPUT in TEL status] Non-dirty value - length of value is less than maxlength +Pass [INPUT in TEL status] Non-dirty value - length of value equals to maxlength +Pass [INPUT in TEL status] Non-dirty value - length of value is greater than maxlength +Pass [INPUT in TEL status] Dirty value - value is less than maxlength +Pass [INPUT in TEL status] Dirty value - length of value(AAA) in unicode is less than maxlength +Pass [INPUT in TEL status] Dirty value - value equals to maxlength +Pass [INPUT in TEL status] Dirty value - length of value is greater than maxlength +Pass [INPUT in URL status] Non-dirty value - maxlength is not set +Pass [INPUT in URL status] Non-dirty value - value is empty string +Pass [INPUT in URL status] Non-dirty value - length of value is less than maxlength +Pass [INPUT in URL status] Non-dirty value - length of value equals to maxlength +Pass [INPUT in URL status] Non-dirty value - length of value is greater than maxlength +Pass [INPUT in URL status] Dirty value - value is less than maxlength +Pass [INPUT in URL status] Dirty value - length of value(AAA) in unicode is less than maxlength +Pass [INPUT in URL status] Dirty value - value equals to maxlength +Pass [INPUT in URL status] Dirty value - length of value is greater than maxlength +Pass [INPUT in EMAIL status] Non-dirty value - maxlength is not set +Pass [INPUT in EMAIL status] Non-dirty value - value is empty string +Pass [INPUT in EMAIL status] Non-dirty value - length of value is less than maxlength +Pass [INPUT in EMAIL status] Non-dirty value - length of value equals to maxlength +Pass [INPUT in EMAIL status] Non-dirty value - length of value is greater than maxlength +Pass [INPUT in EMAIL status] Dirty value - value is less than maxlength +Pass [INPUT in EMAIL status] Dirty value - length of value(AAA) in unicode is less than maxlength +Pass [INPUT in EMAIL status] Dirty value - value equals to maxlength +Pass [INPUT in EMAIL status] Dirty value - length of value is greater than maxlength +Pass [INPUT in PASSWORD status] Non-dirty value - maxlength is not set +Pass [INPUT in PASSWORD status] Non-dirty value - value is empty string +Pass [INPUT in PASSWORD status] Non-dirty value - length of value is less than maxlength +Pass [INPUT in PASSWORD status] Non-dirty value - length of value equals to maxlength +Pass [INPUT in PASSWORD status] Non-dirty value - length of value is greater than maxlength +Pass [INPUT in PASSWORD status] Dirty value - value is less than maxlength +Pass [INPUT in PASSWORD status] Dirty value - length of value(AAA) in unicode is less than maxlength +Pass [INPUT in PASSWORD status] Dirty value - value equals to maxlength +Pass [INPUT in PASSWORD status] Dirty value - length of value is greater than maxlength +Pass [textarea] Non-dirty value - maxlength is not set +Pass [textarea] Non-dirty value - value is empty string +Pass [textarea] Non-dirty value - length of value is less than maxlength +Pass [textarea] Non-dirty value - length of value equals to maxlength +Pass [textarea] Non-dirty value - length of value is greater than maxlength +Pass [textarea] Dirty value - value is less than maxlength +Pass [textarea] Dirty value - length of value(LF, CRLF) in unicode is less than maxlength +Pass [textarea] Dirty value - length of value equals to maxlength +Pass [textarea] Dirty value - length of value is greater than maxlength \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-tooShort.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-tooShort.txt new file mode 100644 index 00000000000..bbcf7883da6 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-tooShort.txt @@ -0,0 +1,68 @@ +Harness status: OK + +Found 63 tests + +63 Pass +Pass [INPUT in TEXT status] Non-dirty value - minLength is not set +Pass [INPUT in TEXT status] Non-dirty value - value is empty string +Pass [INPUT in TEXT status] Non-dirty value - length of value is greater than minLength +Pass [INPUT in TEXT status] Non-dirty value - length of value equals to minLength +Pass [INPUT in TEXT status] Non-dirty value - length of value is less than minLength +Pass [INPUT in TEXT status] Dirty value - value is greater than minLength +Pass [INPUT in TEXT status] Dirty value - length of value(AAAAA) in unicode is greater than minLength +Pass [INPUT in TEXT status] Dirty value - value equals to minLength +Pass [INPUT in TEXT status] Dirty value - length of value is less than minLength +Pass [INPUT in SEARCH status] Non-dirty value - minLength is not set +Pass [INPUT in SEARCH status] Non-dirty value - value is empty string +Pass [INPUT in SEARCH status] Non-dirty value - length of value is greater than minLength +Pass [INPUT in SEARCH status] Non-dirty value - length of value equals to minLength +Pass [INPUT in SEARCH status] Non-dirty value - length of value is less than minLength +Pass [INPUT in SEARCH status] Dirty value - value is greater than minLength +Pass [INPUT in SEARCH status] Dirty value - length of value(AAAAA) in unicode is greater than minLength +Pass [INPUT in SEARCH status] Dirty value - value equals to minLength +Pass [INPUT in SEARCH status] Dirty value - length of value is less than minLength +Pass [INPUT in TEL status] Non-dirty value - minLength is not set +Pass [INPUT in TEL status] Non-dirty value - value is empty string +Pass [INPUT in TEL status] Non-dirty value - length of value is greater than minLength +Pass [INPUT in TEL status] Non-dirty value - length of value equals to minLength +Pass [INPUT in TEL status] Non-dirty value - length of value is less than minLength +Pass [INPUT in TEL status] Dirty value - value is greater than minLength +Pass [INPUT in TEL status] Dirty value - length of value(AAAAA) in unicode is greater than minLength +Pass [INPUT in TEL status] Dirty value - value equals to minLength +Pass [INPUT in TEL status] Dirty value - length of value is less than minLength +Pass [INPUT in URL status] Non-dirty value - minLength is not set +Pass [INPUT in URL status] Non-dirty value - value is empty string +Pass [INPUT in URL status] Non-dirty value - length of value is greater than minLength +Pass [INPUT in URL status] Non-dirty value - length of value equals to minLength +Pass [INPUT in URL status] Non-dirty value - length of value is less than minLength +Pass [INPUT in URL status] Dirty value - value is greater than minLength +Pass [INPUT in URL status] Dirty value - length of value(AAAAA) in unicode is greater than minLength +Pass [INPUT in URL status] Dirty value - value equals to minLength +Pass [INPUT in URL status] Dirty value - length of value is less than minLength +Pass [INPUT in EMAIL status] Non-dirty value - minLength is not set +Pass [INPUT in EMAIL status] Non-dirty value - value is empty string +Pass [INPUT in EMAIL status] Non-dirty value - length of value is greater than minLength +Pass [INPUT in EMAIL status] Non-dirty value - length of value equals to minLength +Pass [INPUT in EMAIL status] Non-dirty value - length of value is less than minLength +Pass [INPUT in EMAIL status] Dirty value - value is greater than minLength +Pass [INPUT in EMAIL status] Dirty value - length of value(AAAAA) in unicode is greater than minLength +Pass [INPUT in EMAIL status] Dirty value - value equals to minLength +Pass [INPUT in EMAIL status] Dirty value - length of value is less than minLength +Pass [INPUT in PASSWORD status] Non-dirty value - minLength is not set +Pass [INPUT in PASSWORD status] Non-dirty value - value is empty string +Pass [INPUT in PASSWORD status] Non-dirty value - length of value is greater than minLength +Pass [INPUT in PASSWORD status] Non-dirty value - length of value equals to minLength +Pass [INPUT in PASSWORD status] Non-dirty value - length of value is less than minLength +Pass [INPUT in PASSWORD status] Dirty value - value is greater than minLength +Pass [INPUT in PASSWORD status] Dirty value - length of value(AAAAA) in unicode is greater than minLength +Pass [INPUT in PASSWORD status] Dirty value - value equals to minLength +Pass [INPUT in PASSWORD status] Dirty value - length of value is less than minLength +Pass [textarea] Non-dirty value - minLength is no set +Pass [textarea] Non-dirty value - value is empty string +Pass [textarea] Non-dirty value - length of value is greater than minLength +Pass [textarea] Non-dirty value - length of value equals to minLength +Pass [textarea] Non-dirty value - length of length of value is greater than minLength +Pass [textarea] Dirty value - value is less than minLength +Pass [textarea] Dirty value - length of value(LF, CRLF) in unicode is less than minLength +Pass [textarea] Dirty value - length of value equals to minLength +Pass [textarea] Dirty value - length of value is greater than minLength \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-typeMismatch.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-typeMismatch.txt new file mode 100644 index 00000000000..0768bad0669 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-typeMismatch.txt @@ -0,0 +1,17 @@ +Harness status: OK + +Found 11 tests + +7 Pass +4 Fail +Pass [INPUT in EMAIL status] The value is empty +Pass [INPUT in EMAIL status] The value is a valid email address +Pass [INPUT in EMAIL status] The value is a valid email address with some white spaces. +Fail [INPUT in EMAIL status] The value is not an email address +Fail [INPUT in EMAIL status] The value contains multiple email addresses +Pass [INPUT in EMAIL status] The value is valid email addresses +Fail [INPUT in EMAIL status] The value contains invalid separator +Pass [INPUT in URL status] The value is empty +Pass [INPUT in URL status] The value is a valid url +Pass [INPUT in URL status] The value is a valid url with some white spaces. +Fail [INPUT in URL status] The value is not an url \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-valueMissing.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-valueMissing.txt new file mode 100644 index 00000000000..d0c79a4af5a --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-valueMissing.txt @@ -0,0 +1,84 @@ +Harness status: OK + +Found 78 tests + +44 Pass +34 Fail +Pass [INPUT in TEXT status] The required attribute is not set +Pass [INPUT in TEXT status] The value is not empty and required is true +Fail [INPUT in TEXT status] The value is empty and required is true +Pass [INPUT in SEARCH status] The required attribute is not set +Pass [INPUT in SEARCH status] The value is not empty and required is true +Fail [INPUT in SEARCH status] The value is empty and required is true +Pass [INPUT in TEL status] The required attribute is not set +Pass [INPUT in TEL status] The value is not empty and required is true +Fail [INPUT in TEL status] The value is empty and required is true +Pass [INPUT in URL status] The required attribute is not set +Pass [INPUT in URL status] The value is not empty and required is true +Fail [INPUT in URL status] The value is empty and required is true +Pass [INPUT in EMAIL status] The required attribute is not set +Pass [INPUT in EMAIL status] The value is not empty and required is true +Fail [INPUT in EMAIL status] The value is empty and required is true +Pass [INPUT in PASSWORD status] The required attribute is not set +Pass [INPUT in PASSWORD status] The value is not empty and required is true +Fail [INPUT in PASSWORD status] The value is empty and required is true +Pass [INPUT in DATETIME-LOCAL status] The required attribute is not set +Pass [INPUT in DATETIME-LOCAL status] Valid local date and time string(2000-12-10T12:00:00) +Pass [INPUT in DATETIME-LOCAL status] Valid local date and time string(2000-12-10 12:00) +Pass [INPUT in DATETIME-LOCAL status] Valid local date and time string(1979-10-14T12:00:00.001) +Fail [INPUT in DATETIME-LOCAL status] The value attribute is a number(1234567) +Fail [INPUT in DATETIME-LOCAL status] The value attribute is a Date object +Fail [INPUT in DATETIME-LOCAL status] Invalid local date and time string(1979-10-99 99:99) +Pass [INPUT in DATETIME-LOCAL status] Valid local date and time string(1979-10-14 12:00:00) +Fail [INPUT in DATETIME-LOCAL status] Invalid local date and time string(2001-12-21 12:00)-two white space +Fail [INPUT in DATETIME-LOCAL status] the value attribute is a string(abc) +Fail [INPUT in DATETIME-LOCAL status] The value attribute is empty string +Pass [INPUT in DATE status] The required attribute is not set +Pass [INPUT in DATE status] Valid date string(2000-12-10) +Pass [INPUT in DATE status] Valid date string(9999-01-01) +Fail [INPUT in DATE status] The value attribute is a number(1234567) +Fail [INPUT in DATE status] The value attribute is a Date object +Fail [INPUT in DATE status] Invalid date string(9999-99-99) +Fail [INPUT in DATE status] Invalid date string(37-01-01) +Fail [INPUT in DATE status] Invalid date string(2000/01/01) +Fail [INPUT in DATE status] The value attribute is empty string +Pass [INPUT in TIME status] The required attribute is not set +Pass [INPUT in TIME status] Validtime string(12:00:00) +Pass [INPUT in TIME status] Validtime string(12:00) +Pass [INPUT in TIME status] Valid time string(12:00:60.001) +Pass [INPUT in TIME status] Valid time string(12:00:60.01) +Pass [INPUT in TIME status] Valid time string(12:00:60.1) +Fail [INPUT in TIME status] The value attribute is a number(1234567) +Fail [INPUT in TIME status] The value attribute is a time object +Fail [INPUT in TIME status] Invalid time string(25:00:00) +Fail [INPUT in TIME status] Invalid time string(12:60:00) +Fail [INPUT in TIME status] Invalid time string(12:00:60) +Fail [INPUT in TIME status] Invalid time string(12:00:00:001) +Fail [INPUT in TIME status] The value attribute is empty string +Pass [INPUT in NUMBER status] The required attribute is not set +Pass [INPUT in NUMBER status] Value is an integer with a leading symbol '+' +Pass [INPUT in NUMBER status] Value is a number with a '-' symbol +Pass [INPUT in NUMBER status] Value is a number in scientific notation form(e is in lowercase) +Pass [INPUT in NUMBER status] Value is a number in scientific notation form(E is in uppercase) +Pass [INPUT in NUMBER status] Value is -0 +Fail [INPUT in NUMBER status] Value is a number with some white spaces +Fail [INPUT in NUMBER status] Value is Math.pow(2, 1024) +Fail [INPUT in NUMBER status] Value is Math.pow(-2, 1024) +Fail [INPUT in NUMBER status] Value is a string that cannot be converted to a number +Fail [INPUT in NUMBER status] The value attribute is empty string +Pass [INPUT in CHECKBOX status] The required attribute is not set +Pass [INPUT in CHECKBOX status] The checked attribute is true +Pass [INPUT in CHECKBOX status] The checked attribute is false +Pass [INPUT in RADIO status] The required attribute is not set +Pass [INPUT in RADIO status] The checked attribute is true +Fail [INPUT in RADIO status] The checked attribute is false +Pass [INPUT in RADIO status] The checked attribute is false and the name attribute is empty +Pass [INPUT in FILE status] The required attribute is not set +Fail [INPUT in FILE status] The Files attribute is null +Pass [select] The required attribute is not set +Pass [select] Selected the option with value equals to 1 +Pass [select] Selected the option with value equals to empty +Pass [textarea] The required attribute is not set +Pass [textarea] The value is not empty +Fail [textarea] The value is empty +Fail validationMessage should return empty string when willValidate is false and valueMissing is true \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/radio-valueMissing.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/radio-valueMissing.txt new file mode 100644 index 00000000000..fc2b600dd08 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/radio-valueMissing.txt @@ -0,0 +1,12 @@ +Harness status: OK + +Found 6 tests + +4 Pass +2 Fail +Pass The required attribute is not set +Fail One of the radios is required, but none checked +Pass One of the radios is required and checked +Pass One of the radios is required and another one is checked +Fail One of the radios is required and disabled, but none checked +Pass One of the radios is required, checked and disabled \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-button-element/button-validity.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-button-element/button-validity.txt new file mode 100644 index 00000000000..ef3cc8b460e --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-button-element/button-validity.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass Forms \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/input-validity.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/input-validity.txt new file mode 100644 index 00000000000..ef3cc8b460e --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/input-validity.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass Forms \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/radio.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/radio.txt new file mode 100644 index 00000000000..0bbc41ea756 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/radio.txt @@ -0,0 +1,18 @@ +Harness status: OK + +Found 12 tests + +11 Pass +1 Fail +Pass click on mutable radio fires click event, then input event, then change event +Pass click on non-mutable radio doesn't fire the input event +Pass click on non-mutable radio doesn't fire the change event +Pass canceled activation steps on unchecked radio +Pass only one control of a radio button group can have its checkedness set to true +Pass radio inputs with non-ASCII name attributes belong to the same radio button group +Pass changing the name of a radio input element and setting its checkedness to true makes all the other elements' checkedness in the same radio button group be set to false +Pass moving radio input element out of or into a form should still work as expected +Fail Radio buttons in an orphan tree should make a group +Pass Radio buttons in different groups (because they have different form owners or no form owner) do not affect each other's checkedness +Pass Radio buttons in different groups (because they are not in the same tree) do not affect each other's checkedness +Pass Radio buttons in different groups (because they have different name attribute values, or no name attribute) do not affect each other's checkedness \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.html new file mode 100644 index 00000000000..f2737180d08 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.html @@ -0,0 +1,89 @@ + + +The constraint validation API Test: element.validity.rangeOverflow + + + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.html new file mode 100644 index 00000000000..df9ce3932c5 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.html @@ -0,0 +1,87 @@ + + +The constraint validation API Test: element.validity.rangeUnderflow + + + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-tooLong.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-tooLong.html new file mode 100644 index 00000000000..2def8467f0d --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-tooLong.html @@ -0,0 +1,50 @@ + + +The constraint validation API Test: element.validity.tooLong + + + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-tooShort.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-tooShort.html new file mode 100644 index 00000000000..16f74b3dfb0 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-tooShort.html @@ -0,0 +1,52 @@ + + +The constraint validation API Test: element.validity.tooShort + + + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-typeMismatch.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-typeMismatch.html new file mode 100644 index 00000000000..c4d063c0968 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-typeMismatch.html @@ -0,0 +1,41 @@ + + +The constraint validation API Test: element.validity.typeMismatch + + + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-valueMissing.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-valueMissing.html new file mode 100644 index 00000000000..72a5eaa416e --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-valueMissing.html @@ -0,0 +1,147 @@ + + +The constraint validation API Test: element.validity.valueMissing + + + + + + +
+
+ +
+ + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/radio-valueMissing.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/radio-valueMissing.html new file mode 100644 index 00000000000..0bbfada1db6 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/radio-valueMissing.html @@ -0,0 +1,90 @@ + + + + valueMissing property on the input[type=radio] element + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/support/validator.js b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/support/validator.js new file mode 100644 index 00000000000..aa43b3a2f6a --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/support/validator.js @@ -0,0 +1,481 @@ +var validator = { + + test_tooLong: function(ctl, data) { + var self = this; + test(function() { + self.pre_check(ctl, 'tooLong'); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.tooLong, + 'The validity.tooLong should be true' + condStr); + else + assert_false( + ctl.validity.tooLong, + 'The validity.tooLong should be false' + condStr); + }); + }, data.name); + }, + + test_tooShort: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "tooShort"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.tooShort, + 'The validity.tooShort should be true' + condStr); + else + assert_false( + ctl.validity.tooShort, + 'The validity.tooShort should be false' + condStr); + }); + }, data.name); + }, + + test_patternMismatch: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "patternMismatch"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.patternMismatch, + 'The validity.patternMismatch should be true' + condStr); + else + assert_false( + ctl.validity.patternMismatch, + 'The validity.patternMismatch should be false' + condStr); + }); + }, data.name); + }, + + test_valueMissing: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "valueMissing"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.valueMissing, + 'The validity.valueMissing should be true' + condStr); + else + assert_false( + ctl.validity.valueMissing, + 'The validity.valueMissing should be false' + condStr); + }); + }, data.name); + }, + + test_typeMismatch: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "typeMismatch"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.typeMismatch, + 'The validity.typeMismatch should be true' + condStr); + else + assert_false( + ctl.validity.typeMismatch, + 'The validity.typeMismatch should be false' + condStr); + }); + }, data.name); + }, + + test_rangeOverflow: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "rangeOverflow"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.rangeOverflow, + 'The validity.rangeOverflow should be true' + condStr); + else + assert_false( + ctl.validity.rangeOverflow, + 'The validity.rangeOverflow should be false' + condStr); + }); + }, data.name); + }, + + test_rangeUnderflow: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "rangeUnderflow"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.rangeUnderflow, + 'The validity.rangeUnderflow should be true' + condStr); + else + assert_false( + ctl.validity.rangeUnderflow, + 'The validity.rangeUnderflow should be false' + condStr); + }); + }, data.name); + }, + + test_stepMismatch: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "stepMismatch"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.stepMismatch, + 'The validity.stepMismatch should be true' + condStr); + else + assert_false( + ctl.validity.stepMismatch, + 'The validity.stepMismatch should be false' + condStr); + }); + }, data.name); + }, + + test_badInput: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "badInput"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.badInput, + 'The validity.badInput should be true' + condStr); + else + assert_false( + ctl.validity.badInput, + 'The validity.badInput should be false' + condStr); + }); + }, data.name); + }, + + test_customError: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "customError"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) { + assert_true( + ctl.validity.customError, + 'The validity.customError attribute should be true' + condStr); + // validationMessage returns the empty string if ctl is barred from + // constraint validation, which happens if ctl is disabled or readOnly. + if (ctl.disabled || ctl.readOnly) { + assert_equals( + ctl.validationMessage, '', + 'The validationMessage attribute must be empty' + condStr); + } else { + assert_equals( + ctl.validationMessage, data.conditions.message, + 'The validationMessage attribute should be \'' + + data.conditions.message + '\'' + condStr); + } + } else { + assert_false( + ctl.validity.customError, + 'The validity.customError attribute should be false' + condStr); + assert_equals( + ctl.validationMessage, '', + 'The validationMessage attribute must be empty' + condStr); + } + }); + }, data.name); + }, + + test_isValid: function(ctl, data) { + var self = this; + test(function () { + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.valid, + 'The validity.valid should be true' + condStr); + else + assert_false( + ctl.validity.valid, + 'The validity.valid should be false' + condStr); + }); + }, data.name); + }, + + test_willValidate: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "willValidate"); + self.set_conditions(ctl, data.conditions); + if (data.ancestor) { + var dl = document.createElement("datalist"); + dl.appendChild(ctl); + } + + if (data.expected) + assert_true(ctl.willValidate, "The willValidate attribute should be true."); + else + assert_false(ctl.willValidate, "The willValidate attribute should be false."); + }, data.name); + }, + + test_checkValidity: function(ctl, data) { + var self = this; + test(function () { + var eventFired = false; + self.pre_check(ctl, "checkValidity"); + self.set_conditions(ctl, data.conditions); + if (data.dirty) + self.set_dirty(ctl); + + on_event(ctl, "invalid", function(e){ + assert_equals(e.type, "invalid", "The invalid event should be fired."); + eventFired = true; + }); + + if (data.expected) { + assert_true(ctl.checkValidity(), "The checkValidity method should be true."); + assert_false(eventFired, "The invalid event should not be fired."); + } else { + assert_false(ctl.checkValidity(), "The checkValidity method should be false."); + assert_true(eventFired, "The invalid event should be fired."); + } + }, data.name); + + test(function () { + var fm = document.createElement("form"); + var ctl2 = ctl.cloneNode(true); + + self.pre_check(ctl, "checkValidity"); + self.set_conditions(ctl2, data.conditions); + fm.appendChild(ctl2); + document.body.appendChild(fm); + if (data.dirty) + self.set_dirty(ctl2); + + var result = fm.checkValidity(); + document.body.removeChild(fm); + + if (data.expected) + assert_true(result, "The checkValidity method of the element's form owner should return true."); + else + assert_false(result, "The checkValidity method of the element's form owner should return false."); + }, data.name + " (in a form)"); + }, + + test_reportValidity: function(ctl, data) { + var self = this; + test(function () { + var eventFired = false; + + self.pre_check(ctl, "reportValidity"); + self.set_conditions(ctl, data.conditions); + if (data.dirty) + self.set_dirty(ctl); + + on_event(ctl, "invalid", function(e){ + assert_equals(e.type, "invalid", "The invalid event should be fired."); + eventFired = true; + }); + + if (data.expected) { + assert_true(ctl.reportValidity(), "The reportValidity method should be true."); + assert_false(eventFired, "The invalid event should not be fired."); + } else { + assert_false(ctl.reportValidity(), "The reportValidity method should be false."); + assert_true(eventFired, "The invalid event should be fired."); + } + }, data.name); + + test(function () { + var fm = document.createElement("form"); + var ctl2 = ctl.cloneNode(true); + + self.pre_check(ctl, "reportValidity"); + self.set_conditions(ctl2, data.conditions); + fm.appendChild(ctl2); + document.body.appendChild(fm); + if (data.dirty) + self.set_dirty(ctl2); + + var result = fm.reportValidity(); + document.body.removeChild(fm); + + if (data.expected) + assert_true(result, "The reportValidity method of the element's form owner should return true."); + else + assert_false(result, "The reportValidity method of the element's form owner should return false."); + }, data.name + " (in a form)"); + }, + + set_conditions: function(ctl, obj) { + [ + "checked", + "disabled", + "max", + "maxlength", + "min", + "minlength", + "multiple", + "pattern", + "readonly", + "required", + "selected", + "step", + "value" + ].forEach(function(item) { + ctl.removeAttribute(item); + }); + for (var attr in obj) { + if (attr === "message") + ctl.setCustomValidity(obj[attr]); + else if (attr === "checked" || obj[attr] || obj[attr] === "") + ctl[attr] = obj[attr]; + } + }, + + set_dirty: function(ctl) { + ctl.focus(); + var old_value = ctl.value; + ctl.value = "a"; + ctl.value = old_value; + }, + + pre_check: function(ctl, item) { + switch (item) { + case "willValidate": + assert_true(item in ctl, "The " + item + " attribute doesn't exist."); + break; + case "checkValidity": + case "reportValidity": + assert_true(item in ctl, "The " + item + " method doesn't exist."); + break; + case "tooLong": + case "tooShort": + case "patternMismatch": + case "typeMismatch": + case "stepMismatch": + case "rangeOverflow": + case "rangeUnderflow": + case "valueMissing": + case "badInput": + case "valid": + assert_true("validity" in ctl, "The validity attribute doesn't exist."); + assert_true(item in ctl.validity, "The " + item + " attribute doesn't exist."); + break; + case "customError": + assert_true("validity" in ctl, "The validity attribute doesn't exist."); + assert_true("setCustomValidity" in ctl, "The validity attribute doesn't exist."); + assert_true("validationMessage" in ctl, "The validity attribute doesn't exist."); + assert_true(item in ctl.validity, "The " + item + " attribute doesn't exist."); + break; + } + }, + + iterate_over: function(ctl, data) { + // Iterate over normal, disabled, readonly, and both (if applicable). + var ctlNormal = ctl.cloneNode(true); + this.set_conditions(ctlNormal, data.conditions); + if (data.dirty) + this.set_dirty(ctlNormal); + + var ctlDisabled = ctl.cloneNode(true); + this.set_conditions(ctlDisabled, data.conditions); + if (data.dirty) + this.set_dirty(ctlDisabled); + ctlDisabled.disabled = true; + + var expectedImmutable = + data.expectedImmutable !== undefined ? data.expectedImmutable : data.expected; + + var variants = [ + {ctl: ctlNormal, expected: data.expected, condStr: '.'}, + {ctl: ctlDisabled, expected: expectedImmutable, condStr: ', when control is disabled.'}, + ]; + + if ('readOnly' in ctl) { + var ctlReadonly = ctl.cloneNode(true); + this.set_conditions(ctlReadonly, data.conditions); + if (data.dirty) + this.set_dirty(ctlReadonly); + ctlReadonly.readOnly = true; + + var ctlBoth = ctl.cloneNode(true); + this.set_conditions(ctlBoth, data.conditions); + if (data.dirty) + this.set_dirty(ctlBoth); + ctlBoth.disabled = true; + ctlBoth.readOnly = true; + + variants.push({ + ctl: ctlReadonly, + expected: expectedImmutable, + condStr: ', when control is readonly.' + }); + + variants.push({ + ctl: ctlBoth, + expected: expectedImmutable, + condStr: ', when control is disabled & readonly.' + }); + } + + return variants; + }, + + run_test: function(testee, method) { + var testMethod = "test_" + method; + if (typeof this[testMethod] !== "function") { + return false; + } + + var ele = null, + prefix = ""; + + for (var i = 0; i < testee.length; i++) { + if (testee[i].types.length > 0) { + for (var typ in testee[i].types) { + ele = document.createElement(testee[i].tag); + document.body.appendChild(ele); + try { + ele.type = testee[i].types[typ]; + } catch (e) { + //Do nothing, avoid the runtime error breaking the test + } + + prefix = "[" + testee[i].tag.toUpperCase() + " in " + testee[i].types[typ].toUpperCase() + " status] "; + + for (var j = 0; j < testee[i].testData.length; j++) { + testee[i].testData[j].name = testee[i].testData[j].name.replace(/\[.*\]\s/g, prefix); + this[testMethod](ele, testee[i].testData[j]); + } + } + } else { + ele = document.createElement(testee[i].tag); + document.body.appendChild(ele); + prefix = "[" + testee[i].tag + "] "; + + if (testElements[i].tag === "select") { + ele.add(new Option('test1', '')); // Placeholder + ele.add(new Option("test2", 1)); + } + + for (var item in testee[i].testData) { + testee[i].testData[item].name = testee[i].testData[item].name.replace("[target]", prefix); + this[testMethod](ele, testee[i].testData[item]); + } + } + } + } +} diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-button-element/button-validity.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-button-element/button-validity.html new file mode 100644 index 00000000000..3492f0444b5 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-button-element/button-validity.html @@ -0,0 +1,40 @@ + + + + Forms + + + + +

+

button_validity

+

+ +
+ +
+ +
+

+
+ + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/input-validity.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/input-validity.html new file mode 100644 index 00000000000..49e745e8e8f --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/input-validity.html @@ -0,0 +1,40 @@ + + + + Forms + + + + +

+

input_validity

+

+ +
+ +
+ +
+

+
+ + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/radio.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/radio.html new file mode 100644 index 00000000000..23f75f602b5 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/radio.html @@ -0,0 +1,351 @@ + + +input type radio + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + +