View
Repeats

Check that an element is hidden via CSS with Spreewald

If you have content inside a page that is hidden by CSS, the following will work with Selenium, but not when using the Rack::Test driver:

Then I should not see "foobear"

This is because the Rack::Test driver does not know if an element is visible, and only looks at the DOM.

Spreewald offers steps to check that an element is hidden by CSS:

Then "foo" should be hidden # "should not be visible" in Spreewald < 1.2.3

You can also check that an element is visible:

Then "foo" shou...
Linked content

Error during Rails 5 upgrade: Environment data not found in the schema

This error is raised because your old database does not have a configured environment yet, which Rails 5 enforces.

If this error occurs while migrating your parallel test databases, make sure to update the parallel_tests gem first: current versions fix this. If you're still using Cucumber < v3, the latest version of parallel_tests will be 2.18.0.

Repeats

Why your Cucumber feature loses cookies when run under Selenium or capybara-webkit

When your Cucumber feature seems to forget cookies / sessions when you run it with Selenium or capybara-webkit, check if the test travels in time like here:

Given the date is 1981-10-20
When I sign in
Then I should see "Welcome!"

What happens here is that the Rails application serving pages runs in 1984, but the process running your Firefox or Webkit still lives today. This gap of 27+ years will expire most Cookies immediately.

If all you need is to freeze the time to a date, a workaround is to travel to the future instead.

chromedriver-helper gem in Gemfile might break you selenium tests (of other projects)

Summary: Don't add chromedriver-helper to the Gemfile

  • the executables might break your tests in projects where chromedriver-helper is not in the Gemfile
  • developers with different chrome versions will have problems using the same chromedriver-helper version

Background

If you install the chromedriver-helper gem, but don't have it in you Gemfile, your selenium tests might fail with:

Selenium::WebDriver::Error::WebDriverError: unable to connect to chromedriver 127.0.0.1:9515

The reason is that chromedriver-helper ov…

Linked contentRepeats

Cucumber: Identifying slow steps that drag down your test speed

In most projects I know, Cucumber test suite speed is not an issue. Of course, running 350 features takes its time, but still each test for itself is reasonably fast. There is nothing you can do to fundamentally speed up such a test (of course, you should be using parallel_tests).

However, in projects that go beyond clicking around in a web GUI and checking results, there might be various measures to speed things up. Katapult tests for example could be sped up more than 4 times by re…

Linked content

Rails + Sidekiq::Web: Configuration for wildcard session cookies

When you're using Sidekiq::Web to monitor the Sidekiq status AND have your session cookie configured to a wildcard domain like .example.com, you need to take an additional step to keep your cookies valid.

Issue

Sidekiq::Web is mounted into your Rails application and will use the Rails session cookie for protection from CSRF attacs. While it somehow figures out the cookie name, it does NOT respect cookie configuration like a custo…

Repeats

Reading an element's attributes with Capybara

capybara_element['attribute_name'] allows accessing an element's attributes in Capybara.

A few examples:

find('#my_element')['class']
# => "first-class second-class"

find('#my_input')['placeholder']
# => "My placeholder value"

find('a#example-link')['href']
# => "http://example.com"

find('#my_element')['missing_attribute']
# => nil

How to install packages from newer Ubuntu releases

We're usually running Ubuntu LTS versions. Sometimes newer hardware requires packages from more recent Ubuntu releases that only come with 6 months of support. If there is really no other way, it's possible to install packages from later Ubuntu releases

Caution: Pay really close attention to what you're doing. Depending on the package, this process may require upgrading a lot of dependencies, possibly breaking the system! You really should not do this unless you've carefully calculated the impact on your system

Preparation

First,…

Selenium: How to close another tab (popup)

If you open a pop-up window [1] in your Selenium tests and you want to close it, you can do this:

# Find our target window
handle = page.driver.find_window("My window title")

# Close it
page.driver.browser.switch_to.window(handle)
page.driver.browser.close

# Have the Selenium driver point to another window
last_handle = page.driver.browser.window_handles.last
page.driver.browser.switch_to.window(last_handle)

