chromium/third_party/blink/web_tests/custom-elements/gc.html

<!DOCTYPE html>
<script src="../resources/gc.js"></script>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<body>
<script>
'use strict';
(() => {

if (!window.internals) {
  // Requires observeGC
  return;
}

promise_test((t) => {
  var observation = null;
  (() => {
    let f = document.createElement('iframe');
    f.srcdoc = 'content';
    document.body.appendChild(f);
    let w = f.contentWindow;

    var X = new Object;
    X.a = [f, w, w.customElements, w.document];
    X.a.forEach((o) => o.x = X);
    observation = internals.observeGC(X);

    f.remove();
  })();

  return asyncGC().then(() => {
    assert_true(observation.wasCollected,
                'cyclic references between objects and DOM wrappers should ' +
                'not leak');
  });
}, 'Sanity check ordinary objects are not leaking');

promise_test((t) => {
  var observation = null;
  (() => {
    let f = document.createElement('iframe');
    f.srcdoc = 'content';
    document.body.appendChild(f);
    let w = f.contentWindow;

    class X extends HTMLElement {}
    X.a = [f, w, w.customElements, w.document];
    X.a.forEach((o) => o.x = X);
    w.customElements.define('a-a', X);
    observation = internals.observeGC(X);

    f.remove();
  })();

  return asyncGC().then(() => {
    assert_true(observation.wasCollected,
                'defining a custom element should not leak its constructor');
  });
}, 'Defining custom elements does not leak');

})();
</script>