gristlabs_grist-core/test/nbrowser/RightPanel.ts
Janet Vorobyeva f8c1bd612c
Linkstate refactor (#609)
* Linkingstate Refactor, and displaying link info in rightpanel

Big refactor to LinkingState
    Collects descriptive/user-facing labels into FilterState
    Unifies/cleans up some logic
    Adds LinkTypeDescription, a string enum which can be used
    to easily switch/case between various cases of linking, and
    codifies the logic in one place (currently only used for linkInfo)

Adds Link info to creator panel, near SelectBy dropdown

Bugfix: Disables linking from Attachment columns
Bugfix/Behavior change: changed linking with empty RefLists to better
match behavior of refs.
    for context: Linking by a blank Ref filters to show records with a
    blank value for that Ref. Previously this didn't work with RefLists. 
    Linking from a blank refList would show no records 
    (except in some cases involving summary tables)
    Fixed this so that linking by a blank val consistently means "show
    all records where the corresponding col is blank"
2023-09-08 14:21:32 -04:00

369 lines
15 KiB
TypeScript

import {assert, driver, Key} from 'mocha-webdriver';
import * as gu from 'test/nbrowser/gristUtils';
import {server, setupTestSuite} from 'test/nbrowser/testUtils';
describe('RightPanel', function() {
this.timeout(20000);
const cleanup = setupTestSuite();
afterEach(() => gu.checkForErrors());
it('should focus on the creator panel when chart/custom section is added', async () => {
const mainSession = await gu.session().teamSite.login();
await mainSession.tempNewDoc(cleanup);
// Reset prefs.
await driver.executeScript('resetDismissedPopups();');
await gu.waitForServer();
// Refresh for a clean start.
await gu.reloadDoc();
// Close panel and make sure it stays closed.
await gu.toggleSidePanel('right', 'close');
// Add a chart section.
await gu.addNewSection('Chart', 'Table1', { dismissTips: true});
assert.isFalse(await gu.isSidePanelOpen('right'));
await gu.undo();
// Add a chart page.
await gu.addNewPage('Chart', 'Table1');
assert.isFalse(await gu.isSidePanelOpen('right'));
await gu.undo();
// Add a custom section.
await gu.addNewSection('Custom', 'Table1');
assert.isFalse(await gu.isSidePanelOpen('right'));
await gu.undo();
// Add a custom page.
await gu.addNewPage('Custom', 'Table1');
assert.isFalse(await gu.isSidePanelOpen('right'));
await gu.undo();
// Now open the panel on the column tab.
const columnTab = async () => {
await gu.toggleSidePanel('right', 'open');
await driver.find('.test-right-tab-field').click();
};
await columnTab();
// Add a chart section.
await gu.addNewSection('Chart', 'Table1');
assert.isTrue(await gu.isSidePanelOpen('right'));
assert.isTrue(await driver.find('.test-right-widget-title').isDisplayed());
await gu.undo();
await columnTab();
// Add a chart page.
await gu.addNewPage('Chart', 'Table1');
assert.isTrue(await gu.isSidePanelOpen('right'));
assert.isTrue(await driver.find('.test-right-widget-title').isDisplayed());
await gu.undo();
await columnTab();
// Add a custom section.
await gu.addNewSection('Custom', 'Table1');
assert.isTrue(await gu.isSidePanelOpen('right'));
assert.isTrue(await driver.find('.test-right-widget-title').isDisplayed());
await gu.undo();
await columnTab();
// Add a custom page.
await gu.addNewPage('Custom', 'Table1');
assert.isTrue(await gu.isSidePanelOpen('right'));
assert.isTrue(await driver.find('.test-right-widget-title').isDisplayed());
await gu.undo();
});
it('should open/close panel, and reflect the current section', async function() {
// Open a document with multiple views and multiple sections.
await server.simulateLogin("Chimpy", "chimpy@getgrist.com", 'nasa');
const doc = await gu.importFixturesDoc('chimpy', 'nasa', 'Horizon', 'World.grist', false);
await driver.get(`${server.getHost()}/o/nasa/doc/${doc.id}`);
// Check current view and section name.
assert.equal(await gu.getActiveSectionTitle(6000), 'CITY');
assert.equal(await driver.find('.test-bc-page').getAttribute('value'), 'City');
// Open side pane, and check it shows the right section.
await gu.toggleSidePanel('right', 'open');
await driver.find('.test-config-widget').click();
assert.equal(await gu.isSidePanelOpen('right'), true);
assert.equal(await driver.find('.test-right-widget-title').value(), 'CITY');
// Check that the tab's name reflects suitable text
assert.equal(await driver.find('.test-right-tab-pagewidget').getText(), 'Table');
assert.equal(await driver.find('.test-right-tab-field').getText(), 'Column');
// Switch to Field tab, check that it shows the right field.
await driver.find('.test-right-tab-field').click();
assert.equal(await driver.find('.test-field-label').value(), "Name");
// Check to a different field, check a different field is shown.
await driver.sendKeys(Key.RIGHT);
assert.equal(await driver.find('.test-field-label').value(), "Country");
// Click to a different section, check a different field is shown.
await gu.getSection('CITY Card List').find('.detail_row_num').click();
assert.equal(await driver.find('.test-field-label').value(), "Name");
// Check that the tab's name reflects suitable text
assert.equal(await driver.find('.test-right-tab-pagewidget').getText(), 'Card List');
assert.equal(await driver.find('.test-right-tab-field').getText(), 'Field');
// Close panel, check it's hidden.
await gu.toggleSidePanel('right');
assert.equal(await gu.isSidePanelOpen('right'), false);
assert.equal(await driver.find('.config_item').isPresent(), false);
// Reopen panel, check it's still right.
await gu.toggleSidePanel('right');
assert.equal(await driver.find('.test-field-label').value(), "Name");
// Switch to the section tab, check the new section is reflected.
await driver.find('.test-right-tab-pagewidget').click();
assert.equal(await driver.find('.test-right-widget-title').value(), 'CITY Card List');
// Switch to a different view, check the new section is reflected.
await driver.findContent('.test-treeview-itemHeader', /Country/).click();
assert.equal(await driver.find('.test-right-widget-title').value(), 'COUNTRY');
// Switch to field tab; check the new field is reflected.
await driver.find('.test-right-tab-field').click();
assert.equal(await driver.find('.test-field-label').value(), "Code");
});
it('should not cause errors when switching pages with Field tab open', async () => {
// There was an error ("this.calcSize is not a function") switching between pages when the
// active section changes type and Field tab is open, triggered by an unnecessary rebuilding
// of FieldConfigTab.
// Check that the active field tab is called "Column" (since the active section is "Table")
// and is open to column "Code".
assert.equal(await driver.find('.test-right-tab-field').getText(), 'Column');
assert.equal(await driver.find('.test-field-label').value(), "Code");
// Switch to the "City" page. Check that the tab is now called "Field" (since the active section is of
// type "CardList"), and open to the field "Name".
await driver.findContent('.test-treeview-itemHeader', /City/).click();
assert.equal(await driver.find('.test-right-tab-field').getText(), 'Field');
assert.equal(await driver.find('.test-field-label').value(), "Name");
// Check that this did not cause client-side errors.
await gu.checkForErrors();
// Now switch back, and check for errors again.
await driver.findContent('.test-treeview-itemHeader', /Country/).click();
await gu.checkForErrors();
});
it('should show tools when requested', async function() {
// Select specific view/section/field. Close side-pane.
await gu.getCell({col: "Name", rowNum: 3}).click();
assert.equal(await driver.find('.test-field-label').value(), "Name");
await gu.toggleSidePanel('right');
assert.equal(await gu.isSidePanelOpen('right'), false);
// Click Activity Log.
assert.equal(await driver.find('.action_log').isPresent(), false);
await driver.find('.test-tools-log').click();
await gu.waitToPass(() => // Click might not work while panel is sliding out to open.
driver.findContentWait('.test-doc-history-tabs .test-select-button', 'Activity', 500).click());
// Check that panel is shown, and correct.
assert.equal(await gu.isSidePanelOpen('right'), true);
assert.equal(await driver.find('.test-right-tab-field').isPresent(), false);
assert.equal(await driver.find('.action_log').isDisplayed(), true);
// Click "x", Check expected section config shown.
await driver.find('.test-right-tool-close').click();
assert.equal(await driver.find('.test-right-tab-field').getText(), 'Column');
assert.equal(await driver.find('.test-field-label').value(), "Name");
// TODO: polish data validation and then uncomment
/*
// Click Validations. Check it's shown and correct.
await driver.find('.test-tools-validate').click();
assert.equal(await driver.findContent('.config_item', /Validations/).isDisplayed(), true);
// Close panel. Switch to another view.
await gu.toggleSidePanel('right');
assert.equal(await gu.isSidePanelOpen('right'), false);
assert.equal(await driver.findContent('.config_item', /Validations/).isPresent(), false);
await driver.findContent('.test-treeview-itemHeader', /Country/).click();
// Open panel. Check Validations are still shown.
await gu.toggleSidePanel('right');
assert.equal(await driver.findContent('.config_item', /Validations/).isDisplayed(), true);
await driver.find('.test-right-tool-close').click();
*/
});
it('should keep panel state on reload', async function() {
// Check the panel is currently open and showing Field options.
assert.equal(await gu.isSidePanelOpen('right'), true);
assert.equal(await driver.find('.test-field-label').value(), "Name");
// Reload the page, and click the same cell as before.
await driver.navigate().refresh();
assert.equal(await gu.getActiveSectionTitle(3000), 'COUNTRY');
await gu.waitForServer();
await gu.getCell({col: "Name", rowNum: 3}).click();
// Check the panel is still open and showing the same Field options.
assert.equal(await gu.isSidePanelOpen('right'), true);
assert.equal(await driver.find('.test-field-label').value(), "Name");
});
it('\'SELECTOR FOR\' should work correctly', async function() {
// open the Data tab
await driver.find('.test-right-tab-pagewidget').click();
await driver.find('.test-config-data').click();
// open a page that has linked section
await driver.findContent('.test-treeview-itemHeader', /Country/).click();
// wait for data to load
assert(await gu.getActiveSectionTitle(3000));
await gu.waitForServer();
// select a view section that does not select other section
await gu.getSection('COUNTRY Card List').click();
// check that selector-for is not present
assert.equal(await driver.find('.test-selector-for').isPresent(), false);
// select a view section that does select other section
await gu.getSection('COUNTRY').click();
// check that selector-of is present and that all selected section are listed
assert.equal(await driver.find('.test-selector-for').isPresent(), true);
assert.deepEqual(await driver.findAll('.test-selector-for-entry', (e) => e.getText().then(s => s.split('\n')[0])), [
"CITY",
"COUNTRYLANGUAGE",
"COUNTRY Card List",
]);
});
it('\'Edit Data Selection\' should allow to change link', async () => {
// select COUNTRY DETAIL
await gu.getSection('CITY').click();
// open page widget picker
await driver.find('.test-pwc-editDataSelection').click();
// remove link
await driver.find('.test-wselect-selectby').doClick();
await driver.findContent('.test-wselect-selectby option', /Select Widget/).doClick();
// click save
await driver.find('.test-wselect-addBtn').doClick();
await gu.waitForServer();
// Go to the first record.
await gu.sendKeys(Key.chord(await gu.modKey(), Key.UP));
// Check that link was removed, by going to Aruba.
await gu.getSection('COUNTRY').click();
await gu.getCell(0, 1).click();
// City section should stay where it was
assert.equal(await gu.getCell(0, 1, 'CITY').getText(), 'Kabul');
// re-set the link
await gu.getSection('CITY').click();
await driver.find('.test-pwc-editDataSelection').click();
await driver.find('.test-wselect-selectby').click();
await driver.findContent('.test-wselect-selectby option', /Country$/).click();
await driver.find('.test-wselect-addBtn').doClick();
await gu.waitForServer();
// check link is set
await gu.getSection('COUNTRY').click();
await gu.getCell(0, 1).click();
assert.equal(await gu.getCell(0, 1, 'CITY').getText(), 'Oranjestad');
});
it('should not cause errors when switching pages with Table tab open', async () => {
// There were an error doing eigher one of 1) switching to `Code View`, or 2) removing the
// active page, when the Table tab was open, because: both caused the activeView to be set to an
// empty model causes some computed property of the ViewSectionRec to fail. This is what this
// test is aiming at catching.
await gu.toggleSidePanel('right', 'open');
await driver.find('.test-config-widget').click();
assert.deepEqual(await gu.getPageNames(), ['City', 'Country', 'CountryLanguage']);
// adds a new page
await gu.addNewPage(/Table/, /City/);
assert.deepEqual(await gu.getPageNames(), ['City', 'Country', 'CountryLanguage', 'New page']);
// remove that page
await gu.openPageMenu(/New page/);
await driver.find('.grist-floating-menu .test-docpage-remove').click();
await gu.waitForServer();
// check pages were removed and nothing break
assert.deepEqual(await gu.getPageNames(), ['City', 'Country', 'CountryLanguage']);
await gu.checkForErrors();
// now switch to `Code View`
await driver.find('.test-tools-code').click();
assert.equal(await driver.findWait('.g-code-viewer', 1000).isPresent(), true);
// check nothing broke
await gu.checkForErrors();
// switch back to City
await gu.getPageItem(/City/).click();
});
it('should not cause errors when editing summary table with `Change Widget` button', async () => {
// Changing the grouped by columns using the `Change Widget` used to throw `TypeError: Cannot
// read property `toUpperCase` of undefined`. The goal of this test is to prevent future
// regression.
// Create a summary table of City groupbed by country
await gu.addNewPage(/Table/, /City/, {summarize: [/Country/]});
// open right panel Widget
await gu.toggleSidePanel('right', 'open');
await driver.find('.test-right-tab-pagewidget').click();
await driver.find('.test-config-widget').click();
// click `Change Widget`
await driver.findContent('.test-right-panel button', /Change Widget/).click();
// remove column `Country` and save
await gu.selectWidget(/Table/, /City/, {summarize: []});
// check there were no error
await gu.checkForErrors();
});
it('should not raise errors when opening with table\'s `Widget Options`', async function() {
// Open right panel and select 'Column'
await gu.toggleSidePanel('right', 'open');
await driver.find('.test-right-tab-field').click();
// Close the right panel
await gu.toggleSidePanel('right', 'close');
// Open the right panel using the table's `Widget option`
await gu.openSectionMenu('viewLayout');
await driver.find('.test-widget-options').click();
await gu.checkForErrors();
});
});