From 51d839f082568333e3a8f545288b5a055bad3732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaros=C5=82aw=20Sadzi=C5=84ski?= Date: Fri, 30 Sep 2022 16:45:28 +0200 Subject: [PATCH 1/9] Adding dedicated folder for external tests --- package.json | 1 + test/deployment/ActionLog.ts | 1 + test/deployment/ChoiceList.ts | 1 + test/deployment/DuplicateDocument.ts | 1 + test/deployment/Fork.ts | 1 + test/deployment/HomeIntro.ts | 1 + test/deployment/Pages.ts | 1 + test/deployment/README.md | 4 ++++ test/deployment/ReferenceColumns.ts | 1 + test/deployment/ReferenceList.ts | 1 + test/deployment/Smoke.ts | 1 + test/nbrowser/Localization.ts | 5 ++++- test/test_under_docker.sh | 2 +- 13 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 test/deployment/ActionLog.ts create mode 100644 test/deployment/ChoiceList.ts create mode 100644 test/deployment/DuplicateDocument.ts create mode 100644 test/deployment/Fork.ts create mode 100644 test/deployment/HomeIntro.ts create mode 100644 test/deployment/Pages.ts create mode 100644 test/deployment/README.md create mode 100644 test/deployment/ReferenceColumns.ts create mode 100644 test/deployment/ReferenceList.ts create mode 100644 test/deployment/Smoke.ts diff --git a/package.json b/package.json index a49ea86d..b7b1dd20 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "build:prod": "buildtools/build.sh", "start:prod": "sandbox/run.sh", "test": "GRIST_SESSION_COOKIE=grist_test_cookie GRIST_TEST_LOGIN=1 TEST_SUPPORT_API_KEY=api_key_for_support TEST_CLEAN_DATABASE=true NODE_PATH=_build:_build/stubs:_build/ext mocha -g ${GREP_TESTS:-''} _build/test/common/*.js _build/test/client/*.js _build/test/nbrowser/*.js _build/test/server/**/*.js _build/test/gen-server/**/*.js", + "test:nbrowser": "GRIST_SESSION_COOKIE=grist_test_cookie GRIST_TEST_LOGIN=1 TEST_SUPPORT_API_KEY=api_key_for_support TEST_CLEAN_DATABASE=true NODE_PATH=_build:_build/stubs:_build/ext mocha -g ${GREP_TESTS:-''} --slow 6000 _build/test/nbrowser/**/*.js", "test:client": "GRIST_SESSION_COOKIE=grist_test_cookie NODE_PATH=_build:_build/stubs:_build/ext mocha _build/test/client/**/*.js", "test:common": "GRIST_SESSION_COOKIE=grist_test_cookie NODE_PATH=_build:_build/stubs:_build/ext mocha _build/test/common/**/*.js", "test:server": "GRIST_SESSION_COOKIE=grist_test_cookie NODE_PATH=_build:_build/stubs:_build/ext mocha _build/test/server/**/*.js _build/test/gen-server/**/*.js", diff --git a/test/deployment/ActionLog.ts b/test/deployment/ActionLog.ts new file mode 100644 index 00000000..4b9ca975 --- /dev/null +++ b/test/deployment/ActionLog.ts @@ -0,0 +1 @@ +import "test/nbrowser/ActionLog"; \ No newline at end of file diff --git a/test/deployment/ChoiceList.ts b/test/deployment/ChoiceList.ts new file mode 100644 index 00000000..1f3af737 --- /dev/null +++ b/test/deployment/ChoiceList.ts @@ -0,0 +1 @@ +import "test/nbrowser/ChoiceList"; \ No newline at end of file diff --git a/test/deployment/DuplicateDocument.ts b/test/deployment/DuplicateDocument.ts new file mode 100644 index 00000000..39928a33 --- /dev/null +++ b/test/deployment/DuplicateDocument.ts @@ -0,0 +1 @@ +import "test/nbrowser/DuplicateDocument"; \ No newline at end of file diff --git a/test/deployment/Fork.ts b/test/deployment/Fork.ts new file mode 100644 index 00000000..604d4cba --- /dev/null +++ b/test/deployment/Fork.ts @@ -0,0 +1 @@ +import "test/nbrowser/Fork"; \ No newline at end of file diff --git a/test/deployment/HomeIntro.ts b/test/deployment/HomeIntro.ts new file mode 100644 index 00000000..8dcee9cb --- /dev/null +++ b/test/deployment/HomeIntro.ts @@ -0,0 +1 @@ +import "test/nbrowser/Pages"; \ No newline at end of file diff --git a/test/deployment/Pages.ts b/test/deployment/Pages.ts new file mode 100644 index 00000000..8dcee9cb --- /dev/null +++ b/test/deployment/Pages.ts @@ -0,0 +1 @@ +import "test/nbrowser/Pages"; \ No newline at end of file diff --git a/test/deployment/README.md b/test/deployment/README.md new file mode 100644 index 00000000..9ea68219 --- /dev/null +++ b/test/deployment/README.md @@ -0,0 +1,4 @@ +# Deployment tests + +Link or import here all tests that can be run against an external server or +a docker container (i.e: tests that don't rely on in-memory TestServer). \ No newline at end of file diff --git a/test/deployment/ReferenceColumns.ts b/test/deployment/ReferenceColumns.ts new file mode 100644 index 00000000..4f83cdb0 --- /dev/null +++ b/test/deployment/ReferenceColumns.ts @@ -0,0 +1 @@ +import "test/nbrowser/ReferenceColumns"; \ No newline at end of file diff --git a/test/deployment/ReferenceList.ts b/test/deployment/ReferenceList.ts new file mode 100644 index 00000000..1de64306 --- /dev/null +++ b/test/deployment/ReferenceList.ts @@ -0,0 +1 @@ +import "test/nbrowser/ReferenceList"; \ No newline at end of file diff --git a/test/deployment/Smoke.ts b/test/deployment/Smoke.ts new file mode 100644 index 00000000..e3146458 --- /dev/null +++ b/test/deployment/Smoke.ts @@ -0,0 +1 @@ +import "test/nbrowser/Smoke"; \ No newline at end of file diff --git a/test/nbrowser/Localization.ts b/test/nbrowser/Localization.ts index 6ab7d2bc..b1179186 100644 --- a/test/nbrowser/Localization.ts +++ b/test/nbrowser/Localization.ts @@ -117,7 +117,10 @@ describe("Localization", function() { }); }); - it("breaks the server if something is wrong with resource files", async () => { + it("breaks the server if something is wrong with resource files", async function() { + if (server.isExternalServer()) { + this.skip(); + } const oldEnv = new testUtils.EnvironmentSnapshot(); try { // Wrong path to locales. diff --git a/test/test_under_docker.sh b/test/test_under_docker.sh index e2db8131..73682fc7 100755 --- a/test/test_under_docker.sh +++ b/test/test_under_docker.sh @@ -64,4 +64,4 @@ TEST_ADD_SAMPLES=1 TEST_ACCOUNT_PASSWORD=not-needed \ GRIST_SESSION_COOKIE=grist_test_cookie \ GRIST_TEST_LOGIN=1 \ NODE_PATH=_build:_build/stubs \ - $MOCHA _build/test/nbrowser/*.js -g ${GREP_TESTS:-''} "$@" + $MOCHA _build/test/deployment/*.js --slow 6000 -g ${GREP_TESTS:-''} "$@" From a8ead09fc539e6d46e9121e8e11b10cacb8d06ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaros=C5=82aw=20Sadzi=C5=84ski?= Date: Fri, 30 Sep 2022 17:00:38 +0200 Subject: [PATCH 2/9] Adding new lines at the end --- test/deployment/ActionLog.ts | 2 +- test/deployment/ChoiceList.ts | 2 +- test/deployment/DuplicateDocument.ts | 2 +- test/deployment/Fork.ts | 2 +- test/deployment/HomeIntro.ts | 2 +- test/deployment/Pages.ts | 2 +- test/deployment/README.md | 2 +- test/deployment/ReferenceColumns.ts | 2 +- test/deployment/ReferenceList.ts | 2 +- test/deployment/Smoke.ts | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/deployment/ActionLog.ts b/test/deployment/ActionLog.ts index 4b9ca975..4a9c7c52 100644 --- a/test/deployment/ActionLog.ts +++ b/test/deployment/ActionLog.ts @@ -1 +1 @@ -import "test/nbrowser/ActionLog"; \ No newline at end of file +import "test/nbrowser/ActionLog"; diff --git a/test/deployment/ChoiceList.ts b/test/deployment/ChoiceList.ts index 1f3af737..389d6c9a 100644 --- a/test/deployment/ChoiceList.ts +++ b/test/deployment/ChoiceList.ts @@ -1 +1 @@ -import "test/nbrowser/ChoiceList"; \ No newline at end of file +import "test/nbrowser/ChoiceList"; diff --git a/test/deployment/DuplicateDocument.ts b/test/deployment/DuplicateDocument.ts index 39928a33..993a1d80 100644 --- a/test/deployment/DuplicateDocument.ts +++ b/test/deployment/DuplicateDocument.ts @@ -1 +1 @@ -import "test/nbrowser/DuplicateDocument"; \ No newline at end of file +import "test/nbrowser/DuplicateDocument"; diff --git a/test/deployment/Fork.ts b/test/deployment/Fork.ts index 604d4cba..9f1da80e 100644 --- a/test/deployment/Fork.ts +++ b/test/deployment/Fork.ts @@ -1 +1 @@ -import "test/nbrowser/Fork"; \ No newline at end of file +import "test/nbrowser/Fork"; diff --git a/test/deployment/HomeIntro.ts b/test/deployment/HomeIntro.ts index 8dcee9cb..508a9e94 100644 --- a/test/deployment/HomeIntro.ts +++ b/test/deployment/HomeIntro.ts @@ -1 +1 @@ -import "test/nbrowser/Pages"; \ No newline at end of file +import "test/nbrowser/HomeIntro"; diff --git a/test/deployment/Pages.ts b/test/deployment/Pages.ts index 8dcee9cb..b510e64d 100644 --- a/test/deployment/Pages.ts +++ b/test/deployment/Pages.ts @@ -1 +1 @@ -import "test/nbrowser/Pages"; \ No newline at end of file +import "test/nbrowser/Pages"; diff --git a/test/deployment/README.md b/test/deployment/README.md index 9ea68219..f2163593 100644 --- a/test/deployment/README.md +++ b/test/deployment/README.md @@ -1,4 +1,4 @@ # Deployment tests Link or import here all tests that can be run against an external server or -a docker container (i.e: tests that don't rely on in-memory TestServer). \ No newline at end of file +a docker container (i.e: tests that don't rely on in-memory TestServer). diff --git a/test/deployment/ReferenceColumns.ts b/test/deployment/ReferenceColumns.ts index 4f83cdb0..48272984 100644 --- a/test/deployment/ReferenceColumns.ts +++ b/test/deployment/ReferenceColumns.ts @@ -1 +1 @@ -import "test/nbrowser/ReferenceColumns"; \ No newline at end of file +import "test/nbrowser/ReferenceColumns"; diff --git a/test/deployment/ReferenceList.ts b/test/deployment/ReferenceList.ts index 1de64306..47186612 100644 --- a/test/deployment/ReferenceList.ts +++ b/test/deployment/ReferenceList.ts @@ -1 +1 @@ -import "test/nbrowser/ReferenceList"; \ No newline at end of file +import "test/nbrowser/ReferenceList"; diff --git a/test/deployment/Smoke.ts b/test/deployment/Smoke.ts index e3146458..2e0bff89 100644 --- a/test/deployment/Smoke.ts +++ b/test/deployment/Smoke.ts @@ -1 +1 @@ -import "test/nbrowser/Smoke"; \ No newline at end of file +import "test/nbrowser/Smoke"; From 3f9d0b45b73a9853ff922d005101477088145426 Mon Sep 17 00:00:00 2001 From: Louis Delbosc Date: Fri, 30 Sep 2022 17:34:53 +0200 Subject: [PATCH 3/9] Remove duplicated hide colum option (#292) * Remove duplicated hide column option * Hide hide field in raw view --- app/client/ui/GridViewMenus.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/client/ui/GridViewMenus.ts b/app/client/ui/GridViewMenus.ts index b366f595..418b108b 100644 --- a/app/client/ui/GridViewMenus.ts +++ b/app/client/ui/GridViewMenus.ts @@ -58,7 +58,7 @@ export function calcFieldsCondition(fields: ViewFieldRec[], condition: (f: ViewF } export function ColumnContextMenu(options: IColumnContextMenu) { - const { disableModify, filterOpenFunc, colId, sortSpec, isReadonly, isRaw } = options; + const { disableModify, filterOpenFunc, colId, sortSpec, isReadonly } = options; const disableForReadonlyColumn = dom.cls('disabled', Boolean(disableModify) || isReadonly); @@ -112,7 +112,6 @@ export function ColumnContextMenu(options: IColumnContextMenu) { menuItem(allCommands.sortFilterTabOpen.run, 'More sort options ...', testId('more-sort-options')), menuDivider({style: 'margin-top: 0;'}), menuItemCmd(allCommands.renameField, 'Rename column', disableForReadonlyColumn), - menuItemCmd(allCommands.hideFields, 'Hide column', dom.cls('disabled', isReadonly || isRaw)), freezeMenuItemCmd(options), menuDivider(), MultiColumnMenu((options.disableFrozenMenu = true, options)), @@ -149,7 +148,7 @@ export function MultiColumnMenu(options: IMultiColumnContextMenu) { (options.isFormula !== true ? menuItemCmd(allCommands.clearValues, 'Clear values', disableForReadonlyColumn) : null), - menuItemCmd(allCommands.hideFields, nameHideColumns, disableForReadonlyView), + (!options.isRaw ? menuItemCmd(allCommands.hideFields, nameHideColumns, disableForReadonlyView) : null), menuItemCmd(allCommands.clearColumns, nameClearColumns, disableForReadonlyColumn), menuItemCmd(allCommands.deleteFields, nameDeleteColumns, disableForReadonlyColumn), From d69ac6a789cdf617e55c1542462c22875a81b214 Mon Sep 17 00:00:00 2001 From: George Gevoian Date: Sun, 2 Oct 2022 23:10:32 -0700 Subject: [PATCH 4/9] Run python tests during main workflow --- .github/workflows/main.yml | 3 +++ package.json | 1 + 2 files changed, 4 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 66bd623c..07df5fe7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -44,6 +44,9 @@ jobs: - name: Run smoke test run: VERBOSE=1 DEBUG=1 MOCHA_WEBDRIVER_HEADLESS=1 yarn run test:smoke + - name: Run python tests + run: yarn run test:python + - name: Run main tests run: MOCHA_WEBDRIVER_HEADLESS=1 yarn run test diff --git a/package.json b/package.json index b7b1dd20..0846a034 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "test:server": "GRIST_SESSION_COOKIE=grist_test_cookie NODE_PATH=_build:_build/stubs:_build/ext mocha _build/test/server/**/*.js _build/test/gen-server/**/*.js", "test:smoke": "NODE_PATH=_build:_build/stubs:_build/ext mocha _build/test/nbrowser/Smoke.js", "test:docker": "./test/test_under_docker.sh", + "test:python": "sandbox_venv3/bin/python sandbox/grist/runtests.py ${GREP_TESTS:+discover -p \"test*${GREP_TESTS}*.py\"} --xunit", "cli": "NODE_PATH=_build:_build/stubs:_build/ext node _build/app/server/companion.js" }, "keywords": [ From 4a1099ad070f755de1c25ef36d8d524b3bd52234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaros=C5=82aw=20Sadzi=C5=84ski?= Date: Fri, 30 Sep 2022 17:26:31 +0200 Subject: [PATCH 5/9] Adding a description and instruction document on how to translate main application --- help/translations.md | 145 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 help/translations.md diff --git a/help/translations.md b/help/translations.md new file mode 100644 index 00000000..80b8d3d2 --- /dev/null +++ b/help/translations.md @@ -0,0 +1,145 @@ +# Internationalization and Localization + +## General description + +Localization support (translations) in Grist is implemented via +[https://www.i18next.com](https://www.i18next.com/overview/plugins-and-utils) javascript library. It +is used both on the server (node) and the client side (browser). It has very good documentation, +supports all needed features (like interpolation, pluralization and context), and has a rich plugin +ecosystem. It is also very popular and widely used. + +## Localization setup + +Resource files are located in a `static/locales` directory, but Grist can be configured to read them +from any other location by using the `GRIST_LOCALES_DIR` environmental variable. All resource files +are read when the server starts. The default and required language code is `en` (English), all other +languages are optional and will be supported if server can find a resource file with proper language +code. Languages are resolved hierarchically, from most specific to a general one, for example, for +Polish code _pl-PL_, the library will first try _pl-PL_, then _pl_, and then will fallback to a +default language _en_ (https://www.i18next.com/principles/translation-resolution). + +Here is an example of a language resource file `en.core.json` currently used by Grist: + +```json +{ + "Welcome": "Welcome to Grist!", + "Loading": "Loading", + "AddNew": "Add New", + "OtherSites": "Other Sites", + "OtherSitesWelcome": "Your are on {{siteName}}. You also have access to the following sites:", + "OtherSitesWelcome_personal": "Your are on your personal site. You also have access to the following sites:", + "AllDocuments": "All Documents", + "ExamplesAndTemplates": "Examples and Templates", + "MoreExamplesAndTemplates": "More Examples and Templates" +} +``` + +It maps a key to a translated message. It also has an example of interpolation and context features +in the `OtherSitesWelcome` resource key. More information about how to use those features can be +found at https://www.i18next.com/translation-function/interpolation and +https://www.i18next.com/translation-function/context. + +Both client and server code (node.js) use the same resource files. A resource file name format +follows a pattern: [language code].[product].json (i.e. `pl-Pl.core.json`, `en-US.core.json`, +`en.core.json`). Grist can be packaged as several different products, and each product can have its +own translation files that are added to the core. Products are supported by leveraging `i18next` +feature called `namespaces` https://www.i18next.com/principles/namespaces. + +## Translation instruction + +### Client + +The entry point for all translations is a function exported from 'app/client/lib/localization'. + +```ts +import { t } from 'app/client/lib/localization'; +``` + +It is a wrapper around `i18next` exported method with the same interface +https://www.i18next.com/overview/api#t. As a future improvement, all resource keys used in +translation files will be extracted and converted to a TypeScript definition file, for a “compile” +time error detection and and better development experience. Here are couple examples how this method +is used: + +_app/client/ui.DocMenu.ts_ + +```ts + css.otherSitesHeader( + t('OtherSites'), + ..... + ), + dom.maybe((use) => !use(hideOtherSitesObs), () => { + const personal = Boolean(home.app.currentOrg?.owner); + const siteName = home.app.currentOrgName; + return [ + dom('div', + t('OtherSitesWelcome', { siteName, context: personal ? 'personal' : '' }), + testId('other-sites-message') +``` + +_app/client/ui/HomeIntro.ts_ + +```ts +function makeAnonIntro(homeModel: HomeModel) { + const signUp = cssLink({href: getLoginOrSignupUrl()}, 'Sign up'); + return [ + css.docListHeader(t('Welcome'), testId('welcome-title')), +``` + +Some things are not supported at this moment and will need to be addressed in future development +tasks: + +- Date time picker component. It has its own resource files that are already imported by Grist but + not used in the main application. https://bootstrap-datepicker.readthedocs.io/en/latest/i18n.html +- Static HTML files used as a placeholder (for example, for Custom widgets). +- DocTours (guided tours) that can be embedded inside a Grist document. +- Formatting dates. Grist is using `moment.js` library, which has its own i18n support. Date formats + used by Grist are shared between client, server and sandbox code and are not compatible with + `i18next` library. + +### Server + +For server-side code, Grist is using https://github.com/i18next/i18next-http-middleware plugin, +which exposes `i18next` API in the `Request` object. It automatically detects user language (from +request headers) and configures all API methods to use the proper language (either requested by the +client or a default one). `Comm` object and `webSocket` API use a very similar approach, each +`Client` object has its own instance of `i18next` library configured with a proper language (also +detected from the HTTP headers). + +Naturally, most of the text that should be translated on the server side is used by the Error +handlers. This requires a significant amount of work to change how errors are reported to the +client, and it is still in a design state. + +Here is an example of how to use the API to translate a message from an HTTP endpoint in +`HomeServer`. + +_app/server/lib/sendAppPage.ts_ + +```ts +function getPageTitle(req: express.Request, config: GristLoadConfig): string { + const maybeDoc = getDocFromConfig(config); + if (!maybeDoc) { + return req.t('Loading') + '...'; + } + + return handlebars.Utils.escapeExpression(maybeDoc.name); +} +``` + +### Next steps + +- Annotate all client code and create all resource files in `en.core.json` file. Almost all static + text is ready for translation. +- Store language settings with the user profile and allow a user to change it on the Account Page. + Consider also adding a cookie-based solution that custom widgets can use, or extend the + **WidgetFrame** component so that it can pass current user language to the hosted widget page. +- Generate type declaration files at build time to provide `missing key` error detection as soon as + possible. +- Dynamically Include calendar control language resource files based on the currently selected + language. +- Refactor server-side code that is handling errors or creating user-facing messages. Currently, + error messages are created at the place where the Error has occurred. Preferably errors should + include error codes and all information needed to assemble the error message by the client code. +- Add localization support to the `moment.js` library to format dates properly according to the + currently selected language. +- Add support for custom HTML page translation. For example `custom-widget.html` From 03631a14547b72eaf1a1c263b5c1d2eb28b6a9c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaros=C5=82aw=20Sadzi=C5=84ski?= Date: Mon, 3 Oct 2022 10:47:42 +0200 Subject: [PATCH 6/9] Improving documentation. Renaming folder to 'documentation' --- app/client/ui/HomeIntro.ts | 2 +- {help => documentation}/translations.md | 9 +++++++-- static/locales/en.core.json | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) rename {help => documentation}/translations.md (92%) diff --git a/app/client/ui/HomeIntro.ts b/app/client/ui/HomeIntro.ts index 8ed16ed1..ed2a6fbf 100644 --- a/app/client/ui/HomeIntro.ts +++ b/app/client/ui/HomeIntro.ts @@ -110,7 +110,7 @@ function makePersonalIntro(homeModel: HomeModel, user: FullUser) { } function makeAnonIntro(homeModel: HomeModel) { - const signUp = cssLink({href: getLoginOrSignupUrl()}, 'Sign up'); + const signUp = cssLink({href: getLoginOrSignupUrl()}, t('SignUp')); return [ css.docListHeader(t('Welcome'), testId('welcome-title')), cssIntroLine('Get started by exploring templates, or creating your first Grist document.'), diff --git a/help/translations.md b/documentation/translations.md similarity index 92% rename from help/translations.md rename to documentation/translations.md index 80b8d3d2..f13e666f 100644 --- a/help/translations.md +++ b/documentation/translations.md @@ -18,6 +18,12 @@ code. Languages are resolved hierarchically, from most specific to a general one Polish code _pl-PL_, the library will first try _pl-PL_, then _pl_, and then will fallback to a default language _en_ (https://www.i18next.com/principles/translation-resolution). +All language variants (e.g., _fr-FR_, _pl-PL_, _en-UK_) are supported if Grist can find a main +language resource file. For example, to support a _fr-FR_ language code, Grist expects to have at +least _fr.core.json_ file. The main language file will be used as a default fallback for all French +language codes like _fr-FR_ or _fr-CA_, in case there is no resource file for a specif variant (like +`fr-CA.core.json`) or some keys are missing from the variant file. + Here is an example of a language resource file `en.core.json` currently used by Grist: ```json @@ -81,7 +87,7 @@ _app/client/ui/HomeIntro.ts_ ```ts function makeAnonIntro(homeModel: HomeModel) { - const signUp = cssLink({href: getLoginOrSignupUrl()}, 'Sign up'); + const signUp = cssLink({href: getLoginOrSignupUrl()}, t('SignUp')); return [ css.docListHeader(t('Welcome'), testId('welcome-title')), ``` @@ -92,7 +98,6 @@ tasks: - Date time picker component. It has its own resource files that are already imported by Grist but not used in the main application. https://bootstrap-datepicker.readthedocs.io/en/latest/i18n.html - Static HTML files used as a placeholder (for example, for Custom widgets). -- DocTours (guided tours) that can be embedded inside a Grist document. - Formatting dates. Grist is using `moment.js` library, which has its own i18n support. Date formats used by Grist are shared between client, server and sandbox code and are not compatible with `i18next` library. diff --git a/static/locales/en.core.json b/static/locales/en.core.json index 1f1a2176..b9818c72 100644 --- a/static/locales/en.core.json +++ b/static/locales/en.core.json @@ -1,5 +1,6 @@ { "Welcome": "Welcome to Grist!", + "SignUp": "Sign up", "Loading": "Loading", "AddNew": "Add New", "OtherSites": "Other Sites", From 7d4d2711ba716ceede9d756a802c5d089ccf4243 Mon Sep 17 00:00:00 2001 From: George Gevoian Date: Mon, 3 Oct 2022 08:13:37 -0700 Subject: [PATCH 7/9] Remove --xunit argument --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0846a034..49fdcea8 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "test:server": "GRIST_SESSION_COOKIE=grist_test_cookie NODE_PATH=_build:_build/stubs:_build/ext mocha _build/test/server/**/*.js _build/test/gen-server/**/*.js", "test:smoke": "NODE_PATH=_build:_build/stubs:_build/ext mocha _build/test/nbrowser/Smoke.js", "test:docker": "./test/test_under_docker.sh", - "test:python": "sandbox_venv3/bin/python sandbox/grist/runtests.py ${GREP_TESTS:+discover -p \"test*${GREP_TESTS}*.py\"} --xunit", + "test:python": "sandbox_venv3/bin/python sandbox/grist/runtests.py ${GREP_TESTS:+discover -p \"test*${GREP_TESTS}*.py\"}", "cli": "NODE_PATH=_build:_build/stubs:_build/ext node _build/app/server/companion.js" }, "keywords": [ From c791e5c0ad273ec8ac7f1c574420ccab8fc3388b Mon Sep 17 00:00:00 2001 From: George Gevoian Date: Mon, 3 Oct 2022 16:43:22 -0700 Subject: [PATCH 8/9] Add Tests section to README --- README.md | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 10ebbf23..946acd60 100644 --- a/README.md +++ b/README.md @@ -291,12 +291,42 @@ Testing: Variable | Purpose -------- | ------- -GRIST_TESTING_SOCKET | a socket used for out-of-channel communication during tests only. +GRIST_TESTING_SOCKET | a socket used for out-of-channel communication during tests only. GRIST_TEST_HTTPS_OFFSET | if set, adds https ports at the specified offset. This is useful in testing. -GRIST_TEST_SSL_CERT | if set, contains filename of SSL certificate. -GRIST_TEST_SSL_KEY | if set, contains filename of SSL private key. -GRIST_TEST_LOGIN | allow fake unauthenticated test logins (suitable for dev environment only). -GRIST_TEST_ROUTER | if set, then the home server will serve a mock version of router api at /test/router +GRIST_TEST_SSL_CERT | if set, contains filename of SSL certificate. +GRIST_TEST_SSL_KEY | if set, contains filename of SSL private key. +GRIST_TEST_LOGIN | allow fake unauthenticated test logins (suitable for dev environment only). +GRIST_TEST_ROUTER | if set, then the home server will serve a mock version of router api at /test/router +GREP_TESTS | pattern for selecting specific tests to run (e.g. `env GREP_TESTS=ActionLog yarn test`). + +## Tests + +Tests are run automatically as part of CI when a PR is opened. However, it can be helpful to run tests locally +before pushing your changes to GitHub. First, you'll want to make sure you've installed all dependencies: + +``` +yarn install +yarn install:python +``` + +Then, you can run the main test suite like so: + +``` +yarn test +``` + +Python tests may also be run locally. (Note: currently requires Python 3.9). + +``` +yarn test:python +``` + +For running specific tests, you can specify a pattern with the `GREP_TESTS` variable: + +``` +env GREP_TESTS=ChoiceList yarn test +env GREP_TESTS=summary yarn test:python +``` ## License From 653eb143d57b3d8f8547e68b9307023aa2f27836 Mon Sep 17 00:00:00 2001 From: George Gevoian Date: Mon, 3 Oct 2022 16:46:33 -0700 Subject: [PATCH 9/9] Move period --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 946acd60..48a1fd9f 100644 --- a/README.md +++ b/README.md @@ -315,7 +315,7 @@ Then, you can run the main test suite like so: yarn test ``` -Python tests may also be run locally. (Note: currently requires Python 3.9). +Python tests may also be run locally. (Note: currently requires Python 3.9.) ``` yarn test:python