Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import * as folderDisplayHelper from "resource://testing-common/mail/FolderDisplayHelpers.sys.mjs";
import { Assert } from "resource://testing-common/Assert.sys.mjs";
import { TestUtils } from "resource://testing-common/TestUtils.sys.mjs";
import * as EventUtils from "resource://testing-common/mail/EventUtils.sys.mjs";
var FAST_TIMEOUT = 1000;
var FAST_INTERVAL = 100;
var mc = folderDisplayHelper.mc;
/**
* Opens a content tab with the given URL.
*
* @param {string} aURL - The URL to load.
* @param {string} [aLinkHandler=null] - See specialTabs.contentTabType.openTab.
* @param {boolean} [aBackground=false] Whether the tab is opened in the background.
*
* @returns {object} The newly-opened tab.
*/
export async function open_content_tab_with_url(
aURL,
aLinkHandler = null,
aBackground = false
) {
const tabmail = mc.document.getElementById("tabmail");
const preCount = tabmail.tabContainer.allTabs.length;
tabmail.openTab("contentTab", {
url: aURL,
background: aBackground,
linkHandler: aLinkHandler,
});
await TestUtils.waitForCondition(
() => tabmail.tabContainer.allTabs.length == preCount + 1,
"Timeout waiting for the content tab to open with URL: " + aURL,
FAST_TIMEOUT,
FAST_INTERVAL
);
// We append new tabs at the end, so check the last one.
const expectedNewTab = tabmail.tabInfo[preCount];
folderDisplayHelper.assert_selected_tab(expectedNewTab);
await promise_content_tab_load(expectedNewTab, aURL);
return expectedNewTab;
}
/**
* Opens a content tab with a click on the given element. The tab is expected to
* be opened in the foreground.
*
* @param {Element} aElem - The element to click or a function that causes the tab to open.
* @param {string} aExpectedURL - The URL that is expected to be opened.
* @param {string} [aTabType] - Optional tab type to expect.
* @returns {TabInfo} The newly-opened tab.
*/
export async function open_content_tab_with_click(
aElem,
aExpectedURL,
aTabType = "contentTab"
) {
const preCount =
mc.document.getElementById("tabmail").tabContainer.allTabs.length;
if (typeof aElem != "function") {
EventUtils.synthesizeMouseAtCenter(aElem, {}, aElem.ownerGlobal);
} else {
aElem();
}
await TestUtils.waitForCondition(
() =>
mc.document.getElementById("tabmail").tabContainer.allTabs.length ==
preCount + 1,
"Timeout waiting for the content tab to open",
FAST_TIMEOUT,
FAST_INTERVAL
);
// We append new tabs at the end, so check the last one.
const expectedNewTab =
mc.document.getElementById("tabmail").tabInfo[preCount];
folderDisplayHelper.assert_selected_tab(expectedNewTab);
folderDisplayHelper.assert_tab_mode_name(expectedNewTab, aTabType);
await promise_content_tab_load(expectedNewTab, aExpectedURL);
return expectedNewTab;
}
/**
* Call this before triggering a page load that you are going to wait for using
* |promise_content_tab_load|. This ensures that if a page is already displayed
* in the given tab that state is sufficiently cleaned up so it doesn't trick us
* into thinking that there is no need to wait.
*
* @param [aTab] optional tab, defaulting to the current tab.
*/
export function plan_for_content_tab_load(aTab) {
if (aTab === undefined) {
aTab = mc.document.getElementById("tabmail").currentTabInfo;
}
aTab.pageLoaded = false;
}
/**
* Waits for the given content tab to load completely with the given URL. This
* is expected to be accompanied by a |plan_for_content_tab_load| right before
* the action triggering the page load takes place.
*
* Note that you cannot call |plan_for_content_tab_load| if you're opening a new
* tab. That is fine, because pageLoaded is initially false.
*
* @param [aTab] Optional tab, defaulting to the current tab.
* @param aURL The URL being loaded in the tab.
* @param [aTimeout] Optional time to wait for the load.
*/
export async function promise_content_tab_load(aTab, aURL, aTimeout) {
if (aTab === undefined) {
aTab = mc.document.getElementById("tabmail").currentTabInfo;
}
function isLoadedChecker() {
// Require that the progress listener think that the page is loaded.
if (!aTab.pageLoaded) {
return false;
}
// Also require that our tab infrastructure thinks that the page is loaded.
return !aTab.busy;
}
await TestUtils.waitForCondition(
isLoadedChecker,
"Timeout waiting for the content tab page to load.",
aTimeout
);
// The above may return immediately, meaning the event queue might not get a
// chance. Give it a chance now.
await TestUtils.waitForTick();
// Finally, require that the tab's browser thinks that no page is being loaded.
await wh.wait_for_browser_load(aTab.browser, aURL);
}
/**
* Gets the element with the given ID from the content tab's displayed page.
*/
export function content_tab_e(aTab, aId) {
return aTab.browser.contentDocument.getElementById(aId);
}
/**
* Returns the current "display" style property of an element.
*/
export function get_content_tab_element_display(aTab, aElem) {
const style = aTab.browser.contentWindow.getComputedStyle(aElem);
return style.getPropertyValue("display");
}
/**
* Asserts that the given element is hidden from view on the page.
*/
export function assert_content_tab_element_hidden(aTab, aElem) {
const display = get_content_tab_element_display(aTab, aElem);
Assert.equal(display, "none", "Element should be hidden");
}
/**
* Asserts that the given element is visible on the page.
*/
export function assert_content_tab_element_visible(aTab, aElem) {
const display = get_content_tab_element_display(aTab, aElem);
Assert.notEqual(display, "none", "Element should be visible");
}
/**
* Waits for the element's display property indicate it is visible.
*/
export async function promise_content_tab_element_display(aTab, aElem) {
await TestUtils.waitForCondition(
() => get_content_tab_element_display(aTab, aElem) != "none",
"waiting for element to become visible"
);
}
/**
* Finds element in document fragment, containing only the specified text
* as its textContent value.
*
* @param aRootNode Root node of the node tree where search should start.
* @param aText The string to search.
*/
export function get_element_by_text(aRootNode, aText) {
// Check every node existing.
const nodes = aRootNode.querySelectorAll("*");
for (const node of nodes) {
// We ignore surrounding whitespace.
if (node.textContent.trim() == aText) {
return node;
}
}
return null;
}
/**
* Finds element containing only the specified text in the content tab's page.
*/
function get_content_tab_element_by_text(aTab, aText) {
const doc = aTab.browser.contentDocument.documentElement;
return get_element_by_text(doc, aText);
}
/**
* Asserts that the given text is present on the content tab's page.
*/
export function assert_content_tab_text_present(aTab, aText) {
Assert.ok(
get_content_tab_element_by_text(aTab, aText),
`String "${aText}" should be on the content tab's page`
);
}
/**
* Asserts that the given text is absent on the content tab's page.
*/
export function assert_content_tab_text_absent(aTab, aText) {
Assert.ok(
!get_content_tab_element_by_text(aTab, aText),
`String "${aText}" should not be on the content tab's page`
);
}
/**
* Returns the notification bar for a tab if one is currently visible,
* null if otherwise.
*/
export function get_notification_bar_for_tab() {
const notificationBoxEls = mc.document
.getElementById("tabmail")
.selectedTab.panel.querySelector("notificationbox");
if (!notificationBoxEls) {
return null;
}
return notificationBoxEls;
}