Capybara-webkit fails to trigger click event on element, possibly due to presence of ontouchstart

Skip to first unread message

Peter Philips

Oct 31, 2012, 2:14:45 AM10/31/12
Hey all,

I'm not really a front end developer, so I'm not too clear on what exactly is going on here, but I"ll explain whats going on.

I had a suite of tests that worked fine testing a highly javascript based app.  Our front end developer switch event handling around to something he called "touch events" because they were 300ms faster on mobile devices.  This is when the tests started failing.

Basically, I have a link "#submitName", that is responsible for moving elements on the page around.  The javascript that is bound to it is as follows: 
$(document.body).on(R.touchEvent, "#submitName", this.submitName.bind(this));

where there is a function submitName() that does the heavy lifting.

I asked the front end dev, and he asked me if "window.ontouchstart" was supported in the testing driver, and if it was, that might cause problems.

So I stuck a debugger in my tests prior to the error and ran: 
=> "object"

I checked in the console of actual Chrome browser:

And I checked in Selenium and Chrome-Selenium webdrivers:

All my tests pass in Selenium and Chrome-Selenium drivers.

I'm running:
capybara (1.1.2)
capybara-webkit (0.12.1)

Any advice on what's going on here?


Joe Ferris

Oct 31, 2012, 10:45:27 AM10/31/12

I'm new to this as I haven't had to deal with touch events before, but it seems like an odd choice in QtWebKit, which we rely on to simulate the browser:

Looks like the official way to fix this right now is for you to recompile Qt without it: - which would be a huge pain.

I'll see if there's a way to make touch support configurable or something, but for now you could either compile Qt without touch support or trigger touch events instead of click events. Feel free to file a bug report on GitHub issues:


Alex Grande

Oct 31, 2012, 1:57:15 PM10/31/12
Hi Joe,

I work with Peter and I'm the front end developer.

We do a simple check for touch. Is ontouchstart in window? 


var hasTouch = 'ontouchstart' in window;

If so, we use jQuery Mobile's touch library to enable "fast touch."

Fast touch is using touch events rather than click.

On touch-enabled devices, "click" is triggered 300ms after touchend.

Thus, for our human interaction, we use "tap" instead of "click" whenever touch is enabled to create a real mobile app experience for our mobile web users.

So this QtWebKit is using touch events now. This doesn't seem to work for some reason.

Ideally my code doesn't end up looking like this:

var hasTouch = 'ontouchstart' in window && navigator.userAgent.indexOf("capybara"); 

Joe Ferris

Oct 31, 2012, 2:03:47 PM10/31/12
Hey Alex,

Here's what I think is happening:

* QtWebKit supports touch events (the library can be used on mobile devices), so window.ontouchstart is defined and works.
* Your application detects whether or not touch events are supported, and if they are, it listens for touch events instead of click events.
* capybara is built around the idea of clicks, so when you tell it to do things like follow links and press buttons, it sends click events and not touch events, so your event listeners don't fire.

There are two possible workarounds on the testing side:

* Remove support for touch events. This can be done by recompiling Qt, but it's time-consuming and inconvenient to do so.
* Change the tests to send touch events instead of click events. Capybara supports sending whatever events you want, so instead of using the normal helpers, you can find link elements and send touch events.

When I have time, I'll look for a way to make touch event support configurable so that you can just disable it for your tests, but in the mean time, the best workaround might be to just the user agent.


Peter Philips

Oct 31, 2012, 3:59:02 PM10/31/12
Hey Joe,

Thanks very much for your reply.

The second workaround is definitely viable for us.  How would one send a touch event via capybara?

something like: page.find("#submitName").touch() ?

Also, I saw some recent(~2 months ago) commits regarding this.  Should I pull latest from master or is this functionality in the latest official gems?


Joe Ferris

Oct 31, 2012, 4:03:48 PM10/31/12
Hey Peter,

You can use capybara's #trigger method to send events to nodes:


The #trigger method is in the released version of capybara, so you can use whatever is most stable for you.


Peter Philips

Oct 31, 2012, 9:13:55 PM10/31/12
awesome! thanks Joe!

Peter Philips

Nov 1, 2012, 4:51:50 AM11/1/12
So, I realized we are using 'tap' events instead of touchstart to fire the behavior I need to test.  However, using trigger('tap') on a capybara element/node still did not work.

The only thing that seems to work for me is directly triggering the tap event via jquery: 

This keeps us moving with a green test suite :)  

Thanks again for your help in figuring this out, and looking forward to when tap support is configurable :)

Reply all
Reply to author
0 new messages