I'm not sure if this is a Javascript issue or if I'm not using Nightmare.js properly.
I'm using .wait(className)
- then I evaluate the innerHTML
of the className
. This works if I add the className
manually. However, if I want to dynamically add className
, I get the following error:
ReferenceError: className is not defined
This is happening at the .evaluate()
line. Code example below:
for (const [className, childCount] of pageSections) {
it(`RENDERS THE ${className} SECTION CHILDREN`, async (done) => {
RenderHelper.visitPage('/') // Nightmare method from helper file
.wait(`${className}`) // This works, dynamically
.evaluate(() => document.querySelector(`${className}`).innerHTML)
// Above line is where the className is 'undefined'
.end()
.then((result) => {
RenderHelper.matchChildCount(result, childCount);
done();
})
.catch(done);
});
}
Just to re-iterate - if I do the above but I populate the className
manually, it works fine.
What am I missing here?
It seems evaluate()
is mangling the execution context which invalidates the use of className
. To fix this, follow the guidelines in the instructions for the evaluate()
method and pass className
into the callback.
Change
.evaluate(() => document.querySelector(`${className}`).innerHTML)
To
.evaluate(className => return document.querySelector(className).innerHTML)
The documentation follows this method:https://github.com/segmentio/nightmare#evaluatefn-arg1-arg2
Note the use of selector
in this example:
const selector = 'h1'
nightmare
.evaluate(selector => {
// now we're executing inside the browser scope.
return document.querySelector(selector).innerText
}, selector) // <-- that's how you pass parameters from Node scope to browser scope
.then(text => {
// ...
})