2026-05-17 17:03:21 +08:00
|
|
|
import { test, expect } from '@playwright/test';
|
|
|
|
|
|
|
|
|
|
test('DataTable comprehensive tests and scrolling benchmarks', async ({ page }) => {
|
|
|
|
|
test.setTimeout(180000);
|
|
|
|
|
page.on('console', msg => console.log('BROWSER LOG:', msg.text()));
|
|
|
|
|
await page.goto('/test/index.html');
|
|
|
|
|
|
|
|
|
|
await page.waitForFunction(() => window.testStatus === 'passed', { timeout: 60000 });
|
|
|
|
|
console.log('DataTable initialized.');
|
|
|
|
|
|
|
|
|
|
// 1. 遍历验证第一行每个单元格的编辑与数据同步
|
|
|
|
|
await page.waitForSelector('.dt-row');
|
|
|
|
|
const fields = await page.evaluate(() => document.querySelector('DataTable').state.fields.map(f => ({ id: f.id, type: f.type })));
|
|
|
|
|
console.log('Fields to test:', fields.map(f => f.id).join(', '));
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < fields.length; i++) {
|
|
|
|
|
const field = fields[i];
|
|
|
|
|
const colIdx = i + 1;
|
|
|
|
|
console.log(`Testing Column [${field.id}] (Type: ${field.type})...`);
|
|
|
|
|
|
|
|
|
|
if (field.id === 'actions' || field.id === 'id') {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 双击进入编辑
|
|
|
|
|
await page.evaluate((idx) => {
|
|
|
|
|
const rows = document.querySelectorAll('.dt-row');
|
|
|
|
|
const row = rows[0];
|
|
|
|
|
const cells = row.querySelectorAll('.dt-cell');
|
|
|
|
|
const cell = cells[idx - 1];
|
|
|
|
|
cell.dispatchEvent(new MouseEvent('dblclick', { bubbles: true }));
|
|
|
|
|
}, colIdx);
|
|
|
|
|
|
|
|
|
|
const editorSelector = '.dt-editor-container';
|
|
|
|
|
await page.waitForSelector(editorSelector, { timeout: 5000 });
|
|
|
|
|
|
|
|
|
|
// 模拟输入
|
|
|
|
|
let newValue;
|
|
|
|
|
if (field.type === 'switch' || field.id === 'active') {
|
|
|
|
|
const oldVal = await page.evaluate(() => document.querySelector('DataTable').state.list[0].active);
|
|
|
|
|
await page.click(`${editorSelector} .form-check-input`);
|
|
|
|
|
newValue = !oldVal;
|
|
|
|
|
} else if (field.type === 'select') {
|
|
|
|
|
newValue = 'Editor';
|
|
|
|
|
await page.selectOption(`${editorSelector} select`, newValue);
|
|
|
|
|
} else if (field.type === 'radio') {
|
|
|
|
|
newValue = 'Female';
|
|
|
|
|
await page.click(`${editorSelector} input[value="Female"]`);
|
|
|
|
|
} else if (field.type === 'textarea') {
|
|
|
|
|
newValue = 'New multi-line content';
|
|
|
|
|
await page.fill(`${editorSelector} textarea`, newValue);
|
|
|
|
|
} else if (field.type === 'TagsInput') {
|
|
|
|
|
newValue = ['Playwright'];
|
|
|
|
|
await page.fill(`${editorSelector} input`, 'Playwright');
|
|
|
|
|
await page.keyboard.press('Enter');
|
|
|
|
|
} else if (field.type === 'number') {
|
|
|
|
|
newValue = 99;
|
|
|
|
|
await page.fill(`${editorSelector} input`, '99');
|
|
|
|
|
} else if (field.type === 'date') {
|
|
|
|
|
newValue = '2026-05-20';
|
|
|
|
|
await page.fill(`${editorSelector} input`, newValue);
|
|
|
|
|
} else {
|
|
|
|
|
newValue = `Edited ${field.id}`;
|
|
|
|
|
await page.fill(`${editorSelector} input`, newValue);
|
|
|
|
|
}
|
2026-05-23 17:37:25 +08:00
|
|
|
|
2026-05-17 17:03:21 +08:00
|
|
|
// 退出编辑模式
|
|
|
|
|
await page.evaluate(() => {
|
|
|
|
|
const table = document.querySelector('DataTable');
|
|
|
|
|
const row = table.state.list[0];
|
|
|
|
|
row._editingF = null;
|
|
|
|
|
});
|
|
|
|
|
|
2026-05-23 17:37:25 +08:00
|
|
|
await page.waitForTimeout(500);
|
2026-05-17 17:03:21 +08:00
|
|
|
|
|
|
|
|
// 验证视图层 (DOM) 是否同步渲染
|
|
|
|
|
const cellText = await page.evaluate((idx) => {
|
|
|
|
|
const rows = document.querySelectorAll('.dt-row');
|
2026-05-23 17:37:25 +08:00
|
|
|
if (!rows.length) return 'NO_ROWS';
|
2026-05-17 17:03:21 +08:00
|
|
|
const row = rows[0];
|
2026-05-23 17:37:25 +08:00
|
|
|
const cells = Array.from(row.querySelectorAll('.dt-cell'));
|
|
|
|
|
return cells[idx - 1] ? cells[idx - 1].textContent.trim() : 'NOT_FOUND';
|
2026-05-17 17:03:21 +08:00
|
|
|
}, colIdx);
|
|
|
|
|
console.log(`Column [${field.id}] UI text:`, cellText);
|
|
|
|
|
|
|
|
|
|
if (field.type !== 'switch' && field.id !== 'active') {
|
|
|
|
|
expect(cellText).toContain(String(newValue).split('\n')[0]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log('All columns editing and persistence verified.');
|
|
|
|
|
|
|
|
|
|
// 2. 滚动测试
|
|
|
|
|
const scrollInfo = await page.evaluate(async () => {
|
|
|
|
|
const el = document.querySelector('.dt-body');
|
|
|
|
|
el.scrollTop = 2000;
|
|
|
|
|
await new Promise(r => setTimeout(r, 500));
|
|
|
|
|
return { scrollTop: el.scrollTop, renderedCount: el.querySelectorAll('.dt-row').length };
|
|
|
|
|
});
|
|
|
|
|
expect(scrollInfo.renderedCount).toBeGreaterThan(0);
|
|
|
|
|
});
|