@@ -3645,4 +3645,330 @@ public void elementsForOf() throws Exception {
36453645
36463646 loadPageVerifyTitle2 (html );
36473647 }
3648+
3649+ /**
3650+ * A control with a CUSTOM validity message (not a built-in constraint like
3651+ * required) must also block submission.
3652+ * @throws Exception if the test fails
3653+ */
3654+ @ Test
3655+ @ Alerts ("first" )
3656+ public void submitBlockedByCustomValidityOnAnyControl () throws Exception {
3657+ final String html = DOCTYPE_HTML
3658+ + "<html>\n "
3659+ + "<head><title>first</title>\n "
3660+ + "<script>\n "
3661+ + " function markInvalid() {\n "
3662+ + " document.getElementsByName('test')[0].setCustomValidity('custom error');\n "
3663+ + " }\n "
3664+ + "</script>\n "
3665+ + "</head>\n "
3666+ + "<body onload='markInvalid()'>\n "
3667+ + " <form name='testForm' action='" + URL_SECOND + "'>\n "
3668+ + " <input type='submit' id='submit'>\n "
3669+ + " <input name='test' value='anything'>"
3670+ + " </form>\n "
3671+ + "</body></html>" ;
3672+
3673+ final String html2 = "<?xml version='1.0'?>\n "
3674+ + "<html>\n "
3675+ + "<head><title>second</title></head>\n "
3676+ + "<body>OK</body></html>" ;
3677+ getMockWebConnection ().setDefaultResponse (html2 );
3678+
3679+ final WebDriver driver = loadPage2 (html );
3680+ driver .findElement (By .id ("submit" )).click ();
3681+ if (useRealBrowser ()) {
3682+ Thread .sleep (400 );
3683+ }
3684+
3685+ assertEquals (getExpectedAlerts ()[0 ], driver .getTitle ());
3686+ }
3687+
3688+ /**
3689+ * A DISABLED, required, empty field must NOT block submission.
3690+ * @throws Exception if the test fails
3691+ */
3692+ @ Test
3693+ @ Alerts ("second" )
3694+ @ HtmlUnitNYI (CHROME = "first" ,
3695+ EDGE = "first" ,
3696+ FF = "first" ,
3697+ FF_ESR = "first" )
3698+ public void submitNotBlockedByDisabledRequiredEmptyField () throws Exception {
3699+ final String html = DOCTYPE_HTML
3700+ + "<html>\n "
3701+ + "<head><title>first</title></head>\n "
3702+ + "<body>\n "
3703+ + " <form name='testForm' action='" + URL_SECOND + "'>\n "
3704+ + " <input type='submit' id='submit'>\n "
3705+ + " <input name='test' value='' required='required' disabled>"
3706+ + " </form>\n "
3707+ + "</body></html>" ;
3708+
3709+ final String html2 = "<?xml version='1.0'?>\n "
3710+ + "<html>\n "
3711+ + "<head><title>second</title></head>\n "
3712+ + "<body>OK</body></html>" ;
3713+ getMockWebConnection ().setDefaultResponse (html2 );
3714+
3715+ final WebDriver driver = loadPage2 (html );
3716+ driver .findElement (By .id ("submit" )).click ();
3717+ if (useRealBrowser ()) {
3718+ Thread .sleep (400 );
3719+ }
3720+
3721+ assertEquals (getExpectedAlerts ()[0 ], driver .getTitle ());
3722+ }
3723+
3724+ /**
3725+ * The form.checkValidity() must return false when a required field is empty.
3726+ * @throws Exception if an error occurs
3727+ */
3728+ @ Test
3729+ @ Alerts ("false" )
3730+ public void formCheckValidityFalseWhenRequiredFieldEmpty () throws Exception {
3731+ final String html = DOCTYPE_HTML
3732+ + "<html><head>\n "
3733+ + "<script>\n "
3734+ + LOG_TITLE_FUNCTION
3735+ + " function test() {\n "
3736+ + " log(document.getElementById('f').checkValidity());\n "
3737+ + " }\n "
3738+ + "</script></head>\n "
3739+ + "<body onload='test()'>\n "
3740+ + " <form id='f'>\n "
3741+ + " <input name='test' value='' required>\n "
3742+ + " </form>\n "
3743+ + "</body></html>" ;
3744+
3745+ loadPageVerifyTitle2 (html );
3746+ }
3747+
3748+ /**
3749+ * The form.checkValidity() must return true when all fields are individually
3750+ * valid.
3751+ * @throws Exception if an error occurs
3752+ */
3753+ @ Test
3754+ @ Alerts ("true" )
3755+ public void formCheckValidityTrueWhenAllFieldsValid () throws Exception {
3756+ final String html = DOCTYPE_HTML
3757+ + "<html><head>\n "
3758+ + "<script>\n "
3759+ + LOG_TITLE_FUNCTION
3760+ + " function test() {\n "
3761+ + " log(document.getElementById('f').checkValidity());\n "
3762+ + " }\n "
3763+ + "</script></head>\n "
3764+ + "<body onload='test()'>\n "
3765+ + " <form id='f'>\n "
3766+ + " <input name='test' value='filled' required>\n "
3767+ + " </form>\n "
3768+ + "</body></html>" ;
3769+
3770+ loadPageVerifyTitle2 (html );
3771+ }
3772+
3773+ /**
3774+ * A disabled, required, empty field must be SKIPPED by
3775+ * form.checkValidity() (since willValidate is false for it), not counted
3776+ * as either passing or failing -- so the form is valid overall as long as
3777+ * every OTHER, non-barred field is valid.
3778+ * @throws Exception if an error occurs
3779+ */
3780+ @ Test
3781+ @ Alerts ("true" )
3782+ public void formCheckValidityIgnoresDisabledFields () throws Exception {
3783+ final String html = DOCTYPE_HTML
3784+ + "<html><head>\n "
3785+ + "<script>\n "
3786+ + LOG_TITLE_FUNCTION
3787+ + " function test() {\n "
3788+ + " log(document.getElementById('f').checkValidity());\n "
3789+ + " }\n "
3790+ + "</script></head>\n "
3791+ + "<body onload='test()'>\n "
3792+ + " <form id='f'>\n "
3793+ + " <input name='disabledField' value='' required disabled>\n "
3794+ + " <input name='okField' value='filled'>\n "
3795+ + " </form>\n "
3796+ + "</body></html>" ;
3797+
3798+ loadPageVerifyTitle2 (html );
3799+ }
3800+
3801+ /**
3802+ * A <button type='button'> with a custom validity message
3803+ * set must NOT cause form.checkValidity() to fail.
3804+ * @throws Exception if an error occurs
3805+ */
3806+ @ Test
3807+ @ Alerts ("true" )
3808+ public void formCheckValidityIgnoresBarredButtonType () throws Exception {
3809+ final String html = DOCTYPE_HTML
3810+ + "<html><head>\n "
3811+ + "<script>\n "
3812+ + LOG_TITLE_FUNCTION
3813+ + " function test() {\n "
3814+ + " document.getElementById('btn').setCustomValidity('button error');\n "
3815+ + " log(document.getElementById('f').checkValidity());\n "
3816+ + " }\n "
3817+ + "</script></head>\n "
3818+ + "<body onload='test()'>\n "
3819+ + " <form id='f'>\n "
3820+ + " <input name='okField' value='filled'>\n "
3821+ + " <button id='btn' type='button'>not a submitter</button>\n "
3822+ + " </form>\n "
3823+ + "</body></html>" ;
3824+
3825+ loadPageVerifyTitle2 (html );
3826+ }
3827+
3828+ /**
3829+ * The form.reportValidity() must return the same boolean as
3830+ * form.checkValidity() for the same invalid form.
3831+ * @throws Exception if an error occurs
3832+ */
3833+ @ Test
3834+ @ Alerts ({"false" , "false" })
3835+ public void formReportValidityMatchesCheckValidity () throws Exception {
3836+ final String html = DOCTYPE_HTML
3837+ + "<html><head>\n "
3838+ + "<script>\n "
3839+ + LOG_TITLE_FUNCTION
3840+ + " function test() {\n "
3841+ + " var f = document.getElementById('f');\n "
3842+ + " log(f.checkValidity());\n "
3843+ + " log(f.reportValidity());\n "
3844+ + " }\n "
3845+ + "</script></head>\n "
3846+ + "<body onload='test()'>\n "
3847+ + " <form id='f'>\n "
3848+ + " <input name='test' value='' required>\n "
3849+ + " </form>\n "
3850+ + "</body></html>" ;
3851+
3852+ loadPageVerifyTitle2 (html );
3853+ }
3854+
3855+ /**
3856+ * The form.reportValidity() -- interactive validation -- must focus
3857+ * the FIRST invalid control it finds when the form is invalid.
3858+ * @throws Exception if an error occurs
3859+ */
3860+ @ Test
3861+ @ Alerts ("invalid1" )
3862+ @ HtmlUnitNYI (CHROME = "" ,
3863+ EDGE = "" ,
3864+ FF = "" ,
3865+ FF_ESR = "" )
3866+ public void formReportValidityFocusesFirstInvalidControl () throws Exception {
3867+ final String html = DOCTYPE_HTML
3868+ + "<html><head>\n "
3869+ + "<script>\n "
3870+ + LOG_TITLE_FUNCTION
3871+ + " function test() {\n "
3872+ + " document.getElementById('f').reportValidity();\n "
3873+ + " log(document.activeElement.id);\n "
3874+ + " }\n "
3875+ + "</script></head>\n "
3876+ + "<body onload='test()'>\n "
3877+ + " <form id='f'>\n "
3878+ + " <input id='valid1' value='ok'>\n "
3879+ + " <input id='invalid1' value='' required>\n "
3880+ + " <input id='invalid2' value='' required>\n "
3881+ + " </form>\n "
3882+ + "</body></html>" ;
3883+
3884+ loadPageVerifyTitle2 (html );
3885+ }
3886+
3887+ /**
3888+ * Contrast to the above: form.checkValidity() -- static validation -- must
3889+ * NOT move focus at all, even though the form is invalid.
3890+ * @throws Exception if an error occurs
3891+ */
3892+ @ Test
3893+ @ Alerts ({"true" , "true" })
3894+ public void formCheckValidityDoesNotMoveFocus () throws Exception {
3895+ final String html = DOCTYPE_HTML
3896+ + "<html><head>\n "
3897+ + "<script>\n "
3898+ + LOG_TITLE_FUNCTION
3899+ + " function test() {\n "
3900+ + " var before = document.activeElement === document.body;\n "
3901+ + " document.getElementById('f').checkValidity();\n "
3902+ + " var after = document.activeElement === document.body;\n "
3903+ + " log(before);\n "
3904+ + " log(after);\n "
3905+ + " }\n "
3906+ + "</script></head>\n "
3907+ + "<body onload='test()'>\n "
3908+ + " <form id='f'>\n "
3909+ + " <input id='invalid1' value='' required>\n "
3910+ + " </form>\n "
3911+ + "</body></html>" ;
3912+
3913+ loadPageVerifyTitle2 (html );
3914+ }
3915+
3916+ /**
3917+ * The form.checkValidity() must fire an 'invalid' event on the failing control.
3918+ * @throws Exception if an error occurs
3919+ */
3920+ @ Test
3921+ @ Alerts ("invalid fired" )
3922+ public void formCheckValidityFiresInvalidEventOnFailingControl () throws Exception {
3923+ final String html = DOCTYPE_HTML
3924+ + "<html><head>\n "
3925+ + "<script>\n "
3926+ + LOG_TITLE_FUNCTION
3927+ + " function test() {\n "
3928+ + " document.getElementById('i1').addEventListener('invalid', function() {\n "
3929+ + " log('invalid fired');\n "
3930+ + " });\n "
3931+ + " document.getElementById('f').checkValidity();\n "
3932+ + " }\n "
3933+ + "</script></head>\n "
3934+ + "<body onload='test()'>\n "
3935+ + " <form id='f'>\n "
3936+ + " <input id='i1' value='' required>\n "
3937+ + " </form>\n "
3938+ + "</body></html>" ;
3939+
3940+ loadPageVerifyTitle2 (html );
3941+ }
3942+
3943+ /**
3944+ * With MULTIPLE invalid controls, form.checkValidity() must fire
3945+ * 'invalid' on EACH of them.
3946+ * @throws Exception if an error occurs
3947+ */
3948+ @ Test
3949+ @ Alerts ({"i1 invalid" , "i2 invalid" , "false" })
3950+ public void formCheckValidityFiresInvalidEventOnAllFailingControls () throws Exception {
3951+ final String html = DOCTYPE_HTML
3952+ + "<html><head>\n "
3953+ + "<script>\n "
3954+ + LOG_TITLE_FUNCTION
3955+ + " function test() {\n "
3956+ + " document.getElementById('i1').addEventListener('invalid', function() {\n "
3957+ + " log('i1 invalid');\n "
3958+ + " });\n "
3959+ + " document.getElementById('i2').addEventListener('invalid', function() {\n "
3960+ + " log('i2 invalid');\n "
3961+ + " });\n "
3962+ + " log(document.getElementById('f').checkValidity());\n "
3963+ + " }\n "
3964+ + "</script></head>\n "
3965+ + "<body onload='test()'>\n "
3966+ + " <form id='f'>\n "
3967+ + " <input id='i1' value='' required>\n "
3968+ + " <input id='i2' value='' required>\n "
3969+ + " </form>\n "
3970+ + "</body></html>" ;
3971+
3972+ loadPageVerifyTitle2 (html );
3973+ }
36483974}
0 commit comments