Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find if a DOM element has an event listener with Ruby

I'm using Watir and Nokogiri to parse web pages and interact with them. I would like to identify whether a DOM element triggers a script when it is clicked. From my research, I understand that this is possible with JavaScript and with the chrome dev tools, but I would like to accomplish this with Ruby.

For example, http://worrydream.com. When I inspect the images displayed, all I see is divs with some CSS styling but no indication that it is a link or that it will react when I click. Yet, when I click certain elements, an animation (or script) is executed. What is there to indicate that clicking an image is an event?

Update: Originally, what I was considering doing was scraping the JavaScript associated with a page and then somehow determining whether an event would be triggered, but I will try the solution proposed by Mark Thomas and mark his answer as correct once I have tested it.

like image 834
Seanny123 Avatar asked Nov 13 '22 05:11

Seanny123


1 Answers

The short answer? Nothing.

The long answer:

In order to find out what elements trigger scripts, you'd need to know what Javascript has been executed that attaches listeners to each element. And in order to do that, you have to be able to execute Javascript. WATIR and Nokogiri don't execute Javascript by themselves. WATIR uses a browser which will execute JavaScript internally. Watir-webdriver uses a Java-based browser emulator (Selenium) which also has a JavaScript executor which will execute the page's javascript. Nokogiri doesn't execute JavaScript at all.

So you'd need to inject some of your own Javascript to "read" what listeners are attached to a particular element. This is not easy because you're not in control of the JavaScript environment. But, even if you found a way to do that, however, it turns out that there is no standard method provided by the W3C DOM interface to find out what event listeners are attached to a particular element. Individual JavaScript libraries like JQuery cache their listeners, but each do it in their own way.

So in other words, this gets VERY complicated.

A possible solution

The following is all conjecture, but if you really wanted to pursue getting this information back in Ruby land, this gives you something to try.

First, you need a way to inject JS into your pages and get a result. This may be possible using watir-webdriver, because Selenium has hooks to do this. See the very end of this page for instructions on how to inject JS and return a result back to the caller in Selenium. Another option is PhantomJS which is a headless browser with a JS API.

Secondly, you need to find a JavaScript library that understands how each of the popular JS libraries cache their listeners and can collect the information. For that, you can try Visual Event 2.

You'd still need to wire these things up, which would require a bit of JS hackery. Good luck.

like image 157
Mark Thomas Avatar answered Nov 14 '22 23:11

Mark Thomas