Mind these:

  • find_window returns a window handle, which is something like `"{485fa8bd-fa99-…
Repeats

Capybara: Easiest way to get the parent of an element

If you already selected an element and want to get its parent, you can call find(:xpath, '..') on it.
To get the parents parent, call find(:xpath, '../..').

Example

Find a link which contains a twitter icon and check that it links to the correct page:

<a href="http://twitter.com/">
  <i class="icon is-twitter"></i>
</a>
link = page.find("a .icon.is-twitter").find(:xpath, '..')
link[:href].should == "http://twitter.com/"

There is a good overview on xpath syntax on [w3schools](https://www.w3schools.com…

Repeats

Async control flow in JavaScript: Promises, Microtasks, async/await

Slides for Henning's talk on Sep 21st 2017.


Understanding sync vs. async control flow

Talking to synchronous (or "blocking") API

print('script start')
html = http_get('/foo')
print(html)
print('script end')

Script outputs 'script start', (long delay), '<html>...</html>', 'script end'.

Talking to asynchronous (or "evented") API

print('script start')
http_get('foo', done: function(html) {
  print(html)
}
print('script end')

Script outputs `'script st…

Spreewald: Content-Disposition not set when testing a download's filename

Precondition

  • You are not using javascript tests
  • The file is served from a public folder (not via controller)

Problem description

If you deliver files from a public folder it might be that the Content-Disposition header is not set. That's why the following spreewald step might raise an error:

Then I should get a download with filename "..."
expected: /filename="some.pdf"$/
     got: nil (using =~) (RSpec::Expectations::ExpectationNotMetError)

Solution

One solution…

Capybara steps to match stuff within any selector

These steps are now part of Spreewald.

Since Capybara 0.4.1 a within scope will only look at the first element that matches. We find this behavior to be impractical, but it is by design.

In order to perform a test or action in all matching elements, do not use within but prefer the attached "inside any" Cucumber steps like these:

When I follow "Foo" inside any "table"
Then I should see "Bar" inside any "li"
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…

Selenium cannot obtain stable Firefox connection

When using geordi for integration tests you might get the following error when trying to run geordi cucumber:

unable to obtain stable firefox connection in 60 seconds (127.0.0.1:7055) (Selenium::WebDriver::Error::WebDriverError)

This means, that the vnc window the tests is talking to has no proper firefox version running. To figure out the issue this might help you:

  • Check if the .firefox-version (e.g. 24.0) is the same as ~/bin/firefoxes/24.0/firefox says in the browser
  • Maybe [rest…

How to make Webpacker compile once for parallel tests, and only if necessary

Webpack is the future. We're using it in our latest Rails applications.

For tests, we want to compile assets like for production.
For parallel tests, we want to avoid 8 workers compiling the same files at the same time.
When assets did not change, we do not want to spend time compiling them.

Here is our solution for all that.

Its concept should work for all test suites. For Cucumber integration tests, place the following into features/support/webpacker.rb.

```
module WebpackerTestSupport
module_function def compile_once
digest_fi…

Cucumber: Test that an element is not overshadowed by another element

I needed to make sure that an element is visible and not overshadowed by an element that has a higher z-index (like a modal overlay).

Here is the step I wanted:

Then the very important notice should not be overshadowed by another element

This is the step definition:

```
Then(/^(.*?) should not be overshadowed by another element$/) do |locator|
selector = selector_for(locator)
expect(page).to have_css(selector)
js = «-JS
var selector = #{selector.to_json};
var elementFromSelector = document.querySelector(selector)…

Clicking issues with chromedriver

ChromeDriver clicking works by simulating a mouse click in the middle of the element's first client rect (or bounding client rect if it doesn't have a first client rect). (Clicking issues)

So if you are trying to click on an element, chromedriver tries to click at the position where it first finds that element.

This can lead to some problems and unexpected behavior like:

  • Element is not clickable at point ... erros
  • Another element which is now located at…
This website uses cookies to improve usability and analyze traffic.
Accept or learn more