3

I am getting an error in Jest test cases that says assignedElements is not a function. In the code, I am trying to query slots and then fetch the value as mentioned below:

let slot = this.element.shadowRoot?.querySelector('slot');
const testItems = slot.assignedElements({flatten:true});

This code is working fine on most of the browsers, but it is failing in Jest test cases. I thought of mocking and spying on this API, but no luck there either.

Lysol
  • 1,547
  • 13
  • 27
  • Is this in a spec or an e2e test? – Simon Hänisch Feb 09 '21 at 12:15
  • 1
    This is in spec test – Sahil Singh Feb 10 '21 at 13:56
  • 1
    Ok I'd raise a bug report in the Stencil Github repository then. Be aware that when running spec tests there is no browser context. Instead the DOM is emulated in the Node.js context (I think using the jsdom package), so it might not behave exactly like a browser would. In the meantime you could probably switch to an e2e test. – Simon Hänisch Feb 11 '21 at 14:30
  • I'm having this same issue in unit (spec) tests. I haven't tried in e2e tests. There was a recommendation to test components like this with e2e, but I'm reading on Stencil's Issues that people are having this same/similar problem with e2e testing. – Logan Richardson Jan 03 '22 at 19:55

2 Answers2

2

Some environments may not have slot.assignedElements yet, but it is super easy to polyfill on top of slot.assignedNodes:

if (!HTMLSlotElement.prototype.assignedElements) {
    HTMLSlotElement.prototype.assignedElements = function (...args) {
        return HTMLSlotElement.prototype.assignedNodes
            .apply(this, args)
            .filter((n) => n instanceof Element)
    }
}
trusktr
  • 44,284
  • 53
  • 191
  • 263
  • Where did you place this polyfill for it to trigger during test runs? Are you also using Stencil? Just curious and wondering for the sake of clarity. This seems like a good solution, I just really know where to place it where it would make the most sense. – Logan Richardson Jan 03 '22 at 19:53
  • 1
    @LoganRichardson depends on your setup. I'm not using Stencil. You have to run that code after jsdom is loaded, but before tests. – trusktr Jan 05 '22 at 20:16
  • 1
    @LoganRichardson The Stencil test guide points to Jest config guide. Look at globalSetup to start getting ideas: https://jestjs.io/docs/configuration#globalsetup-string. The bottom line is not regarding Jest, but jsdom. jsdom provides the fake DOM environment, and that's what needs to be patched. So I think in the Jest case, globalSetup is one way to do that (I assume jsdom is loaded by that point, and globalSetup happens before your tests). – trusktr Jan 05 '22 at 20:20
1

Change .assignedElements() to .assignedElements?.()

and .assignedNodes() to .assignedNodes?.()

leonheess
  • 16,068
  • 14
  • 77
  • 112