These are chat archives for rosshinkley/nightmare

8th
Sep 2016
Mingsterism
@mingsterism
Sep 08 2016 08:59
hey guys. any thoughts on why my for loop fails to insert data into var obj
co(function* () {
    for (let x = 0; x < 10; x++) {
        let url = "www.abc.com"  + x;
        yield Promise.resolve(nightmare
            .goto(url)
            .wait(2000)
            .evaluate(function () {
                console.log('done.......')
                const foo = document.getElementsByTagName('div');
                var obj = {}
                var sum = 0
                // -----------------  This does not work ----------------
                 for (let x of foo) {
                     console.log('this does not appear......')
                        var string = x.innerText.split(':');
                        try {
                            obj.string[0] = string[1]; // <<<<<<<<<<<<< for some cases, the selector will not work. Thus, i use try catch.
                        } catch(e) {};
                    }                
                // ----------------------------------------------------------------
                for (let y=0; y<10;y++) {  // this works testing purposes.......................
                    try {
                        sum += y
                    } catch(e) {}
                }
                    return {obj: obj, 
                        sum: sum}
                    })
            .then((x) => {console.log(x)})
            .catch((err) => {console.log(err)})
    )};
})
this is my output
{ obj: {}, sum: 45 }
{ obj: {}, sum: 45 }
{ obj: {}, sum: 45 }
{ obj: {}, sum: 45 }
Mingsterism
@mingsterism
Sep 08 2016 09:06
its alright guys. got it fixed
:)
Mingsterism
@mingsterism
Sep 08 2016 09:18
One question. within the .evaluate(someFn) whereby someFn is being called from an external script1.js. I am unable to var fn = require('module1'). it keeps on giving error fn is not defined
am i unable to invoke any require statements if im calling the function from .evaluate(someFn) in my main.js script?
appreciate help. thanks
eoxia-jimmy
@eoxia-jimmy
Sep 08 2016 13:17
Hi everybody. How can i get the content of my request response with NightmareJS ? Thanks i didn't understand
nightmare
    .goto('http://localhost/test')
    .type('input[name="log"]', 'a')
    .type('input[name="pwd"]', 'a')
    .click('input[type="submit"]')
    // Here i want the content of request response
eoxia-jimmy
@eoxia-jimmy
Sep 08 2016 13:25
The real question is: how to intercept ajax responses?
Ross Hinkley
@rosshinkley
Sep 08 2016 14:47
@mingsterism require is likely not going to work on your .evaluate() function - remember, .evaluate()d functions are run in the client context
unless you mean you're requiring the function to be evaluated?
sorry, example is a little unclear :)
@jimmy-eoxia good question... i know this has come up before
let me see if i can find the issue
Ross Hinkley
@rosshinkley
Sep 08 2016 14:52
ah, i am incorrect, i was thinking of segmentio/nightmare#521
anyway, the answer to that depends on if you need to modify the response
if you just need to listen, you could listen to did-get-response-details, i think
although i can't remember offhand if that works for ajax requsets
Ross Hinkley
@rosshinkley
Sep 08 2016 14:59
you could also use something similar to the original approach in 521 and modify the XHR
or use a proxy
Nick Stanish
@nickstanish
Sep 08 2016 15:03
Hey guys
I'm building a server that runs jobs on nightmare and it must ensure that the job finishes in a set amount of time (e.g. 20 seconds). I wrapped the nightmare code in a promise and I'm using Promise.race to trigger a timeout error if the nightmare code doesn't finish first. That works well, but nightmare is still running and I'd like to cleanup the resources if it times out. https://github.com/segmentio/nightmare/issues/688#issuecomment-238473332 demonstrates a way to cleanup but operations afterwards are still added to the queue with no electron process to handle them
eoxia-jimmy
@eoxia-jimmy
Sep 08 2016 15:11
@rosshinkley dit-get-response-details doesn't have the response content
I don't wanna modify the XHR, i only want the response content :)
Ross Hinkley
@rosshinkley
Sep 08 2016 15:14
@nickstanish do you have a reference to the nightmare instance in the race? if so, could you use nightmare.die?
i'm guessing you want to stop execution out-of-band
Nick Stanish
@nickstanish
Sep 08 2016 15:16
@jimmy-eoxia
You probably mean something like this - add it to the preload and you can push all the responses to a window variable to be accessed later in an evaluate function
// intercept XHR
  var open = window.XMLHttpRequest.prototype.open;
  window.__responses = [];
  window.XMLHttpRequest.prototype.open = function (method, url, async, user, pass) {
      this.addEventListener("readystatechange", function() {
        console.log('ready state %s is %s', url, this.readyState);
        if (this.readyState === 4) {
          window.__responses.push({
            responseText: this.responseText,
            readyState: this.readyState,
            url: url,
            method: method
          });
        }
      }, false);
    open.apply(this, arguments);
  };
