0

I am very new to lit-element and unit testing and am not sure if the question is even framed correctly. Please correct me if I am wrong anywhere.

So, I have 1 lit component created such that it fetches the json from the uri <abc infoJsonLink="../data/data.json"></abc>

data.json

[
 {"id":1, "name":"one", "img":"one.jpg"},
{"id":1, "name":"two", "img":"two.jpg"}, 
...]

Within abc's render() method, we loop through the json data and create a array with html markup corresponding to each item, itemsMarkupList

 *0* <div "item-data"><span>one</span><img src="one.jpg"/></div> 
 *1* <div "item-data"><span>two</span><img src="two.jpg"/></div>  
 *2* ...

Each one of these markups, has to be rendered in a bootstrap carousel. https://mdbootstrap.com/snippets/jquery/ascensus/135508

For this we have created another component, <carousel-helper>, which has the code to accept an array of markups and render it as a carousel using bootstrap libraries.

Below is the render() method of <abc> component

render(){... 
let ch = document.createElement("carousel-helper"); 
ch.itemsMarkupList = this.itemsMarkupList;
return html`... <div class="parent_wrapper"> ${ch} </div>`;
}

This whole renders perfectly when I npm run it.

But when I am writing the test cases for this, the shadowroot of child elements seems to be not rendering.

  it("test1", async () => {
   const el = /** @type {Abc} */ (await fixture(
    html`<abc infoJsonLink="/data/data.json"></abc>
    `));

  await el.loadJsonData();

  /*statement 1*/
  console.log(el.shadowRoot.querySelector("carousel-helper")); 

  /*statement 2*/
  console.log(el.shadowRoot.querySelector("carousel-helper").
    shadowRoot.querySelectorAll(".item-data"));

  }); 

statement-1 works and returns <carousel-helper></carousel-helper>
statement-2 return and empty array, NodeList {}

Can anyone tell me what I need to do to get a filled array from statement-2?

Agnes Simpson
  • 303
  • 1
  • 3
  • 13
  • And with a setTimeout delay around statement 2? – Danny '365CSI' Engelman Jun 15 '21 at 07:04
  • @Danny'365CSI'Engelman I tried setTimeout... it doesn't change anything... and if i try putting the expect() within settimeout() , it doesnt show any output... – Agnes Simpson Jun 15 '21 at 08:15
  • Without a working (or in your case failing) code-snippet, there is nothing to try. It basically comes down to verifying DOM exists, top-down. You can't get ``.item-data``; but can you access its shadowRoot – Danny '365CSI' Engelman Jun 15 '21 at 08:33
  • @Danny'365CSI'Engelman You are right! I can access the shadow root. But the DOM does not exist within child, so i dont get `item-data` . So what are the options I have to check `expect` only when the shadow DOM of child element is completely loaded. I also tried `await el.updateCompleted()`. But no difference. – Agnes Simpson Jun 15 '21 at 09:51
  • So your next debugging step is: What/when does ``item-data`` get created. Whack plenty of ``console.log`` statements in to fully grasp the what/when. Adding ``setTimeout`` is a trick to delay execution. SInce you didn't get a result with a setTimout wrapper function, something else is (not) happening (or you did setTimeout wrong)... but it is impossible to tell without running code: https://stackoverflow.com/help/minimal-reproducible-example – Danny '365CSI' Engelman Jun 15 '21 at 10:45

1 Answers1

0

Since the web component <abc> is dynamically loaded, you need to ensure it is defined before performing tests. Don't use timeouts or intervals, try the following before you query the element:

   await customElements.whenDefined('abc');

Here's some more info on customElements.whenDefined.

Matt
  • 3,793
  • 3
  • 24
  • 24