tree: 5837b3f33b133f54374e1ae6695dba2508b697f3 [path history] [tgz]
  1. resources/
  2. add-fencedframe-to-detached-iframe.https.html
  3. ancestor-throttle.https.html
  4. anchor-focus.https.html
  5. autofocus-denied.https.html
  6. automatic-beacon-anchor-click-handler.https.html
  7. automatic-beacon-click-handler.https.html
  8. automatic-beacon-component-ad.https.html
  9. automatic-beacon-cross-origin-false.https.html
  10. automatic-beacon-cross-origin-navigation.https.html
  11. automatic-beacon-cross-origin-no-data.https.html
  12. automatic-beacon-cross-origin-no-opt-in.https.html
  13. automatic-beacon-no-destination.https.html
  14. automatic-beacon-no-opt-in.https.html
  15. automatic-beacon-shared-storage.https.html
  16. automatic-beacon-two-events-clear.https.html
  17. automatic-beacon-two-events-persist.https.html
  18. automatic-beacon-unfenced-top.https.html
  19. automatic-beacon-use-ancestor-data.https.html
  20. background-fetch.https.html
  21. background-sync.https.html
  22. badging.https.html
  23. battery_status.https.html
  24. before-unload.https.html
  25. can-load-api.https.html
  26. change-src-attribute-after-config-installation-does-not-trigger-navigation.https.html
  27. client-hints-meta.https.html
  28. client-hints.https.html
  29. client-hints.https.html.headers
  30. compute-pressure.https.html
  31. config-cross-origin-apis.https.html
  32. config-installation-triggers-navigation-of-navigated-fenced-frame.https.html
  33. config-installation-triggers-navigation.https.html
  34. config-with-empty-url-installation-unloads-navigated-fenced-frame.https.html
  35. consume-user-activation.https.html
  36. content-index.https.html
  37. coop-bcg-swap.https.html
  38. create-credential.https.html
  39. create-in-sandbox-and-adopt-outside-sandbox.https.html
  40. csp-allowed.https.html
  41. csp-blocked.https.html
  42. csp-fenced-frame-src-allowed.https.html
  43. csp-fenced-frame-src-blocked.https.html
  44. csp-frame-src-allowed.https.html
  45. csp-frame-src-blocked.https.html
  46. csp-transparent-url.https.html
  47. csp.https.html
  48. cspee.https.html
  49. deep-copy-config.https.html
  50. default-enabled-features-allow-all.https.html
  51. default-enabled-features-allow-all.https.html.headers
  52. default-enabled-features-allow-none.https.html
  53. default-enabled-features-allow-none.https.html.headers
  54. default-enabled-features-allow-self.https.html
  55. default-enabled-features-allow-self.https.html.headers
  56. default-enabled-features-allow-unspecified.https.html
  57. default-enabled-features-attribute-allow.https.html
  58. default-enabled-features-attribute-change.https.html
  59. default-enabled-features-attribute-disallow.https.html
  60. default-enabled-features-attribution-disabled.https.html
  61. default-enabled-features-attribution-disabled.https.html.headers
  62. default-enabled-features-subframe.https.html
  63. default-enabled-features-unset.https.html
  64. default-enabled-features-unset.https.html.headers
  65. deprecated-config-apis.https.html
  66. disable-untrusted-network.https.html
  67. disallowed-navigation-to-blob.https.html
  68. disallowed-navigation-to-data.https.html
  69. disallowed-navigation-to-http.https.html
  70. disallowed-navigations-dangling-markup-urn.https.html
  71. disallowed-navigations-dangling-markup.https.html
  72. disallowed-navigations.https.html
  73. document-activeelement.https.html
  74. document-hasfocus.https.html
  75. document-picture-in-picture-denied.https.html
  76. document-referrer.https.html
  77. download.https.html
  78. embedder-coop-coep-blocked.https.html
  79. embedder-coop-coep-blocked.https.html.headers
  80. embedder-csp-not-propagate.https.html
  81. embedder-no-coep.https.html
  82. embedder-require-corp.https.html
  83. embedder-require-corp.https.html.headers
  84. fedcm-get-credential.https.html
  85. fence-api.https.html
  86. fence-report-event-destination-url.https.html
  87. fence-report-event.https.html
  88. fence-urn-iframes.https.html
  89. fledge-container-size-mutation-observer.https.html
  90. fledge-container-size.https.html
  91. fragment-navigation.https.html
  92. frame-navigation.https.html
  93. gamepad.https.html
  94. get-mode-in-nested-frame.https.html
  95. get-nested-configs.https.html
  96. header-referrer.https.html
  97. header-secFetchDest.https.html
  98. hid.https.html
  99. history-back-and-forward-should-not-work-in-fenced-tree.https.html
  100. history-length-fenced-navigations-replace-do-not-contribute-to-joint.https.html
  101. history-length-outer-page-navigation-not-reflected-in-fenced.https.html
  102. ignore-child-fenced-frame-onload-event.https.html
  103. insecure-context.html
  104. intersection-observer.https.html
  105. invalid-url.https.html
  106. key-scrolling.https.html
  107. key-value-store.https.html
  108. load-ad-with-size.https.html
  109. loading.https.html
  110. location-ancestorOrigins.https.html
  111. mediaDevices-setCaptureHandle.https.html
  112. multiple-component-ads.https.html
  113. navigate-ancestor-by-name.https.html
  114. navigate-ancestor-nested-fenced-frame.https.html
  115. navigate-ancestor-nested-iframe.https.html
  116. navigate-ancestor-top-level-fenced-frame.https.html
  117. navigate-by-name-succeed.https.html
  118. navigate-descendant-by-name.https.html
  119. navigate-related-page-by-name.https.html
  120. navigator-keyboard-layout-map.https.html
  121. navigator-keyboard-lock.https.html
  122. navigator-subapp.https.html
  123. navigator-vibrate.https.html
  124. navigator-virtualkeyboard.https.html
  125. nested-opaque-ad-sizes.https.html
  126. notification.https.html
  127. notify-event-iframe.https.html
  128. notify-event-invalid.https.html
  129. notify-event-nested-fenced-frames.https.html
  130. notify-event-success.https.html
  131. notify-event-transient-user-activation.https.html
  132. opaque-ad-sizes-exact-size.https.html
  133. opaque-ad-sizes-special-cases.https.html
  134. payment-handler.https.html
  135. payment-request.https.html
  136. permission-api-denied-non-standard.https.html
  137. permission-api-denied.https.html
  138. permission-geolocation.https.html
  139. permission-notification.https.html
  140. picture-in-picture.https.html
  141. popup-noopener.https.html
  142. prerender.https.html
  143. presentation-receiver.https.html
  144. README.md
  145. reinsert.https.html
  146. report-event-inactive-document.https.html
  147. report-event-reserved-event.https.html
  148. report-event-sandboxed-iframe.https.html
  149. resize-lock-input.https.html
  150. resize-lock-zoom.https.html
  151. resize-lock.https.html
  152. resolve-to-config-promise.https.html
  153. revoke-nested-fenced-frame-in-iframe-navigation.https.html
  154. revoke-nested-fenced-frame-navigation.https.html
  155. revoke-popup.https.html
  156. revoke-unfenced-top-navigation.https.html
  157. sandbox-attribute.https.html
  158. sandbox-mandatory-flags.https.html
  159. sandboxed-features-alert.https.html
  160. sandboxed-features-confirm.https.html
  161. sandboxed-features-documentdomain.https.html
  162. sandboxed-features-pointerlock.https.html
  163. sandboxed-features-presentation-request.https.html
  164. sandboxed-features-printdialog.https.html
  165. sandboxed-features-prompt.https.html
  166. sandboxed-features-screen-orientation-lock.https.html
  167. script-focus.https.html
  168. scroll-into-view.https.html
  169. selecturl-flexible-size.https.html
  170. self-urn-navigation.https.html
  171. serviceWorker-dedicated-worker.https.html
  172. serviceWorker-frameType.https.html
  173. serviceWorker-push.https.html
  174. set-automatic-beacon.https.html
  175. setting-null-config-navigates-to-about-blank.https.html
  176. show-directory-picker.https.html
  177. show-open-file-picker.https.html
  178. storage-partitioning.https.html
  179. subframe-loading.https.html
  180. unique-cookie-partition.https.html
  181. user-activation.https.html
  182. visual-viewport.https.html
  183. web-bluetooth.https.html
  184. web-nfc.https.html
  185. web-share.https.html
  186. web-usb.https.html
  187. window-close.https.html
  188. window-frameElement.https.html
  189. window-navigation-204.https.html
  190. window-outer-dimensions.https.html
  191. window-parent.https.html
  192. window-top.https.html
