Commit 8b361951 authored by Erik Nordin's avatar Erik Nordin Committed by enordin@mozilla.com
Browse files

Bug 1820252 - Add FindBar tests r=translations-reviewers,gregtatum

This patch adds new Full-Page Translations tests that ensure
showing and hiding the FindBar correctly transitions the
TranslationsDocument between lazy and content-eager mode,
only on a per-tab basis.

Differential Revision: https://phabricator.services.mozilla.com/D250000
parent 32c80de2
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -32,6 +32,12 @@ support-files = [

["browser_translations_full_page_intersection_content_eager.js"]

["browser_translations_full_page_intersection_find_bar.js"]

["browser_translations_full_page_intersection_find_bar_move_tab_to_new_window.js"]

["browser_translations_full_page_intersection_find_bar_multi_tab.js"]

["browser_translations_full_page_intersection_lazy.js"]

["browser_translations_full_page_intersection_mutations_content_eager.js"]
+256 −0
Original line number Diff line number Diff line
/* Any copyright is dedicated to the Public Domain.
   https://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

/**
 * This test case ensures that opening the FindBar on a page where Full-Page Translations
 * is already active will enter into content-eager translations mode, allowing all content
 * translations on the page to be fulfilled while attribute translations remain lazy based
 * on proximity with the viewport.
 */
add_task(
  async function test_findbar_open_switches_to_content_eager_mode_from_lazy_mode() {
    const { cleanup, resolveDownloads, runInPage, tab } = await loadTestPage({
      page: SPANISH_PAGE_URL,
      languagePairs: LANGUAGE_PAIRS,
    });

    await FullPageTranslationsTestUtils.assertTranslationsButton(
      { button: true },
      "The translations button is visible."
    );

    await FullPageTranslationsTestUtils.assertPageIsNotTranslated(runInPage);

    await FullPageTranslationsTestUtils.openPanel({
      expectedFromLanguage: "es",
      expectedToLanguage: "en",
      onOpenPanel: FullPageTranslationsTestUtils.assertPanelViewIntro,
    });

    await FullPageTranslationsTestUtils.clickTranslateButton({
      downloadHandler: resolveDownloads,
    });

    await FullPageTranslationsTestUtils.assertOnlyIntersectingNodesAreTranslated(
      {
        fromLanguage: "es",
        toLanguage: "en",
        runInPage,
      }
    );

    info(
      "Opening the find bar, which should switch us into content eager mode."
    );
    await openFindBar(tab);

    await FullPageTranslationsTestUtils.assertAllPageContentIsTranslated({
      fromLanguage: "es",
      toLanguage: "en",
      runInPage,
    });

    await FullPageTranslationsTestUtils.assertPageFinalParagraphTitleIsNotTranslated(
      {
        runInPage,
        message:
          "Attribute translations are always lazy based on intersection, so the final paragraph's title should remain untranslated.",
      }
    );

    await scrollToBottomOfPage(runInPage);

    await FullPageTranslationsTestUtils.assertPageFinalParagraphTitleIsTranslated(
      {
        fromLanguage: "es",
        toLanguage: "en",
        runInPage,
      }
    );

    info("Mutating the H1 text content and title attribute.");
    await runInPage(async TranslationsTest => {
      const { getH1 } = TranslationsTest.getSelectors();
      const h1 = getH1();

      h1.innerText = "Este contenido de texto de h1 se modificó.";
      h1.setAttribute("title", "Este atributo de título de h1 se modificó.");
      h1.setAttribute(
        "aria-label",
        "Este atributo de etiqueta aria de h1 se añadió."
      );
    });

    info(
      "Ensuring mutated H1 content is translated, but the mutated attributes are not."
    );
    await runInPage(async TranslationsTest => {
      const { getH1, getH1Title, getH1AriaLabel } =
        TranslationsTest.getSelectors();

      await TranslationsTest.assertTranslationResult(
        "The re-mutated h1 text content is translated.",
        getH1,
        "ESTE CONTENIDO DE TEXTO DE H1 SE MODIFICÓ. [es to en]"
      );

      await TranslationsTest.assertTranslationResult(
        "The re-mutated h1 title attribute is not translated.",
        getH1Title,
        "Este atributo de título de h1 se modificó."
      );

      await TranslationsTest.assertTranslationResult(
        "The h1 aria-label attribute remains untranslated.",
        getH1AriaLabel,
        "Este atributo de etiqueta aria de h1 se añadió."
      );
    });

    info(
      "Scrolling back to the top of the page so the mutated H1 intersects the viewport."
    );
    await scrollToTopOfPage(runInPage);

    await FullPageTranslationsTestUtils.waitForAllPendingTranslationsToComplete(
      runInPage
    );

    info("Asserting the H1 is now fully translated (text and attributes).");
    await runInPage(async TranslationsTest => {
      const { getH1, getH1Title, getH1AriaLabel } =
        TranslationsTest.getSelectors();

      await TranslationsTest.assertTranslationResult(
        "The h1 text content remains translated.",
        getH1,
        "ESTE CONTENIDO DE TEXTO DE H1 SE MODIFICÓ. [es to en]"
      );

      await TranslationsTest.assertTranslationResult(
        "The h1 title attribute is now translated after intersecting.",
        getH1Title,
        "ESTE ATRIBUTO DE TÍTULO DE H1 SE MODIFICÓ. [es to en]"
      );

      await TranslationsTest.assertTranslationResult(
        "The h1 aria-label attribute is now translated after intersecting.",
        getH1AriaLabel,
        "ESTE ATRIBUTO DE ETIQUETA ARIA DE H1 SE AÑADIÓ. [es to en]"
      );
    });

    await cleanup();
  }
);

/**
 * This test case ensures that closing the FindBar on a page where Full-Page Translations
 * is already active will enter into lazy translations mode, ensuring that translations
 * for both content and attributes are not fulfilled until the elements that they belong
 * to enter proximity with the viewport.
 */
add_task(
  async function test_findbar_close_switches_to_lazy_mode_from_content_eager_mode() {
    const { cleanup, resolveDownloads, runInPage, tab } = await loadTestPage({
      page: SPANISH_PAGE_URL,
      languagePairs: LANGUAGE_PAIRS,
      contentEagerMode: true,
    });

    await FullPageTranslationsTestUtils.assertTranslationsButton(
      { button: true },
      "The translations button is visible."
    );

    await FullPageTranslationsTestUtils.assertPageIsNotTranslated(runInPage);

    await FullPageTranslationsTestUtils.openPanel({
      expectedFromLanguage: "es",
      expectedToLanguage: "en",
      onOpenPanel: FullPageTranslationsTestUtils.assertPanelViewIntro,
    });

    await FullPageTranslationsTestUtils.clickTranslateButton({
      downloadHandler: resolveDownloads,
    });

    await FullPageTranslationsTestUtils.assertAllPageContentIsTranslated({
      fromLanguage: "es",
      toLanguage: "en",
      runInPage,
    });

    info(
      "Closing the find bar, which should switch the page from content eager mode back to lazy mode."
    );
    await closeFindBar(tab);

    info("Mutating the final paragraph text content and title attribute.");
    await runInPage(async TranslationsTest => {
      const { getFinalParagraph } = TranslationsTest.getSelectors();
      const p = getFinalParagraph();

      p.innerText = "Este contenido de texto de último párrafo se modificó.";
      p.setAttribute(
        "title",
        "Este atributo de título de último párrafo se modificó."
      );
    });

    await FullPageTranslationsTestUtils.waitForAllPendingTranslationsToComplete(
      runInPage
    );

    info(
      "Ensuring mutated final paragraph content and attributes are not translated while out of view in lazy mode."
    );
    await runInPage(async TranslationsTest => {
      const { getFinalParagraph, getFinalParagraphTitle } =
        TranslationsTest.getSelectors();

      await TranslationsTest.assertTranslationResult(
        "The mutated final paragraph text content is not translated.",
        getFinalParagraph,
        "Este contenido de texto de último párrafo se modificó."
      );

      await TranslationsTest.assertTranslationResult(
        "The mutated final paragraph title attribute is not translated.",
        getFinalParagraphTitle,
        "Este atributo de título de último párrafo se modificó."
      );
    });

    info("Scrolling to the bottom of the page so the paragraph intersects.");
    await scrollToBottomOfPage(runInPage);

    await FullPageTranslationsTestUtils.waitForAllPendingTranslationsToComplete(
      runInPage
    );

    info(
      "Asserting the mutated final paragraph content and title are now translated after intersecting."
    );
    await runInPage(async TranslationsTest => {
      const { getFinalParagraph, getFinalParagraphTitle } =
        TranslationsTest.getSelectors();

      await TranslationsTest.assertTranslationResult(
        "The mutated final paragraph text content is translated.",
        getFinalParagraph,
        "ESTE CONTENIDO DE TEXTO DE ÚLTIMO PÁRRAFO SE MODIFICÓ. [es to en]"
      );

      await TranslationsTest.assertTranslationResult(
        "The mutated final paragraph title attribute is translated.",
        getFinalParagraphTitle,
        "ESTE ATRIBUTO DE TÍTULO DE ÚLTIMO PÁRRAFO SE MODIFICÓ. [es to en]"
      );
    });

    await cleanup();
  }
);
+259 −0
Original line number Diff line number Diff line
/* Any copyright is dedicated to the Public Domain.
   https://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

/**
 * This test case ensures that opening the FindBar on a page where Full-Page Translations is active
 * transitions into content-eager translations mode, even after moving the tab to a new window, which
 * necessarily changes to a different FindBar instance.
 */
add_task(
  async function test_findbar_open_switches_to_content_eager_mode_after_moving_tab_to_new_window() {
    const window1 = window;
    const { cleanup, resolveDownloads, runInPage, tab } = await loadTestPage({
      page: SPANISH_PAGE_URL,
      languagePairs: LANGUAGE_PAIRS,
    });

    await FullPageTranslationsTestUtils.assertTranslationsButton(
      { button: true },
      "The translations button is visible.",
      window1
    );

    await FullPageTranslationsTestUtils.assertPageIsNotTranslated(runInPage);

    await FullPageTranslationsTestUtils.openPanel({
      expectedFromLanguage: "es",
      expectedToLanguage: "en",
      onOpenPanel: FullPageTranslationsTestUtils.assertPanelViewIntro,
      win: window1,
    });

    await FullPageTranslationsTestUtils.clickTranslateButton({
      downloadHandler: resolveDownloads,
      win: window1,
    });

    await FullPageTranslationsTestUtils.assertOnlyIntersectingNodesAreTranslated(
      {
        fromLanguage: "es",
        toLanguage: "en",
        runInPage,
      }
    );

    info("Moving the tab to a new window of its own.");
    const window2 = await window1.gBrowser.replaceTabWithWindow(tab);
    const swapDocShellPromise = BrowserTestUtils.waitForEvent(
      tab.linkedBrowser,
      "SwapDocShells"
    );
    await swapDocShellPromise;

    const tab2 = window2.gBrowser.selectedTab;
    function runInPage2(callback, data = {}) {
      return ContentTask.spawn(
        tab2.linkedBrowser,
        { contentData: data, callbackSource: callback.toString() },
        function ({ contentData, callbackSource }) {
          const TranslationsTest = ChromeUtils.importESModule(
            "chrome://mochitests/content/browser/toolkit/components/translations/tests/browser/translations-test.mjs"
          );
          TranslationsTest.setup({ Assert, ContentTaskUtils, content });
          // eslint-disable-next-line no-eval
          let contentCallback = eval(`(${callbackSource})`);
          return contentCallback(TranslationsTest, contentData);
        }
      );
    }

    await FullPageTranslationsTestUtils.assertTranslationsButton(
      { button: true },
      "The translations button is visible.",
      window2
    );

    info(
      "Opening the find bar in the new window, which should switch us into content eager mode."
    );
    await openFindBar(tab2, window2);

    await FullPageTranslationsTestUtils.assertAllPageContentIsTranslated({
      win: window2,
      fromLanguage: "es",
      toLanguage: "en",
      runInPage: runInPage2,
    });

    await FullPageTranslationsTestUtils.assertPageFinalParagraphTitleIsNotTranslated(
      {
        win: window2,
        runInPage: runInPage2,
        message:
          "Attribute translations are always lazy based on intersection, so the final paragraph's title should remain untranslated.",
      }
    );

    await scrollToBottomOfPage(runInPage2);

    await FullPageTranslationsTestUtils.assertPageFinalParagraphTitleIsTranslated(
      {
        win: window2,
        fromLanguage: "es",
        toLanguage: "en",
        runInPage: runInPage2,
      }
    );

    await cleanup();
    await BrowserTestUtils.closeWindow(window2);
  }
);

/**
 * This test case ensures that closing the FindBar on a page where Full-Page Translations is active
 * transitions into lazy translations mode, even after moving the tab to a new window, which
 * necessarily changes to a different FindBar instance.
 */
add_task(
  async function test_findbar_close_switches_to_lazy_mode_after_moving_tab_to_new_window() {
    const window1 = window;
    const { cleanup, resolveDownloads, runInPage, tab } = await loadTestPage({
      page: SPANISH_PAGE_URL,
      languagePairs: LANGUAGE_PAIRS,
      contentEagerMode: true,
    });

    await FullPageTranslationsTestUtils.assertTranslationsButton(
      { button: true },
      "The translations button is visible.",
      window1
    );

    await FullPageTranslationsTestUtils.assertPageIsNotTranslated(runInPage);

    await FullPageTranslationsTestUtils.openPanel({
      expectedFromLanguage: "es",
      expectedToLanguage: "en",
      onOpenPanel: FullPageTranslationsTestUtils.assertPanelViewIntro,
      win: window1,
    });

    await FullPageTranslationsTestUtils.clickTranslateButton({
      downloadHandler: resolveDownloads,
      win: window1,
    });

    await FullPageTranslationsTestUtils.assertAllPageContentIsTranslated({
      fromLanguage: "es",
      toLanguage: "en",
      runInPage,
    });

    info("Moving the tab to a new window of its own.");
    const window2 = await window1.gBrowser.replaceTabWithWindow(tab);
    const swapDocShellPromise = BrowserTestUtils.waitForEvent(
      tab.linkedBrowser,
      "SwapDocShells"
    );
    await swapDocShellPromise;

    const tab2 = window2.gBrowser.selectedTab;
    function runInPage2(callback, data = {}) {
      return ContentTask.spawn(
        tab2.linkedBrowser,
        { contentData: data, callbackSource: callback.toString() },
        function ({ contentData, callbackSource }) {
          const TranslationsTest = ChromeUtils.importESModule(
            "chrome://mochitests/content/browser/toolkit/components/translations/tests/browser/translations-test.mjs"
          );
          TranslationsTest.setup({ Assert, ContentTaskUtils, content });
          // eslint-disable-next-line no-eval
          let contentCallback = eval(`(${callbackSource})`);
          return contentCallback(TranslationsTest, contentData);
        }
      );
    }

    await FullPageTranslationsTestUtils.assertTranslationsButton(
      { button: true },
      "The translations button is visible.",
      window2
    );

    info(
      "Closing the find bar in the new window, which should switch the page back to lazy mode."
    );
    await closeFindBar(tab2, window2);

    info("Mutating the final paragraph text content and title attribute.");
    await runInPage2(async TranslationsTest => {
      const { getFinalParagraph } = TranslationsTest.getSelectors();
      const p = getFinalParagraph();

      p.innerText = "Este contenido de texto de último párrafo se modificó.";
      p.setAttribute(
        "title",
        "Este atributo de título de último párrafo se modificó."
      );
    });

    await FullPageTranslationsTestUtils.waitForAllPendingTranslationsToComplete(
      runInPage2
    );

    info(
      "Ensuring mutated final paragraph content and attributes are not translated while out of view in lazy mode."
    );
    await runInPage2(async TranslationsTest => {
      const { getFinalParagraph, getFinalParagraphTitle } =
        TranslationsTest.getSelectors();

      await TranslationsTest.assertTranslationResult(
        "The mutated final paragraph text content is not translated.",
        getFinalParagraph,
        "Este contenido de texto de último párrafo se modificó."
      );

      await TranslationsTest.assertTranslationResult(
        "The mutated final paragraph title attribute is not translated.",
        getFinalParagraphTitle,
        "Este atributo de título de último párrafo se modificó."
      );
    });

    info("Scrolling to the bottom of the page so the paragraph intersects.");
    await scrollToBottomOfPage(runInPage2);

    await resolveDownloads(1);

    await FullPageTranslationsTestUtils.waitForAllPendingTranslationsToComplete(
      runInPage2
    );

    info(
      "Asserting the mutated final paragraph content and title are now translated after intersecting."
    );
    await runInPage2(async TranslationsTest => {
      const { getFinalParagraph, getFinalParagraphTitle } =
        TranslationsTest.getSelectors();

      await TranslationsTest.assertTranslationResult(
        "The mutated final paragraph text content is translated.",
        getFinalParagraph,
        "ESTE CONTENIDO DE TEXTO DE ÚLTIMO PÁRRAFO SE MODIFICÓ. [es to en]"
      );

      await TranslationsTest.assertTranslationResult(
        "The mutated final paragraph title attribute is translated.",
        getFinalParagraphTitle,
        "ESTE ATRIBUTO DE TÍTULO DE ÚLTIMO PÁRRAFO SE MODIFICÓ. [es to en]"
      );
    });

    await cleanup();
    await BrowserTestUtils.closeWindow(window2);
  }
);
+256 −0

File added.

Preview size limit exceeded, changes collapsed.

+25 −2
Original line number Diff line number Diff line
@@ -1621,9 +1621,12 @@ async function captureTranslationsError(callback) {
  return errors;
}

async function openFindBar(tab) {
/**
 * Opens the FindBar in the given tab for the current window.
 */
async function openFindBar(tab, win = window) {
  info("Opening the find bar in the current tab.");
  const findBar = await gBrowser.getFindBar(tab);
  const findBar = await win.gBrowser.getFindBar(tab);
  const { promise, resolve } = Promise.withResolvers();

  findBar.addEventListener(
@@ -1638,6 +1641,26 @@ async function openFindBar(tab) {
  await promise;
}

/**
 * Opens the FindBar in the given tab for the current window.
 */
async function closeFindBar(tab, win = window) {
  info("Closing the find bar in the current tab.");
  const findBar = await win.gBrowser.getFindBar(tab);
  const { promise, resolve } = Promise.withResolvers();

  findBar.addEventListener(
    "findbarclose",
    () => {
      resolve();
    },
    { once: true }
  );

  findBar.close();
  await promise;
}

/**
 * Load a test page and run
 *