(core) When changing a table for a page widget, unset widget-linking to avoid invalid values.

Summary:
Previously, using "Change Widget" allowed one to change the underlying table,
but would keep the linking settings. This could allow invalid settings which
would sometimes lead to JS errors. These manifested in production as
"UserError: Query error: n is not a function".

- Unset linking settings in this case, to avoid invalid values.
- In case invalid values are encountered (e.g. saved previously), treat them as
  unset, to avoid JS errors.
- If an error does occur, report it with a stack trace.

Also, for testing, added 'selectBy' option to gristUtils helpers for using page-widget-picker.

Test Plan: Added test cases for resetting linking, and for ignoring invalid link settings.

Reviewers: alexmojaki

Reviewed By: alexmojaki

Differential Revision: https://phab.getgrist.com/D2993
This commit is contained in:
Dmitry S
2021-08-23 23:28:07 -04:00
parent 427a17d038
commit faa0d9988e
5 changed files with 82 additions and 18 deletions

View File

@@ -764,8 +764,13 @@ export async function addNewTable() {
await waitForServer();
}
export interface PageWidgetPickerOptions {
summarize?: RegExp[]; // Optional list of patterns to match Group By columns.
selectBy?: RegExp; // Optional pattern of SELECT BY option to pick.
}
// Add a new page using the 'Add New' menu and wait for the new page to be shown.
export async function addNewPage(typeRe: RegExp, tableRe: RegExp, summarize?: RegExp[]) {
export async function addNewPage(typeRe: RegExp, tableRe: RegExp, options?: PageWidgetPickerOptions) {
const url = await driver.getCurrentUrl();
// Click the 'Page' entry in the 'Add New' menu
@@ -773,27 +778,25 @@ export async function addNewPage(typeRe: RegExp, tableRe: RegExp, summarize?: Re
await driver.find('.test-dp-add-new-page').doClick();
// add widget
await selectWidget(typeRe, tableRe, summarize);
await selectWidget(typeRe, tableRe, options);
// wait new page to be selected
await driver.wait(async () => (await driver.getCurrentUrl()) !== url, 2000);
}
// Add a new widget to the current page using the 'Add New' menu.
export async function addNewSection(typeRe: RegExp, tableRe: RegExp, summarize?: RegExp[]) {
export async function addNewSection(typeRe: RegExp, tableRe: RegExp, options?: PageWidgetPickerOptions) {
// Click the 'Add widget to page' entry in the 'Add New' menu
await driver.findWait('.test-dp-add-new', 2000).doClick();
await driver.findWait('.test-dp-add-widget-to-page', 500).doClick();
// add widget
await selectWidget(typeRe, tableRe, summarize);
await selectWidget(typeRe, tableRe, options);
}
// Select type and table that matches respectivelly typeRe and tableRe and save. The widget picker
// must be already opened when calling this function.
export async function selectWidget(typeRe: RegExp, tableRe: RegExp, summarize?: RegExp[]) {
export async function selectWidget(typeRe: RegExp, tableRe: RegExp, options: PageWidgetPickerOptions = {}) {
const tableEl = driver.findContent('.test-wselect-table', tableRe);
@@ -806,16 +809,22 @@ export async function selectWidget(typeRe: RegExp, tableRe: RegExp, summarize?:
await tableEl.click();
if (summarize) {
if (options.summarize) {
// if summarize is requested, let's select the corresponding pivot icon
await tableEl.find('.test-wselect-pivot').click();
// and all the columns
for (const colRef of summarize) {
for (const colRef of options.summarize) {
await driver.findContent('.test-wselect-column', colRef).click();
}
}
if (options.selectBy) {
// select link
await driver.find('.test-wselect-selectby').doClick();
await driver.findContent('.test-wselect-selectby option', options.selectBy).doClick();
}
// let's select right type and save
await driver.findContent('.test-wselect-type', typeRe).doClick();
await driver.find('.test-wselect-addBtn').doClick();