View

How to make a cucumber test work with multiple browser sessions

Imagine you want to write a cucumber test for a user-to-user chat. To do this, you need the test to work with several browser sessions, logged in as separate users, at the same time.

Luckily, Capybara makes this really easy:

Scenario:

```
Scenario: Alice and Bob can chat
Given Alice, Bob, and a chat session
When I am signed in as "Alice"
And I go to the chat
And I am signed in as "Bob" [session: bob]
And I go to the chat [session: bob]
And I send the message "Hello, this is Alice!"
Then I should see "Hello, this is A…

Handling duplicate links with Capybara and Cucumber

Sometimes, you might have duplicate links on a page. Trying to click those links will by default cause Capybara to raise an Ambiguous match error.

If you do not care about which of those links are clicked, you can disable this errors by adding the following meta step:

When(/^(.*) \[allow ambiguous\]$/)do |step_text|
  prior_match_strategy = Capybara.match
  Capybara.match = :first
  step(step_text)
ensure
  Capybara.exact = prior_match_strategy
end

Use it with

When I follow "a duplicate link" [allow ambiguous]
Linked contentRepeats

Taking screenshots in Capybara

Capybara-screenshot can automatically save screenshots and the HTML for failed Capybara tests in Cucumber, RSpec or Minitest.

Requires Capybara-Webkit, Selenium or poltergeist for making screenshots. They're saved into $APPLICATION_ROOT/tmp/capybara

The attached files contain config for cucumber integration and a Then show me a screenshot step.

Linked contentAuto-destruct in 53 days

CucumberFactory 2.0 released

We just released version 2.0 of CucumberFactory. The major version was increased because of the breaking change below.

2.0.0 - 2020-02-10

Breaking changes

  • CucumberFactory now raises an ArgumentError if some parts of a matched step were not used. For example, while this step was accepted in recent versions, it will now complain with the message Unable to parse attributes " and the ".:

    Given there is a user with the attribute "foo" and the
    

Compatible changes

Capybara 'fill_in': Ambiguous match for different input names

When you have two inputs, where one contains the name of the other (eg. Name and Name with special treatment), Capybara's fill_in method will fail with the following message:

Ambiguous match, found 2 elements matching visible field "Name" that is not disabled (Capybara::Ambiguous)

You can force Capybara to match exactly what you are typing (which makes your tests better anyways) with match: :prefer_exact:

name = 'Name'
value = 'Bettertest Cucumberbatch'
fill_in(field, with: value, match: :prefer_exact)

Using Sp…

Repeats

Rspec: around(:all) and around(:each) hook execution order

Summary

  • around(:suite) does not exist.
  • around(:all) runs after before(:all) and before after(:all).
  • around(:each) runs before before(:each) and after after(:each).

As this is not 100% obvious (and not yet documented) it is written down in this card. In RSpec 3 :each has the alias :example and :all the alias :context.

Example

```
RSpec.configure do |config|
config.before(:suite) { puts 'BEFORE :suite' }
config.after(:suite) { puts 'AFTER :suite' }
end

