(core) Fix and move filter tests to grist-core

Summary:
A few tests that hadn't been ported to grist-core yet began failing after
a change in behavior with the column filter menu.

Test Plan: Existing tests.

Reviewers: jarek

Reviewed By: jarek

Differential Revision: https://phab.getgrist.com/D4260
pull/1004/head
George Gevoian 4 months ago
parent 76a43129f1
commit 15590950e6

@ -0,0 +1,621 @@
import { UserAPI } from 'app/common/UserAPI';
import { addToRepl, assert, driver, Key } from 'mocha-webdriver';
import * as gu from 'test/nbrowser/gristUtils';
import { setupTestSuite } from 'test/nbrowser/testUtils';
const limitShown = 500;
// Sum all of the counts directly on the browser using `driver.executeScript(...)`. There could me
// over 500 of them and using the classic driver.findAll(...) approach makes it too slow and causes
// the test to crash (timeout).
function getCount() {
return driver.executeScript(`
return Array.from(document.querySelectorAll('.test-filter-menu-count'), e => e.innerText)
.map(s => s.split(',').join(''))
.map(Number)
.reduce((acc, v) => acc + v, 0);
`);
}
// find a filter value by name
function findByName(regex: RegExp | string) {
return driver.findContent('.test-filter-menu-list label', regex);
}
describe('ColumnFilterMenu', function() {
this.timeout(20000);
const cleanup = setupTestSuite();
addToRepl('findByName', findByName);
let doc: any;
let api: UserAPI;
it('should handle empty lists consistently', async function() {
// A formula returning an empty RecordSet in a RefList columns results in storing [] instead of null.
// This previously caused a bug where the empty list was 'flattened' and the cell not appearing in filters at all.
const session = await gu.session().teamSite.login();
const api = session.createHomeApi();
const docId = await session.tempNewDoc(cleanup, 'FilterEmptyLists', {load: false});
await api.applyUserActions(docId, [
['AddTable', 'Table2', [
{
id: 'A', type: 'RefList:Table2', isFormula: true,
// This means that the first cell will contain [] while the second will contain null.
// The test asserts that both end up being treated the same.
formula: 'if $id == 1: return table.lookupRecords(B="foobar")'
},
{id: 'B'},
]],
['BulkAddRecord', 'Table2', [null, null], {B: [1, 2]}],
]);
await session.loadDoc(`/doc/${docId}/p/2`);
await gu.rightClick(gu.getCell({rowNum: 1, col: 'A'}));
await driver.findContent('.grist-floating-menu li', 'Filter by this value').click();
assert.deepEqual(
await gu.getVisibleGridCells({cols: ['A', 'B'], rowNums: [1, 2, 3]}),
[
'', '1',
'', '2',
'', ''
]
);
await gu.openColumnMenu('A', 'Filter');
assert.deepEqual(
await driver.findAll('.test-filter-menu-list .test-filter-menu-count', (e) => e.getText()),
['2'],
);
});
it('should show only first 500', async function() {
const session = await gu.session().teamSite.login();
await session.tempDoc(cleanup, 'World.grist');
// check row count is > 4000
const total = await gu.getGridRowCount() - 1;
assert.equal(total, 4079);
// scroll back to top
await gu.sendKeys(Key.chord(await gu.modKey(), Key.UP));
// open filter menu for first column
await gu.openColumnMenu('Name', 'Filter');
// check ther are 500 entry shown
assert.lengthOf(await driver.findAll('.test-filter-menu-list label'), limitShown);
// check `Other` summary is present
assert.deepEqual(
await driver.findAll('.test-filter-menu-summary', (e) => e.find('label').getText()),
['Other Values (3,501)', 'Future Values']
);
// check counts add up
assert.equal(await getCount(), total);
// type 'A' to search
await gu.sendKeys('A');
// check summary has `Other matching` and Other Non-matching`
assert.deepEqual(
await driver.findAll('.test-filter-menu-summary', (e) => e.find('label').getText()),
['Other Matching (2,493)', 'Other Non-Matching (1,008)']
);
// check count adds up
assert.equal(await getCount(), total);
// clear search input
await gu.sendKeys(Key.BACK_SPACE);
// Click All Except / Other Matching / Other NOn-Matching
await driver.findContent('.test-filter-menu-bulk-action', /None/).click();
// click Aba and Abadan
await driver.findContent('.test-filter-menu-list label', /Aba/).click();
await driver.findContent('.test-filter-menu-list label', /Abadan/).click();
// Apply filter
await driver.find('.test-filter-menu-apply-btn').click();
// check grid contains aba and abadan
assert.deepEqual(
await gu.getVisibleGridCells({cols: ['Name'], rowNums: [1, 2, 3]}),
[
'Aba',
'Abadan',
''
]
);
});
it('should uncheck \'Other Values\' checkbox when user clicks \'None\'', async () => {
// open the Name filter
await gu.openColumnMenu('Name', 'Filter');
// click None
await driver.findContent('.test-filter-menu-bulk-action', /None/).click();
// check Other values was propertly unchecked
assert.equal(
await driver.findContent('.test-filter-menu-summary', /Other Values/).find('input').matches(':checked'),
false
);
assert.equal(
await driver.findContent('.test-filter-menu-summary', /Future Values/).find('input').matches(':checked'),
false
);
});
it('should take other filters into account', async () => {
const session = await gu.session().teamSite.login();
doc = await session.tempDoc(cleanup, 'SortFilterIconTest.grist');
api = session.createHomeApi();
// check table content
assert.deepEqual(
await gu.getVisibleGridCells({cols: ['Name', 'Count'], rowNums: [1, 2, 3, 4, 5, 6]}),
[ 'Apples', '1',
'Oranges', '3',
'Bananas', '2',
'Grapes', '-1',
'Grapefruit', 'n/a',
'Clementines', '5'
]);
// add Name Filter
await gu.openColumnMenu('Name', 'Filter');
// Click Oranges
await findByName('Oranges').click();
// Click Apply
await driver.find('.test-filter-menu-apply-btn').click();
// add Count filters
await driver.find('.test-add-filter-btn').click();
await driver.findContent('.grist-floating-menu li', /Count/).click();
// Check that there's only 5 values left ('3' is missing)
assert.deepEqual(await driver.findAll('.test-filter-menu-list label', (e) => e.getText()),
['n/a', '-1', '1', '2', '5']);
// Check `Others` shows unique count
assert.equal(await driver.find('.test-filter-menu-summary').getText(),
'Others (1)');
// Check `Others` is checked
assert.equal(await driver.find('.test-filter-menu-summary').find('input').matches(':checked'), true);
// Click `Other`
await driver.find('.test-filter-menu-summary').find('input').click();
// Click '1'
await findByName(/^1/).click();
// Click Apply
await driver.find('.test-filter-menu-apply-btn').click();
// Open the Name menu filter
await driver.findContent('.test-filter-field', /Name/).click();
// Check there's only 4 values left
assert.deepEqual(await driver.findAll('.test-filter-menu-list label', (e) => e.getText()),
['Bananas', 'Clementines', 'Grapefruit', 'Grapes']);
// check `Others` shows 2 unique values
assert.equal(await driver.find('.test-filter-menu-summary').getText(),
'Others (2)');
// check `Others` is in indeterminate state
assert.equal(await driver.find('.test-filter-menu-summary').find('input').matches(':checked'), false);
assert.equal(await driver.find('.test-filter-menu-summary').find('input').matches(':indeterminate'), true);
// Click `Others`
await driver.find('.test-filter-menu-summary').find('input').click();
// check `Others` is checked
assert.equal(await driver.find('.test-filter-menu-summary').find('input').matches(':checked'), true);
assert.equal(await driver.find('.test-filter-menu-summary').find('input').matches(':indeterminate'), false);
// Click `Others`
await driver.find('.test-filter-menu-summary').find('input').click();
// check `Others` is checked
assert.equal(await driver.find('.test-filter-menu-summary').find('input').matches(':checked'), false);
assert.equal(await driver.find('.test-filter-menu-summary').find('input').matches(':indeterminate'), false);
// Click Apply
await driver.find('.test-filter-menu-apply-btn').click();
// open Count filter menu
await driver.findContent('.test-filter-field', /Count/).click();
// Click all and click Apply
await driver.findContent('.test-filter-menu-bulk-action', /All/).click();
await driver.find('.test-filter-menu-apply-btn').click();
// open Name filter menu
await driver.findContent('.test-filter-field', /Name/).click();
// Check Apples and Oranges are unchecked
assert.deepEqual(await driver.findAll('.test-filter-menu-list label', (e) => e.getText()),
['Apples', 'Bananas', 'Clementines', 'Grapefruit', 'Grapes', 'Oranges']);
assert.equal(await findByName('Apples').find('input').matches(':checked'), false);
assert.equal(await findByName('Oranges').find('input').matches(':checked'), false);
// click Apply
await driver.find('.test-filter-menu-apply-btn').click();
// Open count Filter menu
await driver.findContent('.test-filter-field', /Count/).click();
// Check there's only 4 values left
assert.deepEqual(await driver.findAll('.test-filter-menu-list label', (e) => e.getText()),
['n/a', '-1', '2', '5']);
// Click Others
await driver.find('.test-filter-menu-summary').click();
// click Apply
await driver.find('.test-filter-menu-apply-btn').click();
// Open Name filter menu
await driver.findContent('.test-filter-field', /Name/).click();
// Check Others is unchecked
assert.equal(await driver.find('.test-filter-menu-summary').find('input').matches(':checked'), false);
assert.equal(await driver.find('.test-filter-menu-summary').find('input').matches(':indeterminate'), false);
// Click Others
await driver.find('.test-filter-menu-summary').find('input').click();
await driver.find('.test-filter-menu-apply-btn').click();
// Open count filter
await driver.findContent('.test-filter-field', /Count/).click();
// Click All and click apply
await driver.findContent('.test-filter-menu-bulk-action', /All/).click();
await driver.find('.test-filter-menu-apply-btn').click();
// open Name filter menu
await driver.findContent('.test-filter-field', /Name/).click();
// Check both apples and orages are not checked
assert.equal(await findByName('Apples').find('input').matches(':checked'), false);
assert.equal(await findByName('Oranges').find('input').matches(':checked'), false);
// Revert to all
await driver.findContent('.test-filter-menu-bulk-action', /All/).click();
await driver.find('.test-filter-menu-apply-btn').click();
// Open Count filter menu and click All
await driver.findContent('.test-filter-field', /Count/).click();
await driver.findContent('.test-filter-menu-bulk-action', /All/).click();
await driver.find('.test-filter-menu-apply-btn').click();
});
it('should show count of unique values next to summaries', async () => {
// add another Apples
await driver.find('.record-add .field').click();
await driver.sendKeys('Apples', Key.ENTER);
await gu.waitForServer();
assert.deepEqual(
await gu.getVisibleGridCells({cols: ['Name', 'Count'], rowNums: [1, 2, 3, 4, 5, 6, 7]}),
[ 'Apples', '1',
'Oranges', '3',
'Bananas', '2',
'Grapes', '-1',
'Grapefruit', 'n/a',
'Clementines', '5',
'Apples', '0'
]);
// open the Count filter
await driver.findContent('.test-filter-field', /Count/).click();
// uncheck 0 and 1
await findByName(/^0/).click();
await findByName(/^1/).click();
// Click Apply
await driver.find('.test-filter-menu-apply-btn').click();
// open the Name filter
await driver.findContent('.test-filter-field', /Name/).click();
// check Apples is missing
assert.deepEqual(await driver.findAll('.test-filter-menu-list label', (e) => e.getText()),
['Bananas', 'Clementines', 'Grapefruit', 'Grapes', 'Oranges']);
// check count is (1)
assert.deepEqual(
await driver.findAll('.test-filter-menu-summary', (e) => e.find('label').getText()),
['Others (1)']
);
// close filter
await driver.sendKeys(Key.ESCAPE);
});
it('should show a working range filter for numeric columns', async function() {
// open the Count filter
await driver.findContent('.test-filter-field', /Count/).click();
// set min to '2'
await gu.setRangeFilterBound('min', '2');
await driver.find('.test-filter-menu-apply-btn').click();
// check values
assert.deepEqual(
await gu.getVisibleGridCells({cols: ['Name', 'Count'], rowNums: [1, 2, 3, 4]}),
[ 'Oranges', '3',
'Bananas', '2',
'Clementines', '5',
'', ''
]
);
// reopen the filter
await driver.findContent('.test-filter-field', /Count/).click();
// set max to '4'
await gu.setRangeFilterBound('max', '4');
await driver.find('.test-filter-menu-apply-btn').click();
assert.deepEqual(
await gu.getVisibleGridCells({cols: ['Name', 'Count'], rowNums: [1, 2, 3, 4]}),
[ 'Oranges', '3',
'Bananas', '2',
'', '',
undefined, undefined
]
);
// remove both min and max
await driver.findContent('.test-filter-field', /Count/).click();
await gu.setRangeFilterBound('min', null);
await gu.setRangeFilterBound('max', null);
await driver.find('.test-filter-menu-apply-btn').click();
// check all values are there
assert.deepEqual(
await gu.getVisibleGridCells({cols: ['Name', 'Count'], rowNums: [1, 2, 3, 4, 5, 6, 7]}),
[ 'Apples', '1',
'Oranges', '3',
'Bananas', '2',
'Grapes', '-1',
'Grapefruit', 'n/a',
'Clementines', '5',
'Apples', '0'
]);
});
it('should remove new filters when Cancel is clicked in a new filter', async function() {
// Create a new Date filter.
await gu.openColumnMenu('Date', 'Filter');
assert.deepEqual(
[
{checked: true, value: 'n/a', count: 1},
{checked: true, value: '', count: 2},
{checked: true, value: '2019-07-15', count: 1},
{checked: true, value: '2019-07-16', count: 1},
{checked: true, value: '2019-07-17', count: 1},
{checked: true, value: '2019-07-18', count: 1}
],
await gu.getFilterMenuState()
);
// Check that the Date filter is pinned.
assert.deepEqual(
[
{name: 'Name', hasUnsavedChanges: true},
{name: 'Count', hasUnsavedChanges: true},
{name: 'Date', hasUnsavedChanges: true},
],
await gu.getPinnedFilters()
);
// Set a min filter of '2019-07-16'.
await gu.setRangeFilterBound('min', '2019-07-16');
// Click Cancel, and check that the filter is no longer applied to the table data.
await gu.waitToPass(async () => {
await driver.find('.test-filter-menu-cancel-btn').click();
assert.isFalse(await driver.find('.test-filter-menu-wrapper').isPresent());
});
assert.deepEqual(
await gu.getVisibleGridCells({cols: ['Name', 'Count'], rowNums: [1, 2, 3, 4, 5, 6, 7]}),
[ 'Apples', '1',
'Oranges', '3',
'Bananas', '2',
'Grapes', '-1',
'Grapefruit', 'n/a',
'Clementines', '5',
'Apples', '0'
]
);
// Check that the Date filter was removed.
await gu.openSectionMenu('sortAndFilter');
assert.isFalse(await driver.findContent('.test-filter-config-filter', /Date/).isPresent());
await gu.sendKeys(Key.ESCAPE);
assert.deepEqual(
[
{name: 'Name', hasUnsavedChanges: true},
{name: 'Count', hasUnsavedChanges: true},
],
await gu.getPinnedFilters()
);
});
it('should revert to open state when Cancel is clicked in an existing filter', async function() {
// Open the Count filter.
await driver.findContent('.test-filter-field', /Count/).click();
// Filter out 1 and 2.
await driver.findContent('.test-filter-menu-list label', /1/).click();
await driver.findContent('.test-filter-menu-list label', /2/).click();
// Unpin the filter.
await driver.find('.test-filter-menu-pin-btn').click();
// Click Cancel, and check that the filter is no longer applied to the table data.
await driver.find('.test-filter-menu-cancel-btn').click();
assert.deepEqual(
await gu.getVisibleGridCells({cols: ['Name', 'Count'], rowNums: [1, 2, 3, 4, 5, 6, 7]}),
[ 'Apples', '1',
'Oranges', '3',
'Bananas', '2',
'Grapes', '-1',
'Grapefruit', 'n/a',
'Clementines', '5',
'Apples', '0'
]
);
// Check that Count is still pinned to the filter bar.
assert.deepEqual(
[
{name: 'Name', hasUnsavedChanges: true},
{name: 'Count', hasUnsavedChanges: true},
],
await gu.getPinnedFilters()
);
// Check the filter menu state of Count.
await driver.findContent('.test-filter-field', /Count/).click();
assert.deepEqual(
[
{checked: true, value: 'n/a', count: 1},
{checked: true, value: '-1', count: 1},
{checked: true, value: '0', count: 1},
{checked: true, value: '1', count: 1},
{checked: true, value: '2', count: 1},
{checked: true, value: '3', count: 1},
{checked: true, value: '5', count: 1},
],
await gu.getFilterMenuState()
);
await gu.sendKeys(Key.ESCAPE);
});
async function testDateLikeColumn(colId: 'Date'|'DateTime') {
const timeChunk = colId === 'DateTime' ? ' 12:00am' : '';
const colRegex = new RegExp(colId + '\\b');
// add Date Filter
await driver.find('.test-add-filter-btn').click();
await driver.findContent('.grist-floating-menu li', colRegex).click();
// set min to '2019-07-16'
await gu.setRangeFilterBound('min', '2019-07-16');
await driver.find('.test-filter-menu-apply-btn').click();
await gu.waitAppFocus(true);
// check values
assert.deepEqual(
await gu.getVisibleGridCells({cols: ['Name', colId], rowNums: [1, 2, 3, 4]}),
[ 'Apples', '2019-07-17' + timeChunk,
'Oranges', '2019-07-16' + timeChunk,
'Bananas', '2019-07-18' + timeChunk,
'', ''
]
);
// reopen the filter
await driver.findContent('.test-filter-field', colRegex).click();
// set max to '2019-07-17'
await gu.setRangeFilterBound('max', '2019-07-17');
await driver.find('.test-filter-menu-apply-btn').click();
await gu.waitAppFocus(true);
assert.deepEqual(
await gu.getVisibleGridCells({cols: ['Name', colId], rowNums: [1, 2, 3, 4]}),
[ 'Apples', '2019-07-17' + timeChunk,
'Oranges', '2019-07-16' + timeChunk,
'', '',
undefined, undefined
]
);
// remove both min and max
await driver.findContent('.test-filter-field', colRegex).click();
await gu.setRangeFilterBound('min', null);
await gu.setRangeFilterBound('max', null);
await driver.find('.test-filter-menu-apply-btn').click();
await gu.waitAppFocus(true);
// check all values are there
assert.deepEqual(
await gu.getVisibleGridCells({cols: ['Name', colId], rowNums: [1, 2, 3, 4, 5, 6, 7]}),
[ 'Apples', '2019-07-17' + timeChunk,
'Oranges', '2019-07-16' + timeChunk,
'Bananas', '2019-07-18' + timeChunk,
'Grapes', '',
'Grapefruit', '2019-07-15' + timeChunk,
'Clementines', 'n/a',
'Apples', '',
]);
}
it('should show a working range filter for Date column', async function() {
await testDateLikeColumn('Date');
});
it('should show a working range filter for DateTime column', async function() {
// adds a DateTime column
await api.applyUserActions(doc.id, [
['AddVisibleColumn', 'Table1', 'DateTime', {
type: "DateTime:UTC", widgetOptions: '{"dateFormat": "YYYY-MM-DD", "timeFormat": "h:mma"}'
}],
['BulkUpdateRecord', 'Table1', [1, 2, 3, 4, 5, 6], {
DateTime: [
// TODO: fix timezone
"2019-07-17T00:00Z",
"2019-07-16T00:00Z",
"2019-07-18T00:00Z",
"",
"2019-07-15T00:00Z",
"n/a",
]
}],
]);
await testDateLikeColumn('DateTime');
});
it('should have working date range filter also when column is hidden', async function() {
// hide Date column
await gu.toggleSidePanel('right', 'open');
await driver.find('.test-right-tab-pagewidget').click();
await gu.moveToHidden('Date');
// add Date filter
await driver.findContent('.test-filter-field', 'Date').click();
// start typing date in min bounds and send TAB
await driver.find('.test-filter-menu-min').click();
await gu.sendKeys('2019-07-14', Key.TAB);
// check min is set to a valid date
assert.equal(await driver.find('.test-filter-menu-min input').value(), '2019-07-14');
});
});

