From 448e047d25483e1e2332c472fe4c86b511142a04 Mon Sep 17 00:00:00 2001 From: Raju Udava <86527202+dstala@users.noreply.github.com> Date: Tue, 7 Feb 2023 13:20:41 +0530 Subject: [PATCH] test: filters for Number, Decimal, Percent, Currency Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com> --- tests/playwright/package-lock.json | 54 ++- tests/playwright/package.json | 1 + .../playwright/pages/Dashboard/Grid/index.ts | 19 + .../pages/Dashboard/common/Toolbar/Filter.ts | 49 +- tests/playwright/setup/xcdb-records.ts | 131 ++++++ tests/playwright/tests/filters.spec.ts | 417 ++++++++++++++++++ 6 files changed, 651 insertions(+), 20 deletions(-) create mode 100644 tests/playwright/setup/xcdb-records.ts create mode 100644 tests/playwright/tests/filters.spec.ts diff --git a/tests/playwright/package-lock.json b/tests/playwright/package-lock.json index 048933e0cf..a335ff146c 100644 --- a/tests/playwright/package-lock.json +++ b/tests/playwright/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "body-parser": "^1.20.1", "express": "^4.18.2", + "nocodb-sdk": "^0.104.3", "xlsx": "^0.18.5" }, "devDependencies": { @@ -2032,7 +2033,6 @@ "version": "1.15.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "dev": true, "funding": [ { "type": "individual", @@ -2713,6 +2713,14 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsep": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.8.tgz", + "integrity": "sha512-qofGylTGgYj9gZFsHuyWAN4jr35eJ66qJCK4eKDnldohuUoQFbU3iZn2zjvEbd9wOAhP9Wx5DsAAduTyE1PSWQ==", + "engines": { + "node": ">= 10.16.0" + } + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -3165,6 +3173,23 @@ "node": ">= 0.6" } }, + "node_modules/nocodb-sdk": { + "version": "0.104.3", + "resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.104.3.tgz", + "integrity": "sha512-C6uIeexVz2aMWmabpaut3Y/sI8Myp2cRDyKZIjRXmMjSdV1F8BIRrPWVTLGSgHxe6YECFtl+eLR5ma70eJsqCw==", + "dependencies": { + "axios": "^0.21.1", + "jsep": "^1.3.6" + } + }, + "node_modules/nocodb-sdk/node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, "node_modules/node-pre-gyp": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz", @@ -6431,8 +6456,7 @@ "follow-redirects": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "dev": true + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" }, "forwarded": { "version": "0.2.0", @@ -6898,6 +6922,11 @@ "esprima": "^4.0.0" } }, + "jsep": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.8.tgz", + "integrity": "sha512-qofGylTGgYj9gZFsHuyWAN4jr35eJ66qJCK4eKDnldohuUoQFbU3iZn2zjvEbd9wOAhP9Wx5DsAAduTyE1PSWQ==" + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -7248,6 +7277,25 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, + "nocodb-sdk": { + "version": "0.104.3", + "resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.104.3.tgz", + "integrity": "sha512-C6uIeexVz2aMWmabpaut3Y/sI8Myp2cRDyKZIjRXmMjSdV1F8BIRrPWVTLGSgHxe6YECFtl+eLR5ma70eJsqCw==", + "requires": { + "axios": "^0.21.1", + "jsep": "^1.3.6" + }, + "dependencies": { + "axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "requires": { + "follow-redirects": "^1.14.0" + } + } + } + }, "node-pre-gyp": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz", diff --git a/tests/playwright/package.json b/tests/playwright/package.json index d685046cce..f719fa2767 100644 --- a/tests/playwright/package.json +++ b/tests/playwright/package.json @@ -45,6 +45,7 @@ "dependencies": { "body-parser": "^1.20.1", "express": "^4.18.2", + "nocodb-sdk": "^0.104.3", "xlsx": "^0.18.5" } } diff --git a/tests/playwright/pages/Dashboard/Grid/index.ts b/tests/playwright/pages/Dashboard/Grid/index.ts index 9e3f3b507b..59b04c53ca 100644 --- a/tests/playwright/pages/Dashboard/Grid/index.ts +++ b/tests/playwright/pages/Dashboard/Grid/index.ts @@ -201,6 +201,25 @@ export class GridPage extends BasePage { await this.dashboard.waitForLoaderToDisappear(); } + async verifyTotalRowCount({ count }: { count: number }) { + // wait for 100 ms and try again : 5 times + let i = 0; + await this.get().locator(`.nc-pagination`).waitFor(); + let records = await this.get().locator(`[data-testid="grid-pagination"]`).allInnerTexts(); + let recordCnt = records[0].split(' ')[0]; + + while (parseInt(recordCnt) !== count && i < 5) { + await this.get().locator(`.nc-pagination`).waitFor(); + records = await this.get().locator(`[data-testid="grid-pagination"]`).allInnerTexts(); + recordCnt = records[0].split(' ')[0]; + + // to ensure page loading is complete + await this.rootPage.waitForTimeout(500); + i++; + } + expect(parseInt(recordCnt)).toEqual(count); + } + private async pagination({ page }: { page: string }) { await this.get().locator(`.nc-pagination`).waitFor(); diff --git a/tests/playwright/pages/Dashboard/common/Toolbar/Filter.ts b/tests/playwright/pages/Dashboard/common/Toolbar/Filter.ts index 7e1b839969..1a626fa25d 100644 --- a/tests/playwright/pages/Dashboard/common/Toolbar/Filter.ts +++ b/tests/playwright/pages/Dashboard/common/Toolbar/Filter.ts @@ -42,32 +42,47 @@ export class ToolbarFilterPage extends BasePage { await this.get().locator(`button:has-text("Add Filter")`).first().click(); await this.rootPage.locator('.nc-filter-field-select').last().click(); - const selectColumn = this.rootPage + await this.rootPage .locator('div.ant-select-dropdown.nc-dropdown-toolbar-field-list') - .locator(`div[label="${columnTitle}"][aria-selected="false"]:visible`) + .locator(`div[label="${columnTitle}"]`) .click(); - await this.waitForResponse({ - uiAction: selectColumn, - httpMethodsToMatch: isLocallySaved ? ['GET'] : ['POST', 'PATCH'], - requestUrlPathToMatch: isLocallySaved ? `/api/v1/db/public/` : `/filters`, - }); - await this.toolbar.parent.dashboard.waitForLoaderToDisappear(); + // const selectColumn = this.rootPage + // .locator('div.ant-select-dropdown.nc-dropdown-toolbar-field-list') + // .locator(`div[label="${columnTitle}"]`) + // .click(); + // await this.waitForResponse({ + // uiAction: selectColumn, + // httpMethodsToMatch: isLocallySaved ? ['GET'] : ['POST', 'PATCH'], + // requestUrlPathToMatch: isLocallySaved ? `/api/v1/db/public/` : `/filters`, + // }); + // await this.toolbar.parent.dashboard.waitForLoaderToDisappear(); const selectedOpType = await this.rootPage.locator('.nc-filter-operation-select').textContent(); if (selectedOpType !== opType) { - await this.rootPage.locator('.nc-filter-operation-select').last().click(); - const selectOpType = this.rootPage + await this.rootPage.locator('.nc-filter-operation-select').click(); + // first() : filter list has >, >= + await this.rootPage .locator('.nc-dropdown-filter-comp-op') .locator(`.ant-select-item:has-text("${opType}")`) + .first() .click(); - - await this.waitForResponse({ - uiAction: selectOpType, - httpMethodsToMatch: isLocallySaved ? ['GET'] : ['POST', 'PATCH'], - requestUrlPathToMatch: isLocallySaved ? `/api/v1/db/public/` : `/filters`, - }); - await this.toolbar.parent.dashboard.waitForLoaderToDisappear(); } + // if (selectedOpType !== opType) { + // await this.rootPage.locator('.nc-filter-operation-select').last().click(); + // // first() : filter list has >, >= + // const selectOpType = this.rootPage + // .locator('.nc-dropdown-filter-comp-op') + // .locator(`.ant-select-item:has-text("${opType}")`) + // .first() + // .click(); + // + // await this.waitForResponse({ + // uiAction: selectOpType, + // httpMethodsToMatch: isLocallySaved ? ['GET'] : ['POST', 'PATCH'], + // requestUrlPathToMatch: isLocallySaved ? `/api/v1/db/public/` : `/filters`, + // }); + // await this.toolbar.parent.dashboard.waitForLoaderToDisappear(); + // } // if value field was provided, fill it if (value) { diff --git a/tests/playwright/setup/xcdb-records.ts b/tests/playwright/setup/xcdb-records.ts new file mode 100644 index 0000000000..8993be46ed --- /dev/null +++ b/tests/playwright/setup/xcdb-records.ts @@ -0,0 +1,131 @@ +import { ColumnType, UITypes } from 'nocodb-sdk'; + +const rowMixedValue = (column: ColumnType, index: number) => { + // Array of country names + const countries = [ + 'Afghanistan', + 'Albania', + '', + 'Andorra', + 'Angola', + 'Antigua and Barbuda', + 'Argentina', + null, + 'Armenia', + 'Australia', + 'Austria', + '', + null, + ]; + + // Array of sample random paragraphs (comma separated list of cities and countries). Not more than 200 characters + const longText = [ + 'Aberdeen, United Kingdom', + 'Abidjan, Côte d’Ivoire', + 'Abuja, Nigeria', + '', + 'Addis Ababa, Ethiopia', + 'Adelaide, Australia', + 'Ahmedabad, India', + 'Albuquerque, United States', + null, + 'Alexandria, Egypt', + 'Algiers, Algeria', + 'Allahabad, India', + '', + null, + ]; + + // Array of random integers, not more than 10000 + const numbers = [33, null, 456, 333, 267, 34, 8754, 3234, 44, 33, null]; + const decimals = [33.3, 456.34, 333.3, null, 267.5674, 34.0, 8754.0, 3234.547, 44.2647, 33.98, null]; + const duration = [10, 20, 30, 40, 50, 60, null, 70, 80, 90, null]; + const rating = [0, 1, 2, 3, null, 0, 4, 5, 0, 1, null]; + + // Array of random sample email strings (not more than 100 characters) + const emails = [ + 'jbutt@gmail.com', + 'josephine_darakjy@darakjy.org', + 'art@venere.org', + '', + null, + 'donette.foller@cox.net', + 'simona@morasca.com', + 'mitsue_tollner@yahoo.com', + 'leota@hotmail.com', + 'sage_wieser@cox.net', + '', + null, + ]; + + // Array of random sample phone numbers + const phoneNumbers = [ + '1-541-754-3010', + '504-621-8927', + '810-292-9388', + '856-636-8749', + '907-385-4412', + '513-570-1893', + '419-503-2484', + '773-573-6914', + '', + null, + ]; + + // Array of random sample URLs + const urls = [ + 'https://www.google.com', + 'https://www.facebook.com', + 'https://www.youtube.com', + 'https://www.amazon.com', + 'https://www.wikipedia.org', + 'https://www.twitter.com', + 'https://www.instagram.com', + 'https://www.linkedin.com', + 'https://www.reddit.com', + 'https://www.tiktok.com', + 'https://www.pinterest.com', + 'https://www.netflix.com', + 'https://www.microsoft.com', + 'https://www.apple.com', + '', + null, + ]; + + const singleSelect = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec', null]; + + const multiSelect = ['jan,feb,mar', 'apr,may,jun', 'jul,aug,sep', 'oct,nov,dec', 'jan,feb,mar', null]; + + switch (column.uidt) { + case UITypes.Number: + case UITypes.Percent: + return numbers[index % numbers.length]; + case UITypes.Decimal: + case UITypes.Currency: + return decimals[index % decimals.length]; + case UITypes.Duration: + return duration[index % duration.length]; + case UITypes.Rating: + return rating[index % rating.length]; + case UITypes.SingleLineText: + return countries[index % countries.length]; + case UITypes.Email: + return emails[index % emails.length]; + case UITypes.PhoneNumber: + return phoneNumbers[index % phoneNumbers.length]; + case UITypes.LongText: + return longText[index % longText.length]; + case UITypes.Date: + return '2020-01-01'; + case UITypes.URL: + return urls[index % urls.length]; + case UITypes.SingleSelect: + return singleSelect[index % singleSelect.length]; + case UITypes.MultiSelect: + return multiSelect[index % multiSelect.length]; + default: + return `test-${index}`; + } +}; + +export { rowMixedValue }; diff --git a/tests/playwright/tests/filters.spec.ts b/tests/playwright/tests/filters.spec.ts new file mode 100644 index 0000000000..774a70aac0 --- /dev/null +++ b/tests/playwright/tests/filters.spec.ts @@ -0,0 +1,417 @@ +import { test } from '@playwright/test'; +import { DashboardPage } from '../pages/Dashboard'; +import setup from '../setup'; +import { ToolbarPage } from '../pages/Dashboard/common/Toolbar'; +import { UITypes } from 'nocodb-sdk'; +import { Api } from 'nocodb-sdk'; +import { rowMixedValue } from '../setup/xcdb-records'; + +let dashboard: DashboardPage, toolbar: ToolbarPage; +let context: any; +let api: Api; +let records = []; +const skipList = { + Number: ['is null', 'is not null', 'is blank', 'is not blank'], + Decimal: ['is null', 'is not null', 'is blank', 'is not blank'], + Percent: ['is null', 'is not null', 'is blank', 'is not blank'], + Currency: ['is null', 'is not null', 'is blank', 'is not blank'], + Rating: ['is null', 'is not null', 'is blank', 'is not blank'], +}; + +// define validateRowArray function +async function validateRowArray(param) { + const { rowCount } = param; + await dashboard.grid.verifyTotalRowCount({ count: rowCount }); + + // const { sequence, length, totalRowCount, column } = param; + // + // await dashboard.grid.verifyTotalRowCount({ count: totalRowCount }); + // + // for (let j = 0; j < length; j++) { + // await dashboard.grid.cell.verify({ + // index: j, + // columnHeader: column, + // value: sequence, + // }); + // } +} + +async function verifyFilter(param: { column: string; opType: string; value?: string; result: { rowCount: number } }) { + // if opType was included in skip list, skip it + if (skipList[param.column]?.includes(param.opType)) { + return; + } + + await toolbar.clickFilter(); + await toolbar.filter.add({ + columnTitle: param.column, + opType: param.opType, + value: param.value, + isLocallySaved: false, + }); + await toolbar.clickFilter(); + + // verify filtered rows + await validateRowArray({ + rowCount: param.result.rowCount, + }); + + // Reset filter + await toolbar.filter.reset(); +} + +test.describe('Filter Tests: Numerical', () => { + test.beforeEach(async ({ page }) => { + context = await setup({ page }); + dashboard = new DashboardPage(page, context.project); + toolbar = dashboard.grid.toolbar; + + api = new Api({ + baseURL: `http://localhost:8080/`, + headers: { + 'xc-auth': context.token, + }, + }); + + const columns = [ + { + column_name: 'Id', + title: 'Id', + uidt: UITypes.ID, + }, + { + column_name: 'Number', + title: 'Number', + uidt: UITypes.Number, + }, + { + column_name: 'Decimal', + title: 'Decimal', + uidt: UITypes.Decimal, + }, + { + column_name: 'Currency', + title: 'Currency', + uidt: UITypes.Currency, + }, + { + column_name: 'Percent', + title: 'Percent', + uidt: UITypes.Percent, + }, + { + column_name: 'Duration', + title: 'Duration', + uidt: UITypes.Duration, + }, + { + column_name: 'Rating', + title: 'Rating', + uidt: UITypes.Rating, + }, + ]; + + try { + const project = await api.project.read(context.project.id); + const table = await api.base.tableCreate(context.project.id, project.bases?.[0].id, { + table_name: 'numberBased', + title: 'numberBased', + columns: columns, + }); + + const rowAttributes = []; + for (let i = 0; i < 400; i++) { + const row = { + Number: rowMixedValue(columns[1], i), + Decimal: rowMixedValue(columns[2], i), + Currency: rowMixedValue(columns[3], i), + Percent: rowMixedValue(columns[4], i), + Duration: rowMixedValue(columns[5], i), + Rating: rowMixedValue(columns[6], i), + }; + rowAttributes.push(row); + } + + await api.dbTableRow.bulkCreate('noco', context.project.id, table.id, rowAttributes); + records = await api.dbTableRow.list('noco', context.project.id, table.id, { limit: 400 }); + } catch (e) { + console.error(e); + } + }); + + test('Filter: Number', async () => { + // close 'Team & Auth' tab + await dashboard.closeTab({ title: 'Team & Auth' }); + await dashboard.treeView.openTable({ title: 'numberBased' }); + const dataType = 'Number'; + + const filterList = [ + { + op: '=', + value: '33', + rowCount: records.list.filter(r => r[dataType] === 33).length, + }, + { + op: '!=', + value: '33', + rowCount: records.list.filter(r => r[dataType] !== 33).length, + }, + { + op: 'is null', + value: '', + rowCount: records.list.filter(r => r[dataType] === null).length, + }, + { + op: 'is not null', + value: '', + rowCount: records.list.filter(r => r[dataType] !== null).length, + }, + { + op: 'is blank', + value: '', + rowCount: records.list.filter(r => r[dataType] === null).length, + }, + { + op: 'is not blank', + value: '', + rowCount: records.list.filter(r => r[dataType] !== null).length, + }, + { + op: '>', + value: '44', + rowCount: records.list.filter(r => r[dataType] > 44 && r[dataType] != null).length, + }, + { + op: '>=', + value: '44', + rowCount: records.list.filter(r => r[dataType] >= 44 && r[dataType] != null).length, + }, + { + op: '<', + value: '44', + rowCount: records.list.filter(r => r[dataType] < 44 && r[dataType] != null).length, + }, + { + op: '<=', + value: '44', + rowCount: records.list.filter(r => r[dataType] <= 44 && r[dataType] != null).length, + }, + ]; + + for (let i = 0; i < filterList.length; i++) { + await verifyFilter({ + column: dataType, + opType: filterList[i].op, + value: filterList[i].value, + result: { rowCount: filterList[i].rowCount }, + }); + } + }); + + test('Filter: Decimal', async () => { + // close 'Team & Auth' tab + await dashboard.closeTab({ title: 'Team & Auth' }); + await dashboard.treeView.openTable({ title: 'numberBased' }); + const dataType = 'Decimal'; + + const filterList = [ + { + op: '=', + value: '33.3', + rowCount: records.list.filter(r => r[dataType] === 33.3).length, + }, + { + op: '!=', + value: '33.3', + rowCount: records.list.filter(r => r[dataType] !== 33.3).length, + }, + { + op: 'is null', + value: '', + rowCount: records.list.filter(r => r[dataType] === null).length, + }, + { + op: 'is not null', + value: '', + rowCount: records.list.filter(r => r[dataType] !== null).length, + }, + { + op: 'is blank', + value: '', + rowCount: records.list.filter(r => r[dataType] === null).length, + }, + { + op: 'is not blank', + value: '', + rowCount: records.list.filter(r => r[dataType] !== null).length, + }, + { + op: '>', + value: '44.26', + rowCount: records.list.filter(r => r[dataType] > 44.26 && r[dataType] != null).length, + }, + { + op: '>=', + value: '44.26', + rowCount: records.list.filter(r => r[dataType] >= 44.26 && r[dataType] != null).length, + }, + { + op: '<', + value: '44.26', + rowCount: records.list.filter(r => r[dataType] < 44.26 && r[dataType] != null).length, + }, + { + op: '<=', + value: '44.26', + rowCount: records.list.filter(r => r[dataType] <= 44.26 && r[dataType] != null).length, + }, + ]; + + for (let i = 0; i < filterList.length; i++) { + await verifyFilter({ + column: dataType, + opType: filterList[i].op, + value: filterList[i].value, + result: { rowCount: filterList[i].rowCount }, + }); + } + }); + + test('Filter: Percent', async () => { + // close 'Team & Auth' tab + await dashboard.closeTab({ title: 'Team & Auth' }); + await dashboard.treeView.openTable({ title: 'numberBased' }); + const dataType = 'Percent'; + + const filterList = [ + { + op: '=', + value: '33', + rowCount: records.list.filter(r => r[dataType] === 33).length, + }, + { + op: '!=', + value: '33', + rowCount: records.list.filter(r => r[dataType] !== 33).length, + }, + { + op: 'is null', + value: '', + rowCount: records.list.filter(r => r[dataType] === null).length, + }, + { + op: 'is not null', + value: '', + rowCount: records.list.filter(r => r[dataType] !== null).length, + }, + { + op: 'is blank', + value: '', + rowCount: records.list.filter(r => r[dataType] === null).length, + }, + { + op: 'is not blank', + value: '', + rowCount: records.list.filter(r => r[dataType] !== null).length, + }, + { + op: '>', + value: '44', + rowCount: records.list.filter(r => r[dataType] > 44 && r[dataType] != null).length, + }, + { + op: '>=', + value: '44', + rowCount: records.list.filter(r => r[dataType] >= 44 && r[dataType] != null).length, + }, + { + op: '<', + value: '44', + rowCount: records.list.filter(r => r[dataType] < 44 && r[dataType] != null).length, + }, + { + op: '<=', + value: '44', + rowCount: records.list.filter(r => r[dataType] <= 44 && r[dataType] != null).length, + }, + ]; + + for (let i = 0; i < filterList.length; i++) { + await verifyFilter({ + column: dataType, + opType: filterList[i].op, + value: filterList[i].value, + result: { rowCount: filterList[i].rowCount }, + }); + } + }); + + test('Filter: Currency', async () => { + // close 'Team & Auth' tab + await dashboard.closeTab({ title: 'Team & Auth' }); + await dashboard.treeView.openTable({ title: 'numberBased' }); + const dataType = 'Currency'; + + const filterList = [ + { + op: '=', + value: '33.3', + rowCount: records.list.filter(r => r[dataType] === 33.3).length, + }, + { + op: '!=', + value: '33.3', + rowCount: records.list.filter(r => r[dataType] !== 33.3).length, + }, + { + op: 'is null', + value: '', + rowCount: records.list.filter(r => r[dataType] === null).length, + }, + { + op: 'is not null', + value: '', + rowCount: records.list.filter(r => r[dataType] !== null).length, + }, + { + op: 'is blank', + value: '', + rowCount: records.list.filter(r => r[dataType] === null).length, + }, + { + op: 'is not blank', + value: '', + rowCount: records.list.filter(r => r[dataType] !== null).length, + }, + { + op: '>', + value: '44.26', + rowCount: records.list.filter(r => r[dataType] > 44.26 && r[dataType] != null).length, + }, + { + op: '>=', + value: '44.26', + rowCount: records.list.filter(r => r[dataType] >= 44.26 && r[dataType] != null).length, + }, + { + op: '<', + value: '44.26', + rowCount: records.list.filter(r => r[dataType] < 44.26 && r[dataType] != null).length, + }, + { + op: '<=', + value: '44.26', + rowCount: records.list.filter(r => r[dataType] <= 44.26 && r[dataType] != null).length, + }, + ]; + + for (let i = 0; i < filterList.length; i++) { + await verifyFilter({ + column: dataType, + opType: filterList[i].op, + value: filterList[i].value, + result: { rowCount: filterList[i].rowCount }, + }); + } + }); +});