tor-browser

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

browser_inspector_highlighter-cssshape_04.js (17612B)


      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 "use strict";
      6 
      7 // Test that shapes are updated correctly on mouse events.
      8 
      9 const TEST_URL = URL_ROOT + "doc_inspector_highlighter_cssshapes.html";
     10 const { TYPES } = ChromeUtils.importESModule(
     11  "resource://devtools/shared/highlighters.mjs"
     12 );
     13 const HIGHLIGHTER_TYPE = TYPES.SHAPES;
     14 
     15 add_task(async function testPolygon() {
     16  const config = await taskSetup();
     17 
     18  await testPolygonMovePoint(config);
     19  await testPolygonAddPoint(config);
     20  await testPolygonRemovePoint(config);
     21 
     22  config.helper.finalize();
     23 });
     24 
     25 add_task(async function testCircle() {
     26  const config = await taskSetup();
     27 
     28  await testCircleMoveCenter(config);
     29  await testCircleWithoutPosition(config);
     30 
     31  config.helper.finalize();
     32 });
     33 
     34 add_task(async function testEllipse() {
     35  const config = await taskSetup();
     36 
     37  await testEllipseMoveRadius(config);
     38 
     39  config.helper.finalize();
     40 });
     41 
     42 add_task(async function testInset() {
     43  const config = await taskSetup();
     44 
     45  await testInsetMoveEdges(config);
     46 
     47  config.helper.finalize();
     48 });
     49 
     50 async function taskSetup() {
     51  const env = await openInspectorForURL(TEST_URL);
     52  const helper = await getHighlighterHelperFor(HIGHLIGHTER_TYPE)(env);
     53  const { highlighterTestFront, inspector } = env;
     54  const view = selectRuleView(inspector);
     55  const highlighters = view.highlighters;
     56 
     57  return {
     58    inspector,
     59    view,
     60    highlighters,
     61    highlighterTestFront,
     62    helper,
     63  };
     64 }
     65 
     66 async function getComputedPropertyValue(selector, property, inspector) {
     67  const highlightedNode = await getNodeFront(selector, inspector);
     68  const computedStyle =
     69    await highlightedNode.inspectorFront.pageStyle.getComputed(highlightedNode);
     70  return computedStyle[property].value;
     71 }
     72 
     73 async function setup(config) {
     74  const { view, selector, property, inspector } = config;
     75  info(`Turn on shapes highlighter for ${selector}`);
     76  await selectNode(selector, inspector);
     77  await toggleShapesHighlighter(view, selector, property, true);
     78 }
     79 
     80 async function teardown(config) {
     81  const { view, selector, property } = config;
     82  info(`Turn off shapes highlighter for ${selector}`);
     83  await toggleShapesHighlighter(view, selector, property, false);
     84 }
     85 
     86 async function testPolygonMovePoint(config) {
     87  const { inspector, view, highlighterTestFront, helper } = config;
     88  const selector = "#polygon";
     89  const property = "clip-path";
     90 
     91  await setup({ selector, property, ...config });
     92 
     93  const points = await highlighterTestFront.getHighlighterNodeAttribute(
     94    "shapes-polygon",
     95    "points",
     96    inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
     97  );
     98  let [x, y] = points.split(" ")[0].split(",");
     99  const quads = await getAllAdjustedQuadsForContentPageElement(selector);
    100  const { top, left, width, height } = quads.border[0].bounds;
    101  x = left + (width * x) / 100;
    102  y = top + (height * y) / 100;
    103  const dx = width / 10;
    104  const dyPercent = 10;
    105  const dy = height / dyPercent;
    106 
    107  const onRuleViewChanged = view.once("ruleview-changed");
    108  info("Moving first polygon point");
    109  const { mouse } = helper;
    110  await mouse.down(x, y);
    111  await mouse.move(x + dx, y + dy);
    112  await mouse.up();
    113  await reflowContentPage();
    114  info("Waiting for rule view changed from shape change");
    115  await onRuleViewChanged;
    116 
    117  const definition = await getComputedPropertyValue(
    118    selector,
    119    property,
    120    inspector
    121  );
    122  ok(
    123    definition.includes(`${dx}px ${dyPercent}%`),
    124    `Point moved to ${dx}px ${dyPercent}%`
    125  );
    126 
    127  await teardown({ selector, property, ...config });
    128 }
    129 
    130 async function testPolygonAddPoint(config) {
    131  const { inspector, view, highlighterTestFront, helper } = config;
    132  const selector = "#polygon";
    133  const property = "clip-path";
    134 
    135  await setup({ selector, property, ...config });
    136 
    137  // Move first point to have same x as second point, then double click between
    138  // the two points to add a new one.
    139  const points = await highlighterTestFront.getHighlighterNodeAttribute(
    140    "shapes-polygon",
    141    "points",
    142    inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
    143  );
    144  const pointsArray = points.split(" ");
    145  const quads = await getAllAdjustedQuadsForContentPageElement(selector);
    146  const { top, left, width, height } = quads.border[0].bounds;
    147  let [x1, y1] = pointsArray[0].split(",");
    148  let [x2, y2] = pointsArray[1].split(",");
    149  x1 = left + (width * x1) / 100;
    150  x2 = left + (width * x2) / 100;
    151  y1 = top + (height * y1) / 100;
    152  y2 = top + (height * y2) / 100;
    153 
    154  const { mouse } = helper;
    155  await mouse.down(x1, y1);
    156  await mouse.move(x2, y1);
    157  await mouse.up();
    158  await reflowContentPage();
    159 
    160  let newPointX = x2;
    161  let newPointY = (y1 + y2) / 2;
    162 
    163  const onRuleViewChanged = view.once("ruleview-changed");
    164  info("Adding new polygon point");
    165  BrowserTestUtils.synthesizeMouse(
    166    ":root",
    167    newPointX,
    168    newPointY,
    169    { clickCount: 2 },
    170    gBrowser.selectedTab.linkedBrowser
    171  );
    172 
    173  await reflowContentPage();
    174  info("Waiting for rule view changed from shape change");
    175  await onRuleViewChanged;
    176 
    177  // Decimal precision for coordinates with percentage units is 2
    178  const precision = 2;
    179  // Round to the desired decimal precision and cast to Number to remove trailing zeroes.
    180  newPointX = Number(((newPointX * 100) / width).toFixed(precision));
    181  newPointY = Number(((newPointY * 100) / height).toFixed(precision));
    182  const definition = await getComputedPropertyValue(
    183    selector,
    184    property,
    185    inspector
    186  );
    187  ok(
    188    definition.includes(`${newPointX}% ${newPointY}%`),
    189    "Point successfuly added"
    190  );
    191 
    192  await teardown({ selector, property, ...config });
    193 }
    194 
    195 async function testPolygonRemovePoint(config) {
    196  const { inspector, highlighters, highlighterTestFront, helper } = config;
    197  const selector = "#polygon";
    198  const property = "clip-path";
    199 
    200  await setup({ selector, property, ...config });
    201 
    202  const points = await highlighterTestFront.getHighlighterNodeAttribute(
    203    "shapes-polygon",
    204    "points",
    205    inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
    206  );
    207  const [x, y] = points.split(" ")[0].split(",");
    208  const quads = await getAllAdjustedQuadsForContentPageElement(selector);
    209  const { top, left, width, height } = quads.border[0].bounds;
    210 
    211  const adjustedX = left + (width * x) / 100;
    212  const adjustedY = top + (height * y) / 100;
    213 
    214  info("Move mouse over first point in highlighter");
    215  const onEventHandled = highlighters.once("highlighter-event-handled");
    216  const { mouse } = helper;
    217  await mouse.move(adjustedX, adjustedY);
    218  await onEventHandled;
    219  const markerHidden = await highlighterTestFront.getHighlighterNodeAttribute(
    220    "shapes-marker-hover",
    221    "hidden",
    222    inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
    223  );
    224  ok(!markerHidden, "Marker on highlighter is visible");
    225 
    226  info("Double click on first point in highlighter");
    227  const onShapeChangeApplied = highlighters.once(
    228    "shapes-highlighter-changes-applied"
    229  );
    230  BrowserTestUtils.synthesizeMouse(
    231    ":root",
    232    adjustedX,
    233    adjustedY,
    234    { clickCount: 2 },
    235    gBrowser.selectedTab.linkedBrowser
    236  );
    237 
    238  info("Waiting for shape changes to apply");
    239  await onShapeChangeApplied;
    240  const definition = await getComputedPropertyValue(
    241    selector,
    242    property,
    243    inspector
    244  );
    245  ok(!definition.includes(`${x}% ${y}%`), "Point successfully removed");
    246 
    247  await teardown({ selector, property, ...config });
    248 }
    249 
    250 async function testCircleMoveCenter(config) {
    251  const { inspector, highlighters, highlighterTestFront, helper } = config;
    252  const selector = "#circle";
    253  const property = "clip-path";
    254 
    255  const onShapeChangeApplied = highlighters.once(
    256    "shapes-highlighter-changes-applied"
    257  );
    258  await setup({ selector, property, ...config });
    259 
    260  const cx = parseFloat(
    261    await highlighterTestFront.getHighlighterNodeAttribute(
    262      "shapes-ellipse",
    263      "cx",
    264      inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
    265    )
    266  );
    267  const cy = parseFloat(
    268    await highlighterTestFront.getHighlighterNodeAttribute(
    269      "shapes-ellipse",
    270      "cy",
    271      inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
    272    )
    273  );
    274  const quads = await getAllAdjustedQuadsForContentPageElement(selector);
    275  const { width, height } = quads.border[0].bounds;
    276  const cxPixel = (width * cx) / 100;
    277  const cyPixel = (height * cy) / 100;
    278  const dx = width / 10;
    279  const dy = height / 10;
    280 
    281  info("Moving circle center");
    282  const { mouse } = helper;
    283  await mouse.down(cxPixel, cyPixel, selector);
    284  await mouse.move(cxPixel + dx, cyPixel + dy, selector);
    285  await mouse.up(cxPixel + dx, cyPixel + dy, selector);
    286  await reflowContentPage();
    287  info("Waiting for shape changes to apply");
    288  await onShapeChangeApplied;
    289 
    290  const definition = await getComputedPropertyValue(
    291    selector,
    292    property,
    293    inspector
    294  );
    295  ok(
    296    definition.includes(`at ${cx + 10}% ${cy + 10}%`),
    297    "Circle center successfully moved"
    298  );
    299 
    300  await teardown({ selector, property, ...config });
    301 }
    302 
    303 async function testCircleWithoutPosition(config) {
    304  const { inspector, highlighters, highlighterTestFront, helper } = config;
    305  const selector = "#circle-without-position";
    306  const property = "clip-path";
    307 
    308  await setup({ selector, property, ...config });
    309 
    310  const rx = parseFloat(
    311    await highlighterTestFront.getHighlighterNodeAttribute(
    312      "shapes-ellipse",
    313      "rx",
    314      inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
    315    )
    316  );
    317 
    318  const cx = parseFloat(
    319    await highlighterTestFront.getHighlighterNodeAttribute(
    320      "shapes-ellipse",
    321      "cx",
    322      inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
    323    )
    324  );
    325  const cy = parseFloat(
    326    await highlighterTestFront.getHighlighterNodeAttribute(
    327      "shapes-ellipse",
    328      "cy",
    329      inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
    330    )
    331  );
    332  const quads = await getAllAdjustedQuadsForContentPageElement(selector);
    333  const { width, height } = quads.content[0].bounds;
    334  const highlightedNode = await getNodeFront(selector, inspector);
    335  const computedStyle =
    336    await highlightedNode.inspectorFront.pageStyle.getComputed(highlightedNode);
    337  const paddingTop = parseFloat(computedStyle["padding-top"].value);
    338  const paddingLeft = parseFloat(computedStyle["padding-left"].value);
    339  const cxPixel = paddingLeft + (width * cx) / 100;
    340  const cyPixel = paddingTop + (height * cy) / 100;
    341  const rxPixel = cxPixel + (width * rx) / 100;
    342  const dx = width / 10;
    343  const dy = height / 10;
    344 
    345  const { mouse } = helper;
    346  info("Moving circle rx");
    347  let onShapeChangeApplied = highlighters.once(
    348    "shapes-highlighter-changes-applied"
    349  );
    350  await mouse.down(rxPixel, cyPixel, selector);
    351  await mouse.move(rxPixel + dx, cyPixel, selector);
    352  await mouse.up(rxPixel + dx, cyPixel, selector);
    353  await reflowContentPage();
    354  await onShapeChangeApplied;
    355 
    356  let definition = await getComputedPropertyValue(
    357    selector,
    358    property,
    359    inspector
    360  );
    361  is(
    362    definition,
    363    `circle(${rx + 10}%)`,
    364    "Circle without position radiuses successfully changed"
    365  );
    366 
    367  info("Moving circle center");
    368  onShapeChangeApplied = highlighters.once(
    369    "shapes-highlighter-changes-applied"
    370  );
    371  await mouse.down(cxPixel, cyPixel, selector);
    372  await mouse.move(cxPixel + dx, cyPixel, selector);
    373  await mouse.up(cxPixel + dx, cyPixel, selector);
    374  await reflowContentPage();
    375  info("Waiting for shape changes to apply");
    376  await onShapeChangeApplied;
    377 
    378  definition = await getComputedPropertyValue(selector, property, inspector);
    379  is(
    380    definition,
    381    `circle(${rx + 10}% at ${cxPixel + dx}px ${cyPixel}px)`,
    382    `Circle without position center (${cxPixel},${cyPixel}) successfully moved (${dx},${dy})`
    383  );
    384 
    385  await teardown({ selector, property, ...config });
    386 }
    387 
    388 async function testEllipseMoveRadius(config) {
    389  const { inspector, highlighters, highlighterTestFront, helper } = config;
    390  const selector = "#ellipse";
    391  const property = "clip-path";
    392 
    393  await setup({ selector, property, ...config });
    394 
    395  const rx = parseFloat(
    396    await highlighterTestFront.getHighlighterNodeAttribute(
    397      "shapes-ellipse",
    398      "rx",
    399      inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
    400    )
    401  );
    402  const ry = parseFloat(
    403    await highlighterTestFront.getHighlighterNodeAttribute(
    404      "shapes-ellipse",
    405      "ry",
    406      inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
    407    )
    408  );
    409  const cx = parseFloat(
    410    await highlighterTestFront.getHighlighterNodeAttribute(
    411      "shapes-ellipse",
    412      "cx",
    413      inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
    414    )
    415  );
    416  const cy = parseFloat(
    417    await highlighterTestFront.getHighlighterNodeAttribute(
    418      "shapes-ellipse",
    419      "cy",
    420      inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
    421    )
    422  );
    423  const quads = await getAllAdjustedQuadsForContentPageElement("#ellipse");
    424  const { width, height } = quads.content[0].bounds;
    425  const highlightedNode = await getNodeFront(selector, inspector);
    426  const computedStyle =
    427    await highlightedNode.inspectorFront.pageStyle.getComputed(highlightedNode);
    428  const paddingTop = parseFloat(computedStyle["padding-top"].value);
    429  const paddingLeft = parseFloat(computedStyle["padding-left"].value);
    430  const cxPixel = paddingLeft + (width * cx) / 100;
    431  const cyPixel = paddingTop + (height * cy) / 100;
    432  const rxPixel = cxPixel + (width * rx) / 100;
    433  const ryPixel = cyPixel + (height * ry) / 100;
    434  const dx = width / 10;
    435  const dy = height / 10;
    436 
    437  const { mouse } = helper;
    438  info("Moving ellipse rx");
    439  await mouse.down(rxPixel, cyPixel, selector);
    440  await mouse.move(rxPixel + dx, cyPixel, selector);
    441  await mouse.up(rxPixel + dx, cyPixel, selector);
    442  await reflowContentPage();
    443 
    444  info("Moving ellipse ry");
    445  const onShapeChangeApplied = highlighters.once(
    446    "shapes-highlighter-changes-applied"
    447  );
    448  await mouse.down(cxPixel, ryPixel, selector);
    449  await mouse.move(cxPixel, ryPixel - dy, selector);
    450  await mouse.up(cxPixel, ryPixel - dy, selector);
    451  await reflowContentPage();
    452  await onShapeChangeApplied;
    453 
    454  const definition = await getComputedPropertyValue(
    455    selector,
    456    property,
    457    inspector
    458  );
    459  ok(
    460    definition.includes(`${rx + 10}% ${ry - 10}%`),
    461    "Ellipse radiuses successfully moved"
    462  );
    463 
    464  await teardown({ selector, property, ...config });
    465 }
    466 
    467 async function testInsetMoveEdges(config) {
    468  const { inspector, highlighters, highlighterTestFront, helper } = config;
    469  const selector = "#inset";
    470  const property = "clip-path";
    471 
    472  await setup({ selector, property, ...config });
    473 
    474  const x = parseFloat(
    475    await highlighterTestFront.getHighlighterNodeAttribute(
    476      "shapes-rect",
    477      "x",
    478      inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
    479    )
    480  );
    481  const y = parseFloat(
    482    await highlighterTestFront.getHighlighterNodeAttribute(
    483      "shapes-rect",
    484      "y",
    485      inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
    486    )
    487  );
    488  const width = parseFloat(
    489    await highlighterTestFront.getHighlighterNodeAttribute(
    490      "shapes-rect",
    491      "width",
    492      inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
    493    )
    494  );
    495  const height = parseFloat(
    496    await highlighterTestFront.getHighlighterNodeAttribute(
    497      "shapes-rect",
    498      "height",
    499      inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE)
    500    )
    501  );
    502  const quads = await getAllAdjustedQuadsForContentPageElement(selector);
    503  const { width: elemWidth, height: elemHeight } = quads.content[0].bounds;
    504 
    505  const left = (elemWidth * x) / 100;
    506  const top = (elemHeight * y) / 100;
    507  const right = left + (elemWidth * width) / 100;
    508  const bottom = top + (elemHeight * height) / 100;
    509  const xCenter = (left + right) / 2;
    510  const yCenter = (top + bottom) / 2;
    511  const dx = elemWidth / 10;
    512  const dy = elemHeight / 10;
    513  const { mouse } = helper;
    514 
    515  info("Moving inset top");
    516  let onShapeChangeApplied = highlighters.once(
    517    "shapes-highlighter-changes-applied"
    518  );
    519  await mouse.down(xCenter, top, selector);
    520  await mouse.move(xCenter, top + dy, selector);
    521  await mouse.up(xCenter, top + dy, selector);
    522  await reflowContentPage();
    523  await onShapeChangeApplied;
    524 
    525  // TODO: Test bottom inset marker after Bug 1456777 is fixed.
    526  // Bug 1456777 - https://bugzilla.mozilla.org/show_bug.cgi?id=1456777
    527  // The test element is larger than the viewport when tests run in headless mode.
    528  // When moved, the bottom marker value is getting clamped to the viewport.
    529 
    530  info("Moving inset left");
    531  onShapeChangeApplied = highlighters.once(
    532    "shapes-highlighter-changes-applied"
    533  );
    534  await mouse.down(left, yCenter, selector);
    535  await mouse.move(left + dx, yCenter, selector);
    536  await mouse.up(left + dx, yCenter, selector);
    537  await reflowContentPage();
    538  await onShapeChangeApplied;
    539 
    540  info("Moving inset right");
    541  onShapeChangeApplied = highlighters.once(
    542    "shapes-highlighter-changes-applied"
    543  );
    544  await mouse.down(right, yCenter, selector);
    545  await mouse.move(right + dx, yCenter, selector);
    546  await mouse.up(right + dx, yCenter, selector);
    547  await reflowContentPage();
    548  await onShapeChangeApplied;
    549 
    550  const definition = await getComputedPropertyValue(
    551    selector,
    552    property,
    553    inspector
    554  );
    555 
    556  // NOTE: No change to bottom inset until Bug 1456777 is fixed.
    557  ok(
    558    definition.includes(
    559      `${top + dy}px ${elemWidth - right - dx}px ${100 - y - height}% ${
    560        x + 10
    561      }%`
    562    ),
    563    "Inset edges successfully moved"
    564  );
    565 
    566  await teardown({ selector, property, ...config });
    567 }