tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_dbg-project-search.js (8617B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
      4 
      5 // Testing various project search features
      6 
      7 "use strict";
      8 
      9 requestLongerTimeout(3);
     10 
     11 add_task(async function testProjectSearchCloseOnNavigation() {
     12  const dbg = await initDebugger(
     13    "doc-script-switching.html",
     14    "script-switching-01.js"
     15  );
     16 
     17  await selectSource(dbg, "script-switching-01.js");
     18 
     19  await openProjectSearch(dbg);
     20 
     21  ok(
     22    !findElement(dbg, "projectSearchRefreshButton"),
     23    "The refresh button is only visible after having done a search"
     24  );
     25 
     26  await doProjectSearch(dbg, "function", 2);
     27 
     28  is(getExpandedResultsCount(dbg), 6);
     29 
     30  is(dbg.selectors.getActiveSearch(), "project");
     31 
     32  const refreshButton = findElement(dbg, "projectSearchRefreshButton");
     33  ok(
     34    refreshButton,
     35    "Refresh button is visible right after search is completed"
     36  );
     37  ok(
     38    !refreshButton.classList.contains("highlight"),
     39    "Refresh button is *not* highlighted by default"
     40  );
     41 
     42  await navigate(dbg, "doc-scripts.html");
     43 
     44  // Project search is still visible after navigation
     45  is(dbg.selectors.getActiveSearch(), "project");
     46  // With same search results
     47  is(getExpandedResultsCount(dbg), 6);
     48 
     49  ok(
     50    refreshButton.classList.contains("highlight"),
     51    "Refresh button is highlighted after navigation"
     52  );
     53 
     54  info("Try to open a discarded source");
     55  await clickElement(dbg, "fileMatch");
     56 
     57  info("Wait for the warning popup to be visible");
     58  // We are waiting for the popup to be added...
     59  await waitFor(() => dbg.win.document.querySelector(".unavailable-source"));
     60  // ...and verify that the popup is made visible.
     61  await waitFor(() => dbg.win.document.querySelector(".tooltip-shown"));
     62  info("Retry to open the discard source, this should hide the popup");
     63  await clickElement(dbg, "fileMatch");
     64  info("Wait for the popup to be hidden");
     65  // Note that .unavailable-source won't be removed from the DOM
     66  await waitFor(() => !dbg.win.document.querySelector(".tooltip-visible"));
     67 
     68  info("Refresh results against the new page");
     69  refreshButton.click();
     70 
     71  // Wait for the search to be updated against the new page
     72  await waitForSearchResults(dbg, 5);
     73  is(getExpandedResultsCount(dbg), 39);
     74  ok(
     75    !refreshButton.classList.contains("highlight"),
     76    "Refresh button is no longer highlighted after refreshing the search"
     77  );
     78 });
     79 
     80 add_task(async function testSimpleProjectSearch() {
     81  // Start with side panel collapsed so we can assert that the project search keyboard
     82  // shortcut will open it.
     83  await pushPref("devtools.debugger.start-panel-collapsed", true);
     84 
     85  const dbg = await initDebugger(
     86    "doc-script-switching.html",
     87    "script-switching-01.js"
     88  );
     89 
     90  await openProjectSearch(dbg);
     91 
     92  ok(
     93    !!findElementWithSelector(dbg, ".project-text-search"),
     94    "Project search is visible"
     95  );
     96 
     97  const searchTerm = "first";
     98  await doProjectSearch(dbg, searchTerm, 1);
     99 
    100  const queryMatch = findElement(dbg, "fileMatch").querySelector(
    101    ".query-match"
    102  );
    103  is(
    104    queryMatch.innerText,
    105    searchTerm,
    106    "The highlighted text matches the search term"
    107  );
    108 
    109  info("Select a result match to open the location in the source");
    110  await clickElement(dbg, "fileMatch");
    111  await waitForSelectedSource(dbg, "script-switching-01.js");
    112 
    113  info("Close start sidebar");
    114  const startPanelToggleButtonEl = findElementWithSelector(
    115    dbg,
    116    ".toggle-button.start"
    117  );
    118  startPanelToggleButtonEl.click();
    119  await waitFor(() => startPanelToggleButtonEl.classList.contains("collapsed"));
    120 
    121  info("Try to open project search again");
    122  await openProjectSearch(dbg);
    123  ok(
    124    !!findElementWithSelector(dbg, ".project-text-search"),
    125    "Project search is visible"
    126  );
    127 });
    128 
    129 add_task(async function testMatchesForRegexSearches() {
    130  const dbg = await initDebugger("doc-react.html", "App.js");
    131  await openProjectSearch(dbg);
    132 
    133  type(dbg, "import .* from 'react'");
    134  await clickElement(dbg, "projectSearchModifiersRegexMatch");
    135 
    136  await waitForSearchResults(dbg, 2);
    137 
    138  const queryMatch = findAllElements(dbg, "fileMatch")[1].querySelector(
    139    ".query-match"
    140  );
    141 
    142  is(
    143    queryMatch.innerText,
    144    "import React, { Component } from 'react'",
    145    "The highlighted text matches the search term"
    146  );
    147 
    148  // Turn off the regex modifier so does not break tests below
    149  await clickElement(dbg, "projectSearchModifiersRegexMatch");
    150 });
    151 
    152 // Test expanding search results to reveal the search matches.
    153 add_task(async function testExpandSearchResultsToShowMatches() {
    154  const dbg = await initDebugger("doc-react.html", "App.js");
    155 
    156  await openProjectSearch(dbg);
    157  await doProjectSearch(dbg, "we", 19);
    158 
    159  is(getExpandedResultsCount(dbg), 159);
    160 
    161  const collapsedNodes = findAllElements(dbg, "projectSearchCollapsed");
    162  is(collapsedNodes.length, 1);
    163 
    164  collapsedNodes[0].click();
    165 
    166  is(getExpandedResultsCount(dbg), 367);
    167 });
    168 
    169 add_task(async function testSearchModifiers() {
    170  const dbg = await initDebugger("doc-react.html", "App.js");
    171 
    172  await openProjectSearch(dbg);
    173 
    174  await assertProjectSearchModifier(
    175    dbg,
    176    "projectSearchModifiersCaseSensitive",
    177    "FIELDS",
    178    "case sensitive",
    179    { resultWithModifierOn: 0, resultWithModifierOff: 2 }
    180  );
    181  await assertProjectSearchModifier(
    182    dbg,
    183    "projectSearchModifiersRegexMatch",
    184    `\\*`,
    185    "regex match",
    186    { resultWithModifierOn: 12, resultWithModifierOff: 0 }
    187  );
    188  await assertProjectSearchModifier(
    189    dbg,
    190    "projectSearchModifiersWholeWordMatch",
    191    "so",
    192    "whole word match",
    193    { resultWithModifierOn: 6, resultWithModifierOff: 16 }
    194  );
    195 });
    196 
    197 add_task(async function testSearchExcludePatterns() {
    198  const dbg = await initDebugger("doc-react.html", "App.js");
    199 
    200  info("Search across all files");
    201  await openProjectSearch(dbg);
    202  let fileResults = await doProjectSearch(dbg, "console", 5);
    203 
    204  let resultsFromNodeModules = [...fileResults].filter(result =>
    205    result.innerText.includes("node_modules")
    206  );
    207 
    208  is(
    209    resultsFromNodeModules.length,
    210    3,
    211    "3 results were found from node_modules"
    212  );
    213 
    214  info("Excludes search results based on multiple search patterns");
    215 
    216  await clickElement(dbg, "excludePatternsInput");
    217  type(dbg, "App.js, main.js");
    218  pressKey(dbg, "Enter");
    219 
    220  fileResults = await waitForSearchResults(dbg, 3);
    221 
    222  const resultsFromAppJS = [...fileResults].filter(result =>
    223    result.innerText.includes("App.js")
    224  );
    225 
    226  is(resultsFromAppJS.length, 0, "None of the results is from the App.js file");
    227 
    228  const resultsFromMainJS = [...fileResults].filter(result =>
    229    result.innerText.includes("main.js")
    230  );
    231 
    232  is(
    233    resultsFromMainJS.length,
    234    0,
    235    "None of the results is from the main.js file"
    236  );
    237 
    238  info("Excludes search results from node modules files");
    239 
    240  await clearElement(dbg, "excludePatternsInput");
    241  type(dbg, "**/node_modules/**");
    242  pressKey(dbg, "Enter");
    243 
    244  fileResults = await waitForSearchResults(dbg, 2);
    245 
    246  resultsFromNodeModules = [...fileResults].filter(result =>
    247    result.innerText.includes("node_modules")
    248  );
    249 
    250  is(
    251    resultsFromNodeModules.length,
    252    0,
    253    "None of the results is from the node modules files"
    254  );
    255 
    256  info("Assert that the exclude pattern is persisted across reloads");
    257  await reloadBrowser();
    258  await openProjectSearch(dbg);
    259 
    260  const excludePatternsInputElement = await waitForElement(
    261    dbg,
    262    "excludePatternsInput"
    263  );
    264 
    265  is(
    266    excludePatternsInputElement.value,
    267    "**/node_modules/**",
    268    "The exclude pattern for node modules is persisted accross reloads"
    269  );
    270 
    271  // Clear the fields so that it does not impact on the subsequent tests
    272  await clearElement(dbg, "projectSearchSearchInput");
    273  await clearElement(dbg, "excludePatternsInput");
    274  pressKey(dbg, "Enter");
    275 });
    276 
    277 async function assertProjectSearchModifier(
    278  dbg,
    279  searchModifierBtn,
    280  searchTerm,
    281  title,
    282  expected
    283 ) {
    284  info(`Assert ${title} search modifier`);
    285 
    286  type(dbg, searchTerm);
    287  info(`Turn on the ${title} search modifier option`);
    288  await clickElement(dbg, searchModifierBtn);
    289  let results = await waitForSearchResults(dbg, expected.resultWithModifierOn);
    290  is(
    291    results.length,
    292    expected.resultWithModifierOn,
    293    `${results.length} results where found`
    294  );
    295 
    296  info(`Turn off the ${title} search modifier`);
    297  await clickElement(dbg, searchModifierBtn);
    298 
    299  results = await waitForSearchResults(dbg, expected.resultWithModifierOff);
    300  is(
    301    results.length,
    302    expected.resultWithModifierOff,
    303    `${results.length} results where found`
    304  );
    305  await clearElement(dbg, "projectSearchSearchInput");
    306 }