I am using the Angular Material side-nav. Inside the mat-sidenav-content I load up various components, some use infinite scrolling, some don't. But to make the scrolling work properly I need to point the infinite scroller at the parent mat-sidenav-content container like so:
<div infiniteScroll infiniteScrollContainer=".mat-sidenav-content" fromRoot="true" scrollWindow="false" .....
The problem comes when I want to write jasmine/karma tests for my component with infinite scrolling. I use the TestBed to load up my component - but since the side-nav is a parent, it's not present in my component under test TestBed, and the infiniteScroller errors when trying to resolve the container.
I put in place a workaround that seems to work by making it fall back to the window if it can't find the container selector, not sure if there's a better way:

hi @dylan-smith thanks - i'll look into it
hi @dylan-smith
i'm not sure a fall back to window is appropriate in this matter - as it can lead to undesired results. i'm looking at throwing an error instead or at least log to console (error log).
@dylan-smith version 0.7.1 addresses this issue by throwing an error now.
That approach still not solving the test implementation problem.
If setting it to window may cause undesired results, the container should point to defaultElement as it is the one rendered by Karma tests.
Basicaly it should look like this:
function resolveContainerElement(selector, scrollWindow, defaultElement, fromRoot) {
const /** @type {?} */ hasWindow = window && !!window.document && window.document.documentElement;
let /** @type {?} */ container = hasWindow && scrollWindow ? window : defaultElement;
if (selector) {
const /** @type {?} */ containerIsString = selector && hasWindow && typeof selector === 'string';
container = containerIsString
? findElement(selector, defaultElement.nativeElement, fromRoot)
: selector;
if (!container) {
container = defaultElement;
}
}
return container;
}
however, @bzeymer , there should be an error or a warning so the developer knows that something is wrong.
by setting a different element to the container, there could be unexpected behavior.
@dylan-smith does the latest update address the issue you raised?
@dylan-smith does the latest update address the issue you raised?
@orizens i'm getting the same error when trying to test a component with a infinityscroll directive on it.
How to provide a container element when running test with karma/jasmine?
you should provide the actual element or a reference/selector which is visible in the dom
I'am using the directive on a shared component which is reused often.
While testing, the selector is not visible as it belongs to the base layout in app.component.html.
Therefore each component test with a component using this shared component fails.
How can i provide the desired reference/selector for the test?
Thanks in advance for your help
I have the same issue. Did you find a solution @MichaelPruefer? The target of [infiniteScrollContainer] is in AppComponent which doesn't exist in tests when using TestBed.createComponent(...)
We ended up using a TestHostComponent like
@Component({
selector: 'app-host-component',
template: '<div class="content-wrapper" [infiniteScrollContainer]><grid></grid></div>'
})
class TestHostComponent {
@ViewChild(GridComponent)
public component: GridComponent;
}
let component: GridComponent;
let testHostFixture: ComponentFixture<TestHostComponent>;
let testHostComponent: TestHostComponent;
const testHelper = new TestbedHelper();
testHelper.setUpTestBed({
declarations: [
TestHostComponent,
GridComponent
]
});
beforeEach(() => {
testHostFixture = TestBed.createComponent(TestHostComponent);
testHostComponent = testHostFixture.componentInstance;
component = testHostComponent.component;
testHostFixture.detectChanges();
});
...
thank you very much.
The solution I found was to use createHost() from @netbasal/spectator to wrap it in a parent scrollable element:
import { TestBed } from '@angular/core/testing';
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { createHostComponentFactory, SpectatorWithHost } from '@netbasal/spectator';
describe('MyScrollableComponent', () => {
let host: SpectatorWithHost<MyScrollableComponent>;
const createHost = createHostComponentFactory(MyScrollableComponent);
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
InfiniteScrollModule,
],
});
host = createHost(`<div class="scrollable"><my-component></my-component></div>`);
});
});
Most helpful comment
That approach still not solving the test implementation problem.
If setting it to window may cause undesired results, the container should point to defaultElement as it is the one rendered by Karma tests.
Basicaly it should look like this: