2

I have reduced the issue I'm having to this minimal example with a public site. The click on the 'show-all' button triggers more of the site to become visible in every browser, but not in nightmare:

var Nightmare = require('nightmare');

new Nightmare({timeout: 60000})
  .viewport(1920, 10000)
  .goto('http://mtv.de/charts/5-hitlist-germany-top-100')
  .wait(10000)
  .screenshot('before.png')
  .click('div#content div.chart-container a.button.show-all')
  .wait(20000)
  .screenshot('after.png')
  .run();

I'm drawing a blank as to why this doesn't work, I even tried to trigger the click with jQuery('...').trigger('click'), which works in Chrome, but not inside of a nightmare .evaluate(...). Here is the debug output from running the above example, showing nothing extraordinary:

nightmare queueing action "viewport" +0ms
nightmare queueing action "goto" +3ms
nightmare queueing action "wait" +0ms
nightmare queueing action "screenshot" +0ms
nightmare queueing action "click" +0ms
nightmare queueing action "wait" +0ms
nightmare queueing action "screenshot" +0ms
nightmare run +0ms
nightmare .setup() creating phantom instance with options {"timeout":60000,"interval":50,"weak":true,"loadImages":true,"ignoreSslErrors":true,"sslProtocol":"any","proxy":null,"proxyType":null,"proxyAuth":null,"cookiesFile":null,"webSecurity":true} +0ms
nightmare .setup() phantom instance created +588ms
nightmare .setup() phantom page created +4ms
nightmare .viewport() to 1920 x 10000 +2ms
nightmare .goto() url: http://mtv.de/charts/5-hitlist-germany-top-100 +2ms
nightmare .goto() page loaded: success +3s
nightmare .wait() for 10000ms +501ms
nightmare .screenshot() saved to before.png +10s
nightmare .click() on div#content div.chart-container a.button.show-all +2s
nightmare .wait() for 20000ms +11ms
nightmare .screenshot() saved to after.png +20s
nightmare .teardownInstance() tearing down +2s
Martin
  • 627
  • 4
  • 20

2 Answers2

3

This turns out to be an issue with phantomjs that the developers are aware of, but comes from upstream webkit, rendering it unfixable to them. It occurs when sites use Modernizr (or similar) to check for touch support, which phantom provides. Of course, clicks are not touches in the event queue, and nightmare's click only triggers the former.

The github issue with nightmare has all the links to learn more.

Martin
  • 627
  • 4
  • 20
  • Now, that makes sense. The touch detection probably can be disabled by overwriting `delete window.ontouchstart;` or adding a adjusted version of modernizr and aborting the page version. – Artjom B. Jan 14 '15 at 13:55
  • In this particular case it's also easily possible to just fool Modernizr by overwriting `.touch` to `false`. – Martin Jan 14 '15 at 16:45
  • @ArtjomB. how do you make the browser fool Modernizr? What do you enter where? – manihiki Jan 12 '18 at 04:01
0

I couldn't find out why it doesn't work, but you could simply load the url with the ?expanded=true parameter in the url.

I tried it CasperJS with the following methods:

  • CasperJS' native click which uses PhantomJS page.sendEvent,
  • synthetic PhantomJS click (similar to the one Nightmare is using) and
  • naive click: document.querySelector(selector).click().

I registered to all events and none of them provided any clue.

Community
  • 1
  • 1
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • Yes, that workaround is possible in the above example, however I intend to use this as part of a testing framework, where actual clicks have to be simulated. That's why I really need to get to the bottom of what's going on here. – Martin Jan 09 '15 at 13:08