diff --git a/packages/nc-gui/components/virtual-cell/components/ItemChip.vue b/packages/nc-gui/components/virtual-cell/components/ItemChip.vue
index 1202bd19a3..ebe49c6b16 100644
--- a/packages/nc-gui/components/virtual-cell/components/ItemChip.vue
+++ b/packages/nc-gui/components/virtual-cell/components/ItemChip.vue
@@ -65,7 +65,7 @@ export default {
diff --git a/tests/playwright/pages/Account/Users.ts b/tests/playwright/pages/Account/Users.ts
index 1618c98b6e..9b6bbdd854 100644
--- a/tests/playwright/pages/Account/Users.ts
+++ b/tests/playwright/pages/Account/Users.ts
@@ -36,7 +36,8 @@ export class AccountUsersPage extends BasePage {
await this.inviteUserModal.locator(`button:has-text("Invite")`).click();
await this.verifyToast({ message: 'Successfully added user' });
- return await this.inviteUserModal.locator(`.ant-alert-message`).innerText();
+ // http://localhost:3000/#/signup/a5e7bf3a-cbb0-46bc-87f7-c2ae21796707
+ return (await this.inviteUserModal.locator(`.ant-alert-message`).innerText()).slice(0, 67);
}
prefixEmail(email: string) {
diff --git a/tests/playwright/pages/Dashboard/Grid/Column/SelectOptionColumn.ts b/tests/playwright/pages/Dashboard/Grid/Column/SelectOptionColumn.ts
index a05fcd166b..5d1d63e995 100644
--- a/tests/playwright/pages/Dashboard/Grid/Column/SelectOptionColumn.ts
+++ b/tests/playwright/pages/Dashboard/Grid/Column/SelectOptionColumn.ts
@@ -60,7 +60,7 @@ export class SelectOptionColumnPageObject extends BasePage {
async deleteOption({ columnTitle, index }: { index: number; columnTitle: string }) {
await this.column.openEdit({ title: columnTitle });
- await this.column.get().locator(`svg[data-testid="select-column-option-remove-${index}"]`).click();
+ await this.column.get().locator(`[data-testid="select-column-option-remove-${index}"]`).click();
await expect(this.column.get().getByTestId(`select-column-option-${index}`)).toHaveClass(/removed/);
@@ -70,11 +70,11 @@ export class SelectOptionColumnPageObject extends BasePage {
async deleteOptionWithUndo({ columnTitle, index }: { index: number; columnTitle: string }) {
await this.column.openEdit({ title: columnTitle });
- await this.column.get().locator(`svg[data-testid="select-column-option-remove-${index}"]`).click();
+ await this.column.get().locator(`[data-testid="select-column-option-remove-${index}"]`).click();
await expect(this.column.get().getByTestId(`select-column-option-${index}`)).toHaveClass(/removed/);
- await this.column.get().locator(`svg[data-testid="select-column-option-remove-undo-${index}"]`).click();
+ await this.column.get().locator(`[data-testid="select-column-option-remove-undo-${index}"]`).click();
await expect(this.column.get().getByTestId(`select-column-option-${index}`)).not.toHaveClass(/removed/);
@@ -95,8 +95,8 @@ export class SelectOptionColumnPageObject extends BasePage {
await this.column.rootPage.waitForTimeout(150);
await this.column.rootPage.dragAndDrop(
- `svg[data-testid="select-option-column-handle-icon-${sourceOption}"]`,
- `svg[data-testid="select-option-column-handle-icon-${destinationOption}"]`,
+ `[data-testid="select-option-column-handle-icon-${sourceOption}"]`,
+ `[data-testid="select-option-column-handle-icon-${destinationOption}"]`,
{
force: true,
}
diff --git a/tests/playwright/pages/Dashboard/Grid/Column/index.ts b/tests/playwright/pages/Dashboard/Grid/Column/index.ts
index 9c902566bc..3ca90f1f5d 100644
--- a/tests/playwright/pages/Dashboard/Grid/Column/index.ts
+++ b/tests/playwright/pages/Dashboard/Grid/Column/index.ts
@@ -3,6 +3,7 @@ import { GridPage } from '..';
import BasePage from '../../../Base';
import { SelectOptionColumnPageObject } from './SelectOptionColumn';
import { AttachmentColumnPageObject } from './Attachment';
+import { getTextExcludeIconText } from '../../../../tests/utils/general';
export class ColumnPageObject extends BasePage {
readonly grid: GridPage;
@@ -181,28 +182,23 @@ export class ColumnPageObject extends BasePage {
await this.save();
+ const headersText = [];
+ const locator = this.grid.get().locator(`th`);
+ const count = await locator.count();
+ for (let i = 0; i < count; i++) {
+ const header = locator.nth(i);
+ const text = await getTextExcludeIconText(header);
+ headersText.push(text);
+ }
+
// verify column inserted after the target column
if (insertAfterColumnTitle) {
- const headersText = await this.grid.get().locator(`th`).allTextContents();
-
- await expect(
- this.grid
- .get()
- .locator(`th`)
- .nth(headersText.findIndex(title => title.startsWith(insertAfterColumnTitle)) + 1)
- ).toHaveText(title);
+ expect(headersText[headersText.findIndex(title => title.startsWith(insertAfterColumnTitle)) + 1]).toBe(title);
}
// verify column inserted before the target column
if (insertBeforeColumnTitle) {
- const headersText = await this.grid.get().locator(`th`).allTextContents();
-
- await expect(
- this.grid
- .get()
- .locator(`th`)
- .nth(headersText.findIndex(title => title.startsWith(insertBeforeColumnTitle)) - 1)
- ).toHaveText(title);
+ expect(headersText[headersText.findIndex(title => title.startsWith(insertBeforeColumnTitle)) - 1]).toBe(title);
}
}
@@ -254,7 +250,7 @@ export class ColumnPageObject extends BasePage {
}
async delete({ title }: { title: string }) {
- await this.getColumnHeader(title).locator('svg.ant-dropdown-trigger').click();
+ await this.getColumnHeader(title).locator('div.ant-dropdown-trigger').locator('.nc-ui-dt-dropdown').click();
// await this.rootPage.locator('li[role="menuitem"]:has-text("Delete")').waitFor();
await this.rootPage.locator('li[role="menuitem"]:has-text("Delete")').click();
diff --git a/tests/playwright/pages/Dashboard/Import/ImportTemplate.ts b/tests/playwright/pages/Dashboard/Import/ImportTemplate.ts
index 9db97b3318..bc9afbfb4f 100644
--- a/tests/playwright/pages/Dashboard/Import/ImportTemplate.ts
+++ b/tests/playwright/pages/Dashboard/Import/ImportTemplate.ts
@@ -1,6 +1,7 @@
import { expect, Locator } from '@playwright/test';
import BasePage from '../../Base';
import { DashboardPage } from '..';
+import { getTextExcludeIconText } from '../../../tests/utils/general';
export class ImportTemplatePage extends BasePage {
readonly dashboard: DashboardPage;
@@ -22,7 +23,7 @@ export class ImportTemplatePage extends BasePage {
const rowCount = await tr.count();
const tableList: string[] = [];
for (let i = 0; i < rowCount; i++) {
- const tableName = await tr.nth(i).innerText();
+ const tableName = await getTextExcludeIconText(tr.nth(i));
tableList.push(tableName);
}
return tableList;
@@ -35,10 +36,7 @@ export class ImportTemplatePage extends BasePage {
const rowCount = await tr.count();
for (let i = 0; i < rowCount; i++) {
// replace \n and \t from innerText
- const columnType = await tr
- .nth(i)
- .innerText()
- .then(text => text.replace(/\n|\t/g, ''));
+ const columnType = (await getTextExcludeIconText(tr.nth(i))).replace(/\n|\t/g, '');
const columnName = await tr.nth(i).locator(`input[type="text"]`).inputValue();
columnList.push({ type: columnType, name: columnName });
}
diff --git a/tests/playwright/pages/Dashboard/Settings/Metadata.ts b/tests/playwright/pages/Dashboard/Settings/Metadata.ts
index 803e6dfb65..b93c629a1d 100644
--- a/tests/playwright/pages/Dashboard/Settings/Metadata.ts
+++ b/tests/playwright/pages/Dashboard/Settings/Metadata.ts
@@ -1,6 +1,7 @@
import { expect } from '@playwright/test';
import BasePage from '../../Base';
import { DataSourcesPage } from './DataSources';
+import { getTextExcludeIconText } from '../../../tests/utils/general';
export class MetaDataPage extends BasePage {
private readonly dataSources: DataSourcesPage;
@@ -31,12 +32,10 @@ export class MetaDataPage extends BasePage {
}
async verifyRow({ index, model, state }: { index: number; model: string; state: string }) {
- await expect(this.get().locator(`tr.ant-table-row`).nth(index).locator(`td.ant-table-cell`).nth(0)).toHaveText(
- model,
- {
- ignoreCase: true,
- }
- );
+ const fieldLocator = await this.get().locator(`tr.ant-table-row`).nth(index).locator(`td.ant-table-cell`).nth(0);
+ const fieldText = await getTextExcludeIconText(fieldLocator);
+ await expect(fieldText).toBe(model);
+
await expect(this.get().locator(`tr.ant-table-row`).nth(index).locator(`td.ant-table-cell`).nth(1)).toHaveText(
state,
{
diff --git a/tests/playwright/pages/Dashboard/Settings/Teams.ts b/tests/playwright/pages/Dashboard/Settings/Teams.ts
index 0bc59edaef..34bf61a5c3 100644
--- a/tests/playwright/pages/Dashboard/Settings/Teams.ts
+++ b/tests/playwright/pages/Dashboard/Settings/Teams.ts
@@ -44,7 +44,8 @@ export class TeamsPage extends BasePage {
await this.inviteTeamModal.locator(`button:has-text("Invite")`).click();
await this.verifyToast({ message: 'Successfully updated the user details' });
- return await this.inviteTeamModal.locator(`.ant-alert-message`).innerText();
+ // http://localhost:3000/#/signup/a5e7bf3a-cbb0-46bc-87f7-c2ae21796707
+ return (await this.inviteTeamModal.locator(`.ant-alert-message`).innerText()).slice(0, 67);
}
async closeInvite() {
diff --git a/tests/playwright/pages/Dashboard/SurveyForm/index.ts b/tests/playwright/pages/Dashboard/SurveyForm/index.ts
index 5e1067ecf2..87d3b8d789 100644
--- a/tests/playwright/pages/Dashboard/SurveyForm/index.ts
+++ b/tests/playwright/pages/Dashboard/SurveyForm/index.ts
@@ -1,5 +1,6 @@
import { expect, Locator, Page } from '@playwright/test';
import BasePage from '../../Base';
+import { getTextExcludeIconText } from '../../../tests/utils/general';
export class SurveyFormPage extends BasePage {
readonly formHeading: Locator;
@@ -42,7 +43,15 @@ export class SurveyFormPage extends BasePage {
await expect(this.formHeading).toHaveText(heading);
await expect(this.formSubHeading).toHaveText(subHeading);
await expect(this.formFooter).toHaveText(footer);
- await expect(this.get().locator(`[data-testid="nc-form-column-label"]`)).toHaveText(fieldLabel);
+
+ const locator = this.get().locator(`[data-testid="nc-form-column-label"]`);
+ let fieldText = await getTextExcludeIconText(locator);
+
+ // replace whitespace with ' ' for fieldLabel & fieldText
+ fieldLabel = fieldLabel.replace(/\u00A0/g, ' ');
+ fieldText = fieldText.replace(/\u00A0/g, ' ');
+
+ await expect(fieldText).toBe(fieldLabel);
// parse footer text ("1 / 3") to identify if last slide
let isLastSlide = false;
@@ -73,6 +82,9 @@ export class SurveyFormPage extends BasePage {
await modal.locator('.ant-picker-ok').click();
await this.nextButton.click();
}
+
+ // post next button click, allow transitions to complete
+ await this.rootPage.waitForTimeout(100);
}
async validateSuccessMessage(param: { message: string; showAnotherForm?: boolean }) {
diff --git a/tests/playwright/pages/Dashboard/TreeView.ts b/tests/playwright/pages/Dashboard/TreeView.ts
index 7caa2d0f3d..9cc622b461 100644
--- a/tests/playwright/pages/Dashboard/TreeView.ts
+++ b/tests/playwright/pages/Dashboard/TreeView.ts
@@ -39,7 +39,7 @@ export class TreeViewPage extends BasePage {
async openTable({
title,
mode = 'standard',
- networkResponse = true,
+ networkResponse = false,
mobileMode = false,
}: {
title: string;
diff --git a/tests/playwright/pages/Dashboard/ViewSidebar/index.ts b/tests/playwright/pages/Dashboard/ViewSidebar/index.ts
index 0823c8763d..4cc1f9e445 100644
--- a/tests/playwright/pages/Dashboard/ViewSidebar/index.ts
+++ b/tests/playwright/pages/Dashboard/ViewSidebar/index.ts
@@ -86,6 +86,13 @@ export class ViewSidebarPage extends BasePage {
// Todo: Make selection better
async verifyView({ title, index }: { title: string; index: number }) {
+ // flicker while page loading
+ await this.get()
+ .locator('[data-testid="view-item"]')
+ .nth(index)
+ .locator('[data-testid="truncate-label"]')
+ .waitFor({ state: 'visible' });
+
await expect(
this.get().locator('[data-testid="view-item"]').nth(index).locator('[data-testid="truncate-label"]')
).toHaveText(title, { ignoreCase: true });
diff --git a/tests/playwright/pages/Dashboard/WebhookForm/index.ts b/tests/playwright/pages/Dashboard/WebhookForm/index.ts
index 2a1aea22fa..3a203fe1b6 100644
--- a/tests/playwright/pages/Dashboard/WebhookForm/index.ts
+++ b/tests/playwright/pages/Dashboard/WebhookForm/index.ts
@@ -2,6 +2,7 @@ import { expect, Locator } from '@playwright/test';
import BasePage from '../../Base';
import { DashboardPage } from '..';
import { ToolbarPage } from '../common/Toolbar';
+import { getTextExcludeIconText } from '../../../tests/utils/general';
export class WebhookFormPage extends BasePage {
readonly dashboard: DashboardPage;
@@ -181,9 +182,11 @@ export class WebhookFormPage extends BasePage {
}) {
await expect.poll(async () => await this.get().locator('input.nc-text-field-hook-title').inputValue()).toBe(title);
await expect(this.get().locator('.nc-text-field-hook-event >> .ant-select-selection-item')).toHaveText(hookEvent);
- await expect(this.get().locator('.nc-select-hook-notification-type >> .ant-select-selection-item')).toHaveText(
- notificationType
- );
+
+ const locator = this.get().locator('.nc-select-hook-notification-type >> .ant-select-selection-item');
+ const text = await getTextExcludeIconText(locator);
+ await expect(text).toBe(notificationType);
+
await expect(this.get().locator('.nc-select-hook-url-method >> .ant-select-selection-item')).toHaveText(urlMethod);
await expect.poll(async () => await this.get().locator('input.nc-text-field-hook-url-path').inputValue()).toBe(url);
diff --git a/tests/playwright/pages/Dashboard/common/Cell/index.ts b/tests/playwright/pages/Dashboard/common/Cell/index.ts
index 23f9b0d0b1..0f95fc607b 100644
--- a/tests/playwright/pages/Dashboard/common/Cell/index.ts
+++ b/tests/playwright/pages/Dashboard/common/Cell/index.ts
@@ -273,7 +273,7 @@ export class CellPageObject extends BasePage {
// verify only the elements that are passed in
for (let i = 0; i < value.length; ++i) {
- await expect(await chips.nth(i)).toHaveText(value[i]);
+ await expect(await chips.nth(i).locator('.name')).toHaveText(value[i]);
}
}
@@ -292,6 +292,7 @@ export class CellPageObject extends BasePage {
// press escape to close the input
await cell.press('Escape');
+ await cell.press('Escape');
await cell.click({ button: 'right', clickCount: 1 });
await expect(await this.rootPage.locator(`.nc-dropdown-grid-context-menu:visible`)).toHaveCount(
diff --git a/tests/playwright/pages/Dashboard/common/Toolbar/Actions/index.ts b/tests/playwright/pages/Dashboard/common/Toolbar/Actions/index.ts
index 86b093cdef..a9286d0d65 100644
--- a/tests/playwright/pages/Dashboard/common/Toolbar/Actions/index.ts
+++ b/tests/playwright/pages/Dashboard/common/Toolbar/Actions/index.ts
@@ -18,10 +18,10 @@ export class ToolbarActionsPage extends BasePage {
// todo: use enum
async click(label: string) {
- await this.get().locator(`span:has-text("${label}")`).click();
+ await this.get().locator(`span:has-text("${label}")`).first().click();
}
async clickDownloadSubmenu(label: string) {
- await this.rootPage.locator(`div[class="nc-project-menu-item"]:has-text("${label}")`).click();
+ await this.rootPage.locator(`div[class="nc-project-menu-item"]:has-text("${label}")`).first().click();
}
}
diff --git a/tests/playwright/pages/Dashboard/common/Toolbar/Filter.ts b/tests/playwright/pages/Dashboard/common/Toolbar/Filter.ts
index ee69da6728..285898a0e5 100644
--- a/tests/playwright/pages/Dashboard/common/Toolbar/Filter.ts
+++ b/tests/playwright/pages/Dashboard/common/Toolbar/Filter.ts
@@ -2,6 +2,7 @@ import { expect } from '@playwright/test';
import BasePage from '../../../Base';
import { ToolbarPage } from './index';
import { UITypes } from 'nocodb-sdk';
+import { getTextExcludeIconText } from '../../../../tests/utils/general';
export class ToolbarFilterPage extends BasePage {
readonly toolbar: ToolbarPage;
@@ -16,7 +17,10 @@ export class ToolbarFilterPage extends BasePage {
}
async verify({ index, column, operator, value }: { index: number; column: string; operator: string; value: string }) {
- await expect(this.get().locator('.nc-filter-field-select').nth(index)).toHaveText(column);
+ const fieldLocator = await this.get().locator('.nc-filter-field-select').nth(index);
+ const fieldText = await getTextExcludeIconText(fieldLocator);
+ await expect(fieldText).toBe(column);
+
await expect(this.get().locator('.nc-filter-operation-select').nth(index)).toHaveText(operator);
await expect
.poll(async () => await this.get().locator('.nc-filter-value-select > input').nth(index).inputValue())
diff --git a/tests/playwright/pages/Dashboard/common/Toolbar/ShareView.ts b/tests/playwright/pages/Dashboard/common/Toolbar/ShareView.ts
index d28de9a9c3..816d0e6538 100644
--- a/tests/playwright/pages/Dashboard/common/Toolbar/ShareView.ts
+++ b/tests/playwright/pages/Dashboard/common/Toolbar/ShareView.ts
@@ -1,5 +1,6 @@
import BasePage from '../../../Base';
import { ToolbarPage } from './index';
+import { getTextExcludeIconText } from '../../../../tests/utils/general';
export class ToolbarShareViewPage extends BasePage {
readonly toolbar: ToolbarPage;
@@ -29,7 +30,9 @@ export class ToolbarShareViewPage extends BasePage {
}
async getShareLink() {
- return await this.get().locator(`[data-testid="nc-modal-share-view__link"]`).innerText();
+ const locator = this.get().locator(`[data-testid="nc-modal-share-view__link"]`);
+ const linkText = getTextExcludeIconText(locator);
+ return linkText;
}
async close() {
diff --git a/tests/playwright/pages/Dashboard/common/Toolbar/Sort.ts b/tests/playwright/pages/Dashboard/common/Toolbar/Sort.ts
index 7da27ba7fe..d006d46818 100644
--- a/tests/playwright/pages/Dashboard/common/Toolbar/Sort.ts
+++ b/tests/playwright/pages/Dashboard/common/Toolbar/Sort.ts
@@ -1,6 +1,7 @@
import { expect } from '@playwright/test';
import BasePage from '../../../Base';
import { ToolbarPage } from './index';
+import { getTextExcludeIconText } from '../../../../tests/utils/general';
export class ToolbarSortPage extends BasePage {
readonly toolbar: ToolbarPage;
@@ -15,7 +16,10 @@ export class ToolbarSortPage extends BasePage {
}
async verify({ index, column, direction }: { index: number; column: string; direction: string }) {
- await expect(this.get().locator('.nc-sort-field-select').nth(index)).toHaveText(column);
+ const fieldLocator = await this.get().locator('.nc-sort-field-select').nth(index);
+ const fieldText = await getTextExcludeIconText(fieldLocator);
+ await expect(fieldText).toBe(column);
+
await expect(
await this.get().locator('.nc-sort-dir-select >> span.ant-select-selection-item').nth(index)
).toHaveText(direction);
diff --git a/tests/playwright/pages/Dashboard/common/Toolbar/ViewMenu.ts b/tests/playwright/pages/Dashboard/common/Toolbar/ViewMenu.ts
index 508e958be9..071685c6fe 100644
--- a/tests/playwright/pages/Dashboard/common/Toolbar/ViewMenu.ts
+++ b/tests/playwright/pages/Dashboard/common/Toolbar/ViewMenu.ts
@@ -141,7 +141,7 @@ export class ToolbarViewMenuPage extends BasePage {
await expect(await this.toolbar.get().locator(`.nc-filter-menu-btn.nc-toolbar-btn`)).toBeDisabled();
await expect(await this.toolbar.get().locator(`.nc-sort-menu-btn.nc-toolbar-btn`)).toBeDisabled();
await expect(
- await this.toolbar.get().locator(`.nc-add-new-row-btn.nc-toolbar-btn > .nc-icon.disabled`)
+ await this.toolbar.get().locator(`.nc-add-new-row-btn.nc-toolbar-btn > .material-symbols-outlined.disabled`)
).toBeVisible();
await (this.toolbar.parent as GridPage).verifyEditDisabled({
@@ -153,7 +153,9 @@ export class ToolbarViewMenuPage extends BasePage {
await expect(await this.toolbar.get().locator(`.nc-fields-menu-btn.nc-toolbar-btn`)).toBeEnabled();
await expect(await this.toolbar.get().locator(`.nc-filter-menu-btn.nc-toolbar-btn`)).toBeEnabled();
await expect(await this.toolbar.get().locator(`.nc-sort-menu-btn.nc-toolbar-btn`)).toBeEnabled();
- await expect(await this.toolbar.get().locator(`.nc-add-new-row-btn.nc-toolbar-btn > .nc-icon`)).toBeVisible();
+ await expect(
+ await this.toolbar.get().locator(`.nc-add-new-row-btn.nc-toolbar-btn > .material-symbols-outlined`)
+ ).toBeVisible();
await (this.toolbar.parent as GridPage).verifyEditEnabled({
columnHeader: 'Country',
diff --git a/tests/playwright/pages/Dashboard/common/Toolbar/index.ts b/tests/playwright/pages/Dashboard/common/Toolbar/index.ts
index 99f79e4364..6f756f21f1 100644
--- a/tests/playwright/pages/Dashboard/common/Toolbar/index.ts
+++ b/tests/playwright/pages/Dashboard/common/Toolbar/index.ts
@@ -16,6 +16,7 @@ import { ToolbarAddEditStackPage } from './AddEditKanbanStack';
import { ToolbarSearchDataPage } from './SearchData';
import { RowHeight } from './RowHeight';
import { MapPage } from '../../Map';
+import { getTextExcludeIconText } from '../../../../tests/utils/general';
export class ToolbarPage extends BasePage {
readonly parent: GridPage | GalleryPage | FormPage | KanbanPage | MapPage;
@@ -82,14 +83,26 @@ export class ToolbarPage extends BasePage {
async verifyFieldsButtonIsVisibleWithTextAndIcon() {
await expect(this.get().locator(`button.nc-fields-menu-btn`)).toBeVisible();
- await expect(this.get().locator(`button.nc-fields-menu-btn`)).toHaveText('Fields');
- expect(await this.get().locator(`button.nc-fields-menu-btn`).locator(`svg`).count()).toBe(2);
+
+ // menu text
+ const fieldLocator = await this.get().locator(`button.nc-fields-menu-btn`);
+ const fieldText = await getTextExcludeIconText(fieldLocator);
+ await expect(fieldText).toBe('Fields');
+
+ // icons count within fields menu button
+ expect(await this.get().locator(`button.nc-fields-menu-btn`).locator(`.material-symbols-outlined`).count()).toBe(2);
}
async verifyFieldsButtonIsVisibleWithoutTextButIcon() {
await expect(this.get().locator(`button.nc-fields-menu-btn`)).toBeVisible();
- await expect(this.get().locator(`button.nc-fields-menu-btn`)).not.toHaveText('Fields');
- expect(await this.get().locator(`button.nc-fields-menu-btn`).locator(`svg`).count()).toBe(2);
+
+ // menu text
+ const fieldLocator = await this.get().locator(`button.nc-fields-menu-btn`);
+ const fieldText = await getTextExcludeIconText(fieldLocator);
+ await expect(fieldText).not.toBe('Fields');
+
+ // icons count within fields menu button
+ expect(await this.get().locator(`button.nc-fields-menu-btn`).locator(`.material-symbols-outlined`).count()).toBe(2);
}
async clickFilter({
diff --git a/tests/playwright/tests/columnLinkToAnotherRecord.spec.ts b/tests/playwright/tests/columnLinkToAnotherRecord.spec.ts
index 1b7f53c999..dd74bf0fd4 100644
--- a/tests/playwright/tests/columnLinkToAnotherRecord.spec.ts
+++ b/tests/playwright/tests/columnLinkToAnotherRecord.spec.ts
@@ -43,7 +43,7 @@ test.describe('LTAR create & update', () => {
});
await dashboard.closeTab({ title: 'Sheet1' });
- await dashboard.treeView.openTable({ title: 'Sheet2' });
+ await dashboard.treeView.openTable({ title: 'Sheet2', networkResponse: false });
await dashboard.grid.column.create({
title: 'Link2-1hm',
type: 'LinkToAnotherRecord',
@@ -116,6 +116,9 @@ test.describe('LTAR create & update', () => {
value: '2c',
type: 'text',
});
+
+ await dashboard.rootPage.waitForTimeout(1000);
+
await dashboard.expandedForm.save();
const expected = [
diff --git a/tests/playwright/tests/columnMenuOperations.spec.ts b/tests/playwright/tests/columnMenuOperations.spec.ts
index 01a4e016bf..429d9cf5d7 100644
--- a/tests/playwright/tests/columnMenuOperations.spec.ts
+++ b/tests/playwright/tests/columnMenuOperations.spec.ts
@@ -66,6 +66,7 @@ test.describe('Column menu operations', () => {
}
await dashboard.closeTab({ title: 'Film' });
});
+
test('Insert after', async () => {
await dashboard.treeView.openTable({ title: 'Film' });
diff --git a/tests/playwright/tests/filters.spec.ts b/tests/playwright/tests/filters.spec.ts
index 2bc6b30f64..95d29c5e4b 100644
--- a/tests/playwright/tests/filters.spec.ts
+++ b/tests/playwright/tests/filters.spec.ts
@@ -668,7 +668,7 @@ test.describe('Filter Tests: Date based', () => {
const oneYearAgo = new Date(new Date().setFullYear(new Date().getFullYear() - 1)).setHours(0, 0, 0, 0);
const oneYearFromNow = new Date(new Date().setFullYear(new Date().getFullYear() + 1)).setHours(0, 0, 0, 0);
- async function dateTimeBasedFilterTest(dataType) {
+ async function dateTimeBasedFilterTest(dataType, setCount) {
await dashboard.closeTab({ title: 'Team & Auth' });
await dashboard.treeView.openTable({ title: 'dateTimeBased' });
@@ -829,100 +829,102 @@ test.describe('Filter Tests: Date based', () => {
await toolbar.clickFilter();
await toolbar.filter.clickAddFilter();
- // "is" filter list
- for (let i = 0; i < isFilterList.length; i++) {
- await verifyFilter_withFixedModal({
- column: dataType,
- opType: 'is',
- opSubType: isFilterList[i].opSub,
- value: isFilterList[i]?.value?.toString() || '',
- result: { rowCount: isFilterList[i].rowCount },
- dataType: dataType,
- });
- }
-
- // mutually exclusive of "is" filter list
- for (let i = 0; i < isFilterList.length; i++) {
- await verifyFilter_withFixedModal({
- column: dataType,
- opType: 'is not',
- opSubType: isFilterList[i].opSub,
- value: isFilterList[i]?.value?.toString() || '',
- result: { rowCount: 800 - isFilterList[i].rowCount },
- dataType: dataType,
- });
- }
+ if (setCount === 0) {
+ // "is" filter list
+ for (let i = 0; i < isFilterList.length; i++) {
+ await verifyFilter_withFixedModal({
+ column: dataType,
+ opType: 'is',
+ opSubType: isFilterList[i].opSub,
+ value: isFilterList[i]?.value?.toString() || '',
+ result: { rowCount: isFilterList[i].rowCount },
+ dataType: dataType,
+ });
+ }
- // "is before" filter list
- for (let i = 0; i < isAfterFilterList.length; i++) {
- await verifyFilter_withFixedModal({
- column: dataType,
- opType: 'is before',
- opSubType: isAfterFilterList[i].opSub,
- value: isAfterFilterList[i]?.value?.toString() || '',
- result: { rowCount: 800 - isAfterFilterList[i].rowCount - 1 },
- dataType: dataType,
- });
- }
+ // mutually exclusive of "is" filter list
+ for (let i = 0; i < isFilterList.length; i++) {
+ await verifyFilter_withFixedModal({
+ column: dataType,
+ opType: 'is not',
+ opSubType: isFilterList[i].opSub,
+ value: isFilterList[i]?.value?.toString() || '',
+ result: { rowCount: 800 - isFilterList[i].rowCount },
+ dataType: dataType,
+ });
+ }
- // "is on or before" filter list
- for (let i = 0; i < isAfterFilterList.length; i++) {
- await verifyFilter_withFixedModal({
- column: dataType,
- opType: 'is on or before',
- opSubType: isAfterFilterList[i].opSub,
- value: isAfterFilterList[i]?.value?.toString() || '',
- result: { rowCount: 800 - isAfterFilterList[i].rowCount },
- dataType: dataType,
- });
- }
+ // "is before" filter list
+ for (let i = 0; i < isAfterFilterList.length; i++) {
+ await verifyFilter_withFixedModal({
+ column: dataType,
+ opType: 'is before',
+ opSubType: isAfterFilterList[i].opSub,
+ value: isAfterFilterList[i]?.value?.toString() || '',
+ result: { rowCount: 800 - isAfterFilterList[i].rowCount - 1 },
+ dataType: dataType,
+ });
+ }
+ } else {
+ // "is on or before" filter list
+ for (let i = 0; i < isAfterFilterList.length; i++) {
+ await verifyFilter_withFixedModal({
+ column: dataType,
+ opType: 'is on or before',
+ opSubType: isAfterFilterList[i].opSub,
+ value: isAfterFilterList[i]?.value?.toString() || '',
+ result: { rowCount: 800 - isAfterFilterList[i].rowCount },
+ dataType: dataType,
+ });
+ }
- // "is after" filter list
- for (let i = 0; i < isAfterFilterList.length; i++) {
- await verifyFilter_withFixedModal({
- column: dataType,
- opType: 'is after',
- opSubType: isAfterFilterList[i].opSub,
- value: isAfterFilterList[i]?.value?.toString() || '',
- result: { rowCount: isAfterFilterList[i].rowCount },
- dataType: dataType,
- });
- }
+ // "is after" filter list
+ for (let i = 0; i < isAfterFilterList.length; i++) {
+ await verifyFilter_withFixedModal({
+ column: dataType,
+ opType: 'is after',
+ opSubType: isAfterFilterList[i].opSub,
+ value: isAfterFilterList[i]?.value?.toString() || '',
+ result: { rowCount: isAfterFilterList[i].rowCount },
+ dataType: dataType,
+ });
+ }
- // "is on or after" filter list
- for (let i = 0; i < isAfterFilterList.length; i++) {
- await verifyFilter_withFixedModal({
- column: dataType,
- opType: 'is on or after',
- opSubType: isAfterFilterList[i].opSub,
- value: isAfterFilterList[i]?.value?.toString() || '',
- result: { rowCount: 1 + isAfterFilterList[i].rowCount },
- dataType: dataType,
- });
- }
+ // "is on or after" filter list
+ for (let i = 0; i < isAfterFilterList.length; i++) {
+ await verifyFilter_withFixedModal({
+ column: dataType,
+ opType: 'is on or after',
+ opSubType: isAfterFilterList[i].opSub,
+ value: isAfterFilterList[i]?.value?.toString() || '',
+ result: { rowCount: 1 + isAfterFilterList[i].rowCount },
+ dataType: dataType,
+ });
+ }
- // "is within" filter list
- for (let i = 0; i < isWithinFilterList.length; i++) {
- await verifyFilter_withFixedModal({
- column: dataType,
- opType: 'is within',
- opSubType: isWithinFilterList[i].opSub,
- value: isWithinFilterList[i]?.value?.toString() || '',
- result: { rowCount: isWithinFilterList[i].rowCount },
- dataType: dataType,
- });
- }
+ // "is within" filter list
+ for (let i = 0; i < isWithinFilterList.length; i++) {
+ await verifyFilter_withFixedModal({
+ column: dataType,
+ opType: 'is within',
+ opSubType: isWithinFilterList[i].opSub,
+ value: isWithinFilterList[i]?.value?.toString() || '',
+ result: { rowCount: isWithinFilterList[i].rowCount },
+ dataType: dataType,
+ });
+ }
- // "is blank" and "is not blank" filter list
- for (let i = 0; i < filterList.length; i++) {
- await verifyFilter_withFixedModal({
- column: dataType,
- opType: filterList[i].opType,
- opSubType: null,
- value: null,
- result: { rowCount: filterList[i].rowCount },
- dataType: dataType,
- });
+ // "is blank" and "is not blank" filter list
+ for (let i = 0; i < filterList.length; i++) {
+ await verifyFilter_withFixedModal({
+ column: dataType,
+ opType: filterList[i].opType,
+ opSubType: null,
+ value: null,
+ result: { rowCount: filterList[i].rowCount },
+ dataType: dataType,
+ });
+ }
}
}
@@ -974,8 +976,12 @@ test.describe('Filter Tests: Date based', () => {
}
});
- test('Date : filters', async () => {
- await dateTimeBasedFilterTest('Date');
+ test('Date : filters-1', async () => {
+ await dateTimeBasedFilterTest('Date', 1);
+ });
+
+ test('Date : filters-2', async () => {
+ await dateTimeBasedFilterTest('Date', 2);
});
});
diff --git a/tests/playwright/tests/metaSync.spec.ts b/tests/playwright/tests/metaSync.spec.ts
index f845c384d3..f97c690e99 100644
--- a/tests/playwright/tests/metaSync.spec.ts
+++ b/tests/playwright/tests/metaSync.spec.ts
@@ -39,6 +39,8 @@ test.describe('Meta sync', () => {
await dbExec(`CREATE TABLE table2 (id INT NOT NULL, col1 INT NULL, PRIMARY KEY (id))`);
await settings.dataSources.metaData.clickReload();
+ await dashboard.rootPage.waitForTimeout(1000);
+
await settings.dataSources.metaData.verifyRow({
index: isPg(context) ? 21 : 16,
model: `table1`,
diff --git a/tests/playwright/tests/rolesPreview.spec.ts b/tests/playwright/tests/rolesPreview.spec.ts
index 0ecea16c31..eaca9f9fea 100644
--- a/tests/playwright/tests/rolesPreview.spec.ts
+++ b/tests/playwright/tests/rolesPreview.spec.ts
@@ -66,7 +66,7 @@ test.describe('Preview Mode', () => {
await dashboard.rootPage.waitForTimeout(1500);
- await dashboard.treeView.openTable({ title: 'Country' });
+ await dashboard.treeView.openTable({ title: 'Country', networkResponse: false });
await dashboard.viewSidebar.validateRoleAccess({
role: role.toLowerCase(),
diff --git a/tests/playwright/tests/utils/general.ts b/tests/playwright/tests/utils/general.ts
new file mode 100644
index 0000000000..1571666b1a
--- /dev/null
+++ b/tests/playwright/tests/utils/general.ts
@@ -0,0 +1,22 @@
+// Selector objects include the text of any icons in the textContent property.
+// This function removes the text of any icons from the textContent property.
+async function getTextExcludeIconText(selector) {
+ // Get the text of the selector
+ let text = await selector.textContent();
+
+ // List of icons
+ const icons = await selector.locator('.material-symbols-outlined');
+ const iconCount = await icons.count();
+
+ // Remove the text of each icon from the text
+ for (let i = 0; i < iconCount; i++) {
+ await icons.nth(i).waitFor();
+ const iconText = await icons.nth(i).textContent();
+ text = text.replace(iconText, '');
+ }
+
+ // trim text for any spaces
+ return text.trim();
+}
+
+export { getTextExcludeIconText };