0

I'm trying to write a Jest test to cover a scenario: when the "Reset Location" link is clicked, a modal appears. However, I'm unable to access the cancel button within the modal to simulate a click on it. It seems to be returning null, causing the test to fail. Any suggestions on how to resolve this issue would be appreciated.

    <template>
    <div class="content-container">
        <div class="slds-card__body">
            <div class="test-details-header">
                <span>Location</span>
                <!-- Add Reset Location link -->
                <a href="#" class="details-link" onclick={openModal}>Reset Location</a>
            </div>
            <div class="test-details">
                <span>123 County Rd 1205 Bullard, Texas</span>
            </div>
        </div>
    </div>
     <!-- Modal -->
    <template if:true={isModalOpen}>
            <section role="dialog" tabindex="-1" aria-modal="true" id= "modalDialog" aria-labelledby="modal-heading-01" class="slds-modal slds-fade-in-open">
                <div class="slds-modal__container">
                    <header class="slds-modal__header slds-modal__header ">
                        <button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" title="Close" onclick={closeModal}>
                            <lightning-icon icon-name="utility:close"
                                alternative-text="close"
                                variant="inverse"
                                size="small" ></lightning-icon>
                            <span class="slds-assistive-text">Close</span>
                        </button>
                        <h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate modal-heading">Are you sure you want to reset your location?</h2>
                    </header>
                    <div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
                        <p> If you proceed to reset your location, you will lose your current progress.</p>
                        <p> Do you want to continue?</p>
                        <p>&nbsp;</p> <p>&nbsp;</p><p>&nbsp;</p> <p>&nbsp;</p><p>&nbsp;</p> 
                    </div>
                    <div class="slds-modal__footer slds-modal__footer ">
                        <button class="slds-button slds-button_neutral cancel-btn" id ="cancelButtonId" title="Cancel" onclick={closeModal}>Cancel</button>
                        <button class="slds-button slds-button_brand reset-location-btn">Reset Location</button>
                    </div>
                </div>
            </section>
            <div class="slds-backdrop slds-backdrop_open" role="presentation"></div>
    </template>
</template>

js file below

import { LightningElement,track } from 'lwc';

export default class testLocationData extends LightningElement {
    @track isModalOpen = false;
    
    openModal(event) {
        // to open modal set isModalOpen tarck value as true
        event.preventDefault();
        this.isModalOpen = true;
    }
    closeModal() {
        // to close modal set isModalOpen tarck value as false
        this.isModalOpen = false;
    }
}

    import { createElement } from 'lwc';
import TestLocationData from 'c/testLocationData'; // Corrected import statement

//jest.setTimeout(10000);

describe('c-test-location-data', () => {
    afterEach(() => {
        while (document.body.firstChild) {
            document.body.removeChild(document.body.firstChild);
        }
    });

    test('renders modal when openModal is called', () => {
        // Create the LWC component instance
        const element = createElement('c-weat-location-data', {
            is: TestLocationData
        });
        document.body.appendChild(element);
    
        // Wait for the component to be rendered
        return Promise.resolve().then(() => {
            // Find the "Reset Location" link
            const resetLocationLink = element.shadowRoot.querySelector('.details-link');
    
            // Simulate a click event on the link to open the modal
            resetLocationLink.click();

            jest.runAllTimers();
            const modal = element.shadowRoot.querySelectorAll('.slds-modal__container');
            expect(modal).not.toBeNull();
        });
    });
    
    test('closes modal when cancel button is clicked', () => {
        // Create the LWC component instance
        const element = createElement('c-test-location-data', {
            is: TestLocationData
        });
        document.body.appendChild(element);
    
        return Promise.resolve().then(() => {
            const resetLocationLink = element.shadowRoot.querySelector('.details-link');
            resetLocationLink.click();

            jest.runAllTimers();

            const modal = element.shadowRoot.querySelectorAll('.slds-modal__container');
            expect(modal).not.toBeNull();

            const modalFooter = element.shadowRoot.querySelector('.slds-modal__footer');
            console.log('modalFooter', modalFooter);
            const buttons = modalFooter.querySelectorAll('button');
            const cancelButton = Array.from(buttons).find(button => 
            button.classList.contains('cancel-btn'));
            console.log('cancelButton', cancelButton);


            // Check if the modal is closed
            const closeModal = element.shadowRoot.querySelectorAll('.slds-modal__container');
            expect(closeModal).toBeNull();
        });
    });

    test('displays modal content correctly', () => {
        const element = createElement('c-test-location-data', {
            is: TestLocationData// Use the imported component name
        });
        document.body.appendChild(element);

        return Promise.resolve().then(() => {
            const resetLocationLink = element.shadowRoot.querySelector('.details-link');
            resetLocationLink.click();

            jest.runAllTimers();

            const modal = element.shadowRoot.querySelectorAll('.slds-modal__container');
            const modalContent = modal.querySelector(".slds-modal__content")
            expect(modalContent.textContent).toContain('Are you sure you want to reset your location?');
            expect(modalContent.textContent).toContain('If you proceed to reset your location, you will lose your current progress.');
            expect(modalContent.textContent).toContain('Do you want to continue?');
        });
    });
});

1 Answer 1

0

Your assertions are not waiting for DOM to re-render. After you click the anchor tag, the changes to the elements will a take a while to reflect in the jsdom.

const flushPromises = async () => Promise.resolve();

return Promise.resolve().then( async () => {
        // Find the "Reset Location" link
        const resetLocationLink = element.shadowRoot.querySelector('.details-link');

        // Simulate a click event on the link to open the modal
        resetLocationLink.click();

        jest.runAllTimers();

        await flushPromises(); //awaits re-render required because of changes to the DOM elements

        const modal = element.shadowRoot.querySelectorAll('.slds-modal__container');
        expect(modal).not.toBeNull();
    });
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .