UNPKG

@v4fire/client

Version:

V4Fire client core library

239 lines (205 loc) • 6.69 kB
/*! * V4Fire Client Core * https://github.com/V4Fire/Client * * Released under the MIT license * https://github.com/V4Fire/Client/blob/master/LICENSE */ import type { Locator, Page } from 'playwright'; import { ComponentObject, Scroll } from 'tests/helpers'; import type bVirtualScrollNew from 'base/b-virtual-scroll-new/b-virtual-scroll-new'; import type { ComponentRefs, VirtualScrollState } from 'base/b-virtual-scroll-new/interface'; import type { SlotsStateObj } from 'base/b-virtual-scroll-new/modules/slots'; import { testStyles } from 'base/b-virtual-scroll-new/test/api/component-object/styles'; /** * The component object API for testing the {@link bVirtualScrollNew} component. */ export class VirtualScrollComponentObject extends ComponentObject<bVirtualScrollNew['unsafe']> { /** * The locator for the container ref. */ readonly container: Locator; /** * The locator to select all children in the container ref. */ readonly childList: Locator; override get componentStyles(): string { return testStyles; } /** * @param page - the Playwright page instance. */ constructor(page: Page) { super(page, 'b-virtual-scroll-new'); this.container = this.node.locator(this.elSelector('container')); this.childList = this.container.locator('> *'); } /** * Calls the reload method of the component * {@link bVirtualScrollNew.reload} */ reload(): Promise<void> { return this.evaluate((ctx) => ctx.reload()); } /** * Returns the internal component state * {@link bVirtualScrollNew.getVirtualScrollState} */ getVirtualScrollState(): Promise<VirtualScrollState> { return this.evaluate((ctx) => ctx.getVirtualScrollState()); } /** * Returns the count of children in the container ref */ getChildCount(): Promise<number> { return this.childList.count(); } /** * Waits for the container child count to be equal to N. * Throws an error if there are more items in the child list than expected. * * @param count - the expected child count. */ async waitForChildCountEqualsTo(count: number): Promise<void> { await this.childList.nth(count - 1).waitFor({state: 'attached'}); const realCount = await this.childList.count(); if (realCount > count) { throw new Error(`Expected container to have exactly ${count} items, but got ${realCount}`); } } /** * Returns a promise that resolves when an element matching the given selector is inserted into the container. * * @param selector - the selector to match the element. * @returns A promise that resolves when the element is attached. */ async waitForChild(selector: string): Promise<void> { await this.container.locator(selector).waitFor({state: 'attached'}); } /** * Returns a promise that resolves when an element with the attribute data-index="n" is inserted into the container. * * @param index - the index value for the data-index attribute. * @returns A promise that resolves when the element is attached. */ async waitForDataIndexChild(index: number): Promise<void> { return this.waitForChild(`[data-index="${index}"]`); } /** * Returns a promise that resolves when the specified event occurs. * * @param eventName - the name of the event to wait for. * @returns A promise that resolves to the payload of the event, or `undefined`. */ async waitForEvent<PAYLOAD extends unknown>(eventName: string): Promise<CanUndef<PAYLOAD>> { return this.evaluate((ctx, [eventName]) => ctx.promisifyOnce(eventName), <const>[eventName]); } /** * Waits for the component lifecycle to be done */ async waitForLifecycleDone(): Promise<void> { await this.evaluate((ctx) => { const state = ctx.getVirtualScrollState(); if (state.isLifecycleDone) { return; } return ctx.unsafe.componentEmitter.promisifyOnce('lifecycleDone'); }); } /** * Waits for the provided slot to reach the specified visibility state. * * @param slotName - the name of the slot. * @param isVisible - the expected visibility state. * @param timeout - the timeout for waiting (optional). */ async waitForSlotState(slotName: keyof ComponentRefs, isVisible: boolean, timeout?: number): Promise<void> { const slot = this.node.locator(this.elSelector(slotName.dasherize())); await slot.waitFor({state: isVisible ? 'visible' : 'hidden', timeout}); } /** * Returns an object representing the state of all slots. * Each slot is represented as [slotName: slotState], where `slotState=true` means the slot is visible. */ async getSlotsState(): Promise<Required<SlotsStateObj>> { const container = this.node.locator(this.elSelector('container')), loader = this.node.locator(this.elSelector('loader')), tombstones = this.node.locator(this.elSelector('tombstones')), empty = this.node.locator(this.elSelector('empty')), retry = this.node.locator(this.elSelector('retry')), done = this.node.locator(this.elSelector('done')), renderNext = this.node.locator(this.elSelector('render-next')); return { container: await container.isVisible(), loader: await loader.isVisible(), tombstones: await tombstones.isVisible(), empty: await empty.isVisible(), retry: await retry.isVisible(), done: await done.isVisible(), renderNext: await renderNext.isVisible() }; } /** * Scrolls the page to the bottom */ async scrollToBottom(): Promise<this> { await Scroll.scrollToBottom(this.pwPage); return this; } /** * Scrolls the page to the top */ async scrollToTop(): Promise<this> { await Scroll.scrollToTop(this.pwPage); return this; } /** * Adds default `itemProps` for pagination */ withPaginationItemProps(): this { this.withProps({ item: 'section', itemProps: (item) => ({'data-index': item.i}) }); return this; } /** * Adds a `requestProp` for pagination. * * @param requestParams - the request parameters. */ withRequestPaginationProps(requestParams: Dictionary = {}): this { this.withProps({ request: { get: { chunkSize: 10, id: Math.random(), ...requestParams } } }); return this; } /** * Adds a `Provider` into the provider prop for pagination */ withPaginationProvider(): this { this.withProps({dataProvider: 'Provider'}); return this; } /** * Calls all default pagination prop setters: * - `withPaginationProvider` * - `withPaginationItemProps` * - `withRequestProp` * * @param requestParams - the request parameters. */ withDefaultPaginationProviderProps(requestParams: Dictionary = {}): this { this.withPaginationProvider(); this.withPaginationItemProps(); this.withRequestPaginationProps(requestParams); return this; } }