nightwatchjs / nightwatch

Integrated end-to-end testing framework written in Node.js and using W3C Webdriver API. Developed at @browserstack
https://nightwatchjs.org
MIT License
11.79k stars 1.31k forks source link

Loop inside a loop #1029

Closed alexazus closed 8 years ago

alexazus commented 8 years ago

I have this this code, first part is running ok but when it´s time to pass the i value to second loop, it doesn´t work. It looks like that:

function () {
                 return document.querySelectorAll('.menuElementsAgregator>li:nth-of-type(' + i + ')>.tsr-nav-second-level .has-sub .clickableTabWithLink').length
                                },

doesn´t accept(' + i + ') because if for eg. i manually write 2 in place of i rest of the code will run

 .execute(
            function() {
                return document.querySelectorAll('.menuElementsAgregator>li').length
            },
            function(result) {
                total_links = result.value;
                console.log("Number of main links:" + total_links);
                for (var i = 2; i <= total_links; i++) {
                  (function (i) {
                      browser.waitForElementPresent('.menuElementsAgregator', 3000)
                             .click('.menuElementsAgregator>li:nth-child(' + i + ')>a')
                             .waitForElementVisible('.menuElementsAgregator>li:nth-child(' + i + ')', 2000)
                        .execute(
                                function () {
                                    return document.querySelectorAll('.menuElementsAgregator>li:nth-of-type(' + i + ')>.tsr-nav-second-level .has-sub .clickableTabWithLink').length
                                },
                                    function(result) {
                                    total_links2 = result.value;
                                    console.log("Number of links:" + total_links2);
                                for (var j = 2; j <= total_links2 + 1; j++) {
                                    browser.waitUntilElementIsClickable('.menuElementsAgregator>li:nth-child(' + i + ')')
                                           .click('.menuElementsAgregator>li:nth-child(' + i + ')')
                                           .waitForElementPresent('.menuElementsAgregator>li:nth-of-type(' + i + ')>.tsr-nav-second-level>li:nth-of-type(' + j + ').has-sub', 5000)
                                           .click(' .menuElementsAgregator>li:nth-of-type(' + i + ')>.tsr-nav-second-level>li:nth-of-type(' + j + ').has-sub  .clickableTabWithLink:first-child')
                                           .pause(1000)
                                           .waitForElementVisible('.games-list', 5000);
                                            // .end();
                                    }
                                }
                            )
                  })(i);
              }
          })
mrjamesriley commented 8 years ago

Hello - can you post the test in full, and also include the verbose output from running this test. (so I can see the output of the console.log calls you are making, and the fail message etc)

alexazus commented 8 years ago

when i run the code the result is the follwing:

C:\wamp\www\azercell-nightwatch>node nightwatch
Starting selenium server... started - PID:  10048

[76] Test Suite
===================

Running:  Main Menu - Dropdown
Number of main links:4
 √ Element <.menuElementsAgregator> was present after 49 milliseconds.
 √ Element <.menuElementsAgregator>li:nth-child(2)> was visible after 99 millise
conds.
Number of links:[object Object]
 √ Element <.menuElementsAgregator> was present after 19 milliseconds.
 √ Element <.menuElementsAgregator>li:nth-child(3)> was visible after 60 millise
conds.
Number of links:[object Object]
 √ Element <.menuElementsAgregator> was present after 22 milliseconds.
 √ Element <.menuElementsAgregator>li:nth-child(4)> was visible after 55 millise
conds.
Number of links:[object Object]

OK. 6 assertions passed. (6.701s)
mrjamesriley commented 8 years ago

The output you've posted shows all assertions to be passing - is this after having hardcoded the value of i? (in otherwise, please point out what has you thinking that it doesn't work).

Please also post the HTML that this test is running against and I can see if I can help.

alexazus commented 8 years ago

Is passing just for the value of i. when it need to enter here function () { return document.querySelectorAll('.menuElementsAgregator>li:nth-of-type(' + i + ')>.tsr-nav-second-level .has-sub .clickableTabWithLink').length }, it fails returning Number of links:[object Object]

Hope I made myself understood

mrjamesriley commented 8 years ago

Ok, try this, can you change that Number of links line to: console.log("Number of links:" + JSON.stringify(total_links2)) and then paste the output here.

The issue is that the result from the execute initial function is not returning an integer, but instead it's an error - possibly an error object of some kind. Either way, do post the HTML of the page that you are using Nightwatch to test and I'll try and replicate the issue.

alexazus commented 8 years ago

untitled 2 the HTML code

mrjamesriley commented 8 years ago

Ok, so the answer here is that you cannot refer to variables within the execute first function as you would normally expect to. What you can do, is make use of the optional second argument to the execute function, which allows you to pass in data. So in your case, you can pass in the value of i doing something like the following:

.execute(
  function (i) {
    return document.querySelectorAll('.menuElementsAgregator>li:nth-of-type(' + i + ')>.tsr-nav-second-level .has-sub .clickableTabWithLink').length
  }, [i],
  function(result) {

Note the second argument which is an array of data that will be passed into the execute function, referred to in order by the function arguments. You may want to rename i within the initial function, to avoid future confusion - but that should work for you.

See: http://nightwatchjs.org/api#execute

alexazus commented 8 years ago

It worked James, Thank you a lot!! I´ve tried also [i] but I put it at the wrong place!

.execute(
  function (i) {
    return document.querySelectorAll('.menuElementsAgregator>li:nth-of-type[i]>.tsr-nav-second-level .has-sub .clickableTabWithLink').length
  }, 
  function(result) {

Once again thanks for your help and now i understood how it works!

beatfactor commented 8 years ago

In the future please post requests for assistance on the Mailing List or StackOverflow.