@ -0,0 +1,120 @@
import * as gu from 'test/nbrowser/gristUtils';
import { setupTestSuite } from "test/nbrowser/testUtils";
import { assert, driver } from 'mocha-webdriver';
function getItems() {
return driver.findAll('.test-filter-menu-list label', async (e) => ({
checked: await e.find('input').isSelected(),
label: await e.getText(),
count: await e.findClosest('div').find('.test-filter-menu-count').getText()
}));
}
describe('ColumnFilterMenu2', function() {
this.timeout(20000);
const cleanup = setupTestSuite();
let mainSession: gu.Session;
let docId: string;
let api: any;
before(async function() {
mainSession = await gu.session().teamSite.user('user1').login();
docId = await mainSession.tempNewDoc(cleanup, 'ColumnFilterMenu2.grist', {load: false});
api = mainSession.createHomeApi();
// Prepare a table with some interestingly-formatted columns, and some data.
await api.applyUserActions(docId, [
['AddTable', 'Test', []],
['AddVisibleColumn', 'Test', 'Bool', {
type: 'Bool', widgetOptions: JSON.stringify({widget:"TextBox"})
}],
['AddVisibleColumn', 'Test', 'Choice', {
type: 'Choice', widgetOptions: JSON.stringify({choices: ['foo', 'bar']})
}],
['AddVisibleColumn', 'Test', 'ChoiceList', {
type: 'ChoiceList', widgetOptions: JSON.stringify({choices: ['foo', 'bar']})
}],
['AddRecord', 'Test', null, {Bool: true, Choice: 'foo', ChoiceList: ['L', 'foo']}],
]);
return docId;
});
afterEach(() => gu.checkForErrors());
it('should show all options for Bool columns', async () => {
await mainSession.loadDoc(`/doc/${docId}/p/2`);
await gu.openColumnMenu('Bool', 'Filter');
assert.deepEqual(await getItems(), [
{checked: true, label: 'false', count: '0'},
{checked: true, label: 'true', count: '1'},
]);
// click false
await driver.findContent('.test-filter-menu-list label', 'false').click();
assert.deepEqual(await getItems(), [
{checked: false, label: 'false', count: '0'},
{checked: true, label: 'true', count: '1'},
]);
// add new record with Bool=false
const {retValues} = await api.applyUserActions(docId, [
['AddRecord', 'Test', null, {Bool: false}],
]);
// check record is not shown on screen
assert.deepEqual(
await gu.getVisibleGridCells({cols: ['Bool', 'Choice', 'ChoiceList'], rowNums: [1, 2]}),
['true', 'foo', 'foo',
'', '', ''
] as any
);
// remove added record
await api.applyUserActions(docId, [
['RemoveRecord', 'Test', retValues[0]]
]);
});
it('should show all options for Choice/ChoiceList columns', async () => {
await gu.openColumnMenu('Choice', 'Filter');
assert.deepEqual(await getItems(), [
{checked: true, label: 'bar', count: '0'},
{checked: true, label: 'foo', count: '1'},
]);
// click bar
await driver.findContent('.test-filter-menu-list label', 'bar').click();
assert.deepEqual(await getItems(), [
{checked: false, label: 'bar', count: '0'},
{checked: true, label: 'foo', count: '1'},
]);
// add new record with Choice=bar
const {retValues} = await api.applyUserActions(docId, [
['AddRecord', 'Test', null, {Choice: 'bar'}],
]);
// check record is not shown on screen
assert.deepEqual(
await gu.getVisibleGridCells({cols: ['Bool', 'Choice', 'ChoiceList'], rowNums: [1, 2]}),
['true', 'foo', 'foo',
'', '', ''
] as any
);
// remove added record
await api.applyUserActions(docId, [
['RemoveRecord', 'Test', retValues[0]]
]);
// check ChoiceList filter offeres all options
await gu.openColumnMenu('ChoiceList', 'Filter');
assert.deepEqual(await getItems(), [
{checked: true, label: 'bar', count: '0'},
{checked: true, label: 'foo', count: '1'},
]);
});
});

