I am making use of ComponentHarness
from @angular/cdk/testing
and have a scenario in my protractor test suite where I need to wait for a number of elements to become visible.
I have a custom list component which displays a bunch of custom card components and contains a filter input for searching on these.
e.g.
My component harnesses are setup like so:
import { ComponentHarness, TestElement } from '@angular/cdk/testing';
import { browser } from 'protractor';
export class AcCardListHarness extends ComponentHarness {
static hostSelector = 'ac-cardlist';
getCardstackList = this.locatorFor('.ac-card-list .ac-list');
getCardstackListItems = this.locatorForAll(AcBaseCardHarness);
getCardstackSearchInput = this.locatorFor('.ac-search-input');
async performTextFilter(searchTerm: string) {
const input = await this.getCardstackSearchInput();
return input.sendKeys(searchTerm);
}
async getCardStackListItem(index: number) {
const items = await this.getCardstackListItems();
return items[index];
}
public waitForPresenceOfNumberOfElements(elements: Promise<TestElement[]|ComponentHarness[]>, numberOfElements: number) {
return browser.wait(async() => {
const items = await elements;
return items.length === numberOfElements;
}, 60000, `Could not find exactly ${numberOfElements} elements on the page.`);
}
}
export class AcBaseCardHarness extends ComponentHarness {
static hostSelector = 'ac-basecard';
}
I am able to use these in my protractor test suite perfectly fine, apart from the waitForPresenceOfNumberOfElements
method, which is meant to resolve when a specified number of elements for an array of TestElement
or ComponentHarness
instances are found.
The idea is that I am wanting to perform some filtering during my test and wait for the filter operation to complete in my component by checking the number of items that are displayed after calling the performTextFilter
function in the AcCardListHarness
.
it('should be able to find the item in the list view', async() => {
harness = await harnessLoader.getHarness(AlCardstackHarness);
await harness.performTextFilter('<serach_term_here>');
await harness.waitForPresenceOfNumberOfElements(harness.getCardstackListItems(), 1);
const items = await harness.getCardstackListItems();
expect(items.length).toEqual(1);
});
During the test run, I can see the text filter being interacted with and can see the list component (ac-cardlist
) correctly filtering down to the number of items I expect to see (1), but the call to await harness.waitForPresenceOfNumberOfElements(harness.getCardstackListItems(), 1);
in my test spec never resolves, it just times out with my default error message in the browser.wait()
.
Before using ComponentHarness
, I was using regular Protractor page objects and was using this helper method with ElementArrayFinder
instances and works fine for me in that setup.
public static waitForPresenceOfNumberOfElements(elementArrayFinder: ElementArrayFinder, numberOfElements: number) {
return browser.wait(() => {
return elementArrayFinder.count().then((actualCount) => {
return actualCount === numberOfElements;
});
}, 60000, `Could not find exactly ${numberOfElements} elements on the page`);
}
What am I missing to get this same behaviour working with the ComponentHarness
approach?