summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/fledge/tentative/join-leave-ad-interest-group-in-fenced-frame.https.window.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/fledge/tentative/join-leave-ad-interest-group-in-fenced-frame.https.window.js')
-rw-r--r--testing/web-platform/tests/fledge/tentative/join-leave-ad-interest-group-in-fenced-frame.https.window.js369
1 files changed, 369 insertions, 0 deletions
diff --git a/testing/web-platform/tests/fledge/tentative/join-leave-ad-interest-group-in-fenced-frame.https.window.js b/testing/web-platform/tests/fledge/tentative/join-leave-ad-interest-group-in-fenced-frame.https.window.js
new file mode 100644
index 0000000000..e6836ab2f4
--- /dev/null
+++ b/testing/web-platform/tests/fledge/tentative/join-leave-ad-interest-group-in-fenced-frame.https.window.js
@@ -0,0 +1,369 @@
+// META: script=/resources/testdriver.js
+// META: script=/common/utils.js
+// META: script=resources/fledge-util.sub.js
+// META: script=/common/subset-tests.js
+// META: timeout=long
+// META: variant=?1-4
+// META: variant=?5-8
+// META: variant=?9-last
+
+"use strict;"
+
+// These are separate from the other join-leave tests because these all create
+// and navigate fenced frames, which is much slower than just joining/leaving
+// interest groups, and running the occasional auction. Most tests use a
+// buyer with an origin of OTHER_ORIGIN1, so it has a distinct origin from the
+// seller and publisher.
+
+// Creates a tracker URL that's requested when a call succeeds in a fenced
+// frame.
+function createSuccessURL(uuid, origin = document.location.origin) {
+ return createTrackerURL(origin, uuid, "track_get", "success");
+}
+
+// Creates a tracker URL that's requested when a call fails in a fenced frame, with
+// the expected exception.
+function createExceptionURL(uuid, origin = document.location.origin) {
+ return createTrackerURL(origin, uuid, "track_get", "exception");
+}
+
+// Creates a tracker URL that's requested when joinAdInterestGroup() or
+// leaveAdInterestGroup() fails with an exception other than the one that's
+// expected.
+function createBadExceptionURL(uuid, origin = document.location.origin) {
+ return createTrackerURL(origin, uuid, "track_get", "bad_exception");
+}
+
+// Creates render URL that calls "navigator.leaveAdInterestGroup()" when
+// loaded, with no arguments. It then fetches a URL depending on whether it
+// threw an exception. No exception should ever be thrown when this is run
+// in an ad URL, so only fetch the "bad exception" URL on error.
+function createNoArgsTryLeaveRenderURL(uuid, origin = document.location.origin) {
+ return createRenderURL(
+ uuid,
+ `async function TryLeave() {
+ try {
+ await navigator.leaveAdInterestGroup();
+ await fetch("${createSuccessURL(uuid, origin)}");
+ } catch (e) {
+ await fetch("${createBadExceptionURL(uuid, origin)}");
+ }
+ }
+
+ TryLeave();`,
+ /*signalsParams=*/null,
+ origin);
+}
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+
+ // Interest group that an ad fenced frame attempts to join. The join should
+ // fail.
+ let interestGroupJoinedInFrame = createInterestGroupForOrigin(
+ uuid, document.location.origin, {name: 'group2'});
+
+ // Create a render URL that tries to join "interestGroupJoinedInFrame".
+ const renderURL = createRenderURL(
+ uuid,
+ `async function TryJoin() {
+ try {
+ await navigator.joinAdInterestGroup(
+ ${JSON.stringify(interestGroupJoinedInFrame)});
+ await fetch("${createSuccessURL(uuid)}");
+ } catch (e) {
+ if (e instanceof DOMException && e.name === "NotAllowedError") {
+ await fetch("${createExceptionURL(uuid)}");
+ } else {
+ await fetch("${createBadExceptionURL(uuid)}");
+ }
+ }
+ }
+
+ TryJoin();`);
+
+ await joinInterestGroup(test, uuid, {ads: [{ renderURL: renderURL}]});
+
+ await runBasicFledgeAuctionAndNavigate(test, uuid);
+
+ // This should wait until the leave call has thrown an exception.
+ await waitForObservedRequests(
+ uuid,
+ [createBidderReportURL(uuid), createSellerReportURL(uuid), createExceptionURL(uuid)]);
+
+ // Leave the initial interest group.
+ await leaveInterestGroup();
+
+ // Check the interest group was not successfully joined in the fenced frame
+ // by running an auction, to make sure the thrown exception accurately
+ // indicates the group wasn't joined.
+ await runBasicFledgeTestExpectingNoWinner(test, uuid);
+}, 'joinAdInterestGroup() in ad fenced frame.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+
+ // Create a render URL that tries to leave the default test interest group by
+ // name. Even a though a render URL can leave its own interest group by using
+ // the 0-argument version of leaveAdInterestGroup(), it can't leave its own
+ // interest group by using the 1-argument version, so this should fail.
+ const renderURL = createRenderURL(
+ uuid,
+ `async function TryLeave() {
+ try {
+ await navigator.leaveAdInterestGroup(
+ {owner: "${window.location.origin}", name: "${DEFAULT_INTEREST_GROUP_NAME}"});
+ await fetch("${createSuccessURL(uuid)}");
+ } catch (e) {
+ if (e instanceof DOMException && e.name === "NotAllowedError") {
+ await fetch("${createExceptionURL(uuid)}");
+ } else {
+ await fetch("${createBadExceptionURL(uuid)}");
+ }
+ }
+ }
+
+ TryLeave();`);
+
+ await joinInterestGroup(
+ test, uuid,
+ {ads: [{ renderURL: renderURL}]});
+
+ await runBasicFledgeAuctionAndNavigate(test, uuid);
+
+ // This should wait until the leave call has thrown an exception.
+ await waitForObservedRequests(
+ uuid,
+ [createBidderReportURL(uuid), createSellerReportURL(uuid), createExceptionURL(uuid)]);
+
+ // Check the interest group was not left.
+ await runBasicFledgeTestExpectingWinner(test, uuid);
+}, 'leaveAdInterestGroup() in ad fenced frame, specify an interest group.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+
+ const bidder_origin = OTHER_ORIGIN1;
+ const render_url_origin = window.location.origin;
+
+ await joinCrossOriginInterestGroup(
+ test, uuid, bidder_origin,
+ {ads: [{ renderURL: createNoArgsTryLeaveRenderURL(uuid, render_url_origin) }]});
+
+ await runBasicFledgeAuctionAndNavigate(test, uuid, {interestGroupBuyers : [bidder_origin]});
+
+ // Leaving the interest group should claim to succeed, to avoid leaking
+ // whether or not the buyer was same-origin or to the fenced frame.
+ await waitForObservedRequests(
+ uuid,
+ [ createBidderReportURL(uuid), createSellerReportURL(uuid),
+ createSuccessURL(uuid, render_url_origin)]);
+
+ // Check the interest group was not actually left.
+ await runBasicFledgeTestExpectingWinner(test, uuid, {interestGroupBuyers : [bidder_origin]});
+}, 'leaveAdInterestGroup() in non-buyer origin ad fenced frame, no parameters.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+
+ const bidder_origin = OTHER_ORIGIN1;
+ const render_url_origin = OTHER_ORIGIN1;
+
+ // Use a different origin for the buyer, to make sure that's the origin
+ // that matters.
+ await joinCrossOriginInterestGroup(
+ test, uuid, bidder_origin,
+ {ads: [{ renderURL: createNoArgsTryLeaveRenderURL(uuid, render_url_origin) }]});
+
+ await runBasicFledgeAuctionAndNavigate(test, uuid, {interestGroupBuyers : [bidder_origin]});
+
+ // This should wait until the leave call has completed.
+ await waitForObservedRequests(
+ uuid,
+ [ createBidderReportURL(uuid), createSellerReportURL(uuid),
+ createSuccessURL(uuid, render_url_origin)]);
+
+ // Check the interest group was actually left.
+ await runBasicFledgeTestExpectingNoWinner(test, uuid, {interestGroupBuyers : [bidder_origin]});
+}, 'leaveAdInterestGroup() in buyer origin ad fenced frame, no parameters.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+
+ const bidder_origin = OTHER_ORIGIN1;
+ const render_url_origin = OTHER_ORIGIN1;
+ const iframe_origin = OTHER_ORIGIN1;
+
+ // Create a render URL which, in an iframe, loads the common "try leave"
+ // render URL from the buyer's origin (which isn't technically being used as
+ // a render URL, in this case).
+ const renderURL = createRenderURL(
+ uuid,
+ `let iframe = document.createElement("iframe");
+ iframe.permissions = "join-ad-interest-group";
+ iframe.src = "${createNoArgsTryLeaveRenderURL(uuid, iframe_origin)}";
+ document.body.appendChild(iframe);`,
+ /*signalsParams=*/null,
+ render_url_origin);
+
+ await joinCrossOriginInterestGroup(
+ test, uuid, bidder_origin,
+ {ads: [{ renderURL: renderURL }]});
+
+ await runBasicFledgeAuctionAndNavigate(test, uuid, {interestGroupBuyers : [bidder_origin]});
+
+ // This should wait until the leave call has completed.
+ await waitForObservedRequests(
+ uuid,
+ [ createBidderReportURL(uuid), createSellerReportURL(uuid),
+ createSuccessURL(uuid, iframe_origin)]);
+
+ // Check the interest group was actually left.
+ await runBasicFledgeTestExpectingNoWinner(test, uuid, {interestGroupBuyers : [bidder_origin]});
+}, 'leaveAdInterestGroup() in same-origin iframe inside buyer origin ad fenced frame, no parameters.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+
+ const bidder_origin = OTHER_ORIGIN1;
+ const render_url_origin = OTHER_ORIGIN1;
+ const iframe_origin = document.location.origin;
+
+ // Create a render URL which, in an iframe, loads the common "try leave"
+ // render URL from an origin other than the buyer's origin.
+ const renderURL = createRenderURL(
+ uuid,
+ `let iframe = document.createElement("iframe");
+ iframe.permissions = "join-ad-interest-group";
+ iframe.src = "${createNoArgsTryLeaveRenderURL(uuid, iframe_origin)}";
+ document.body.appendChild(iframe);`,
+ /*signalsParams=*/null,
+ render_url_origin);
+
+ await joinCrossOriginInterestGroup(
+ test, uuid, bidder_origin,
+ {ads: [{ renderURL: renderURL }]});
+
+ await runBasicFledgeAuctionAndNavigate(test, uuid, {interestGroupBuyers : [bidder_origin]});
+
+ // Leaving the interest group should claim to succeed, to avoid leaking
+ // whether or not the buyer was same-origin or to the iframe.
+ await waitForObservedRequests(
+ uuid,
+ [ createBidderReportURL(uuid), createSellerReportURL(uuid),
+ createSuccessURL(uuid, iframe_origin)]);
+
+ // Check the interest group was not actually left.
+ await runBasicFledgeTestExpectingWinner(test, uuid, {interestGroupBuyers : [bidder_origin]});
+}, 'leaveAdInterestGroup() in cross-origin iframe inside buyer origin ad fenced frame, no parameters.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+
+ const bidder_origin = OTHER_ORIGIN1;
+ const render_url_origin = document.location.origin;
+ const iframe_origin = document.location.origin;
+
+ // Create a render URL which, in an iframe, loads the common "try leave"
+ // render URL from an origin other than the buyer's origin (which isn't
+ // technically being used as a render URL, in this case).
+ const renderURL = createRenderURL(
+ uuid,
+ `let iframe = document.createElement("iframe");
+ iframe.permissions = "join-ad-interest-group";
+ iframe.src = "${createNoArgsTryLeaveRenderURL(uuid, iframe_origin)}";
+ document.body.appendChild(iframe);`,
+ /*signalsParams=*/null,
+ render_url_origin);
+
+ await joinCrossOriginInterestGroup(
+ test, uuid, bidder_origin,
+ {ads: [{ renderURL: renderURL }]});
+
+ await runBasicFledgeAuctionAndNavigate(test, uuid, {interestGroupBuyers : [bidder_origin]});
+
+ // Leaving the interest group should claim to succeed, to avoid leaking
+ // whether or not the buyer was same-origin or to the fenced frame.
+ await waitForObservedRequests(
+ uuid,
+ [ createBidderReportURL(uuid), createSellerReportURL(uuid),
+ createSuccessURL(uuid, iframe_origin)]);
+
+ // Check the interest group was not actually left.
+ await runBasicFledgeTestExpectingWinner(test, uuid, {interestGroupBuyers : [bidder_origin]});
+}, 'leaveAdInterestGroup() in same-origin iframe inside non-buyer origin ad fenced frame, no parameters.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+
+ const bidder_origin = OTHER_ORIGIN1;
+ const render_url_origin = document.location.origin;
+ const iframe_origin = OTHER_ORIGIN1;
+
+ // Create a render URL which, in an iframe, loads the common "try leave"
+ // render URL from the buyer's origin (which isn't technically being used as
+ // a render URL, in this case).
+ const renderURL = createRenderURL(
+ uuid,
+ `let iframe = document.createElement("iframe");
+ iframe.permissions = "join-ad-interest-group";
+ iframe.src = "${createNoArgsTryLeaveRenderURL(uuid, iframe_origin)}";
+ document.body.appendChild(iframe);`,
+ /*signalsParams=*/null,
+ render_url_origin);
+
+ await joinCrossOriginInterestGroup(
+ test, uuid, bidder_origin,
+ {ads: [{ renderURL: renderURL }]});
+
+ await runBasicFledgeAuctionAndNavigate(test, uuid, {interestGroupBuyers : [bidder_origin]});
+ // Leaving the interest group should succeed.
+ await waitForObservedRequests(
+ uuid,
+ [ createBidderReportURL(uuid), createSellerReportURL(uuid),
+ createSuccessURL(uuid, iframe_origin)]);
+
+ // Check the interest group was left.
+ await runBasicFledgeTestExpectingNoWinner(test, uuid, {interestGroupBuyers : [bidder_origin]});
+}, 'leaveAdInterestGroup() in cross-origin buyer iframe inside non-buyer origin ad fenced frame, no parameters.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+
+ // Render URL that loads the first ad component in a nested fenced frame.
+ let loadFirstComponentAdURL =
+ createRenderURL(
+ uuid,
+ `let fencedFrame = document.createElement("fencedframe");
+ fencedFrame.mode = "opaque-ads";
+ fencedFrame.config = window.fence.getNestedConfigs()[0];
+ document.body.appendChild(fencedFrame);`,
+ /*signalsParams=*/null,
+ OTHER_ORIGIN1);
+
+ await joinInterestGroup(
+ test, uuid,
+ // Interest group that makes a bid with a component ad. The render URL
+ // will open the component ad in a fenced frame, and the component ad
+ // URL is the common URL that tries to leave the ad's current interest
+ // group, reporting the result to a tracker URL.
+ { biddingLogicURL: createBiddingScriptURL(
+ { generateBid: `return {
+ bid: 1,
+ render: interestGroup.ads[0].renderURL,
+ adComponents: [interestGroup.adComponents[0].renderURL]
+ };` }),
+ ads: [{ renderURL: loadFirstComponentAdURL }],
+ adComponents: [{ renderURL: createNoArgsTryLeaveRenderURL(uuid) }]});
+
+ await runBasicFledgeAuctionAndNavigate(test, uuid);
+
+ // Leaving the interest group should claim to succeed, to avoid leaking
+ // whether or not the buyer was same-origin or to the fenced frame.
+ await waitForObservedRequests(
+ uuid,
+ [createSellerReportURL(uuid), createSuccessURL(uuid)]);
+
+ // Check the interest group was left.
+ await runBasicFledgeTestExpectingNoWinner(test, uuid);
+}, 'leaveAdInterestGroup() in component ad fenced frame, no parameters.');