Package: django-html-validator
django-html-validatorA tool to do validation of your HTML generated from your Django app.
Python 3 compatible.License:MPL 2Warning!If you don't download a localvnu.jarfile (see below), it will usevalidator.nuandsend your HTML there.If you usehtmlvalidatorto validate tests it's unlikely your HTML contains
anything sensitive or personally identifiable but if you use the middleware
option there's a potential risk.InstallFirst things first, very simple:pip install django-html-validatorNote, it won't do anything until you chose how you want to use it and you also
need to explicitly enable it with a setting.Basically, you have a choice of how you want to use this:As a middlewareIn your unit tests (technically they're integration tests in Django)If you chose to set it up as a middleware and enable it accordingly it will
run for every rendered template in the tests too. Not just when you run the
server.SettingsIndependent of how you usehtmlvalidatoryou need to switch it on.
It's not on by default. The setting to do that is:HTMLVALIDATOR_ENABLED=TrueWhat this does, is that it prints all validation errors tostdout.
But it doesn't stop the execution from running. Even if there are errors.To make it so that the execution stops as soon as there is any validation
error switch this on in your settings:HTMLVALIDATOR_FAILFAST=TrueNow, if there's any validation error going through the client you'll
get ahtmlvalidator.exceptions.ValidationErrorexception raised.Equally, if you're running it as a middleware and have this setting on it
will raise the exception in the request.When validation errors and warnings are encountered,htmlvalidatorwill
dump the HTML to a file and the errors in a file with the same name except
with the extension.txtinstead. It will dump this into, by default, the
systems tmp directory and in sub-directory calledhtmlvalidator.
E.g./tmp/htmlvalidator/. If you want to override that change:HTMLVALIDATOR_DUMPDIR='~/validationerrors/'# default it /tmpWhatever you set, the directory doesn't need to exist but its parent does.By default whenhtmlvalidatorencounters validation errors it stores
the relevant HTML file in theHTMLVALIDATOR_DUMPDIRtogether with a file
with the extension.txtin the same directory. Alternatively you can just let
it dump the validation errors and warnings straight onto stdout with:HTMLVALIDATOR_OUTPUT='stdout'# default is 'file'Setting the vnu.jar pathBy default, all validation is done by sending your HTML with HTTP POST tohtml5.validator.nu.Not only does this put a lot of stress on their server. Especially if you have
a lot of tests. It's also slow because it depends on network latency. A much
better way is to download thevnu.jarfile from theirlatest releaseonGitHub page.You set it up simply like this:HTMLVALIDATOR_VNU_JAR='~/downloads/vnu.jar'This alsorequires java to be installedbecause that's how.jarfiles are
executed on the command line.Be aware that calling thisvnu.jarfile is quite slow. Over 2 seconds is
not unusual. A faster alternative is to use thevnu.jarto run a local web
instance of the validator, and pointing validation to use that byNOTsettingHTMLVALIDATOR_VNU_JARand doing this instead:HTMLVALIDATOR_VNU_URL='http://localhost:8888/'The local web instance of the validator can be started typically by:java -cp vnu.jar nu.validator.servlet.Main 8888Validating during running the serverA way to do HTML validation is to do it during running the
server. E.g. with./manage.py runserver.To do that you need to enable the middleware. In your settings module,
appendhtmlvalidator.middleware.HTMLValidatortoMIDDLEWARE_CLASSESfor example like this:ifHTMLVALIDATOR_ENABLED:MIDDLEWARE_CLASSES+=("htmlvalidator.middleware.HTMLValidator",)You can also add it directly and unconditionally toMIDDLEWARE_CLASSESand it won't do anything (except be loaded) unless enabled, see
the note above aboutHTMLVALIDATOR_ENABLEDfor more info.Also, if you enableHTMLVALIDATOR_FAILFAST, when running thehtmlvalidatormiddleware it will raise an exception as soon as it
sees some invalid HTML.Validating HTML in testsSuppose you have a class that does tests. By default it already has aself.clientwhich you use to make requests. All you need to do is to
replace it with thehtmlvalidator.client.ValidatingClientclass. For example:fromdjango.testimportTestCasefromhtmlvalidator.clientimportValidatingClientclassMyAppTests(TestCase):defsetUp(self):super(MyAppTests,self).setUp()self.client=ValidatingClient()deftest_homepage(self):response=self.client.get('/')self.assertEqual(response.status_code,200)