chromium/third_party/blink/web_tests/http/tests/security/contentSecurityPolicy/frame-src-cross-origin-load.html

<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<meta http-equiv="Content-Security-Policy" content="frame-src 'self' http://localhost:8080">

<script>
async_test(t => {

  let test_urls = [
    "https://localhost:8443/security/contentSecurityPolicy/resources/post-message-fail.html",
    "/security/contentSecurityPolicy/resources/post-message-pass.html",
    "http://localhost:8080/security/contentSecurityPolicy/resources/post-message-pass.html"
  ];

  let num_messages = 0;
  let num_loads = 0;

  function maybe_finish() {
    if (num_messages == 2 && num_loads == 3) {
      t.done();
    }
  };

  function run_url(url) {
    let iframe = document.createElement('iframe');
    iframe.src = url;
    iframe.addEventListener('load', iframe_load);
    document.body.appendChild(iframe);
  };

  function iframe_load(e) {
    num_loads++;
    maybe_finish();
    if (test_urls.length > 0) {
      run_url(test_urls.shift());
    }
  };

  // We will only receive messages from content that actually loaded, which does
  // not include any blocked content. The messages are asynchronous, so there's
  // no way to know when we've waited "long enough" for a failure. This test is
  // best-effort, in that it loads the failure case first; so if we receive
  // "pass" messages for the subsequent iframes without receiving a "fail"
  // message, we can have high confidence that the blocked content didn't load.
  addEventListener('message', t.step_func(e => {
    num_messages++;
    assert_equals(e.data, 'PASS', 'Content from blocked frame should not load');
    maybe_finish();
  }));

  onload = () => { run_url(test_urls.shift()) };

}, "IFrames blocked by CSP should generate a 'load' event, regardless of blocked state. This means they appear to be normal cross-origin loads, thereby not leaking URL information directly to JS.");
</script>