Skip to content

Instantly share code, notes, and snippets.

@tgaff
Last active October 20, 2016 02:55
Show Gist options
  • Save tgaff/5094609 to your computer and use it in GitHub Desktop.
Save tgaff/5094609 to your computer and use it in GitHub Desktop.
become and become_true matchers --- use instead of Capybara's wait_until
# Matchers that will wait for a value to change.
# Ex. expect { email.reload.delivered? }.to become_true
RSpec::Matchers.define :become_true do
match do |block|
begin
Timeout.timeout(Capybara.default_wait_time) do
sleep(0.1) until value = block.call
value
end
rescue TimeoutError
false
end
end
end
RSpec::Matchers.define :become_false do
match do |block|
begin
Timeout.timeout(Capybara.default_wait_time) do
sleep(0.1) until value = !block.call
value
end
rescue TimeoutError
false
end
end
end
# Ex. expect { page.current_url }.to become( '/#/something_or_other' )
RSpec::Matchers.define :become do |expected|
match do |block|
begin
Timeout.timeout(Capybara.default_wait_time) do
sleep(0.1) until value = ( block.call == expected )
value
end
rescue TimeoutError
false
end
end
end
@wardpenney
Copy link

@tgaff How would you call this? I get an error:

Failure/Error: expect(font_color_is_good).to become_true
     NoMethodError:
       undefined method `call' for false:FalseClass

@showaltb
Copy link

@wardpenney use a block:

expect { font_color_is_good }.to become_true

@showaltb
Copy link

n.b. you also have to add the line:

supports_block_expectations

to each matcher for RSpec 3.0+

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment