mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-06-28 04:02:12 +00:00
[tests] Fix and refactor e2e test "Same keys" in "translations_spec.js" (#3809)
While working on the translations (in #3792 and #3794) I realised that the e2e "Same keys" tests were not working entirely. There was also a TODO entry for this in the test, as well as a try-catch-block workaround. I therefore fixed and refactored it. I also sorted the translations in `translations/translations.js`, so that the test outputs are alphabetically.
This commit is contained in:
parent
faf15ad211
commit
2194ffd929
@ -45,6 +45,7 @@ planned for 2025-07-01
|
|||||||
- [calendar] fix fullday event rrule until with timezone offset (#3781)
|
- [calendar] fix fullday event rrule until with timezone offset (#3781)
|
||||||
- [feat] Add rule `no-undef` in config file validation to fix #3785 (#3786)
|
- [feat] Add rule `no-undef` in config file validation to fix #3785 (#3786)
|
||||||
- [fonts] Fix `roboto.css` to avoid error message `Unknown descriptor 'var(' in @font-face rule.` in firefox console (#3787)
|
- [fonts] Fix `roboto.css` to avoid error message `Unknown descriptor 'var(' in @font-face rule.` in firefox console (#3787)
|
||||||
|
- [tests] Fix and refactor e2e test `Same keys` in `translations_spec.js` (#3809)
|
||||||
|
|
||||||
### Updated
|
### Updated
|
||||||
|
|
||||||
|
@ -154,77 +154,79 @@ describe("Translations", () => {
|
|||||||
|
|
||||||
describe("Same keys", () => {
|
describe("Same keys", () => {
|
||||||
let base;
|
let base;
|
||||||
let missing = [];
|
|
||||||
|
|
||||||
beforeAll(() => {
|
// Some expressions are not easy to translate automatically. For the sake of a working test, we filter them out.
|
||||||
return new Promise((done) => {
|
const COMMON_EXCEPTIONS = ["WEEK_SHORT"];
|
||||||
const dom = new JSDOM(
|
|
||||||
`<script>var translations = ${JSON.stringify(translations)}; var Log = {log: () => {}};</script>\
|
// Some languages don't have certain words, so we need to filter those language specific exceptions.
|
||||||
<script src="file://${path.join(__dirname, "..", "..", "js", "translator.js")}">`,
|
const LANGUAGE_EXCEPTIONS = {
|
||||||
{ runScripts: "dangerously", resources: "usable" }
|
ca: ["DAYBEFOREYESTERDAY"],
|
||||||
);
|
cv: ["DAYBEFOREYESTERDAY"],
|
||||||
|
cy: ["DAYBEFOREYESTERDAY"],
|
||||||
|
en: ["DAYAFTERTOMORROW", "DAYBEFOREYESTERDAY"],
|
||||||
|
fy: ["DAYBEFOREYESTERDAY"],
|
||||||
|
gl: ["DAYBEFOREYESTERDAY"],
|
||||||
|
hu: ["DAYBEFOREYESTERDAY"],
|
||||||
|
id: ["DAYBEFOREYESTERDAY"],
|
||||||
|
it: ["DAYBEFOREYESTERDAY"],
|
||||||
|
"pt-br": ["DAYAFTERTOMORROW"],
|
||||||
|
tr: ["DAYBEFOREYESTERDAY"]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to initialize JSDOM and load translations
|
||||||
|
const initializeTranslationDOM = (language) => {
|
||||||
|
const dom = new JSDOM("", { runScripts: "dangerously", resources: "usable" });
|
||||||
|
dom.window.Log = { log: jest.fn() };
|
||||||
|
dom.window.translations = translations;
|
||||||
|
const translatorJs = fs.readFileSync(path.join(__dirname, "..", "..", "js", "translator.js"), "utf-8");
|
||||||
|
dom.window.eval(translatorJs);
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
dom.window.onload = async () => {
|
dom.window.onload = async () => {
|
||||||
const { Translator } = dom.window;
|
const { Translator } = dom.window;
|
||||||
|
await Translator.load(mmm, translations[language], false);
|
||||||
await Translator.load(mmm, translations.de, false);
|
resolve(Translator.translations[mmm.name]);
|
||||||
base = Object.keys(Translator.translations[mmm.name]).sort();
|
|
||||||
done();
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
// Using German as the base rather than English, since
|
||||||
|
// some words do not have a direct translation in English.
|
||||||
|
const germanTranslations = await initializeTranslationDOM("de");
|
||||||
|
base = Object.keys(germanTranslations).sort();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
for (const language in translations) {
|
||||||
console.log(missing);
|
if (language === "de") continue;
|
||||||
});
|
|
||||||
|
|
||||||
// Using German as the base rather than English, since
|
|
||||||
// at least one translated word doesn't exist in English.
|
|
||||||
for (let language in translations) {
|
|
||||||
if (language === "de") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
describe(`Translation keys of ${language}`, () => {
|
describe(`Translation keys of ${language}`, () => {
|
||||||
let keys;
|
let keys;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(async () => {
|
||||||
return new Promise((done) => {
|
const languageTranslations = await initializeTranslationDOM(language);
|
||||||
const dom = new JSDOM(
|
keys = Object.keys(languageTranslations).sort();
|
||||||
`<script>var translations = ${JSON.stringify(translations)}; var Log = {log: () => {}};</script>\
|
|
||||||
<script src="file://${path.join(__dirname, "..", "..", "js", "translator.js")}">`,
|
|
||||||
{ runScripts: "dangerously", resources: "usable" }
|
|
||||||
);
|
|
||||||
dom.window.onload = async () => {
|
|
||||||
const { Translator } = dom.window;
|
|
||||||
|
|
||||||
await Translator.load(mmm, translations[language], false);
|
|
||||||
keys = Object.keys(Translator.translations[mmm.name]).sort();
|
|
||||||
done();
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`${language} keys should be in base`, () => {
|
it(`${language} should not contain keys that are not in base language`, () => {
|
||||||
keys.forEach((key) => {
|
keys.forEach((key) => {
|
||||||
expect(base.indexOf(key)).toBeGreaterThanOrEqual(0);
|
expect(base).toContain(key, `Translation key '${key}' in language '${language}' is not present in base language`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`${language} should contain all base keys`, () => {
|
it(`${language} should contain all base keys (excluding defined exceptions)`, () => {
|
||||||
// TODO: when all translations are fixed, use
|
let filteredBase = base.filter((key) => !COMMON_EXCEPTIONS.includes(key));
|
||||||
// expect(keys).toEqual(base);
|
let filteredKeys = keys.filter((key) => !COMMON_EXCEPTIONS.includes(key));
|
||||||
// instead of the try-catch-block
|
|
||||||
|
|
||||||
try {
|
if (LANGUAGE_EXCEPTIONS[language]) {
|
||||||
expect(keys).toEqual(base);
|
const exceptions = LANGUAGE_EXCEPTIONS[language];
|
||||||
} catch (e) {
|
filteredBase = filteredBase.filter((key) => !exceptions.includes(key));
|
||||||
if (e.message.match(/expect.*toEqual/)) {
|
filteredKeys = filteredKeys.filter((key) => !exceptions.includes(key));
|
||||||
const diff = base.filter((key) => !keys.includes(key));
|
|
||||||
missing.push(`Missing Translations for language ${language}: ${diff}`);
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filteredBase.forEach((baseKey) => {
|
||||||
|
expect(filteredKeys).toContain(baseKey, `Translation key '${baseKey}' is missing in language '${language}'`);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,49 +1,49 @@
|
|||||||
let translations = {
|
let translations = {
|
||||||
en: "translations/en.json", // English
|
en: "translations/en.json", // English
|
||||||
nl: "translations/nl.json", // Dutch
|
af: "translations/af.json", // Afrikaans
|
||||||
|
bg: "translations/bg.json", // Bulgarian
|
||||||
|
ca: "translations/ca.json", // Catalan
|
||||||
|
cs: "translations/cs.json", // Czech
|
||||||
|
cv: "translations/cv.json", // Chuvash
|
||||||
|
cy: "translations/cy.json", // Welsh (Cymraeg)
|
||||||
|
da: "translations/da.json", // Danish
|
||||||
de: "translations/de.json", // German
|
de: "translations/de.json", // German
|
||||||
|
el: "translations/el.json", // Greek
|
||||||
eo: "translations/eo.json", // Esperanto
|
eo: "translations/eo.json", // Esperanto
|
||||||
|
es: "translations/es.json", // Spanish
|
||||||
|
et: "translations/et.json", // Estonian
|
||||||
fi: "translations/fi.json", // Suomi
|
fi: "translations/fi.json", // Suomi
|
||||||
fr: "translations/fr.json", // French
|
fr: "translations/fr.json", // French
|
||||||
fy: "translations/fy.json", // Frysk
|
fy: "translations/fy.json", // Frysk
|
||||||
es: "translations/es.json", // Spanish
|
gl: "translations/gl.json", // Galego
|
||||||
ca: "translations/ca.json", // Catalan
|
gu: "translations/gu.json", // Gujarati
|
||||||
cv: "translations/cv.json", // Chuvash
|
he: "translations/he.json", // Hebrew
|
||||||
|
hi: "translations/hi.json", // Hindi
|
||||||
|
hr: "translations/hr.json", // Croatian
|
||||||
|
hu: "translations/hu.json", // Hungarian
|
||||||
|
id: "translations/id.json", // Indonesian
|
||||||
|
is: "translations/is.json", // Icelandic
|
||||||
|
it: "translations/it.json", // Italian
|
||||||
|
ja: "translations/ja.json", // Japanese
|
||||||
|
ko: "translations/ko.json", // Korean
|
||||||
|
lt: "translations/lt.json", // Lithuanian
|
||||||
|
"ms-my": "translations/ms-my.json", // Malay
|
||||||
nb: "translations/nb.json", // Norsk bokmål
|
nb: "translations/nb.json", // Norsk bokmål
|
||||||
|
nl: "translations/nl.json", // Dutch
|
||||||
nn: "translations/nn.json", // Norsk nynorsk
|
nn: "translations/nn.json", // Norsk nynorsk
|
||||||
|
pl: "translations/pl.json", // Polish
|
||||||
pt: "translations/pt.json", // Português
|
pt: "translations/pt.json", // Português
|
||||||
"pt-br": "translations/pt-br.json", // Português Brasileiro
|
"pt-br": "translations/pt-br.json", // Português Brasileiro
|
||||||
sv: "translations/sv.json", // Svenska
|
|
||||||
id: "translations/id.json", // Indonesian
|
|
||||||
it: "translations/it.json", // Italian
|
|
||||||
"zh-cn": "translations/zh-cn.json", // Simplified Chinese
|
|
||||||
"zh-tw": "translations/zh-tw.json", // Traditional Chinese
|
|
||||||
ja: "translations/ja.json", // Japanese
|
|
||||||
pl: "translations/pl.json", // Polish
|
|
||||||
el: "translations/el.json", // Greek
|
|
||||||
da: "translations/da.json", // Danish
|
|
||||||
tr: "translations/tr.json", // Turkish
|
|
||||||
ru: "translations/ru.json", // Russian
|
|
||||||
af: "translations/af.json", // Afrikaans
|
|
||||||
hu: "translations/hu.json", // Hungarian
|
|
||||||
is: "translations/is.json", // Icelandic
|
|
||||||
et: "translations/et.json", // Estonian
|
|
||||||
ko: "translations/ko.json", // Korean
|
|
||||||
ro: "translations/ro.json", // Romanian
|
ro: "translations/ro.json", // Romanian
|
||||||
cy: "translations/cy.json", // Welsh (Cymraeg)
|
ru: "translations/ru.json", // Russian
|
||||||
bg: "translations/bg.json", // Bulgarian
|
|
||||||
cs: "translations/cs.json", // Czech
|
|
||||||
hr: "translations/hr.json", // Croatian
|
|
||||||
sk: "translations/sk.json", // Slovak
|
sk: "translations/sk.json", // Slovak
|
||||||
|
sv: "translations/sv.json", // Svenska
|
||||||
|
th: "translations/th.json", // Thai
|
||||||
tlh: "translations/tlh.json", // Klingon
|
tlh: "translations/tlh.json", // Klingon
|
||||||
"ms-my": "translations/ms-my.json", // Malay
|
tr: "translations/tr.json", // Turkish
|
||||||
he: "translations/he.json", // Hebrew
|
|
||||||
uk: "translations/uk.json", // Ukrainian
|
uk: "translations/uk.json", // Ukrainian
|
||||||
hi: "translations/hi.json", // Hindi
|
"zh-cn": "translations/zh-cn.json", // Simplified Chinese
|
||||||
gu: "translations/gu.json", // Gujarati
|
"zh-tw": "translations/zh-tw.json" // Traditional Chinese
|
||||||
gl: "translations/gl.json", // Galego
|
|
||||||
lt: "translations/lt.json", // Lithuanian
|
|
||||||
th: "translations/th.json" // Thai
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof module !== "undefined") {
|
if (typeof module !== "undefined") {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user