diff --git a/tests/playwright/pages/Dashboard/ProjectView/Audit.ts b/tests/playwright/pages/Dashboard/ProjectView/Audit.ts new file mode 100644 index 0000000000..c9482c0e5e --- /dev/null +++ b/tests/playwright/pages/Dashboard/ProjectView/Audit.ts @@ -0,0 +1,76 @@ +import { expect } from '@playwright/test'; +import BasePage from '../../Base'; +import { DataSourcePage } from './DataSourcePage'; + +export class AuditPage extends BasePage { + constructor(dataSource: DataSourcePage) { + super(dataSource.rootPage); + } + + get() { + return this.rootPage.locator('div.ant-modal-content'); + } + async verifyRow({ + index, + opType, + opSubtype, + description, + user, + created, + }: { + index: number; + opType?: string; + opSubtype?: string; + description?: string; + user?: string; + created?: string; + }) { + const table = this.get().locator('[data-testid="audit-tab-table"]'); + const row = table.locator(`tr.ant-table-row`).nth(index); + + if (opType) { + await row + .locator(`td.ant-table-cell`) + .nth(0) + .textContent() + .then(async text => expect(text).toContain(opType)); + } + + if (opSubtype) { + await row + .locator(`td.ant-table-cell`) + .nth(1) + .textContent() + .then(async text => expect(text).toContain(opSubtype)); + } + + if (description) { + await row + .locator(`td.ant-table-cell`) + .nth(2) + .textContent() + .then(async text => expect(text).toContain(description)); + } + + if (user) { + await row + .locator(`td.ant-table-cell`) + .nth(3) + .textContent() + .then(async text => expect(text).toContain(user)); + } + + if (created) { + await row + .locator(`td.ant-table-cell`) + .nth(4) + .textContent() + .then(async text => expect(text).toContain(created)); + } + } + + async close() { + await this.get().click(); + await this.rootPage.keyboard.press('Escape'); + } +} diff --git a/tests/playwright/pages/Dashboard/ProjectView/DataSourcePage.ts b/tests/playwright/pages/Dashboard/ProjectView/DataSourcePage.ts index d7274ae435..9ad71297f7 100644 --- a/tests/playwright/pages/Dashboard/ProjectView/DataSourcePage.ts +++ b/tests/playwright/pages/Dashboard/ProjectView/DataSourcePage.ts @@ -2,17 +2,20 @@ import BasePage from '../../Base'; import { ProjectViewPage } from './index'; import { Locator } from '@playwright/test'; import { MetaDataPage } from './Metadata'; +import { AuditPage } from './Audit'; export class DataSourcePage extends BasePage { readonly projectView: ProjectViewPage; readonly databaseType: Locator; readonly metaData: MetaDataPage; + readonly audit: AuditPage; constructor(projectView: ProjectViewPage) { super(projectView.rootPage); this.projectView = projectView; this.databaseType = this.get().locator('.nc-extdb-db-type'); this.metaData = new MetaDataPage(this); + this.audit = new AuditPage(this); } get() { @@ -40,13 +43,18 @@ export class DataSourcePage extends BasePage { } async openERD({ rowIndex }: { rowIndex: number }) { - // hardwired - // await this.rootPage.locator('button.nc-action-btn:has-text("Relations")').click(); - // 0th offset for header const row = this.get() .locator('.ds-table-row') .nth(rowIndex + 1); await row.locator('button.nc-action-btn:has-text("Relations")').click(); } + + async openAudit({ rowIndex }: { rowIndex: number }) { + // 0th offset for header + const row = this.get() + .locator('.ds-table-row') + .nth(rowIndex + 1); + await row.locator('button.nc-action-btn:has-text("Audit")').click(); + } } diff --git a/tests/playwright/tests/db/general/tableOperations.spec.ts b/tests/playwright/tests/db/general/tableOperations.spec.ts index 38661f68b1..96d5086976 100644 --- a/tests/playwright/tests/db/general/tableOperations.spec.ts +++ b/tests/playwright/tests/db/general/tableOperations.spec.ts @@ -1,20 +1,20 @@ import { expect, test } from '@playwright/test'; import { Api, TableListType, TableType } from 'nocodb-sdk'; import { DashboardPage } from '../../../pages/Dashboard'; -import { SettingsPage, SettingTab } from '../../../pages/Dashboard/Settings'; import { deepCompare } from '../../../tests/utils/objectCompareUtil'; import setup, { unsetup } from '../../../setup'; import { ProjectInfoApiUtil, TableInfo } from '../../../tests/utils/projectInfoApiUtil'; import { isEE } from '../../../setup/db'; +import { AuditPage } from '../../../pages/Dashboard/ProjectView/Audit'; test.describe('Table Operations', () => { - let dashboard: DashboardPage, settings: SettingsPage; + let dashboard: DashboardPage, audit: AuditPage; let context: any; test.beforeEach(async ({ page }) => { context = await setup({ page, isEmptyProject: false }); dashboard = new DashboardPage(page, context.project); - settings = dashboard.settings; + audit = dashboard.projectView.dataSources.audit; }); test.afterEach(async () => { @@ -30,21 +30,24 @@ test.describe('Table Operations', () => { if (!isEE()) { // Audit logs in clickhouse; locally wont be accessible - await dashboard.gotoSettings(); - await settings.selectTab({ tab: SettingTab.Audit }); - await settings.audit.verifyRow({ + + await dashboard.treeView.openProject({ title: context.project.title }); + await dashboard.projectView.tab_dataSources.click(); + await dashboard.projectView.dataSources.openAudit({ rowIndex: 0 }); + + await audit.verifyRow({ index: 0, opType: 'TABLE', opSubtype: 'DELETE', - user: 'user@nocodb.com', + user: `user-${process.env.TEST_PARALLEL_INDEX}@nocodb.com`, }); - await settings.audit.verifyRow({ + await audit.verifyRow({ index: 1, opType: 'TABLE', opSubtype: 'CREATE', - user: 'user@nocodb.com', + user: `user-${process.env.TEST_PARALLEL_INDEX}@nocodb.com`, }); - await settings.close(); + await audit.close(); } await dashboard.treeView.renameTable({ title: 'City', newTitle: 'Cityx' });