summaryrefslogtreecommitdiffstats
path: root/browser/components/extensions/test/browser/browser_ext_find.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/extensions/test/browser/browser_ext_find.js')
-rw-r--r--browser/components/extensions/test/browser/browser_ext_find.js465
1 files changed, 465 insertions, 0 deletions
diff --git a/browser/components/extensions/test/browser/browser_ext_find.js b/browser/components/extensions/test/browser/browser_ext_find.js
new file mode 100644
index 0000000000..cf9db29b4c
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_find.js
@@ -0,0 +1,465 @@
+/* global browser */
+"use strict";
+
+function frameScript() {
+ let docShell = content.docShell;
+ let controller = docShell
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsISelectionDisplay)
+ .QueryInterface(Ci.nsISelectionController);
+ let selection = controller.getSelection(controller.SELECTION_FIND);
+ if (!selection.rangeCount) {
+ return {
+ text: "",
+ };
+ }
+
+ let range = selection.getRangeAt(0);
+ const { FindContent } = ChromeUtils.importESModule(
+ "resource://gre/modules/FindContent.sys.mjs"
+ );
+ let highlighter = new FindContent(docShell).highlighter;
+ let r1 = content.parent.frameElement.getBoundingClientRect();
+ let f1 = highlighter._getFrameElementOffsets(content.parent);
+ let r2 = content.frameElement.getBoundingClientRect();
+ let f2 = highlighter._getFrameElementOffsets(content);
+ let r3 = range.getBoundingClientRect();
+ let rect = {
+ top: r1.top + r2.top + r3.top + f1.y + f2.y,
+ left: r1.left + r2.left + r3.left + f1.x + f2.x,
+ };
+ return {
+ text: selection.toString(),
+ rect,
+ };
+}
+
+add_task(async function testFind() {
+ async function background() {
+ function awaitLoad(tabId, url) {
+ return new Promise(resolve => {
+ browser.tabs.onUpdated.addListener(function listener(
+ tabId_,
+ changed,
+ tab
+ ) {
+ if (
+ tabId == tabId_ &&
+ changed.status == "complete" &&
+ tab.url == url
+ ) {
+ browser.tabs.onUpdated.removeListener(listener);
+ resolve();
+ }
+ });
+ });
+ }
+
+ let url =
+ "http://example.com/browser/browser/components/extensions/test/browser/file_find_frames.html";
+ let tab = await browser.tabs.update({ url });
+ await awaitLoad(tab.id, url);
+
+ let data = await browser.find.find("banana", { includeRangeData: true });
+ let rangeData = data.rangeData;
+
+ browser.test.log("Test that `data.count` is the expected value.");
+ browser.test.assertEq(
+ 6,
+ data.count,
+ "The value returned from `data.count`"
+ );
+
+ browser.test.log("Test that `rangeData` has the proper number of values.");
+ browser.test.assertEq(
+ 6,
+ rangeData.length,
+ "The number of values held in `rangeData`"
+ );
+
+ browser.test.log(
+ "Test that the text found in the top window and nested frames corresponds to the proper position."
+ );
+ let terms = ["Bánana", "bAnana", "baNana", "banAna", "banaNa", "bananA"];
+ for (let i = 0; i < terms.length; i++) {
+ browser.test.assertEq(
+ terms[i],
+ rangeData[i].text,
+ `The text at range position ${i}:`
+ );
+ }
+
+ browser.test.log("Test that case sensitive match works properly.");
+ data = await browser.find.find("baNana", {
+ caseSensitive: true,
+ includeRangeData: true,
+ });
+ browser.test.assertEq(1, data.count, "The number of matches found:");
+ browser.test.assertEq("baNana", data.rangeData[0].text, "The text found:");
+
+ browser.test.log("Test that diacritic sensitive match works properly.");
+ data = await browser.find.find("bánana", {
+ matchDiacritics: true,
+ includeRangeData: true,
+ });
+ browser.test.assertEq(1, data.count, "The number of matches found:");
+ browser.test.assertEq("Bánana", data.rangeData[0].text, "The text found:");
+
+ browser.test.log("Test that case insensitive match works properly.");
+ data = await browser.find.find("banana", { caseSensitive: false });
+ browser.test.assertEq(6, data.count, "The number of matches found:");
+
+ browser.test.log("Test that entire word match works properly.");
+ data = await browser.find.find("banana", { entireWord: true });
+ browser.test.assertEq(
+ 4,
+ data.count,
+ 'The number of matches found, should skip 2 matches, "banaNaland" and "bananAland":'
+ );
+
+ let expectedRangeData = [
+ {
+ framePos: 0,
+ text: "example",
+ startTextNodePos: 16,
+ startOffset: 11,
+ endTextNodePos: 16,
+ endOffset: 18,
+ },
+ {
+ framePos: 0,
+ text: "example",
+ startTextNodePos: 16,
+ startOffset: 25,
+ endTextNodePos: 16,
+ endOffset: 32,
+ },
+ {
+ framePos: 0,
+ text: "example",
+ startTextNodePos: 19,
+ startOffset: 6,
+ endTextNodePos: 19,
+ endOffset: 13,
+ },
+ {
+ framePos: 0,
+ text: "example",
+ startTextNodePos: 21,
+ startOffset: 3,
+ endTextNodePos: 21,
+ endOffset: 10,
+ },
+ {
+ framePos: 1,
+ text: "example",
+ startTextNodePos: 0,
+ startOffset: 0,
+ endTextNodePos: 0,
+ endOffset: 7,
+ },
+ {
+ framePos: 2,
+ text: "example",
+ startTextNodePos: 0,
+ startOffset: 0,
+ endTextNodePos: 0,
+ endOffset: 7,
+ },
+ ];
+
+ browser.test.log(
+ "Test that word found in the same node, different nodes and different frames returns the correct rangeData results."
+ );
+ data = await browser.find.find("example", { includeRangeData: true });
+ for (let i = 0; i < data.rangeData.length; i++) {
+ for (let name in data.rangeData[i]) {
+ browser.test.assertEq(
+ expectedRangeData[i][name],
+ data.rangeData[i][name],
+ `rangeData[${i}].${name}:`
+ );
+ }
+ }
+
+ browser.test.log(
+ "Test that `rangeData` is not returned if `includeRangeData` is false."
+ );
+ data = await browser.find.find("banana", {
+ caseSensitive: false,
+ includeRangeData: false,
+ });
+ browser.test.assertEq(
+ false,
+ !!data.rangeData,
+ "The boolean cast value of `rangeData`:"
+ );
+
+ browser.test.log(
+ "Test that `rectData` is not returned if `includeRectData` is false."
+ );
+ data = await browser.find.find("banana", {
+ caseSensitive: false,
+ includeRectData: false,
+ });
+ browser.test.assertEq(
+ false,
+ !!data.rectData,
+ "The boolean cast value of `rectData`:"
+ );
+
+ browser.test.log(
+ "Test that text spanning multiple inline elements is found."
+ );
+ data = await browser.find.find("fruitcake");
+ browser.test.assertEq(1, data.count, "The number of matches found:");
+
+ browser.test.log(
+ "Test that text spanning multiple block elements is not found."
+ );
+ data = await browser.find.find("angelfood");
+ browser.test.assertEq(0, data.count, "The number of matches found:");
+
+ browser.test.log(
+ "Test that `highlightResults` returns proper status code."
+ );
+ await browser.find.find("banana");
+
+ await browser.test.assertRejects(
+ browser.find.highlightResults({ rangeIndex: 6 }),
+ /index supplied was out of range/,
+ "rejected Promise should pass the expected error"
+ );
+
+ data = await browser.find.find("xyz");
+ await browser.test.assertRejects(
+ browser.find.highlightResults({ rangeIndex: 0 }),
+ /no search results to highlight/,
+ "rejected Promise should pass the expected error"
+ );
+
+ // Test highlightResults without any arguments, especially `rangeIndex`.
+ data = await browser.find.find("example");
+ browser.test.assertEq(6, data.count, "The number of matches found:");
+ await browser.find.highlightResults();
+
+ await browser.find.removeHighlighting();
+
+ data = await browser.find.find("banana", { includeRectData: true });
+ await browser.find.highlightResults({ rangeIndex: 5 });
+
+ browser.test.sendMessage("test:find:WebExtensionFinished", data.rectData);
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["find", "tabs"],
+ },
+ background,
+ });
+
+ await extension.startup();
+ let rectData = await extension.awaitMessage("test:find:WebExtensionFinished");
+ let { top, left } = rectData[5].rectsAndTexts.rectList[0];
+ await extension.unload();
+
+ let subFrameBrowsingContext =
+ gBrowser.selectedBrowser.browsingContext.children[0].children[1];
+ let result = await SpecialPowers.spawn(
+ subFrameBrowsingContext,
+ [],
+ frameScript
+ );
+
+ info("Test that text was highlighted properly.");
+ is(
+ result.text,
+ "bananA",
+ `The text that was highlighted: - Expected: bananA, Actual: ${result.text}`
+ );
+
+ info(
+ "Test that rectangle data returned from the search matches the highlighted result."
+ );
+ is(
+ result.rect.top,
+ top,
+ `rect.top: - Expected: ${result.rect.top}, Actual: ${top}`
+ );
+ is(
+ result.rect.left,
+ left,
+ `rect.left: - Expected: ${result.rect.left}, Actual: ${left}`
+ );
+});
+
+add_task(async function testRemoveHighlighting() {
+ async function background() {
+ function awaitLoad(tabId, url) {
+ return new Promise(resolve => {
+ browser.tabs.onUpdated.addListener(function listener(
+ tabId_,
+ changed,
+ tab
+ ) {
+ if (
+ tabId == tabId_ &&
+ changed.status == "complete" &&
+ tab.url == url
+ ) {
+ browser.tabs.onUpdated.removeListener(listener);
+ resolve();
+ }
+ });
+ });
+ }
+
+ let url =
+ "http://example.com/browser/browser/components/extensions/test/browser/file_find_frames.html";
+ let tab = await browser.tabs.update({ url });
+ await awaitLoad(tab.id, url);
+
+ let data = await browser.find.find("banana", { includeRangeData: true });
+
+ browser.test.log("Test that `data.count` is the expected value.");
+ browser.test.assertEq(
+ 6,
+ data.count,
+ "The value returned from `data.count`"
+ );
+
+ await browser.find.highlightResults({ rangeIndex: 5 });
+
+ browser.find.removeHighlighting();
+
+ browser.test.sendMessage("test:find:WebExtensionFinished");
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["find", "tabs"],
+ },
+ background,
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("test:find:WebExtensionFinished");
+ await extension.unload();
+
+ let subFrameBrowsingContext =
+ gBrowser.selectedBrowser.browsingContext.children[0].children[1];
+ let result = await SpecialPowers.spawn(
+ subFrameBrowsingContext,
+ [],
+ frameScript
+ );
+
+ info("Test that highlight was cleared properly.");
+ is(
+ result.text,
+ "",
+ `The text that was highlighted: - Expected: '', Actual: ${result.text}`
+ );
+});
+
+add_task(async function testAboutFind() {
+ async function background() {
+ await browser.test.assertRejects(
+ browser.find.find("banana"),
+ /Unable to search:/,
+ "Should not be able to search about tabs"
+ );
+
+ browser.test.sendMessage("done");
+ }
+
+ let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home");
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["find", "tabs"],
+ },
+ background,
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("done");
+ await extension.unload();
+ BrowserTestUtils.removeTab(tab);
+});
+
+add_task(async function testIncognitoFind() {
+ async function background() {
+ await browser.test.assertRejects(
+ browser.find.find("banana"),
+ /Unable to search:/,
+ "Should not be able to search private window"
+ );
+ await browser.test.assertRejects(
+ browser.find.highlightResults(),
+ /Unable to search:/,
+ "Should not be able to highlight in private window"
+ );
+ await browser.test.assertRejects(
+ browser.find.removeHighlighting(),
+ /Invalid tab ID:/,
+ "Should not be able to remove highlight in private window"
+ );
+
+ browser.test.sendMessage("done");
+ }
+
+ let privateWin = await BrowserTestUtils.openNewBrowserWindow({
+ private: true,
+ });
+ BrowserTestUtils.loadURIString(
+ privateWin.gBrowser.selectedBrowser,
+ "http://example.com"
+ );
+ await BrowserTestUtils.browserLoaded(privateWin.gBrowser.selectedBrowser);
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["find", "tabs"],
+ },
+ background,
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("done");
+ await extension.unload();
+ await BrowserTestUtils.closeWindow(privateWin);
+});
+
+add_task(async function testIncognitoFindAllowed() {
+ // We're only testing we can make the calls in a private window,
+ // testFind above tests full functionality.
+ async function background() {
+ await browser.find.find("banana");
+ await browser.find.highlightResults({ rangeIndex: 0 });
+ await browser.find.removeHighlighting();
+
+ browser.test.sendMessage("done");
+ }
+
+ let url =
+ "http://example.com/browser/browser/components/extensions/test/browser/file_find_frames.html";
+ let privateWin = await BrowserTestUtils.openNewBrowserWindow({
+ private: true,
+ });
+ BrowserTestUtils.loadURIString(privateWin.gBrowser.selectedBrowser, url);
+ await BrowserTestUtils.browserLoaded(privateWin.gBrowser.selectedBrowser);
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["find", "tabs"],
+ },
+ background,
+ incognitoOverride: "spanning",
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("done");
+ await extension.unload();
+ await BrowserTestUtils.closeWindow(privateWin);
+});