{"id":28,"date":"2020-01-15T11:23:27","date_gmt":"2020-01-15T11:23:27","guid":{"rendered":"https:\/\/cebucodesolutions.com\/blog\/?p=28"},"modified":"2020-01-15T11:23:27","modified_gmt":"2020-01-15T11:23:27","slug":"disabling-html5-form-validation-for-laravel-dusk-tests","status":"publish","type":"post","link":"https:\/\/cebucodesolutions.com\/blog\/2020\/01\/15\/disabling-html5-form-validation-for-laravel-dusk-tests\/","title":{"rendered":"Disabling HTML5 form validation for Laravel Dusk tests"},"content":{"rendered":"\n<p>If you\u2019re testing form validation using Laravel Dusk, you\u2019ve probably\n hit a scenario where the form submission is blocked by Chrome before \nit\u2019s sent to the server because of HTML5 form validation.<\/p>\n\n\n\n<p>HTML5 form validation blocks a submission when you add an attribute such as <code>required<\/code> to an input element, or you use <code>type=\"email\"<\/code>.  In your Laravel Dusk tests, you\u2019ll probably see this manifesting as a  client-side popup dialog in your failing test screenshots.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"241\" src=\"https:\/\/cebucodesolutions.com\/blog\/wp-content\/uploads\/2020\/01\/Screenshot-2020-01-02-at-7.58.23-PM-1024x241.png\" alt=\"\" class=\"wp-image-29\" srcset=\"https:\/\/cebucodesolutions.com\/blog\/wp-content\/uploads\/2020\/01\/Screenshot-2020-01-02-at-7.58.23-PM-1024x241.png 1024w, https:\/\/cebucodesolutions.com\/blog\/wp-content\/uploads\/2020\/01\/Screenshot-2020-01-02-at-7.58.23-PM-300x71.png 300w, https:\/\/cebucodesolutions.com\/blog\/wp-content\/uploads\/2020\/01\/Screenshot-2020-01-02-at-7.58.23-PM-768x181.png 768w, https:\/\/cebucodesolutions.com\/blog\/wp-content\/uploads\/2020\/01\/Screenshot-2020-01-02-at-7.58.23-PM.png 1054w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/figure>\n\n\n\n<p>This is a really tricky thing to test. Since it happens completely \nclient-side without modifying the DOM, it\u2019s hard to assert that the \nerror appears. Even if you do work out a hacky way to do it, it\u2019s not \nactually testing that your web application\u2019s form validation is working.\n You\u2019re essentially just testing that Chrome supports HTML5 form \nvalidation, and I\u2019m sure the Google\/Chromium teams have their own tests \nfor that. \ud83d\ude42<\/p>\n\n\n\n<p>Your first thought may be to try to disable HTML5 form validation using <code>ChromeOptions<\/code> in <code>DuskTestCase<\/code>. Unfortunately there is no such option. That really only leaves one way: adding the <code>novalidate<\/code>\n property to your HTML forms. This attribute, when applied to a HTML \nform, disables the browser\u2019s native form validation. But this has its \nown drawback in that it disables a perfectly useful feature that \nprobably provides value to your users.<\/p>\n\n\n\n<p>Thankfully, Dusk allows you to <strong>inject JavaScript onto the page at runtime!<\/strong> Using this feature, we can dynamically inject a small code snippet that iterates over the forms on the page and adds the <code>novalidate<\/code> attribute automatically, <strong>just for your tests<\/strong>. By adding this browser macro to <code>DuskTestCase<\/code>:<\/p>\n\n\n\n<p>Thankfully, Dusk allows you to <strong>inject JavaScript onto the page at runtime!<\/strong> Using this feature, we can dynamically inject a small code snippet that iterates over the forms on the page and adds the <code>novalidate<\/code> attribute automatically, <strong>just for your tests<\/strong>. By adding this browser macro to <code>DuskTestCase<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public static function prepare()\n{\n    static::startChromeDriver();\n\n    Browser::macro('disableClientSideValidation', function () {\n        $this->script('for(var f=document.forms,i=f.length;i--;)f[i].setAttribute(\"novalidate\",i)');\n\n        return $this;\n    });\n}<\/code><\/pre>\n\n\n\n<p>\nyou can then call it within your tests like so:\n\n<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$this->browse(function (Browser $browser) {\n    $browser->visit('\/register')\n        ->disableClientSideValidation()\n        ->type('email', 'notvalidemail')\n        ->click('@submit')\n\n        ->assertPathIs('\/register')\n        ->assertSee('The email must be a valid email address.');\n});<\/code><\/pre>\n\n\n\n<p>\nAnd viola! The result is you\u2019re actually testing your application\u2019s form validation, and <strong>you don\u2019t have to give up HTML5 form validation to do it<\/strong>.\n\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you\u2019re testing form validation using Laravel Dusk, you\u2019ve probably hit a scenario where the form submission is blocked by Chrome before it\u2019s sent to the server because of HTML5 form validation. HTML5 form validation blocks a submission when you add an attribute such as required to an input element, or you use type=&#8221;email&#8221;. In &hellip; <a href=\"https:\/\/cebucodesolutions.com\/blog\/2020\/01\/15\/disabling-html5-form-validation-for-laravel-dusk-tests\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Disabling HTML5 form validation for Laravel Dusk tests&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-28","post","type-post","status-publish","format-standard","hentry","category-updates"],"_links":{"self":[{"href":"https:\/\/cebucodesolutions.com\/blog\/wp-json\/wp\/v2\/posts\/28","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cebucodesolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cebucodesolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cebucodesolutions.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cebucodesolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=28"}],"version-history":[{"count":1,"href":"https:\/\/cebucodesolutions.com\/blog\/wp-json\/wp\/v2\/posts\/28\/revisions"}],"predecessor-version":[{"id":30,"href":"https:\/\/cebucodesolutions.com\/blog\/wp-json\/wp\/v2\/posts\/28\/revisions\/30"}],"wp:attachment":[{"href":"https:\/\/cebucodesolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=28"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cebucodesolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=28"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cebucodesolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=28"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}