gristlabs_grist-core/test/nbrowser/SelectionSummary.ts

212 lines
6.4 KiB
TypeScript
Raw Normal View History

import {assert, driver, Key, WebElement} from 'mocha-webdriver';
import * as gu from 'test/nbrowser/gristUtils';
import {setupTestSuite} from 'test/nbrowser/testUtils';
interface CellPosition {
/** 0-based column index. */
col: number;
/** 0-based row index. */
row: number;
}
interface SelectionSummary {
dimensions: string;
count: number | null;
sum: string | null;
}
describe('SelectionSummary', function () {
this.timeout(20000);
const cleanup = setupTestSuite();
before(async function() {
const session = await gu.session().personalSite.login();
await session.tempDoc(cleanup, 'SelectionSummary.grist');
});
async function assertSelectionSummary(summary: SelectionSummary | null) {
if (!summary) {
assert.isFalse(await driver.find('.test-selection-summary-dimensions').isPresent());
assert.isFalse(await driver.find('.test-selection-summary-count').isPresent());
assert.isFalse(await driver.find('.test-selection-summary-sum').isPresent());
return;
}
const {dimensions, count, sum} = summary;
await gu.waitToPass(async () => assert.equal(
await driver.find('.test-selection-summary-dimensions').getText(),
dimensions
), 500);
if (count === null) {
assert.isFalse(await driver.find('.test-selection-summary-count').isPresent());
} else {
await gu.waitToPass(async () => assert.equal(
await driver.find('.test-selection-summary-count').getText(),
`COUNT ${count}`
), 500);
}
if (sum === null) {
assert.isFalse(await driver.find('.test-selection-summary-sum').isPresent());
} else {
await gu.waitToPass(async () => assert.equal(
await driver.find('.test-selection-summary-sum').getText(),
`SUM ${sum}`
), 500);
}
}
function shiftClick(el: WebElement) {
return driver.withActions((actions) => actions.keyDown(Key.SHIFT).click(el).keyUp(Key.SHIFT));
}
async function selectAndAssert(start: CellPosition, end: CellPosition, summary: SelectionSummary | null) {
const {col: startCol, row: startRow} = start;
await gu.getCell(startCol, startRow + 1).click();
const {col: endCol, row: endRow} = end;
await shiftClick(await gu.getCell(endCol, endRow + 1));
await assertSelectionSummary(summary);
}
it('does not display anything if only a single cell is selected', async function () {
for (const [col, row] of [[0, 1], [2, 3]]) {
await gu.getCell(col, row).click();
await assertSelectionSummary(null);
}
});
it('displays sum if the selection contains numbers', async function () {
await selectAndAssert({col: 0, row: 0}, {col: 0, row: 6}, {
dimensions: '71',
count: null,
sum: '$135,692,590',
});
await selectAndAssert({col: 0, row: 3}, {col: 0, row: 6}, {
dimensions: '41',
count: null,
sum: '$135,679,011',
});
await selectAndAssert({col: 4, row: 0}, {col: 4, row: 6}, {
dimensions: '71',
count: null,
sum: '135692590',
});
await selectAndAssert({col: 0, row: 0}, {col: 4, row: 6}, {
dimensions: '75',
count: null,
sum: '$271,385,168.02',
});
});
it('uses formatter of the first (leftmost) numeric column', async function () {
// Column 0 is U.S. currency, while column 1 is just a plain decimal number.
await selectAndAssert({col: 0, row: 0}, {col: 1, row: 6}, {
dimensions: '72',
count: null,
sum: '$135,692,578.02',
});
await selectAndAssert({col: 1, row: 0}, {col: 1, row: 6}, {
dimensions: '71',
count: null,
sum: '-11.98',
});
// The entire selection (spanning 6 columns) uses the formatter of column 0.
await selectAndAssert({col: 0, row: 0}, {col: 5, row: 6}, {
dimensions: '76',
count: null,
sum: '$271,385,156.04',
});
});
it("displays count if the selection doesn't contain numbers", async function () {
await selectAndAssert({col: 2, row: 0}, {col: 2, row: 6}, {
dimensions: '71',
count: 5,
sum: null,
});
await selectAndAssert({col: 2, row: 3}, {col: 2, row: 6}, {
dimensions: '41',
count: 2,
sum: null,
});
await selectAndAssert({col: 2, row: 0}, {col: 3, row: 5}, {
dimensions: '62',
count: 11,
sum: null,
});
// Scroll horizontally to the end of the table.
await gu.sendKeys(Key.END);
await selectAndAssert({col: 7, row: 0}, {col: 10, row: 4}, {
dimensions: '54',
count: 7,
sum: null,
});
await selectAndAssert({col: 10, row: 0}, {col: 12, row: 6}, {
dimensions: '73',
count: 5,
sum: null,
});
});
it('uses the show column of reference columns for computations', async function () {
// Column 6 is a Reference column pointing to column 0.
await gu.sendKeys(Key.HOME);
await selectAndAssert({col: 6, row: 0}, {col: 6, row: 6}, {
dimensions: '71',
count: null,
sum: '-$123,456',
});
// Column 7 is a Reference List column pointing to column 0. At this time, it
// only displays counts (but flattening sums also seems like intuitive behavior).
await gu.sendKeys(Key.END);
await selectAndAssert({col: 7, row: 0}, {col: 7, row: 6}, {
dimensions: '71',
count: 2,
sum: null,
});
});
it('updates whenever the selection changes', async function () {
// Scroll horizontally to the beginning of the table.
await gu.sendKeys(Key.HOME);
// Select a region of the table.
await selectAndAssert({col: 0, row: 2}, {col: 0, row: 6}, {
dimensions: '51',
count: null,
sum: '$135,691,356',
});
// Without de-selecting, use keyboard shortcuts to grow the selection to the right.
await gu.sendKeys(Key.chord(Key.SHIFT, Key.ARROW_RIGHT));
// Check that the selection summary was updated.
await assertSelectionSummary({
dimensions: '52',
count: null,
sum: '$135,691,368.5',
});
});
it('displays correct sum when all rows/columns are selected', async function () {
await driver.find(".gridview_data_corner_overlay").click();
await assertSelectionSummary({
dimensions: '714',
count: null,
sum: '$271,261,700.04',
});
});
describe('on narrow screens', function() {
gu.narrowScreen();
it('is not visible', async function() {
await assertSelectionSummary(null);
await selectAndAssert({col: 0, row: 0}, {col: 0, row: 6}, null);
});
});
});