mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-22 04:25:13 +00:00
LibWeb: Implement validity IDL attribute
This commit is contained in:
parent
184ae687c5
commit
83c4e22247
Notes:
github-actions[bot]
2025-02-18 06:38:10 +00:00
Author: https://github.com/Psychpsyo Commit: https://github.com/LadybirdBrowser/ladybird/commit/83c4e222473 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3583 Reviewed-by: https://github.com/shannonbooth Reviewed-by: https://github.com/tcl3 ✅
33 changed files with 2007 additions and 31 deletions
|
@ -23,6 +23,7 @@
|
|||
#include <LibWeb/HTML/HTMLSelectElement.h>
|
||||
#include <LibWeb/HTML/HTMLTextAreaElement.h>
|
||||
#include <LibWeb/HTML/Parser/HTMLParser.h>
|
||||
#include <LibWeb/HTML/ValidityState.h>
|
||||
#include <LibWeb/Painting/Paintable.h>
|
||||
#include <LibWeb/Selection/Selection.h>
|
||||
|
||||
|
@ -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<ValidityState const> FormAssociatedElement::validity() const
|
||||
{
|
||||
auto& realm = form_associated_element_to_html_element().realm();
|
||||
return realm.create<ValidityState>(realm, *this);
|
||||
}
|
||||
|
||||
bool FormAssociatedElement::enabled() const
|
||||
{
|
||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-fe-disabled
|
||||
|
|
|
@ -122,6 +122,9 @@ public:
|
|||
String form_action() const;
|
||||
WebIDL::ExceptionOr<void> set_form_action(String const&);
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-validity
|
||||
GC::Ref<ValidityState const> validity() const;
|
||||
|
||||
protected:
|
||||
FormAssociatedElement() = default;
|
||||
virtual ~FormAssociatedElement() = default;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#import <HTML/HTMLElement.idl>
|
||||
#import <HTML/HTMLFormElement.idl>
|
||||
#import <HTML/PopoverInvokerElement.idl>
|
||||
#import <HTML/ValidityState.idl>
|
||||
|
||||
[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();
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
#include <LibWeb/HTML/SelectedFile.h>
|
||||
#include <LibWeb/HTML/SharedResourceRequest.h>
|
||||
#include <LibWeb/HTML/ValidityState.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/Infra/CharacterTypes.h>
|
||||
#include <LibWeb/Infra/Strings.h>
|
||||
|
@ -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<ValidityState const> HTMLInputElement::validity() const
|
||||
{
|
||||
auto& realm = this->realm();
|
||||
|
||||
dbgln("FIXME: Implement validity attribute getter");
|
||||
|
||||
return realm.create<ValidityState>(realm);
|
||||
}
|
||||
|
||||
GC::Ptr<Layout::Node> HTMLInputElement::create_layout_node(GC::Ref<CSS::ComputedProperties> style)
|
||||
{
|
||||
if (type_state() == TypeAttributeState::Hidden)
|
||||
|
|
|
@ -191,8 +191,6 @@ public:
|
|||
|
||||
virtual WebIDL::ExceptionOr<void> cloned(Node&, bool) const override;
|
||||
|
||||
GC::Ref<ValidityState const> validity() const;
|
||||
|
||||
// ^HTMLElement
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#category-label
|
||||
virtual bool is_labelable() const override { return type_state() != TypeAttributeState::Hidden; }
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#import <DOM/Document.idl>
|
||||
#import <HTML/HTMLElement.idl>
|
||||
#import <HTML/ValidityState.idl>
|
||||
|
||||
// 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();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#import <HTML/HTMLElement.idl>
|
||||
#import <HTML/HTMLFormElement.idl>
|
||||
#import <HTML/ValidityState.idl>
|
||||
|
||||
// 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();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#import <HTML/HTMLElement.idl>
|
||||
#import <HTML/HTMLFormElement.idl>
|
||||
#import <HTML/HTMLOptionsCollection.idl>
|
||||
#import <HTML/ValidityState.idl>
|
||||
|
||||
// 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();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#import <HTML/HTMLElement.idl>
|
||||
#import <HTML/HTMLFormElement.idl>
|
||||
#import <HTML/ValidityState.idl>
|
||||
|
||||
// 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();
|
||||
|
|
|
@ -6,14 +6,21 @@
|
|||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Bindings/ValidityStatePrototype.h>
|
||||
#include <LibWeb/HTML/HTMLElement.h>
|
||||
#include <LibWeb/HTML/ValidityState.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(ValidityState);
|
||||
|
||||
ValidityState::ValidityState(JS::Realm& realm)
|
||||
GC::Ref<ValidityState> ValidityState::create(JS::Realm& realm, FormAssociatedElement const& control)
|
||||
{
|
||||
return realm.create<ValidityState>(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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/HTML/FormAssociatedElement.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
|
@ -16,12 +17,40 @@ class ValidityState final : public Bindings::PlatformObject {
|
|||
GC_DECLARE_ALLOCATOR(ValidityState);
|
||||
|
||||
public:
|
||||
[[nodiscard]] static GC::Ref<ValidityState> 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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)
|
|
@ -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)
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,6 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Pass Forms
|
|
@ -0,0 +1,6 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Pass Forms
|
|
@ -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
|
|
@ -0,0 +1,89 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>The constraint validation API Test: element.validity.rangeOverflow</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com/">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-validitystate-rangeoverflow">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="support/validator.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
var testElements = [
|
||||
{
|
||||
tag: "input",
|
||||
types: ["datetime-local"],
|
||||
testData: [
|
||||
{conditions: {max: "", value: "2000-01-01T12:00:00"}, expected: false, name: "[target] The max attribute is not set"},
|
||||
{conditions: {max: "2000-01-01T12:00:00", value: ""}, expected: false, name: "[target] Value is empty string"},
|
||||
{conditions: {max: "2000-01-01 12:00:00", value: "2001-01-01T12:00:00"}, expected: false, name: "[target] The max attribute is an invalid local date time string"},
|
||||
{conditions: {max: "2000-01-01T12:00:00", value: "2000-01-01T11:00:00"}, expected: false, name: "[target] The max attribute is greater than the value attribute"},
|
||||
{conditions: {max: "2000-01-01T23:59:59", value: "2001-01-01T24:00:00"}, expected: false, name: "[target] The value is an invalid local date time string(hour is greater than 23)"},
|
||||
{conditions: {max: "1970-01-01T12:00", value: "80-01-01T12:00"}, expected: false, name: "[target] The value if an invalid local date time string(year is two digits)"},
|
||||
{conditions: {max: "2000-01-01T12:00:00", value: "2001-01-01T13:00:00"}, expected: true, name: "[target] The value is greater than max"},
|
||||
{conditions: {max: "2000-01-01T12:00:00.1", value: "2000-01-01T12:00:00.2"}, expected: true, name: "[target] The value is greater than max(with millisecond in 1 digit)"},
|
||||
{conditions: {max: "2000-01-01T12:00:00.01", value: "2000-01-01T12:00:00.02"}, expected: true, name: "[target] The value is greater than max(with millisecond in 2 digits)"},
|
||||
{conditions: {max: "2000-01-01T12:00:00.001", value: "2000-01-01T12:00:00.002"}, expected: true, name: "[target] The value is greater than max(with millisecond in 3 digits)"},
|
||||
{conditions: {max: "2000-01-01T12:00:00", value: "10000-01-01T12:00:00"}, expected: true, name: "[target] The value is greater than max(Year is 10000 should be valid)"},
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "input",
|
||||
types: ["date"],
|
||||
testData: [
|
||||
{conditions: {max: "", value: "2000-01-01"}, expected: false, name: "[target] The max attribute is not set"},
|
||||
{conditions: {max: "2000-01-01", value: ""}, expected: false, name: "[target] Value is empty string"},
|
||||
{conditions: {max: "2000/01/01", value: "2002-01-01"}, expected: false, name: "[target] The max attribute is an invalid date"},
|
||||
{conditions: {max: "2000-01-01", value: "2000-2-2"}, expected: false, name: "[target] The value attribute is an invalid date"},
|
||||
{conditions: {max: "987-01-01", value: "988-01-01"}, expected: false, name: "[target] The value is an invalid date(year is three digits)"},
|
||||
{conditions: {max: "2000-01-01", value: "2000-13-01"}, expected: false, name: "[target] The value is an invalid date(month is greater than 12)"},
|
||||
{conditions: {max: "2000-01-01", value: "2000-02-30"}, expected: false, name: "[target] The value is an invalid date(date is greater than 29 for Feb)"},
|
||||
{conditions: {max: "2000-12-01", value: "2000-01-01"}, expected: false, name: "[target] The max attribute is greater than value attribute"},
|
||||
{conditions: {max: "2000-12-01", value: "2001-01-01"}, expected: true, name: "[target] The value attribute is greater than max attribute"},
|
||||
{conditions: {max: "9999-01-01", value: "10000-01-01"}, expected: true, name: "[target] The value attribute is greater than max attribute(Year is 10000 should be valid)"}
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "input",
|
||||
types: ["time"],
|
||||
testData: [
|
||||
{conditions: {max: "", value: "12:00:00"}, expected: false, name: "[target] The max attribute is not set"},
|
||||
{conditions: {max: "12:00:00", value: ""}, expected: false, name: "[target] Value is empty string"},
|
||||
{conditions: {max: "12.00.00", value: "12:00:01"}, expected: false, name: "[target] The max attribute is an invalid time string"},
|
||||
{conditions: {max: "12:00:00", value: "12.00.01"}, expected: false, name: "[target] The value attribute is an invalid time string"},
|
||||
{conditions: {max: "23:59:59", value: "24:00:00"}, expected: false, name: "[target] The value attribute is an invalid time string(hour is greater than 23)"},
|
||||
{conditions: {max: "23:59:59", value: "23:60:00"}, expected: false, name: "[target] The value attribute is an invalid time string(minute is greater than 59)"},
|
||||
{conditions: {max: "23:59:59", value: "23:59:60"}, expected: false, name: "[target] The value attribute is an invalid time string(second is greater than 59)"},
|
||||
{conditions: {max: "13:00:00", value: "12:00:00"}, expected: false, name: "[target] The max attribute is greater than value attribute"},
|
||||
{conditions: {max: "12:00:00", value: "13"}, expected: false, name: "[target] The time missing second and minute parts is invalid"},
|
||||
{conditions: {max: "12:00:00", value: "12:00:02"}, expected: true, name: "[target] The value attribute is greater than max attribute"},
|
||||
{conditions: {max: "12:00:00.1", value: "12:00:00.2"}, expected: true, name: "[target] The value is greater than max(with millisecond in 1 digit)"},
|
||||
{conditions: {max: "12:00:00.01", value: "12:00:00.02"}, expected: true, name: "[target] The value is greater than max(with millisecond in 2 digit)"},
|
||||
{conditions: {max: "12:00:00.001", value: "12:00:00.002"}, expected: true, name: "[target] The value is greater than max(with millisecond in 3 digit)"},
|
||||
{conditions: {max: "12:00:00", value: "12:01"}, expected: true, name: "[target] The time missing second part is valid"},
|
||||
{conditions: {max: "12:00:00", min: "14:00:00", value: "12:00:00"}, expected: false, name: "[target] The time is max for reversed range"},
|
||||
{conditions: {max: "12:00:00", min: "14:00:00", value: "13:00:00"}, expected: true, name: "[target] The time is outside the accepted range for reversed range"},
|
||||
{conditions: {max: "12:00:00", min: "14:00:00", value: "14:00:00"}, expected: false, name: "[target] The time is min for reversed range"},
|
||||
{conditions: {max: "12:00:00", min: "14:00:00", value: "15:00:00"}, expected: false, name: "[target] The time is inside the accepted range for reversed range"},
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "input",
|
||||
types: ["number"],
|
||||
testData: [
|
||||
{conditions: {max: "", value: "10"}, expected: false, name: "[target] The max attribute is not set"},
|
||||
{conditions: {max: "5", value: ""}, expected: false, name: "[target] Value is empty string"},
|
||||
{conditions: {max: "5", value: "4"}, expected: false, name: "[target] The max is greater than value(integer)"},
|
||||
{conditions: {max: "-5.5", value: "-5.6"}, expected: false, name: "[target] The max is greater than value(floating number)"},
|
||||
{conditions: {max: "-0", value: "0"}, expected: false, name: "[target] The max equals to value"},
|
||||
{conditions: {max: "5", value: "1abc"}, expected: false, name: "[target] The value is not a number"},
|
||||
{conditions: {max: "5", value: "6"}, expected: true, name: "[target] The value is greater than max(integer)"},
|
||||
{conditions: {max: "-5.5", value: "-5.4"}, expected: true, name: "[target] The value is greater than max(floating number)"},
|
||||
{conditions: {max: "-1", value: "-.8"}, expected: true, name: "[target] The value is greater than max(special floating number)"},
|
||||
{conditions: {max: "-5e-1", value: "5e+2"}, expected: true, name: "[target] The value is greater than max(scientific notation)"},
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
validator.run_test(testElements, "rangeOverflow");
|
||||
</script>
|
|
@ -0,0 +1,87 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>The constraint validation API Test: element.validity.rangeUnderflow</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com/">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-validitystate-rangeunderflow">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="support/validator.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
var testElements = [
|
||||
{
|
||||
tag: "input",
|
||||
types: ["datetime-local"],
|
||||
testData: [
|
||||
{conditions: {min: "", value: "2000-01-01T12:00:00"}, expected: false, name: "[target] The min attribute is not set"},
|
||||
{conditions: {min: "2000-01-01T12:00:00", value: ""}, expected: false, name: "[target] Value is empty string"},
|
||||
{conditions: {min: "2001-01-01 12:00:00", value: "2000-01-01T12:00:00"}, expected: false, name: "[target] The min attribute is an invalid local date time string"},
|
||||
{conditions: {min: "2000-01-01T11:00:00", value: "2000-01-01T12:00:00"}, expected: false, name: "[target] The min attribute is less than the value attribute"},
|
||||
{conditions: {min: "2001-01-01T23:59:59", value: "2000-01-01T24:00:00"}, expected: false, name: "[target] The value is an invalid local date time string(hour is greater than 23)"},
|
||||
{conditions: {min: "1980-01-01T12:00", value: "79-01-01T12:00"}, expected: false, name: "[target] The value is an invalid local date time string(year is two digits)"},
|
||||
{conditions: {min: "2000-01-01T13:00:00", value: "2000-01-01T12:00:00"}, expected: true, name: "[target] The value is less than min"},
|
||||
{conditions: {min: "2000-01-01T12:00:00.2", value: "2000-01-01T12:00:00.1"}, expected: true, name: "[target] The value is less than min(with millisecond in 1 digit)"},
|
||||
{conditions: {min: "2000-01-01T12:00:00.02", value: "2000-01-01T12:00:00.01"}, expected: true, name: "[target] The value is less than min(with millisecond in 2 digits)"},
|
||||
{conditions: {min: "2000-01-01T12:00:00.002", value: "2000-01-01T12:00:00.001"}, expected: true, name: "[target] The value is less than min(with millisecond in 3 digits)"},
|
||||
{conditions: {min: "10000-01-01T12:00:00", value: "2000-01-01T12:00:00"}, expected: true, name: "[target] The value is less than min(Year is 10000 should be valid)"},
|
||||
{conditions: {max: "8593-01-01T02:09", value: "8592-01-01T02:09"}, expected: false, name: "[target] The value is greater than max"}
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "input",
|
||||
types: ["date"],
|
||||
testData: [
|
||||
{conditions: {min: "", value: "2000-01-01"}, expected: false, name: "[target] The min attribute is not set"},
|
||||
{conditions: {min: "2000-01-01", value: ""}, expected: false, name: "[target] Value is empty string"},
|
||||
{conditions: {min: "2001/01/01", value: "2000-01-01"}, expected: false, name: "[target] The min attribute is an invalid date"},
|
||||
{conditions: {min: "2000-02-02", value: "2000-1-1"}, expected: false, name: "[target] The value attribute is an invalid date"},
|
||||
{conditions: {min: "988-01-01", value: "987-01-01"}, expected: false, name: "[target] The value is an invalid date(year is three digits)"},
|
||||
{conditions: {min: "2001-01-01", value: "2000-13-01"}, expected: false, name: "[target] The value is an invalid date(month is less than 12)"},
|
||||
{conditions: {min: "2001-01-01", value: "2000-02-30"}, expected: false, name: "[target] The value is an invalid date(date is less than 29 for Feb)"},
|
||||
{conditions: {min: "2000-01-01", value: "2000-12-01"}, expected: false, name: "[target] The min attribute is less than value attribute"},
|
||||
{conditions: {min: "2000-12-01", value: "2000-01-01"}, expected: true, name: "[target] The value attribute is less than min attribute"},
|
||||
{conditions: {min: "10000-01-01", value: "9999-01-01"}, expected: true, name: "[target] The value attribute is less than min attribute(Year is 10000 should be valid)"}
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "input",
|
||||
types: ["time"],
|
||||
testData: [
|
||||
{conditions: {min: "", value: "12:00:00"}, expected: false, name: "[target] The min attribute is not set"},
|
||||
{conditions: {min: "12:00:00", value: ""}, expected: false, name: "[target] Value is empty string"},
|
||||
{conditions: {min: "12.00.01", value: "12:00:00"}, expected: false, name: "[target] The min attribute is an invalid time string"},
|
||||
{conditions: {min: "12:00:01", value: "12.00.00"}, expected: false, name: "[target] The value attribute is an invalid time string"},
|
||||
{conditions: {min: "12:00:00", value: "13:00:00"}, expected: false, name: "[target] The min attribute is less than value attribute"},
|
||||
{conditions: {min: "13:00:00", value: "12"}, expected: false, name: "[target] The time missing second and minute parts is invalid"},
|
||||
{conditions: {min: "12:00:02", value: "12:00:00"}, expected: true, name: "[target] The value attribute is less than min attribute"},
|
||||
{conditions: {min: "12:00:00.2", value: "12:00:00.1"}, expected: true, name: "[target] The value is less than min(with millisecond in 1 digit)"},
|
||||
{conditions: {min: "12:00:00.02", value: "12:00:00.01"}, expected: true, name: "[target] The value is less than min(with millisecond in 2 digit)"},
|
||||
{conditions: {min: "12:00:00.002", value: "12:00:00.001"}, expected: true, name: "[target] The value is less than min(with millisecond in 3 digit)"},
|
||||
{conditions: {min: "12:00:00", value: "11:59"}, expected: true, name: "[target] The time missing second part is valid"},
|
||||
{conditions: {min: "14:00:00", max: "12:00:00", value: "12:00:00"}, expected: false, name: "[target] The time is max for reversed range"},
|
||||
{conditions: {min: "14:00:00", max: "12:00:00", value: "13:00:00"}, expected: true, name: "[target] The time is outside the accepted range for reversed range"},
|
||||
{conditions: {min: "14:00:00", max: "12:00:00", value: "14:00:00"}, expected: false, name: "[target] The time is min for reversed range"},
|
||||
{conditions: {min: "14:00:00", max: "12:00:00", value: "15:00:00"}, expected: false, name: "[target] The time is inside the accepted range for reversed range"},
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "input",
|
||||
types: ["number"],
|
||||
testData: [
|
||||
{conditions: {min: "", value: "10"}, expected: false, name: "[target] The min attribute is not set"},
|
||||
{conditions: {min: "5", value: ""}, expected: false, name: "[target] Value is empty string"},
|
||||
{conditions: {min: "4", value: "5"}, expected: false, name: "[target] The min is less than value(integer)"},
|
||||
{conditions: {min: "-5.6", value: "-5.5"}, expected: false, name: "[target] The min is less than value(floating number)"},
|
||||
{conditions: {min: "0", value: "-0"}, expected: false, name: "[target] The min equals to value"},
|
||||
{conditions: {min: "5", value: "6abc"}, expected: false, name: "[target] The value is not a number"},
|
||||
{conditions: {min: "6", value: "5"}, expected: true, name: "[target] The value is less than min(integer)"},
|
||||
{conditions: {min: "-5.4", value: "-5.5"}, expected: true, name: "[target] The value is less than min(floating number)"},
|
||||
{conditions: {min: "1", value: "-.8"}, expected: true, name: "[target] The value is less than min(special floating number)"},
|
||||
{conditions: {min: "5e+2", value: "-5e-1"}, expected: true, name: "[target] The value is less than min(scientific notation)"}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
validator.run_test(testElements, "rangeUnderflow");
|
||||
</script>
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>The constraint validation API Test: element.validity.tooLong</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com/">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-validitystate-toolong">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="support/validator.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
var testElements = [
|
||||
{
|
||||
tag: "input",
|
||||
types: ["text", "search", "tel", "url", "email", "password"],
|
||||
testData: [ // Non-dirty value
|
||||
{conditions: {maxLength: "", value: "abc"}, expected: false, name: "[target] Non-dirty value - maxlength is not set"},
|
||||
{conditions: {maxLength: "4", value: ""}, expected: false, name: "[target] Non-dirty value - value is empty string"},
|
||||
{conditions: {maxLength: "4", value: "abc"}, expected: false, name: "[target] Non-dirty value - length of value is less than maxlength"},
|
||||
{conditions: {maxLength: "4", value: "abcd"}, expected: false, name: "[target] Non-dirty value - length of value equals to maxlength"},
|
||||
{conditions: {maxLength: "4", value: "abcde"}, expected: false, name: "[target] Non-dirty value - length of value is greater than maxlength"},
|
||||
//Dirty value
|
||||
{conditions: {maxLength: "4", value: "abc"}, expected: false, name: "[target] Dirty value - value is less than maxlength", dirty: true},
|
||||
{conditions: {maxLength: "4", value: "\u0041\u0041\u0041"}, expected: false, name: "[target] Dirty value - length of value(AAA) in unicode is less than maxlength", dirty: true},
|
||||
{conditions: {maxLength: "4", value: "abcd"}, expected: false, name: "[target] Dirty value - value equals to maxlength", dirty: true},
|
||||
// False due to lack of required interactive editing by the user
|
||||
{conditions: {maxLength: "4", value: "abcde"}, expected: false, name: "[target] Dirty value - length of value is greater than maxlength", dirty: true}
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "textarea",
|
||||
types: [],
|
||||
testData: [
|
||||
{conditions: {maxLength: "", value: "abc"}, expected: false, name: "[target] Non-dirty value - maxlength is not set"},
|
||||
{conditions: {maxLength: "4", value: ""}, expected: false, name: "[target] Non-dirty value - value is empty string"},
|
||||
{conditions: {maxLength: "4", value: "abc"}, expected: false, name: "[target] Non-dirty value - length of value is less than maxlength"},
|
||||
{conditions: {maxLength: "4", value: "abcd"}, expected: false, name: "[target] Non-dirty value - length of value equals to maxlength"},
|
||||
{conditions: {maxLength: "4", value: "abcde"}, expected: false, name: "[target] Non-dirty value - length of value is greater than maxlength"},
|
||||
//Dirty value
|
||||
{conditions: {maxLength: "4", value: "abc"}, expected: false, name: "[target] Dirty value - value is less than maxlength", dirty: true},
|
||||
{conditions: {maxLength: "4", value: "\u000D\u000A"}, expected: false, name: "[target] Dirty value - length of value(LF, CRLF) in unicode is less than maxlength", dirty: true},
|
||||
{conditions: {maxLength: "4", value: "abcd"}, expected: false, name: "[target] Dirty value - length of value equals to maxlength", dirty: true},
|
||||
// False due to lack of required interactive editing by the user
|
||||
{conditions: {maxLength: "4", value: "abcde"}, expected: false, name: "[target] Dirty value - length of value is greater than maxlength", dirty: true}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
validator.run_test (testElements, "tooLong");
|
||||
</script>
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>The constraint validation API Test: element.validity.tooShort</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com/">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/#suffering-from-being-too-short">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="support/validator.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
var testElements = [
|
||||
{
|
||||
tag: "input",
|
||||
types: ["text", "search", "tel", "url", "email", "password"],
|
||||
testData: [
|
||||
// Non-dirty value
|
||||
{conditions: {minLength: "", value: "abc"}, expected: false, name: "[target] Non-dirty value - minLength is not set"},
|
||||
{conditions: {minLength: "4", value: ""}, expected: false, name: "[target] Non-dirty value - value is empty string"},
|
||||
{conditions: {minLength: "4", value: "abcde"}, expected: false, name: "[target] Non-dirty value - length of value is greater than minLength"},
|
||||
{conditions: {minLength: "4", value: "abcd"}, expected: false, name: "[target] Non-dirty value - length of value equals to minLength"},
|
||||
{conditions: {minLength: "4", value: "abc"}, expected: false, name: "[target] Non-dirty value - length of value is less than minLength"},
|
||||
//Dirty value
|
||||
{conditions: {minLength: "4", value: "abcde"}, expected: false, name: "[target] Dirty value - value is greater than minLength", dirty: true},
|
||||
{conditions: {minLength: "4", value: "\u0041\u0041\u0041\u0041\u0041"}, expected: false, name: "[target] Dirty value - length of value(AAAAA) in unicode is greater than minLength", dirty: true},
|
||||
{conditions: {minLength: "4", value: "abcd"}, expected: false, name: "[target] Dirty value - value equals to minLength", dirty: true},
|
||||
// False due to lack of required interactive editing by the user
|
||||
{conditions: {minLength: "4", value: "abc"}, expected: false, name: "[target] Dirty value - length of value is less than minLength", dirty: true}
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "textarea",
|
||||
types: [],
|
||||
testData: [
|
||||
// Non-dirty value
|
||||
{conditions: {minLength: "", value: "abc"}, expected: false, name: "[target] Non-dirty value - minLength is no set"},
|
||||
{conditions: {minLength: "4", value: ""}, expected: false, name: "[target] Non-dirty value - value is empty string"},
|
||||
{conditions: {minLength: "4", value: "abcde"}, expected: false, name: "[target] Non-dirty value - length of value is greater than minLength"},
|
||||
{conditions: {minLength: "4", value: "abcd"}, expected: false, name: "[target] Non-dirty value - length of value equals to minLength"},
|
||||
{conditions: {minLength: "4", value: "abc"}, expected: false, name: "[target] Non-dirty value - length of length of value is greater than minLength"},
|
||||
//Dirty value
|
||||
{conditions: {minLength: "4", value: "abcde"}, expected: false, name: "[target] Dirty value - value is less than minLength", dirty: true},
|
||||
{conditions: {minLength: "4", value: "\u000D\u000A\u000D\u000A\u000D\u000A"}, expected: false, name: "[target] Dirty value - length of value(LF, CRLF) in unicode is less than minLength", dirty: true},
|
||||
{conditions: {minLength: "4", value: "abcd"}, expected: false, name: "[target] Dirty value - length of value equals to minLength", dirty: true},
|
||||
// False due to lack of required interactive editing by the user
|
||||
{conditions: {minLength: "4", value: "abc"}, expected: false, name: "[target] Dirty value - length of value is greater than minLength", dirty: true}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
validator.run_test (testElements, "tooShort");
|
||||
</script>
|
|
@ -0,0 +1,41 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>The constraint validation API Test: element.validity.typeMismatch</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com/">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-validitystate-typemismatch">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="support/validator.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
var testElements = [
|
||||
{
|
||||
tag: "input",
|
||||
types: ["email"],
|
||||
testData: [
|
||||
// multiple is false
|
||||
{conditions: {multiple: false, value: ""}, expected: false, name: "[target] The value is empty"},
|
||||
{conditions: {multiple: false, value: "test@example.com"}, expected: false, name: "[target] The value is a valid email address"},
|
||||
{conditions: {multiple: false, value: "\u000A\u000D\u0020\u0009 test@example.com \u000A\u000D\u0020\u0009"}, expected: false, name: "[target] The value is a valid email address with some white spaces."},
|
||||
{conditions: {multiple: false, value: "abc"}, expected: true, name: "[target] The value is not an email address"},
|
||||
{conditions: {multiple: false, value: "test1@example.com,test2@example.com"}, expected: true, name: "[target] The value contains multiple email addresses"},
|
||||
//multiple is true
|
||||
{conditions: {multiple: true, value: "test1@example.com,test2@example.com"}, expected: false, name: "[target] The value is valid email addresses"},
|
||||
{conditions: {multiple: true, value: "test1@example.com;test2@example.com"}, expected: true, name: "[target] The value contains invalid separator"}
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "input",
|
||||
types: ["url"],
|
||||
testData: [
|
||||
{conditions: {multiple: false, value: ""}, expected: false, name: "[target] The value is empty"},
|
||||
{conditions: {multiple: false, value: "http://www.example.com"}, expected: false, name: "[target] The value is a valid url"},
|
||||
{conditions: {multiple: false, value: "\u000A\u000D\u0020\u0009 http://www.example.com \u000A\u000D\u0020\u0009 "}, expected: false, name: "[target] The value is a valid url with some white spaces."},
|
||||
{conditions: {multiple: false, value: "abc"}, expected: true, name: "[target] The value is not an url"}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
validator.run_test(testElements, "typeMismatch");
|
||||
</script>
|
|
@ -0,0 +1,147 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>The constraint validation API Test: element.validity.valueMissing</title>
|
||||
<link rel="author" title="Intel" href="http://www.intel.com/">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-validitystate-valuemissing">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="support/validator.js"></script>
|
||||
<div id="log"></div>
|
||||
<form>
|
||||
<input id="messagetest" type="checkbox" required="" disabled="">
|
||||
</form>
|
||||
|
||||
<script>
|
||||
var testElements = [
|
||||
{
|
||||
tag: "input",
|
||||
types: ["text", "search", "tel", "url", "email", "password"],
|
||||
testData: [
|
||||
{conditions: {required: false, value: ""}, expected: false, name: "[target] The required attribute is not set"},
|
||||
{conditions: {required: true, value: "abc"}, expected: false, name: "[target] The value is not empty and required is true"},
|
||||
{conditions: {required: true, value: ""}, expected: true, expectedImmutable: false, name: "[target] The value is empty and required is true"}
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "input",
|
||||
types: ["datetime-local"],
|
||||
testData: [
|
||||
{conditions: {required: false, value: ""}, expected: false, name: "[target] The required attribute is not set"},
|
||||
{conditions: {required: true, value: "2000-12-10T12:00:00"}, expected: false, name: "[target] Valid local date and time string(2000-12-10T12:00:00)"},
|
||||
{conditions: {required: true, value: "2000-12-10 12:00"}, expected: false, name: "[target] Valid local date and time string(2000-12-10 12:00)"},
|
||||
{conditions: {required: true, value: "1979-10-14T12:00:00.001"}, expected: false, name: "[target] Valid local date and time string(1979-10-14T12:00:00.001)"},
|
||||
{conditions: {required: true, value: 1234567}, expected: true, expectedImmutable: false, name: "[target] The value attribute is a number(1234567)"},
|
||||
{conditions: {required: true, value: new Date()}, expected: true, expectedImmutable: false, name: "[target] The value attribute is a Date object"},
|
||||
{conditions: {required: true, value: "1979-10-99 99:99"}, expected: true, expectedImmutable: false, name: "[target] Invalid local date and time string(1979-10-99 99:99)"},
|
||||
{conditions: {required: true, value: "1979-10-14 12:00:00"}, expected: false, name: "[target] Valid local date and time string(1979-10-14 12:00:00)"},
|
||||
{conditions: {required: true, value: "2001-12-21 12:00"}, expected: true, expectedImmutable: false, name: "[target] Invalid local date and time string(2001-12-21 12:00)-two white space"},
|
||||
{conditions: {required: true, value: "abc"}, expected: true, expectedImmutable: false, name: "[target] the value attribute is a string(abc)"},
|
||||
{conditions: {required: true, value: ""}, expected: true, expectedImmutable: false, name: "[target] The value attribute is empty string"}
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "input",
|
||||
types: ["date"],
|
||||
testData: [
|
||||
{conditions: {required: false, value: ""}, expected: false, name: "[target] The required attribute is not set"},
|
||||
{conditions: {required: true, value: "2000-12-10"}, expected: false, name: "[target] Valid date string(2000-12-10)"},
|
||||
{conditions: {required: true, value: "9999-01-01"}, expected: false, name: "[target] Valid date string(9999-01-01)"},
|
||||
{conditions: {required: true, value: 1234567}, expected: true, expectedImmutable: false, name: "[target] The value attribute is a number(1234567)"},
|
||||
{conditions: {required: true, value: new Date()}, expected: true, expectedImmutable: false, name: "[target] The value attribute is a Date object"},
|
||||
{conditions: {required: true, value: "9999-99-99"}, expected: true, expectedImmutable: false, name: "[target] Invalid date string(9999-99-99)"},
|
||||
{conditions: {required: true, value: "37/01/01"}, expected: true, expectedImmutable: false, name: "[target] Invalid date string(37-01-01)"},
|
||||
{conditions: {required: true, value: "2000/01/01"}, expected: true, expectedImmutable: false, name: "[target] Invalid date string(2000/01/01)"},
|
||||
{conditions: {required: true, value: ""}, expected: true, expectedImmutable: false, name: "[target] The value attribute is empty string"}
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "input",
|
||||
types: ["time"],
|
||||
testData: [
|
||||
{conditions: {required: false, value: ""}, expected: false, name: "[target] The required attribute is not set"},
|
||||
{conditions: {required: true, value: "12:00:00"}, expected: false, name: "[target] Validtime string(12:00:00)"},
|
||||
{conditions: {required: true, value: "12:00"}, expected: false, name: "[target] Validtime string(12:00)"},
|
||||
{conditions: {required: true, value: "12:00:00.001"}, expected: false, name: "[target] Valid time string(12:00:60.001)"},
|
||||
{conditions: {required: true, value: "12:00:00.01"}, expected: false, name: "[target] Valid time string(12:00:60.01)"},
|
||||
{conditions: {required: true, value: "12:00:00.1"}, expected: false, name: "[target] Valid time string(12:00:60.1)"},
|
||||
{conditions: {required: true, value: 1234567}, expected: true, expectedImmutable: false, name: "[target] The value attribute is a number(1234567)"},
|
||||
{conditions: {required: true, value: new Date()}, expected: true, expectedImmutable: false, name: "[target] The value attribute is a time object"},
|
||||
{conditions: {required: true, value: "25:00:00"}, expected: true, expectedImmutable: false, name: "[target] Invalid time string(25:00:00)"},
|
||||
{conditions: {required: true, value: "12:60:00"}, expected: true, expectedImmutable: false, name: "[target] Invalid time string(12:60:00)"},
|
||||
{conditions: {required: true, value: "12:00:60"}, expected: true, expectedImmutable: false, name: "[target] Invalid time string(12:00:60)"},
|
||||
{conditions: {required: true, value: "12:00:00:001"}, expected: true, expectedImmutable: false, name: "[target] Invalid time string(12:00:00:001)"},
|
||||
{conditions: {required: true, value: ""}, expected: true, expectedImmutable: false, name: "[target] The value attribute is empty string"}
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "input",
|
||||
types: ["number"],
|
||||
testData: [
|
||||
{conditions: {required: false, value: ""}, expected: false, name: "[target] The required attribute is not set"},
|
||||
{conditions: {required: true, value: "123"}, expected: false, name: "[target] Value is an integer with a leading symbol '+'"},
|
||||
{conditions: {required: true, value: "-123.45"}, expected: false, name: "[target] Value is a number with a '-' symbol"},
|
||||
{conditions: {required: true, value: "123.01e-10"}, expected: false, name: "[target] Value is a number in scientific notation form(e is in lowercase)"},
|
||||
{conditions: {required: true, value: "123.01E+10"}, expected: false, name: "[target] Value is a number in scientific notation form(E is in uppercase)"},
|
||||
{conditions: {required: true, value: "-0"}, expected: false, name: "[target] Value is -0"},
|
||||
{conditions: {required: true, value: " 123 "}, expected: true, expectedImmutable: false, name: "[target] Value is a number with some white spaces"},
|
||||
{conditions: {required: true, value: Math.pow(2, 1024)}, expected: true, expectedImmutable: false, name: "[target] Value is Math.pow(2, 1024)"},
|
||||
{conditions: {required: true, value: Math.pow(-2, 1024)}, expected: true, expectedImmutable: false, name: "[target] Value is Math.pow(-2, 1024)"},
|
||||
{conditions: {required: true, value: "abc"}, expected: true, expectedImmutable: false, name: "[target] Value is a string that cannot be converted to a number"},
|
||||
{conditions: {required: true, value: ""}, expected: true, expectedImmutable: false, name: "[target] The value attribute is empty string"}
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "input",
|
||||
types: ["checkbox"],
|
||||
testData: [
|
||||
{conditions: {required: false, checked: false, name: "test1"}, expected: false, name: "[target] The required attribute is not set"},
|
||||
{conditions: {required: true, checked: true, name: "test2"}, expected: false, name: "[target] The checked attribute is true"},
|
||||
{conditions: {required: true, checked: false, name: "test3"}, expected: true, name: "[target] The checked attribute is false"}
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "input",
|
||||
types: ["radio"],
|
||||
testData: [
|
||||
{conditions: {required: false, checked: false, name: "test4"}, expected: false, name: "[target] The required attribute is not set"},
|
||||
{conditions: {required: true, checked: true, name: "test5"}, expected: false, name: "[target] The checked attribute is true"},
|
||||
{conditions: {required: true, checked: false, name: "test6"}, expected: true, name: "[target] The checked attribute is false"},
|
||||
{conditions: {required: true, checked: false, name: ""}, expected: false, name: "[target] The checked attribute is false and the name attribute is empty"}
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "input",
|
||||
types: ["file"],
|
||||
testData: [
|
||||
{conditions: {required: false, files: null}, expected: false, name: "[target] The required attribute is not set"},
|
||||
{conditions: {required: true, files: null}, expected: true, name: "[target] The Files attribute is null"}
|
||||
//ToDo: Add a case to test the files is not null
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "select",
|
||||
types: [],
|
||||
testData: [
|
||||
{conditions: {required: false, value: ""}, expected: false, name: "[target] The required attribute is not set"},
|
||||
{conditions: {required: true, value: 1}, expected: false, name: "[target] Selected the option with value equals to 1"},
|
||||
{conditions: {required: true, value: ""}, expected: true, name: "[target] Selected the option with value equals to empty"}
|
||||
]
|
||||
},
|
||||
{
|
||||
tag: "textarea",
|
||||
types: [],
|
||||
testData: [
|
||||
{conditions: {required: false, value: ""}, expected: false, name: "[target] The required attribute is not set"},
|
||||
{conditions: {required: true, value: "abc"}, expected: false, name: "[target] The value is not empty"},
|
||||
{conditions: {required: true, value: ""}, expected: true, expectedImmutable: false, name: "[target] The value is empty"}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
validator.run_test(testElements, "valueMissing");
|
||||
|
||||
test(() => {
|
||||
assert_equals(document.getElementById("messagetest").validationMessage, '');
|
||||
}, 'validationMessage should return empty string when willValidate is false and valueMissing is true');
|
||||
</script>
|
|
@ -0,0 +1,90 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>valueMissing property on the input[type=radio] element</title>
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
|
||||
<meta content="valueMissing property on the input[type=radio] element" name="description">
|
||||
<link href="https://html.spec.whatwg.org/multipage/#dom-validitystate-valuemissing" rel="help">
|
||||
<link href="https://html.spec.whatwg.org/multipage/#radio-button-state-(type%3Dradio)%3Asuffering-from-being-missing" rel="help">
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
|
||||
<form style="display: none">
|
||||
<input type="radio" name="group1" id="radio1">
|
||||
<input type="radio" name="group1" id="radio2">
|
||||
|
||||
<input type="radio" name="group2" required id="radio3">
|
||||
<input type="radio" name="group2" id="radio4">
|
||||
|
||||
<input type="radio" name="group3" required checked id="radio5">
|
||||
<input type="radio" name="group3" id="radio6">
|
||||
|
||||
<input type="radio" name="group4" required id="radio7">
|
||||
<input type="radio" name="group4" checked id="radio8">
|
||||
<input type="radio" name="group4" id="radio9">
|
||||
|
||||
<input type="radio" name="group5" required disabled id="radio10">
|
||||
<input type="radio" name="group5" id="radio11">
|
||||
|
||||
<input type="radio" name="group6" required checked disabled id="radio12">
|
||||
<input type="radio" name="group6" id="radio13">
|
||||
</form>
|
||||
|
||||
<script type="text/javascript">
|
||||
var cases = [
|
||||
{
|
||||
name: "The required attribute is not set",
|
||||
group: ["radio1", "radio2"],
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
name: "One of the radios is required, but none checked",
|
||||
group: ["radio3", "radio4"],
|
||||
expected: true
|
||||
},
|
||||
{
|
||||
name: "One of the radios is required and checked",
|
||||
group: ["radio5", "radio6"],
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
name: "One of the radios is required and another one is checked",
|
||||
group: ["radio7", "radio8", "radio9"],
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
name: "One of the radios is required and disabled, but none checked",
|
||||
group: ["radio10", "radio11"],
|
||||
expected: true
|
||||
},
|
||||
{
|
||||
name: "One of the radios is required, checked and disabled",
|
||||
group: ["radio12", "radio13"],
|
||||
expected: false
|
||||
}
|
||||
];
|
||||
|
||||
for (var info of cases) {
|
||||
test(function () {
|
||||
for (var id of info.group) {
|
||||
var radio = document.getElementById(id);
|
||||
|
||||
assert_class_string(radio.validity, "ValidityState",
|
||||
"HTMLInputElement.validity must be a ValidityState instance");
|
||||
|
||||
if (info.expected) {
|
||||
assert_true(radio.validity.valueMissing,
|
||||
"The " + id + ".validity.valueMissing should be true");
|
||||
} else {
|
||||
assert_false(radio.validity.valueMissing,
|
||||
"The " + id + ".validity.valueMissing should be false");
|
||||
}
|
||||
}
|
||||
}, info.name);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Forms</title>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<h3>button_validity</h3>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="log"></div>
|
||||
|
||||
<form method="post"
|
||||
enctype="application/x-www-form-urlencoded"
|
||||
action=""
|
||||
id="input_form">
|
||||
<p><button id='button_id'>button</button></p>
|
||||
</form>
|
||||
<script>
|
||||
|
||||
var button = document.getElementById("button_id");
|
||||
|
||||
if (typeof(button.validity) == "object") {
|
||||
test(function() {
|
||||
assert_equals(button.validity.valueMissing, false, "validity attribute is not correct.");
|
||||
});
|
||||
} else {
|
||||
test(function() {
|
||||
assert_unreached("validity attribute is not exist.");
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Forms</title>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<h3>input_validity</h3>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="log"></div>
|
||||
|
||||
<form method="post"
|
||||
enctype="application/x-www-form-urlencoded"
|
||||
action=""
|
||||
id="input_form">
|
||||
<p><input type='hidden' id='input_text'></p>
|
||||
</form>
|
||||
<script>
|
||||
|
||||
var input = document.getElementById("input_text");
|
||||
|
||||
if (typeof(input.validity) == "object") {
|
||||
test(function() {
|
||||
assert_equals(input.validity.valueMissing, false, "validity attribute is not correct.");
|
||||
});
|
||||
} else {
|
||||
test(function() {
|
||||
assert_unreached("validity attribute is not exist.");
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,351 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>input type radio</title>
|
||||
<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
|
||||
<link rel=help href="https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio)">
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<input type=radio name=group1 id=radio1>
|
||||
<input type=radio name=group1 id=radio2>
|
||||
|
||||
<input type=radio name=groüp2 id=radio3>
|
||||
<input type=radio name=groüp2 id=radio4>
|
||||
|
||||
<input type=radio id=radio5>
|
||||
<input type=radio id=radio6 disabled>
|
||||
|
||||
<input type=radio name="group5" id=radio71 checked>
|
||||
<input type=radio name="group5" id=radio72>
|
||||
|
||||
<input type=radio name=group3 id=radio8 checked>
|
||||
<input type=radio name=group3 id=radio9>
|
||||
<input type=radio name=group4 id=radio10>
|
||||
<input type=radio name=group4 id=radio11 checked>
|
||||
|
||||
<form id="testform"></form>
|
||||
<input type=radio form=testform name=group6 id=radio12 checked>
|
||||
<input type=radio form=testform name=group6 id=radio13>
|
||||
<input type=radio form=testform name=group6 id=radio14>
|
||||
|
||||
<script>
|
||||
var radio1 = document.getElementById('radio1'),
|
||||
radio2 = document.getElementById('radio2'),
|
||||
radio3 = document.getElementById('radio3'),
|
||||
radio4 = document.getElementById('radio4'),
|
||||
radio5 = document.getElementById('radio5'),
|
||||
radio6 = document.getElementById('radio6'),
|
||||
radio71 = document.getElementById('radio71'),
|
||||
radio72 = document.getElementById('radio72'),
|
||||
radio8 = document.getElementById('radio8'),
|
||||
radio9 = document.getElementById('radio9'),
|
||||
radio10 = document.getElementById('radio10'),
|
||||
radio11 = document.getElementById('radio11'),
|
||||
radio12 = document.getElementById('radio12'),
|
||||
radio13 = document.getElementById('radio13'),
|
||||
radio14 = document.getElementById('radio14'),
|
||||
testform = document.getElementById('testform'),
|
||||
t1 = async_test("click on mutable radio fires click event, then input event, then change event"),
|
||||
t3 = async_test("click on non-mutable radio doesn't fire the input event"),
|
||||
t4 = async_test("click on non-mutable radio doesn't fire the change event"),
|
||||
t5 = async_test("canceled activation steps on unchecked radio"),
|
||||
input_fired = false,
|
||||
change_fired = false;
|
||||
|
||||
test(function(){
|
||||
assert_false(radio1.checked);
|
||||
assert_false(radio2.checked);
|
||||
radio1.checked = true;
|
||||
assert_true(radio1.checked);
|
||||
assert_false(radio2.checked);
|
||||
radio2.checked = true;
|
||||
assert_false(radio1.checked);
|
||||
assert_true(radio2.checked);
|
||||
}, "only one control of a radio button group can have its checkedness set to true");
|
||||
|
||||
test(function(){
|
||||
assert_false(radio3.checked);
|
||||
assert_false(radio4.checked);
|
||||
radio3.checked = true;
|
||||
assert_true(radio3.checked);
|
||||
assert_false(radio4.checked);
|
||||
radio4.checked = true;
|
||||
assert_false(radio3.checked);
|
||||
assert_true(radio4.checked);
|
||||
}, "radio inputs with non-ASCII name attributes belong to the same radio button group");
|
||||
|
||||
test(function(){
|
||||
assert_true(radio8.checked);
|
||||
assert_false(radio9.checked);
|
||||
assert_false(radio10.checked);
|
||||
assert_true(radio11.checked);
|
||||
radio9.name="group4";
|
||||
radio9.checked = true;
|
||||
assert_true(radio8.checked);
|
||||
assert_true(radio9.checked);
|
||||
assert_false(radio10.checked);
|
||||
assert_false(radio11.checked);
|
||||
}, "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");
|
||||
|
||||
test(function(){
|
||||
radio12.remove();
|
||||
assert_true(radio12.checked);
|
||||
assert_false(radio13.checked);
|
||||
assert_false(radio14.checked);
|
||||
radio13.checked = true;
|
||||
assert_true(radio13.checked);
|
||||
assert_false(radio14.checked);
|
||||
radio13.removeAttribute("form");
|
||||
radio14.removeAttribute("form");
|
||||
assert_true(radio13.checked);
|
||||
assert_false(radio14.checked);
|
||||
radio14.checked = true;
|
||||
assert_false(radio13.checked);
|
||||
assert_true(radio14.checked);
|
||||
radio13.setAttribute("form", "testform");
|
||||
radio14.setAttribute("form", "testform");
|
||||
radio13.checked = true;
|
||||
assert_true(radio13.checked);
|
||||
assert_false(radio14.checked);
|
||||
testform.remove();
|
||||
assert_true(radio13.checked);
|
||||
assert_false(radio14.checked);
|
||||
}, "moving radio input element out of or into a form should still work as expected");
|
||||
|
||||
radio5.onclick = t1.step_func(function(e) {
|
||||
click_fired = true;
|
||||
assert_false(input_fired, "click event should fire before input event");
|
||||
assert_false(change_fired, "click event should fire before change event");
|
||||
assert_false(e.isTrusted, "click()-initiated click event shouldn't be trusted");
|
||||
});
|
||||
|
||||
radio5.oninput = t1.step_func(function(e) {
|
||||
input_fired = true;
|
||||
assert_true(click_fired, "input event should fire after click event");
|
||||
assert_false(change_fired, "input event should fire before change event");
|
||||
assert_true(e.bubbles, "input event should bubble")
|
||||
assert_true(e.isTrusted, "input event should be trusted");
|
||||
assert_false(e.cancelable, "input event should not be cancelable");
|
||||
});
|
||||
|
||||
radio5.onchange = t1.step_func(function(e) {
|
||||
change_fired = true;
|
||||
assert_true(click_fired, "change event should fire after click event");
|
||||
assert_true(input_fired, "change event should fire after input event");
|
||||
assert_true(e.bubbles, "change event should bubble")
|
||||
assert_true(e.isTrusted, "change event should be trusted");
|
||||
assert_false(e.cancelable, "change event should not be cancelable");
|
||||
});
|
||||
|
||||
radio6.oninput= t3.step_func_done(function(e) {
|
||||
assert_unreached("event input fired");
|
||||
});
|
||||
|
||||
radio6.onchange = t4.step_func_done(function(e) {
|
||||
assert_unreached("event change fired");
|
||||
});
|
||||
|
||||
t1.step(function() {
|
||||
radio5.click();
|
||||
assert_true(input_fired);
|
||||
t1.done();
|
||||
});
|
||||
|
||||
t3.step(function(){
|
||||
radio6.click();
|
||||
t3.done();
|
||||
t4.done();
|
||||
});
|
||||
|
||||
radio72.onclick = t5.step_func_done(function(e){
|
||||
assert_false(radio71.checked, "click on radio should uncheck other radio in same group");
|
||||
assert_true(radio72.checked, "click on radio should check that radio");
|
||||
e.preventDefault();
|
||||
// The cancelation of the click doesn't have an effect until after all the click event handlers have been run.
|
||||
assert_false(radio71.checked, "radio remains unchecked immediately after click event on other radio in same group is canceled");
|
||||
assert_true(radio72.checked, "clicked radio remains checked immediately after click event is canceled");
|
||||
});
|
||||
|
||||
t5.step(function(){
|
||||
assert_true(radio71.checked, "initially checked radio should be checked");
|
||||
assert_false(radio72.checked, "other radios in same group as initially-checked radio should be unchecked");
|
||||
radio72.click();
|
||||
// Now that the click event has been fully dispatched, its cancelation has taken effect.
|
||||
assert_true(radio71.checked, "canceled click event on radio should leave the previously-checked radio checked");
|
||||
assert_false(radio72.checked, "canceled click event on previously-unchecked radio should leave that radio unchecked");
|
||||
});
|
||||
|
||||
test(() => {
|
||||
const container = document.createElement('div');
|
||||
container.innerHTML =
|
||||
'<input type=radio name=n1><span><input type=radio name=n1 checked></span>' +
|
||||
'<form><input type=radio name=n1 checked></form>';
|
||||
const radios = container.querySelectorAll('input');
|
||||
assert_false(radios[0].checked, 'Sanity check: The first radio should be unchecked');
|
||||
assert_true(radios[1].checked, 'Sanity check: The second radio should be checked');
|
||||
assert_true(radios[2].checked, 'Sanity check: The third radio should be checked');
|
||||
|
||||
radios[0].checked = true;
|
||||
assert_true(radios[0].checked, 'The first radio should be checked after setting checked');
|
||||
assert_false(radios[1].checked, 'The second radio should be unchecked after setting checked');
|
||||
assert_true(radios[2].checked, 'The third radio should be checked after setting checked');
|
||||
|
||||
radios[1].required = true;
|
||||
assert_false(radios[0].validity.valueMissing, 'The first radio should be valid');
|
||||
assert_false(radios[1].validity.valueMissing, 'The second radio should be valid');
|
||||
assert_false(radios[2].validity.valueMissing, 'The third radio should be valid');
|
||||
|
||||
radios[0].remove();
|
||||
assert_false(radios[0].validity.valueMissing, 'The first radio should be valid because of no required');
|
||||
assert_true(radios[1].validity.valueMissing, 'The second radio should be invalid***');
|
||||
assert_false(radios[2].validity.valueMissing, 'The third radio should be valid');
|
||||
|
||||
radios[0].required = true;
|
||||
radios[0].checked = false;
|
||||
assert_true(radios[0].validity.valueMissing, 'The first radio should be invalid because of required');
|
||||
}, 'Radio buttons in an orphan tree should make a group');
|
||||
|
||||
test(() => {
|
||||
const container = document.createElement('div');
|
||||
container.innerHTML =
|
||||
'<form>' +
|
||||
'<input type=radio name=group1 id=radio1 checked>' +
|
||||
'<input type=radio name=group1 id=radio2>' +
|
||||
'</form>' +
|
||||
'<form>' +
|
||||
'<input type=radio name=group1 id=radio3 checked>' +
|
||||
'<input type=radio name=group1 id=radio4>' +
|
||||
'</form>' +
|
||||
'<input type=radio name=group1 id=radio5 checked>' +
|
||||
'<input type=radio name=group1 id=radio6>';
|
||||
const radio1 = container.querySelector('#radio1');
|
||||
const radio2 = container.querySelector('#radio2');
|
||||
const radio3 = container.querySelector('#radio3');
|
||||
const radio4 = container.querySelector('#radio4');
|
||||
const radio5 = container.querySelector('#radio5');
|
||||
const radio6 = container.querySelector('#radio6');
|
||||
|
||||
// initial conditions
|
||||
assert_true(radio1.checked, 'radio1 should be checked');
|
||||
assert_false(radio2.checked, 'radio2 should be unchecked');
|
||||
assert_true(radio3.checked, 'radio3 should be checked');
|
||||
assert_false(radio4.checked, 'radio4 should be unchecked');
|
||||
assert_true(radio5.checked, 'radio5 should be checked');
|
||||
assert_false(radio6.checked, 'radio6 should be unchecked');
|
||||
|
||||
radio2.checked = true;
|
||||
assert_false(radio1.checked, 'radio1 should be unchecked');
|
||||
assert_true(radio2.checked, 'radio2 should be checked');
|
||||
assert_true(radio3.checked, 'radio3 should remain checked');
|
||||
assert_true(radio5.checked, 'radio5 should remain checked');
|
||||
|
||||
radio4.checked = true;
|
||||
assert_false(radio1.checked, 'radio1 should remain unchecked');
|
||||
assert_true(radio2.checked, 'radio2 should remain checked');
|
||||
assert_false(radio3.checked, 'radio3 should be unchecked');
|
||||
assert_true(radio4.checked, 'radio4 should be checked');
|
||||
assert_true(radio5.checked, 'radio5 should remain checked');
|
||||
|
||||
radio6.checked = true;
|
||||
assert_false(radio1.checked, 'radio1 should remain unchecked');
|
||||
assert_true(radio2.checked, 'radio2 should remain checked');
|
||||
assert_false(radio3.checked, 'radio3 should remain unchecked');
|
||||
assert_true(radio4.checked, 'radio4 should remain checked');
|
||||
assert_false(radio5.checked, 'radio5 should be unchecked');
|
||||
assert_true(radio6.checked, 'radio6 should be checked');
|
||||
}, "Radio buttons in different groups (because they have different form owners or no form owner) do not affect each other's checkedness");
|
||||
|
||||
test(() => {
|
||||
const container = document.createElement('div');
|
||||
container.innerHTML =
|
||||
'<form>' +
|
||||
'<input type=radio name=group1 id=radio1 checked>' +
|
||||
'<input type=radio name=group1 id=radio2>' +
|
||||
'<input type=radio name=group1 id=radio3>' +
|
||||
'<input type=radio name=group1 id=radio4>' +
|
||||
'</form>';
|
||||
const radio1 = container.querySelector('#radio1');
|
||||
const radio2 = container.querySelector('#radio2');
|
||||
const radio3 = container.querySelector('#radio3');
|
||||
const radio4 = container.querySelector('#radio4');
|
||||
|
||||
// initial conditions
|
||||
assert_true(radio1.checked, 'radio1 should be checked');
|
||||
assert_false(radio2.checked, 'radio2 should be unchecked');
|
||||
assert_false(radio3.checked, 'radio3 should be unchecked');
|
||||
assert_false(radio4.checked, 'radio4 should be unchecked');
|
||||
|
||||
radio3.remove();
|
||||
radio4.remove();
|
||||
radio3.checked = true;
|
||||
radio4.checked = true;
|
||||
assert_true(radio1.checked, 'radio1 should remain checked');
|
||||
assert_false(radio2.checked, 'radio2 should remain unchecked');
|
||||
assert_true(radio3.checked, 'radio3 should be checked');
|
||||
assert_true(radio4.checked, 'radio4 should be checked');
|
||||
}, "Radio buttons in different groups (because they are not in the same tree) do not affect each other's checkedness");
|
||||
|
||||
test(() => {
|
||||
const container = document.createElement('div');
|
||||
container.innerHTML =
|
||||
'<form>' +
|
||||
'<input type=radio name=group1 id=radio1 checked>' +
|
||||
'<input type=radio name=group1 id=radio2>' +
|
||||
'<input type=radio name=group2 id=radio3 checked>' +
|
||||
'<input type=radio name=group2 id=radio4>' +
|
||||
'<input type=radio name="" id=radio5 checked>' +
|
||||
'<input type=radio name="" id=radio6>' +
|
||||
'<input type=radio id=radio7 checked>' +
|
||||
'<input type=radio id=radio8>' +
|
||||
'</form>';
|
||||
const radio1 = container.querySelector('#radio1');
|
||||
const radio2 = container.querySelector('#radio2');
|
||||
const radio3 = container.querySelector('#radio3');
|
||||
const radio4 = container.querySelector('#radio4');
|
||||
const radio5 = container.querySelector('#radio5');
|
||||
const radio6 = container.querySelector('#radio6');
|
||||
const radio7 = container.querySelector('#radio7');
|
||||
const radio8 = container.querySelector('#radio8');
|
||||
|
||||
// initial conditions
|
||||
assert_true(radio1.checked, 'radio1 should be checked');
|
||||
assert_false(radio2.checked, 'radio2 should be unchecked');
|
||||
assert_true(radio3.checked, 'radio3 should be checked');
|
||||
assert_false(radio4.checked, 'radio4 should be unchecked');
|
||||
assert_true(radio5.checked, 'radio5 should be checked');
|
||||
assert_false(radio6.checked, 'radio6 should be unchecked');
|
||||
assert_true(radio7.checked, 'radio7 should be checked');
|
||||
assert_false(radio8.checked, 'radio8 should be unchecked');
|
||||
|
||||
radio2.checked = true;
|
||||
assert_false(radio1.checked, 'radio1 should be unchecked');
|
||||
assert_true(radio2.checked, 'radio2 should be checked');
|
||||
assert_true(radio3.checked, 'radio3 should remain checked');
|
||||
assert_false(radio4.checked, 'radio4 should remain unchecked');
|
||||
assert_true(radio5.checked, 'radio5 should remain checked');
|
||||
assert_false(radio6.checked, 'radio6 should remain unchecked');
|
||||
assert_true(radio7.checked, 'radio7 should remain checked');
|
||||
assert_false(radio8.checked, 'radio8 should remain unchecked');
|
||||
|
||||
radio6.checked = true;
|
||||
assert_false(radio1.checked, 'radio1 should remain unchecked');
|
||||
assert_true(radio2.checked, 'radio2 should remain checked');
|
||||
assert_true(radio3.checked, 'radio3 should remain checked');
|
||||
assert_false(radio4.checked, 'radio4 should remain unchecked');
|
||||
assert_true(radio5.checked, 'radio5 should remain checked');
|
||||
assert_true(radio6.checked, 'radio6 should be checked');
|
||||
assert_true(radio7.checked, 'radio7 should remain checked');
|
||||
|
||||
radio8.checked = true;
|
||||
assert_false(radio1.checked, 'radio1 should remain unchecked');
|
||||
assert_true(radio2.checked, 'radio2 should remain checked');
|
||||
assert_true(radio3.checked, 'radio3 should remain checked');
|
||||
assert_false(radio4.checked, 'radio4 should remain unchecked');
|
||||
assert_true(radio5.checked, 'radio5 should remain checked');
|
||||
assert_true(radio6.checked, 'radio6 should remain checked');
|
||||
assert_true(radio7.checked, 'radio7 should remain checked');
|
||||
assert_true(radio8.checked, 'radio8 should be checked');
|
||||
|
||||
}, "Radio buttons in different groups (because they have different name attribute values, or no name attribute) do not affect each other's checkedness");
|
||||
|
||||
</script>
|
Loading…
Add table
Reference in a new issue