Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

screenshots zero-length when taking multiple screenshots in custom action (empty screenshots) #1161

Closed
auser opened this issue Jun 16, 2017 · 4 comments

Comments

@auser
Copy link

auser commented Jun 16, 2017

I'm kind of stuck on an issue and I'm not sure if I'm understanding the custom action or not. I'm running a nightmare.js script where where I'm trying to take a screenshot of multiple elements on a page.

The first element is captured just fine, but every other element that is below the fold is captured with a zero length. I am struggling to debug this issue. Any help would be incredibly appreciated.

Basically this script walks through a page and selects all the elements on the page that match a selector. Then, using async it collects the responses and returns a buffer of objects. The issue is that the elements below the fold do not get screenshotted (buffer length ends up at zero). I tried to wait() and scroll to the element, but I have not had any success as of yet.

The code is:

import * as Nightmare from 'nightmare'
import * as vo from 'vo'
import * as async from 'async'
import * as fs from 'fs'

const urls:String[] = [
  'https://yahoo.com/'
]


Nightmare.action('snap', function(selector:String, done:Function) {
  const self = this;

  this.evaluate_now(function (selector) {
    return Array.from(document.querySelectorAll(selector))
    .map((ele:Element) => {
      if (ele) {
        const rect = ele.getBoundingClientRect()
        const r:Function = Math.round
        return {
          x: r(rect.left),
          y: r(rect.top),
          width: r(rect.width),
          height: r(rect.height)
        }
      }
    })
  }, function(err, clips) {
    if (err) return done(err)
    if (!clips) return done(new Error(`Selector not found`))
    let snaps = []
    const snap = (clip, cb) => {
      self
        .scrollTo(clip.y - clip.height, clip.x)
        .screenshot(clip, cb)
        .run()
    }
    async.mapSeries(clips.reverse(), snap, (err, res) => {
      done(err, res)
    })
  }, selector)
})

const scrape = (url) => {
  const nightmare = Nightmare({
    show: true
  });
  nightmare
    .goto(url)
    .snap('.navbar')
    .end()
    .then((buffers:Buffer[]) => {
      buffers.forEach((data, index) => {
        fs.writeFileSync(`images/navbar-${index}.png`, data)
      })
    })
}

urls.forEach(scrape)

(I've also posted this on stackoverflow here

@auser auser changed the title screenshot buffer length of 0 when taking multiple screenshots in custom action screenshots zero-length when taking multiple screenshots in custom action (empty screenshots) Jun 16, 2017
@stevenvachon
Copy link

stevenvachon commented Jun 19, 2017

Try running your screenshot after a then:

nightmare.goto(url).then(() => nightmare.snap('.navbar'))

I once had a similar issue where code was being ran before the page was loaded.

@auser
Copy link
Author

auser commented Jun 19, 2017

Hm... Sadly that doesn't fix the bug... :/. Thanks for the idea though!

@casesandberg
Copy link

@wojons
Copy link

wojons commented Sep 7, 2019

I wanted to leave a little note here that I had this same issue while running nightmare in docker and was able to google enough to find that the docker shared memory is 64mb by default and is the cause of this and a few other things changing it to 128mb fixed it but you may need more or less I submitted #1570 to add more info onto the readme.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants