2

I have a function to be called in some of my protractor tests which does some tasks that take more than the protractor default timeout (which seems to be 60 seconds)

I've read that you should be able to change the default timeout with "jasmine.DEFAULT_TIMEOUT_INTERVAL", however with the following code, the timeout still happens before the 4 minutes I have set up. Since I want to reuse this test part in the future, I cannot simply add it as a parameter to the test function.

Here is the sample code, can anyone tell me what I'm doing wrong?

describe('reset data', function() {
  it('should reset data', function() {
    jasmine.DEFAULT_TIMEOUT_INTERVAL = 240000;

    browser.ignoreSynchronization = true;

    // ... test code here
  });
});

I get the following error, after the test fails after roughly 60 seconds:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

private_meta
  • 561
  • 4
  • 19
  • Did you read the timeout docs? https://github.com/angular/protractor/blob/master/docs/timeouts.md The syntax in your spec for the timeout isnt correct (and I would set it in the config anyway, not the spec) – Gunderson Apr 27 '17 at 12:56
  • Several posts I found via google use them directly in the spec. As I added in the answer, I don't want the entire test to have a timeout of e.g. 4 minutes, just some commands that take a long time to finish. I don't want 100 commands to have a 4 minute timeout when only 2 of them need it. – private_meta Apr 29 '17 at 12:05
  • Sure, but right now it seems your tests timeout at 60 seconds. So that `jasmine.DEFAULT_TIMEOUT_INTERVAL = 240000;` doesnt seem to be doing anything. – Gunderson Apr 29 '17 at 18:39
  • Yes, that is the purpose of the question. I want it at 240000 while having the ability to change it back to 60000 in the same test, but it's not working, and I wanted to know if there is a way. – private_meta Apr 29 '17 at 21:26
  • The link I posted has information about that. "To change for all specs, add `jasmineNodeOpts: {defaultTimeoutInterval: timeout_in_millis}` to your Protractor configuration file. To change for one individual spec, pass a third parameter to it: `it(description, testFn, timeout_in_millis)`" – Gunderson Apr 29 '17 at 22:39
  • The timeout is supposed to change WITHIN the spec, not for a separate spec, maybe I wasn't clear about that. – private_meta May 01 '17 at 01:47

2 Answers2

1

I have created two functions to override, then restore the default protractor timeouts: (Only tested in Chrome)

import { browser } from 'protractor';

export function DefaultTimeoutOverride(milliseconds: number) {
    browser.driver.manage().timeouts().setScriptTimeout(milliseconds);
}

export function DefaultTimeoutRestore() {
    browser.driver.manage().timeouts().setScriptTimeout(browser.allScriptsTimeout);
}

EDIT

I have now created a helper function ('itTO') that wraps Jasmine's 'it' statement and applies the timeout automatically :)

import { browser } from 'protractor';

export function itTO(expectation: string, assertion: (done: DoneFn) => void, timeout: number): void {
    it(expectation, AssertionWithTimeout(assertion, timeout), timeout);
}

function AssertionWithTimeout<T extends Function>(fn: T, timeout: number): T {
    return <any>function(...args) {
        DefaultTimeoutOverride(timeout);
        const response = fn(...args);
        DefaultTimeoutRestore();
        return response;
    };
}

function DefaultTimeoutOverride(milliseconds: number) {
    browser.driver.manage().timeouts().setScriptTimeout(milliseconds);
}

function DefaultTimeoutRestore() {
    browser.driver.manage().timeouts().setScriptTimeout(browser.allScriptsTimeout);
}

use like this:

itTO('should run longer than protractors default', async () => {
        await delay(14000);
}, 15000);

const delay = ms => new Promise(res => setTimeout(res, ms))
samneric
  • 3,038
  • 2
  • 28
  • 31
0

Try his one instead:

By using a recursive function to identify if it is present.

function checkIfPresent(maxSec, elm, blnPresent) {
    if (maxSec > 0) {
        browser.sleep(1000).then(function() {
            elm.isPresent().then(function(bln) {
                if (bln != blnPresent) {
                    checkIfPresent(maxSec - 1, elm, blnPresent)
                }
            });
        });
    }
}

If you pass checkIfPresent(300000, elm, true)
It will check if the object is present every second, within 5mins.
Hope it helps. :)

Previous Comment:
I agree with the comment.
It should be declared on config file (conf.js)

jasmineNodeOpts: {
    onComplete: null,
    isVerbose: true,
    showColors: true,
    includeStackTrace: true,
    defaultTimeoutInterval: 1000000
}
Paul Co
  • 447
  • 2
  • 9
  • That won't help me. This test is supposed to have two separate timeouts. The first one is for something I know takes long, up to several minutes. For example: first 3 calls should have timeout 4 minutes, remaining calls should only take up to 30 seconds. – private_meta Apr 28 '17 at 22:27
  • Is there a certain element that you are waiting to appear or disappear? – Paul Co Apr 29 '17 at 22:33
  • Checking for said element is not a problem, the problem is that I have the test where the first element takes 3-4 minutes to appear, afterwards it should be instant (under 30s) for the rest, and I don't want to set an entire spec to 4-5 minutes because of ONE call. – private_meta May 01 '17 at 01:49