@ -0,0 +1,211 @@
import { assert, driver, Key } from "mocha-webdriver";
import * as gu from 'test/nbrowser/gristUtils';
import { setupTestSuite } from "test/nbrowser/testUtils";
void(driver);
void(Key);
async function getValues() {
return driver.findAll('.test-filter-menu-list label', e => e.getText());
}
describe('ColumnFilterMenu3', function() {
this.timeout(30000);
const cleanup = setupTestSuite();
let mainSession: gu.Session;
let docId: string;
before(async () => {
mainSession = await gu.session().teamSite.user('user1').login();
docId = await mainSession.tempNewDoc(cleanup, 'Search3.grist', {load: false});
const api = mainSession.createHomeApi();
// Prepare a table with some interestingly-formatted columns, and some data.
const {retValues} = await api.applyUserActions(docId, [
['AddTable', 'Test', []],
['AddVisibleColumn', 'Test', 'Date', {type: 'Date', widgetOptions: '{"dateFormat":"DD-MM-YYYY"}'}],
['AddVisibleColumn', 'Test', 'Numeric', {type: 'Numeric'}],
['AddVisibleColumn', 'Test', 'Int', {type: 'Int'}],
['AddVisibleColumn', 'Test', 'Ref', {type: 'Ref:Test'}],
['AddVisibleColumn', 'Test', 'RefList', {type: 'RefList:Test'}],
]);
await api.applyUserActions(docId, [
['UpdateRecord', '_grist_Tables_column', retValues[4].colRef, {visibleCol: retValues[1].colRef}],
['UpdateRecord', '_grist_Tables_column', retValues[5].colRef, {visibleCol: retValues[1].colRef}],
['SetDisplayFormula', 'Test', null, retValues[4].colRef, '$Ref.Date'],
['SetDisplayFormula', 'Test', null, retValues[5].colRef, '$RefList.Date'],
['AddRecord', 'Test', null, {Date: '22-12-2011', Numeric: 2, Int: 2, Ref: 1,
RefList: ['L', 1, 2]}],
['AddRecord', 'Test', null, {Date: '20-12-2021', Numeric: 22, Int: 22, Ref: 2,
RefList: ['L', 1]}],
['AddRecord', 'Test', null, {Date: '20-12-2011', Numeric: 3, Int: 3, Ref: 3,
RefList: ['L', 1, 2, 3]}],
]);
await mainSession.loadDoc(`/doc/${docId}/p/2`);
});
afterEach(async () => {
// close menu if one was opened
if (await driver.find('.grist-floating-menu').isPresent()) {
await driver.sendKeys(Key.ESCAPE);
}
if (await driver.find('.test-filter-menu-wrapper').isPresent()) {
await driver.sendKeys(Key.ESCAPE);
}
});
it('should correctly focus between inputs in Numeric columns', async () => {
// A bug was introduced where the search input could no longer be focused if either range
// input had focus.
await gu.openColumnMenu('Numeric', 'Filter');
const assertSearchCanBeFocused = async () => {
await driver.find('.test-filter-menu-search-input').click();
assert.equal(
await driver.switchTo().activeElement().getId(),
await driver.find('.test-filter-menu-search-input').getId()
);
};
await driver.find('.test-filter-menu-min').click();
await assertSearchCanBeFocused();
await driver.find('.test-filter-menu-max').click();
await assertSearchCanBeFocused();
});
it('should have correct order for Numeric column', async () => {
await gu.openColumnMenu('Numeric', 'Filter');
assert.deepEqual(await getValues(), ['2', '3', '22']);
});
it('should have correct order for Integer column', async () => {
await gu.openColumnMenu('Int', 'Filter');
assert.deepEqual(await getValues(), ['2', '3', '22']);
await driver.find('.test-filter-menu-apply-btn');
});
it('should have correct order for Date column', async () => {
await gu.openColumnMenu('Date', 'Filter');
assert.deepEqual(await getValues(), ['20-12-2011', '22-12-2011', '20-12-2021']);
});
describe('Ref', function() {
it('should have correct order for Numeric column', async () => {
await gu.toggleSidePanel('right', 'open');
await gu.openColumnMenu('Ref', 'Options');
await gu.setRefShowColumn('Numeric');
await gu.openColumnMenu('Ref', 'Filter');
assert.deepEqual(await getValues(), ['2', '3', '22']);
});
it('should have correct order for Integer column', async () => {
await gu.setRefShowColumn('Int');
await gu.openColumnMenu('Ref', 'Filter');
assert.deepEqual(await getValues(), ['2', '3', '22']);
});
it('should have correct order for Date column', async () => {
await gu.setRefShowColumn('Date');
await gu.openColumnMenu('Ref', 'Filter');
assert.deepEqual(await getValues(), ['20-12-2011', '22-12-2011', '20-12-2021']);
});
});
describe('RefList', function() {
it('should have correct order for Numeric column', async () => {
await gu.openColumnMenu('RefList', 'Options');
await gu.setRefShowColumn('Numeric');
await gu.openColumnMenu('RefList', 'Filter');
assert.deepEqual(await getValues(), ['2', '3', '22']);
});
it('should have correct order for Integer column', async () => {
await gu.setRefShowColumn('Int');
await gu.openColumnMenu('RefList', 'Filter');
assert.deepEqual(await getValues(), ['2', '3', '22']);
});
it('should have correct order for Date column', async () => {
await gu.setRefShowColumn('Date');
await gu.openColumnMenu('RefList', 'Filter');
assert.deepEqual(await getValues(), ['20-12-2011', '22-12-2011', '20-12-2021']);
});
});
describe('id mismatch', function() {
// This test intent to replicate a bug that happened with filters. For the bug to happen we need
// to have a view field row id (here view field of col B) that matches the row id of another
// column (here col A). When this happen, and when col A is hidden, and when users open the
// column menu for B, the filter apply mistakingly to column A values as well, which could
// intail unexpected result depending on the values of A.
let docId2: string;
before(async () => {
docId2 = await mainSession.tempNewDoc(cleanup, 'ColumnFilterMenu3IdMismatch.grist', {load: false});
const api = mainSession.createHomeApi();
await api.applyUserActions(docId2, [
['BulkAddRecord', 'Table1', [null, null, null], {A: [1, 3, 3], B: [1, 1, 3]}],
['RemoveRecord', "_grist_Views_section_field", 1], // Hide 'A' column
]);
});
it('filters should work correctly', async function() {
await mainSession.loadDoc(`/doc/${docId2}/p/1`);
// filter B by {max: 2}
await gu.openColumnMenu('B', 'Filter');
await gu.setRangeFilterBound('max', '2');
await driver.find('.test-filter-menu-apply-btn').click();
// check filter does not behaves in-correctly (here mostly to show what the problem looked
// like)
assert.notDeepEqual(
await gu.getVisibleGridCells({cols: ['B'], rowNums: [1, 2, 3]}),
[ '1', '', undefined]
);
// check filter does behave correctly
assert.deepEqual(
await gu.getVisibleGridCells({cols: ['B'], rowNums: [1, 2, 3]}),
[ '1', '1', '']
);
});
});
describe('empty choice columns', function() {
// Previously, a bug would cause an error to be thrown when filtering an empty
// choice or choice list column. This suite replicates that scenario.
async function assertEmptyRowCount(count: number) {
assert.deepEqual(
await driver.findAll('.test-filter-menu-list label', (e) => e.getText()),
['']
);
assert.deepEqual(
await driver.findAll('.test-filter-menu-list .test-filter-menu-count', (e) => e.getText()),
[count.toString()],
);
}
async function assertEmptyColumnIsFilterable(
columnType: 'Choice' | 'Choice List' | 'Reference List'
) {
const columnLabel = `Empty ${columnType}`;
await gu.addColumn(columnLabel);
await gu.setType(new RegExp(`${columnType}$`));
await gu.openColumnMenu(columnLabel, 'Filter');
await assertEmptyRowCount(2);
await gu.sendKeys(Key.ESCAPE);
}
afterEach(() => gu.checkForErrors());
it('should not throw an error when filtering empty choice columns', async function() {
await assertEmptyColumnIsFilterable('Choice');
});
it('should not throw an error when filtering empty choice list columns', async function() {
await assertEmptyColumnIsFilterable('Choice List');
});
it('should not throw an error when filtering empty reference list columns', async function() {
// Note: this wasn't impacted by the aforementioned bug; this test is only included for
// completeness.
await assertEmptyColumnIsFilterable('Reference List');
});
});
});

