Changing protractor default timeout inside functio

2020-04-16 03:24发布

问题:

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.

回答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))


回答2:

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
}


标签: protractor