Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
576 lines
21 KiB
TypeScript
576 lines
21 KiB
TypeScript
import { nanoid } from 'nanoid';
|
|
|
|
import { test, expect } from '../../../fixtures/base';
|
|
import type { n8nPage } from '../../../pages/n8nPage';
|
|
|
|
test.describe(
|
|
'Data Table details view',
|
|
{
|
|
annotation: [{ type: 'owner', description: 'Adore' }],
|
|
},
|
|
() => {
|
|
let testDataTableName: string;
|
|
|
|
const COLUMN_NAMES = {
|
|
name: 'name',
|
|
age: 'age',
|
|
active: 'active',
|
|
birthday: 'birthday',
|
|
} as const;
|
|
|
|
const generateTestData = () => [
|
|
{
|
|
name: `User ${nanoid(8)}`,
|
|
age: '30',
|
|
active: 'true',
|
|
birthday: '2024-01-15',
|
|
},
|
|
{
|
|
name: `User ${nanoid(8)}`,
|
|
age: '25',
|
|
active: 'false',
|
|
birthday: '2024-06-20',
|
|
},
|
|
{
|
|
name: `User ${nanoid(8)}`,
|
|
age: '45',
|
|
active: 'true',
|
|
birthday: '2024-12-10',
|
|
},
|
|
];
|
|
|
|
const addColumnsAndGetIds = async (
|
|
n8n: n8nPage,
|
|
method: 'header' | 'table',
|
|
): Promise<{
|
|
nameColumn: string;
|
|
ageColumn: string;
|
|
activeColumn: string;
|
|
birthdayColumn: string;
|
|
}> => {
|
|
const addColumnFn =
|
|
method === 'header'
|
|
? n8n.dataTableDetails.addColumn.bind(n8n.dataTableDetails)
|
|
: n8n.dataTableDetails.addColumn.bind(n8n.dataTableDetails);
|
|
|
|
await addColumnFn(COLUMN_NAMES.name, 'string', method);
|
|
await addColumnFn(COLUMN_NAMES.age, 'number', method);
|
|
await addColumnFn(COLUMN_NAMES.active, 'boolean', method);
|
|
await addColumnFn(COLUMN_NAMES.birthday, 'date', method);
|
|
|
|
const visibleColumns = n8n.dataTableDetails.getVisibleColumns();
|
|
await expect(visibleColumns).toHaveCount(7);
|
|
|
|
await expect(n8n.dataTableDetails.getColumnHeaderByName(COLUMN_NAMES.name)).toBeVisible();
|
|
await expect(n8n.dataTableDetails.getColumnHeaderByName(COLUMN_NAMES.age)).toBeVisible();
|
|
await expect(n8n.dataTableDetails.getColumnHeaderByName(COLUMN_NAMES.active)).toBeVisible();
|
|
await expect(n8n.dataTableDetails.getColumnHeaderByName(COLUMN_NAMES.birthday)).toBeVisible();
|
|
|
|
return {
|
|
nameColumn: await n8n.dataTableDetails.getColumnIdByName(COLUMN_NAMES.name),
|
|
ageColumn: await n8n.dataTableDetails.getColumnIdByName(COLUMN_NAMES.age),
|
|
activeColumn: await n8n.dataTableDetails.getColumnIdByName(COLUMN_NAMES.active),
|
|
birthdayColumn: await n8n.dataTableDetails.getColumnIdByName(COLUMN_NAMES.birthday),
|
|
};
|
|
};
|
|
|
|
const fillRowData = async (
|
|
n8n: n8nPage,
|
|
rowIndex: number,
|
|
columnIds: {
|
|
nameColumn: string;
|
|
ageColumn: string;
|
|
activeColumn: string;
|
|
birthdayColumn: string;
|
|
},
|
|
data: { name: string; age: string; active: string; birthday: string },
|
|
skipFirstDoubleClick: boolean = false,
|
|
) => {
|
|
await n8n.dataTableDetails.setCellValue(rowIndex, columnIds.nameColumn, data.name, 'string', {
|
|
skipDoubleClick: skipFirstDoubleClick,
|
|
});
|
|
await n8n.dataTableDetails.setCellValue(rowIndex, columnIds.ageColumn, data.age, 'number');
|
|
await n8n.dataTableDetails.setCellValue(
|
|
rowIndex,
|
|
columnIds.activeColumn,
|
|
data.active,
|
|
'boolean',
|
|
);
|
|
await n8n.dataTableDetails.setCellValue(
|
|
rowIndex,
|
|
columnIds.birthdayColumn,
|
|
data.birthday,
|
|
'date',
|
|
);
|
|
};
|
|
|
|
const verifyCellValues = async (
|
|
n8n: n8nPage,
|
|
columnIds: {
|
|
nameColumn: string;
|
|
ageColumn: string;
|
|
activeColumn: string;
|
|
birthdayColumn: string;
|
|
},
|
|
testData: Array<{ name: string; age: string; active: string; birthday: string }>,
|
|
) => {
|
|
const firstRowNameValue = await n8n.dataTableDetails.getCellValue(
|
|
0,
|
|
columnIds.nameColumn,
|
|
'string',
|
|
);
|
|
expect(firstRowNameValue).toContain(testData[0].name);
|
|
|
|
const secondRowAgeValue = await n8n.dataTableDetails.getCellValue(
|
|
1,
|
|
columnIds.ageColumn,
|
|
'number',
|
|
);
|
|
expect(secondRowAgeValue).toContain(testData[1].age);
|
|
|
|
const thirdRowActiveValue = await n8n.dataTableDetails.getCellValue(
|
|
2,
|
|
columnIds.activeColumn,
|
|
'boolean',
|
|
);
|
|
expect(thirdRowActiveValue).toBe(testData[2].active);
|
|
|
|
const firstRowBirthdayValue = await n8n.dataTableDetails.getCellValue(
|
|
0,
|
|
columnIds.birthdayColumn,
|
|
'date',
|
|
);
|
|
expect(firstRowBirthdayValue).toContain(testData[0].birthday);
|
|
};
|
|
|
|
test.beforeEach(async ({ n8n, api }) => {
|
|
await api.enableFeature('sharing');
|
|
await api.enableFeature('folders');
|
|
await api.enableFeature('advancedPermissions');
|
|
await api.enableFeature('projectRole:admin');
|
|
await api.enableFeature('projectRole:editor');
|
|
await api.setMaxTeamProjectsQuota(-1);
|
|
await n8n.goHome();
|
|
|
|
await n8n.sideBar.clickPersonalMenuItem();
|
|
testDataTableName = `Data Table ${nanoid(8)}`;
|
|
await n8n.projectTabs.clickDataTablesTab();
|
|
await n8n.dataTable.clickAddDataTableAction();
|
|
await n8n.dataTableComposer.createNewDataTable(testDataTableName);
|
|
});
|
|
|
|
test('Should display empty state with default columns', async ({ n8n }) => {
|
|
const dataTableDetailsContainer = n8n.dataTableDetails.getPageWrapper();
|
|
await expect(dataTableDetailsContainer).toBeVisible();
|
|
|
|
const emptyStateMessage = n8n.dataTableDetails.getNoRowsMessage();
|
|
await expect(emptyStateMessage).toBeVisible();
|
|
|
|
const visibleColumns = n8n.dataTableDetails.getVisibleColumns();
|
|
await expect(visibleColumns).toHaveCount(3);
|
|
|
|
await expect(n8n.dataTableDetails.getColumnHeaderByName('id')).toBeVisible();
|
|
await expect(n8n.dataTableDetails.getColumnHeaderByName('createdAt')).toBeVisible();
|
|
await expect(n8n.dataTableDetails.getColumnHeaderByName('updatedAt')).toBeVisible();
|
|
});
|
|
|
|
test('Should add columns of different types and rows from the header buttons', async ({
|
|
n8n,
|
|
}) => {
|
|
await expect(n8n.dataTableDetails.getPageWrapper()).toBeVisible();
|
|
|
|
const columnIds = await addColumnsAndGetIds(n8n, 'header');
|
|
const testData = generateTestData();
|
|
|
|
await n8n.dataTableDetails.addRow();
|
|
await expect(n8n.dataTableDetails.getNoRowsMessage()).toBeHidden();
|
|
await fillRowData(n8n, 0, columnIds, testData[0], true);
|
|
|
|
await n8n.dataTableDetails.addRow();
|
|
await fillRowData(n8n, 1, columnIds, testData[1], true);
|
|
|
|
await n8n.dataTableDetails.addRow();
|
|
await fillRowData(n8n, 2, columnIds, testData[2], true);
|
|
|
|
await verifyCellValues(n8n, columnIds, testData);
|
|
});
|
|
|
|
test('Should add columns of different types and rows from the table buttons', async ({
|
|
n8n,
|
|
}) => {
|
|
await expect(n8n.dataTableDetails.getPageWrapper()).toBeVisible();
|
|
|
|
const columnIds = await addColumnsAndGetIds(n8n, 'table');
|
|
const testData = generateTestData();
|
|
|
|
await n8n.dataTableDetails.addRowFromTable();
|
|
await expect(n8n.dataTableDetails.getNoRowsMessage()).toBeHidden();
|
|
await fillRowData(n8n, 0, columnIds, testData[0], true);
|
|
|
|
await n8n.dataTableDetails.addRowFromTable();
|
|
await fillRowData(n8n, 1, columnIds, testData[1], true);
|
|
|
|
await n8n.dataTableDetails.addRowFromTable();
|
|
await fillRowData(n8n, 2, columnIds, testData[2], true);
|
|
|
|
await verifyCellValues(n8n, columnIds, testData);
|
|
});
|
|
|
|
test('Should automatically move to second page when adding 21st row', async ({ n8n }) => {
|
|
await expect(n8n.dataTableDetails.getPageWrapper()).toBeVisible();
|
|
|
|
await n8n.dataTableDetails.addColumn(COLUMN_NAMES.name, 'string', 'header');
|
|
|
|
for (let i = 0; i < 20; i++) {
|
|
await n8n.dataTableDetails.addRow();
|
|
// This loop was enough to break it, as we'd get transaction lock errors
|
|
// eslint-disable-next-line playwright/no-wait-for-timeout
|
|
await n8n.page.waitForTimeout(150);
|
|
}
|
|
|
|
const rowsOnPage1 = n8n.dataTableDetails.getDataRows();
|
|
await expect(rowsOnPage1).toHaveCount(20);
|
|
|
|
await n8n.dataTableDetails.addRow();
|
|
|
|
const rowsOnPage2 = n8n.dataTableDetails.getDataRows();
|
|
await expect(rowsOnPage2).toHaveCount(1);
|
|
});
|
|
|
|
test('Should select and delete rows', async ({ n8n }) => {
|
|
await expect(n8n.dataTableDetails.getPageWrapper()).toBeVisible();
|
|
|
|
await n8n.dataTableDetails.addColumn(COLUMN_NAMES.name, 'string', 'header');
|
|
const nameColumn = await n8n.dataTableDetails.getColumnIdByName(COLUMN_NAMES.name);
|
|
|
|
const rowData = ['Row 1', 'Row 2', 'Row 3', 'Row 4', 'Row 5'];
|
|
for (let i = 0; i < rowData.length; i++) {
|
|
await n8n.dataTableDetails.addRow();
|
|
// eslint-disable-next-line playwright/no-wait-for-timeout
|
|
await n8n.page.waitForTimeout(150);
|
|
await n8n.dataTableDetails.setCellValue(i, nameColumn, rowData[i], 'string', {
|
|
skipDoubleClick: true,
|
|
});
|
|
}
|
|
|
|
const initialRows = n8n.dataTableDetails.getDataRows();
|
|
await expect(initialRows).toHaveCount(5);
|
|
|
|
await n8n.dataTableDetails.selectRow(1);
|
|
await n8n.dataTableDetails.selectRow(3);
|
|
|
|
const selectedItemsInfo = n8n.dataTableDetails.getSelectedItemsInfo();
|
|
await expect(selectedItemsInfo).toBeVisible();
|
|
await expect(selectedItemsInfo).toContainText('2');
|
|
|
|
await n8n.dataTableDetails.deleteSelectedRows();
|
|
|
|
const remainingRows = n8n.dataTableDetails.getDataRows();
|
|
await expect(remainingRows).toHaveCount(3);
|
|
|
|
await expect(selectedItemsInfo).toBeHidden();
|
|
|
|
const row0Value = await n8n.dataTableDetails.getCellValue(0, nameColumn, 'string');
|
|
expect(row0Value).toContain('Row 1');
|
|
|
|
const row1Value = await n8n.dataTableDetails.getCellValue(1, nameColumn, 'string');
|
|
expect(row1Value).toContain('Row 3');
|
|
|
|
const row2Value = await n8n.dataTableDetails.getCellValue(2, nameColumn, 'string');
|
|
expect(row2Value).toContain('Row 5');
|
|
});
|
|
|
|
test('Should clear selection', async ({ n8n }) => {
|
|
await expect(n8n.dataTableDetails.getPageWrapper()).toBeVisible();
|
|
|
|
await n8n.dataTableDetails.addColumn(COLUMN_NAMES.name, 'string', 'header');
|
|
const nameColumn = await n8n.dataTableDetails.getColumnIdByName(COLUMN_NAMES.name);
|
|
|
|
for (let i = 0; i < 3; i++) {
|
|
await n8n.dataTableDetails.addRow();
|
|
await n8n.dataTableDetails.setCellValue(i, nameColumn, `Row ${i + 1}`, 'string', {
|
|
skipDoubleClick: true,
|
|
});
|
|
}
|
|
|
|
await n8n.dataTableDetails.selectRow(0);
|
|
await n8n.dataTableDetails.selectRow(1);
|
|
await n8n.dataTableDetails.selectRow(2);
|
|
|
|
const selectedItemsInfo = n8n.dataTableDetails.getSelectedItemsInfo();
|
|
await expect(selectedItemsInfo).toBeVisible();
|
|
await expect(selectedItemsInfo).toContainText('3');
|
|
|
|
await n8n.dataTableDetails.clearSelection();
|
|
|
|
await expect(selectedItemsInfo).toBeHidden();
|
|
|
|
const rows = n8n.dataTableDetails.getDataRows();
|
|
await expect(rows).toHaveCount(3);
|
|
});
|
|
|
|
test('Should add columns of each type with rows and then delete all columns', async ({
|
|
n8n,
|
|
}) => {
|
|
await expect(n8n.dataTableDetails.getPageWrapper()).toBeVisible();
|
|
|
|
const columnIds = await addColumnsAndGetIds(n8n, 'header');
|
|
const testData = generateTestData().slice(0, 2);
|
|
|
|
await n8n.dataTableDetails.addRow();
|
|
await fillRowData(n8n, 0, columnIds, testData[0], true);
|
|
|
|
await n8n.dataTableDetails.addRow();
|
|
await fillRowData(n8n, 1, columnIds, testData[1], true);
|
|
|
|
const rows = n8n.dataTableDetails.getDataRows();
|
|
await expect(rows).toHaveCount(2);
|
|
|
|
await n8n.dataTableDetails.deleteColumn(COLUMN_NAMES.name);
|
|
await expect(n8n.dataTableDetails.getVisibleColumns()).toHaveCount(6);
|
|
|
|
await n8n.dataTableDetails.deleteColumn(COLUMN_NAMES.age);
|
|
await expect(n8n.dataTableDetails.getVisibleColumns()).toHaveCount(5);
|
|
|
|
await n8n.dataTableDetails.deleteColumn(COLUMN_NAMES.active);
|
|
await expect(n8n.dataTableDetails.getVisibleColumns()).toHaveCount(4);
|
|
|
|
await n8n.dataTableDetails.deleteColumn(COLUMN_NAMES.birthday);
|
|
|
|
await expect(n8n.dataTableDetails.getVisibleColumns()).toHaveCount(3);
|
|
|
|
await expect(n8n.dataTableDetails.getColumnHeaderByName('id')).toBeVisible();
|
|
await expect(n8n.dataTableDetails.getColumnHeaderByName('createdAt')).toBeVisible();
|
|
await expect(n8n.dataTableDetails.getColumnHeaderByName('updatedAt')).toBeVisible();
|
|
|
|
await expect(rows).toHaveCount(2);
|
|
});
|
|
|
|
test('Should rename data table from breadcrumbs', async ({ n8n }) => {
|
|
await expect(n8n.dataTableDetails.getPageWrapper()).toBeVisible();
|
|
|
|
const nameBreadcrumb = n8n.dataTableDetails.getDataTableBreadcrumb();
|
|
const initialName = (await nameBreadcrumb.textContent())?.toString();
|
|
|
|
const newName = `Renamed Table ${nanoid(8)}`;
|
|
|
|
await n8n.dataTableDetails.renameDataTable(newName);
|
|
|
|
await expect(nameBreadcrumb).toContainText(newName);
|
|
|
|
expect(initialName).not.toEqual(newName);
|
|
});
|
|
|
|
test.fixme('Should filter correctly using column filters', async ({ n8n }) => {
|
|
await expect(n8n.dataTableDetails.getPageWrapper()).toBeVisible();
|
|
|
|
await n8n.dataTableDetails.setPageSize('10');
|
|
|
|
await n8n.dataTableDetails.addColumn(COLUMN_NAMES.name, 'string', 'header');
|
|
await n8n.dataTableDetails.addColumn(COLUMN_NAMES.age, 'number', 'header');
|
|
await n8n.dataTableDetails.addColumn(COLUMN_NAMES.active, 'boolean', 'header');
|
|
await n8n.dataTableDetails.addColumn(COLUMN_NAMES.birthday, 'date', 'header');
|
|
|
|
const nameColumn = await n8n.dataTableDetails.getColumnIdByName(COLUMN_NAMES.name);
|
|
const ageColumn = await n8n.dataTableDetails.getColumnIdByName(COLUMN_NAMES.age);
|
|
const activeColumn = await n8n.dataTableDetails.getColumnIdByName(COLUMN_NAMES.active);
|
|
const birthdayColumn = await n8n.dataTableDetails.getColumnIdByName(COLUMN_NAMES.birthday);
|
|
|
|
const rowsData = [
|
|
{ name: 'User 1', age: '20', active: 'true', birthday: '2024-01-01' },
|
|
{ name: 'User 2', age: '21', active: 'true', birthday: '2024-01-02' },
|
|
{ name: 'User 3', age: '22', active: 'true', birthday: '2024-01-03' },
|
|
{ name: 'User 4', age: '23', active: 'true', birthday: '2024-01-04' },
|
|
{ name: 'User 5', age: '24', active: 'true', birthday: '2024-01-05' },
|
|
{ name: 'User 6', age: '25', active: 'false', birthday: '2024-01-06' },
|
|
{ name: 'User 7', age: '20', active: 'false', birthday: '2024-01-07' },
|
|
{ name: 'User 8', age: '21', active: 'false', birthday: '2024-01-08' },
|
|
{ name: 'User 9', age: '22', active: 'false', birthday: '2024-01-09' },
|
|
{ name: 'User 10', age: '23', active: 'false', birthday: '2024-01-10' },
|
|
{ name: 'User 11', age: '24', active: 'true', birthday: '2024-01-11' },
|
|
{ name: 'User 12', age: '25', active: 'true', birthday: '2024-01-12' },
|
|
{ name: 'User 13', age: '20', active: 'true', birthday: '2024-01-13' },
|
|
{ name: 'User 14', age: '21', active: 'false', birthday: '2024-01-14' },
|
|
{ name: 'User 15', age: '22', active: 'false', birthday: '2024-01-15' },
|
|
] as const;
|
|
|
|
for (let i = 0; i < 15; i++) {
|
|
await n8n.dataTableDetails.addRow();
|
|
const rowIndexOnPage = i % 10;
|
|
await n8n.dataTableDetails.setCellValue(
|
|
rowIndexOnPage,
|
|
nameColumn,
|
|
rowsData[i].name,
|
|
'string',
|
|
{
|
|
skipDoubleClick: true,
|
|
},
|
|
);
|
|
await n8n.dataTableDetails.setCellValue(
|
|
rowIndexOnPage,
|
|
ageColumn,
|
|
rowsData[i].age,
|
|
'number',
|
|
);
|
|
await n8n.dataTableDetails.setCellValue(
|
|
rowIndexOnPage,
|
|
activeColumn,
|
|
rowsData[i].active,
|
|
'boolean',
|
|
);
|
|
await n8n.dataTableDetails.setCellValue(
|
|
rowIndexOnPage,
|
|
birthdayColumn,
|
|
rowsData[i].birthday,
|
|
'date',
|
|
);
|
|
}
|
|
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(5);
|
|
|
|
await n8n.dataTableDetails.setTextFilter(COLUMN_NAMES.name, 'User 1');
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(7);
|
|
await n8n.dataTableDetails.clearColumnFilter(COLUMN_NAMES.name);
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(10);
|
|
|
|
await n8n.dataTableDetails.setNumberFilter(COLUMN_NAMES.age, '22', 'greaterThan');
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(6);
|
|
await n8n.dataTableDetails.clearColumnFilter(COLUMN_NAMES.age);
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(10);
|
|
|
|
await n8n.dataTableDetails.setBooleanFilter(COLUMN_NAMES.active, true);
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(8);
|
|
await n8n.dataTableDetails.clearColumnFilter(COLUMN_NAMES.active);
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(10);
|
|
|
|
await n8n.dataTableDetails.setDateFilter(COLUMN_NAMES.birthday, '2024-01-10', 'greaterThan');
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(5);
|
|
await n8n.dataTableDetails.clearColumnFilter(COLUMN_NAMES.birthday);
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(10);
|
|
|
|
await n8n.dataTableDetails.setBooleanFilter(COLUMN_NAMES.active, true);
|
|
await n8n.dataTableDetails.setNumberFilter(COLUMN_NAMES.age, '22', 'greaterThan');
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(4);
|
|
});
|
|
|
|
test('Should reorder columns using drag and drop', async ({ n8n }) => {
|
|
await expect(n8n.dataTableDetails.getPageWrapper()).toBeVisible();
|
|
|
|
await n8n.dataTableDetails.addColumn(COLUMN_NAMES.name, 'string', 'header');
|
|
await n8n.dataTableDetails.addColumn(COLUMN_NAMES.age, 'number', 'header');
|
|
await n8n.dataTableDetails.addColumn(COLUMN_NAMES.active, 'boolean', 'header');
|
|
await n8n.dataTableDetails.addColumn(COLUMN_NAMES.birthday, 'date', 'header');
|
|
await n8n.dataTableDetails.addColumn('email', 'string', 'header');
|
|
|
|
const initialOrder = await n8n.dataTableDetails.getColumnOrder();
|
|
expect(initialOrder).toContain(COLUMN_NAMES.name);
|
|
expect(initialOrder).toContain(COLUMN_NAMES.age);
|
|
expect(initialOrder).toContain(COLUMN_NAMES.active);
|
|
expect(initialOrder).toContain(COLUMN_NAMES.birthday);
|
|
expect(initialOrder).toContain('email');
|
|
|
|
const nameIndex = initialOrder.indexOf(COLUMN_NAMES.name);
|
|
const activeIndex = initialOrder.indexOf(COLUMN_NAMES.active);
|
|
const emailIndex = initialOrder.indexOf('email');
|
|
|
|
await n8n.dataTableDetails.dragColumnToPosition(COLUMN_NAMES.active, COLUMN_NAMES.name);
|
|
|
|
const orderAfterFirstDrag = await n8n.dataTableDetails.getColumnOrder();
|
|
const newActiveIndex = orderAfterFirstDrag.indexOf(COLUMN_NAMES.active);
|
|
const newNameIndex = orderAfterFirstDrag.indexOf(COLUMN_NAMES.name);
|
|
|
|
expect(newActiveIndex).toBeLessThan(newNameIndex);
|
|
expect(activeIndex).toBeGreaterThan(nameIndex);
|
|
|
|
await n8n.dataTableDetails.dragColumnToPosition('email', COLUMN_NAMES.age);
|
|
|
|
const orderAfterSecondDrag = await n8n.dataTableDetails.getColumnOrder();
|
|
const emailIndexAfter = orderAfterSecondDrag.indexOf('email');
|
|
const ageIndexAfter = orderAfterSecondDrag.indexOf(COLUMN_NAMES.age);
|
|
|
|
expect(emailIndexAfter).toBeLessThan(ageIndexAfter);
|
|
expect(emailIndex).toBeGreaterThan(initialOrder.indexOf(COLUMN_NAMES.age));
|
|
|
|
await n8n.dataTableDetails.dragColumnToPosition(COLUMN_NAMES.birthday, COLUMN_NAMES.name);
|
|
|
|
const finalOrder = await n8n.dataTableDetails.getColumnOrder();
|
|
const birthdayFinalIndex = finalOrder.indexOf(COLUMN_NAMES.birthday);
|
|
const nameFinalIndex = finalOrder.indexOf(COLUMN_NAMES.name);
|
|
|
|
expect(birthdayFinalIndex).toBeLessThan(nameFinalIndex);
|
|
});
|
|
|
|
test('Should search and filter rows globally', async ({ n8n }) => {
|
|
await expect(n8n.dataTableDetails.getPageWrapper()).toBeVisible();
|
|
|
|
await n8n.dataTableDetails.addColumn(COLUMN_NAMES.name, 'string', 'header');
|
|
await n8n.dataTableDetails.addColumn(COLUMN_NAMES.age, 'number', 'header');
|
|
const nameColumn = await n8n.dataTableDetails.getColumnIdByName(COLUMN_NAMES.name);
|
|
const ageColumn = await n8n.dataTableDetails.getColumnIdByName(COLUMN_NAMES.age);
|
|
|
|
const testData = [
|
|
{ name: 'Alice Johnson', age: '25' },
|
|
{ name: 'Bob Smith', age: '30' },
|
|
{ name: 'Charlie Brown', age: '35' },
|
|
{ name: 'Diana Prince', age: '28' },
|
|
{ name: 'Eve Adams', age: '32' },
|
|
{ name: 'Frank Miller', age: '29' },
|
|
];
|
|
|
|
for (let i = 0; i < testData.length; i++) {
|
|
await n8n.dataTableDetails.addRow();
|
|
await n8n.dataTableDetails.setCellValue(i, nameColumn, testData[i].name, 'string', {
|
|
skipDoubleClick: true,
|
|
});
|
|
await n8n.dataTableDetails.setCellValue(i, ageColumn, testData[i].age, 'number');
|
|
}
|
|
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(6);
|
|
|
|
// Test search for partial name match
|
|
await n8n.dataTableDetails.search('Alice');
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(1);
|
|
const aliceValue = await n8n.dataTableDetails.getCellValue(0, nameColumn, 'string');
|
|
expect(aliceValue).toContain('Alice Johnson');
|
|
|
|
// Test search for last name
|
|
await n8n.dataTableDetails.search('Smith');
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(1);
|
|
const bobValue = await n8n.dataTableDetails.getCellValue(0, nameColumn, 'string');
|
|
expect(bobValue).toContain('Bob Smith');
|
|
|
|
// Test search across all columns (search by age)
|
|
await n8n.dataTableDetails.search('30');
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(1);
|
|
const bobAgeValue = await n8n.dataTableDetails.getCellValue(0, ageColumn, 'number');
|
|
expect(bobAgeValue).toContain('30');
|
|
|
|
// Test search with multiple results
|
|
await n8n.dataTableDetails.search('a');
|
|
const multipleResultsCount = await n8n.dataTableDetails.getDataRows().count();
|
|
expect(multipleResultsCount).toBeGreaterThan(1);
|
|
|
|
// Clear search and verify all rows are shown
|
|
await n8n.dataTableDetails.clearSearch();
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(6);
|
|
|
|
// Test case-insensitive search
|
|
await n8n.dataTableDetails.search('ALICE');
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(1);
|
|
const aliceCaseValue = await n8n.dataTableDetails.getCellValue(0, nameColumn, 'string');
|
|
expect(aliceCaseValue).toContain('Alice Johnson');
|
|
|
|
// Clear search for next test
|
|
await n8n.dataTableDetails.clearSearch();
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(6);
|
|
|
|
// test search combined with column filter
|
|
await n8n.dataTableDetails.setNumberFilter(COLUMN_NAMES.age, '29', 'greaterThan');
|
|
await n8n.dataTableDetails.search('Adams');
|
|
await expect(n8n.dataTableDetails.getDataRows()).toHaveCount(1);
|
|
const adamValue = await n8n.dataTableDetails.getCellValue(0, nameColumn, 'string');
|
|
expect(adamValue).toContain('Eve Adams');
|
|
});
|
|
},
|
|
);
|