|
# coding: utf-8 |
|
ENV['RAILS_ENV'] ||= 'test' |
|
require_relative '../config/environment' |
|
require 'rails/test_help' |
|
require 'w3c_validators' # Key module. Write in Gemfile: gem 'w3c_validators' |
|
|
|
# meant to be included in /test/test_helper.rb |
|
class ActiveSupport::TestCase |
|
|
|
# Botch fix of W3C validation errors for HTMLs generated by button_to |
|
# |
|
# On 2022-10-26, W3C validation implemented a check, which may raise an error: |
|
# |
|
# > An input element with a type attribute whose value is hidden must not have an autocomplete attribute whose value is on or off. |
|
# |
|
# This is particularly the case for HTMLs generated by button_to as of Rails 7.0.4. |
|
# It seems the implementation in Rails was deliberate to deal with mal-behaviours of |
|
# Firefox (Github Issue-42610: https://github.com/rails/rails/issues/42610 ). |
|
# |
|
# Whatever the reason is, it is highly inconvenient for developers who |
|
# use W3C validation for their Rails apps. |
|
# |
|
# This routine takes a W3C-validation error object (Array) and |
|
# return the same Array where the specific errors are deleted |
|
# so that one could still test the other potential errors with the W3C validation. |
|
# The said errors are recorded with +logger.warn+ (if +prefix+ is given). |
|
# |
|
# Note that this routine does nothing *unless* the config parameter |
|
# config.ignore_w3c_validate_hidden_autocomplete = true |
|
# is set in config, e.g., in the file (if for testing use only): |
|
# /config/environments/test.rb |
|
# |
|
# == References |
|
# |
|
# * Stackoverflow: https://stackoverflow.com/questions/74256523/rails-button-to-fails-with-w3c-validator |
|
# * Github: https://github.com/validator/validator/pull/1458 |
|
# * HTML Spec: https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute:autofill-anchor-mantle-2 |
|
# |
|
# @example Usage, maybe in /test/test_helper.rb |
|
# # Make sure to write in /config/environments/test.rb |
|
# # config.ignore_w3c_validate_hidden_autocomplete = true |
|
# # |
|
# #require 'w3c_validators' |
|
# bind = caller_locations(1,1)[0] # Ruby 2.0+ |
|
# caller_info = sprintf "%s:%d", bind.absolute_path.sub(%r@.*(/test/)@, '\1'), bind.lineno |
|
# errors = @validator.validate_text(response.body).errors |
|
# prefix = "Ignores W3C validation errors (#{caller_info}): " |
|
# errors = _may_ignore_autocomplete_errors_for_hidden(errors, prefix) |
|
# assert_empty errors, "Failed in W3C validation: "+errors.map(&:to_s).inspect |
|
# |
|
# @param errs [Array<W3CValidators::Message>] Output of [email protected]_text(response.body).errors+ |
|
# @param prefix [String] Prefix of the warning message recorded with Logger. |
|
# If empty, no message is recorded in Logger. |
|
# @return [Array<String, W3CValidators::Message>] |
|
def _may_ignore_autocomplete_errors_for_hidden(errs, prefix="") |
|
removeds = [] |
|
return errs if !Rails.configuration.ignore_w3c_validate_hidden_autocomplete |
|
errs.map{ |es| |
|
# Example of an Error: |
|
# ERROR; line 165: An “input” element with a “type” attribute whose value is “hidden” must not have an “autocomplete” attribute whose value is “on” or “off” |
|
if /\AERROR\b.+\binput\b[^a-z]+\belement.+\btype\b.+\bhidden\b.+\bautocomplete\b[^a-z]+\battribute\b/i =~ es.to_s |
|
removeds << es |
|
nil |
|
else |
|
es |
|
end |
|
}.compact |
|
|
|
ensure |
|
# Records it in Logger |
|
if !removeds.empty? && !prefix.blank? |
|
Rails.logger.warn(prefix + removeds.map(&:to_s).uniq.inspect) |
|
end |
|
end |
|
end |