Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ function testsFactory(testModel: {
await testModel.assertFirstColumnHidden(t, cardView);

await testModel.showFirstColumn(t, cardView);

await testModel.assertFirstColumnVisible(t, cardView);

await testModel.hideFirstColumn(t, cardView);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
expectColumns,
getColumnItem,
triggerDragStart,
triggerDragEnd,
SELECTORS,
} from './utils';

Expand All @@ -29,12 +30,16 @@ fixture.disablePageReloads`CardView - ColumnSortable.Functional`

await triggerDragStart(columnElement);

const draggingElement = Selector(SELECTORS.dragging);
try {
const draggingElement = Selector(SELECTORS.dragging);

if (result) {
await t.expect(draggingElement.exists).ok();
} else {
await t.expect(draggingElement.exists).notOk();
if (result) {
await t.expect(draggingElement.exists).ok();
} else {
await t.expect(draggingElement.exists).notOk();
}
} finally {
await triggerDragEnd(columnElement);
}
}).before(async () => createWidget('dxCardView', {
allowColumnReordering,
Expand All @@ -59,12 +64,16 @@ fixture.disablePageReloads`CardView - ColumnSortable.Functional`

await triggerDragStart(columnElement);

const draggingElement = Selector(SELECTORS.dragging);
try {
const draggingElement = Selector(SELECTORS.dragging);

if (result) {
await t.expect(draggingElement.exists).ok();
} else {
await t.expect(draggingElement.exists).notOk();
if (result) {
await t.expect(draggingElement.exists).ok();
} else {
await t.expect(draggingElement.exists).notOk();
}
} finally {
await triggerDragEnd(columnElement);
}
}).before(async () => createWidget('dxCardView', {
allowColumnReordering: true,
Expand All @@ -90,7 +99,10 @@ fixture.disablePageReloads`CardView - ColumnSortable.Functional`

const columnElement = getColumnItem(cardView, columnIndex);

await dragToHeaderPanel(t, cardView, columnElement, gapIndex);
// dropping next to the dragged column is a no-op, so no placeholder appears
const isNoOp = gapIndex === columnIndex || gapIndex === columnIndex + 1;

await dragToHeaderPanel(t, cardView, columnElement, gapIndex, isNoOp);

await expectColumns(t, cardView, expectedColumns);
}).before(async () => createWidget('dxCardView', {
Expand All @@ -102,18 +114,18 @@ fixture.disablePageReloads`CardView - ColumnSortable.Functional`

[0, 1].forEach((columnIndex) => {
[0, 1, 2].forEach((gapIndex) => {
test.meta({ unstable: true })(`drag from columnChooser to headerPanel: from index ${columnIndex} to index ${gapIndex}`, async (t) => {
test(`drag from columnChooser to headerPanel: from index ${columnIndex} to index ${gapIndex}`, async (t) => {
const cardView = new CardView('#container');
await cardView.apiShowColumnChooser();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we check isReady here? Also, shouldn't we verify that the Column Chooser exists before accessing it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isReady won't help here, because it indicates whether dataController finished loading data:

In this test we don't care whether the data was loaded or not. Explicit wait for column chooser is also not needed, because there's an implement check:

const columnElement = getColumnItem(cardView, columnIndex, 'columnChooser');. Column element is a testcafe Selector, so testcafe will wait for the element to appear before doing anything with it


const columnElement = getColumnItem(cardView, columnIndex, 'columnChooser');

await dragToHeaderPanel(t, cardView, columnElement, gapIndex);

const headerPanelColumns = [2, 3, 4];
const headerPanelColumns = [2, 3];
headerPanelColumns.splice(gapIndex, 0, columnIndex);

const chooserColumns = [0, 1, 2, 3, 4].filter((c) => !headerPanelColumns.includes(c));
const chooserColumns = [0, 1].filter((c) => c !== columnIndex);

await expectColumns(t, cardView, headerPanelColumns);
await expectColumns(t, cardView, chooserColumns, 'columnChooser');
Expand All @@ -124,7 +136,6 @@ fixture.disablePageReloads`CardView - ColumnSortable.Functional`
{ dataField: 'Column 1', visible: false },
{ dataField: 'Column 2' },
{ dataField: 'Column 3' },
{ dataField: 'Column 4' },

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This matrix tests iterates through [0, 1, 2] for gapIndex. With 4 columns, testcases for gapIndex==1 and gapIndex==2 basically test the same thing: drag from column chooser to the middle of header panel.

With 3 columns, gapIndex==2 now checks the case when column is dragged to the end of header panel

],
}));
});
Expand Down Expand Up @@ -178,7 +189,10 @@ fixture.disablePageReloads`CardView - ColumnSortable.Functional`
const cardView = new CardView('#container');
const columnElement = getColumnItem(cardView, draggingColumnIndex);

await dragToHeaderPanel(t, cardView, columnElement, gapIndex);
// dropping next to the dragged column is a no-op, so no placeholder appears
const isNoOp = gapIndex === draggingColumnIndex || gapIndex === draggingColumnIndex + 1;

await dragToHeaderPanel(t, cardView, columnElement, gapIndex, isNoOp);

await expectColumns(t, cardView, expectedColumns);
}).before(async () => createWidget('dxCardView', {
Expand Down
58 changes: 38 additions & 20 deletions e2e/testcafe-devextreme/tests/cardView/columnSortable/utils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ClientFunction, Selector } from 'testcafe';
import CardView from 'devextreme-testcafe-models/cardView';
import TreeView from 'devextreme-testcafe-models/treeView';
import { MouseUpEvents, MouseAction } from '../../../helpers/mouseUpEvents';

const DRAG_ASSERTION_TIMEOUT = 1000;
const HEADER_DROP_OFFSET_Y = 5;

export const SELECTORS = {
Expand Down Expand Up @@ -73,41 +73,58 @@ export const dragToHeaderPanel = async (
cardView: CardView,
columnElement: Selector,
gapIndex: number,
isNoOp = false,
): Promise<void> => {
const headers = cardView.getHeaders();
const columnsNum = await headers.getHeaderItemsElements().count;

await MouseUpEvents.disable(MouseAction.dragToElement);

if (gapIndex < columnsNum) {
const insertBeforeColumn = headers.getHeaderItemNth(gapIndex).element;
const { width } = await insertBeforeColumn.boundingClientRect;

await t.dragToElement(
columnElement,
insertBeforeColumn,
{
destinationOffsetX: 5,
offsetX: 5,
offsetY: 5,
destinationOffsetX: -(Math.floor(width) + 3), // 3px left of the left edge
destinationOffsetY: HEADER_DROP_OFFSET_Y,
speed: 0.5,
},
);
} else {
const insertAfterColumn = headers.getHeaderItemNth(columnsNum - 1).element;
const { width } = await insertAfterColumn.boundingClientRect;

await t.dragToElement(
columnElement,
insertAfterColumn,
{
destinationOffsetX: -5,
offsetX: 5,
offsetY: 5,
destinationOffsetX: (Math.floor(width) + 3), // 3px right of the right edge
destinationOffsetY: HEADER_DROP_OFFSET_Y,
speed: 0.5,
},
);
}

if (!isNoOp) {
await t
.expect(cardView.getHeaderPanel().getDropPlaceholder().exists)
.ok();
}

await MouseUpEvents.enable(MouseAction.dragToElement);

await t.dispatchEvent(columnElement, 'mouseup');

await t
.expect(Selector(SELECTORS.dragging).exists)
.notOk({ timeout: DRAG_ASSERTION_TIMEOUT })
.expect(cardView.isReady())
.ok({ timeout: DRAG_ASSERTION_TIMEOUT });
.notOk();
};

export const dragToColumnChooser = async (
Expand All @@ -119,6 +136,10 @@ export const dragToColumnChooser = async (
const treeView = columnChooser.element.find(SELECTORS.treeView);

await t.dragToElement(columnElement, treeView);

await t
.expect(Selector(SELECTORS.dragging).exists)
.notOk();
};

export const arrayMoveToGap = (arr: number[], index: number, gapIndex: number): number[] => {
Expand All @@ -139,23 +160,20 @@ export const expectColumns = async (
expectedColumns: number[],
source: 'headerPanel' | 'columnChooser' = 'headerPanel',
): Promise<void> => {
const actualColumns: string[] = [];
const adjustedExpectedColumns = expectedColumns.map((columnIndex) => `Column ${columnIndex}`);

for (let i = 0; i < expectedColumns.length; i += 1) {
// eslint-disable-next-line @typescript-eslint/init-declarations
let column: Selector;
const actualColumnsCount = source === 'headerPanel'
? await cardView.getHeaders().getHeaderItemsElements().count
: await cardView.getColumnChooser().getColumns().count;

if (source === 'headerPanel') {
column = cardView.getHeaders().getHeaderItemNth(i)?.element;
} else {
const treeView = new TreeView(cardView.getColumnChooser().element.find(SELECTORS.treeView));
column = treeView.getNodeItem(i);
}
for (let i = 0; i < actualColumnsCount; i += 1) {
const column = source === 'headerPanel'
? cardView.getHeaders().getHeaderItemNth(i).element
: cardView.getColumnChooser().getColumn(i);

await t
.expect(column.exists)
.ok({ timeout: DRAG_ASSERTION_TIMEOUT })
.expect(column.innerText)
.eql(adjustedExpectedColumns[i], { timeout: DRAG_ASSERTION_TIMEOUT });
actualColumns.push(await column.innerText);
}

await t.expect(actualColumns).eql(adjustedExpectedColumns, 'Columns order should match');
};
34 changes: 31 additions & 3 deletions e2e/testcafe-devextreme/tests/common/treeList/toast.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
import { createScreenshotsComparer } from 'devextreme-screenshot-comparer';
import TreeList from 'devextreme-testcafe-models/treeList';
import { ClientFunction } from 'testcafe';
import url from '../../../helpers/getPageUrl';
import { createWidget } from '../../../helpers/createWidget';
import { testScreenshot } from '../../../helpers/themeUtils';

fixture.disablePageReloads`Toasts in TreeList`
fixture`Toasts in TreeList`
.page(url(__dirname, '../../container.html'));

test('Toast should be visible after calling and should be not visible after default display time', async (t) => {
const setToastDisplayTime = (displayTime: number) => ClientFunction(() => {
(window as any).DevExpress.ui.dxToast.defaultOptions({
options: {
displayTime,
},
});
}, { dependencies: { displayTime } })();

test('Toast should be visible after calling', async (t) => {
const treeList = new TreeList('#container');
const { takeScreenshot, compareResults } = createScreenshotsComparer(t);
await t
.expect(treeList.isReady())
.ok();

await setToastDisplayTime(100000);
await treeList.apiShowErrorToast();
await t.expect(treeList.getToast().exists).ok();

Expand All @@ -22,7 +32,25 @@ test('Toast should be visible after calling and should be not visible after defa
await t
.expect(compareResults.isValid())
.ok(compareResults.errorMessages());
await t.expect(treeList.getToast().exists).notOk();
}).before(async () => {
await createWidget('dxTreeList', {});
});

test('Toast should hide after the display time', async (t) => {
const treeList = new TreeList('#container');

await t
.expect(treeList.isReady())
.ok();

await setToastDisplayTime(1000);
await treeList.apiShowErrorToast();
await t
.expect(treeList.getToast().exists).ok();

await t
.wait(1100)
.expect(treeList.getToast().exists).notOk();
}).before(async () => {
await createWidget('dxTreeList', {});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ fixture`Ai Column.Virtual Scrolling.Functional`

const DATA_GRID_SELECTOR = '#container';

const CLASS = {
loadPanelContent: 'dx-loadpanel-content',
};

const checkAIColumnTexts = async (
t: TestController,
component: DataGrid,
Expand All @@ -28,6 +24,8 @@ const checkAIColumnTexts = async (
}
};

const isAIRequestPending = ClientFunction(() => !!(window as any).aiResolve);

const resolveAIRequest = ClientFunction((): void => {
const { aiResponseData } = (window as any);
const { aiResolve } = (window as any);
Expand All @@ -51,7 +49,9 @@ test('DataGrid should send an AI request for rendered rows after scrolling witho

// assert
await t
.expect(dataGrid.element.find(`.${CLASS.loadPanelContent}`).visible)
.expect(isAIRequestPending())
.ok()
.expect(dataGrid.getLoadPanel().isVisible())
.ok();

// act
Expand All @@ -61,7 +61,7 @@ test('DataGrid should send an AI request for rendered rows after scrolling witho
await t
.expect(dataGrid.isReady())
.ok()
.expect(dataGrid.element.find(`.${CLASS.loadPanelContent}`).visible)
.expect(dataGrid.getLoadPanel().isVisible())
.notOk();
await checkAIColumnTexts(t, dataGrid, 11);

Expand All @@ -76,7 +76,9 @@ test('DataGrid should send an AI request for rendered rows after scrolling witho
.eql(0)
.expect(dataGrid.getDataCell(20, 0).element.textContent)
.eql('21')
.expect(dataGrid.element.find(`.${CLASS.loadPanelContent}`).visible)
.expect(isAIRequestPending())
.ok()
.expect(dataGrid.getLoadPanel().isVisible())
.ok();

// act
Expand All @@ -86,7 +88,7 @@ test('DataGrid should send an AI request for rendered rows after scrolling witho
await t
.expect(dataGrid.isReady())
.ok()
.expect(dataGrid.element.find(`.${CLASS.loadPanelContent}`).visible)
.expect(dataGrid.getLoadPanel().isVisible())
.notOk();
await checkAIColumnTexts(t, dataGrid, 12);
})
Expand Down Expand Up @@ -154,7 +156,9 @@ test('DataGrid should send an AI request for rendered rows after scrolling with

// assert
await t
.expect(dataGrid.element.find(`.${CLASS.loadPanelContent}`).visible)
.expect(isAIRequestPending())
.ok()
.expect(dataGrid.getLoadPanel().isVisible())
.ok();

// act
Expand All @@ -164,7 +168,7 @@ test('DataGrid should send an AI request for rendered rows after scrolling with
await t
.expect(dataGrid.isReady())
.ok()
.expect(dataGrid.element.find(`.${CLASS.loadPanelContent}`).visible)
.expect(dataGrid.getLoadPanel().isVisible())
.notOk();
await checkAIColumnTexts(t, dataGrid, 11);

Expand All @@ -179,7 +183,9 @@ test('DataGrid should send an AI request for rendered rows after scrolling with
.eql(1)
.expect(dataGrid.getDataCell(20, 0).element.textContent)
.eql('21')
.expect(dataGrid.element.find(`.${CLASS.loadPanelContent}`).visible)
.expect(isAIRequestPending())
.ok()
.expect(dataGrid.getLoadPanel().isVisible())
.ok();

// act
Expand All @@ -189,7 +195,7 @@ test('DataGrid should send an AI request for rendered rows after scrolling with
await t
.expect(dataGrid.isReady())
.ok()
.expect(dataGrid.element.find(`.${CLASS.loadPanelContent}`).visible)
.expect(dataGrid.getLoadPanel().isVisible())
.notOk();
await checkAIColumnTexts(t, dataGrid, 12);
})
Expand Down
Loading