describe 'order of hook execution' do
around(:a…

Linked contentRepeats

Automated "git bisect" will make your day

So you're hunting down a regression (or just a bug) and want to use git bisect to find out when it was introduced? Smart kid.
If you have a shell command ready to reveal if your current state is good or bad, you can have git do most of the work for you.

Using git bisect run <your command> you can tell git that your command will reveal the issue; git on the other hand will use the return value of that call to decide if the state is good or bad. …

Repeats

Detect the current Rails environment from JavaScript or CSS

Detecting if a Javascript is running under Selenium WebDriver is super-painful. It's much easier to detect the current Rails environment instead.

You might be better of checking against the name of the current Rails environment. To do this, store the environment name in a data-environment of your <body>. E.g., in your application layout:

%body{'data-environment' => Rails.env}

Now you can say in a piece of Jav…

Repeats

Fixing flaky integration tests

This card shows basic techniques for fixing a flaky integration test suite that sometimes passes and sometimes fails. "Integration test" is a test script that remote-controls a web browser with tools like Selenium WebDriver.

Although the examples in this card use Cucumber and Selenium, the techniques are applicable to all languages and testing tools.

Why tests are flaky

Your tests probably look like this:

When I click on A
When I click on B
When I click on C
Then I should see effects of C

A test like this works fine most of t…

Repeats

Heads up: JavaScript does not like big numbers

In a JavaScript console, type this:

> 9112347935156469760
9112347935156470000

Ooops.

This occurs because JavaScript uses double precision floats to store numbers.

So according to IEEE floating point definition only numbers between -(2^53 - 1) (-9007199254740991) and 2^53 - 1 (9007199254740991) can safely be represented in JavaScript.

Note that ECMAScript 6 will probably also offer [Number.MAX_SAFE_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference…

Geordi 2.7.0 released

  • Fixed #68: The "cucumber" command now fails early when @solo features fail.
  • Added: The "setup" command now prints the db adapter when prompting db credentials.
  • Fixed #71: When used without staged changes, the "commit" command will print a warning and create an empty commit. Any arguments to the command are forwarded to Git.
  • Fixed: The "commit" command will not print the extra message any more.
  • Added: The "commit" command prints a (progre…

Linux, Arial and Helvetica: Different font rendering in Firefox and Chrome

When text renders differently in Firefox and Chrome, it may be caused by a font alias that both browsers handle differently.

Situation

A machine running Linux, and a website with the Bootstrap 3 default font-family: "Helvetica Neue", Helvetica, Arial, sans-serif.

Issue

Anti-aliasing and kerning of text looks bad in Firefox. Worse, it is rendered 1px lower than in Chrome (shifted down).

Reason

Firefox resolves "Helvetica" to an installed ["TeX Gyre Heros", which is its Ghostscript clone](https://www.fontsquirrel.com/fonts/…

Repeats

Capybara: you can use `evaluate_async_script` to execute asynchronous JavaScript

Capybara provides execute_script and evaluate_script to execute JavaScript code in a Selenium-controlled browser. This however is not a good solution for asynchronous JavaScript.

Enter evaluate_async_script, which allows you to execute some asynchronous code and wait until it finishes. There is a timeout of a couple of seconds, so it will not wait forever.

Use it like this:

```ruby
page.evaluate_async_script(«~JS)
let [done] = arguments
doSomethingAsynchronous().then(() => {
done() // call this to indicate we're done
})
J…

Email validation regex

There is a practical short list for valid/invalid example email addresses - Thanks to Florian L.! The definition for valid emails (RFC 5322) can be unhandy for some reasons, though.

Since Ruby 2.3, Ruby's URI lib has a built in email regex. Probably that's the best solution to work with:

```
URI::MailTo::EMAIL_REGEXP

=> /\A[a-zA-Z0-9.!#$%&'*+\/=?^_`{ }~-]+@[a-zA-Z0-…
Repeats

Waiting for page loads and AJAX requests to finish with Capybara

If you're using the Capybara webdriver, steps sometimes fail because the browser hasn't finished loading the next page yet, or it still has a pending AJAX request. You'll often see workarounds like

When I wait for the page to load
Then ...

Workarounds like this do not work reliably, will result in flickering tests and should be avoided. There is no known reliable way to detect if the browser has finished loading the page.

Solution

Instead you should wait until you can observe the result of a page load. E.g. if y…

How to: Specify size of Selenium browser window

Applications often show or hide elements based on viewport dimensions, or may have components that behave differently (like mobile vs desktop navigation menus).
Since you want your integration tests to behave consistently, you want to set a specific size for your tests' browser windows.

Using WebDriver options / Chrome device metrics

For Google Chrome, the preferred way is setting "device metrics". This allows you to configure dimensions larger than your display and enable/disable touch behavior.

Simply use register_driver to set up…

How to enable Chromedriver logging

When using Chrome for Selenium tests, the chromedriver binary will be used to control Chrome. To debug problems that stem from Selenium's Chrome and/or Chromedriver, you might want to enable logging for the chromedriver itself. Here is how.

Option 1: Use Selenium::WebDriver::Service

In your test setup, you may already have something like Capybara::Selenium::Driver.new(@app, browser: :chrome, options: ...), especially when passing options like device emulation.

Similar to options, simply add an extra key service and pass an ins…

Repeats

An auto-mapper for ARIA labels and BEM classes in Cucumber selectors

Spreewald comes with a selector_for helper that matches an English term like the user's profile into a CSS selector. This is useful for steps that refer to a particular section of the page, like the following:

Then I should see "Bruce" within the user's profile
                                 ^^^^^^^^^^^^^^^^^^

If you're too lazy to manually translate English to a CSS selector by adding a line to features/env/selectors.rb, we already have an [auto-mapper to translate English into …

This website uses cookies to improve usability and analyze traffic.
Accept or learn more