wpt / css / css-sizing / responsive-iframe / responsive-iframe-allow-origins.html?origin=same,allow=parent,expect=400

Open test on wpt.live | wpt.fyi

Runs: Chrome 160.0.8162.0 (wpt@fa649586f, 2026-11-15) | Firefox 162.0a1 (wpt@fa649586f, 2026-11-15) | Safari 256 preview (wpt@fa649586f, 2026-11-15) | Ladybird 1.0-78c90 (wpt@c0f2b11f4, 2026-11-15) | Servo Servo 0.8 (wpt@76f3efc65, 2026-11-14) | Blitz ea07ee716 (wpt@bbb30d0f5, 2026-11-15)

ChromeFirefoxSafariLadybirdServoBlitz
Total1/10/10/10/10/10/1
SubtestChromeFirefoxSafariLadybirdServoBlitz
Allow origins check: container=parent, origin=same, allow=parentPASSTIMEOUTTIMEOUTTIMEOUTTIMEOUT—

/css/css-sizing/responsive-iframe/responsive-iframe-allow-origins.html

<!doctype HTML>
<title>Test allow-origins validation for responsive iframes</title>
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#responsive-iframes">
<link rel="author" href="mailto:kojii@chromium.org">
<meta name="variant" content="?origin=same,allow=star,expect=400">
<meta name="variant" content="?origin=same,allow=parent,expect=400">
<meta name="variant" content="?origin=same,allow=other,expect=150">
<meta name="variant" content="?origin=same,allow=wildcard,expect=150">
<meta name="variant" content="?origin=same,allow=http,expect=400">
<meta name="variant" content="?origin=same,allow=https,expect=150">
<meta name="variant" content="?origin=same,allow=self,expect=400">
<meta name="variant" content="?origin=same,allow=none,expect=150">
<meta name="variant" content="?origin=same,allow=multiple,expect=400">
<meta name="variant" content="?origin=same,allow=no-prefix,expect=150">
<meta name="variant" content="?origin=same,allow=invalid-prefix,expect=150">
<meta name="variant" content="?origin=same,allow=uppercase-prefix,expect=150">
<meta name="variant" content="?origin=same,allow=space,expect=150">
<meta name="variant" content="?origin=same,allow=empty,expect=150">
<meta name="variant" content="?origin=same,allow=missing,expect=150">
<meta name="variant" content="?origin=cross,allow=star,expect=400">
<meta name="variant" content="?origin=cross,allow=parent,expect=400">
<meta name="variant" content="?origin=cross,allow=child,expect=150">
<meta name="variant" content="?origin=cross,allow=self,expect=150">
<meta name="variant" content="?origin=cross,allow=other,expect=150">
<meta name="variant" content="?origin=subdomain,allow=star,expect=400">
<meta name="variant" content="?origin=subdomain,allow=parent,expect=400">
<meta name="variant" content="?origin=subdomain,allow=child,expect=150">
<meta name="variant" content="?container=subdomain,origin=same,allow=wildcard,expect=400">
<meta name="variant" content="?container=subdomain,origin=cross,allow=wildcard,expect=400">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="/common/rendering-utils.js"></script>
<style>
iframe {
  border: 0;
  frame-sizing: content-height;
}
</style>
<body>
<script>
const hostInfo = get_host_info();
// TODO(crbug.com/479970848): Chromium bots don't support '&'.
const search = location.search.replace(/,/g, '&');
const params = new URLSearchParams(search);
const containerType = params.get('container') || 'parent';
const originType = params.get('origin') || 'same';
const allowType = params.get('allow') || 'other';
const expectedHeight = parseInt(params.get('expect') || '150');
const paramsDesc = `container=${containerType}, origin=${originType}, allow=${allowType}`;
const currentContainerOrigin = location.origin;

function computeAllowParam() {
  switch (allowType) {
    case 'star': return 'allow-origins=*';
    case 'parent': return 'allow-origins=' + currentContainerOrigin;
    case 'child':
      switch (originType) {
        case 'cross': return 'allow-origins=' + hostInfo.HTTP_NOTSAMESITE_ORIGIN;
        case 'subdomain': return 'allow-origins=' + hostInfo.HTTP_REMOTE_ORIGIN;
      }
      return 'allow-origins=' + currentContainerOrigin;
    case 'other': return 'allow-origins=https://invalid-origin.example';
    case 'wildcard': return 'allow-origins=http://*.' + hostInfo.ORIGINAL_HOST + ':' + hostInfo.HTTP_PORT;
    case 'http': return 'allow-origins=http:';
    case 'https': return 'allow-origins=https:';
    case 'self': return "allow-origins='self'";
    case 'none': return "allow-origins='none'";
    case 'multiple': return 'allow-origins=https://invalid-origin.example ' + currentContainerOrigin;
    case 'no-prefix': return '*';
    case 'invalid-prefix': return 'alloworigins=*';
    case 'uppercase-prefix': return 'ALLOW-ORIGINS=*';
    case 'space': return 'allow-origins= ';
    case 'empty': return 'allow-origins=';
    default: return '';
  }
}

function waitForHeight(t, element, targetHeight) {
  if (element.offsetHeight === targetHeight) {
    return Promise.resolve();
  }
  return new Promise(resolve => {
    const observer = new ResizeObserver(() => {
      if (element.offsetHeight === targetHeight) {
        observer.disconnect();
        resolve();
      }
    });
    t.add_cleanup(() => observer.disconnect());
    observer.observe(element);
  });
}

if (containerType === 'subdomain' && location.origin !== hostInfo.HTTP_REMOTE_ORIGIN) {
  location.href = hostInfo.HTTP_REMOTE_ORIGIN + location.pathname + location.search;
} else {
  async_test(t => {
    const iframe = document.createElement('iframe');
    iframe.frameBorder = '0';
    iframe.scrolling = 'no';

    const fileName = (allowType === 'missing')
        ? 'iframe-contents-allow-origins-missing.html'
        : 'iframe-contents-allow-origins.sub.html';
    const resourcePath = new URL(`resources/${fileName}`, window.location.href).pathname;
    const allowParam = computeAllowParam();
    const query = (allowType === 'missing') ? '' : `?allow=${encodeURIComponent(allowParam)}`;
    let iframeSrc = resourcePath + query;
    if (originType === 'cross') {
      iframeSrc = hostInfo.HTTP_NOTSAMESITE_ORIGIN + resourcePath + query;
    } else if (originType === 'subdomain') {
      iframeSrc = hostInfo.HTTP_REMOTE_ORIGIN + resourcePath + query;
    }

    iframe.src = iframeSrc;
    iframe.addEventListener('load', t.step_func(async () => {
      try {
        if (iframe.contentWindow && iframe.contentWindow.location.href === 'about:blank') {
          return;
        }
      } catch (e) {
        // Cross-origin iframe accesses `location.href` with `SecurityError`,
        // which means it loaded target URL.
      }
      if (expectedHeight !== 150) {
        await waitForHeight(t, iframe, expectedHeight);
      } else {
        await waitForAtLeastOneFrame();
        if (originType !== 'same') {
          await waitForAtLeastOneFrame();
        }
      }
      t.step(() => {
        assert_equals(iframe.offsetHeight, expectedHeight,
          `iframe height should be ${expectedHeight}px for ${paramsDesc}`);
      });
      t.done();
    }));

    document.body.appendChild(iframe);
  }, `Allow origins check: ${paramsDesc}`);
}
</script>
</body>