diff --git a/tests/playwright/pages/Dashboard/Grid/index.ts b/tests/playwright/pages/Dashboard/Grid/index.ts index 59b04c53ca..9fadbc3851 100644 --- a/tests/playwright/pages/Dashboard/Grid/index.ts +++ b/tests/playwright/pages/Dashboard/Grid/index.ts @@ -217,6 +217,7 @@ export class GridPage extends BasePage { await this.rootPage.waitForTimeout(500); i++; } + console.log('recordCnt', parseInt(recordCnt), 'count', count); expect(parseInt(recordCnt)).toEqual(count); } diff --git a/tests/playwright/tests/filters.spec.ts b/tests/playwright/tests/filters.spec.ts index 48d949ac51..697d2cb525 100644 --- a/tests/playwright/tests/filters.spec.ts +++ b/tests/playwright/tests/filters.spec.ts @@ -10,12 +10,20 @@ 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'], + SingleLineText: ['is blank', 'is not blank'], + MultiLineText: ['is blank', 'is not blank'], + Email: ['is blank', 'is not blank'], + PhoneNumber: ['is blank', 'is not blank'], + URL: ['is blank', 'is not blank'], + SingleSelect: ['is blank', 'is not blank', 'contains all of', 'does not contain all of'], + MultiSelect: ['is blank', 'is not blank', 'is', 'is not'], }; // define validateRowArray function @@ -68,6 +76,74 @@ async function verifyFilter(param: { } test.describe('Filter Tests: Numerical', () => { + async function numBasedFilterTest(dataType, eqString, isLikeString) { + await dashboard.closeTab({ title: 'Team & Auth' }); + await dashboard.treeView.openTable({ title: 'numberBased' }); + + const filterList = [ + { + op: '=', + value: eqString, + rowCount: records.list.filter(r => r[dataType] === parseFloat(eqString)).length, + }, + { + op: '!=', + value: eqString, + rowCount: records.list.filter(r => r[dataType] !== parseFloat(eqString)).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: isLikeString, + rowCount: records.list.filter(r => r[dataType] > parseFloat(isLikeString) && r[dataType] != null).length, + }, + { + op: '>=', + value: isLikeString, + rowCount: records.list.filter(r => r[dataType] >= parseFloat(isLikeString) && r[dataType] != null).length, + }, + { + op: '<', + value: isLikeString, + rowCount: records.list.filter(r => r[dataType] < parseFloat(isLikeString) && r[dataType] != null).length, + }, + { + op: '<=', + value: isLikeString, + rowCount: records.list.filter(r => r[dataType] <= parseFloat(isLikeString) && 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 }, + dataType: dataType, + }); + } + } + test.beforeEach(async ({ page }) => { context = await setup({ page }); dashboard = new DashboardPage(page, context.project); @@ -147,90 +223,44 @@ test.describe('Filter Tests: Numerical', () => { }); test('Filter: Number', async () => { - // close 'Team & Auth' tab - await dashboard.closeTab({ title: 'Team & Auth' }); - await dashboard.treeView.openTable({ title: 'numberBased' }); - const dataType = 'Number'; + await numBasedFilterTest('Number', '33', '44'); + }); - 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, - }, - ]; + test('Filter: Decimal', async () => { + await numBasedFilterTest('Decimal', '33.3', '44.26'); + }); - 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 () => { + await numBasedFilterTest('Percent', '33', '44'); }); - test('Filter: Decimal', async () => { - // close 'Team & Auth' tab + test('Filter: Currency', async () => { + await numBasedFilterTest('Currency', '33.3', '44.26'); + }); + + test('Filter: Rating', async () => { + await numBasedFilterTest('Rating', '3', '2'); + }); +}); + +// Text based filters +// + +test.describe.only('Filter Tests: Text based', () => { + async function textBasedFilterTest(dataType, eqString, isLikeString) { await dashboard.closeTab({ title: 'Team & Auth' }); - await dashboard.treeView.openTable({ title: 'numberBased' }); - const dataType = 'Decimal'; + await dashboard.treeView.openTable({ title: 'textBased' }); const filterList = [ { - op: '=', - value: '33.3', - rowCount: records.list.filter(r => r[dataType] === 33.3).length, + op: 'is equal', + value: eqString, + rowCount: records.list.filter(r => r[dataType] === eqString).length, }, { - op: '!=', - value: '33.3', - rowCount: records.list.filter(r => r[dataType] !== 33.3).length, + op: 'is not equal', + value: eqString, + rowCount: records.list.filter(r => r[dataType] !== eqString).length, }, { op: 'is null', @@ -243,107 +273,39 @@ test.describe('Filter Tests: Numerical', () => { 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', + op: 'is empty', value: '', - rowCount: records.list.filter(r => r[dataType] === null).length, + rowCount: records.list.filter(r => r[dataType] === '').length, }, { - op: 'is not null', + op: 'is not empty', value: '', - rowCount: records.list.filter(r => r[dataType] !== null).length, + rowCount: records.list.filter(r => r[dataType] !== '').length, }, { op: 'is blank', value: '', - rowCount: records.list.filter(r => r[dataType] === null).length, + rowCount: records.list.filter(r => r[dataType] === '' || r[dataType] === null).length, }, { op: 'is not blank', value: '', - rowCount: records.list.filter(r => r[dataType] !== null).length, + rowCount: records.list.filter(r => r[dataType] !== '' && 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: 'is like', + value: isLikeString, + rowCount: records.list.filter(r => r[dataType]?.includes(isLikeString)).length, }, { - op: '<=', - value: '44', - rowCount: records.list.filter(r => r[dataType] <= 44 && r[dataType] != null).length, + op: 'is not like', + value: isLikeString, + rowCount: records.list.filter(r => !r[dataType]?.includes(isLikeString)).length, }, ]; for (let i = 0; i < filterList.length; i++) { + console.log(`${dataType} Filter: ${filterList[i].op} ${filterList[i].value}`); await verifyFilter({ column: dataType, opType: filterList[i].op, @@ -351,144 +313,97 @@ test.describe('Filter Tests: Numerical', () => { 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'; + test.beforeEach(async ({ page }) => { + context = await setup({ page }); + dashboard = new DashboardPage(page, context.project); + toolbar = dashboard.grid.toolbar; - 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, + api = new Api({ + baseURL: `http://localhost:8080/`, + headers: { + 'xc-auth': context.token, }, + }); + + const columns = [ { - op: 'is blank', - value: '', - rowCount: records.list.filter(r => r[dataType] === null).length, + column_name: 'Id', + title: 'Id', + uidt: UITypes.ID, }, { - op: 'is not blank', - value: '', - rowCount: records.list.filter(r => r[dataType] !== null).length, + column_name: 'SingleLineText', + title: 'SingleLineText', + uidt: UITypes.SingleLineText, }, { - op: '>', - value: '44.26', - rowCount: records.list.filter(r => r[dataType] > 44.26 && r[dataType] != null).length, + column_name: 'MultiLineText', + title: 'MultiLineText', + uidt: UITypes.LongText, }, { - op: '>=', - value: '44.26', - rowCount: records.list.filter(r => r[dataType] >= 44.26 && r[dataType] != null).length, + column_name: 'Email', + title: 'Email', + uidt: UITypes.Email, }, { - op: '<', - value: '44.26', - rowCount: records.list.filter(r => r[dataType] < 44.26 && r[dataType] != null).length, + column_name: 'PhoneNumber', + title: 'PhoneNumber', + uidt: UITypes.PhoneNumber, }, { - op: '<=', - value: '44.26', - rowCount: records.list.filter(r => r[dataType] <= 44.26 && r[dataType] != null).length, + column_name: 'URL', + title: 'URL', + uidt: UITypes.URL, }, ]; - 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 }, + 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: 'textBased', + title: 'textBased', + columns: columns, }); + + const rowAttributes = []; + for (let i = 0; i < 400; i++) { + const row = { + SingleLineText: rowMixedValue(columns[1], i), + MultiLineText: rowMixedValue(columns[2], i), + Email: rowMixedValue(columns[3], i), + PhoneNumber: rowMixedValue(columns[4], i), + URL: rowMixedValue(columns[5], 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: Rating', async () => { - // close 'Team & Auth' tab - await dashboard.closeTab({ title: 'Team & Auth' }); - await dashboard.treeView.openTable({ title: 'numberBased' }); - const dataType = 'Rating'; + test('Filter: Single Line Text', async () => { + await textBasedFilterTest('SingleLineText', 'Afghanistan', 'Au'); + }); - const filterList = [ - { - op: '=', - value: '3', - rowCount: records.list.filter(r => r[dataType] === 3).length, - }, - { - op: '!=', - value: '3', - rowCount: records.list.filter(r => r[dataType] !== 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: '2', - rowCount: records.list.filter(r => r[dataType] > 2 && r[dataType] != null).length, - }, - { - op: '>=', - value: '2', - rowCount: records.list.filter(r => r[dataType] >= 2 && r[dataType] != null).length, - }, - { - op: '<', - value: '2', - rowCount: records.list.filter(r => r[dataType] < 2 && r[dataType] != null).length, - }, - { - op: '<=', - value: '2', - rowCount: records.list.filter(r => r[dataType] <= 2 && r[dataType] != null).length, - }, - ]; + test('Filter: Long Text', async () => { + await textBasedFilterTest('MultiLineText', 'Aberdeen, United Kingdom', 'abad'); + }); - 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 }, - dataType: dataType, - }); - } + test('Filter: Email', async () => { + await textBasedFilterTest('Email', 'leota@hotmail.com', 'cox.net'); + }); + + test('Filter: PhoneNumber', async () => { + await textBasedFilterTest('PhoneNumber', '504-621-8927', '504'); + }); + + test('Filter: URL', async () => { + await textBasedFilterTest('URL', 'https://www.youtube.com', 'e.com'); }); });