From 8015731aa04a1a05d69174e4ab69233497893862 Mon Sep 17 00:00:00 2001 From: Willard Nilges Date: Sat, 23 Nov 2024 00:11:45 -0500 Subject: [PATCH] Translate the info confirmation dialogue (#125) * Add additional Spanish translations * Translate haitian creole's label * Fix locators on tests * pretty * Use Google Translate on the languages I don't speak * computers * oops forgot a stanza * Update README.md --- README.md | 9 +++---- messages/en.json | 2 +- messages/es.json | 19 ++++++++++++-- messages/fr.json | 17 ++++++++++++- messages/ht.json | 17 ++++++++++++- messages/zh.json | 17 ++++++++++++- tests/02_join_form.spec.ts | 10 +++++++- tests/05_join_form_i18n.spec.ts | 45 +++++++++++++++++++++++++++++++++ tests/util.ts | 30 ++++++++++------------ 9 files changed, 138 insertions(+), 28 deletions(-) create mode 100644 tests/05_join_form_i18n.spec.ts diff --git a/README.md b/README.md index d4dbf83..94a4a97 100644 --- a/README.md +++ b/README.md @@ -107,8 +107,8 @@ Try running `npm run build` ## Internationalization > [!NOTE] -> Do you speak a language we already have? Feel free to validate the translation, -> offer feedback, or help translate more of Meshforms! +> Do you speak a language besides English? Please help us by adding more languages, +> validating our existing translations, or translating more of Meshforms! We use `next-intl` as a library for internationalization. @@ -120,8 +120,7 @@ To add a new language: - Update the "locale" key in every file in the `messages/` directory (this one: `"locale": "{locale, select, en {🇺🇸 English} es {🇪🇸 Español} fr {🇫🇷 Français} ht {🇭🇹 Haitian Creole} zh {🇨🇳 中文} other {Unknown}}"`) - Add some tests to ensure that your language shows up in the Join Form properly -> [!WARN] +> [!WARNING] > Please keep the language codes alphabetical! -Thank you for helping us reach more people by adding your language. Your contributions -as an interpreter are invaluable and we very much appreciate it! +Thank you for your contributions! diff --git a/messages/en.json b/messages/en.json index 028f956..3aab15f 100644 --- a/messages/en.json +++ b/messages/en.json @@ -4,7 +4,7 @@ }, "LocaleSwitcher": { "label": "Language", - "locale": "{locale, select, en {🇺🇸 English} es {🇪🇸 Español} fr {🇫🇷 Français} ht {🇭🇹 Haitian Creole} zh {🇨🇳 中文} other {Unknown}}" + "locale": "{locale, select, en {🇺🇸 English} es {🇪🇸 Español} fr {🇫🇷 Français} ht {🇭🇹 Kreyòl ayisyen} zh {🇨🇳 中文} other {Unknown}}" }, "Landing": { "welcome": "Welcome to MeshForms!" diff --git a/messages/es.json b/messages/es.json index dd8c13a..f7f2099 100644 --- a/messages/es.json +++ b/messages/es.json @@ -1,7 +1,7 @@ { "LocaleSwitcher": { "label": "Idioma", - "locale": "{locale, select, en {🇺🇸 English} es {🇪🇸 Español} fr {🇫🇷 Français} ht {🇭🇹 Haitian Creole} zh {🇨🇳 中文} other {Unknown}}" + "locale": "{locale, select, en {🇺🇸 English} es {🇪🇸 Español} fr {🇫🇷 Français} ht {🇭🇹 Kreyòl ayisyen} zh {🇨🇳 中文} other {Unknown}}" }, "Landing": { "welcome": "¡Bienvenidos a MeshForms!" @@ -39,11 +39,26 @@ "NJ": "Nueva Jersey" }, "thankYou": { - "header": "¡Gracias! Revisa su correo electronico, por favor.", + "header": "¡Gracias! Por favor revisa su correo electronico.", "thankYou": "Recibirá un correo electronico de nosotros en {slo} con instrucciónes, incluyendo cómo entregar fotos panoramicos.", "minutes": "5-10 minutos", "days": "2-3 dias", "support": "Si no vista el correco electronico, por favor revisa su carpeta de \"Spam\", o envia un correo electronico a support@nycmesh.net por ayuda." + }, + "errors": { + "error": "No pudó entregar el Join Form:", + "errorTryAgain": "No pudó entregar el Join Form. Por favor intentar otra vez más tarde, o contata support@nycmesh.net por ayuda.", + "confirm": "Por favor confirma algo información", + "captchaFail": "Por favor completa una etapa adicional para confirmar su entrega." } + }, + "InfoConfirmation": { + "goBack": "Regresar", + "useOriginal": "Usa original", + "acceptChanges": "Acceptar los cambios", + "pleaseConfirmHeader": "Por favor confirma algo información", + "pleaseConfirmBody": "Debíamos que reformatear algunos de sus datos. Por favor asegurar que los campos abajos son ascertados.", + "originalInformationColumnHeader": "Original", + "newInformationColumnHeader": "Nuevo" } } diff --git a/messages/fr.json b/messages/fr.json index 4009184..478a86e 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -1,7 +1,7 @@ { "LocaleSwitcher": { "label": "Langue", - "locale": "{locale, select, en {🇺🇸 English} es {🇪🇸 Español} fr {🇫🇷 Français} ht {🇭🇹 Haitian Creole} zh {🇨🇳 中文} other {Unknown}}" + "locale": "{locale, select, en {🇺🇸 English} es {🇪🇸 Español} fr {🇫🇷 Français} ht {🇭🇹 Kreyòl ayisyen} zh {🇨🇳 中文} other {Unknown}}" }, "Landing": { "welcome": "Bienvenue dans MeshForms !" @@ -44,6 +44,21 @@ "minutes": "5-10 minutes", "days": "2-3 jours", "support": "Si vous ne voyez pas un courriel de nous, veuillez vérifier votre dossier \"Spam\" ou envoyer un message à support@nycmesh.net pour obtenir de l'aide." + }, + "errors": { + "error": "Impossible de soumettre le formulaire d'inscription :", + "errorTryAgain": "Impossible de soumettre le formulaire d'inscription. Veuillez réessayer plus tard ou contacter support@nycmesh.net pour obtenir de l'aide.", + "confirm": "Veuillez confirmer certaines informations", + "captchaFail": "Veuillez effectuer une étape de vérification supplémentaire pour confirmer votre soumission" } + }, + "InfoConfirmation": { + "goBack": "Revenir en arrière", + "useOriginal": "Utiliser l'original", + "acceptChanges": "Accepter les modifications", + "pleaseConfirmHeader": "Veuillez confirmer certaines informations", + "pleaseConfirmBody": "Nous avons dû reformater certaines de vos informations. Veuillez vous assurer que les champs ci-dessous sont exacts.", + "originalInformationColumnHeader": "Original", + "newInformationColumnHeader": "Nouveau" } } diff --git a/messages/ht.json b/messages/ht.json index f37d23b..9dfcbd0 100644 --- a/messages/ht.json +++ b/messages/ht.json @@ -1,7 +1,7 @@ { "LocaleSwitcher": { "label": "Lang", - "locale": "{locale, select, en {🇺🇸 English} es {🇪🇸 Español} fr {🇫🇷 Français} ht {🇭🇹 Haitian Creole} zh {🇨🇳 中文} other {Unknown}}" + "locale": "{locale, select, en {🇺🇸 English} es {🇪🇸 Español} fr {🇫🇷 Français} ht {🇭🇹 Kreyòl ayisyen} zh {🇨🇳 中文} other {Unknown}}" }, "Landing": { "welcome": "Byenveni nan MeshForms!" @@ -44,6 +44,21 @@ "minutes": "5-10 minit", "days": "2-3 jou", "support": "Si ou pa wè imèl la, tanpri tcheke dosye \"Spam\" ou a, oswa voye yon imèl ba support@nycmesh.net pou jwenn èd." + }, + "errors": { + "error": "Pa t 'kapab soumèt Fòm Join:", + "errorTryAgain": "Pa t 'kapab soumèt Fòm Join. Tanpri eseye ankò pita, oswa kontakte support@nycmesh.net pou asistans.", + "confirm": "Tanpri konfime kèk enfòmasyon", + "captchaFail": "Tanpri ranpli yon etap verifikasyon adisyonèl pou konfime soumèt ou a" } + }, + "InfoConfirmation": { + "goBack": "Tounen", + "useOriginal": "Sèvi ak orijinal", + "acceptChanges": "Aksepte Chanjman", + "pleaseConfirmHeader": "Tanpri konfime kèk enfòmasyon", + "pleaseConfirmBody": "Nou te bezwen re-fòma kèk nan enfòmasyon ou yo. Tanpri asire ke jaden ki anba yo egzat.", + "originalInformationColumnHeader": "Original", + "newInformationColumnHeader": "Nouvo" } } diff --git a/messages/zh.json b/messages/zh.json index f6d0296..beb3b83 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -1,7 +1,7 @@ { "LocaleSwitcher": { "label": "语言", - "locale": "{locale, select, en {🇺🇸 English} es {🇪🇸 Español} fr {🇫🇷 Français} ht {🇭🇹 Haitian Creole} zh {🇨🇳 中文} other {Unknown}}" + "locale": "{locale, select, en {🇺🇸 English} es {🇪🇸 Español} fr {🇫🇷 Français} ht {🇭🇹 Kreyòl ayisyen} zh {🇨🇳 中文} other {Unknown}}" }, "Landing": { "welcome": "欢迎来到 MeshForms!" @@ -44,6 +44,21 @@ "minutes": "5-10 分钟", "days": "2-3 天", "support": "如果您没有看到电子邮件,请检查您的\"垃圾邮件\"文件夹,或发送电子邮件至 support@nycmesh.net 寻求帮助。" + }, + "errors": { + "error": "无法提交加入表单:", + "errorTryAgain": "无法提交加入表单。请稍后重试,或联系 support@nycmesh.net 寻求帮助。", + "confirm": "请确认一些信息", + "captchaFail": "请完成额外的验证步骤以确认您的提交" } + }, + "InfoConfirmation": { + "goBack": "返回", + "useOriginal": "使用原始信息", + "acceptChanges": "接受更改", + "pleaseConfirmHeader": "请确认一些信息", + "pleaseConfirmBody": "我们需要重新格式化您的一些信息。请确保以下字段准确无误。", + "originalInformationColumnHeader": "原始信息", + "newInformationColumnHeader": "新信息" } } diff --git a/tests/02_join_form.spec.ts b/tests/02_join_form.spec.ts index 584b419..fa2edf0 100644 --- a/tests/02_join_form.spec.ts +++ b/tests/02_join_form.spec.ts @@ -27,7 +27,7 @@ const unitTestTimeout = 5000; // the form creates a good-looking payload and can hit a mock API. test("change language from english to spanish", async ({ page }) => { - test.setTimeout(10000); + test.setTimeout(20000); await page.goto("/join"); // Is the page title correct? @@ -42,6 +42,14 @@ test("change language from english to spanish", async ({ page }) => { await expect(page.locator("[id='joinform-title']")).toHaveText( "Únase NYC Mesh", ); + + // Set up sample data. + await fillOutJoinForm(page, sampleData); + + await submitSuccessExpected(page, unitTestTimeout); + await expect(page.locator("[id='alert-thank-you-h2']")).toHaveText( + "¡Gracias! Por favor revisa su correo electronico.", + ); }); test("happy join form", async ({ page }) => { diff --git a/tests/05_join_form_i18n.spec.ts b/tests/05_join_form_i18n.spec.ts new file mode 100644 index 0000000..26c1985 --- /dev/null +++ b/tests/05_join_form_i18n.spec.ts @@ -0,0 +1,45 @@ +import { JoinFormValues } from "@/components/JoinForm/JoinForm"; +import { test, expect } from "./mock/test"; + +import { + sampleData, + fillOutJoinForm, + submitConfirmationDialogExpected, + expectSuccess, +} from "./util"; + +const joinFormTimeout = 40000; +const unitTestTimeout = 5000; + +test("es confirm street address", async ({ page }) => { + test.setTimeout(joinFormTimeout); + await page.goto("/join"); + + // Is the page title correct? + await expect(page).toHaveTitle(/Join Our Community Network!/); + + await page + .locator("[id='joinform-locale-switcher-select']") + .selectOption("🇪🇸 Español"); + + await expect(page.locator("[id='joinform-title']")).toHaveText( + "Únase NYC Mesh", + ); + + let data: JoinFormValues = Object.assign({}, sampleData); + data.street_address = "197 prospect pl"; + + // Set up sample data. + await fillOutJoinForm(page, data); + + await submitConfirmationDialogExpected(page, 2000); + + // Ensure the dialogue is translated + await expect(page.locator("[id='alert-dialog-description']")).toHaveText( + "Debíamos que reformatear algunos de sus datos. Por favor asegurar que los campos abajos son ascertados.", + ); + + await page.locator("[name='confirm']").click(); + + await expectSuccess(page, unitTestTimeout); +}); diff --git a/tests/util.ts b/tests/util.ts index 232f445..89ed3b0 100644 --- a/tests/util.ts +++ b/tests/util.ts @@ -83,22 +83,20 @@ export async function fillOutJoinForm(page: Page, sampleData: JoinFormValues) { // Set up some sample data // Personal info - await page.getByPlaceholder("First Name").fill(sampleData.first_name); - await page.getByPlaceholder("Last Name").fill(sampleData.last_name); - await page.getByPlaceholder("Email Address").fill(sampleData.email_address); - await page.getByPlaceholder("Phone Number").fill(sampleData.phone_number); + await page.locator("[name='first_name']").fill(sampleData.first_name); + await page.locator("[name='last_name']").fill(sampleData.last_name); + await page.locator("[name='email_address']").fill(sampleData.email_address); + await page.locator("[name='phone_number']").fill(sampleData.phone_number); // Address Info - await page.getByPlaceholder("Street Address").fill(sampleData.street_address); - await page.getByPlaceholder("Unit / Apartment #").fill(sampleData.apartment); - await page.getByPlaceholder("City").fill(sampleData.city); - await page.getByPlaceholder("State").fill(sampleData.state); - await page.getByPlaceholder("Zip Code").fill(sampleData.zip_code.toString()); + await page.locator("[name='street_address']").fill(sampleData.street_address); + await page.locator("[name='apartment']").fill(sampleData.apartment); + await page.locator("[name='city']").fill(sampleData.city); + await page.locator("[name='state']").fill(sampleData.state); + await page.locator("[name='zip_code']").fill(sampleData.zip_code.toString()); // How did you hear about us? - await page - .getByPlaceholder("How did you hear about us?") - .fill(sampleData.referral); + await page.locator("[name='referral']").fill(sampleData.referral); // Agree to the NCL if (sampleData.ncl) { @@ -114,7 +112,7 @@ export async function fillOutJoinForm(page: Page, sampleData: JoinFormValues) { export async function submitFailureExpected(page: Page) { await page.waitForTimeout(1000); // Submit the join form - await page.getByRole("button", { name: /Submit/i }).click(); + await page.locator("[name='submit_join_form']").click(); await page.waitForTimeout(1000); @@ -125,7 +123,7 @@ export async function submitFailureExpected(page: Page) { export async function submitAndCheckToast(page: Page, toastMessage: string) { await page.waitForTimeout(1000); // Submit the join form - await page.getByRole("button", { name: /Submit/i }).click(); + await page.locator("[name='submit_join_form']").click(); await page.waitForTimeout(1000); @@ -143,7 +141,7 @@ export async function submitSuccessExpected( page.on("console", (msg) => console.log(msg.text())); // Submit the join form - await page.getByRole("button", { name: /Submit/i }).click(); + await page.locator("[name='submit_join_form']").click(); await expectSuccess(page, timeout); } @@ -162,7 +160,7 @@ export async function submitConfirmationDialogExpected( page.on("console", (msg) => console.log(msg.text())); // Submit the join form - await page.getByRole("button", { name: /Submit/i }).click(); + await page.locator("[name='submit_join_form']").click(); await page.waitForTimeout(timeout); await expect(page.locator("[id='alert-dialog-title']")).toBeVisible();