gristlabs_grist-core/test/nbrowser/NumericEditor.ts

150 lines
6.2 KiB
TypeScript
Raw Normal View History

import type {UserAPI} from 'app/common/UserAPI';
import * as gu from 'test/nbrowser/gristUtils';
import {setupTestSuite} from 'test/nbrowser/testUtils';
import {assert, driver, Key} from 'mocha-webdriver';
describe('NumericEditor', function() {
this.timeout(20000);
const cleanup = setupTestSuite();
afterEach(() => gu.checkForErrors());
interface Entry {
initial: string;
workaround?: () => Promise<void>;
expect: string;
exp0: string;
expPlain: string;
expFmt: string;
}
interface TestOpts {
localeCode: string;
locale: string;
entriesByColumn: Entry[];
valPlain: string;
valFmt: string;
}
describe('locale en-US', testSuite({
localeCode: 'en-US',
locale: 'United States (English)',
entriesByColumn: [
{initial: '17', expect: '17', exp0: '0', expPlain: '-4.4', expFmt: '-1234.56' },
{initial: '17.500', expect: '17.500', exp0: '0.000', expPlain: '-4.400', expFmt: '-1234.560' },
{initial: '(1.2)', expect: '(1.2)', exp0: ' 0 ', expPlain: '(4.4)', expFmt: '(1234.56)' },
{initial: '1000.456', expect: '1000.456', exp0: '0', expPlain: '-4.4', expFmt: '-1234.56' },
{initial: '1,000.0', expect: '1,000.0', exp0: '0.0', expPlain: '-4.4', expFmt: '-1,234.56' },
{initial: '$5.00', expect: '$5.00', exp0: '$0.00', expPlain: '-$4.40', expFmt: '-$1,234.56'},
{initial: '4.5%', expect: '4.5%', exp0: '0%', expPlain: '-440%', expFmt: '-123,456%' },
],
valPlain: '-4.4',
valFmt: '(1,234.56)',
}));
describe('locale de-DE', testSuite({
localeCode: 'de-DE',
locale: 'Germany (German)',
entriesByColumn: [
{initial: '17', expect: '17', exp0: '0', expPlain: '-4,4', expFmt: '-1234,56' },
{initial: '17,500', expect: '17,500', exp0: '0,000', expPlain: '-4,400', expFmt: '-1234,560' },
{initial: '(1,2)', expect: '(1,2)', exp0: ' 0 ', expPlain: '(4,4)', expFmt: '(1234,56)' },
{initial: '1000,456', expect: '1000,456', exp0: '0', expPlain: '-4,4', expFmt: '-1234,56' },
{initial: '1.000,0', expect: '1.000,0', exp0: '0,0', expPlain: '-4,4', expFmt: '-1.234,56', },
{initial: '5,00€', expect: '5,00 €', exp0: '0,00 €', expPlain: '-4,40 €', expFmt: '-1.234,56 €' },
{initial: '4,5%', expect: '4,5 %', exp0: '0 %', expPlain: '-440 %', expFmt: '-123.456 %' },
],
valPlain: '-4,4',
valFmt: '(1.234,56)',
}));
function testSuite(options: TestOpts) {
const {entriesByColumn} = options;
return function() {
let docId: string;
let api: UserAPI;
let MODKEY: string;
before(async function() {
MODKEY = await gu.modKey();
const session = await gu.session().login();
docId = await session.tempNewDoc(cleanup, `NumericEditor-${options.localeCode}`);
api = session.createHomeApi();
await api.applyUserActions(docId, [
// Make sure there are as many columns as entriesByColumn.
...entriesByColumn.slice(3).map(() => ['AddVisibleColumn', 'Table1', '', {}]),
]);
// Set locale for the document.
await gu.openDocumentSettings();
await driver.findWait('.test-locale-autocomplete', 500).click();
await driver.sendKeys(options.locale, Key.ENTER);
await gu.waitForServer();
assert.equal(await driver.find('.test-locale-autocomplete input').value(), options.locale);
await gu.openPage('Table1');
});
beforeEach(async function() {
// Scroll grid to the left before each test case.
await gu.sendKeys(Key.HOME);
});
it('should create Numeric columns with suitable format', async function() {
// Entering a value into an empty column should switch it to a suitably formatted Numeric.
for (const [i, entry] of Object.entries(entriesByColumn)) {
await gu.getCell({rowNum: 1, col: Number(i)}).click();
await entry.workaround?.();
await gu.enterCell(entry.initial);
assert.equal(await gu.getCell({rowNum: 1, col: Number(i)}).getText(), entry.expect);
}
// Add a new row, which should be filled with 0's. Check what formatted 0's look like.
await gu.sendKeys(Key.chord(MODKEY, Key.ENTER));
await gu.waitForServer();
// Check what 0's look like.
for (const [i, entry] of Object.entries(entriesByColumn)) {
assert.equal(await gu.getCell({rowNum: 2, col: Number(i)}).getText(), entry.exp0);
}
});
it('should support entering plain numbers into a formatted column', async function() {
const rowNum = 3;
const cols = entriesByColumn.map((_, i) => i);
await gu.enterGridRows({rowNum, col: 0},
[ entriesByColumn.map(() => options.valPlain) ]);
assert.deepEqual(await gu.getVisibleGridCells({rowNums: [rowNum], cols}),
entriesByColumn.map((entry) => entry.expPlain));
});
it('should support entering formatted numbers into a formatted column', async function() {
const rowNum = 4;
const cols = entriesByColumn.map((_, i) => i);
await gu.enterGridRows({rowNum, col: 0},
[ entriesByColumn.map(() => options.valFmt) ]);
assert.deepEqual(await gu.getVisibleGridCells({rowNums: [rowNum], cols}),
entriesByColumn.map((entry) => entry.expFmt));
});
it('should allow editing and saving a formatted value', async function() {
for (const [i, entry] of Object.entries(entriesByColumn)) {
await gu.getCell({rowNum: 1, col: Number(i)}).click();
await gu.sendKeys(Key.ENTER);
await gu.waitAppFocus(false);
// Save the value the way it's opened in the editor. It's important that it doesn't
// change interpretation (there was a bug related to this, when a value with "," decimal
// separator would open with a "." decimal separator, and get saved back incorrectly).
await gu.sendKeys(Key.ENTER);
await gu.waitForServer();
await gu.waitAppFocus(true);
assert.equal(await gu.getCell({rowNum: 1, col: Number(i)}).getText(), entry.expect);
}
});
};
}
});