From 485c5671ed725d0c64c2428ca8a9730986f455ad Mon Sep 17 00:00:00 2001 From: Raju Udava <86527202+dstala@users.noreply.github.com> Date: Thu, 23 Mar 2023 21:21:28 +0530 Subject: [PATCH] test: undo tests for link/unlink Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com> --- .../Dashboard/Grid/Column/LTAR/LinkRecord.ts | 1 + .../pages/Dashboard/common/Cell/index.ts | 2 +- tests/playwright/tests/undo-redo.spec.ts | 175 +++++++++++++++--- 3 files changed, 156 insertions(+), 22 deletions(-) diff --git a/tests/playwright/pages/Dashboard/Grid/Column/LTAR/LinkRecord.ts b/tests/playwright/pages/Dashboard/Grid/Column/LTAR/LinkRecord.ts index 7bc71f114b..56927eec1e 100644 --- a/tests/playwright/pages/Dashboard/Grid/Column/LTAR/LinkRecord.ts +++ b/tests/playwright/pages/Dashboard/Grid/Column/LTAR/LinkRecord.ts @@ -35,6 +35,7 @@ export class LinkRecord extends BasePage { } async select(cardTitle: string) { + await this.rootPage.waitForTimeout(100); await this.get().locator(`.ant-card:has-text("${cardTitle}"):visible`).click(); } diff --git a/tests/playwright/pages/Dashboard/common/Cell/index.ts b/tests/playwright/pages/Dashboard/common/Cell/index.ts index 0f95fc607b..f74d7ef50f 100644 --- a/tests/playwright/pages/Dashboard/common/Cell/index.ts +++ b/tests/playwright/pages/Dashboard/common/Cell/index.ts @@ -280,7 +280,7 @@ export class CellPageObject extends BasePage { async unlinkVirtualCell({ index, columnHeader }: CellProps) { const cell = this.get({ index, columnHeader }); await cell.click(); - await cell.locator('.nc-icon.unlink-icon').click(); + await cell.locator('.nc-icon.unlink-icon').first().click(); } async verifyRoleAccess(param: { role: string }) { diff --git a/tests/playwright/tests/undo-redo.spec.ts b/tests/playwright/tests/undo-redo.spec.ts index 5c534eff7c..246a59fe56 100644 --- a/tests/playwright/tests/undo-redo.spec.ts +++ b/tests/playwright/tests/undo-redo.spec.ts @@ -1,18 +1,40 @@ import { expect, Page, test } from '@playwright/test'; import { DashboardPage } from '../pages/Dashboard'; import setup from '../setup'; -import { ToolbarPage } from '../pages/Dashboard/common/Toolbar'; import { Api, UITypes } from 'nocodb-sdk'; import { rowMixedValue } from '../setup/xcdb-records'; import { GridPage } from '../pages/Dashboard/Grid'; -let dashboard: DashboardPage, grid: GridPage, context: any, api: Api, records: Record, table: any; +let dashboard: DashboardPage, + grid: GridPage, + context: any, + api: Api, + records: Record, + table: any, + cityTable: any, + countryTable: any; + +/** + This change provides undo/redo on multiple actions over UI. + + Scope Actions + ------------------------------ + Row Create, Update, Delete + LTAR Link, Unlink + Fields Show/hide, Reorder + Sort Add, Update, Delete + Filters Add, Update, Delete (Excluding Filter Groups) + Row Height Update + Column width Update + View Rename + Table Rename + + **/ test.describe('Undo Redo', () => { test.beforeEach(async ({ page }) => { context = await setup({ page, isEmptyProject: true }); dashboard = new DashboardPage(page, context.project); - const toolbar: ToolbarPage = dashboard.grid.toolbar; grid = dashboard.grid; api = new Api({ @@ -93,23 +115,6 @@ test.describe('Undo Redo', () => { await verifyRecords(values); } - /** - This change provides undo/redo on multiple actions over UI. - - Scope Actions - ------------------------------ - Row Create, Update, Delete - LTAR Link, Unlink - Fields Show/hide, Reorder - Sort Add, Update, Delete - Filters Add, Update, Delete (Excluding Filter Groups) - Row Height Update - Column width Update - View Rename - Table Rename - - **/ - test('Row: Create, Update, Delete', async ({ page }) => { await dashboard.closeTab({ title: 'Team & Auth' }); await dashboard.treeView.openTable({ title: 'numberBased' }); @@ -140,7 +145,135 @@ test.describe('Undo Redo', () => { // Undo : Row.Create await undo({ page, values: [333] }); await undo({ page, values: [] }); + }); +}); + +test.describe('Undo Redo - 2', () => { + test.beforeEach(async ({ page }) => { + context = await setup({ page, isEmptyProject: true }); + dashboard = new DashboardPage(page, context.project); + grid = dashboard.grid; + + api = new Api({ + baseURL: `http://localhost:8080/`, + headers: { + 'xc-auth': context.token, + }, + }); - console.log('records', records); + const cityColumns = [ + { + column_name: 'Id', + title: 'Id', + uidt: UITypes.ID, + }, + { + column_name: 'City', + title: 'City', + uidt: UITypes.SingleLineText, + pv: true, + }, + ]; + const countryColumns = [ + { + column_name: 'Id', + title: 'Id', + uidt: UITypes.ID, + }, + { + column_name: 'Country', + title: 'Country', + uidt: UITypes.SingleLineText, + pv: true, + }, + ]; + + try { + const project = await api.project.read(context.project.id); + cityTable = await api.base.tableCreate(context.project.id, project.bases?.[0].id, { + table_name: 'City', + title: 'City', + columns: cityColumns, + }); + countryTable = await api.base.tableCreate(context.project.id, project.bases?.[0].id, { + table_name: 'Country', + title: 'Country', + columns: countryColumns, + }); + + const cityRowAttributes = [{ City: 'Mumbai' }, { City: 'Pune' }, { City: 'Delhi' }, { City: 'Bangalore' }]; + await api.dbTableRow.bulkCreate('noco', context.project.id, cityTable.id, cityRowAttributes); + + const countryRowAttributes = [ + { Country: 'India' }, + { Country: 'USA' }, + { Country: 'UK' }, + { Country: 'Australia' }, + ]; + await api.dbTableRow.bulkCreate('noco', context.project.id, countryTable.id, countryRowAttributes); + + // create LTAR Country has-many City + await api.dbTableColumn.create(countryTable.id, { + column_name: 'CityList', + title: 'CityList', + uidt: UITypes.LinkToAnotherRecord, + parentId: countryTable.id, + childId: cityTable.id, + type: 'hm', + }); + + // await api.dbTableRow.nestedAdd('noco', context.project.id, countryTable.id, '1', 'hm', 'CityList', '1'); + } catch (e) { + console.log(e); + } + }); + + async function verifyRecords(values: any[] = []) { + // inserted values + const expectedValues = [...values]; + + const currentRecords: Record = await api.dbTableRow.list('noco', context.project.id, countryTable.id, { + fields: ['CityList'], + limit: 100, + }); + + // verify if expectedValues array includes all the values in currentRecords + // currentRecords [ { Id: 1, City: 'Mumbai' }, { Id: 3, City: 'Delhi' } ] + // expectedValues [ 'Mumbai', 'Delhi' ] + currentRecords.list[0].CityList.forEach((record: any) => { + expect(expectedValues).toContain(record.City); + }); + expect(currentRecords.list[0].CityList.length).toBe(expectedValues.length); + } + + async function undo({ page, values }: { page: Page; values: string[] }) { + const isMac = await grid.isMacOs(); + await dashboard.grid.waitForResponse({ + uiAction: () => page.keyboard.press(isMac ? 'Meta+z' : 'Control+z'), + httpMethodsToMatch: ['GET'], + requestUrlPathToMatch: `/api/v1/db/data/noco/`, + responseJsonMatcher: json => json.pageInfo, + }); + await verifyRecords(values); + } + + test('Row: Link, Unlink', async ({ page }) => { + await dashboard.closeTab({ title: 'Team & Auth' }); + await dashboard.treeView.openTable({ title: 'Country' }); + + await grid.cell.inCellAdd({ index: 0, columnHeader: 'CityList' }); + await dashboard.linkRecord.select('Mumbai'); + + await grid.cell.inCellAdd({ index: 0, columnHeader: 'CityList' }); + await dashboard.linkRecord.select('Delhi'); + + await grid.cell.unlinkVirtualCell({ index: 0, columnHeader: 'CityList' }); + await grid.cell.unlinkVirtualCell({ index: 0, columnHeader: 'CityList' }); + + await verifyRecords([]); + await undo({ page, values: ['Delhi'] }); + await undo({ page, values: ['Mumbai', 'Delhi'] }); + await undo({ page, values: ['Mumbai'] }); + await undo({ page, values: [] }); }); });