Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

// META: script=/resources/testdriver.js
// META: script=/common/utils.js
// META: script=/common/subset-tests.js
// META: script=resources/fledge-util.sub.js
// META: timeout=long
// META: variant=?1-4
// META: variant=?5-8
// META: variant=?9-12
// META: variant=?13-last
"use strict;"
////////////////////////////////////////////////////////////////////////////////
// Join interest group in iframe tests.
////////////////////////////////////////////////////////////////////////////////
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
let iframe = await createIframe(test, document.location.origin);
// Join a same-origin InterestGroup in a iframe navigated to its origin.
await runInFrame(test, iframe, `await joinInterestGroup(test_instance, "${uuid}");`);
// Run an auction using window.location.origin as a bidder. The IG should
// make a bid and win an auction.
await runBasicFledgeTestExpectingWinner(test, uuid);
}, 'Join interest group in same-origin iframe, default permissions.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
let iframe = await createIframe(test, OTHER_ORIGIN1);
// Join a cross-origin InterestGroup in a iframe navigated to its origin.
await runInFrame(test, iframe, `await joinInterestGroup(test_instance, "${uuid}");`);
// Run an auction in this frame using the other origin as a bidder. The IG should
// make a bid and win an auction.
//
// TODO: Once the permission defaults to not being able to join InterestGroups in
// cross-origin iframes, this auction should have no winner.
await runBasicFledgeTestExpectingWinner(
test, uuid,
{ interestGroupBuyers: [OTHER_ORIGIN1],
scoreAd: `if (browserSignals.interestGroupOwner !== "${OTHER_ORIGIN1}")
throw "Wrong owner: " + browserSignals.interestGroupOwner`
});
}, 'Join interest group in cross-origin iframe, default permissions.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
let iframe = await createIframe(test, OTHER_ORIGIN1, 'join-ad-interest-group');
// Join a cross-origin InterestGroup in a iframe navigated to its origin.
await runInFrame(test, iframe, `await joinInterestGroup(test_instance, "${uuid}");`);
// Run an auction in this frame using the other origin as a bidder. The IG should
// make a bid and win an auction.
await runBasicFledgeTestExpectingWinner(
test, uuid,
{ interestGroupBuyers: [OTHER_ORIGIN1],
scoreAd: `if (browserSignals.interestGroupOwner !== "${OTHER_ORIGIN1}")
throw "Wrong owner: " + browserSignals.interestGroupOwner`
});
}, 'Join interest group in cross-origin iframe with join-ad-interest-group permission.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
let iframe = await createIframe(test, OTHER_ORIGIN1, "join-ad-interest-group 'none'");
// Try to join an InterestGroup in a cross-origin iframe whose permissions policy
// blocks joining interest groups. An exception should be thrown, and the interest
// group should not be joined.
await runInFrame(test, iframe,
`try {
await joinInterestGroup(test_instance, "${uuid}");
} catch (e) {
assert_true(e instanceof DOMException, "DOMException thrown");
assert_equals(e.name, "NotAllowedError", "NotAllowedError DOMException thrown");
return {result: "success"};
}
return "exception unexpectedly not thrown";`);
// Run an auction in this frame using the other origin as a bidder. Since the join
// should have failed, the auction should have no winner.
await runBasicFledgeTestExpectingNoWinner(
test, uuid,
{ interestGroupBuyers: [OTHER_ORIGIN1] });
}, 'Join interest group in cross-origin iframe with join-ad-interest-group permission denied.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
let iframe = await createIframe(test, OTHER_ORIGIN1, 'join-ad-interest-group');
// Try to join an IG with the parent's origin as an owner in a cross-origin iframe.
// This should require a .well-known fetch to the parents origin, which will not
// grant permission. The case where permission is granted is not yet testable.
let interestGroup = JSON.stringify(createInterestGroupForOrigin(uuid, window.location.origin));
await runInFrame(test, iframe,
`try {
await joinInterestGroup(test_instance, "${uuid}", ${interestGroup});
} catch (e) {
assert_true(e instanceof DOMException, "DOMException thrown");
assert_equals(e.name, "NotAllowedError", "NotAllowedError DOMException thrown");
return {result: "success"};
}
return "exception unexpectedly not thrown";`);
// Run an auction with this page's origin as a bidder. Since the join
// should have failed, the auction should have no winner.
await runBasicFledgeTestExpectingNoWinner(test, uuid);
}, "Join interest group owned by parent's origin in cross-origin iframe.");
////////////////////////////////////////////////////////////////////////////////
// Run auction in iframe tests.
////////////////////////////////////////////////////////////////////////////////
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
await joinInterestGroup(test, uuid);
let iframe = await createIframe(test, document.location.origin);
// Join a same-origin InterestGroup in a iframe navigated to its origin.
await runInFrame(test, iframe, `await joinInterestGroup(test_instance, "${uuid}");`);
// Run auction in same-origin iframe. This should succeed, by default.
await runInFrame(
test, iframe,
`await runBasicFledgeTestExpectingWinner(test_instance, "${uuid}");`);
}, 'Run auction in same-origin iframe, default permissions.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
// Join an interest group owned by the the main frame's origin.
await joinInterestGroup(test, uuid);
let iframe = await createIframe(test, OTHER_ORIGIN1);
// Run auction in cross-origin iframe. Currently, this is allowed by default.
await runInFrame(
test, iframe,
`await runBasicFledgeTestExpectingWinner(
test_instance, "${uuid}",
{interestGroupBuyers: ["${window.location.origin}"]});`);
}, 'Run auction in cross-origin iframe, default permissions.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
// Join an interest group owned by the the main frame's origin.
await joinInterestGroup(test, uuid);
let iframe = await createIframe(test, OTHER_ORIGIN1, "run-ad-auction");
// Run auction in cross-origin iframe that should allow the auction to occur.
await runInFrame(
test, iframe,
`await runBasicFledgeTestExpectingWinner(
test_instance, "${uuid}",
{interestGroupBuyers: ["${window.location.origin}"]});`);
}, 'Run auction in cross-origin iframe with run-ad-auction permission.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
// No need to join any interest groups in this case - running an auction
// should only throw an exception based on permissions policy, regardless
// of whether there are any interest groups can participate.
let iframe = await createIframe(test, OTHER_ORIGIN1, "run-ad-auction 'none'");
// Run auction in cross-origin iframe that should not allow the auction to occur.
await runInFrame(
test, iframe,
`try {
await runBasicFledgeAuction(test_instance, "${uuid}");
} catch (e) {
assert_true(e instanceof DOMException, "DOMException thrown");
assert_equals(e.name, "NotAllowedError", "NotAllowedError DOMException thrown");
return {result: "success"};
}
throw "Attempting to run auction unexpectedly did not throw"`);
}, 'Run auction in cross-origin iframe with run-ad-auction permission denied.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
// Join an interest group owned by the the main frame's origin.
await joinInterestGroup(test, uuid);
let iframe = await createIframe(test, OTHER_ORIGIN1, `run-ad-auction ${OTHER_ORIGIN1}`);
await runInFrame(
test, iframe,
`await runBasicFledgeTestExpectingWinner(
test_instance, "${uuid}",
{ interestGroupBuyers: ["${window.location.origin}"],
seller: "${OTHER_ORIGIN2}",
decisionLogicURL: createDecisionScriptURL("${uuid}", {origin: "${OTHER_ORIGIN2}"})
});`);
}, 'Run auction in cross-origin iframe with run-ad-auction for iframe origin, which is different from seller origin.');
////////////////////////////////////////////////////////////////////////////////
// Navigate fenced frame iframe tests.
////////////////////////////////////////////////////////////////////////////////
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
// Join an interest group and run an auction with a winner.
await joinInterestGroup(test, uuid);
let config = await runBasicFledgeTestExpectingWinner(test, uuid);
// Try to navigate a fenced frame to the winning ad in a cross-origin iframe
// with no fledge-related permissions.
let iframe = await createIframe(
test, OTHER_ORIGIN1, "join-ad-interest-group 'none'; run-ad-auction 'none'");
await runInFrame(
test, iframe,
`await createAndNavigateFencedFrame(test_instance, param);`,
/*param=*/config);
await waitForObservedRequests(
uuid, [createBidderReportURL(uuid), createSellerReportURL(uuid)]);
}, 'Run auction main frame, open winning ad in cross-origin iframe.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
let iframe = await createIframe(
test, OTHER_ORIGIN1, "join-ad-interest-group; run-ad-auction");
await runInFrame(
test, iframe,
`await joinInterestGroup(test_instance, "${uuid}");
await runBasicFledgeAuctionAndNavigate(test_instance, "${uuid}");
await waitForObservedRequests(
"${uuid}", [createBidderReportURL("${uuid}"), createSellerReportURL("${uuid}")])`);
}, 'Run auction in cross-origin iframe and open winning ad in nested fenced frame.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
// Run an auction in an cross-origin iframe, and get the resulting FencedFrameConfig.
let iframe = await createIframe(
test, OTHER_ORIGIN1, "join-ad-interest-group; run-ad-auction");
let config = await runInFrame(
test, iframe,
`await joinInterestGroup(test_instance, "${uuid}");
let config = await runBasicFledgeTestExpectingWinner(test_instance, "${uuid}");
return {result: "success", returnValue: config};`);
assert_true(config != null, "Value not returned from auction in iframe");
assert_true(config instanceof FencedFrameConfig,
`Wrong value type returned from auction: ${config.constructor.type}`);
// Loading the winning ad in a fenced frame that's a child of the main frame should
// succeed.
await createAndNavigateFencedFrame(test, config);
await waitForObservedRequests(
uuid,
[ createBidderReportURL(uuid, '1', OTHER_ORIGIN1),
createSellerReportURL(uuid, '1', OTHER_ORIGIN1)]);
}, 'Run auction in cross-origin iframe and open winning ad in a fenced frame child of the main frame.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
// Run an auction in an cross-origin iframe, and get the resulting FencedFrameConfig.
let iframe = await createIframe(
test, OTHER_ORIGIN1, "join-ad-interest-group; run-ad-auction");
let config = await runInFrame(
test, iframe,
`await joinInterestGroup(test_instance, "${uuid}");
let config = await runBasicFledgeTestExpectingWinner(test_instance, "${uuid}");
return {result: "success", returnValue: config};`);
assert_true(config != null, "Value not returned from auction in iframe");
assert_true(config instanceof FencedFrameConfig,
`Wrong value type returned from auction: ${config.constructor.type}`);
// Try to navigate a fenced frame to the winning ad in a cross-origin iframe
// with no fledge-related permissions. The iframe is a different origin from the
// first cross-origin iframe.
let iframe2 = await createIframe(
test, OTHER_ORIGIN2, "join-ad-interest-group 'none'; run-ad-auction 'none'");
await runInFrame(
test, iframe2,
`await createAndNavigateFencedFrame(test_instance, param);`,
/*param=*/config);
await waitForObservedRequests(
uuid,
[ createBidderReportURL(uuid, '1', OTHER_ORIGIN1),
createSellerReportURL(uuid, '1', OTHER_ORIGIN1)]);
}, 'Run auction in cross-origin iframe and open winning ad in a fenced frame child of another cross-origin iframe.');
////////////////////////////////////////////////////////////////////////////////
// Other tests.
////////////////////////////////////////////////////////////////////////////////
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
let iframe = await createIframe(test, OTHER_ORIGIN1, "run-ad-auction");
// Do everything in a cross-origin iframe, and make sure correct top-frame origin is used.
await runInFrame(
test, iframe,
`const uuid = "${uuid}";
const renderURL = createRenderURL(uuid, /*script=*/null, /*signalsParam=*/'hostname');
await joinInterestGroup(
test_instance, uuid,
{ trustedBiddingSignalsKeys: ['hostname'],
trustedBiddingSignalsURL: TRUSTED_BIDDING_SIGNALS_URL,
ads: [{ renderURL: renderURL }],
biddingLogicURL: createBiddingScriptURL({
generateBid:
\`if (browserSignals.topWindowHostname !== "${document.location.hostname}")
throw "Wrong topWindowHostname: " + browserSignals.topWindowHostname;
if (trustedBiddingSignals.hostname !== '${window.location.hostname}')
throw 'Wrong hostname: ' + trustedBiddingSignals.hostname;\`})});
await runBasicFledgeTestExpectingWinner(
test_instance, uuid,
{ trustedScoringSignalsURL: TRUSTED_SCORING_SIGNALS_URL,
decisionLogicURL:
createDecisionScriptURL(
uuid,
{ scoreAd:
\`if (browserSignals.topWindowHostname !== "${document.location.hostname}")
throw "Wrong topWindowHostname: " + browserSignals.topWindowHostname;
if (trustedScoringSignals.renderURL["\${renderURL}"] !== '${window.location.hostname}')
throw 'Wrong hostname: ' + trustedScoringSignals.renderURL["\${renderURL}"];\` })});`);
}, 'Different top-frame origin.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
let bidderOrigin = OTHER_ORIGIN1;
let sellerOrigin = OTHER_ORIGIN2;
let bidderSendReportToURL = createBidderReportURL(uuid, '1', OTHER_ORIGIN3);
let sellerSendReportToURL = createSellerReportURL(uuid, '2', OTHER_ORIGIN4);
let bidderBeaconURL = createBidderBeaconURL(uuid, '3', OTHER_ORIGIN5);
let sellerBeaconURL = createSellerBeaconURL(uuid, '4', OTHER_ORIGIN6);
let renderURL = createRenderURL(
uuid,
`window.fence.reportEvent({
eventType: "beacon",
eventData: window.location.href,
destination: ["buyer", "seller"]
})`,
/*signalsParams=*/null, OTHER_ORIGIN7);
let iframe = await createIframe(test, bidderOrigin, "join-ad-interest-group");
let interestGroup = createInterestGroupForOrigin(
uuid, bidderOrigin,
{biddingLogicURL: createBiddingScriptURL(
{ origin: bidderOrigin,
generateBid: `if (browserSignals.topWindowHostname !== "${document.location.hostname}")
throw "Wrong topWindowHostname: " + browserSignals.topWindowHostname;
if (interestGroup.owner !== "${bidderOrigin}")
throw "Wrong origin: " + interestGroup.owner;
if (!interestGroup.biddingLogicURL.startsWith("${bidderOrigin}"))
throw "Wrong origin: " + interestGroup.biddingLogicURL;
if (interestGroup.ads[0].renderURL !== "${renderURL}")
throw "Wrong renderURL: " + interestGroup.ads[0].renderURL;
if (browserSignals.seller !== "${sellerOrigin}")
throw "Wrong origin: " + browserSignals.seller;`,
reportWin: `if (browserSignals.topWindowHostname !== "${document.location.hostname}")
throw "Wrong topWindowHostname: " + browserSignals.topWindowHostname;
if (browserSignals.seller !== "${sellerOrigin}")
throw "Wrong seller: " + browserSignals.seller;
if (browserSignals.interestGroupOwner !== "${bidderOrigin}")
throw "Wrong interestGroupOwner: " + browserSignals.interestGroupOwner;
if (browserSignals.renderURL !== "${renderURL}")
throw "Wrong renderURL: " + browserSignals.renderURL;
if (browserSignals.seller !== "${sellerOrigin}")
throw "Wrong seller: " + browserSignals.seller;
sendReportTo("${bidderSendReportToURL}");
registerAdBeacon({beacon: "${bidderBeaconURL}"});` }),
ads: [{ renderURL: renderURL }]});
await runInFrame(
test, iframe,
`await joinInterestGroup(test_instance, "${uuid}", ${JSON.stringify(interestGroup)});`);
await runBasicFledgeAuctionAndNavigate(test, uuid,
{ seller: sellerOrigin,
interestGroupBuyers: [bidderOrigin],
decisionLogicURL: createDecisionScriptURL(
uuid,
{ origin: sellerOrigin,
scoreAd: `if (browserSignals.topWindowHostname !== "${document.location.hostname}")
throw "Wrong topWindowHostname: " + browserSignals.topWindowHostname;
if (auctionConfig.seller !== "${sellerOrigin}")
throw "Wrong seller: " + auctionConfig.seller;
if (auctionConfig.interestGroupBuyers[0] !== "${bidderOrigin}")
throw "Wrong interestGroupBuyers: " + auctionConfig.interestGroupBuyers;
if (browserSignals.interestGroupOwner !== "${bidderOrigin}")
throw "Wrong interestGroupOwner: " + browserSignals.interestGroupOwner;
if (browserSignals.renderURL !== "${renderURL}")
throw "Wrong renderURL: " + browserSignals.renderURL;`,
reportResult: `if (browserSignals.topWindowHostname !== "${document.location.hostname}")
throw "Wrong topWindowHostname: " + browserSignals.topWindowHostname;
if (browserSignals.interestGroupOwner !== "${bidderOrigin}")
throw "Wrong interestGroupOwner: " + browserSignals.interestGroupOwner;
if (browserSignals.renderURL !== "${renderURL}")
throw "Wrong renderURL: " + browserSignals.renderURL;
sendReportTo("${sellerSendReportToURL}");
registerAdBeacon({beacon: "${sellerBeaconURL}"});`})
});
await waitForObservedRequests(
uuid,
[ bidderSendReportToURL,
sellerSendReportToURL,
`${bidderBeaconURL}, body: ${renderURL}`,
`${sellerBeaconURL}, body: ${renderURL}`
]);
}, 'Single seller auction with as many distinct origins as possible (except no component ads).');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
// Join an interest group and run an auction with a winner. Use a tracking
// URL for the ad, so that if it's incorrectly loaded in this test, the
// waitForObservedRequests() at the end of the test will see it, and the
// test will fail.
await joinInterestGroup(
test, uuid,
{ads: [{renderURL: createTrackerURL(window.location.origin, uuid, 'track_get', 'renderURL')}]});
let config = await runBasicFledgeTestExpectingWinner(test, uuid);
// Try to navigate a fenced frame to the winning ad in a new same-origin
// window. This should fail. Unfortunately, there's no assertion that
// can be checked for, and can't communicate with the contents of the
// fenced frame to make sure the load fails.
//
// So instead, join an interest group with a different sendReportTo-url,
// overwriting the previously joined one, and run another auction, loading
// the winner in another fenced frame.
//
// Then wait to see that only the reporting URLs from that second auction
// are requested. They should almost always be requested after the URLs
// from the first auction.
let child_window =
await createFrame(test, document.location.origin, /*is_iframe=*/false);
await runInFrame(
test, child_window,
`await createAndNavigateFencedFrame(test_instance, param);
await joinInterestGroup(
test_instance, "${uuid}",
{biddingLogicURL: createBiddingScriptURL(
{reportWin: "sendReportTo('${createBidderReportURL(uuid, "2")}');" })});
await runBasicFledgeAuctionAndNavigate(test_instance, "${uuid}");`,
/*param=*/config);
await waitForObservedRequests(
uuid, [createBidderReportURL(uuid, "2"), createSellerReportURL(uuid)]);
}, 'Run auction in main frame, try to open winning ad in different same-origin main frame.');