chromium/third_party/blink/web_tests/wpt_internal/web-locks/storage-deprecation-trial-enabled.https.html

<!DOCTYPE html>
<meta charset="utf-8"/>
<title>Web Locks API: Partitioned WebLocks</title>

<!-- Pull in get_host_info() -->
<script src="/common/get-host-info.sub.js"></script>
<script src="/common/utils.js"></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="resources/helpers.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>

// NOTE: this test is based on the external WPT found at:
// third_party/blink/web_tests/external/wpt/web-locks/partitioned-web-locks.tentative.https.html
// This test changes the assertions to ensure that when the
// deprecation trial is enabled, web-locks in third-party contexts
// under the top-level site that registered for the trial are
// unpartitioned. Also, it uses separate copies of partitioned-parent.html
// so that we can set origin trial tokens on them (since one test uses it
// with web-platform.test and the other uses it with not-web-platform.test).
// These tokens were generated via:
// - tools/origin_trials/generate_token.py https://web-platform.test:8444
//   DisableThirdPartyStoragePartitioning2 --expire-timestamp=2000000000
// - tools/origin_trials/generate_token.py https://not-web-platform.test:8444
//   DisableThirdPartyStoragePartitioning2 --expire-timestamp=2000000000

// How this test works:
// Step 1 (top-frame): request an exclusive web-lock and store its id
// and release for clean-up.
// Step 2 (top-frame): open a pop-up window and load a not-same-site
// ./resources/partitioned-parent-copy-not-same-site.html.
// Step 3 (pop-up): load a same-site iframe inside the pop-up.
// Step 4 (pop-up): send a web-lock request to the same-site iframe.
// Step 5 (iframe): process the web-lock request and message the result
// back to the pop-up.
// Step 6 (pop-up): intercept the result message from the iframe and
// send it to the top-frame.
// Step 7 (top-frame): ensure that the same-site iframe's web-lock
// request failed since it and the top-level site are in the same
// partition and an exclusive lock has already been granted.
// Step 8 (top-frame): clean up.

const { HTTPS_ORIGIN, HTTPS_NOTSAMESITE_ORIGIN } = get_host_info();
// Map of lock_id => function that releases a lock.
const held = new Map();
let next_lock_id = 1;

async function third_party_test(t) {
  let target_url = HTTPS_ORIGIN + '/web-locks/resources/iframe.html';
  target_url = new URL(
    `./resources/partitioned-parent-copy-not-same-site.html?target=${encodeURIComponent(target_url)}`,
    HTTPS_NOTSAMESITE_ORIGIN + self.location.pathname);

  // Step 1.
  navigator.locks.request('testLock', {mode: 'exclusive', ifAvailable: true},
        lock => {
          if (lock === null) {
            assert_true(false)
            return;
          }
          let lock_id = next_lock_id++;
          let release;
          const promise = new Promise(r => { release = r; });
          held.set(lock_id, release);
          return promise;
        });

  // Step 2.
  const w = window.open(target_url);
  const result = await new Promise(resolve => window.onmessage = resolve);

  // Step 7.
  // With third-party storage partitioning disabled, the same-site iframe
  // lives in the same partition as the previously acquired lock, so an
  // additional lock is not granted.
  assert_equals(result.data.failed, true);

  // Step 8.
  t.add_cleanup(() => {
    w.close()
    for(let i = 1; i < next_lock_id; i++){
      held.get(i)();
    }
  });
}

promise_test(t => {
  return third_party_test(t);
}, 'WebLocks are not partitioned when deprecation trial is enabled');


// Optional Test: Checking for partitioned web locks in an A->B->A
// (nested-iframe with cross-site ancestor chain) scenario.

// How this test works:
// Nested Step 1 (top frame): request an exclusive web-lock and
// store its id and release for clean-up.
// Nested Step 2 (top frame): open a pop-up window and load a
// same-site ./resources/partitioned-parent-copy-same-site.html.
// Nested Step 3 (pop-up): load a not-same-site "parent" iframe (A->B)
// (/web-locks/resources/iframe-parent.html) inside the pop-up.
// Nested Step 4 (pop-up): send a web-lock request to the parent iframe.
// Nested Step 5 (parent iframe): load a "child" iframe (A->B->A)
// (/web-locks/resources/iframe.html) that is same-site with the
// pop-up inside the "parent" iframe.
// Nested Step 6 (parent iframe): pass on the web-lock request message to
// the "child" iframe.
// Nested Step 7 (child iframe): process the web-lock request and message
// the result to the parent iframe.
// Nested Step 8 (parent iframe): intercept the result message from the
// child iframe and send it to the pop-up.
// Nested Step 9 (pop-up): intercept the result message from the parent
// iframe and send it to the top frame.
// Nested Step 10 (top frame): ensure that the same-site iframe's web-lock
// request failed since it and the top-level site are in the same
// partition and an exclusive lock has already been granted.
// Nested Step 11 (top frame): clean up.

// Map of lock_id => function that releases a lock.
const held_2 = new Map();
let next_lock_id_2 = 1;

async function nested_iframe_test(t) {
  // Create innermost child iframe (leaf).
  let leaf_url = HTTPS_ORIGIN + '/web-locks/resources/iframe.html';
  // Wrap the child iframe in its cross-origin parent (middle).
  let middle_url = new URL(
    `/web-locks/resources/iframe-parent.html?target=${encodeURIComponent(leaf_url)}`,
    HTTPS_NOTSAMESITE_ORIGIN + self.location.pathname);
  // Embed the parent iframe in the top-level site (top).
  let top_url = new URL(
    `./resources/partitioned-parent-copy-same-site.html?target=${encodeURIComponent(middle_url)}`,
    HTTPS_ORIGIN + self.location.pathname);

  // Nested Step 1.
  // Request the weblock for the top-level site.
  navigator.locks.request('testLock', {mode: 'exclusive', ifAvailable: true},
        lock => {
          if (lock === null) {
            assert_true(false)
            return;
          }
          // Obtain and store the release functions for clean-up.
          let lock_id = next_lock_id_2++;
          let release;
          const promise = new Promise(r => { release = r; });
          held_2.set(lock_id, release);
          return promise;
        }).catch(error => alert(error.message));

  // Nested Step 2.
  // Open the nested iframes. The script in the innermost child iframe
  // will attempt to obtain the same weblock as above.
  const w = window.open(top_url);
  const result = await new Promise(resolve => window.onmessage = resolve);

  // Nested Step 10.
  // With third-party storage partitioning disabled, the same-site iframe
  // lives in the same partition as the previously acquired lock, so an
  // additional lock is not granted.
  assert_equals(result.data.failed, true);

  // Nested Step 11.
  t.add_cleanup(() => {
    w.close()
    for(let i = 1; i < next_lock_id_2; i++){
      held_2.get(i)();
    }
  });
}

promise_test(t => {
  return nested_iframe_test(t);
}, 'WebLocks of a nested iframe with a cross-site ancestor are not partitioned when deprecation trial is enabled');
</script>
</body>