gristlabs_grist-core/test/nbrowser/ReferenceColumns.ts
Jarosław Sadziński 6460c22a89 (core) Changing shortcuts for adding and removing rows
Summary:
New shortcuts for removing and adding rows.
For adding a row we now have Mod+(Shift)+Enter
For removing rows we now have Mod+Delete/Mod+Backspace

Before removing rows, the user is prompted to confirm, this prompt
can be dismissed and this setting can be remembered. User needs
to confirm only when using shortcut.

Old shortcuts are still active and shows information about this change.
This information is shown only once, after this shortcuts have default
behavior (zooming).
New users don't see this explanation.

Test Plan: Updated

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3655
2022-10-21 18:45:25 +02:00

582 lines
25 KiB
TypeScript

import {assert, driver, Key, stackWrapFunc} from 'mocha-webdriver';
import * as gu from 'test/nbrowser/gristUtils';
import {Session} from 'test/nbrowser/gristUtils';
import {server, setupTestSuite} from 'test/nbrowser/testUtils';
describe('ReferenceColumns', function() {
this.timeout(20000);
let session: Session;
const cleanup = setupTestSuite({team: true});
describe('rendering', function() {
before(async function() {
session = await gu.session().teamSite.login();
await session.tempDoc(cleanup, 'Favorite_Films.grist');
await gu.toggleSidePanel('right');
await driver.find('.test-config-data').click();
});
it('should render Row ID values as TableId[RowId]', async function() {
await driver.find('.test-right-tab-field').click();
await driver.find('.mod-add-column').click();
await gu.waitForServer();
await gu.setType(/Reference/);
await gu.waitForServer();
await gu.enterGridRows({col: 3, rowNum: 1}, [['1'], ['2'], ['3'], ['4']]);
assert.deepEqual(await gu.getVisibleGridCells(3, [1, 2, 3, 4, 5, 6]),
['Films[1]', 'Films[2]', 'Films[3]', 'Films[4]', '', '']);
await driver.find('.test-fbuilder-ref-table-select').click();
await driver.findContent('.test-select-row', /Friends/).click();
await gu.waitForServer();
// These are now invalid cells containing AltText such as 'Films[1]'
// We don't simply convert Films[1] -> Friends[1]
assert.deepEqual(await gu.getVisibleGridCells(3, [1, 2, 3, 4, 5, 6]),
['Films[1]', 'Films[2]', 'Films[3]', 'Films[4]', '', '']);
await driver.find('.test-type-transform-apply').click();
await gu.waitForServer();
await driver.find('.test-fbuilder-ref-col-select').click();
await driver.findContent('.test-select-row', /Name/).click();
await gu.waitForServer();
assert.deepEqual(await gu.getVisibleGridCells(3, [1, 2, 3, 4, 5, 6]),
['Films[1]', 'Films[2]', 'Films[3]', 'Films[4]', '', '']);
await gu.getCell(3, 5).click();
await driver.sendKeys('Roger');
await driver.sendKeys(Key.ENTER);
await gu.waitForServer();
// 'Roger' is an actual reference
assert.deepEqual(await gu.getVisibleGridCells(3, [1, 2, 3, 4, 5, 6]),
['Films[1]', 'Films[2]', 'Films[3]', 'Films[4]', 'Roger', '']);
await driver.find('.test-fbuilder-ref-col-select').click();
await driver.findContent('.test-select-row', /Row ID/).click();
await gu.waitForServer();
// 'Friends[1]' is an actual reference, the rest are invalid
assert.deepEqual(await gu.getVisibleGridCells(3, [1, 2, 3, 4, 5, 6]),
['Films[1]', 'Films[2]', 'Films[3]', 'Films[4]', 'Friends[1]', '']);
await driver.find('.test-fbuilder-ref-col-select').click();
await driver.findContent('.test-select-row', /Name/).click();
await gu.waitForServer();
assert.deepEqual(await gu.getVisibleGridCells(3, [1, 2, 3, 4, 5, 6]),
['Films[1]', 'Films[2]', 'Films[3]', 'Films[4]', 'Roger', '']);
await gu.undo();
});
it('should allow entering numeric id before target table is loaded', async function() {
if (server.isExternalServer()) {
this.skip();
}
// Refresh the document.
await driver.navigate().refresh();
await gu.waitForDocToLoad();
// Now pause the server
const cell = gu.getCell({col: 'A', rowNum: 1});
await server.pauseUntil(async () => {
assert.equal(await cell.getText(), 'Films[1]');
await cell.click();
await gu.sendKeys('5');
// Check that the autocomplete has no items yet.
assert.isEmpty(await driver.findAll('.test-autocomplete .test-ref-editor-new-item'));
await gu.sendKeys(Key.ENTER);
});
await gu.waitForServer();
assert.equal(await cell.getText(), 'Friends[5]');
await gu.undo();
assert.equal(await cell.getText(), 'Films[1]');
// Once server is responsive, a valid value should not offer a "new item".
await cell.click();
await gu.sendKeys('5');
await driver.findWait('.test-ref-editor-item', 500);
assert.isFalse(await driver.find('.test-ref-editor-new-item').isPresent());
await gu.sendKeys(Key.ENTER);
await gu.waitForServer();
assert.equal(await cell.getText(), 'Friends[5]');
});
it(`should show '[Blank]' if the referenced item is blank`, async function() {
// Open the All page.
await driver.findContentWait('.test-treeview-itemHeader', /All/, 2000).click();
await gu.waitForDocToLoad();
// Clear the cells in Films record containing Avatar and Alien.
await gu.getCell('Title', 3, 'Films record').doClick();
await gu.sendKeys(Key.BACK_SPACE);
await gu.waitForServer();
await gu.sendKeys(Key.ARROW_DOWN, Key.BACK_SPACE);
await gu.waitForServer();
// Check that all references to Avatar and Alien now show '[Blank]'.
assert.deepEqual(
await gu.getVisibleGridCells('Favorite Film', [1, 2, 3, 4, 5, 6], 'Friends record'),
[
'Forrest Gump',
'Toy Story',
'[Blank]',
'The Dark Knight',
'Forrest Gump',
'[Blank]'
]
);
// Check that '[Blank]' is not shown when the reference editor is open.
await gu.getCell('Favorite Film', 3, 'Friends record').doClick();
await gu.sendKeys(Key.ENTER);
assert.equal(await driver.find('.celleditor_text_editor').value(), '');
await gu.sendKeys(Key.ESCAPE);
// Undo (twice), and check that it shows Avatar and Alien again.
await gu.undo(2);
assert.deepEqual(
await gu.getVisibleGridCells('Favorite Film', [1, 2, 3, 4, 5, 6], 'Friends record'),
[
'Forrest Gump',
'Toy Story',
'Avatar',
'The Dark Knight',
'Forrest Gump',
'Alien'
]
);
});
});
describe('autocomplete', function() {
const getACOptions = stackWrapFunc(async (limit?: number) => {
await driver.findWait('.test-ref-editor-item', 1000);
return (await driver.findAll('.test-ref-editor-item', el => el.getText())).slice(0, limit);
});
before(async function() {
await session.tempDoc(cleanup, 'Ref-AC-Test.grist');
await gu.toggleSidePanel('right', 'close');
});
it('should open to correct item selected, and leave it unchanged on Enter', async function() {
const checkRefCell = stackWrapFunc(async (col: string, rowNum: number, expValue: string) => {
// Click cell and open for editing.
const cell = await gu.getCell({section: 'References', col, rowNum}).doClick();
assert.equal(await cell.getText(), expValue);
await driver.sendKeys(Key.ENTER);
// Wait for expected value to appear in the list; check that it's selected.
const match = await driver.findContentWait('.test-ref-editor-item', expValue, 1000);
assert.equal(await match.matches('.selected'), true);
// Save the value.
await driver.sendKeys(Key.ENTER);
await gu.waitForServer();
assert.equal(await cell.getText(), expValue);
// Assert that the undo is disabled, i.e. no action was generated.
assert.equal(await driver.find('.test-undo').matches('[class*=-disabled]'), true);
});
await checkRefCell('Color', 1, 'Dark Slate Blue');
await checkRefCell('ColorCode', 2, '#808080');
await checkRefCell('XNum', 3, '2019-11-05');
await checkRefCell('School', 1, 'TECHNOLOGY, ARTS AND SCIENCES STUDIO');
});
it('should render first items when opening empty cell', async function() {
await driver.sendKeys(Key.HOME);
let cell = await gu.getCell({section: 'References', col: 'Color', rowNum: 4}).doClick();
assert.equal(await cell.getText(), '');
await driver.sendKeys(Key.ENTER);
// Check the first few items.
assert.deepEqual(await getACOptions(3), ["Alice Blue", "Añil", "Aqua"]);
// No item is selected.
assert.equal(await driver.find('.test-ref-editor-item.selected').isPresent(), false);
await driver.sendKeys(Key.ESCAPE);
cell = await gu.getCell({section: 'References', col: 'School', rowNum: 6}).doClick();
assert.equal(await cell.getText(), '');
await driver.sendKeys(Key.ENTER);
// Check the first few items; should be sorted alphabetically.
assert.deepEqual(await getACOptions(3),
["2 SCHOOL", "4 SCHOOL", "47 AMER SIGN LANG & ENG LOWER "]);
// No item is selected.
assert.equal(await driver.find('.test-ref-editor-item.selected').isPresent(), false);
await driver.sendKeys(Key.ESCAPE);
});
it('should save correct item on click', async function() {
await driver.sendKeys(Key.HOME);
// Edit a cell by double-clicking.
let cell = await gu.getCell({section: 'References', col: 'Color', rowNum: 2}).doClick();
await driver.withActions(a => a.doubleClick(cell));
assert.equal(await driver.findWait('.test-ref-editor-item.selected', 1000).getText(), 'Red');
// Scroll to another item and click it.
let item = driver.findContent('.test-ref-editor-item', 'Rosy Brown');
await gu.scrollIntoView(item);
await item.click();
// It should get saved; and undo should restore the previous value.
await gu.waitForServer();
assert.equal(await cell.getText(), 'Rosy Brown');
await gu.undo();
assert.equal(await cell.getText(), 'Red');
// Edit another cell by starting to type.
cell = await gu.getCell({section: 'References', col: 'Color', rowNum: 4}).doClick();
await driver.sendKeys("gr");
await driver.findWait('.test-ref-editor-item', 1000);
item = driver.findContent('.test-ref-editor-item', 'Medium Sea Green');
await gu.scrollIntoView(item);
await item.click();
// It should get saved; and undo should restore the previous value.
await gu.waitForServer();
assert.equal(await cell.getText(), 'Medium Sea Green');
await gu.undo();
assert.equal(await cell.getText(), '');
});
it('should save correct item after selecting with arrow keys', async function() {
// Same as the previous test, but instead of clicking items, select item using arrow keys.
// Edit a cell by double-clicking.
let cell = await gu.getCell({section: 'References', col: 'Color', rowNum: 2}).doClick();
await driver.withActions(a => a.doubleClick(cell));
assert.equal(await driver.findWait('.test-ref-editor-item.selected', 1000).getText(), 'Red');
// Move to another item and hit Enter
await driver.sendKeys(Key.DOWN, Key.DOWN, Key.DOWN, Key.DOWN, Key.DOWN);
assert.equal(await driver.findWait('.test-ref-editor-item.selected', 1000).getText(), 'Pale Violet Red');
await driver.sendKeys(Key.ENTER);
// It should get saved; and undo should restore the previous value.
await gu.waitForServer();
assert.equal(await cell.getText(), 'Pale Violet Red');
await gu.undo();
assert.equal(await cell.getText(), 'Red');
// Edit another cell by starting to type.
cell = await gu.getCell({section: 'References', col: 'Color', rowNum: 4}).doClick();
await driver.sendKeys("gr");
await driver.findWait('.test-ref-editor-item', 1000);
await driver.sendKeys(Key.UP, Key.UP, Key.UP, Key.UP, Key.UP);
assert.equal(await driver.findWait('.test-ref-editor-item.selected', 1000).getText(), 'Chocolate');
await driver.sendKeys(Key.ENTER);
// It should get saved; and undo should restore the previous value.
await gu.waitForServer();
assert.equal(await cell.getText(), 'Chocolate');
await gu.undo();
assert.equal(await cell.getText(), '');
});
it('should return to text-as-typed when nothing is selected', async function() {
const cell = await gu.getCell({section: 'References', col: 'Color', rowNum: 2}).doClick();
await driver.sendKeys("da");
assert.deepEqual(await getACOptions(2), ["Dark Blue", "Dark Cyan"]);
// Check that the first item is highlighted by default.
assert.equal(await driver.find('.celleditor_text_editor').value(), 'da');
assert.equal(await driver.find('.test-ref-editor-item.selected').getText(), 'Dark Blue');
// Select second item. Both the textbox and the dropdown show the selection.
await driver.sendKeys(Key.DOWN);
assert.equal(await driver.find('.celleditor_text_editor').value(), 'Dark Cyan');
assert.equal(await driver.find('.test-ref-editor-item.selected').getText(), 'Dark Cyan');
// Move back to no-selection state.
await driver.sendKeys(Key.UP, Key.UP);
assert.equal(await driver.find('.celleditor_text_editor').value(), 'da');
assert.equal(await driver.find('.test-ref-editor-item.selected').isPresent(), false);
// Mouse over an item.
await driver.findContent('.test-ref-editor-item', /Dark Gray/).mouseMove();
assert.equal(await driver.find('.celleditor_text_editor').value(), 'Dark Gray');
assert.equal(await driver.find('.test-ref-editor-item.selected').getText(), 'Dark Gray');
// Mouse back out of the dropdown
await driver.find('.celleditor_text_editor').mouseMove();
assert.equal(await driver.find('.celleditor_text_editor').value(), 'da');
assert.equal(await driver.find('.test-ref-editor-item.selected').isPresent(), false);
// Click away to save the typed-in text.
await gu.getCell({section: 'References', col: 'Color', rowNum: 1}).doClick();
await gu.waitForServer();
assert.equal(await cell.getText(), "da");
assert.equal(await cell.find('.field_clip').matches('.invalid'), true);
await gu.undo();
assert.equal(await cell.getText(), "Red");
assert.equal(await cell.find('.field_clip').matches('.invalid'), false);
});
it('should save text as typed when nothing is selected', async function() {
const cell = await gu.getCell({section: 'References', col: 'Color', rowNum: 1}).doClick();
await driver.sendKeys("lavender ", Key.ENTER);
await gu.waitForServer();
assert.equal(await cell.getText(), "Lavender");
await gu.undo();
assert.equal(await cell.getText(), "Dark Slate Blue");
});
it('should offer an add-new option when no good match', async function() {
const cell = await gu.getCell({section: 'References', col: 'Color', rowNum: 2}).doClick();
await driver.sendKeys("pinkish");
// There are inexact matches.
assert.deepEqual(await getACOptions(3),
["Pink", "Deep Pink", "Hot Pink"]);
// Nothing is selected, and the "add new" item is present.
assert.equal(await driver.find('.test-ref-editor-item.selected').isPresent(), false);
assert.equal(await driver.find('.test-ref-editor-new-item').getText(), "pinkish");
// Click the "add new" item. The new value should be saved, and should not appear invalid.
await driver.find('.test-ref-editor-new-item').click();
await gu.waitForServer();
assert.equal(await cell.getText(), "pinkish");
assert.equal(await cell.find('.field_clip').matches('.invalid'), false);
// Requires 2 undos, because adding the "pinkish" record is a separate action. TODO these
// actions should be bundled.
await gu.undo(2);
assert.equal(await cell.getText(), "Red");
});
it('should offer an add-new option when opening alt-text', async function() {
const cell = await gu.getCell({section: 'References', col: 'Color', rowNum: 2}).doClick();
// Enter and invalid value and save without clicking "add new".
await driver.sendKeys("super pink", Key.ENTER);
// It should be saved but appear invalid (as alt-text).
await gu.waitForServer();
assert.equal(await cell.getText(), "super pink");
assert.equal(await cell.find('.field_clip').matches('.invalid'), true);
// Open the cell again. The "Add New" option should be there.
await driver.withActions(a => a.doubleClick(cell));
assert.equal(await driver.find('.test-ref-editor-new-item').getText(), "super pink");
assert.equal(await driver.find('.test-ref-editor-item.selected').isPresent(), false);
// Select "add new" (this time with arrow keys), and save.
await driver.sendKeys(Key.UP);
assert.equal(await driver.find('.test-ref-editor-new-item').matches('.selected'), true);
await driver.sendKeys(Key.ENTER);
// Once "add new" is clicked, the "super pink" no longer appears as invalid.
await gu.waitForServer();
assert.equal(await cell.getText(), "super pink");
assert.equal(await cell.find('.field_clip').matches('.invalid'), false);
await gu.undo(3);
assert.equal(await cell.getText(), "Red");
});
it('should not offer an add-new option when target is a formula', async function() {
// Click on an alt-text cell.
const cell = await gu.getCell({section: 'References', col: 'Color', rowNum: 3}).doClick();
assert.equal(await cell.getText(), "hello");
assert.equal(await cell.find('.field_clip').matches('.invalid'), true);
await driver.sendKeys(Key.ENTER);
assert.equal(await driver.find('.test-ref-editor-new-item').getText(), "hello");
await driver.sendKeys(Key.ESCAPE);
// Change the visible column to the formula column "C2".
await gu.toggleSidePanel('right', 'open');
await driver.find('.test-right-tab-field').click();
await driver.find('.test-fbuilder-ref-col-select').click();
await driver.findContent('.test-select-row', /C2/).click();
await gu.waitForServer();
// Check that for the same cell, the dropdown no longer has an "add new" option.
await cell.click();
await driver.sendKeys(Key.ENTER);
assert.equal(await driver.find('.celleditor_text_editor').value(), 'hello');
await driver.findWait('.test-ref-editor-item', 1000);
assert.equal(await driver.find('.test-ref-editor-item.selected').isPresent(), false);
assert.equal(await driver.find('.test-ref-editor-new-item').isPresent(), false);
await driver.sendKeys(Key.ESCAPE);
await gu.undo();
await gu.toggleSidePanel('right', 'close');
});
it('should offer items ordered by best match', async function() {
let cell = await gu.getCell({section: 'References', col: 'Color', rowNum: 1}).doClick();
assert.equal(await cell.getText(), 'Dark Slate Blue');
await driver.sendKeys(Key.ENTER);
assert.deepEqual(await getACOptions(4),
['Dark Slate Blue', 'Dark Slate Gray', 'Slate Blue', 'Medium Slate Blue']);
await driver.sendKeys(Key.ESCAPE);
// Starting to type Añil with the accent
await driver.sendKeys('añ');
assert.deepEqual(await getACOptions(2),
['Añil', 'Alice Blue']);
await driver.sendKeys(Key.ESCAPE);
// Starting to type Añil without the accent should work too
await driver.sendKeys('an');
assert.deepEqual(await getACOptions(2),
['Añil', 'Alice Blue']);
await driver.sendKeys(Key.ESCAPE);
await driver.sendKeys('blac');
assert.deepEqual(await getACOptions(6),
['Black', 'Blanched Almond', 'Blue', 'Blue Violet', 'Alice Blue', 'Cadet Blue']);
await driver.sendKeys(Key.ESCAPE);
cell = await gu.getCell({section: 'References', col: 'Color', rowNum: 3}).doClick();
assert.equal(await cell.getText(), 'hello'); // Alt-text
await driver.sendKeys(Key.ENTER);
assert.deepEqual(await getACOptions(2),
['Honeydew', 'Hot Pink']);
await driver.sendKeys(Key.ESCAPE);
cell = await gu.getCell({section: 'References', col: 'ColorCode', rowNum: 2}).doClick();
assert.equal(await cell.getText(), '#808080');
await driver.sendKeys(Key.ENTER);
assert.deepEqual(await getACOptions(5),
['#808080', '#808000', '#800000', '#800080', '#87CEEB']);
await driver.sendKeys(Key.ESCAPE);
cell = await gu.getCell({section: 'References', col: 'XNum', rowNum: 2}).doClick();
assert.equal(await cell.getText(), '2019-04-29');
await driver.sendKeys(Key.ENTER);
assert.deepEqual(await getACOptions(4),
['2019-04-29', '2020-04-29', '2019-11-05', '2020-04-28']);
await driver.sendKeys(Key.ESCAPE);
});
it('should update choices as user types into textbox', async function() {
let cell = await gu.getCell({section: 'References', col: 'School', rowNum: 1}).doClick();
assert.equal(await cell.getText(), 'TECHNOLOGY, ARTS AND SCIENCES STUDIO');
await driver.sendKeys(Key.ENTER);
assert.deepEqual(await getACOptions(3), [
'TECHNOLOGY, ARTS AND SCIENCES STUDIO',
'SCIENCE AND TECHNOLOGY ACADEMY',
'SCHOOL OF SCIENCE AND TECHNOLOGY',
]);
await driver.sendKeys(Key.ESCAPE);
cell = await gu.getCell({section: 'References', col: 'School', rowNum: 2}).doClick();
await driver.sendKeys('stuy');
assert.deepEqual(await getACOptions(3), [
'STUYVESANT HIGH SCHOOL',
'BEDFORD STUY COLLEGIATE CHARTER SCH',
'BEDFORD STUY NEW BEGINNINGS CHARTER',
]);
await driver.sendKeys(Key.BACK_SPACE);
assert.deepEqual(await getACOptions(3), [
'STUART M TOWNSEND MIDDLE SCHOOL',
'STUDIO SCHOOL (THE)',
'STUYVESANT HIGH SCHOOL',
]);
await driver.sendKeys(' bre');
assert.equal(await driver.find('.celleditor_text_editor').value(), 'stu bre');
assert.deepEqual(await getACOptions(3), [
'ST BRENDAN SCHOOL',
'BRONX STUDIO SCHOOL-WRITERS-ARTISTS',
'BROOKLYN STUDIO SECONDARY SCHOOL',
]);
await driver.sendKeys(Key.DOWN, Key.ENTER);
await gu.waitForServer();
assert.equal(await cell.getText(), 'ST BRENDAN SCHOOL');
await gu.undo();
assert.equal(await cell.getText(), '');
});
it('should highlight matching parts of items', async function() {
await driver.sendKeys(Key.HOME);
let cell = await gu.getCell({section: 'References', col: 'Color', rowNum: 2}).doClick();
assert.equal(await cell.getText(), 'Red');
await driver.sendKeys(Key.ENTER);
await driver.findWait('.test-ref-editor-item', 1000);
assert.deepEqual(
await driver.findContent('.test-ref-editor-item', /Dark Red/).findAll('span', e => e.getText()),
['Red']);
assert.deepEqual(
await driver.findContent('.test-ref-editor-item', /Rebecca Purple/).findAll('span', e => e.getText()),
['Re']);
await driver.sendKeys(Key.ESCAPE);
cell = await gu.getCell({section: 'References', col: 'School', rowNum: 1}).doClick();
await driver.sendKeys('br tech');
assert.deepEqual(
await driver.findContentWait('.test-ref-editor-item', /BROOKLYN TECH/, 1000).findAll('span', e => e.getText()),
['BR', 'TECH']);
assert.deepEqual(
await driver.findContent('.test-ref-editor-item', /BUFFALO.*TECHNOLOGY/).findAll('span', e => e.getText()),
['B', 'TECH']);
assert.deepEqual(
await driver.findContent('.test-ref-editor-item', /ENERGY TECH/).findAll('span', e => e.getText()),
['TECH']);
await driver.sendKeys(Key.ESCAPE);
});
it('should reflect changes to the target column', async function() {
await driver.sendKeys(Key.HOME);
const cell = await gu.getCell({section: 'References', col: 'Color', rowNum: 4}).doClick();
assert.equal(await cell.getText(), '');
await driver.sendKeys(Key.ENTER);
assert.deepEqual(await getACOptions(2), ['Alice Blue', 'Añil']);
await driver.sendKeys(Key.ESCAPE);
// Change a color
await gu.getCell({section: 'Colors', col: 'Color Name', rowNum: 1}).doClick();
await driver.sendKeys('HAZELNUT', Key.ENTER);
await gu.waitForServer();
// See that the old value is gone from the autocomplete, and the new one is present.
await cell.click();
await driver.sendKeys(Key.ENTER);
assert.deepEqual(await getACOptions(2), ['Añil', 'Aqua']);
await driver.sendKeys('H');
assert.deepEqual(await getACOptions(2), ['HAZELNUT', 'Honeydew']);
await driver.sendKeys(Key.ESCAPE);
// Delete a row.
await gu.getCell({section: 'Colors', col: 'Color Name', rowNum: 1}).doClick();
await driver.find('body').sendKeys(Key.chord(await gu.modKey(), Key.DELETE));
await gu.confirm(true, true);
await gu.waitForServer();
// See that the value is gone from the autocomplete.
await cell.click();
await driver.sendKeys('H');
assert.deepEqual(await getACOptions(2), ['Honeydew', 'Hot Pink']);
await driver.sendKeys(Key.ESCAPE);
// Add a row.
await gu.getCell({section: 'Colors', col: 'Color Name', rowNum: 1}).doClick();
await driver.find('body').sendKeys(Key.chord(await gu.modKey(), Key.ENTER));
await gu.waitForServer();
await driver.sendKeys('HELIOTROPE', Key.ENTER);
await gu.waitForServer();
// See that the new value is visible in the autocomplete.
await cell.click();
await driver.sendKeys('H');
assert.deepEqual(await getACOptions(2), ['HELIOTROPE', 'Honeydew']);
await driver.sendKeys(Key.BACK_SPACE);
assert.deepEqual(await getACOptions(2), ['Añil', 'Aqua']);
await driver.sendKeys(Key.ESCAPE);
// Undo all the changes.
await gu.undo(4);
await cell.click();
await driver.sendKeys('H');
assert.deepEqual(await getACOptions(2), ['Honeydew', 'Hot Pink']);
await driver.sendKeys(Key.BACK_SPACE);
assert.deepEqual(await getACOptions(2), ['Alice Blue', 'Añil']);
await driver.sendKeys(Key.ESCAPE);
});
});
});