0

I have a recursive function that is being called like so:

return click(myArray.slice(1));

myArray contains URL objects with some information regarding how they should be processed.

Here is the whole function, as part of a Protractor test suite:

.then(function click(myArray) {
    var tryItButton, tosCheckboxElement, tosContinueButton;

    if (labServices.length < 1) {
        return;
    }

    tryItButton = ...
    tosCheckboxElement = ...
    tosContinueButton = ...

    var EC = protractor.ExpectedConditions;
    var tryItButtonClickable = EC.elementToBeClickable(tryItButton);
    var tryItButtonVisible = EC.visibilityOf(tryItButton);

    return browser.wait(EC.and(tryItButtonClickable, tryItButtonVisible), getWaitTime())
        .then(function() {
            var protocol = url.parse(myArray[0].url).protocol;
            if (protocol === null) {
                throw new Error('expected ' + protocol + ' not to be null');
            }
        })
        .then(function() {
            return tryItButton.click();
        })
        .then(function() {
            return browser.wait(automationcore.ExpectedConditions.responseCompleted(proxy, myArray[0].url));
        })
        .then(function() {
            return browser.get(browser.baseUrl);
        })
        .then(function() {
            return element(tosCheckboxElement).isPresent();
        })
        .then(function(tosCheckboxElementPresent) {
            if (tosCheckboxElementPresent) {
                return browser.wait(EC.elementToBeClickable(element(tosCheckboxElement)), getWaitTime())
                    .then(function() {
                        element(tosCheckboxElement).click();
                        return element(tosContinueButton).isPresent();
                    })
            } else {
                return click(myArray.slice(1));
            }
        })
        .then(function(tosContinueButtonPresent) {
            if(tosContinueButtonPresent) {
                return browser.wait(EC.elementToBeClickable(element(tosContinueButton)), getWaitTime())
                    .then(function() {
                        element(tosContinueButton).click();
                        return browser.get(browser.baseUrl);
                    })
            }
        });
}).catch(fail).then(done);

The results are intermittent in the sense that sometimes, the function is called, and other times, I get a timeout after x ms (For example, on my last run, it was 5548ms). Does slice() usually timeout? If so, is there a good way of handling this behavior? In other words, this test fails because of a function not related to my suite, but rather, a JS function call.

Thanks

TheVillageIdiot
  • 40,053
  • 20
  • 133
  • 188
User 5842
  • 2,849
  • 7
  • 33
  • 51
  • "and other times, I get a timeout after x ms" --- elaborate that. – zerkms Aug 24 '17 at 22:55
  • We need the definition of `click` and the contents of `myArray`. Have you used your debugger? Is this running in Node or a browser or some other host? – Dai Aug 24 '17 at 22:55
  • What are you trying to acheive? Please explain! – ibrahim mahrir Aug 24 '17 at 22:57
  • I added some more context. Let me know if I can clarify more. Thanks – User 5842 Aug 24 '17 at 22:58
  • It seemed like changing the original `return click(myArray.slice(1));` to `browser.wait(return click(myArray.slice(1)));` worked fine until it threw an error when a promise was expected. – User 5842 Aug 24 '17 at 23:18
  • "*this test fails because of a function not related to my suite, but rather, a JS function call*" - what makes you think that? – Bergi Aug 25 '17 at 00:32
  • I may be wrong, and I'm open to learning more about this, but the error came up on the line with that function call. The object Prototype I pass to the `slice` function contains the function `slice` so I'm not sure it could be because of the object I'm giving it. – User 5842 Aug 25 '17 at 00:34
  • No, `slice` does not timeout. In fact no synchronous function really ever timeouts. But your code contains all kinds of asynchronous stuff. Like `browser.wait` - to which you are even explicitly [passing a **timeout parameter**](http://www.protractortest.org/#/api?view=webdriver.WebDriver.prototype.wait)! – Bergi Aug 25 '17 at 00:34
  • "*The object Prototype I pass to the slice function…*" - Wat? You're not passing any prototype or object, you're passing a number. – Bergi Aug 25 '17 at 00:36
  • Btw, I would recommend [to use `.then(done, fail);` over `.catch(fail).then(done);`](https://stackoverflow.com/q/24662289/1048572) – Bergi Aug 25 '17 at 00:38
  • I meant that I'm passing in an array to the `this` value of the function. And okay @Bergi, I'll give that a shot, thanks for the info – User 5842 Aug 25 '17 at 00:48
  • @Bergi, regarding your previous comment, is the only place I'm exhibiting the anti-pattern at the end of the function? Or should I correct in more places? – User 5842 Aug 25 '17 at 00:58
  • @User5842 As the linked answer explains, it's not necessarily an anti-pattern - it's just a pattern, and you have to decide which syntax you need. For callbacks, `.then(done, fail)` is more appropriate (although you really shouldn't be using callbacks at all of course, better return the promise). – Bergi Aug 25 '17 at 01:50

0 Answers0