import { assert, driver } from 'mocha-webdriver'; import { $, gu, test } from 'test/nbrowser/gristUtil-nbrowser'; const colHeaderScrollOpts = {block: "start", inline: "end"}; describe('ColumnOps.ntest', function() { const cleanup = test.setupTestSuite(this); before(async function() { await gu.supportOldTimeyTestCode(); await gu.useFixtureDoc(cleanup, "World.grist", true); await gu.toggleSidePanel('left', 'close'); }); afterEach(function() { return gu.checkForErrors(); }); it("should allow adding and deleting columns", async function() { await gu.clickColumnMenuItem('Name', 'Insert column to the right'); await gu.waitForServer(); // Newly created columns labels become editable automatically. The next line checks that the // label is editable and then closes the editor. await gu.userActionsCollect(true); await gu.getOpenEditingLabel(await gu.getColumnHeader('A')).wait().sendKeys($.ENTER); // Verify that no UserActions were actually sent. await gu.waitForServer(); await gu.userActionsVerify([]); await gu.userActionsCollect(false); await gu.waitAppFocus(true); await assert.isPresent(gu.getColumnHeader('A'), true); await assert.isPresent(gu.getOpenEditingLabel(gu.getColumnHeader('A')), false); await gu.clickColumnMenuItem('A', 'Delete column'); await gu.waitForServer(); await assert.isPresent(gu.getColumnHeader('A'), false); }); it("should allow adding columns with new column menu", async function() { await assert.isPresent(gu.getColumnHeader('A'), false); await $('.mod-add-column').scrollIntoView(true); await $('.mod-add-column').click(); await gu.actions.selectFloatingOption('Add Column'); await gu.userActionsCollect(true); await gu.waitToPass(() => gu.getColumnHeader('A')); await gu.getOpenEditingLabel(await gu.getColumnHeader('A')).wait().sendKeys($.ENTER); await gu.waitForServer(); await gu.userActionsVerify([["AddRecord", "_grist_Views_section_field", null, {"colRef":43, "parentId":4, "parentPos":null}]]); await gu.userActionsCollect(false); await gu.waitAppFocus(true); await assert.isPresent(gu.getColumnHeader('A'), true); await assert.isPresent(gu.getOpenEditingLabel(gu.getColumnHeader('A')), false); assert.deepEqual(await gu.getGridLabels('City'), ["Name", "Country", "District", "Population", "A"]); }); it("should allow hiding columns", async function() { await assert.isPresent(gu.getColumnHeader('Name'), true); await gu.getColumnHeader('Name').scrollIntoView(colHeaderScrollOpts); await gu.clickColumnMenuItem('Name', 'Hide column'); await gu.waitForServer(); await assert.isPresent(gu.getColumnHeader('Name'), false); await $(".test-undo").click(); await gu.waitForServer(); await assert.isPresent(gu.getColumnHeader('Name'), true); }); it("[+] button should allow showing hidden columns", async function() { // Hide a column first await assert.isPresent(gu.getColumnHeader('Name'), true); await gu.getColumnHeader('Name').scrollIntoView(colHeaderScrollOpts); await gu.clickColumnMenuItem('Name', 'Hide column'); await gu.waitForServer(); await assert.isPresent(gu.getColumnHeader('Name'), false); // Then show it using the add column menu await $('.mod-add-column').scrollIntoView(true); await $(".mod-add-column").click(); await gu.actions.selectFloatingOption('Show column Name'); await gu.waitForServer(); await assert.isPresent(gu.getColumnHeader('Name'), true); }); it("[+] button show add column directly if no hidden columns", async function() { await $('.mod-add-column').scrollIntoView(true); await $(".mod-add-column").click(); await gu.actions.selectFloatingOption('Show column Pop'); await gu.waitForServer(); await assert.isPresent(gu.getColumnHeader("Pop. '000"), true); await assert.isPresent(gu.getColumnHeader('B'), false); await $('.mod-add-column').scrollIntoView(true); await $(".mod-add-column").click(); await gu.waitToPass(() => gu.getColumnHeader('B')); await gu.getOpenEditingLabel(await gu.getColumnHeader('B')).wait().sendKeys($.ENTER); await gu.waitForServer(); await gu.waitAppFocus(true); await assert.isPresent(gu.getColumnHeader('B'), true); }); it("should allow renaming columns", async function() { await gu.getColumnHeader('Name').scrollIntoView(colHeaderScrollOpts); await gu.clickColumnMenuItem('Name', 'Rename column'); await gu.getOpenEditingLabel(await gu.getColumnHeader('Name')).sendKeys('Renamed', $.ENTER); await gu.waitForServer(); await assert.isPresent(gu.getColumnHeader('Renamed'), true); assert.deepEqual(await gu.getGridValues({ cols: ['Renamed'], rowNums: [3, 4, 5], }), ['A Coruña (La Coruña)', 'Aachen', 'Aalborg']); // Verify that undo/redo works with renaming await gu.undo(); await assert.isPresent(gu.getColumnHeader('Name'), true); assert.deepEqual(await gu.getGridValues({ cols: ['Name'], rowNums: [3, 4, 5], }), ['A Coruña (La Coruña)', 'Aachen', 'Aalborg']); await gu.redo(); await assert.isPresent(gu.getColumnHeader('Renamed'), true); assert.deepEqual(await gu.getGridValues({ cols: ['Renamed'], rowNums: [3, 4, 5], }), ['A Coruña (La Coruña)', 'Aachen', 'Aalborg']); // Refresh the page and check that the rename sticks. await driver.navigate().refresh(); assert.equal(await $('.active_section .test-viewsection-title').wait().text(), 'CITY'); await gu.waitForServer(5000); await gu.clickCellRC(1, 4); await assert.isPresent(gu.getColumnHeader('Renamed'), true); // Check that it is renamed in the sidepane await gu.openSidePane('field'); assert.equal(await $(".test-field-label").val(), "Renamed"); // Check that both the label and the Id are changed when label and Id are linked let deriveIdCheckbox = $(".test-field-derive-id"); assert.isTrue(await deriveIdCheckbox.is('[class*=-selected]')); await deriveIdCheckbox.click(); await gu.waitForServer(); assert.isFalse(await deriveIdCheckbox.is('[class*=-selected]')); assert(await $(".test-field-col-id").val(), "Renamed"); // Check that just the label is changed when label and Id are unlinked await gu.getColumnHeader('Renamed').scrollIntoView(colHeaderScrollOpts); await gu.clickColumnMenuItem('Renamed', 'Rename column'); await gu.getOpenEditingLabel(await gu.getColumnHeader('Renamed')).wait().sendKeys('foo', $.ENTER); await gu.waitForServer(); await assert.isPresent(gu.getColumnHeader('foo'), true); await assert.isPresent(gu.getOpenEditingLabel(gu.getColumnHeader('foo')), false); assert.equal(await $(".test-field-label").val(), "foo"); assert(await $(".test-field-col-id").val(), "Renamed"); // Saving an identical column label should still close the input. await gu.getColumnHeader('foo').scrollIntoView(colHeaderScrollOpts); await gu.clickColumnMenuItem('foo', 'Rename column'); await gu.userActionsCollect(true); await gu.getOpenEditingLabel(await gu.getColumnHeader('foo')).wait().sendKeys('foo', $.ENTER); await gu.waitForServer(); await gu.userActionsVerify([]); await gu.userActionsCollect(false); await assert.isPresent(gu.getOpenEditingLabel(gu.getColumnHeader('foo')), false); await gu.waitAppFocus(true); // Bug T384: Should save the column name after cancelling a rename earlier. await gu.getColumnHeader('A').scrollIntoView(colHeaderScrollOpts); await gu.clickColumnMenuItem('A', 'Rename column'); await gu.getOpenEditingLabel(await gu.getColumnHeader('A')).wait().sendKeys('C', $.ESCAPE); await gu.waitForServer(); await assert.isPresent(gu.getColumnHeader('A'), true); await gu.clickColumnMenuItem('A', 'Rename column'); await gu.getOpenEditingLabel(await gu.getColumnHeader('A')).sendKeys('C', $.TAB); await gu.waitForServer(); await assert.isPresent(gu.getColumnHeader('C'), true); }); it("should allow renaming columns with a click", async function() { // Go to a non-target column first await gu.getColumnHeader('Population').scrollIntoView(colHeaderScrollOpts); await gu.getColumnHeader('Population').click(); // Now select the column of interest await gu.getColumnHeader('foo').scrollIntoView(colHeaderScrollOpts); await gu.getColumnHeader('foo').click(); // And click one more time to rename await gu.getColumnHeader('foo').click(); await gu.getOpenEditingLabel(await gu.getColumnHeader('foo')).sendKeys('foot', $.ENTER); await gu.waitForServer(); await assert.isPresent(gu.getColumnHeader('foo'), false); await assert.isPresent(gu.getColumnHeader('foot'), true); // Click to rename back again await gu.getColumnHeader('foot').click(); await gu.getOpenEditingLabel(await gu.getColumnHeader('foot')).sendKeys('foo', $.ENTER); await gu.waitForServer(); await assert.isPresent(gu.getColumnHeader('foo'), true); await assert.isPresent(gu.getColumnHeader('foot'), false); }); it("should allow deleting multiple columns", async function() { await gu.actions.selectTabView('Country'); // delete shortcut should delete all selected columns await gu.selectGridArea([1, 0], [1, 1]); await gu.sendKeys([$.ALT, '-']); await gu.waitForServer(); assert.deepEqual(await gu.getGridLabels('Country'), ["Continent", "Region", "SurfaceArea", "IndepYear", "Population", "LifeExpectancy", "GNP", "GNPOld", "LocalName", "GovernmentForm", "HeadOfState", "Capital", "Code2"]); // Undo to restore changes await gu.undo(1, 5000); // delete menu item should delete all selected columns await gu.selectGridArea([1, 2], [1, 8]); await gu.clickColumnMenuItem('SurfaceArea', 'Delete', true); await gu.waitForServer(); assert.deepEqual(await gu.getGridLabels('Country'), ["Code", "Name", "GNPOld", "LocalName", "GovernmentForm", "HeadOfState", "Capital", "Code2"]); // Undo to restore changes await gu.undo(1, 5000); // the delete shortcut should delete all columns in a cell selection as well await gu.clickCellRC(2, 5); await gu.sendKeys([$.SHIFT, $.RIGHT, $.RIGHT]); await gu.sendKeys([$.ALT, '-']); await gu.waitForServer(); assert.deepEqual(await gu.getGridLabels('Country'), ["Code", "Name", "Continent", "Region", "SurfaceArea", "GNP", "GNPOld", "LocalName", "GovernmentForm", "HeadOfState", "Capital", "Code2"]); // Undo to restore changes await gu.undo(1, 5000); // Nudge first few columns back into view if they've drifted out of it. await gu.toggleSidePanel('right', 'close'); await gu.sendKeys($.LEFT, $.LEFT, $.LEFT); // opening a column menu outside the selection should move the selection await gu.clickCellRC(2, 2); await gu.sendKeys([$.SHIFT, $.RIGHT]); await gu.clickColumnMenuItem('IndepYear', 'Delete', true); await gu.waitForServer(); assert.deepEqual(await gu.getGridLabels('Country'), ["Code", "Name", "Continent", "Region", "SurfaceArea", "Population", "LifeExpectancy", "GNP", "GNPOld", "LocalName", "GovernmentForm", "HeadOfState", "Capital", "Code2"]); // Undo to restore changes await gu.undo(); }); it("should allow hiding multiple columns", async function() { await gu.actions.selectTabView('Country'); await gu.openSidePane('view'); // hide menu item should hide all selected columns await gu.selectGridArea([1, 2], [1, 8]); await gu.clickColumnMenuItem('SurfaceArea', 'Hide 7 columns', true); await gu.waitForServer(); assert.deepEqual(await gu.getGridLabels('Country'), ["Code", "Name", "GNPOld", "LocalName", "GovernmentForm", "HeadOfState", "Capital", "Code2"]); assert.deepEqual(await $('.test-vfc-visible-fields .kf_draggable_content').array().text(), ["Code", "Name", "GNPOld", "LocalName", "GovernmentForm", "HeadOfState", "Capital", "Code2"]); assert.deepEqual(await $('.test-vfc-hidden-fields .kf_draggable_content').array().text(), ["Name", "Continent", "Region", "SurfaceArea", "IndepYear", "Population", "LifeExpectancy", "GNP", "Self"]); // Undo to restore changes await gu.undo(1, 5000); assert.deepEqual(await gu.getGridLabels('Country'), ["Code", "Name", "Continent", "Region", "SurfaceArea", "IndepYear", "Population", "LifeExpectancy", "GNP", "GNPOld", "LocalName", "GovernmentForm", "HeadOfState", "Capital", "Code2"]); }); });