Skip to content

Commit af086de

Browse files
committed
Bug 1826437 - Add translations panel tests; r=nordzilla
Differential Revision: https://phabricator.services.mozilla.com/D174683
1 parent 2d5cb34 commit af086de

File tree

5 files changed

+351
-0
lines changed

5 files changed

+351
-0
lines changed

browser/components/moz.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ DIRS += [
6060
"tabunloader",
6161
"textrecognition",
6262
"translation",
63+
"translations",
6364
"uitour",
6465
"urlbar",
6566
]

browser/components/translations/moz.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@
55
with Files("**"):
66
BUG_COMPONENT = ("Firefox", "Translation")
77

8+
BROWSER_CHROME_MANIFESTS += ["tests/browser/browser.ini"]
9+
810
JAR_MANIFESTS += ["jar.mn"]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[DEFAULT]
2+
support-files =
3+
head.js
4+
!/toolkit/components/translations/tests/browser/shared-head.js
5+
!/toolkit/components/translations/tests/browser/translations-test.mjs
6+
[browser_translations_panel.js]
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
/* Any copyright is dedicated to the Public Domain.
2+
http://creativecommons.org/publicdomain/zero/1.0/ */
3+
4+
"use strict";
5+
6+
const languagePairs = [
7+
{ fromLang: "es", toLang: "en" },
8+
{ fromLang: "en", toLang: "es" },
9+
{ fromLang: "fr", toLang: "en" },
10+
{ fromLang: "en", toLang: "fr" },
11+
];
12+
13+
const spanishPageUrl = TRANSLATIONS_TESTER_ES;
14+
const englishPageUrl = TRANSLATIONS_TESTER_EN;
15+
16+
/**
17+
* Test that the translations button is correctly visible when navigating between pages.
18+
*/
19+
add_task(async function test_button_visible_navigation() {
20+
info("Start at a page in Spanish.");
21+
const { cleanup } = await loadTestPage({
22+
page: spanishPageUrl,
23+
languagePairs,
24+
});
25+
26+
await assertTranslationsButton(
27+
button => !button.hidden,
28+
"The button should be visible since the page can be translated from Spanish."
29+
);
30+
31+
navigate(englishPageUrl, "Navigate to an English page.");
32+
33+
await assertTranslationsButton(
34+
button => button.hidden,
35+
"The button should be invisible since the page is in English."
36+
);
37+
38+
navigate(spanishPageUrl, "Navigate back to a Spanish page.");
39+
40+
await assertTranslationsButton(
41+
button => !button.hidden,
42+
"The button should be visible again since the page is in Spanish."
43+
);
44+
45+
await cleanup();
46+
});
47+
48+
/**
49+
* Test that the translations button is correctly visible when opening and switch tabs.
50+
*/
51+
add_task(async function test_button_visible() {
52+
info("Start at a page in Spanish.");
53+
54+
const { cleanup, tab: spanishTab } = await loadTestPage({
55+
page: spanishPageUrl,
56+
languagePairs,
57+
});
58+
59+
await assertTranslationsButton(
60+
button => !button.hidden,
61+
"The button should be visible since the page can be translated from Spanish."
62+
);
63+
64+
const { removeTab, tab: englishTab } = await addTab(
65+
englishPageUrl,
66+
"Creating a new tab for a page in English."
67+
);
68+
69+
await assertTranslationsButton(
70+
button => button.hidden,
71+
"The button should be invisible since the tab is in English."
72+
);
73+
74+
await switchTab(spanishTab);
75+
76+
await assertTranslationsButton(
77+
button => !button.hidden,
78+
"The button should be visible again since the page is in Spanish."
79+
);
80+
81+
await switchTab(englishTab);
82+
83+
await assertTranslationsButton(
84+
button => button.hidden,
85+
"Don't show for english pages"
86+
);
87+
88+
await removeTab();
89+
await cleanup();
90+
});
91+
92+
/**
93+
* Tests a basic panel open, and translation.
94+
*/
95+
add_task(async function test_translations_panel() {
96+
const { cleanup, runInPage } = await loadTestPage({
97+
page: spanishPageUrl,
98+
languagePairs,
99+
});
100+
101+
const button = await assertTranslationsButton(
102+
b => !b.hidden,
103+
"The button is available."
104+
);
105+
106+
await runInPage(async TranslationsTest => {
107+
const { getH1 } = TranslationsTest.getSelectors();
108+
await TranslationsTest.assertTranslationResult(
109+
"The page's H1 is in Spanish.",
110+
getH1,
111+
"Don Quijote de La Mancha"
112+
);
113+
});
114+
115+
{
116+
const popupshown = waitForTranslationsPopupEvent("popupshown");
117+
click(button, "Opening the popup");
118+
await popupshown;
119+
}
120+
121+
{
122+
const translateButton = getByL10nId(
123+
"translations-panel-dual-translate-button"
124+
);
125+
126+
const popuphidden = waitForTranslationsPopupEvent("popuphidden");
127+
click(
128+
translateButton,
129+
"Start translating by clicking the translate button."
130+
);
131+
await popuphidden;
132+
}
133+
134+
await runInPage(async TranslationsTest => {
135+
const { getH1 } = TranslationsTest.getSelectors();
136+
await TranslationsTest.assertTranslationResult(
137+
"The pages H1 is translated.",
138+
getH1,
139+
"DON QUIJOTE DE LA MANCHA [es to en, html]"
140+
);
141+
});
142+
143+
{
144+
const popupshown = waitForTranslationsPopupEvent("popupshown");
145+
click(button, "Re-opening the popup");
146+
await popupshown;
147+
}
148+
149+
{
150+
const restoreButton = getByL10nId("translations-panel-restore-button");
151+
const popuphidden = waitForTranslationsPopupEvent("popuphidden");
152+
click(restoreButton, "Start translating by clicking the translate button.");
153+
await popuphidden;
154+
}
155+
156+
await runInPage(async TranslationsTest => {
157+
const { getH1 } = TranslationsTest.getSelectors();
158+
await TranslationsTest.assertTranslationResult(
159+
"The page's H1 is restored to Spanish.",
160+
getH1,
161+
"Don Quijote de La Mancha"
162+
);
163+
});
164+
165+
await cleanup();
166+
});
167+
168+
/**
169+
* Tests a basic panel open, and translation.
170+
*/
171+
add_task(async function test_translations_panel_switch_language() {
172+
const { cleanup, runInPage } = await loadTestPage({
173+
page: spanishPageUrl,
174+
languagePairs,
175+
});
176+
177+
const button = await assertTranslationsButton(
178+
b => !b.hidden,
179+
"The button is available."
180+
);
181+
182+
await runInPage(async TranslationsTest => {
183+
const { getH1 } = TranslationsTest.getSelectors();
184+
await TranslationsTest.assertTranslationResult(
185+
"The page's H1 is in Spanish.",
186+
getH1,
187+
"Don Quijote de La Mancha"
188+
);
189+
});
190+
191+
{
192+
const popupshown = waitForTranslationsPopupEvent("popupshown");
193+
click(button, "Opening the popup");
194+
await popupshown;
195+
}
196+
197+
const fromSelect = document.getElementById("translations-panel-from");
198+
fromSelect.value = "en";
199+
fromSelect.dispatchEvent(new Event("input"));
200+
201+
const toSelect = document.getElementById("translations-panel-to");
202+
toSelect.value = "fr";
203+
toSelect.dispatchEvent(new Event("input"));
204+
205+
{
206+
const translateButton = getByL10nId(
207+
"translations-panel-dual-translate-button"
208+
);
209+
210+
const popuphidden = waitForTranslationsPopupEvent("popuphidden");
211+
click(
212+
translateButton,
213+
"Start translating by clicking the translate button."
214+
);
215+
await popuphidden;
216+
}
217+
218+
await runInPage(async TranslationsTest => {
219+
const { getH1 } = TranslationsTest.getSelectors();
220+
await TranslationsTest.assertTranslationResult(
221+
"The pages H1 is translated using the changed languages.",
222+
getH1,
223+
"DON QUIJOTE DE LA MANCHA [en to fr, html]"
224+
);
225+
});
226+
227+
await cleanup();
228+
});
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/* Any copyright is dedicated to the Public Domain.
2+
http://creativecommons.org/publicdomain/zero/1.0/ */
3+
4+
"use strict";
5+
6+
Services.scriptloader.loadSubScript(
7+
"chrome://mochitests/content/browser/toolkit/components/translations/tests/browser/shared-head.js",
8+
this
9+
);
10+
11+
/**
12+
* Assert some property about the translations button.
13+
*
14+
* @param {Function} assertion
15+
* @param {string} message The messag for the assertion.
16+
* @returns {HTMLElement}
17+
*/
18+
function assertTranslationsButton(assertion, message) {
19+
return TestUtils.waitForCondition(() => {
20+
const button = document.getElementById("translations-button");
21+
if (!button) {
22+
return false;
23+
}
24+
if (assertion(button)) {
25+
ok(button, message);
26+
return button;
27+
}
28+
return false;
29+
}, message);
30+
}
31+
32+
/**
33+
* Navigate to a URL and indicate a message as to why.
34+
*/
35+
function navigate(url, message) {
36+
info(message);
37+
BrowserTestUtils.loadURIString(gBrowser.selectedBrowser, url);
38+
}
39+
40+
/**
41+
* Add a tab to the page
42+
*
43+
* @param {string} url
44+
*/
45+
async function addTab(url) {
46+
info(`Adding tab for ` + url);
47+
const tab = await BrowserTestUtils.openNewForegroundTab(
48+
gBrowser,
49+
url,
50+
true // Wait for laod
51+
);
52+
return {
53+
tab,
54+
removeTab() {
55+
BrowserTestUtils.removeTab(tab);
56+
},
57+
};
58+
}
59+
60+
async function switchTab(tab) {
61+
info("Switching tabs");
62+
await BrowserTestUtils.switchTab(gBrowser, tab);
63+
}
64+
65+
function click(button, message) {
66+
info(message);
67+
EventUtils.synthesizeMouseAtCenter(button, {});
68+
}
69+
70+
/**
71+
* Get an element by its l10n id, as this is a user-visible way to find an element.
72+
* The `l10nId` represents the text that a user would actually see.
73+
*
74+
* @param {string} l10nId
75+
*/
76+
function getByL10nId(l10nId) {
77+
const element = document.querySelector(`[data-l10n-id="${l10nId}"]`);
78+
if (!element) {
79+
throw new Error("Could not find the element by l10n id: " + l10nId);
80+
}
81+
const { visibility, display } = window.getComputedStyle(element);
82+
if (visibility !== "visible" || display === "none") {
83+
throw new Error("The element is not visible in the DOM: " + l10nId);
84+
}
85+
return element;
86+
}
87+
88+
/**
89+
* XUL popups will fire the popupshown and popuphidden events. These will fire for
90+
* any type of popup in the browser. This function waits for one of those events, and
91+
* checks that the viewId of the popup is PanelUI-profiler
92+
*
93+
* @param {"popupshown" | "popuphidden"} eventName
94+
* @returns {Promise<void>}
95+
*/
96+
function waitForTranslationsPopupEvent(eventName) {
97+
return new Promise(resolve => {
98+
const panel = document.getElementById("translations-panel");
99+
if (!panel) {
100+
throw new Error("Unable to find the translations panel element.");
101+
}
102+
103+
function handleEvent(event) {
104+
if (event.type === eventName) {
105+
panel.removeEventListener(eventName, handleEvent);
106+
// Resolve after a setTimeout so that any other event handlers will finish
107+
// first. Only then will the test resume.
108+
setTimeout(resolve, 0);
109+
}
110+
}
111+
112+
panel.addEventListener(eventName, handleEvent);
113+
});
114+
}

0 commit comments

Comments
 (0)