2022-09-29 16:32:54 +00:00
|
|
|
|
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();
|
(core) Moving nbrowser tests to grist-core
Summary:
Moving bulk of nbrowser tests to core. Some tests were split and only part of them were moved.
Tests that are left are either: not suitable for grist-core (like billing) or are failing during browser tests (are not reliable).
Four fixtures directory (uploads, docs, exports-csv/excel) where completely moved to grist-core and are linked as folders.
Those changes allows to add an nbrowser test in grist-core or in the main test folder without any need to link it or link a fixture document.
Other changes:
- testrun.sh has been modified, now it runs tests from both folders (test and core/test),
- TestServer used in grist-core is now adding sample orgs and users (kiwi and others),
Test modified
- SelectionSummary: now it is run on a bigScreen, it was failing randomly
- Billing.ts: relative paths were used
- DateEditor: added waitForServer - it was failing in browser mode
- FrozenColumns, ImportFromGDrive, Printing: updated import paths
- UserManager.ts: was split into two parts (it assumed limited products)
- ViewLayoutResize.ts: this test is still in main repo, it is still failing in browser mode tests
Test Plan: Existing
Reviewers: paulfitz
Reviewed By: paulfitz
Subscribers: dsagal, paulfitz
Differential Revision: https://phab.getgrist.com/D3664
2022-10-21 21:34:26 +00:00
|
|
|
|
gu.bigScreen();
|
2022-09-29 16:32:54 +00:00
|
|
|
|
|
|
|
|
|
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: '7⨯1',
|
|
|
|
|
count: null,
|
|
|
|
|
sum: '$135,692,590',
|
|
|
|
|
});
|
|
|
|
|
await selectAndAssert({col: 0, row: 3}, {col: 0, row: 6}, {
|
|
|
|
|
dimensions: '4⨯1',
|
|
|
|
|
count: null,
|
|
|
|
|
sum: '$135,679,011',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await selectAndAssert({col: 4, row: 0}, {col: 4, row: 6}, {
|
|
|
|
|
dimensions: '7⨯1',
|
|
|
|
|
count: null,
|
|
|
|
|
sum: '135692590',
|
|
|
|
|
});
|
|
|
|
|
await selectAndAssert({col: 0, row: 0}, {col: 4, row: 6}, {
|
|
|
|
|
dimensions: '7⨯5',
|
|
|
|
|
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: '7⨯2',
|
|
|
|
|
count: null,
|
|
|
|
|
sum: '$135,692,578.02',
|
|
|
|
|
});
|
|
|
|
|
await selectAndAssert({col: 1, row: 0}, {col: 1, row: 6}, {
|
|
|
|
|
dimensions: '7⨯1',
|
|
|
|
|
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: '7⨯6',
|
|
|
|
|
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: '7⨯1',
|
|
|
|
|
count: 5,
|
|
|
|
|
sum: null,
|
|
|
|
|
});
|
|
|
|
|
await selectAndAssert({col: 2, row: 3}, {col: 2, row: 6}, {
|
|
|
|
|
dimensions: '4⨯1',
|
|
|
|
|
count: 2,
|
|
|
|
|
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: '5⨯4',
|
|
|
|
|
count: 7,
|
|
|
|
|
sum: null,
|
|
|
|
|
});
|
|
|
|
|
await selectAndAssert({col: 10, row: 0}, {col: 12, row: 6}, {
|
|
|
|
|
dimensions: '7⨯3',
|
|
|
|
|
count: 5,
|
|
|
|
|
sum: null,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2023-07-26 19:08:04 +00:00
|
|
|
|
it('does not count false values', async function () {
|
|
|
|
|
// False values in boolean columns should not be included in count
|
|
|
|
|
await selectAndAssert({col: 2, row: 0}, {col: 3, row: 5}, {
|
|
|
|
|
dimensions: '6⨯2',
|
|
|
|
|
count: 9,
|
|
|
|
|
sum: null,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2022-09-29 16:32:54 +00:00
|
|
|
|
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: '7⨯1',
|
|
|
|
|
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: '7⨯1',
|
|
|
|
|
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: '5⨯1',
|
|
|
|
|
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: '5⨯2',
|
|
|
|
|
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: '7⨯14',
|
|
|
|
|
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);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|