diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 4284d2537..f9853ef91 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -26,6 +26,10 @@ nav_order: 5 *JP Balarini* +* Support opt-in Nokogiri HTML5 parsing in view components rendered for test + + *Noah Silvera* + ## 3.21.0 * Updates testing docs to include an example of how to use with RSpec. diff --git a/docs/api.md b/docs/api.md index 3e18fbe58..1bbd7e1a4 100644 --- a/docs/api.md +++ b/docs/api.md @@ -272,6 +272,11 @@ or are made more publicly available via `"render.view_component"`. Will default to `false` in next major version. Defaults to `true`. +### `.use_html5_parsing` + +Whether `Nokogiri::HTML5` is used for parsing generated view component HTML in test. +Defaults to `false`. + ### `.view_component_path` The path in which components, their templates, and their sidecars should diff --git a/lib/view_component/config.rb b/lib/view_component/config.rb index 3edcd22d2..ec7536e65 100644 --- a/lib/view_component/config.rb +++ b/lib/view_component/config.rb @@ -25,7 +25,8 @@ def defaults preview_paths: default_preview_paths, test_controller: "ApplicationController", default_preview_layout: nil, - capture_compatibility_patch_enabled: false + capture_compatibility_patch_enabled: false, + use_html5_parsing: false }) end @@ -126,6 +127,11 @@ def defaults # Will default to `false` in next major version. # Defaults to `true`. + # @!attribute use_html5_parsing + # @return [Boolean] + # Whether `Nokogiri::HTML5` is used for parsing generated view component HTML in test. + # Defaults to `false`. + # @!attribute render_monkey_patch_enabled # @return [Boolean] Whether the #render method should be monkey patched. # If this is disabled, use `#render_component` or diff --git a/lib/view_component/test_helpers.rb b/lib/view_component/test_helpers.rb index 3677763fb..3ad93f511 100644 --- a/lib/view_component/test_helpers.rb +++ b/lib/view_component/test_helpers.rb @@ -60,7 +60,7 @@ def render_inline(component, **args, &block) # :nocov: - Nokogiri::HTML.fragment(@rendered_content) + html_document_class.fragment(@rendered_content) end # `JSON.parse`-d component output. @@ -107,7 +107,7 @@ def render_preview(name, from: __vc_test_helpers_preview_class, params: {}) @rendered_content = result - Nokogiri::HTML.fragment(@rendered_content) + html_document_class.fragment(@rendered_content) end # Execute the given block in the view context (using `instance_exec`). @@ -124,7 +124,7 @@ def render_preview(name, from: __vc_test_helpers_preview_class, params: {}) def render_in_view_context(*args, &block) @page = nil @rendered_content = vc_test_controller.view_context.instance_exec(*args, &block) - Nokogiri::HTML.fragment(@rendered_content) + html_document_class.fragment(@rendered_content) end ruby2_keywords(:render_in_view_context) if respond_to?(:ruby2_keywords, true) @@ -297,5 +297,13 @@ def __vc_test_helpers_preview_class raise NameError, "`render_preview` expected to find #{result}, but it does not exist." end # :nocov: + + def html_document_class + @html_document_class ||= if Rails.application.config.view_component.use_html5_parsing + Nokogiri::HTML5 + else + Nokogiri::HTML4 + end + end end end diff --git a/test/sandbox/test/rendering_test.rb b/test/sandbox/test/rendering_test.rb index fbdf75763..8dd1a42cf 100644 --- a/test/sandbox/test/rendering_test.rb +++ b/test/sandbox/test/rendering_test.rb @@ -16,8 +16,8 @@ def test_render_inline_allocations MyComponent.ensure_compiled allocations = (Rails.version.to_f >= 8.0) ? - {"3.5.0" => 117, "3.4.1" => 117, "3.3.7" => 129} : - {"3.3.7" => 120, "3.3.0" => 120, "3.2.7" => 118, "3.1.6" => 118, "3.0.7" => 127} + {"3.5.0" => 117, "3.4.1" => 119, "3.3.7" => 131} : + {"3.3.7" => 122, "3.3.0" => 120, "3.2.7" => 120, "3.1.6" => 120, "3.0.7" => 130} assert_allocations(**allocations) do render_inline(MyComponent.new)