1

I have a function for an animation that uses a callback. The function uses promises:

export function createExpandCollapseCallback(
    containerSelector,
    toExpandCollapseSelector,
    animationDuration
) {
    return function () {
        if ( animating ) {
            return;
        }
        animating = true;
        if ( console.time ) {
            console.time( 'animation' );
        }
        const container = document.querySelector( containerSelector );
        const toExpandCollapse = container.querySelector(
            toExpandCollapseSelector
        );
        toExpandCollapse.style.display = 'block';
        let animation;
        if ( expanded ) {
            const moveUp = ( moved ) => -moved;
            animation = animateHeight(
                toExpandCollapse,
                animationDuration,
                moveUp
            );
        } else {
            const moveDown = ( moved, height ) => moved - height;
            animation = animateHeight(
                toExpandCollapse,
                animationDuration,
                moveDown
            );
        }
        animation.then( () => {
            animating = false;
            if ( console.timeEnd ) {
                console.timeEnd( 'animation' );
            }
            updateExpanded( ! expanded );
        } );
    };
}

function animateHeight( children, animationDuration, changeTop ) {
    const height = children.clientHeight;
    const frameDuration = ( 1 / 60 ) * 1000; // 60 fps
    return new Promise( ( resolve ) => {
        const slideSomeMore = function ( moved, computationTime = 0 ) {
            const start = window.performance.now();
            const next = start + frameDuration;
            while ( moved < height ) {
                if ( window.performance.now() < next ) {
                    continue;
                }
                const incrementPerMs = height / animationDuration;
                const uncomputedIncrement = incrementPerMs * computationTime;
                moved = moved + ( incrementPerMs + uncomputedIncrement ) * 1.2;
                children.style.top = `${ changeTop( moved, height ) }px`;
                const end = window.performance.now();
                setTimeout( () => slideSomeMore( moved, end - start ), 0 );
                return;
            }
            resolve();
        };
        slideSomeMore( 0 );
    } );
} 

I have set up Qunit in an HTML file. First I render UI in a playground div inside the HTML file and then call the animation callback. My goal is to simulate the animation and verify that the simulation duration is between the animation-duration(3rd parameter passed to the function) + the error margin. I first render a UI AND then perform the animation. Here is the Html file:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width">
        <title>Rusty Inc. Org Chart WordPress Plugin JavaScript Tests</title>
        <link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.7.1.css">
    </head>
    <body>
        <div id="qunit"></div>
        <div id="qunit-fixture"></div>
        <div  >
            <h1>Here is the playground</h1>
            <div id="playground"></div>

        </div>
        <script src="https://code.jquery.com/qunit/qunit-2.7.1.js"></script>
        <script type="module">
            import { subscribe, updateTree, updateSecretURL, getTree , createExpandCollapseCallback } from '../framework.js';
            import { ui } from '../ui.js';
            const q = QUnit;
            q.module( 'Framework' );
            q.test('animation duraion is as much provided', assert=>{
                const tree = {"id":1,"name":"Rusty Corp.","emoji":"","parent_id":null,"children":[{"id":2,"name":"Food","emoji":"","parent_id":1,"children":[{"id":"cltp","name":"new","emoji”:””,”parent_id":2,"children":[]}]},{"id":3,"name":"Canine Therapy","emoji":"","parent_id":1,"children":[{"id":4,"name":"Massages","emoji":"","parent_id":3,"children":[]},{"id":5,"name":"Games","emoji":"","parent_id":3,"children":[]},{"id":"8xza","name":"lol","emoji":"","parent_id":3,"children":[]},{"id":"lctu","name":"new","emoji":"","parent_id":3,"children":[]}]}]};
                updateTree( tree ); 
                const secretURL= "random.com"
                const insertionElement = document.getElementById("playground")
                ui(tree,secretURL,true,insertionElement)
                const pluginUI =  document.querySelector(`#ui > button`)
                console.log('lel', pluginUI );
                const durationTime = 1500;
                const errorMargin = 200; 
                const dur2 = 3000 
                const expandCollapse = createExpandCollapseCallback( '#ui > .team','.children', durationTime );
                const done = assert.async();
                const start = window.performance.now();
                expandCollapse()
                const end = window.performance.now();
                assert.ok(  end - start <  durationTime + errorMargin, 'someshit untrue' );
                done();

            } ) 
        </script>
    </body>
</html>

When I run the test I get an alternating message between the testing passing and failing due to assertion being called after the test has finished. This happens every time I refresh, If the test passes and I hit refresh it fails and passes if I refresh again. In this manner, It alternates between passing and failing every time I refresh.

Here are the screenshots for both states:

passing test screenshot

Failing test screensht

krickht
  • 29
  • 5

0 Answers0