tor-browser

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

browser_rules_registered-custom-properties.js (21267B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Tests that registed custom properties (@property/Css.registerProperty) are displayed
      7 // in a dedicated section and that they are properly reflected in the `var()` popup.
      8 
      9 const CSS_NO_INHERIT_INITIAL_VALUE = "tomato";
     10 const CSS_INHERIT_INITIAL_VALUE = "gold";
     11 const CSS_NOT_DEFINED_INITIAL_VALUE = "purple";
     12 const JS_NO_INHERIT_INITIAL_VALUE = "42px";
     13 
     14 const CSS_NO_INHERIT_MAIN_VALUE = "#0000FF";
     15 const CSS_INHERIT_MAIN_VALUE = "#FF0000";
     16 const JS_NO_INHERIT_MAIN_VALUE = "100%";
     17 const JS_INHERIT_MAIN_VALUE = "50vw";
     18 
     19 const TEST_URI = `https://example.org/document-builder.sjs?html=${encodeURIComponent(`
     20 <script>
     21    CSS.registerProperty({
     22      name: "--js-no-inherit",
     23      syntax: "<length>",
     24      inherits: false,
     25      initialValue: "${JS_NO_INHERIT_INITIAL_VALUE}",
     26    });
     27    CSS.registerProperty({
     28      name: "--js-inherit",
     29      syntax: "*",
     30      inherits: true,
     31    });
     32  </script>
     33  <style>
     34    @property --css-no-inherit {
     35      syntax: "<color>";
     36      inherits: false;
     37      initial-value: ${CSS_NO_INHERIT_INITIAL_VALUE};
     38    }
     39 
     40    @property --css-inherit {
     41      syntax: "<color>";
     42      inherits: true;
     43      initial-value: ${CSS_INHERIT_INITIAL_VALUE};
     44    }
     45 
     46    @property --css-not-defined {
     47      syntax: "<color>";
     48      inherits: true;
     49      initial-value: ${CSS_NOT_DEFINED_INITIAL_VALUE};
     50    }
     51 
     52    @property --empty {
     53      syntax: "*";
     54      inherits: true;
     55      initial-value: ;
     56    }
     57 
     58    main {
     59      --js-no-inherit: ${JS_NO_INHERIT_MAIN_VALUE};
     60      --js-inherit: ${JS_INHERIT_MAIN_VALUE};
     61      --css-no-inherit: ${CSS_NO_INHERIT_MAIN_VALUE};
     62      --css-inherit: ${CSS_INHERIT_MAIN_VALUE};
     63    }
     64 
     65    h1 {
     66      background-color: var(--css-no-inherit);
     67      color: var(--css-inherit);
     68      border-color: var(--css-not-defined);
     69      height: var(--js-no-inherit);
     70      width: var(--js-inherit);
     71      outline: 10px solid var(--constructed, green);
     72      text-decoration-color: var(--js-not-defined, blue);
     73      caret-color: var(--css-dynamic-registered, turquoise);
     74      --test-empty: var(--empty);
     75    }
     76 
     77    aside {
     78     /* registered property has <color> syntax, this declaration is invalid at computed-value time */
     79      --css-inherit: dashed;
     80      /* valid, complex value */
     81      --js-no-inherit: calc(100px * cos(45deg));
     82      /* based on another property */
     83      --css-dynamic-registered: var(--css-no-inherit);
     84    }
     85  </style>
     86  <main>
     87    <h1>Hello world</h1>
     88    <aside>fries</aside>
     89    <iframe src="https://example.com/document-builder.sjs?html=iframe"></iframe>
     90  </main>
     91 `)}`;
     92 
     93 add_task(async function () {
     94  await pushPref("layout.css.properties-and-values.enabled", true);
     95  const tab = await addTab(TEST_URI);
     96  const { inspector, view } = await openRuleView();
     97  const doc = view.styleDocument;
     98  await selectNode("h1", inspector);
     99 
    100  info("Check the content of the @property section");
    101  is(
    102    doc.querySelector(".ruleview-expandable-header").textContent,
    103    "@property",
    104    "The @property section header is displayed"
    105  );
    106  const registeredPropertiesContainer = doc.getElementById(
    107    "registered-properties-container"
    108  );
    109  ok(!!registeredPropertiesContainer, "The @property container is displayed");
    110 
    111  const expectedProperties = [
    112    {
    113      header: `--css-inherit {`,
    114      propertyDefinition: [
    115        `  syntax: "<color>";`,
    116        `  inherits: true;`,
    117        `  initial-value: ${CSS_INHERIT_INITIAL_VALUE};`,
    118      ],
    119    },
    120    {
    121      header: `--css-no-inherit {`,
    122      propertyDefinition: [
    123        `  syntax: "<color>";`,
    124        `  inherits: false;`,
    125        `  initial-value: ${CSS_NO_INHERIT_INITIAL_VALUE};`,
    126      ],
    127    },
    128    {
    129      header: `--css-not-defined {`,
    130      propertyDefinition: [
    131        `  syntax: "<color>";`,
    132        `  inherits: true;`,
    133        `  initial-value: ${CSS_NOT_DEFINED_INITIAL_VALUE};`,
    134      ],
    135    },
    136    {
    137      header: `--empty {`,
    138      propertyDefinition: [
    139        `  syntax: "*";`,
    140        `  inherits: true;`,
    141        `  initial-value: ;`,
    142      ],
    143    },
    144    {
    145      header: `--js-inherit {`,
    146      propertyDefinition: [
    147        `  name: "--js-inherit",`,
    148        `  syntax: "*",`,
    149        `  inherits: true,`,
    150      ],
    151    },
    152    {
    153      header: `--js-no-inherit {`,
    154      propertyDefinition: [
    155        `  name: "--js-no-inherit",`,
    156        `  syntax: "<length>",`,
    157        `  inherits: false,`,
    158        `  initialValue: "${JS_NO_INHERIT_INITIAL_VALUE}",`,
    159      ],
    160    },
    161  ];
    162 
    163  checkRegisteredProperties(view, expectedProperties);
    164 
    165  info("Check that var() tooltips handle registered properties");
    166  await assertVariableTooltipForProperty(view, "h1", "background-color", {
    167    // The variable value is the initial value since the variable does not inherit
    168    header:
    169      // prettier-ignore
    170      '<span xmlns="http://www.w3.org/1999/xhtml" data-color="tomato" class="color-swatch-container">' +
    171        '<span ' +
    172          'class="inspector-swatch inspector-colorswatch" ' +
    173          'style="background-color:tomato">' +
    174        '</span>' +
    175        `<span class="ruleview-color">${CSS_NO_INHERIT_INITIAL_VALUE}</span>` +
    176      '</span>',
    177    registeredProperty: {
    178      syntax: `"&lt;color&gt;"`,
    179      inherits: "false",
    180      "initial-value":
    181        // prettier-ignore
    182        '<span xmlns="http://www.w3.org/1999/xhtml" data-color="tomato" class="color-swatch-container">' +
    183          '<span ' +
    184            'class="inspector-swatch inspector-colorswatch" ' +
    185            'style="background-color:tomato">' +
    186          '</span>' +
    187          `<span class="ruleview-color">${CSS_NO_INHERIT_INITIAL_VALUE}</span>` +
    188        '</span>',
    189    },
    190  });
    191  await assertVariableTooltipForProperty(view, "h1", "color", {
    192    // The variable value is the value set in the main selector, since the variable does inherit
    193    header:
    194      // prettier-ignore
    195      '<span xmlns="http://www.w3.org/1999/xhtml" data-color="#FF0000" class="color-swatch-container">' +
    196        '<span ' +
    197          'class="inspector-swatch inspector-colorswatch" ' +
    198          'style="background-color:#FF0000">' +
    199        '</span>' +
    200        `<span class="ruleview-color">${CSS_INHERIT_MAIN_VALUE}</span>` +
    201      '</span>',
    202    computed:
    203      // prettier-ignore
    204      '<span xmlns="http://www.w3.org/1999/xhtml" data-color="rgb(255, 0, 0)" class="color-swatch-container">' +
    205        '<span ' +
    206          'class="inspector-swatch inspector-colorswatch" ' +
    207          'style="background-color:rgb(255, 0, 0)">' +
    208        '</span>' +
    209        `<span class="ruleview-color">rgb(255, 0, 0)</span>` +
    210      '</span>',
    211    registeredProperty: {
    212      syntax: `"&lt;color&gt;"`,
    213      inherits: "true",
    214      "initial-value":
    215        // prettier-ignore
    216        '<span xmlns="http://www.w3.org/1999/xhtml" data-color="gold" class="color-swatch-container">' +
    217          '<span ' +
    218            'class="inspector-swatch inspector-colorswatch" ' +
    219            'style="background-color:gold">' +
    220          '</span>' +
    221          `<span class="ruleview-color">${CSS_INHERIT_INITIAL_VALUE}</span>` +
    222        '</span>',
    223    },
    224  });
    225  await assertVariableTooltipForProperty(
    226    view,
    227    "h1",
    228    "border-color",
    229    // The variable value is the initial value since the variable is not set
    230    {
    231      header:
    232        // prettier-ignore
    233        `<span xmlns="http://www.w3.org/1999/xhtml" data-color="purple" class="color-swatch-container">` +
    234          `<span ` +
    235            `class="inspector-swatch inspector-colorswatch" ` +
    236            `style="background-color:purple">` +
    237          `</span>` +
    238          `<span class="ruleview-color">${CSS_NOT_DEFINED_INITIAL_VALUE}</span>` +
    239        `</span>`,
    240      registeredProperty: {
    241        syntax: `"&lt;color&gt;"`,
    242        inherits: "true",
    243        "initial-value":
    244          // prettier-ignore
    245          `<span xmlns="http://www.w3.org/1999/xhtml" data-color="purple" class="color-swatch-container">` +
    246            `<span ` +
    247              `class="inspector-swatch inspector-colorswatch" ` +
    248              `style="background-color:purple">` +
    249            `</span>` +
    250            `<span class="ruleview-color">${CSS_NOT_DEFINED_INITIAL_VALUE}</span>` +
    251          `</span>`,
    252      },
    253    }
    254  );
    255  await assertVariableTooltipForProperty(
    256    view,
    257    "h1",
    258    "height",
    259    // The variable value is the initial value since the variable does not inherit
    260    {
    261      header: JS_NO_INHERIT_INITIAL_VALUE,
    262      registeredProperty: {
    263        syntax: `"&lt;length&gt;"`,
    264        inherits: "false",
    265        "initial-value": JS_NO_INHERIT_INITIAL_VALUE,
    266      },
    267    }
    268  );
    269  await assertVariableTooltipForProperty(
    270    view,
    271    "h1",
    272    "width",
    273    // The variable value is the value set in the main selector, since the variable does inherit
    274    {
    275      header: JS_INHERIT_MAIN_VALUE,
    276      // Computed value isn't displayed when it's the same as we put in the header
    277      computed: null,
    278      registeredProperty: { syntax: `"*"`, inherits: "true" },
    279    }
    280  );
    281  await assertVariableTooltipForProperty(view, "h1", "--test-empty", {
    282    header: "&lt;empty&gt;",
    283    headerClasses: ["empty-css-variable"],
    284    registeredProperty: {
    285      syntax: `"*"`,
    286      inherits: "true",
    287      "initial-value": "&lt;empty&gt;",
    288    },
    289  });
    290 
    291  info(
    292    "Check that registered properties from new regular stylesheets are displayed"
    293  );
    294  let onRuleViewRefreshed = view.once("ruleview-refreshed");
    295  await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {
    296    const s = content.wrappedJSObject.document.createElement("style");
    297    s.id = "added";
    298    s.textContent = `
    299      @property --css-dynamic-registered {
    300        syntax: "<color>";
    301        inherits: false;
    302        initial-value: orchid;
    303      }
    304    `;
    305 
    306    content.wrappedJSObject.document.head.append(s);
    307  });
    308  info("Wait for the new registered property to be displayed");
    309  await onRuleViewRefreshed;
    310 
    311  checkRegisteredProperties(
    312    view,
    313    [
    314      ...expectedProperties,
    315      {
    316        header: `--css-dynamic-registered {`,
    317        propertyDefinition: [
    318          `  syntax: "<color>";`,
    319          `  inherits: false;`,
    320          `  initial-value: orchid;`,
    321        ],
    322      },
    323    ].sort((a, b) => (a.header < b.header ? -1 : 1))
    324  );
    325 
    326  // The var() tooltip should show the initial value of the new property
    327  await assertVariableTooltipForProperty(view, "h1", "caret-color", {
    328    header:
    329      // prettier-ignore
    330      `<span xmlns="http://www.w3.org/1999/xhtml" data-color="orchid" class="color-swatch-container">` +
    331        `<span ` +
    332          `class="inspector-swatch inspector-colorswatch" ` +
    333          `style="background-color:orchid">` +
    334        `</span>` +
    335        `<span class="ruleview-color">orchid</span>` +
    336      `</span>`,
    337    registeredProperty: {
    338      syntax: `"&lt;color&gt;"`,
    339      inherits: "false",
    340      "initial-value":
    341        // prettier-ignore
    342        `<span xmlns="http://www.w3.org/1999/xhtml" data-color="orchid" class="color-swatch-container">` +
    343          `<span ` +
    344            `class="inspector-swatch inspector-colorswatch" ` +
    345            `style="background-color:orchid">` +
    346          `</span>` +
    347          `<span class="ruleview-color">orchid</span>` +
    348        `</span>`,
    349    },
    350  });
    351 
    352  info("Check that updating property does update rules view");
    353  onRuleViewRefreshed = view.once("ruleview-refreshed");
    354  await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {
    355    content.wrappedJSObject.document.querySelector("style#added").textContent =
    356      `
    357      @property --css-dynamic-registered {
    358        syntax: "<color>";
    359        inherits: true;
    360        initial-value: purple;
    361      }
    362    `;
    363  });
    364  info("Wait for the rules view to be updated");
    365  await onRuleViewRefreshed;
    366 
    367  checkRegisteredProperties(
    368    view,
    369    [
    370      ...expectedProperties,
    371      {
    372        header: `--css-dynamic-registered {`,
    373        propertyDefinition: [
    374          `  syntax: "<color>";`,
    375          `  inherits: true;`,
    376          `  initial-value: purple;`,
    377        ],
    378      },
    379    ].sort((a, b) => (a.header < b.header ? -1 : 1))
    380  );
    381 
    382  // The var() tooltip should show the new initial value of the updated property
    383  await assertVariableTooltipForProperty(view, "h1", "caret-color", {
    384    header:
    385      // prettier-ignore
    386      `<span xmlns="http://www.w3.org/1999/xhtml" data-color="purple" class="color-swatch-container">` +
    387        `<span ` +
    388          `class="inspector-swatch inspector-colorswatch" ` +
    389          `style="background-color:purple">` +
    390        `</span>` +
    391        `<span class="ruleview-color">purple</span>` +
    392      `</span>`,
    393    registeredProperty: {
    394      syntax: `"&lt;color&gt;"`,
    395      inherits: "true",
    396      "initial-value":
    397        // prettier-ignore
    398        `<span xmlns="http://www.w3.org/1999/xhtml" data-color="purple" class="color-swatch-container">` +
    399          `<span ` +
    400            `class="inspector-swatch inspector-colorswatch" ` +
    401            `style="background-color:purple">` +
    402          `</span>` +
    403          `<span class="ruleview-color">purple</span>` +
    404        `</span>`,
    405    },
    406  });
    407 
    408  info("Check that removing property does update rules view");
    409  await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {
    410    content.wrappedJSObject.document.querySelector("style#added").remove();
    411  });
    412  info("Wait for registered property to be removed");
    413  await waitFor(
    414    () =>
    415      view.styleDocument.querySelector(
    416        `[data-name="--css-dynamic-registered"]`
    417      ) == null
    418  );
    419  ok(true, `--css-dynamic-registered was removed`);
    420  checkRegisteredProperties(view, expectedProperties);
    421 
    422  // The var() tooltip should indicate that the property isn't set anymore
    423  await assertVariableTooltipForProperty(view, "h1", "caret-color", {
    424    header: `--css-dynamic-registered is not set`,
    425    headerClasses: [],
    426    isMatched: false,
    427  });
    428 
    429  info(
    430    "Check that registered properties from new constructed stylesheets are displayed"
    431  );
    432  is(
    433    getRuleViewProperty(view, "h1", "outline").valueSpan.querySelector(
    434      ".inspector-unmatched"
    435    ).textContent,
    436    "--constructed",
    437    "The --constructed variable is set as unmatched since it's not defined nor registered"
    438  );
    439 
    440  onRuleViewRefreshed = view.once("ruleview-refreshed");
    441  await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {
    442    const s = new content.wrappedJSObject.CSSStyleSheet();
    443    s.replaceSync(`
    444      @property --constructed {
    445        syntax: "<color>";
    446        inherits: true;
    447        initial-value: aqua;
    448      }
    449    `);
    450    content.wrappedJSObject.document.adoptedStyleSheets.push(s);
    451  });
    452  await onRuleViewRefreshed;
    453 
    454  info("Wait for the new registered property to be displayed");
    455  checkRegisteredProperties(
    456    view,
    457    [
    458      ...expectedProperties,
    459      {
    460        header: `--constructed {`,
    461        propertyDefinition: [
    462          `  syntax: "<color>";`,
    463          `  inherits: true;`,
    464          `  initial-value: aqua;`,
    465        ],
    466      },
    467    ].sort((a, b) => (a.header < b.header ? -1 : 1))
    468  );
    469 
    470  // The `var()` tooltip should show the initial-value of the new property
    471  await assertVariableTooltipForProperty(view, "h1", "outline", {
    472    header:
    473      // prettier-ignore
    474      `<span xmlns="http://www.w3.org/1999/xhtml" data-color="aqua" class="color-swatch-container">` +
    475        `<span ` +
    476          `class="inspector-swatch inspector-colorswatch" ` +
    477          `style="background-color:aqua">` +
    478        `</span>` +
    479        `<span class="ruleview-color">aqua</span>` +
    480      `</span>`,
    481    registeredProperty: {
    482      syntax: `"&lt;color&gt;"`,
    483      inherits: "true",
    484      "initial-value":
    485        // prettier-ignore
    486        `<span xmlns="http://www.w3.org/1999/xhtml" data-color="aqua" class="color-swatch-container">` +
    487          `<span ` +
    488            `class="inspector-swatch inspector-colorswatch" ` +
    489            `style="background-color:aqua">` +
    490          `</span>` +
    491          `<span class="ruleview-color">aqua</span>` +
    492        `</span>`,
    493    },
    494  });
    495 
    496  info(
    497    "Check that selecting a node in another document with no registered property hides the container"
    498  );
    499  await selectNodeInFrames(["iframe", "body"], inspector);
    500  is(
    501    getRegisteredPropertiesContainer(view),
    502    null,
    503    "registered properties container isn't displayed"
    504  );
    505 
    506  info(
    507    "Check that registering a property will cause the @property container to be displayed"
    508  );
    509  const iframeBrowsingContext = await SpecialPowers.spawn(
    510    tab.linkedBrowser,
    511    [],
    512    () => content.document.querySelector("iframe").browsingContext
    513  );
    514 
    515  await SpecialPowers.spawn(iframeBrowsingContext, [], () => {
    516    content.CSS.registerProperty({
    517      name: "--js-iframe",
    518      syntax: "<color>",
    519      inherits: true,
    520      initialValue: "turquoise",
    521    });
    522    content.CSS.registerProperty({
    523      name: "--js-inherit",
    524      syntax: "*",
    525      inherits: true,
    526    });
    527  });
    528 
    529  await waitFor(() => getRegisteredPropertiesContainer(view));
    530  ok(true, "@property container is diplayed when registering a property");
    531 
    532  // Wait for the 2 properties to be added.
    533  await waitFor(() => getRegisteredPropertiesElements(view).length == 2);
    534  checkRegisteredProperties(view, [
    535    {
    536      header: `--js-iframe {`,
    537      propertyDefinition: [
    538        `  name: "--js-iframe",`,
    539        `  syntax: "<color>",`,
    540        `  inherits: true,`,
    541        `  initialValue: turquoise,`,
    542      ],
    543    },
    544    {
    545      header: `--js-inherit {`,
    546      propertyDefinition: [
    547        `  name: "--js-inherit",`,
    548        `  syntax: "*",`,
    549        `  inherits: true,`,
    550      ],
    551    },
    552  ]);
    553 
    554  info("Select a node from the top-level document");
    555  await selectNode("main", inspector);
    556 
    557  checkRegisteredProperties(
    558    view,
    559    [
    560      ...expectedProperties,
    561      {
    562        header: `--constructed {`,
    563        propertyDefinition: [
    564          `  syntax: "<color>";`,
    565          `  inherits: true;`,
    566          `  initial-value: aqua;`,
    567        ],
    568      },
    569    ].sort((a, b) => (a.header < b.header ? -1 : 1))
    570  );
    571 
    572  await selectNode("aside", inspector);
    573 
    574  info(
    575    "Check that the invalid at computed-value time icon is displayed when needed"
    576  );
    577  checkInvalidAtComputedValueTime(view, {
    578    ruleIndex: 1,
    579    declaration: { "--css-inherit": "dashed" },
    580    invalid: true,
    581    syntax: `<color>`,
    582  });
    583 
    584  info(
    585    "Check that the invalid at computed-value time icon is not displayed for valid properties"
    586  );
    587  checkInvalidAtComputedValueTime(view, {
    588    ruleIndex: 1,
    589    declaration: { "--js-no-inherit": "calc(100px * cos(45deg))" },
    590    invalid: false,
    591  });
    592 
    593  info(
    594    "Declaration of variable based on other variable are not marked as invalid"
    595  );
    596  checkInvalidAtComputedValueTime(view, {
    597    ruleIndex: 1,
    598    declaration: { "--css-dynamic-registered": "var(--css-no-inherit)" },
    599    invalid: false,
    600  });
    601 });
    602 
    603 function checkInvalidAtComputedValueTime(
    604  view,
    605  { ruleIndex, declaration, invalid, syntax }
    606 ) {
    607  const prop = getTextProperty(view, ruleIndex, declaration);
    608  const warningIcon = prop.editor.element.querySelector(
    609    ".ruleview-invalid-at-computed-value-time-warning:not([hidden])"
    610  );
    611  if (invalid) {
    612    ok(
    613      !!warningIcon,
    614      `invalid at computed-value time icon is displayed for ${JSON.stringify(
    615        declaration
    616      )}`
    617    );
    618    is(
    619      warningIcon?.title,
    620      `Property value does not match expected "${syntax}" syntax`,
    621      `invalid at computed-value time icon has expected title for ${JSON.stringify(
    622        declaration
    623      )}`
    624    );
    625  } else {
    626    ok(
    627      !warningIcon,
    628      `invalid at computed-value time icon is not displayed for ${JSON.stringify(
    629        declaration
    630      )}`
    631    );
    632  }
    633 }
    634 
    635 function getRegisteredPropertiesContainer(view) {
    636  return view.styleDocument.querySelector("#registered-properties-container");
    637 }
    638 
    639 function getRegisteredPropertiesElements(view) {
    640  const container = getRegisteredPropertiesContainer(view);
    641  if (!container) {
    642    return [];
    643  }
    644 
    645  return Array.from(
    646    container.querySelectorAll(
    647      "#registered-properties-container .ruleview-rule"
    648    )
    649  );
    650 }
    651 
    652 function checkRegisteredProperties(view, expectedProperties) {
    653  const registeredPropertiesEl = getRegisteredPropertiesElements(view);
    654 
    655  is(
    656    registeredPropertiesEl.length,
    657    expectedProperties.length,
    658    "There are the expected number of registered properties"
    659  );
    660  for (let i = 0; i < expectedProperties.length; i++) {
    661    info(`Checking registered property #${i}`);
    662    const { header, propertyDefinition } = expectedProperties[i];
    663    const registeredPropertyEl = registeredPropertiesEl[i];
    664 
    665    is(
    666      registeredPropertyEl.querySelector("header").textContent,
    667      header,
    668      `Registered property #${i} has the expected header text`
    669    );
    670    const propertyDefinitionEl = Array.from(
    671      registeredPropertyEl.querySelectorAll("div[role=listitem]")
    672    );
    673    is(
    674      propertyDefinitionEl.length,
    675      propertyDefinition.length,
    676      `Registered property #${i} have the expected number of items in its definition`
    677    );
    678    for (let j = 0; j < expectedProperties.length; j++) {
    679      is(
    680        propertyDefinitionEl[j]?.textContent,
    681        propertyDefinition[j],
    682        `Registered property #${i} have the expected definition at index #${j}`
    683      );
    684    }
    685  }
    686 }