The function setFindTimeout does not work for me

99 Views Asked by At

I write functional tests for the web application on Intern. I have a file in which I describe all the actions on the test, and also there is a test where these actions are called

for example:

there is an Action.ts file

in it functions which in the test are called sequentially

//1 
//open the registration window
openRegistration(): Command<void> {
    return Action.openRegistration(this.parent);
}

static openRegistration(command: Command<any>): Command<void> {
    return command
        // click on the authorization menu
        .setPageLoadTimeout (10000)
        .get(intern.args.url)
        .end()
}

//2
inputTextByCssSelector(selector: string, value: string): Command <void> {
    return Input.inputTextByCssSelector(this.parent, selector, value);
}

static inputTextByCssSelector(
    command: Command<any>,
    selector: string, 
    value: string
): Command<void> {
    return command
        .setFindTimeout(10000)
        .findByCssSelector(selector)
        .click()
        .type(value)
        .end()
        .end()
}

like this

.then(() => action.openRegistration())
.then(() => input.inputTextByCssSelector(
    "input [name = userName]", 
    intern.args.username
))
.then(() => input.inputTextByCssSelector(
    "input [name = password]", 
    intern.args.password
))

But when I run the test, it drops.

If I set an explicit delay at the end of openRegistration for example like this

openRegistration(): Command<void> {
    return Action.openRegistration(this.parent);
}

static openRegistration(command: Command<any>): Command<void> {
    return command
        .setPageLoadTimeout(10000)
        .get(intern.args.url)
        .sleep(7000)
        .end()
}

then everything works

Why does not work setFindTimeout(10000) in inputTextByCssSelector, but with sleep(7000) in openRegistration works

2

There are 2 best solutions below

0
On

What do you mean by "it drops"? Is the test throwing a timeout error?

One potential issue is component visibility. Is there some delay between when the page has loaded and the elements you're trying to interact with become visible (like, a JS fade in animation)? The findBy commands return the first found element, but that element may not be visible. If it's not visible, Intern can't interact with it, and a command like type will fail. To wait until the element is visible, use findDisplayedByCssSelector.

Note that spacing is important in CSS selectors. The selector "input [name = userName]" is actually looking for an element with attribute name=userName contained within an input element. Assuming the actual intention is to select an input with a particular name attribute, it should be formatted as 'input[name="userName"]'.

Also note that end() commands are only needed after find commands, and aren't typically needed at the end of command chains in helper commands (things started from this.parent). So, for example, there's no need for an end after the get in openRegistration, and at most one end would be needed in inputTextByCssSelector (for the findByCssSelector command).

0
On

I tried something similar to this (just not using TypeScript) when I first started learning how to use intern and hit some similar issues to what you're having.

The issue for me was that the Promise chain wasn't being maintained correctly as the test executed. You should try making a subtle change to your code as follows in order to increase the consistency of the Promise chain.

So just for example, your test script is like this before we start:

return this.remote
    .then(() => action.openRegistration())
    .then(() => input.inputTextByCssSelector("input[name = userName]", intern.args.username))
    .then(() => input.inputTextByCssSelector("input[name = password]", intern.args.password))

The first thing you need to do is remove those arrow functions. I had several issues when using arrow functions, namely the this.remote leadfoot/Session was not passed around consistently between methods when I did this.

So your first .then() statement invokes a method called openRegistration(), right? Edit your method to, instead, return a function which executes the steps you are looking for:

static openRegistration(): Command<void> {
    return function () {
        return this.parent
            .setPageLoadTimeout (10000)
            .get(intern.args.url)
            .end()
   };
}

So now your test script will look something like this (and assuming you repeat this pattern for all methods you are calling):

return this.remote
    .then(action.openRegistration())
    .then(input.inputTextByCssSelector("input[name = userName]", intern.args.username))
    .then(input.inputTextByCssSelector("input[name = password]", intern.args.password))

This should resolve your problem.