How to write an RSpec matcher that respect's Capybara's within block?
up vote
0
down vote
favorite
I'm trying to write a custom RSpec matcher to be used in Rails system tests, running under Capybara — the idea is to match text while ignoring certain <span>
tags with it.
This is the matcher:
RSpec::Matchers.define :have_cleaned_text do |text|
match do |content|
content.body.include?(text) || content.body.gsub(%r{<span class=["']separator["'].*?>.*?</span>}, ' ').include?(text)
end
end
and the HTML body of the page being tested:
<h1>Test Page</h1>
<div id='constraint'>
<p>Clean text</p>
<p>Broken<span class='separator'>|<span>text</p>
</div>
The first two tests pass:
within('#constraint') do
expect(page).to have_cleaned_text('Clean text')
expect(page).to have_cleaned_text('Broken text')
expect(page).not_to have_cleaned_text('Test Page') # fails!
end
…but the third fails, as have_cleaned_text
is ignoring the within
block and testing against the whole page.
How can I make my matcher respect the within
block? I would have expected it to have been passed as content
, not the whole page…
ruby-on-rails rspec capybara
add a comment |
up vote
0
down vote
favorite
I'm trying to write a custom RSpec matcher to be used in Rails system tests, running under Capybara — the idea is to match text while ignoring certain <span>
tags with it.
This is the matcher:
RSpec::Matchers.define :have_cleaned_text do |text|
match do |content|
content.body.include?(text) || content.body.gsub(%r{<span class=["']separator["'].*?>.*?</span>}, ' ').include?(text)
end
end
and the HTML body of the page being tested:
<h1>Test Page</h1>
<div id='constraint'>
<p>Clean text</p>
<p>Broken<span class='separator'>|<span>text</p>
</div>
The first two tests pass:
within('#constraint') do
expect(page).to have_cleaned_text('Clean text')
expect(page).to have_cleaned_text('Broken text')
expect(page).not_to have_cleaned_text('Test Page') # fails!
end
…but the third fails, as have_cleaned_text
is ignoring the within
block and testing against the whole page.
How can I make my matcher respect the within
block? I would have expected it to have been passed as content
, not the whole page…
ruby-on-rails rspec capybara
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I'm trying to write a custom RSpec matcher to be used in Rails system tests, running under Capybara — the idea is to match text while ignoring certain <span>
tags with it.
This is the matcher:
RSpec::Matchers.define :have_cleaned_text do |text|
match do |content|
content.body.include?(text) || content.body.gsub(%r{<span class=["']separator["'].*?>.*?</span>}, ' ').include?(text)
end
end
and the HTML body of the page being tested:
<h1>Test Page</h1>
<div id='constraint'>
<p>Clean text</p>
<p>Broken<span class='separator'>|<span>text</p>
</div>
The first two tests pass:
within('#constraint') do
expect(page).to have_cleaned_text('Clean text')
expect(page).to have_cleaned_text('Broken text')
expect(page).not_to have_cleaned_text('Test Page') # fails!
end
…but the third fails, as have_cleaned_text
is ignoring the within
block and testing against the whole page.
How can I make my matcher respect the within
block? I would have expected it to have been passed as content
, not the whole page…
ruby-on-rails rspec capybara
I'm trying to write a custom RSpec matcher to be used in Rails system tests, running under Capybara — the idea is to match text while ignoring certain <span>
tags with it.
This is the matcher:
RSpec::Matchers.define :have_cleaned_text do |text|
match do |content|
content.body.include?(text) || content.body.gsub(%r{<span class=["']separator["'].*?>.*?</span>}, ' ').include?(text)
end
end
and the HTML body of the page being tested:
<h1>Test Page</h1>
<div id='constraint'>
<p>Clean text</p>
<p>Broken<span class='separator'>|<span>text</p>
</div>
The first two tests pass:
within('#constraint') do
expect(page).to have_cleaned_text('Clean text')
expect(page).to have_cleaned_text('Broken text')
expect(page).not_to have_cleaned_text('Test Page') # fails!
end
…but the third fails, as have_cleaned_text
is ignoring the within
block and testing against the whole page.
How can I make my matcher respect the within
block? I would have expected it to have been passed as content
, not the whole page…
ruby-on-rails rspec capybara
ruby-on-rails rspec capybara
edited Nov 18 at 14:12
asked Nov 18 at 13:45
John Y
658516
658516
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
In your example page
is a Capybara session (which contains its current scope). When you call body
(source
and html
are aliases) on a session it returns the HTML source of the document. Since you're looking for the HTML source of an element you need something like
RSpec::Matchers.define :have_cleaned_text do |text|
match do |session|
session.current_scope[:innerHTML].include?(text) || session.current_scope[:innerHTML].gsub(%r{<span class=["']separator["'].*?>.*?</span>}, ' ').include?(text)
end
end
Note that a matcher written like that won't have any waiting/retrying behavior, like the Capybara provided matchers, so you need to ensure your page is loaded/stable before using it.
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
In your example page
is a Capybara session (which contains its current scope). When you call body
(source
and html
are aliases) on a session it returns the HTML source of the document. Since you're looking for the HTML source of an element you need something like
RSpec::Matchers.define :have_cleaned_text do |text|
match do |session|
session.current_scope[:innerHTML].include?(text) || session.current_scope[:innerHTML].gsub(%r{<span class=["']separator["'].*?>.*?</span>}, ' ').include?(text)
end
end
Note that a matcher written like that won't have any waiting/retrying behavior, like the Capybara provided matchers, so you need to ensure your page is loaded/stable before using it.
add a comment |
up vote
2
down vote
accepted
In your example page
is a Capybara session (which contains its current scope). When you call body
(source
and html
are aliases) on a session it returns the HTML source of the document. Since you're looking for the HTML source of an element you need something like
RSpec::Matchers.define :have_cleaned_text do |text|
match do |session|
session.current_scope[:innerHTML].include?(text) || session.current_scope[:innerHTML].gsub(%r{<span class=["']separator["'].*?>.*?</span>}, ' ').include?(text)
end
end
Note that a matcher written like that won't have any waiting/retrying behavior, like the Capybara provided matchers, so you need to ensure your page is loaded/stable before using it.
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
In your example page
is a Capybara session (which contains its current scope). When you call body
(source
and html
are aliases) on a session it returns the HTML source of the document. Since you're looking for the HTML source of an element you need something like
RSpec::Matchers.define :have_cleaned_text do |text|
match do |session|
session.current_scope[:innerHTML].include?(text) || session.current_scope[:innerHTML].gsub(%r{<span class=["']separator["'].*?>.*?</span>}, ' ').include?(text)
end
end
Note that a matcher written like that won't have any waiting/retrying behavior, like the Capybara provided matchers, so you need to ensure your page is loaded/stable before using it.
In your example page
is a Capybara session (which contains its current scope). When you call body
(source
and html
are aliases) on a session it returns the HTML source of the document. Since you're looking for the HTML source of an element you need something like
RSpec::Matchers.define :have_cleaned_text do |text|
match do |session|
session.current_scope[:innerHTML].include?(text) || session.current_scope[:innerHTML].gsub(%r{<span class=["']separator["'].*?>.*?</span>}, ' ').include?(text)
end
end
Note that a matcher written like that won't have any waiting/retrying behavior, like the Capybara provided matchers, so you need to ensure your page is loaded/stable before using it.
answered Nov 18 at 16:56
Thomas Walpole
29.2k32546
29.2k32546
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53361565%2fhow-to-write-an-rspec-matcher-that-respects-capybaras-within-block%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown