[webkit-dev] Waiting for an event in layout test...

Jer Noble jer.noble at apple.com
Fri May 31 13:43:43 PDT 2019


> On May 30, 2019, at 11:01 PM, Ryosuke Niwa <rniwa at webkit.org> wrote:
> 
> I’m gonna give you a game changing function:
> 
> function listenForEventOnce(target, name, timeout) {
>     return new Promise((resolve, reject) => {
>         const timer = timeout ? setTimeout(reject, timeout) : null;
>         target.addEventListener(name, () => {
>             if (timer)
>                 clearTimeout(timer);
>             resolve();
>         }, {once: true});
>     });
> }
> 
> You can then write a test like this:
> await listenForEventOnce(document.body, 'load');
> // do stuff after load event.
> 
> await listenForEventOnce(document.querySelector('input'), 'focus');
> await listenForEventOnce(visualViewport, 'scroll', 5000);
> // After the input element is focused, then the visual viewport scrolled or 5 seconds has passed.

Ryosuke++.

Just FYI, if you’re writing LayoutTests, we’ve got something very similar in LayoutTests/media/video-test.js:

function waitFor(element, type) {
    return new Promise(resolve => {
        element.addEventListener(type, event => {
            consoleWrite(`EVENT(${event.type})`);
            resolve(event);
        }, { once: true });
    });
}

And:

function sleepFor(duration) {
    return new Promise(resolve => {
        setTimeout(resolve, duration);
    });
}

And also:

function shouldReject(promise) {
    return new Promise((resolve, reject) => {
        promise.then(result => {
            logResult(Failed, 'Promise resolved incorrectly');
            reject(result);
        }).catch((error) => {
            logResult(Success, 'Promise rejected correctly');
            resolve(error);
        });
    });
}

So you could also do:

await Promise.race(waitFor(document.body, ‘load’), shouldReject(sleepFor(5000)));

Although we’d probably want a new function, “rejectIn(duration)”, and then it’d be:

await shouldResolve(Promise.race(waitFor(document.body, ‘load’), rejectIn(5000)));

But all that said, I agree that wrapping events in Promises makes it very easy to write readable, single `async` function test cases. A+++, would write test again.

-Jer


> - R. Niwa
> 
> _______________________________________________
> webkit-dev mailing list
> webkit-dev at lists.webkit.org
> https://lists.webkit.org/mailman/listinfo/webkit-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-dev/attachments/20190531/d22e8144/attachment.html>


More information about the webkit-dev mailing list