dommy-rails 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +129 -0
- data/lib/dommy/rails/aria_snapshot_matching.rb +100 -0
- data/lib/dommy/rails/browser_spec.rb +148 -0
- data/lib/dommy/rails/dom_source.rb +35 -0
- data/lib/dommy/rails/form_inspector.rb +52 -0
- data/lib/dommy/rails/lint.rb +109 -0
- data/lib/dommy/rails/mail_part.rb +32 -0
- data/lib/dommy/rails/match_target.rb +23 -0
- data/lib/dommy/rails/minitest/assertions.rb +298 -0
- data/lib/dommy/rails/minitest/integration.rb +13 -0
- data/lib/dommy/rails/minitest.rb +4 -0
- data/lib/dommy/rails/page_inspector.rb +66 -0
- data/lib/dommy/rails/rspec/browser.rb +40 -0
- data/lib/dommy/rails/rspec/integration.rb +16 -0
- data/lib/dommy/rails/rspec/matchers.rb +793 -0
- data/lib/dommy/rails/rspec.rb +12 -0
- data/lib/dommy/rails/stimulus.rb +50 -0
- data/lib/dommy/rails/turbo_stream.rb +40 -0
- data/lib/dommy/rails/url_matcher.rb +26 -0
- data/lib/dommy/rails/url_normalizer.rb +45 -0
- data/lib/dommy/rails/version.rb +5 -0
- data/lib/dommy/rails.rb +18 -0
- metadata +78 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require "rspec/expectations"
|
|
5
|
+
rescue LoadError => e
|
|
6
|
+
raise LoadError, "dommy-rails RSpec integration requires rspec-expectations. Add `gem \"rspec\"` or `gem \"rspec-expectations\"` to your Gemfile.", e.backtrace
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
require "dommy/rspec/capy_style_matchers"
|
|
10
|
+
require_relative "../rails"
|
|
11
|
+
require_relative "rspec/matchers"
|
|
12
|
+
require_relative "rspec/integration"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dommy
|
|
4
|
+
module Rails
|
|
5
|
+
module Stimulus
|
|
6
|
+
module_function
|
|
7
|
+
|
|
8
|
+
# ----- Scope-level predicates (any element in scope matches) -----
|
|
9
|
+
|
|
10
|
+
def controller?(scope, name)
|
|
11
|
+
scope.query_selector_all("[data-controller]").to_a.any? { |element| has_controller?(element, name) }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def action?(scope, action)
|
|
15
|
+
scope.query_selector_all("[data-action]").to_a.any? { |element| has_action?(element, action) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def target?(scope, controller, target)
|
|
19
|
+
scope.query_selector_all("[data-#{controller}-target]").to_a.any? { |element| has_target?(element, controller, target) }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def value?(scope, controller, key, value)
|
|
23
|
+
scope.query_selector_all("[data-#{controller}-#{key}-value]").to_a.any? { |element| has_value?(element, controller, key, value) }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# ----- Element-level predicates -----
|
|
27
|
+
|
|
28
|
+
def has_controller?(element, name)
|
|
29
|
+
controllers = element.get_attribute("data-controller").to_s.split
|
|
30
|
+
controllers.include?(name.to_s)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def has_action?(element, action)
|
|
34
|
+
actions = element.get_attribute("data-action").to_s.split
|
|
35
|
+
actions.any? { |a| a == action.to_s || a.end_with?("->#{action}") }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def has_target?(element, controller, target)
|
|
39
|
+
element.has_attribute?("data-#{controller}-target") &&
|
|
40
|
+
element.get_attribute("data-#{controller}-target").to_s.split.include?(target.to_s)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def has_value?(element, controller, key, value)
|
|
44
|
+
attr_name = "data-#{controller}-#{key}-value"
|
|
45
|
+
return false unless element.has_attribute?(attr_name)
|
|
46
|
+
element.get_attribute(attr_name).to_s == value.to_s
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dommy
|
|
4
|
+
module Rails
|
|
5
|
+
module TurboStream
|
|
6
|
+
module_function
|
|
7
|
+
|
|
8
|
+
def parse(body)
|
|
9
|
+
Dommy.parse(body).document.query_selector_all("turbo-stream").to_a
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def find(body, action:, target:)
|
|
13
|
+
parse(body).find do |stream|
|
|
14
|
+
stream.get_attribute("action") == action.to_s && stream.get_attribute("target") == target.to_s
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def matches?(body, action:, target:)
|
|
19
|
+
!find(body, action: action, target: target).nil?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# The <template> payload of a stream element, parsed as its own
|
|
23
|
+
# document (nil when the stream has no template).
|
|
24
|
+
def fragment_document(stream)
|
|
25
|
+
fragment = stream.query_selector("template")&.inner_html
|
|
26
|
+
fragment ? Dommy.parse(fragment).document : nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def fragment_for(body, action:, target:)
|
|
30
|
+
stream = find(body, action: action, target: target)
|
|
31
|
+
stream ? stream.query_selector("template")&.inner_html : nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def fragment_document_for(body, action:, target:)
|
|
35
|
+
stream = find(body, action: action, target: target)
|
|
36
|
+
stream ? fragment_document(stream) : nil
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "url_normalizer"
|
|
4
|
+
|
|
5
|
+
module Dommy
|
|
6
|
+
module Rails
|
|
7
|
+
# Adapts Rails URL normalization to the matcher protocol accepted by
|
|
8
|
+
# Dommy::Internal::ElementMatching.attribute_matches?, so `href:` /
|
|
9
|
+
# `action:` criteria absorb scheme/host, query-parameter order,
|
|
10
|
+
# HTML-escaped `&`, and trailing-slash differences.
|
|
11
|
+
class UrlMatcher
|
|
12
|
+
def initialize(expected)
|
|
13
|
+
@expected = expected
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def matches?(actual)
|
|
17
|
+
case @expected
|
|
18
|
+
when Regexp
|
|
19
|
+
actual.to_s.match?(@expected)
|
|
20
|
+
else
|
|
21
|
+
UrlNormalizer.equal?(@expected, actual)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cgi"
|
|
4
|
+
require "uri"
|
|
5
|
+
|
|
6
|
+
module Dommy
|
|
7
|
+
module Rails
|
|
8
|
+
# Normalizes URLs so Rails URL-helper output and rendered HTML
|
|
9
|
+
# compare equal despite representational differences.
|
|
10
|
+
#
|
|
11
|
+
# Deliberately lenient: scheme and host are dropped, query
|
|
12
|
+
# parameters are sorted, HTML entities are unescaped, and trailing
|
|
13
|
+
# slashes are removed. Strict external-host matching is out of
|
|
14
|
+
# scope (see README).
|
|
15
|
+
module UrlNormalizer
|
|
16
|
+
module_function
|
|
17
|
+
|
|
18
|
+
def equal?(expected, actual)
|
|
19
|
+
normalize(expected) == normalize(actual)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def normalize(url)
|
|
23
|
+
url = url.to_s
|
|
24
|
+
return "" if url.empty?
|
|
25
|
+
|
|
26
|
+
# Attribute values may arrive HTML-escaped (e.g. & in raw
|
|
27
|
+
# response bodies).
|
|
28
|
+
url = CGI.unescapeHTML(url)
|
|
29
|
+
|
|
30
|
+
uri = URI.parse(url)
|
|
31
|
+
path = uri.path.to_s
|
|
32
|
+
path = path.chomp("/") unless path == "/"
|
|
33
|
+
|
|
34
|
+
query = if uri.query
|
|
35
|
+
params = URI.decode_www_form(uri.query).sort_by { |k, _| k }
|
|
36
|
+
URI.encode_www_form(params)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
[path, query].compact.join("?")
|
|
40
|
+
rescue URI::InvalidURIError
|
|
41
|
+
url
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
data/lib/dommy/rails.rb
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require "dommy"
|
|
2
|
+
require_relative "rails/version"
|
|
3
|
+
require_relative "rails/form_inspector"
|
|
4
|
+
require_relative "rails/turbo_stream"
|
|
5
|
+
require_relative "rails/stimulus"
|
|
6
|
+
require_relative "rails/lint"
|
|
7
|
+
require_relative "rails/url_normalizer"
|
|
8
|
+
require_relative "rails/url_matcher"
|
|
9
|
+
require_relative "rails/mail_part"
|
|
10
|
+
require_relative "rails/match_target"
|
|
11
|
+
require_relative "rails/dom_source"
|
|
12
|
+
require_relative "rails/page_inspector"
|
|
13
|
+
require_relative "rails/aria_snapshot_matching"
|
|
14
|
+
|
|
15
|
+
module Dommy
|
|
16
|
+
module Rails
|
|
17
|
+
end
|
|
18
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: dommy-rails
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.9.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- takahashim
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: dommy
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 0.9.0
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 0.9.0
|
|
26
|
+
description: Rails-specific matchers and assertions for Dommy, including form helper
|
|
27
|
+
understanding, Turbo Stream support, Stimulus attribute checking, and HTML quality
|
|
28
|
+
linting.
|
|
29
|
+
email:
|
|
30
|
+
- takahashimm@gmail.com
|
|
31
|
+
executables: []
|
|
32
|
+
extensions: []
|
|
33
|
+
extra_rdoc_files: []
|
|
34
|
+
files:
|
|
35
|
+
- README.md
|
|
36
|
+
- lib/dommy/rails.rb
|
|
37
|
+
- lib/dommy/rails/aria_snapshot_matching.rb
|
|
38
|
+
- lib/dommy/rails/browser_spec.rb
|
|
39
|
+
- lib/dommy/rails/dom_source.rb
|
|
40
|
+
- lib/dommy/rails/form_inspector.rb
|
|
41
|
+
- lib/dommy/rails/lint.rb
|
|
42
|
+
- lib/dommy/rails/mail_part.rb
|
|
43
|
+
- lib/dommy/rails/match_target.rb
|
|
44
|
+
- lib/dommy/rails/minitest.rb
|
|
45
|
+
- lib/dommy/rails/minitest/assertions.rb
|
|
46
|
+
- lib/dommy/rails/minitest/integration.rb
|
|
47
|
+
- lib/dommy/rails/page_inspector.rb
|
|
48
|
+
- lib/dommy/rails/rspec.rb
|
|
49
|
+
- lib/dommy/rails/rspec/browser.rb
|
|
50
|
+
- lib/dommy/rails/rspec/integration.rb
|
|
51
|
+
- lib/dommy/rails/rspec/matchers.rb
|
|
52
|
+
- lib/dommy/rails/stimulus.rb
|
|
53
|
+
- lib/dommy/rails/turbo_stream.rb
|
|
54
|
+
- lib/dommy/rails/url_matcher.rb
|
|
55
|
+
- lib/dommy/rails/url_normalizer.rb
|
|
56
|
+
- lib/dommy/rails/version.rb
|
|
57
|
+
homepage: https://github.com/takahashim/dommy
|
|
58
|
+
licenses:
|
|
59
|
+
- MIT
|
|
60
|
+
metadata: {}
|
|
61
|
+
rdoc_options: []
|
|
62
|
+
require_paths:
|
|
63
|
+
- lib
|
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '3.2'
|
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '0'
|
|
74
|
+
requirements: []
|
|
75
|
+
rubygems_version: 3.6.9
|
|
76
|
+
specification_version: 4
|
|
77
|
+
summary: Rails integration for Dommy DOM testing
|
|
78
|
+
test_files: []
|