mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) updates from grist-core
This commit is contained in:
commit
91eabb6b0c
@ -399,7 +399,20 @@
|
||||
"Unfreeze {{count}} columns_one": "Unfreeze this column",
|
||||
"Unfreeze {{count}} columns_other": "Unfreeze {{count}} columns",
|
||||
"Insert column to the left": "Insert column to the left",
|
||||
"Insert column to the right": "Insert column to the right"
|
||||
"Insert column to the right": "Insert column to the right",
|
||||
"Apply on record changes": "Apply on record changes",
|
||||
"Apply to new records": "Apply to new records",
|
||||
"Authorship": "Authorship",
|
||||
"Created At": "Created At",
|
||||
"Created By": "Created By",
|
||||
"Hidden Columns": "Hidden Columns",
|
||||
"Last Updated At": "Last Updated At",
|
||||
"Last Updated By": "Last Updated By",
|
||||
"Lookups": "Lookups",
|
||||
"Shortcuts": "Shortcuts",
|
||||
"Show hidden columns": "Show hidden columns",
|
||||
"Timestamp": "Timestamp",
|
||||
"no reference column": "no reference column"
|
||||
},
|
||||
"GristDoc": {
|
||||
"Added new linked section to view {{viewName}}": "Added new linked section to view {{viewName}}",
|
||||
@ -820,7 +833,8 @@
|
||||
"Choice List": "Choice List",
|
||||
"Reference": "Reference",
|
||||
"Reference List": "Reference List",
|
||||
"Attachment": "Attachment"
|
||||
"Attachment": "Attachment",
|
||||
"Search columns": "Search columns"
|
||||
},
|
||||
"modals": {
|
||||
"Cancel": "Cancel",
|
||||
|
@ -13,7 +13,7 @@ import * as gu from 'test/nbrowser/gristUtils';
|
||||
import {setupTestSuite} from 'test/nbrowser/testUtils';
|
||||
|
||||
describe('CopyPaste', function() {
|
||||
this.timeout(60000);
|
||||
this.timeout(90000);
|
||||
const cleanup = setupTestSuite();
|
||||
const clipboard = gu.getLockableClipboard();
|
||||
afterEach(() => gu.checkForErrors());
|
||||
@ -69,8 +69,7 @@ describe('CopyPaste', function() {
|
||||
await session.tempDoc(cleanup, 'PasteParsing.grist');
|
||||
await driver.executeScript(createDummyTextArea);
|
||||
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copyAndCheck(cb, [
|
||||
await copyAndCheck(clipboard, [
|
||||
'$1', '1',
|
||||
'(2)', '-2',
|
||||
'3e4', '30000',
|
||||
@ -84,7 +83,6 @@ describe('CopyPaste', function() {
|
||||
// Doesn't match the default currency of the document, whereas $ above does
|
||||
'€89', '€89 INVALID',
|
||||
], true);
|
||||
});
|
||||
|
||||
// Open the side panel for the numeric column.
|
||||
await gu.toggleSidePanel('right', 'open');
|
||||
@ -144,8 +142,7 @@ describe('CopyPaste', function() {
|
||||
'€89', '€89.00',
|
||||
]);
|
||||
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copyAndCheck(cb, [
|
||||
await copyAndCheck(clipboard, [
|
||||
// Now we're copying from the text column so everything is parsed again.
|
||||
// $ can no longer be parsed now the currency is euros.
|
||||
'$1', '$1 INVALID',
|
||||
@ -158,7 +155,6 @@ describe('CopyPaste', function() {
|
||||
'1.234.567', '1.234.567 INVALID',
|
||||
'€89', '€89.00',
|
||||
], true);
|
||||
});
|
||||
|
||||
// Change the document locale
|
||||
await gu.openDocumentSettings();
|
||||
@ -202,8 +198,7 @@ describe('CopyPaste', function() {
|
||||
'€89', '89,00 €',
|
||||
]);
|
||||
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copyAndCheck(cb, [
|
||||
await copyAndCheck(clipboard, [
|
||||
'$1', '$1 INVALID',
|
||||
'(2)', '-2,00 €',
|
||||
'3e4', '30.000,00 €',
|
||||
@ -222,13 +217,11 @@ describe('CopyPaste', function() {
|
||||
'€89', '89,00 €',
|
||||
], true);
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse pasted dates', async function() {
|
||||
await gu.getPageItem("Dates").click();
|
||||
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copyAndCheck(cb, [
|
||||
await copyAndCheck(clipboard, [
|
||||
'01-02-03', '01-02-2003',
|
||||
'01 02 2003', '01-02-2003',
|
||||
'1/02/03', '01-02-2003',
|
||||
@ -238,7 +231,6 @@ describe('CopyPaste', function() {
|
||||
'20/10/03', '20-10-2003',
|
||||
'10/20/03', '10/20/03 INVALID',
|
||||
]);
|
||||
});
|
||||
|
||||
await gu.getCell({col: 'Parsed', rowNum: 1}).click();
|
||||
assert.equal(await gu.getDateFormat(), "DD-MM-YYYY");
|
||||
@ -274,8 +266,7 @@ describe('CopyPaste', function() {
|
||||
]);
|
||||
|
||||
// Copy from the text column again, things get re-parsed
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copyAndCheck(cb, [
|
||||
await copyAndCheck(clipboard, [
|
||||
'01-02-03', '01-02-2003',
|
||||
'01 02 2003', '01-02-2003',
|
||||
'1/02/03', '01-02-2003',
|
||||
@ -286,7 +277,6 @@ describe('CopyPaste', function() {
|
||||
'10/20/03', '10-20-2003',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
// Note that these tests which reference other tables
|
||||
// assume that the previous tests have run.
|
||||
@ -298,8 +288,7 @@ describe('CopyPaste', function() {
|
||||
|
||||
// Initially the References.Parsed column is displaying Dates.Text
|
||||
// No date parsing happens, we just see which strings exist in that column
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copyAndCheck(cb, [
|
||||
await copyAndCheck(clipboard, [
|
||||
'20/10/03', '20/10/03',
|
||||
'10/20/03', '10/20/03',
|
||||
'1/2/3', '1/2/3',
|
||||
@ -309,7 +298,6 @@ describe('CopyPaste', function() {
|
||||
'$1', '$1 INVALID',
|
||||
'€89', '€89 INVALID',
|
||||
], true);
|
||||
});
|
||||
|
||||
await gu.setRefShowColumn("Parsed");
|
||||
|
||||
@ -328,8 +316,7 @@ describe('CopyPaste', function() {
|
||||
'€89', '€89 INVALID',
|
||||
]);
|
||||
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copyAndCheck(cb, [
|
||||
await copyAndCheck(clipboard, [
|
||||
'20/10/03', '20/10/03',
|
||||
'10/20/03', '10-20-2003',
|
||||
'1/2/3', '1/2/3',
|
||||
@ -339,7 +326,6 @@ describe('CopyPaste', function() {
|
||||
'$1', `$1 INVALID`,
|
||||
'€89', '€89 INVALID',
|
||||
]);
|
||||
});
|
||||
|
||||
await gu.setRefShowColumn("Row ID");
|
||||
|
||||
@ -355,8 +341,7 @@ describe('CopyPaste', function() {
|
||||
'€89', '€89 INVALID',
|
||||
]);
|
||||
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copyAndCheck(cb, [
|
||||
await copyAndCheck(clipboard, [
|
||||
'20/10/03', '20/10/03 INVALID',
|
||||
'10/20/03', '10/20/03 INVALID',
|
||||
'1/2/3', '1/2/3 INVALID',
|
||||
@ -366,7 +351,6 @@ describe('CopyPaste', function() {
|
||||
'$1', '$1 INVALID',
|
||||
'€89', '€89 INVALID',
|
||||
]);
|
||||
});
|
||||
|
||||
await gu.setRefTable("Numbers");
|
||||
|
||||
@ -374,8 +358,7 @@ describe('CopyPaste', function() {
|
||||
async function checkRefsToNumbers() {
|
||||
await gu.setRefShowColumn("Row ID");
|
||||
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copyAndCheck(cb, [
|
||||
await copyAndCheck(clipboard, [
|
||||
'20/10/03', '20/10/03 INVALID',
|
||||
'10/20/03', '10/20/03 INVALID',
|
||||
'1/2/3', '1/2/3 INVALID',
|
||||
@ -385,12 +368,10 @@ describe('CopyPaste', function() {
|
||||
'$1', '$1 INVALID',
|
||||
'€89', '€89 INVALID',
|
||||
], true);
|
||||
});
|
||||
|
||||
await gu.setRefShowColumn("Text");
|
||||
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copyAndCheck(cb, [
|
||||
await copyAndCheck(clipboard, [
|
||||
'20/10/03', '20/10/03 INVALID',
|
||||
'10/20/03', '10/20/03 INVALID',
|
||||
'1/2/3', '1/2/3 INVALID',
|
||||
@ -401,7 +382,6 @@ describe('CopyPaste', function() {
|
||||
'$1', '$1',
|
||||
'€89', '€89',
|
||||
]);
|
||||
});
|
||||
|
||||
await gu.setRefShowColumn("Parsed");
|
||||
|
||||
@ -417,8 +397,7 @@ describe('CopyPaste', function() {
|
||||
'€89', '89,00 €',
|
||||
]);
|
||||
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copyAndCheck(cb, [
|
||||
await copyAndCheck(clipboard, [
|
||||
'20/10/03', '20/10/03 INVALID',
|
||||
'10/20/03', '10/20/03 INVALID',
|
||||
'1/2/3', '1/2/3 INVALID',
|
||||
@ -428,7 +407,6 @@ describe('CopyPaste', function() {
|
||||
'$1', '$1', // invalid in Numbers.parsed, but a valid reference
|
||||
'€89', '89,00 €',
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
await checkRefsToNumbers();
|
||||
@ -461,9 +439,7 @@ describe('CopyPaste', function() {
|
||||
|
||||
// Now test that pasting the same values into a Reference List column
|
||||
// produces the same result (reflists containing a single reference)
|
||||
await gu.setType(/Reference List/);
|
||||
await gu.applyTypeTransform();
|
||||
await gu.waitForServer();
|
||||
await gu.setType(/Reference List/, {apply: true});
|
||||
|
||||
// Clear the Parsed column. Make sure we don't edit the column header.
|
||||
await gu.getCell({col: "Parsed", rowNum: 1}).click();
|
||||
@ -478,8 +454,7 @@ describe('CopyPaste', function() {
|
||||
async function checkMultiRefs() {
|
||||
await gu.setRefShowColumn("Row ID");
|
||||
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copyAndCheck(cb, [
|
||||
await copyAndCheck(clipboard, [
|
||||
'"(2)",$1', '"(2)",$1 INVALID',
|
||||
'$1,(2),22', '$1,(2),22 INVALID',
|
||||
'["$1",-2]', '["$1",-2] INVALID',
|
||||
@ -489,12 +464,10 @@ describe('CopyPaste', function() {
|
||||
'7,0', '7,0 INVALID', // 0 is not a valid row ID
|
||||
'', '',
|
||||
]);
|
||||
});
|
||||
|
||||
await gu.setRefShowColumn("Text");
|
||||
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copyAndCheck(cb, [
|
||||
await copyAndCheck(clipboard, [
|
||||
'"(2)",$1', '(2)\n$1', // only verbatim text
|
||||
'$1,(2),22', '$1,(2),22 INVALID', // 22 is invalid so whole thing fails
|
||||
'["$1",-2]', '["$1",-2] INVALID', // -2 is invalid because this is text, not parsed
|
||||
@ -504,12 +477,10 @@ describe('CopyPaste', function() {
|
||||
'7,0', '7,0 INVALID',
|
||||
'', '',
|
||||
]);
|
||||
});
|
||||
|
||||
await gu.setRefShowColumn("Parsed");
|
||||
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copyAndCheck(cb, [
|
||||
await copyAndCheck(clipboard, [
|
||||
'"(2)",$1', '-2,00 €\n$1',
|
||||
'$1,(2),22', '$1,(2),22 INVALID',
|
||||
'["$1",-2]', '$1\n-2,00 €',
|
||||
@ -519,7 +490,6 @@ describe('CopyPaste', function() {
|
||||
'7,0', '7,0 INVALID',
|
||||
'', '',
|
||||
], true);
|
||||
});
|
||||
}
|
||||
|
||||
await gu.getPageItem("Multi-References").click();
|
||||
@ -539,8 +509,7 @@ describe('CopyPaste', function() {
|
||||
await gu.getPageItem("ChoiceLists").click();
|
||||
await gu.waitForServer();
|
||||
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copyAndCheck(cb, [
|
||||
await copyAndCheck(clipboard, [
|
||||
'', '',
|
||||
'a', 'a',
|
||||
|
||||
@ -563,14 +532,12 @@ describe('CopyPaste', function() {
|
||||
'[]', '',
|
||||
], true);
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse pasted datetimes', async function() {
|
||||
await gu.getPageItem("DateTimes").click();
|
||||
await gu.waitForServer();
|
||||
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copyAndCheck(cb, [
|
||||
await copyAndCheck(clipboard, [
|
||||
'2021-11-12 22:57:17+03:00', '12-11-2021 21:57 SAST', // note the 1-hour difference
|
||||
'2021-11-12 22:57:17+02:00', '12-11-2021 22:57 SAST',
|
||||
'12-11-2021 22:57:17 SAST', '12-11-2021 22:57 SAST',
|
||||
@ -584,7 +551,6 @@ describe('CopyPaste', function() {
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// mapper for getVisibleGridCells to get both text and whether the cell is invalid (pink).
|
||||
@ -620,7 +586,12 @@ async function copy(cb: gu.IClipboard, fromCol: 'Text' | 'Parsed') {
|
||||
await paste(cb);
|
||||
}
|
||||
|
||||
async function copyAndCheck(cb: gu.IClipboard, expected: string[], extraChecks: boolean = false) {
|
||||
async function copyAndCheck(
|
||||
clipboard: gu.ILockableClipboard,
|
||||
expected: string[],
|
||||
extraChecks: boolean = false
|
||||
) {
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
// Copy Text cells into the Parsed column
|
||||
await copy(cb, 'Text');
|
||||
await checkGridCells(expected);
|
||||
@ -638,11 +609,16 @@ async function copyAndCheck(cb: gu.IClipboard, expected: string[], extraChecks:
|
||||
arrayRepeat(8, ''),
|
||||
);
|
||||
|
||||
// Paste the text cells to the dummy textarea and copy.
|
||||
// Paste the text cells to the dummy textarea.
|
||||
await driver.find('#dummyText').click();
|
||||
await gu.waitAppFocus(false);
|
||||
await cb.paste();
|
||||
}
|
||||
});
|
||||
|
||||
if (extraChecks) {
|
||||
await gu.sendKeys(await gu.selectAllKey());
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await cb.copy();
|
||||
await gu.sendKeys(Key.BACK_SPACE);
|
||||
|
||||
@ -650,10 +626,13 @@ async function copyAndCheck(cb: gu.IClipboard, expected: string[], extraChecks:
|
||||
await gu.getCell({col: 'Text', rowNum: 1}).click();
|
||||
await gu.waitAppFocus();
|
||||
await paste(cb);
|
||||
});
|
||||
await checkGridCells(expected);
|
||||
|
||||
// Check that copying from the Parsed column back into itself doesn't change anything.
|
||||
await clipboard.lockAndPerform(async (cb) => {
|
||||
await copy(cb, 'Parsed');
|
||||
});
|
||||
await checkGridCells(expected);
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import * as gu from 'test/nbrowser/gristUtils';
|
||||
import {setupTestSuite} from 'test/nbrowser/testUtils';
|
||||
|
||||
describe('CopyPasteColumnOptions', function() {
|
||||
this.timeout(10000);
|
||||
this.timeout(20000);
|
||||
const cleanup = setupTestSuite();
|
||||
const clipboard = gu.getLockableClipboard();
|
||||
afterEach(() => gu.checkForErrors());
|
||||
|
@ -4,7 +4,7 @@ import * as gu from 'test/nbrowser/gristUtils';
|
||||
import {server, setupTestSuite} from 'test/nbrowser/testUtils';
|
||||
|
||||
describe('SelectByRefList', function() {
|
||||
this.timeout(80000);
|
||||
this.timeout(90000);
|
||||
setupTestSuite();
|
||||
addToRepl('gu2', gu);
|
||||
gu.bigScreen();
|
||||
|
@ -117,7 +117,7 @@ describe('UploadLimits', function() {
|
||||
const largeFilePath2 = await generateFile(".jpg", maxAttachment - 1000);
|
||||
await gu.fileDialogUpload([largeFilePath1, largeFilePath2].join(","),
|
||||
() => gu.getCell(0, 1).find('.test-attachment-icon').click());
|
||||
await gu.getCell(0, 1).findWait('.test-attachment-widget > [class*=test-pw-]', 1000);
|
||||
await gu.getCell(0, 1).findWait('.test-attachment-widget > [class*=test-pw-]', 2000);
|
||||
|
||||
// We don't expect any errors here.
|
||||
assert.lengthOf(await driver.findAll('.test-notifier-toast-wrapper'), 0);
|
||||
|
@ -3305,8 +3305,9 @@ class LockableClipboard implements ILockableClipboard {
|
||||
lockfilePath: path.join(path.resolve(getAppRoot(), 'test'), '.clipboard.lock'),
|
||||
retries: {
|
||||
/* The clipboard generally isn't locked for long, so retry frequently. */
|
||||
maxTimeout: 1000,
|
||||
retries: 20,
|
||||
minTimeout: 200,
|
||||
maxTimeout: 200,
|
||||
retries: 100,
|
||||
},
|
||||
});
|
||||
try {
|
||||
|
Loading…
Reference in New Issue
Block a user