Summer Sale! All accounts are 50% off this week.

PhilKz's avatar

Make dusk wait for all CSS animations to end

The Problem

I'm using Dusk to test an SPA (I know it's not the best tool, but I need to get stuff done with what I already know for now). I frequently have the issue that tests fail because Dusk isn't waiting for all CSS animations to end. I am dealing with this by adding pause functions throughout tests, and setting these longer than my longest CSS animations take to account for Webdriver randomly getting stuck sometimes. This is bad for two reasons: 1. I am making my tests run longer than they need because just doing overkill on pauses is faster than trying to optimize how long they take, and 2. I still spend a lot of time debugging tests by hunting down places I didn't realize I need another pause.

What I'm Looking For

Is there a way to make Dusk wait until all CSS animations on a page are finished before continuing. Ideally something like:

$browser->visit('/somepage')
				->waitForCssAnimations(10) //Maximum number of seconds the function is allowed to wait.
				->assertSee("Some text");

(Even better would be some global setting that made Dusk do this on every action, but I know that doesn't exist.)

If not, does anyone have any clever methods for achieving something like this. I had the idea of doing something like adding an element to each page in development mode that gets animated with the longest animation in the app, and then using $browser->waitFor('.animationsOverIndicator').

0 likes
4 replies
bwrigley's avatar

Sorry I asked way too soon. Just in case anyone has same problem.

The cleanest solution I found was to use Vue's transition javascript hooks:

https://vuejs.org/guide/built-ins/transition#javascript-hooks

So I have a Vue 'slider' component :

<script setup>

import { ref } from 'vue';

const isActivated = ref(false);

//only set when the transformation is actually complete - mostly for dusk
const open = ref(false);

</script>

<template>


<div class="flex justify-between items-center">

    <div class="relative w-full">
        <Transition name="slide-left" @after-enter="open = !open">
            <div v-show="!isActivated" class="w-full top-0 left-0">
                <slot name="first-content" />
            </div>
        </Transition>

        <Transition  name="slide-right" @after-enter="open = !open">
            <div v-show="isActivated" class="w-full top-0 left-0">
                <slot name="second-content" />
            </div>
        </Transition>
    </div>
    <div @click.prevent.stop="isActivated = !isActivated" >
        <slot name="trigger" />
    </div>

</div>

</template>

<style>
    //
</style>

Then I can test:

          ->waitUntilVue('open', true, '@slider')
1 like

Please or to participate in this conversation.