2023-06-27 06:11:08 +00:00
|
|
|
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');
|
2023-11-06 15:42:04 +00:00
|
|
|
await driver.find('.test-new-columns-menu-add-new').click();
|
2023-06-27 06:11:08 +00:00
|
|
|
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");
|
|
|
|
});
|
|
|
|
});
|