angularjasminekarma-jasmine

How to find proper harness by id?


In my component tests, I need to find a proper Input element.

I can find all of them by doing:

let loader: HarnessLoader = TestbedHarnessEnvironment.loader(fixture);
const inputs = await loader.getAllHarnesses(MatInputHarness);
expect(inputs).toBeTruthy();

But how can I find a proper input in the array?

Deep inside, each 'input' has the id because I see it:

console.log(`id: ${await inputs[0].getId()}`);

outputs the proper id.

Do I have to go in a loop through the whole list of inputs to check the id of every element? And call 'await' for each of those?

I'm afraid this might be too computational-heavy. Also, this just smells wrong.

How do I get a required input element by id?


Solution

  • Apparently (I'm really sarcastic here), the documentation is very useful.

    By reading this (https://material.angular.io/guide/using-component-harnesses) I got the idea. After some learning and digging, here is some knowledge and later the solution.

    1. For all Harnesses (inherited from ComponentHarness) we can use the 'with' static method that creates HarnessPredicate that allows filtering.
    2. All Harnesses have filters with 'selector' and 'ancestor' CSS selector that supports standard CSS selection and search by id can be done.
    3. To see more implemented filters I checked parameters that are accepted by 'with' methods for appropriate harness class. For instance, for MatInputHarness class, the 'with' methods accept that in addition to default 'selector' and 'ancestor' also supports 'value' and 'placeholder'.

    So the code looks as follow:

    await loader.getHarness(MatInputHarness.with({ selector: '#elementId' }));
    

    Obviously, the selector can use the CSS standard. Search by class would be

    {selector: '.className'}
    

    P.S. Useful hint is that it is possible to optimize search and narrow down the scope by

    const smallerScopeLoader = await loader.getChildLoader('#childComponent');