0

I have a Lightning Web Component that represents a "wizard" and assists in animating the transitions between views. It has a <slot> tag which allows users to define whatever views they want by creating a series of <div> tags.

myWizard.html-------------------------------------------

<template>
    <slot class="wizard-view-container"></slot>
</template>


Sample usage of myWizard component ----------------------------

<c-my-wizard>
    <div data-view-id="first-view"> ... </div>
    <div data-view-id="second-view"> ... </div>
    <div data-view-id="first-view"> ... </div>
</c-my-wizard>

I want to write some Jest Test scripts for this component, but I can't seem to programmatically add children to the body slot

import { createElement } from 'lwc';
import MyWizard from 'c/MyWizard';

describe('myWizard', () => {
    afterEach(() => {
        while (document.body.firstChild) {
            document.body.removeChild(document.body.firstChild);
        }
    });

    it('sets the first view to have class curr-view by default and all other views to have next-view', () => {
        let testElement = createElement('c-my-wizard', { is: MyWizard });

        let divElement1 = document.createElement('div');
        let divElement2 = document.createElement('div');
        let divElement3 = document.createElement('div');

        testElement.appendChild(divElement1);
        testElement.appendChild(divElement2);
        testElement.appendChild(divElement3);

        document.body.appendChild(testElement);

        expect(divElement1.classList.contains('curr-view')).toBeTruthy();
        expect(divElement2.classList.contains('next-view')).toBeTruthy();
        expect(divElement3.classList.contains('next-view')).toBeTruthy();
    });
});

When I run this test, I get errors let the following

[LWC error]: appendChild is disallowed in Element unless lwc:dom="manual" directive is used in the template.

I tried putting lwc:dom="manual" to the <slot> tag, but that is not allowed. I can't seem to figure out where to go from here. Is testing for this type of component possible?

  • We are building the same component LOL, did you find a solution?, I think Sebastian provided a wrong answer, since the use case is to passed components declaratively and not programmatically. – AngelSalazar May 28 at 17:48
  • FYI, I ended up not creating any automated testing scripts for the Wizard LWC. But your answer below has me intrigued and i'll have to give it a go. Thanks for the suggestion. – Vincent Ip May 29 at 18:09
1

I don't know much about Jest but I can spot a potential problem.

You're creating a test element (let testElement = createElement('c-my-wizard', { is: MyWizard });) and later attempting to modify its DOM.

LWC only lets you manipulate an element's DOM if you decorate it with a lwc:dom="manual" in it's definition. The error gives you that hint.

The component you created gets rendered as <c-my-wizard></c-my-wizard> but it should get rendered as <c-my-wizard lwc:dom="manual"></c-my-wizard>

My lack of knowledge in Jest will preclude me from fixing your syntax, but if you can add that directive you'll be good to go

  • Yeah, I realized that and I tried to put the lwc:dom="manual" directive in the html portion of the component, but LWC doesn't allow that attribute on <slot> tags. I also tried to programmatically put the attribute in that testElement but using setAttribute(), but that didn't seem to work either. Thanks for trying to help. – Vincent Ip Mar 18 at 19:49
  • That wouldn't go on the slot tag, it'd go on the <c-my-wizard> declaration – Sebastian Kessel Mar 18 at 19:51
1

The solution I can think of to solve this problem is to create a demo component that wraps the wizard component and declaratively add the wizard steps components as children of wizard.

wizardTestDemo lwc

<template>
   <c-my-wizard>
     <c-my-wizard-step name="test1" label="Test 1">
     <c-my-wizard-step name="test2" label="Test 2">
     <c-my-wizard-step name="test3" label="Test 3">
   </c-my-wizard>
</template>
  • This is interesting. A component specifically for test only and then indirectly test the base component through Jest testing this component. I'll have to give this a try. – Vincent Ip May 29 at 18:06

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.