javascriptnode.jsnightmare

nightmare break at 2nd time run in forloop


I am making a web bot the check is a page loaded correctly with nightmare. I have more then one page that need to check per execution of program. I understand how to use nightmare to check a page is loaded or not by checking the selector of a page. It is successful when I only check one page. But when it comes to a for-loop to check 2 page. It fails. I need to use 'vo' module as I found that doing multiple execution of nightmare we need to use vo.

I use my debugger to check. The first loop is well executed. The second one is break when it comes to the '.then' in nightmare.

var run_true = function*() {
    yield nightmare
      .goto('https://www.hkbn.net/personal/home/tc/landing')
      .wait('#root') // Wait for landing page
      .catch(() => {
        console.log('T:Not Found')
      })
      .then(() => {
        console.log('T:Landing page is loaded.');
      })

    yield nightmare.end();
    return null;
  }

  var run_fail = function*() {
    yield nightmare
      .goto('https://www.hkbn.net/personal/home/tc/landing')
      .wait('#rodfsdfdsffsfdsfdsfot') // Wait for landing page
      .then(() => {
        console.log('F:Landing page is loaded.');
      })
      .catch(() => {
        console.log('F:Not Found')
      })
    yield nightmare.end();
    return null;
  }

var test = function*(){
    for(var i = 0; i <2 ; i++){
        if (i==0){
            var x = yield vo(run_fail)();   //x is meaningless, just let it call the run fail
        }else{
            var y = yield vo(run_true)();
        }
    }
}


vo(test)();

I need to have result of run_fail and run_true both being shown. It should be 'F:Not Found' , then 'T:Landing page is loaded.' Currently it is only F:Not Found.


Solution

  • May I suggest rewriting it all with Promises? You will get rid of a lot of headaches. Also, when you have the end() calls, it means the nightmare object will be released after the chain run. Which also means you cannot reuse the object for your second loop run. Here's the code to get you started:

    const Nightmare = require('nightmare');
    const nightmare = Nightmare({ show: true });
    
    var run_true = function() {
        return nightmare
            .goto('https://www.hkbn.net/personal/home/tc/landing')
            .wait('#root') // Wait for landing page
            .catch(() => {
                console.log('T:Not Found')
            })
            .then(() => {
                console.log('T:Landing page is loaded.');
            });
    }
    
    var run_fail = function() {
        return nightmare
            .goto('https://www.hkbn.net/personal/home/tc/landing')
            .wait('#rodfsdfdsffsfdsfdsfot') // Wait for landing page
            .then(() => {
                console.log('F:Landing page is loaded.');
            })
            .catch(() => {
                console.log('F:Not Found')
            });
    }
    
    var test = async function() {
        for (var i = 0; i < 2; i++) {
            try {
                if (i == 0) {
                    await run_fail();
                } else {
                    await run_true();
                }
            } catch (e) {
                // do something with errors
            }
        }
    }
    
    test().catch(err => {
        console.error(err); // do something with error
        process.exit(1);
    }).then(result => {
        console.log('All processes finished');
        process.exit(0);
    });