sbstnssndn
sbstnssndn

Reputation: 55

How to wait after browser.keys() in WebdriverIO async mode?

I'm struggling to do something with async WebdriverIO v7 that in sync mode is quite easy.

Context: I'm using a React masked input component that has a bug (I can't fix that nor change the component), if I type too quickly the keys aren't registered and the cursor goes to the end, so I need to type at a relatively slow speed. When I use await input.setValue('test') the typing is too quick and it only types the first letter and can't type the rest, so I need to type every character separately and wait a little between keystrokes.

Basically I want to do this in async mode:

[...textValue].forEach(char => {
  browser.keys(char);
  browser.pause(100);
});

I tried using waitUntil() but because this is a masked input, if I type 123456, the value in the input will be 123.456.___-_ so I can't directly compare the two strings and wait until they are equal. Also, this seems like a lot of work for something that was so simple, so I'm wondering if there is a better way.

Thanks!

EDIT: I tried comparing the saved input text so far on each browser.key(char) with the actual input.getValue() in the waitUntil() condition an it still doesn't work

Upvotes: 0

Views: 876

Answers (1)

sbstnssndn
sbstnssndn

Reputation: 55

Alright I solved the problem. The issue was that the forEach loop can't wait for async operations, so I use a for..of loop now (reference).

async typeSlowly (input, content) {
    let inputSoFar = '';

    for (const char of content) {
        inputSoFar = inputSoFar.concat(char);

        await browser.keys(char);
        await browser.waitUntil(
            async () => (await input.getValue()) === inputSoFar,
            {
                timeout: 500,
                timeoutMsg: 'expected text to be different after 500ms'
            }
        );
    }
}

I omitted the masking logic part because that's just a detail, the important bit here is the async waiting inside the loop.

Upvotes: 2

Related Questions