fenced-frame/README.md

Fenced Frames

This directory contains Web Platform Tests for the Fenced Frames feature.).

In general, these tests should follow Chromium's web tests guidelines and web-platform-tests guidelines. This document describes how to use the specific fenced frame testing infrastructure.

How to run tests

Fenced frames feature needs to be enabled to run tests. A convenient way to do this is to define the following variable for fenced frames virtual test suites directories.

export MPTEST=virtual/fenced-frame-mparch/external/wpt/fenced-frame

Then run tests under the virtual test suite. This will include necessary fenced frame flags.

third_party/blink/tools/run_web_tests.py -t Default $MPTEST/test-name.https.html

How to write tests

The <fencedframe> element has a strict requirement that it cannot directly communicate with or reach its embedder document. The fenced frame does have network access however, so we can use a server as a middleman to communicate with the outer page. There are two main test patterns we use: remote execution (recommended) and message passing (deprecated).

Remote execution

Remote execution uses the helper attachFencedFrameContext() defined in resources/utils.js, which requires /common/dispatcher/dispatcher.js and /common/utils.js. This returns a fenced frame that is wrapped with additional functionality from RemoteContext, which allows you to perform a remote procedure call into the frame using the function execute(function, [arguments]=[]).

This interface allows us to write an entire test in only one file, with minimal boilerplate and an obvious control flow between all the frames on the page (including nested fenced frames, which can be achieved with nested execute calls).

