JS cucumber timeout will not work

Using protractor-cucumber-framework , I try to click a button a hundred times in one step. However, doing this will result in a timeout with a default value of 5000 ms. I would prefer not to change this default value using:

 var config = function() { this.setDefaultTimeout(60*1000); }; module.exports = config; 

This works, but I would rather set a timeout for this single step like this:

 this.When(/^I click on the "([^"]*)" button$/, {timeout: 60*1000}, function(text, callback) { // Click the button 100 times var button = element(by.partialButtonText('Widget')); for(j = 0; j < i; j++) { button.click(); } callback(); }); 

According to cucumber-js readme, this should work, but still leads to:

 Error: Step timed out after 5000 milliseconds at Timer.listOnTimeout (timer.js:92:15) 

Any ideas on why this is not working?

EDIT: It really worked. However, I used it incorrectly. Calling click() hundred times does not take much time. It expires on the step after it:

 this.Then(/^a new widget is created$/, {timeout: 60 * 1000}, function(callback) { // Check if 100 widgets are created }); 

Can someone explain why a long timeout is required in the step after all the click calls? Is there a more elegant way for the cucumber to wait for the button to finish?

+5
source share
1 answer

The reason the timeout does not work for you is expected to be because your callback() gets started earlier, even before the first click() . This is due to the fact that click() is asynchronous and is added to the controlFlow transporter (they are queued to run one after another), but callback() is not. There are several options to avoid this.

Option number 1

You need to make sure that callback() is only triggered after all the promises returned by click() executed.

You can collect all the promises returned and call callback() after they are all resolved. This is what you would like to do if you do not know about controlFlow :

 this.When(/^I click on the "([^"]*)" button$/, {timeout: 60*1000}, function(text, callback) { // Click the button 100 times var button = element(by.partialButtonText('Widget')); var promises = []; for (var i = 0; i < 101; i++) { promises.push(button.click()); } protractor.promise.all(promises).then(callback); }); 

Option number 2

But things can become much simpler if you simply attach callback() to the controlFlow queue as follows:

 this.When(/^I click on the "([^"]*)" button$/, {timeout: 60*1000}, function(text, callback) { // Click the button 100 times var button = element(by.partialButtonText('Widget')); for(var i = 0; i < 101; i++) { button.click(); } browser.controlFlow().execute(callback); }); 

As you can see, when working with Protractor you should use its controlFlow to avoid writing asynchronous (looking) code.

+2
source

Source: https://habr.com/ru/post/1245909/


All Articles