0

Brief introduction to the problem. So my project is using BDD Framework (Cucumber) automated with help of Protractor/Selenium using Typescript as scripting language. I passed a table with multiple rows to the step definition and want to run the function in iteration mode using typescript/javascript. I pass the expected dropdowns values and verify it against the application. I came with the below solution with help of one topic on stack overflow. (Using protractor with loops)

But the problem is that it does not work all the time. Many times i have got function time out error.(Error: function timed out after 30000 milliseconds)

Can anyone please let me know what am i missing here? Any help would be greatly appreciated.

Please find below Cucumber and Typescript code.

Cucumber Step Definition_Screenshot

@then(/^.*verify the country data in both the citizenship drop downs$/, 'extratime', 30000)

public VerifyCountryData(table, callback: CallbackStepDefinition): void {
        let promises = []
        let dropcheck
        let dropcheck1
        let promise
        let noOfRows
        var i,j;
        var i1,j1;
        var k,l;
        var funcs = [];
        for (i = 0; i < 2; i++) {
            let index = i;
            funcs[i] = function(index) {




  promises.push(element(by.model('vm.citizenships['+index+'].citizenshipCd')).all(by.tagName('option')).getText().then((CitizenValueList) => {
                        var dropdown = table.rows()[index][1].split(";")
                        for (i1 = 0; i1 < dropdown.length; i1++) {
                            dropcheck = false;
                            for (j1 = 0; j1 < CitizenValueList.length; j1++) {
                                if (dropdown[i1] === CitizenValueList[j1]) {
                                    dropcheck = true;
                                    break;
                                }
                            }
                            if (!dropcheck) {
                                callback("Passed value: '" + dropdown[i1] + "' not found")
                            }
                        }


                        for (k = 0; k < CitizenValueList.length; k++) {
                            dropcheck1 = false;
                            for (l = 0; l < dropdown.length; l++) {
                                if (CitizenValueList[k] === dropdown[l]) {
                                    dropcheck1 = true;
                                    break;
                                }
                            }
                            if (!dropcheck1) {
                                callback("Application value: '" + CitizenValueList[k] + "' not found in expected")
                            }
                        }

                }))

            }.bind(null, i);
        }
        for (j = 0; j < 2; j++) {
            funcs[j]();
        }

       Promise.all(promises).then(() => {
            callback();
        }, (error) => {
            callback(error);
        });

    }
}
Community
  • 1
  • 1

1 Answers1

0

as far as I can see in your code you loops will take more then 30 seconds, that's the timeout you gave in the @then(/^.*verify the country data in both the citizenship drop downs$/, 'extratime', 30000). If you change it to for example 60000 you have more time for this method.

Upgrading the time is a temporary solution in my opinion, you also need to find the root-cause of exceeding the 30 seconds time limit. One of the problems can be a slow connection which results in not retrieving the webdriver-calls fast enough. Are you testing it locally or against a cloud solution? The experience I have with cloud solutions is that 1 webdriver-call can take up to 1 second. If you compare it to local testing than local webdriver-calls just take a few milliseconds.

About the code. Depending on the version of Typescript you have (I think you need at least version 2.1) you can use async/await. This will remove all the promises.push(..), Promise.all(promises) hell and introduce a more clean code like this

@then(/^.*verify the country data in both the citizenship drop downs$/, 'extratime', 30000)
public async VerifyCountryData(table): Promise < void > {
  const citizenValueListOne = await element(by.model('vm.citizenships[1].citizenshipCd')).all(by.tagName('option')).getText();
  const dropdownOne = table.rows()[1][1].split(';');
  const citizenValueListTwo = await element(by.model('vm.citizenships[2].citizenshipCd')).all(by.tagName('option')).getText();
  const dropdownTwo = table.rows()[2][2].split(';');

  for (let i1 = 0; i1 < dropdownOne.length; i1++) {
    let dropdownOnecheck = false;
    for (let j1 = 0; j1 < citizenValueListOne.length; j1++) {
      if (dropdownOne[i1] === citizenValueListOne[j1]) {
        dropdownOnecheck = true;
        break;
      }
    }
    if (!dropdownOnecheck) {
      Promise.reject(`Passed value: '${dropdownOne[i1]}' not found`);
    }
  }

  for (let k = 0; k < citizenValueListTwo.length; k++) {
    let dropdownTwocheck = false;
    for (let l = 0; l < dropdownTwo.length; l++) {
      if (citizenValueListTwo[k] === dropdownTwo[l]) {
        dropdownTwocheck = true;
        break;
      }
    }
    if (!dropdownTwocheck) {
      Promise.reject(`Application value: '${citizenValueListTwo[k]}' not found in expected`);
    }
  }

  return Promise.resolve();
}

This can also have an impact on the execution time.

Hope this helps

wswebcreation
  • 2,365
  • 2
  • 10
  • 18
  • Thank you so much for the response. Really appreciate it. Well, my project is using Typescript version 1.8.10 so i will need to upgrade it to version 2.1.0 in order to utilize the async/await Typescript features. Meanwhile, I will try to increase the wait period to 60000 or more. As you correctly stated as I am testing against the cloud solution the webdriver call is taking some time and hence it is giving me the timeout errors. – Yogita Nesargi May 17 '17 at 18:17
  • Maybe [this](https://github.com/wswebcreation/protractor-cucumber-typescript-boilerplate) example project can help you – wswebcreation May 17 '17 at 18:37
  • Thanks so much. This link is helpful! – Yogita Nesargi May 17 '17 at 19:51
  • I know, it's mine – wswebcreation May 17 '17 at 19:52
  • That's great. Well explained – Yogita Nesargi May 17 '17 at 20:10