Let's see an example of communication between the top-level frame and the fenced frame.

promise_test(async () => {
  const important_value = "Hello";

  // First, create an empty fenced frame.
  const frame = attachFencedFrameContext();

  // Next, make a function call into the frame, passing a particular string
  // "Hello" as an argument. Make sure to `await` the call.
  const response = await frame.execute((message_from_embedder) => {

    // This code runs inside the fenced frame.
    if (message_from_embedder == "Hello") {
      // Message that we received was expected.
      return "Hello to you too");
    } else {
      // Message that we received was *not* expected, let's report an error to
      // the outer page so it fails the test.
      return "Unexpected message";
    }

  }, [important_value]);

  // Assert that the returned value was what we expected.
  // Keep in mind that in a less contrived example, you can perform this assert
  // inside the fenced frame.
  assert_equals(response, "Hello to you too",
      "The fenced frame received the message, and said hello back to us".)
}, "Fenced frame and receive and send a greeting");

For test examples, see document-referrer.https.html, hid.https.html, or web-usb.https.html.

Some tips to keep in mind while writing tests using remote execution:

  • The functions attachFencedFrameContext() and attachIFrameContext() optionally take a dictionary of configs as an argument. You can use it to pass:
    • The API you want to use to generate the fenced frame urn. Either 'fledge', 'sharedstorage', or default (case-insensitive). When you use this option, the return value becomes a promise so you must await it.For example:
      await attachFencedFrameContext({generator_api: 'fledge'});
      
    • HTML source code to inject into the frame's DOM tree. For example:
      attachFencedFrameContext({html: '<button id="Button">Click me!</button>'});
      
    • Response headers. For example:
      attachFencedFrameContext({headers: [["Content-Security-Policy", "frame-src 'self'"]]});
      
    • Attributes to set on the frame. For example:
      attachIFrameContext({attributes: [["csp", "frame-src 'self'"]]})
      
    • Origin of the url to allow cross-origin test. For example:
      attachIFrameContext({origin:get_host_info().HTTPS_REMOTE_ORIGIN})
      
    • Number of ad components to create the frame with. Note that this only works with generator_api: 'fledge'. Protected Audience supports up to 20 ad components per auction.
      attachFencedFrameContext({num_components: 1});
      attachIFrameContext({num_components: 20});
      
      After creating the frame with ad components, the ad component frame won't be created until you explicitly call a special creator from within the frame.
      attachComponentFencedFrameContext(0, {html: "<b>Hello, world!</b>"});
      attachComponentIFrameContext(19);
      
      This takes in an index, and, optionally, the html and attributes fields as described above.
  • There is also a helper attachIFrameContext(), which does the same thing but for iframes instead of fencedframes.
  • There is also a helper replaceFrameContext(frame, {options}) which will replace an existing frame context using the same underlying element (i.e., you can use it to test when happens when you navigate an existing frame).
  • Make sure to await the result of an execute call, even if it doesn't return anything.
  • In order to save a global variable, you need to explicitly assign to window.variable_name. Assigning to variable_name without declaring it will not persist across execute calls. This is especially important for tests with nested frames, if you want to keep a handle to the nested frame across multiple calls.
  • Remember to declare the function passed to execute as async if it itself needs to invoke any async functions, including to create nested frames.

