chromium/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-samesite-cookies.js

(async function(/** @type {import('test_runner').TestRunner} */ testRunner) {
  const {page, session, dp} = await testRunner.startBlank(
      `Tests that fetch exposes cookies according to SameSite rules.`);

  const FetchHelper = await testRunner.loadScript('resources/fetch-test.js');
  const helper = new FetchHelper(testRunner, testRunner.browserP());
  await helper.enable();

  helper.onceRequest(/setcookies.a.test/).fulfill({
    responseCode: 200,
    responseHeaders: [
      {name: 'Set-Cookie', value: 'StrictCookie=1; Secure; SameSite=Strict; Domain=a.test'},
      {name: 'Set-Cookie', value: 'LaxCookie=1; Secure; SameSite=Lax; Domain=a.test'},
      {name: 'Set-Cookie', value: 'NoneCookie=1; Secure; SameSite=None; Domain=a.test'},
      {name: 'Set-Cookie', value: 'UnspecifiedCookie=1; Secure; Domain=a.test'}
    ],
    body: btoa("<html></html>")
  });

  await dp.Page.enable();
  await session.navigate('https://setcookies.a.test/');

  // URL whose cookies are dumped in the following tests.
  const cookieUrl = 'https://a.test/';

  // Set up redirect to a.test from any URL containing 'redirect'.
  helper.onRequest(/redirect/).fulfill({
    responseCode: 302,
    responseHeaders: [{name: 'Location', value: cookieUrl}]
  });

  // Returns a string containing a script to append an iframe to the DOM.
  function appendIframeScript(url) {
    // This may run before or after the page is fully loaded, so account for
    // both cases to avoid flakiness.
    return `
        function appendIframe() {
          var frame = document.createElement('iframe');
          frame.src = '${url}';
          document.body.appendChild(frame);
        }
        window.onload = appendIframe;
        if (document.readyState === 'complete')
          appendIframe();`
  }

  // Navigates to `fromUrl`, then navigates to a.test and dumps cookies that
  // were sent.
  async function navigateAndDumpCookies(fromUrl, description) {
    // Navigate to the starting location.
    helper.onceRequest(new RegExp(fromUrl)).fulfill({
      responseCode: 200,
      body: btoa("<html></html>")
    });
    await dp.Page.navigate({url: fromUrl});
    // Navigate to a.test.
    session.evaluate(`location.href = '${cookieUrl}'`);
    const request = await helper.onceRequest(cookieUrl).matched();
    testRunner.log(`Cookies after ${description}:`);
    testRunner.log(request.request.headers['Cookie']);
    dp.Fetch.fulfillRequest({requestId: request.requestId, responseCode: 200});
  }

  // Navigates to `mainUrl`, then loads a.test in an iframe and dumps cookies
  // that were sent.
  async function loadIframeAndDumpCookies(mainUrl, description) {
    // Navigate to the main page URL.
    helper.onceRequest(new RegExp(mainUrl)).fulfill({
      responseCode: 200,
      body: btoa("<html></html>")
    });
    await dp.Page.navigate({url: mainUrl});
    // Load iframe with a.test.
    session.evaluate(appendIframeScript(cookieUrl));
    const request = await helper.onceRequest(cookieUrl).matched();
    testRunner.log(`Cookies for ${description}:`);
    testRunner.log(request.request.headers['Cookie']);
    dp.Fetch.fulfillRequest({requestId: request.requestId, responseCode: 200});
  }

  // Navigates to `fromUrl`, then navigates to `redirectUrl`, which then
  // redirects to a.test and dumps cookies that were sent.
  // `redirectUrl` must match the pattern /redirect/.
  async function redirectAndDumpCookies(fromUrl, redirectUrl, description) {
    helper.onceRequest(new RegExp(fromUrl)).fulfill({
      responseCode: 200,
      body: btoa("<html></html>")
    });
    // Navigate to the starting location.
    await dp.Page.navigate({url: fromUrl});
    // Navigate to `redirectUrl` which then redirects to a.test.
    session.evaluate(`location.href = '${redirectUrl}'`);
    const request = await helper.onceRequest(cookieUrl).matched();
    testRunner.log(`Cookies for ${description}:`);
    testRunner.log(request.request.headers['Cookie']);
    dp.Fetch.fulfillRequest({requestId: request.requestId, responseCode: 200});
  }

  // Navigates to `mainUrl`, then loads `redirectUrl` in an iframe. The iframe
  // then redirects to a.test and dumps cookies that were sent.
  // `redirectUrl` must match the pattern /redirect/.
  async function redirectInIframeAndDumpCookies(mainUrl, redirectUrl, description) {
    helper.onceRequest(new RegExp(mainUrl)).fulfill({
      responseCode: 200,
      body: btoa("<html></html>")
    });
    // Navigate to the main page URL.
    await dp.Page.navigate({url: mainUrl});
    // Load an iframe with `redirectUrl` which then redirects to a.test.
    session.evaluate(appendIframeScript(redirectUrl));
    const request = await helper.onceRequest(cookieUrl).matched();
    testRunner.log(`Cookies for ${description}:`);
    testRunner.log(request.request.headers['Cookie']);
    dp.Fetch.fulfillRequest({requestId: request.requestId, responseCode: 200});
  }

  await navigateAndDumpCookies('https://subdomain.a.test/', 'same-site navigation');
  await navigateAndDumpCookies('https://b.test/', 'cross-site navigation');
  await loadIframeAndDumpCookies('https://subdomain.a.test/', 'same-site iframe');
  await loadIframeAndDumpCookies('https://b.test/', 'cross-site iframe');
  await redirectAndDumpCookies('https://subdomain.a.test/', 'https://redirect.a.test/', 'same-site initiated same-site redirect');
  await redirectAndDumpCookies('https://subdomain.a.test/', 'https://redirect.b.test/', 'same-site initiated cross-site redirect');
  await redirectAndDumpCookies('https://b.test/', 'https://redirect.a.test/', 'cross-site initiated same-site redirect');
  await redirectAndDumpCookies('https://b.test/', 'https://redirect.b.test/', 'cross-site initiated cross-site redirect');
  await redirectInIframeAndDumpCookies('https://subdomain.a.test/', 'https://redirect.a.test/', 'same-site embedded same-site redirect');
  await redirectInIframeAndDumpCookies('https://subdomain.a.test/', 'https://redirect.b.test/', 'same-site embedded cross-site redirect');
  await redirectInIframeAndDumpCookies('https://b.test/', 'https://redirect.a.test/', 'cross-site embedded same-site redirect');
  await redirectInIframeAndDumpCookies('https://b.test/', 'https://redirect.b.test/', 'cross-site embedded cross-site redirect');

  testRunner.completeTest();
})