Ross Hinkley
@rosshinkley
Sep 08 2016 15:16
@jimmy-eoxia ah, i see. I don't know of a great way to do that without touching the xhr
as @nickstanish pointed out above :)
Nick Stanish
@nickstanish
Sep 08 2016 15:17
@rosshinkley i should be able to access the nightmare instance
eoxia-jimmy
@eoxia-jimmy
Sep 08 2016 15:18
@nickstanish Oh, i think it's a good way for make this, i'm trying! Thanks :)
Ross Hinkley
@rosshinkley
Sep 08 2016 15:18
@nickstanish yeah, then if you set nightmareInstance.die = 'bad things'; or something
Mingsterism
@mingsterism
Sep 08 2016 15:18
@rosshinkley thanks ross for the comments. my .evaluate() is calling a function from another scriptA. so is there any way to allow that scriptA itself to require from another other scriptB ?
Ross Hinkley
@rosshinkley
Sep 08 2016 15:19
it's not documented as it was intended as a shortcut to handle bad http authentication :P
Nick Stanish
@nickstanish
Sep 08 2016 15:20
@rosshinkley so setting nightmare.die should trigger an error callback right?
Ross Hinkley
@rosshinkley
Sep 08 2016 15:20
memory serving
if you don't want to go that route, i wonder if you could splice an .end() action into the chain... hm, i haven't really thought about doing something like that
@mingsterism so... like...
var myFunction = require('./my-script');
nightmare.evaluate(myFunction)
...
where myFunction is like...
function(){
  var myOtherFunction = require('./my-other-script');
  return myOtherFunction();
}
Mingsterism
@mingsterism
Sep 08 2016 15:25
@rosshinkley yes like that.
// main.js
var scriptA = require('scriptA')
.evaluate(scriptA.fn)


// scriptA
var scriptB = require('scriptB')

exports.fn = function() {
    var b = scriptB.foo()
}
Ross Hinkley
@rosshinkley
Sep 08 2016 15:26
so, fn isn't going to have a reference to scriptB
.evaluate()d functions don't have the inherited scope from where they were pulled from
you might want to give this a read
@nickstanish does that work for you?
btw?
Nick Stanish
@nickstanish
Sep 08 2016 15:30
@rosshinkley would nightmare be open to a PR to expose this functionality? something along the lines of setting the error to 'killed by user' or a passed message, emptying the queue, calling end immediately, and preventing further operations from being queued
Ross Hinkley
@rosshinkley
Sep 08 2016 15:31
expanding how die works, essentially?
and making it a full-on feature?
Nick Stanish
@nickstanish
Sep 08 2016 15:31
right, and documenting it :)
Ross Hinkley
@rosshinkley
Sep 08 2016 15:31
100%
by all means
:)
Nick Stanish
@nickstanish
Sep 08 2016 15:31
any tips or recommendations before I dive in?
Ross Hinkley
@rosshinkley
Sep 08 2016 15:32
make sure it's tested? :)
Nick Stanish
@nickstanish
Sep 08 2016 15:33
:100: I'll see what I can do
Ross Hinkley
@rosshinkley
Sep 08 2016 15:33
awesome, lmk if you hit any snags :)
Nick Stanish
@nickstanish
Sep 08 2016 15:34
thanks!
Ross Hinkley
@rosshinkley
Sep 08 2016 15:34
anytime
eoxia-jimmy
@eoxia-jimmy
Sep 08 2016 15:34
@nickstanish i preload your script in custom script, i didn't understand how to use evaluate with my script
Mingsterism
@mingsterism
Sep 08 2016 15:35
@rosshinkley thanks Ross.
Drew Diamantoukos
@KennyRules
Sep 08 2016 15:36

(I have no idea if this is the right room / the right etiquette, apologies !)
I'm trying to do some acceptance testing with React + MaterialUI + codecept.js + NightmareJS, and I love how it requires no extra dev setup with a npm run command - but I've been trying to click a React component by div id, and Nightmare just kind of sends it to an emptyFunction.

I'm using this.click('#UserInfoButton'); and it looks like I can click the element just fine when I use Selenium, but not so with Nightmare/Electron. I've also torn through the dev tools in electron to no success.

I'm relatively new to all this, so please let me know if there are better ways, or if more info is needed!!