Message passing (deprecated)

Message passing is done by using the helpers defined in resources/utils.js to send a message to the server, and poll the server for a response. All messages have a unique key associated with them so that documents that want to receive messages can poll the server for a given message that can be identified by a unique key.

Let's see an example of sending a message to the server that a fenced frame will receive and respond to.

outer-page.js:

promise_test(async () => {
  const important_message_key = token();
  const fenced_frame_ack_key = token();
  const important_value = "Hello";

  // First, let's embed a new fenced frame in our test, and pass the key we
  // just created into it as a parameter.
  const frame_url = generateURL("resources/page-inner.html",
      [important_message_key, fenced_frame_ack_key]);
  attachFencedFrame(frame_url);

  // Then, let's send the message over to the fenced frame.
  writeValueToServer(important_message_key, important_value);

  // Now that the message has been sent to the fenced frame, let's wait for its
  // ACK, so that we don't exit the test before the fenced frame gets the
  // message.
  const response_from_fenced_frame = await
      nextValueFromServer(fenced_frame_ack_key);
  assert_equals(response_from_fenced_frame, "Hello to you too",
      "The fenced frame received the message, and said hello back to us");
}, "Fenced frame and receive and send a greeting");

inner-fenced-frame.js:

async function init() { // Needed in order to use top-level await.
  const [important_message_key, fenced_frame_ack_key] = parseKeylist();
  const greeting_from_embedder = await nextValueFromServer(important_message_key);

  if (greeting_from_embedder == "Hello") {
    // Message that we received was expected.
    writeValueToServer(fenced_frame_ack_key, "Hello to you too");
  } else {
    // Message that we received was *not* expected, let's report an error to the
    // outer page so it fails the test.
    writeValueToServer(fenced_frame_ack_key, "Unexpected message");
  }
}

init();

When you write a new web platform test, it will likely involve passing a new message like the messages above, to and from the fenced frame. Keep in mind that you may have to use a pair of keys, so that when one document writes a message associated with one unique key, it can listen for an ACK from the receiving document, so that it doesn't write over the message again before the receiving document actually reads it. No two tests should ever use the same key to communicate information to and from a fenced frame, as this will cause server-side race conditions.

For a good test example, see window-parent.html.

Underlying implementations

This directory contains tests that exercise the blink::features::kFencedFrames feature.

Wrap lines at 80 columns

This is the convention for most Chromium/WPT style tests. Note that git cl format [--js] does not reformat js code in .html files.