2
votes

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.

2
Did you read the timeout docs? 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
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
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
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
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

2 Answers

1
votes

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))
0
votes

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
}