3

I am trying to JEST test these two buttons but I am currently not hitting these two functions in my LWC Coverage. I tried doing btn.click() on them and then resolving them in a promise to check the to see if the button was null or not, since the other button would show on the UI. But this would fail and it would return the object of each of the buttons. I know the promise syntax is wrong, atm didn't copy the code for it but just wanted to show that the JEST test has the Promise to resolve the clicks.

HTML:

<template if:false={isViewDesc}>
<lightning-button label='View Description' title="View Description"
                        onclick={handleClickedView} class="view-button">
                    </lightning-button>
</template>
<template if:true={isViewDesc}>
<lightning-button label='Hide Description' title="Hide Description"
                        onclick={handleClickedHide} class="hide-button">
                    </lightning-button>
</template>

JavaScript:

@api isViewDesc = false

handleClickedHide(){
     this.isViewDesc = false;
}

handleClickedView(){
     this.isViewDesc = true;
}

JEST Test:

testedComponent.isViewDesc = false;
document.appendChild(testedComponent);
const hideInjBtn = testedComponent.shadowRoot.querySelector('.hide-button');
const viewInjBtn = testedComponent.shadowRoot.querySelector('.view-button');

expect(hideInjBtn).toBeNull();
expect(viewInjBtn).not.toBeNull();

viewInjBtn.click();
Promise() => {(
expect(hideInjBtn).not.toBeNull();
expect(viewInjBtn).toBeNull();
hideInjBtn.click();
     Promise() => {(
          expect(hideInjBtn).toBeNull();
          expect(viewInjBtn).not.toBeNull();
     )}
)}

1 Answer 1

2

With each click, you want to allow for the re-render to take effect. While not exactly your scenario, this example in the lwc-recipes has the following function and comment

// Helper function to wait until the microtask queue is empty. 
// This is needed for promise timing when calling imperative Apex.
async function flushPromises() {
    return Promise.resolve();
}

Notice the comment mentioning waiting until the microtask queue is empty. You don't just want to create a Promise, you want it to be resolved - meaning that the re-render (which is also a microtask enqueued on the click) has finished since your interaction (in this case, a button click). My previous answer contains more information regarding this if you're interested.

In terms of your example, you can resolve the promise and chain .then() to be sure your clicks that enqueued a re-render have completed.

viewInjBtn.click();

return Promise.resolve()
    .then(async () => {
        expect(hideInjBtn).not.toBeNull();
        expect(viewInjBtn).toBeNull();
        hideInjBtn.click();
    })
    .then(() => {
        expect(hideInjBtn).toBeNull();
        expect(viewInjBtn).not.toBeNull();
    });
1
  • thank you, this was my issue. I was missing the .then on the clicks to be resolved. Feb 8 at 20:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.