@ -0,0 +1,531 @@
import {assert, driver, Key, until} from 'mocha-webdriver';
import * as gu from 'test/nbrowser/gristUtils';
import {setupTestSuite} from 'test/nbrowser/testUtils';
describe('SectionFilter', function() {
this.timeout(60000);
const cleanup = setupTestSuite();
describe('Core tests', function() {
before(async function() {
this.timeout(10000);
const session = await gu.session().teamSite.login();
await session.tempNewDoc(cleanup);
});
it('should be able to open / close filter menu', async () => {
const menu = await gu.openColumnMenu('A', 'Filter');
assert.equal(await menu.find('.test-filter-menu-list').getText(), 'No matching values');
await driver.sendKeys(Key.ESCAPE);
await driver.wait(until.stalenessOf(menu));
});
it('should filter out records in response to filter menu selections', async () => {
this.timeout(10000);
await gu.enterGridRows({col: 'A', rowNum: 1}, [
['Apples', '1'],
['Oranges', '2'],
['Bananas', '1'],
['Apples', '2'],
['Bananas', '1'],
['Apples', '2'],
]);
const menu = await gu.openColumnMenu('A', 'Filter');
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: true, value: 'Apples', count: 3},
{ checked: true, value: 'Bananas', count: 2},
{ checked: true, value: 'Oranges', count: 1}
]);
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3, 4, 5, 6]),
['Apples', 'Oranges', 'Bananas', 'Apples', 'Bananas', 'Apples']);
await menu.findContent('label', /Apples/).click();
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: false, value: 'Apples', count: 3},
{ checked: true, value: 'Bananas', count: 2},
{ checked: true, value: 'Oranges', count: 1}
]);
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3]),
['Oranges', 'Bananas', 'Bananas']);
await menu.findContent('label', /Apples/).click();
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: true, value: 'Apples', count: 3},
{ checked: true, value: 'Bananas', count: 2},
{ checked: true, value: 'Oranges', count: 1}
]);
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3, 4, 5, 6]),
['Apples', 'Oranges', 'Bananas', 'Apples', 'Bananas', 'Apples']);
await driver.sendKeys(Key.ESCAPE);
});
it('should undo filter changes on cancel', async () => {
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3, 4, 5, 6]),
['Apples', 'Oranges', 'Bananas', 'Apples', 'Bananas', 'Apples']);
const menu = await gu.openColumnMenu('A', 'Filter');
await menu.findContent('label', /Apples/).click();
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: false, value: 'Apples', count: 3},
{ checked: true, value: 'Bananas', count: 2},
{ checked: true, value: 'Oranges', count: 1}
]);
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3]),
['Oranges', 'Bananas', 'Bananas']);
await menu.find('.test-filter-menu-cancel-btn').click();
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3, 4, 5, 6]),
['Apples', 'Oranges', 'Bananas', 'Apples', 'Bananas', 'Apples']);
});
it('should display new/updated rows even when only certain values are filtered in', async () => {
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3, 4, 5, 6]),
['Apples', 'Oranges', 'Bananas', 'Apples', 'Bananas', 'Apples']);
let menu = await gu.openColumnMenu('A', 'Filter');
// Put the filter into the "inclusion" state, with nothing selected initially.
assert.deepEqual(
await driver.findAll('.test-filter-menu-bulk-action:not(:disabled)', (e) => e.getText()),
['None']);
await driver.findContent('.test-filter-menu-bulk-action', /None/).click();
assert.deepEqual(
await driver.findAll('.test-filter-menu-bulk-action:not(:disabled)', (e) => e.getText()),
['All']);
// Include only "Apples".
await menu.findContent('label', /Apples/).click();
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: true, value: 'Apples', count: 3},
{ checked: false, value: 'Bananas', count: 2},
{ checked: false, value: 'Oranges', count: 1}
]);
await driver.find('.test-filter-menu-apply-btn').click();
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3, 4]),
['Apples', 'Apples', 'Apples', '']);
// Update first row to Oranges; it should remain shown.
await gu.getCell(0, 1).click();
await gu.enterCell('Oranges');
// Enter a new row using a keyboard shortcut.
await driver.find('body').sendKeys(Key.chord(await gu.modKey(), Key.ENTER));
// Enter a new row by typing in a value into the "add-row".
await driver.find('.gridview_row .record-add .field').click();
await gu.enterCell('Bananas');
// Ensure all 3 changes are visible.
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3, 4, 5, 6]),
['Oranges', 'Apples', '', 'Apples', 'Bananas', '']);
// Check that the filter menu looks as expected.
menu = await gu.openColumnMenu('A', 'Filter');
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: false, value: '', count: 1},
{ checked: true, value: 'Apples', count: 2},
{ checked: false, value: 'Bananas', count: 3},
{ checked: false, value: 'Oranges', count: 2}
]);
// Apply the filter to make it only-Apples again.
await menu.find('.test-filter-menu-apply-btn').click();
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3]),
['Apples', 'Apples', '']);
// Reset the filter
menu = await gu.openColumnMenu('A', 'Filter');
assert.deepEqual(
await driver.findAll('.test-filter-menu-bulk-action:not([class*=-disabled])', (e) => e.getText()),
['All', 'None']);
await driver.findContent('.test-filter-menu-bulk-action', /All/).click();
await menu.find('.test-filter-menu-apply-btn').click();
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3, 4, 5, 6, 7, 8]),
['Oranges', 'Oranges', 'Bananas', 'Apples', 'Bananas', '', 'Apples', 'Bananas']);
// Restore changes of this test case.
await gu.undo(3);
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3, 4, 5, 6]),
['Apples', 'Oranges', 'Bananas', 'Apples', 'Bananas', 'Apples']);
});
it('should display new/updated rows even when filtered, but refilter on menu changes', async () => {
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3, 4, 5, 6]),
['Apples', 'Oranges', 'Bananas', 'Apples', 'Bananas', 'Apples']);
let menu = await gu.openColumnMenu('A', 'Filter');
await menu.findContent('label', /Apples/).click();
await driver.find('.test-filter-menu-apply-btn').click();
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3]),
['Oranges', 'Bananas', 'Bananas']);
// Update Oranges to Apples and make sure it's not filtered out
await (await gu.getCell(0, 1)).click();
await gu.enterCell('Apples');
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3]),
['Apples', 'Bananas', 'Bananas']);
// Set back to Oranges and make sure it stays
await driver.sendKeys(Key.UP);
await gu.enterCell('Oranges');
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3]),
['Oranges', 'Bananas', 'Bananas']);
// Enter two new rows and make sure they're also not filtered out
await driver.find('.gridview_row .record-add .field').click();
await gu.enterCell('Apples');
await gu.enterCell('Bananas');
// Enter a new row using a keyboard shortcut.
await driver.find('body').sendKeys(Key.chord(await gu.modKey(), Key.ENTER));
await gu.waitForServer();
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3, 4, 5, 6]),
['Oranges', 'Bananas', 'Bananas', 'Apples', 'Bananas', '']);
menu = await gu.openColumnMenu('A', 'Filter');
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: true, value: '', count: 1},
{ checked: false, value: 'Apples', count: 4},
{ checked: true, value: 'Bananas', count: 3},
{ checked: true, value: 'Oranges', count: 1}
]);
await menu.findContent('label', /Apples/).click();
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3, 4, 5, 6, 7, 8]),
['Apples', 'Oranges', 'Bananas', 'Apples', 'Bananas', 'Apples', 'Apples', 'Bananas']);
await menu.findContent('label', /Apples/).click();
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3, 4]),
['Oranges', 'Bananas', 'Bananas', 'Bananas']);
await driver.sendKeys(Key.ESCAPE);
});
});
describe('Type tests', function() {
before(async function() {
const session = await gu.session().teamSite.login();
await session.tempDoc(cleanup, 'FilterTest.grist');
});
it('should properly filter strings', async () => {
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3, 4, 5, 6, 7, 8]),
['Foo', 'Bar', '1', '2.0', '2016-01-01', '5+6', '', '']);
const menu = await gu.openColumnMenu('Text', 'Filter');
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: true, value: '', count: 1},
{ checked: true, value: '1', count: 1},
{ checked: true, value: '2.0', count: 1},
{ checked: true, value: '5+6', count: 1},
{ checked: true, value: '2016-01-01', count: 1},
{ checked: true, value: 'Bar', count: 1},
{ checked: true, value: 'Foo', count: 1}
]);
await menu.findContent('label', /^$/).click();
await menu.findContent('label', /Bar/).click();
assert.deepEqual(await gu.getVisibleGridCells(0, [1, 2, 3, 4, 5, 6, 7]),
['Foo', '1', '2.0', '2016-01-01', '5+6', '', undefined]);
await menu.find('.test-filter-menu-cancel-btn').click();
});
it('should properly filter numbers', async () => {
assert.deepEqual(await gu.getVisibleGridCells(1, [1, 2, 3, 4, 5, 6, 7, 8]),
['5.00', '6.00', '7.00', '-1.00', 'foo', '0.00', '', '']);
const menu = await gu.openColumnMenu('Number', 'Filter');
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: true, value: '', count: 1},
{ checked: true, value: 'foo', count: 1},
{ checked: true, value: '-1.00', count: 1},
{ checked: true, value: '0.00', count: 1},
{ checked: true, value: '5.00', count: 1},
{ checked: true, value: '6.00', count: 1},
{ checked: true, value: '7.00', count: 1},
]);
await menu.findContent('label', /^$/).click();
await menu.findContent('label', /7/).click();
await menu.findContent('label', /foo/).click();
assert.deepEqual(await gu.getVisibleGridCells(1, [1, 2, 3, 4, 5, 6]),
['5.00', '6.00', '-1.00', '0.00', '', undefined]);
await menu.find('.test-filter-menu-cancel-btn').click();
});
it('should properly filter dates', async () => {
assert.deepEqual(await gu.getVisibleGridCells(2, [1, 2, 3, 4, 5, 6, 7, 8]),
['2019-06-03', '2019-06-07', '2019-06-05', 'bar', '2019-06-123', '0', '', '']);
const menu = await gu.openColumnMenu('Date', 'Filter');
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: true, value: '', count: 1},
{ checked: true, value: '2019-06-123', count: 1},
{ checked: true, value: 'bar', count: 1},
{ checked: true, value: '0', count: 1},
{ checked: true, value: '2019-06-03', count: 1},
{ checked: true, value: '2019-06-05', count: 1},
{ checked: true, value: '2019-06-07', count: 1},
]);
await menu.findContent('label', /^$/).click();
await menu.findContent('label', /2019-06-05/).click();
await menu.findContent('label', /bar/).click();
assert.deepEqual(await gu.getVisibleGridCells(2, [1, 2, 3, 4, 5, 6]),
['2019-06-03', '2019-06-07', '2019-06-123', '0', '', undefined]);
await menu.find('.test-filter-menu-cancel-btn').click();
});
it('should properly search through list of date to filter', async () => {
const menu = await gu.openColumnMenu('Date', 'Filter');
assert.lengthOf(await gu.getFilterMenuState(), 7);
await driver.sendKeys('07');
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: true, value: '2019-06-07', count: 1}
]);
assert.deepEqual(
await menu.findAll('.test-filter-menu-list label', (e) => e.getText()),
['2019-06-07']
);
await menu.findContent('.test-filter-menu-bulk-action', /All Shown/).click();
assert.deepEqual(
await gu.getVisibleGridCells(2, [1, 2]),
['2019-06-07', '']
);
await menu.find('.test-filter-menu-cancel-btn').click();
});
it('should properly filter formulas', async () => {
assert.deepEqual(await gu.getVisibleGridCells(3, [1, 2, 3, 4, 5, 6, 7, 8]),
['25', '36', '49', '1', '#TypeError', '0', '#TypeError', '']);
const menu = await gu.openColumnMenu('Formula', 'Filter');
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: true, value: '#TypeError', count: 2},
{ checked: true, value: '0', count: 1},
{ checked: true, value: '1', count: 1},
{ checked: true, value: '25', count: 1},
{ checked: true, value: '36', count: 1},
{ checked: true, value: '49', count: 1},
]);
await menu.findContent('label', /0/).click();
await menu.findContent('label', /#TypeError/).click();
await menu.findContent('label', /25/).click();
assert.deepEqual(await gu.getVisibleGridCells(3, [1, 2, 3, 4, 5]),
['36', '49', '1', '', undefined]);
await menu.find('.test-filter-menu-cancel-btn').click();
});
it('should properly filter references', async () => {
assert.deepEqual(await gu.getVisibleGridCells(4, [1, 2, 3, 4, 5, 6, 7, 8]),
['alice', 'carol', 'bob', 'denis', '0', 'denis', '', '']);
const menu = await gu.openColumnMenu('Reference', 'Filter');
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: true, value: '', count: 1},
{ checked: true, value: '#Invalid Ref: 0', count: 1},
{ checked: true, value: '#Invalid Ref: denis', count: 2},
{ checked: true, value: 'alice', count: 1},
{ checked: true, value: 'bob', count: 1},
{ checked: true, value: 'carol', count: 1},
]);
await menu.findContent('label', /^$/).click();
await menu.findContent('label', /#Invalid Ref: denis/).click();
await menu.findContent('label', /bob/).click();
assert.deepEqual(await gu.getVisibleGridCells(4, [1, 2, 3, 4, 5]),
['alice', 'carol', '0', '', undefined]);
await menu.find('.test-filter-menu-cancel-btn').click();
});
it('should properly filter choice lists', async () => {
assert.deepEqual(await gu.getVisibleGridCells(5, [1, 2, 3, 4, 5, 6, 7, 8]),
['Foo\nBar\nBaz', 'Foo\nBar', 'Foo', 'InvalidChoice', 'Baz\nBaz\nBaz', 'Bar\nBaz', '', '']);
const menu = await gu.openColumnMenu('ChoiceList', 'Filter');
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: true, value: '', count: 1},
{ checked: true, value: 'Bar', count: 3},
{ checked: true, value: 'Baz', count: 5},
{ checked: true, value: 'Foo', count: 3},
{ checked: true, value: 'InvalidChoice', count: 1},
]);
// Check that all the choices are rendered in the right colors.
const choiceColors = await menu.findAll(
'label .test-filter-menu-choice-token',
async (c) => [await c.getCssValue('background-color'), await c.getCssValue('color')]
);
assert.deepEqual(
choiceColors,
[
[ 'rgba(254, 204, 129, 1)', 'rgba(0, 0, 0, 1)' ],
[ 'rgba(53, 253, 49, 1)', 'rgba(0, 0, 0, 1)' ],
[ 'rgba(204, 254, 254, 1)', 'rgba(0, 0, 0, 1)' ],
[ 'rgba(255, 255, 255, 1)', 'rgba(0, 0, 0, 1)' ]
]
);
// Check that Foo is rendered with font options.
const boldFonts = await menu.findAll(
'label .test-filter-menu-choice-token.font-italic.font-bold',
(c) => c.getText()
);
assert.deepEqual(boldFonts, ['Foo']);
await menu.findContent('label', /^$/).click();
await menu.findContent('label', /Bar/).click();
await menu.findContent('label', /Baz/).click();
assert.deepEqual(await gu.getVisibleGridCells(5, [1, 2, 3, 4, 5]),
['Foo\nBar\nBaz', 'Foo\nBar', 'Foo', 'InvalidChoice', '']);
await menu.find('.test-filter-menu-cancel-btn').click();
});
it('should properly filter errors in choice lists', async () => {
assert.deepEqual(await gu.getVisibleGridCells(6, [1, 2, 3, 4, 5, 6, 7, 8]),
['25.0', '36.0', '49.0', '1.0', '#TypeError', '', '#TypeError', '']);
await gu.scrollIntoView(gu.getColumnHeader('ChoiceListErrors'));
const menu = await gu.openColumnMenu('ChoiceListErrors', 'Filter');
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: true, value: '', count: 1},
{ checked: true, value: '#TypeError', count: 2},
{ checked: true, value: '1.0', count: 1},
{ checked: true, value: '25.0', count: 1},
{ checked: true, value: '36.0', count: 1},
{ checked: true, value: '49.0', count: 1},
{ checked: true, value: 'A', count: 0},
{ checked: true, value: 'B', count: 0},
{ checked: true, value: 'C', count: 0},
{ checked: true, value: 'D', count: 0},
]);
await menu.findContent('label', /^$/).click();
await menu.findContent('label', /#TypeError/).click();
await menu.findContent('label', /25\.0/).click();
await menu.findContent('label', /36\.0/).click();
await menu.findContent('label', /49\.0/).click();
assert.deepEqual(await gu.getVisibleGridCells(6, [1, 2]),
['1.0', '']);
await menu.find('.test-filter-menu-cancel-btn').click();
});
it('should properly filter choices', async () => {
assert.deepEqual(await gu.getVisibleGridCells(7, [1, 2, 3, 4, 5, 6, 7, 8]),
['Red', 'Orange', 'Yellow', 'InvalidChoice', '', 'Red', '', '']);
const menu = await gu.openColumnMenu('Choice', 'Filter');
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: true, value: '', count: 2},
{ checked: true, value: 'InvalidChoice', count: 1},
{ checked: true, value: 'Orange', count: 1},
{ checked: true, value: 'Red', count: 2},
{ checked: true, value: 'Yellow', count: 1},
]);
// Check that all the choices are rendered in the right colors.
const choiceColors = await menu.findAll(
'label .test-filter-menu-choice-token',
async (c) => [await c.getCssValue('background-color'), await c.getCssValue('color')]
);
assert.deepEqual(
choiceColors,
[
[ 'rgba(255, 255, 255, 1)', 'rgba(0, 0, 0, 1)' ],
[ 'rgba(254, 204, 129, 1)', 'rgba(0, 0, 0, 1)' ],
[ 'rgba(252, 54, 59, 1)', 'rgba(255, 255, 255, 1)' ],
[ 'rgba(255, 250, 205, 1)', 'rgba(0, 0, 0, 1)' ]
]
);
// Check that Red is rendered with font options.
const withFonts = await menu.findAll(
'label .test-filter-menu-choice-token.font-underline.font-strikethrough',
(c) => c.getText()
);
assert.deepEqual(withFonts, ['Red']);
await menu.findContent('label', /InvalidChoice/).click();
await menu.findContent('label', /Orange/).click();
await menu.findContent('label', /Yellow/).click();
assert.deepEqual(await gu.getVisibleGridCells(7, [1, 2, 3, 4, 5]),
['Red', '', 'Red', '', '']);
await menu.find('.test-filter-menu-cancel-btn').click();
});
it('should properly filter reference lists', async () => {
assert.deepEqual(await gu.getVisibleGridCells(8, [1, 2, 3, 4, 5, 6, 7, 8]),
['alice\ncarol', 'bob', 'carol\nbob\nalice', '[u\'denis\']', '[u\'0\']', '[u\'denis\', u\'edward\']', '', '']);
const menu = await gu.openColumnMenu('ReferenceList', 'Filter');
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: true, value: '', count: 1 },
{ checked: true, value: '#Invalid RefList: [u\'0\']', count: 1 },
{
checked: true,
value: '#Invalid RefList: [u\'denis\', u\'edward\']',
count: 1
},
{
checked: true,
value: '#Invalid RefList: [u\'denis\']',
count: 1
},
{ checked: true, value: 'alice', count: 2 },
{ checked: true, value: 'bob', count: 2 },
{ checked: true, value: 'carol', count: 2 }
]);
await menu.findContent('label', /^$/).click();
await menu.findContent('label', /bob/).click();
await menu.findContent('label', /#Invalid RefList: \[u'0'\]/).click();
assert.deepEqual(await gu.getVisibleGridCells(8, [1, 2, 3, 4, 5]),
['alice\ncarol', 'carol\nbob\nalice', '[u\'denis\']', '[u\'denis\', u\'edward\']', '']);
await menu.find('.test-filter-menu-cancel-btn').click();
});
it('should reflect the section show column setting in the filter menu', async () => {
// Scroll col 3 into view to make sure col 4 is clickable
await gu.scrollIntoView(gu.getCell(3, 1));
// Change the show column setting of the Reference column to 'color'.
await gu.getCell(4, 1).click();
await gu.toggleSidePanel('right', 'open');
await driver.find('.test-right-tab-field').click();
await gu.setRefShowColumn('color');
// Open the filter menu for Reference, and check that the values are now from 'color'.
const menu = await gu.openColumnMenu('Reference', 'Filter');
assert.deepEqual(await gu.getFilterMenuState(), [
{ checked: true, value: '', count: 1 },
{ checked: true, value: '#Invalid Ref: 0', count: 1 },
{ checked: true, value: '#Invalid Ref: denis', count: 2 },
{ checked: true, value: 'blue', count: 1 },
{ checked: true, value: 'green', count: 1 },
{ checked: true, value: 'red', count: 1 }
]);
await menu.find('.test-filter-menu-cancel-btn').click();
});
});
});
Loading…
Cancel
Save