Mingsterism
@mingsterism
Sep 08 2016 15:37
btw, sent you a PM. when u got the time, appreciate your help. thanks @rosshinkley
Ross Hinkley
@rosshinkley
Sep 08 2016 15:37
@mingsterism i saw :)
@KennyRules you should be able to use .click() like that, but i'm not clear on what this is in your context
Drew Diamantoukos
@KennyRules
Sep 08 2016 15:40
Sure! So as part of codeceptjs, they have an I object to attach custom functions to, so outside of the definition file I could use I.logout(), for example.
This works perfectly fine, for example: this.fillField('Username', username); - the right field is easily found and the right text is entered.
And this.click('LOGIN'); finds the right button too
It seems to be struggling with the id for a React component though - and I'm not sure which domain the question is most relevant to!
Ross Hinkley
@rosshinkley
Sep 08 2016 15:42
... silly question, does it have an ID? if you inspect it, what does it say?
Drew Diamantoukos
@KennyRules
Sep 08 2016 15:46

Totally fine, I'm hoping it's something obvious!

If I inspect it, it comes up as <span id="UserInfoButton" other-css-things>
If I do something like this.see('#UserInfoButton'), it indicates success. Modifying the search query results in an error

Ross Hinkley
@rosshinkley
Sep 08 2016 15:49
two more silly questions: does the button exist when you try to click on it? and what does the error say?
Drew Diamantoukos
@KennyRules
Sep 08 2016 15:50
Yep! Manually clicking on it when Electron is running works perfectly fine.
And, the weird part is, there is no error - I set up event listener breakpoints with dev tools, and it looks manual clicking vs the simulated clicking is going down two seperate code paths and is where my knowledge is hitting its limits. The end result of clicking via Nightmare/Codecept is emptyFunction.js
Nick Stanish
@nickstanish
Sep 08 2016 15:51

@jimmy-eoxia To get the responses from evaluate you could do something like this:

nightmare
  .goto('http://example.com')
  .wait(10000)
  .evaluate(function () {
    return window.__responses;
  })
  .end()
  .then(function (result) {
    console.log(result)
  })

preload is executed in the browser and you need to use evaluate to get the data. You can also use the console.log events, but there will likely be a lot of noise there

Drew Diamantoukos
@KennyRules
Sep 08 2016 16:29
Having a slight breakthrough - In the react component, if I switch onTouchTap={onClick} to onClick={onClick}, Nightmare/codecept can find it ! But as far as I know, onTouchTap means I get more flexibility with browsers/mobile. Is there some way of combining this handlers?
Though that's probably a question for the MaterialUI people
Rob Brackett
@Mr0grog
Sep 08 2016 16:40
@KennyRules you may want to check out https://www.npmjs.com/package/nightmare-real-mouse
IIRC React does some funny business surrounding events that causes it not to get triggered by the way Nightmare does clicks
Ross Hinkley
@rosshinkley
Sep 08 2016 16:41
:point_up:
Rob Brackett
@Mr0grog
Sep 08 2016 16:42
would be very interested to know if that package also works properly when you only use onTouchTap
Drew Diamantoukos
@KennyRules
Sep 08 2016 16:51
Sure, I'll try playing with it!
Nick Stanish
@nickstanish
Sep 08 2016 20:04
@rosshinkley I'd love to hear some feedback on this: segmentio/nightmare#788
Ross Hinkley
@rosshinkley
Sep 08 2016 20:23
i'll take a look as time permits
:)
Drew Diamantoukos
@KennyRules
Sep 08 2016 21:02
I think you're definitely right @Mr0grog , React definitely seems to be doing some funky business with onClick vs onTouchTap. Unfortunately I could not get that package working with my setup of using codecept as a wrapper for Nightmare - might just be lack of experience in this area though. For now onClick works and I'll try to dive deeper as to what the funny business is - Thanks!
Rob Brackett
@Mr0grog
Sep 08 2016 21:20
Hmmmm, looks like it wouldn't even matter if you did use nightmare-real-mouse; CodeceptJS bypasses Nightmare's click behavior anyway and reproduces the same bug on its own: https://github.com/Codeception/CodeceptJS/blob/d11e30d59f2bb863167732b31850ff4c1bafc2e4/lib/helper/clientscripts/nightmare.js#L81-L86
:(
Drew Diamantoukos
@KennyRules
Sep 08 2016 21:23

!! I've been trying to look for something like that to figure out the root cause!

Well, looks like I have some new ideas to test this weekend and see if I can contribute! Thank you!!

Rob Brackett
@Mr0grog
Sep 08 2016 22:38
no problem