diff --git a/app/demo.config.json b/app/demo.config.json index df7b734a..812c2f55 100644 --- a/app/demo.config.json +++ b/app/demo.config.json @@ -23,7 +23,6 @@ "body": "Need run" }, "description": "Need to run the scroller", - "ds": "./datasources/common.js", "runner": "./runners/empty.js" }, { diff --git a/tests/e2e/index.d.ts b/tests/e2e/index.d.ts index 93775e9c..339c1383 100644 --- a/tests/e2e/index.d.ts +++ b/tests/e2e/index.d.ts @@ -1,7 +1,9 @@ +import * as VScroll from '../../src/index'; import { VSCROLL, TESTS } from './misc/types'; declare global { interface Window { + VScroll: typeof VScroll; __vscroll__: VSCROLL; __tests__: TESTS; } diff --git a/tests/e2e/initialization.spec.ts b/tests/e2e/initialization.spec.ts index 4aa95b4d..93648bde 100644 --- a/tests/e2e/initialization.spec.ts +++ b/tests/e2e/initialization.spec.ts @@ -1,94 +1,101 @@ import { test, expect } from '@playwright/test'; -import { runScroller } from './misc/runner'; +import { makeTest } from './misc/runner'; const URL = '127.0.0.1:3000'; -test('DOM + Workflow', async ({ page }) => { - await page.goto(URL + '/common'); - - await expect(page.locator('[data-padding-forward]')).toBeAttached(); - await expect(page.locator('[data-padding-backward]')).toBeAttached(); - await expect(page.locator('[data-padding-forward]')).toHaveCount(1); - await expect(page.locator('[data-padding-backward]')).toHaveCount(1); - - const firstItemElt = page.locator('[data-sid="1"]'); - await expect(firstItemElt).toBeVisible(); - await expect(firstItemElt).toContainText('1) item #1'); - - const { datasource, scroller: { workflow } } = await page.evaluate(async () => { - const vscroll = window['__vscroll__']; - await vscroll.datasource.adapter.relax(); - return vscroll; - }); - - // eslint-disable-next-line no-prototype-builtins - expect(datasource.hasOwnProperty('get')).toBe(true); - expect(typeof workflow).toBe('object'); - expect(workflow.isInitialized).toBe(true); - expect(workflow.errors.length).toEqual(0); - expect(workflow.cyclesDone).toEqual(1); - const name = workflow?.scroller?.state?.packageInfo?.core?.name; - expect(name).toBe('vscroll'); +// test.use({ headless: false }); + +makeTest({ + title: 'DOM + Workflow', + config: { datasourceDevSettings: { initDelay: 100 } }, + it: async ({ page }) => { + await expect(page.locator('[data-padding-forward]')).toBeAttached(); + await expect(page.locator('[data-padding-backward]')).toBeAttached(); + await expect(page.locator('[data-padding-forward]')).toHaveCount(1); + await expect(page.locator('[data-padding-backward]')).toHaveCount(1); + + const firstItemElt = page.locator('[data-sid="1"]'); + await expect(firstItemElt).toBeVisible(); + await expect(firstItemElt).toContainText('1) item #1'); + + const { datasource, workflow } = await page.evaluate(async () => { + const vscroll = window['__vscroll__']; + await vscroll.datasource.adapter.relax(); + return vscroll; + }); + + expect(Object.hasOwn(datasource, 'get')).toBe(true); + expect(typeof workflow).toBe('object'); + expect(workflow.isInitialized).toBe(true); + expect(workflow.errors.length).toEqual(0); + expect(workflow.cyclesDone).toEqual(1); + const name = workflow?.scroller?.state?.packageInfo?.core?.name; + expect(name).toBe('vscroll'); + } }); -test('Workflow & Adapter. Delayed initialization', async ({ page }) => { - await page.goto(URL + '/need-run'); - await runScroller(page, { datasourceDevSettings: { initDelay: 100 } }); - - await page.waitForFunction(() => { - const { workflow, datasource } = window['__vscroll__']; - return !workflow.isInitialized && !datasource.adapter.init; - }); - - await page.waitForTimeout(100); - - await page.waitForFunction(() => { - const { workflow, datasource } = window['__vscroll__']; - return workflow.isInitialized && datasource.adapter.init; - }); +makeTest({ + title: 'Workflow & Adapter. Delayed initialization', + config: { datasourceDevSettings: { initDelay: 100 } }, + it: async ({ page }) => { + await page.waitForFunction(() => { + const { workflow, datasource } = window['__vscroll__']; + return !workflow.isInitialized && !datasource.adapter.init; + }); + + await page.waitForTimeout(100); + + await page.waitForFunction(() => { + const { workflow, datasource } = window['__vscroll__']; + return workflow.isInitialized && datasource.adapter.init; + }); + } }); -test('Workflow & Adapter. Disposing after delayed initialization', async ({ page }) => { - await page.goto(URL + '/need-run'); - await runScroller(page, { datasourceDevSettings: { initDelay: 100 } }); - - await page.waitForTimeout(100); - await page.evaluate(() => window['__vscroll__'].workflow.dispose()); - - await page.waitForFunction(() => { - const { workflow, datasource } = window['__vscroll__']; - return !workflow.isInitialized && !datasource.adapter.init; - }); +makeTest({ + title: 'Workflow & Adapter. Disposing after delayed initialization', + config: { datasourceDevSettings: { initDelay: 100 } }, + it: async ({ page }) => { + await page.waitForTimeout(100); + await page.evaluate(() => window['__vscroll__'].workflow.dispose()); + + await page.waitForFunction(() => { + const { workflow, datasource } = window['__vscroll__']; + return !workflow.isInitialized && !datasource.adapter.init; + }); + } }); -test('Workflow & Adapter. Disposing before delayed initialization', async ({ page }) => { - await page.goto(URL + '/need-run'); - await runScroller(page, { datasourceDevSettings: { initDelay: 100 } }); - - await page.evaluate(() => window['__vscroll__'].workflow.dispose()); - await page.waitForTimeout(100); - - await page.waitForFunction(() => { - const { workflow, datasource } = window['__vscroll__']; - return !workflow.isInitialized && !datasource.adapter.init; - }); +makeTest({ + title: 'Workflow & Adapter. Disposing before delayed initialization', + config: { datasourceDevSettings: { initDelay: 100 } }, + it: async ({ page }) => { + await page.evaluate(() => window['__vscroll__'].workflow.dispose()); + await page.waitForTimeout(100); + + await page.waitForFunction(() => { + const { workflow, datasource } = window['__vscroll__']; + return !workflow.isInitialized && !datasource.adapter.init; + }); + } }); -test('Workflow & Adapter. Disposing after immediate initialization', async ({ page }) => { - await page.goto(URL + '/need-run'); - await runScroller(page); - - await page.waitForFunction(() => { - const { workflow, datasource } = window['__vscroll__']; - return workflow.isInitialized && datasource.adapter.init; - }); - - await page.evaluate(() => window['__vscroll__'].workflow.dispose()); - - await page.waitForFunction(() => { - const { workflow, datasource } = window['__vscroll__']; - return !workflow.isInitialized && !datasource.adapter.init; - }); +makeTest({ + title: 'Workflow & Adapter. Disposing after immediate initialization', + config: { datasourceDevSettings: { initDelay: 100 } }, + it: async ({ page }) => { + await page.waitForFunction(() => { + const { workflow, datasource } = window['__vscroll__']; + return workflow.isInitialized && datasource.adapter.init; + }); + + await page.evaluate(() => window['__vscroll__'].workflow.dispose()); + + await page.waitForFunction(() => { + const { workflow, datasource } = window['__vscroll__']; + return !workflow.isInitialized && !datasource.adapter.init; + }); + } }); test('Multiple instances initialization', async ({ page }) => { diff --git a/tests/e2e/misc/runner.ts b/tests/e2e/misc/runner.ts index d8cfc9db..a6af901c 100644 --- a/tests/e2e/misc/runner.ts +++ b/tests/e2e/misc/runner.ts @@ -3,52 +3,81 @@ import { Config, It } from './types'; const URL = '127.0.0.1:3000'; -export const runScroller = async (page: Page, config: Config = {}) => - await page.evaluate(config => { - const { datasourceSettings, datasourceDevSettings, templateSettings } = config as Config; - const { Scroller, datasource } = window['__vscroll__']; - datasource.settings = { ...datasource.settings, ...datasourceSettings }; - datasource.devSettings = { ...datasource.devSettings, ...datasourceDevSettings }; - +const makeTemplate = (page: Page, config: Config) => + page.evaluate(templateSettings => { const viewport = window.document.querySelector('.viewport') as HTMLElement; + let styles = ''; if (templateSettings?.viewportWidth) { - viewport.style.width = templateSettings.viewportWidth + 'px'; + styles += ` +.viewport { + width: ${templateSettings.viewportWidth}px; +}`; } if (templateSettings?.viewportHeight) { - viewport.style.height = templateSettings.viewportHeight + 'px'; - } - if (templateSettings?.horizontal) { - viewport.className += ' horizontal'; + styles += ` +.viewport { + height: ${templateSettings.viewportHeight}px; +}`; } - let styles = ''; if (templateSettings?.itemWidth) { styles += ` - .viewport .item { - width: ${templateSettings.itemWidth}px; - }`; +.viewport .item { + width: ${templateSettings.itemWidth}px; +}`; } if (templateSettings?.itemHeight) { styles += ` - .viewport .item { - height: ${templateSettings.itemHeight}px; - }`; +.viewport .item { + height: ${templateSettings.itemHeight}px; +}`; } if (styles) { const styleSheet = document.createElement('style'); styleSheet.innerText = styles; document.head.appendChild(styleSheet); } + if (templateSettings?.horizontal) { + viewport.className += ' horizontal'; + } + }, config.templateSettings); + +const makeDatasource = (page: Page, config: Config) => + page.evaluate(config => { + const { datasourceSettings, datasourceDevSettings } = config as Config; + const { makeDatasource } = window['VScroll']; + const Datasource = makeDatasource(); + const datasource = new Datasource({ + get: (index, count, success) => { + const data = []; + for (let i = index; i <= index + count - 1; i++) { + data.push({ id: i, text: 'item #' + i }); + } + success(data); + }, + settings: { ...(datasourceSettings || {}) }, + devSettings: { ...(datasourceDevSettings || {}) } + }); + + window.__vscroll__.datasource = datasource; + }, config as unknown); + +export const runScroller = async (page: Page, config: Config = {}) => { + await makeTemplate(page, config); + await makeDatasource(page, config); + await page.evaluate(() => { + const { Scroller, datasource } = window['__vscroll__']; const { workflow } = new Scroller(datasource); window['__vscroll__'].workflow = workflow; - }, config as unknown); + }); +}; export const makeTest = ( { title, config, it }: { title: string; config: Config; it: It } ) => test(title, async ({ page }) => { await page.goto(URL + '/need-run'); - await runScroller(page, config as Config); + await runScroller(page, config); await it({ config, page }); // await new Promise(r => setTimeout(r, 2000)); }); diff --git a/tests/e2e/scroll-basic.spec.ts b/tests/e2e/scroll-basic.spec.ts index 5e4c26a5..154a4f9a 100644 --- a/tests/e2e/scroll-basic.spec.ts +++ b/tests/e2e/scroll-basic.spec.ts @@ -109,17 +109,16 @@ const massTwoDirectionalScrollsConfigList_bwd = } } as Config)); - const shouldWork = async ({ config, page }: { config: Config, page: Page }) => { await initializeItemsCounter(page); const result = await page.evaluate(custom => new Promise(resolve => { - const { workflow } = window['__vscroll__']; + const { workflow, datasource } = window['__vscroll__']; const { ItemsCounter: helper } = window['__tests__']; - workflow.scroller.state.cycle.busy.on(busy => { + datasource.adapter.isLoading$.on(busy => { if (busy) { return; } diff --git a/tests/tsconfig.json b/tests/tsconfig.json index f5b2bc29..71b2ed98 100644 --- a/tests/tsconfig.json +++ b/tests/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../tsconfig.json", "compilerOptions": { "rootDir": "../", + "lib": ["dom", "es2022"], "noImplicitAny": true }, "exclude": ["node_modules"],