gristlabs_grist-core/test/nbrowser/TextEditor.ntest.js
Paul Fitzpatrick bcbf57d590 (core) bump mocha version to allow parallel tests; move more tests to core
Summary:
This uses a newer version of mocha in grist-core so that tests can be run in parallel. That allows more tests to be moved without slowing things down overall. Tests moved are venerable browser tests; only the ones that "just work" or worked without too much trouble to are moved, in order to keep the diff from growing too large. Will wrestle with more in follow up.

Parallelism is at the file level, rather than the individual test.

The newer version of mocha isn't needed for grist-saas repo; tests are parallelized in our internal CI by other means. I've chosen to allocate files to workers in a cruder way than our internal CI, based on initial characters rather than an automated process. The automated process would need some reworking to be compatible with mocha running in parallel mode.

Test Plan: this diff was tested first on grist-core, then ported to grist-saas so saas repo history will correctly track history of moved files.

Reviewers: jarek

Reviewed By: jarek

Subscribers: jarek

Differential Revision: https://phab.getgrist.com/D3927
2023-06-27 02:55:34 -04:00

281 lines
11 KiB
JavaScript

import { assert, driver } from 'mocha-webdriver';
import { $, gu, test } from 'test/nbrowser/gristUtil-nbrowser';
describe('TextEditor.ntest', function() {
test.setupTestSuite(this);
before(async function() {
await gu.supportOldTimeyTestCode();
await gu.actions.createNewDoc();
});
afterEach(function() {
return gu.checkForErrors();
});
async function autoCompleteSelect(options) {
await gu.sendKeys(options.input);
const values = await $('.test-ref-editor-item').array().text();
if (options.keys) {
await gu.sendKeys(...options.keys);
await $('.test-ref-editor-item.selected').wait(assert.isPresent, true);
} else if (options.click) {
await driver.findContent('.test-ref-editor-item', gu.exactMatch(options.click)).click();
}
return values;
}
async function autoCompleteWaitForSelection(text, selected) {
await $('.test-ref-editor-item:contains('+ text +')').wait(assert.hasClass, 'selected', selected);
}
it('should allow saving values into new Reference column', async function() {
await gu.getCellRC(0, 0).wait().click();
await gu.sendKeys("foo", $.ENTER);
await gu.waitForServer();
await gu.sendKeys("bar", $.ENTER);
await gu.waitForServer();
await gu.sendKeys("baz", $.ENTER);
await gu.waitForServer();
// Add a new section and switch to it.
await gu.actions.addNewSection('New', 'Table');
await gu.toggleSidePanel('left', 'close');
await $(".viewsection_title:contains(TABLE2)").click();
await gu.getCellRC(0, 0).click();
await gu.setType('Reference');
await gu.setRefTable('Table1');
await gu.setVisibleCol('A');
// Populate some of the reference column.
await gu.getCellRC(0, 0).click();
// Select "foo" from autocomplete dropdown with keyboard.
await autoCompleteSelect({input: 'f'});
await gu.sendKeys($.ENTER);
await gu.waitForServer();
assert.equal(await gu.getCellRC(0, 0).text(), "foo");
// Select "bar" from autocomplete dropdown with the mouse.
await autoCompleteSelect({input: 'b', click: 'bar'});
await gu.waitForServer();
await gu.sendKeys($.DOWN); // Selecting with the mouse saves without moving the cursor
assert.equal(await gu.getCellRC(1, 0).text(), "bar");
// Entering an existing value should reference it
await autoCompleteSelect({input: 'baz'});
await gu.sendKeys($.ENTER);
await gu.waitForServer();
assert.equal(await gu.getCellRC(2, 0).text(), "baz");
// Select "foo" from autocomplete dropdown with tab.
await autoCompleteSelect({input: 'foo'});
await gu.sendKeys($.TAB); // Select "foo" from autocomplete dropdown with tab.
await gu.waitForServer();
assert.equal(await gu.getCellRC(3, 0).text(), "foo");
// Esc should Cancel.
await gu.getCellRC(4, 0).click();
await autoCompleteSelect({input: 'baz'});
await gu.sendKeys($.ESCAPE);
assert.equal(await gu.getCellRC(4, 0).text(), "");
});
it('should allow adding new values from Reference column', async function() {
// Select add new from autocomplete dropdown.
await autoCompleteSelect({input: 'foobar', keys: [$.UP]});
await gu.sendKeys($.ENTER);
await gu.waitForServer();
await $(".viewsection_title:contains(TABLE1)").click();
assert.equal(await gu.getCellRC(3, 0).text(), "foobar");
// Add new by tab
await $(".viewsection_title:contains(TABLE2)").click();
await gu.getCellRC(4, 0).click();
await autoCompleteSelect({input: 'foobar1', keys: [$.UP]});
await gu.sendKeys($.TAB);
await gu.waitForServer();
await $(".viewsection_title:contains(TABLE1)").click();
assert.equal(await gu.getCellRC(4, 0).text(), "foobar1");
// Add new by click
await $(".viewsection_title:contains(TABLE2)").click();
await gu.getCellRC(5, 0).click();
await autoCompleteSelect({input: 'foobar2', click: 'foobar2'});
await gu.waitForServer();
await $(".viewsection_title:contains(TABLE1)").click();
assert.equal(await gu.getCellRC(5, 0).text(), "foobar2");
// Cancel with escape
await $(".viewsection_title:contains(TABLE2)").click();
await gu.getCellRC(5, 0).click();
await autoCompleteSelect({input: 'foobar3', keys: [$.UP]});
await gu.sendKeys($.ESCAPE);
await gu.waitForServer();
await gu.waitAppFocus(true);
await $(".viewsection_title:contains(TABLE1)").click();
assert.equal(await gu.getCellRC(6, 0).text(), "");
// Once add new is selected it should not be possible to change the input.
await $(".viewsection_title:contains(TABLE2)").click();
await gu.getCellRC(6, 0).click();
await autoCompleteSelect({input: 'foobar4', keys: [$.UP]});
await gu.sendKeys("567");
// Make sure add item loses selection
await autoCompleteWaitForSelection('foobar4', false);
await gu.sendKeys($.ENTER);
await gu.waitForServer();
assert.equal(await gu.getCellRC(6, 0).text(), "foobar4567");
await assert.hasClass(gu.getCellRC(6, 0).find('.field_clip'), 'invalid');
await $(".viewsection_title:contains(TABLE1)").click();
assert.equal(await gu.getCellRC(6, 0).text(), "");
});
async function addColumnRightOf(index) {
// Add a column. We have to hover over the column header first.
await gu.openColumnMenu({col: index}, 'Insert column to the right');
await gu.waitForServer();
await gu.sendKeys($.ESCAPE);
}
it('should allow saving values into new Date column', async function() {
// Add another column. We have to hover over the column header first.
await addColumnRightOf(0);
await gu.getCellRC(0, 1).click();
// Convert to Date. No need to "Apply conversion" since it's a new empty column.
await gu.setType('Date');
// Enter a new value and check that it's parsed and shows correctly.
await gu.getCellRC(0, 1).click();
await gu.sendKeys("2016/04/20", $.ENTER);
await gu.waitForServer();
assert.equal(await gu.getCellRC(0, 1).text(), "2016-04-20");
});
it('should show formatted values for ReferenceEditor autocomplete', async function() {
// Set a Reference column to use a displayCol that's a Date, and ensure that properly
// formatted dates show in its autocomplete.
// First, fill in a few more dates into Table1.D
await gu.enterGridValues(1, 1, [['2014-03-14', '2017-05-01', '2016-12-31', '', '2011-07-15']]);
// Now switch to the section with the Reference column and switch its displayCol to Table1.D.
await gu.actions.viewSection('TABLE2').selectSection();
await gu.clickCell({rowNum: 1, col: 0});
await gu.setVisibleCol('D');
// Check that the values displayed are properly formatted.
assert.deepEqual(await gu.getGridValues({rowNums: [1, 2, 3, 4, 5, 6, 7], cols: [0]}),
['2016-04-20', '2014-03-14', '2017-05-01', '2016-04-20', '[Blank]', '2011-07-15', 'foobar4567']);
// Check that formatted values are shown in the auto-complete dropdown.
await gu.clickCell({rowNum: 3, col: 0});
assert.deepEqual(await autoCompleteSelect({input: '2016', keys: [$.DOWN]}),
['2016-04-20', '2016-12-31', '2011-07-15', '2014-03-14', '2017-05-01', '2016']);
await gu.sendKeys($.ENTER);
await gu.waitForServer();
// Check that after selection, the right value is saved, and that it's valid (not AltText).
let cell = await gu.getCell({rowNum: 3, col: 0});
assert.equal(await cell.text(), '2016-12-31');
await assert.hasClass(cell.find('.field_clip'), 'invalid', false);
// Check that the formatted value is used to start the autocomplete lookup.
await gu.clickCell({rowNum: 3, col: 0});
assert.deepEqual(await autoCompleteSelect({input: $.ENTER}),
['2016-12-31', '2016-04-20', '2011-07-15', '2014-03-14', '2017-05-01']);
await gu.sendKeys($.SELECT_ALL, '2017-05-01', $.ENTER);
await gu.waitForServer();
// Check that after typing, the right value is saved, and that it's valid (not AltText).
cell = await gu.getCell({rowNum: 3, col: 0});
assert.equal(await cell.text(), '2017-05-01');
await assert.hasClass(cell.find('.field_clip'), 'invalid', false);
// Switch back to the view section we started from.
await gu.actions.viewSection('TABLE1').selectSection();
});
it('should allow saving values into new Checkbox column', async function() {
await addColumnRightOf(1);
await gu.getCellRC(0, 2).click();
// Convert to Toggle. No need to "Apply conversion" since it's a new empty column.
await gu.setType('Toggle');
// Toggle a value in the new column.
await gu.getCellRC(1, 2).find('.widget_checkbox').click();
await gu.waitForServer();
// To ensure it got saved to the server, convert to text, and check the text.
await gu.setType('Text');
await $('.test-type-transform-apply').wait().click();
await gu.waitForServer();
assert.deepEqual(await gu.getVisibleGridCells(2, [1, 2, 3]),
["false", "true", "false"]);
});
it('should allow saving values into a new row of a new column', async function() {
await gu.getColumnHeader('A').scrollIntoView({inline: "end"});
await addColumnRightOf(0);
await gu.getCellRC(0, 1).click();
await gu.setType('Date');
assert.equal(await gu.getCellRC(6, 1).text(), ""); // Last "add new" row.
await assert.isPresent(gu.getCellRC(7, 1), false); // Check that there is no next row.
await gu.getCellRC(0, 1).click();
await gu.sendKeys([$.MOD, $.DOWN]); // Jump to last row.
await gu.sendKeys("2001/11/23", $.ENTER);
await gu.waitForServer();
assert.equal(await gu.getCellRC(6, 1).text(), "2001-11-23");
await assert.isPresent(gu.getCellRC(7, 1), true); // Check that there is now one more row.
});
it('should allow changing a Date column to/from formula', async function() {
// What column D (index 1) start off with.
assert.equal(await gu.getCellRC(0, 1).text(), "");
assert.equal(await gu.getCellRC(6, 1).text(), "2001-11-23");
// Replace it with a formula that uses another date column B.
await gu.getCellRC(0, 1).click();
await gu.sendKeys('=');
await $('.test-editor-tooltip-convert').click(); // Convert to a formula
await gu.sendKeys('$D and $D.replace(day=2)', $.ENTER);
await gu.waitForServer();
// Check that it worked.
assert.equal(await gu.getCellRC(0, 1).text(), "2016-04-02");
assert.equal(await gu.getCellRC(6, 1).text(), "");
// Converting it to a data column.
await gu.clickColumnMenuItem('F', 'Convert formula to data');
await gu.waitForServer();
assert.equal(await gu.getCellRC(0, 1).text(), "2016-04-02");
assert.equal(await gu.getCellRC(6, 1).text(), "");
// Enter a new value, make sure that works.
await gu.getCellRC(6, 1).click();
await gu.sendKeys("2016/05/01", $.ENTER);
await gu.waitForServer();
assert.equal(await gu.getCellRC(0, 1).text(), "2016-04-02");
assert.equal(await gu.getCellRC(6, 1).text(), "2016-05-01");
});
// NOTE: This tests a specific bug which prevented moving the editor cursor via clicking.
// See https://phab.getgrist.com/T326
it('should allow moving cursor inside the editor via clicking', async function() {
await gu.clickCellRC(0, 0);
await gu.sendKeys($.ENTER);
await gu.waitAppFocus(false);
// Double click the cell to select all the text. This will fail if the bug is active.
await driver.withActions(a => a.doubleClick($('.celleditor_text_editor').elem()));
// Since the text was selected, the new text will replace the old text.
await gu.sendKeys('abcd', $.ENTER);
await gu.waitForServer();
assert.equal(await gu.getCellRC(0, 0).text(), "abcd");
});
});