Skip to content

Commit e52f034

Browse files
committed
Bug 1968644 - Part 7: Add tests. r=necko-reviewers,anti-tracking-reviewers,emz,valentin
Differential Revision: https://phabricator.services.mozilla.com/D252449
1 parent f564c21 commit e52f034

File tree

12 files changed

+391
-0
lines changed

12 files changed

+391
-0
lines changed

toolkit/components/antitracking/test/browser/browser.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,21 @@ support-files = [
328328

329329
["browser_thirdPartyStorageRejectionForCORS.js"]
330330

331+
["browser_triggeringClassificationFlags.js"]
332+
support-files = [
333+
"empty_size.mp3",
334+
"empty_size.mp3^headers^",
335+
"fetch.html",
336+
"fetch.html^headers^",
337+
"file_ws_handshake_delay_wsh.py",
338+
"short.mp4",
339+
"short.mp4^headers^",
340+
"style.css",
341+
"style.css^headers^",
342+
"test.font.woff",
343+
"test.font.woff^headers^",
344+
]
345+
331346
["browser_urlDecorationStripping.js"]
332347

333348
["browser_urlQueryStringStripping.js"]
Lines changed: 366 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,366 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
"use strict";
6+
7+
const TEST_CASES = [
8+
{
9+
name: "XHR",
10+
url: TEST_4TH_PARTY_PAGE_HTTPS,
11+
testFunc: async (browsingContext, url) => {
12+
await SpecialPowers.spawn(browsingContext, [url], async srcUrl => {
13+
let xhr = new content.XMLHttpRequest();
14+
xhr.open("GET", srcUrl);
15+
xhr.send();
16+
});
17+
},
18+
},
19+
{
20+
name: "Fetch",
21+
url: TEST_4TH_PARTY_DOMAIN_HTTPS + TEST_PATH + "fetch.html",
22+
testFunc: async (browsingContext, url) => {
23+
await SpecialPowers.spawn(browsingContext, [url], async srcUrl => {
24+
await content.fetch(srcUrl);
25+
});
26+
},
27+
},
28+
{
29+
name: "Image",
30+
url: TEST_4TH_PARTY_DOMAIN_HTTPS + TEST_PATH + "raptor.jpg",
31+
testFunc: async (browsingContext, url) => {
32+
await SpecialPowers.spawn(browsingContext, [url], async srcUrl => {
33+
await new content.Promise(resolve => {
34+
let img = content.document.createElement("img");
35+
img.src = srcUrl;
36+
img.onload = resolve;
37+
content.document.body.appendChild(img);
38+
});
39+
});
40+
},
41+
},
42+
{
43+
name: "CSS",
44+
url: TEST_4TH_PARTY_DOMAIN_HTTPS + TEST_PATH + "style.css",
45+
testFunc: async (browsingContext, url) => {
46+
await SpecialPowers.spawn(browsingContext, [url], async srcUrl => {
47+
await new content.Promise(resolve => {
48+
let link = content.document.createElement("link");
49+
link.rel = "stylesheet";
50+
link.href = srcUrl;
51+
link.onload = resolve;
52+
content.document.head.appendChild(link);
53+
});
54+
});
55+
},
56+
},
57+
{
58+
name: "Video",
59+
url: TEST_4TH_PARTY_DOMAIN_HTTPS + TEST_PATH + "short.mp4",
60+
testFunc: async (browsingContext, url) => {
61+
await SpecialPowers.spawn(browsingContext, [url], async srcUrl => {
62+
await new content.Promise(resolve => {
63+
let video = content.document.createElement("video");
64+
video.src = srcUrl;
65+
video.onloadeddata = resolve;
66+
content.document.body.appendChild(video);
67+
});
68+
});
69+
},
70+
},
71+
{
72+
name: "Audio",
73+
url: TEST_4TH_PARTY_DOMAIN_HTTPS + TEST_PATH + "empty_size.mp3",
74+
testFunc: async (browsingContext, url) => {
75+
await SpecialPowers.spawn(browsingContext, [url], async srcUrl => {
76+
await new content.Promise(resolve => {
77+
let audio = content.document.createElement("audio");
78+
audio.src = srcUrl;
79+
audio.onloadeddata = resolve;
80+
content.document.body.appendChild(audio);
81+
});
82+
});
83+
},
84+
},
85+
{
86+
name: "Iframe",
87+
url: TEST_4TH_PARTY_DOMAIN_HTTPS + TEST_PATH + "page.html",
88+
testFunc: async (browsingContext, url) => {
89+
await SpecialPowers.spawn(browsingContext, [url], async srcUrl => {
90+
await new content.Promise(resolve => {
91+
let iframe = content.document.createElement("iframe");
92+
iframe.src = srcUrl;
93+
iframe.onload = resolve;
94+
content.document.body.appendChild(iframe);
95+
});
96+
});
97+
},
98+
},
99+
{
100+
name: "Script",
101+
url: TEST_4TH_PARTY_DOMAIN_HTTPS + TEST_PATH + "empty.js",
102+
testFunc: async (browsingContext, url) => {
103+
await SpecialPowers.spawn(browsingContext, [url], async srcUrl => {
104+
await new content.Promise(resolve => {
105+
let script = content.document.createElement("script");
106+
script.src = srcUrl;
107+
script.onload = resolve;
108+
content.document.body.appendChild(script);
109+
});
110+
});
111+
},
112+
},
113+
{
114+
name: "Font",
115+
url: TEST_4TH_PARTY_DOMAIN_HTTPS + TEST_PATH + "test.font.woff",
116+
testFunc: async (browsingContext, url) => {
117+
await SpecialPowers.spawn(browsingContext, [url], srcUrl => {
118+
let fontName = "TestFont" + Math.random().toString(36).substring(2);
119+
let style = content.document.createElement("style");
120+
style.textContent = `@font-face { font-family: ${fontName}; src: url('${srcUrl}'); }`;
121+
content.document.head.appendChild(style);
122+
let span = content.document.createElement("span");
123+
span.textContent = "FontTest";
124+
span.style.fontFamily = fontName;
125+
content.document.body.appendChild(span);
126+
// Force layout to trigger font load
127+
content.getComputedStyle(span).fontFamily;
128+
});
129+
},
130+
},
131+
// The url of a websocket channel is still using http scheme in the observer.
132+
// So we need to use a http url but not a ws url. But the actual websocket
133+
// request is still made to the ws url.
134+
{
135+
name: "WebSocket",
136+
url: "http://mochi.test:8888/browser/toolkit/components/antitracking/test/browser/file_ws_handshake_delay",
137+
testFunc: async (browsingContext, _) => {
138+
await SpecialPowers.spawn(browsingContext, [], async _ => {
139+
let ws = new content.WebSocket(
140+
"ws://mochi.test:8888/browser/toolkit/components/antitracking/test/browser/file_ws_handshake_delay",
141+
["test"]
142+
);
143+
144+
await ContentTaskUtils.waitForEvent(ws, "open");
145+
});
146+
},
147+
},
148+
];
149+
150+
// A helper function to observe and check flags on the channel.
151+
function observeAndCheck(
152+
url,
153+
expectedFirstPartyFlags,
154+
expectedThirdPartyFlags
155+
) {
156+
return new Promise(resolve => {
157+
let observer = {
158+
observe(subject, topic) {
159+
if (topic !== "http-on-opening-request") {
160+
return;
161+
}
162+
let channel = subject.QueryInterface(Ci.nsIHttpChannel);
163+
if (!channel || channel.URI.spec !== url) {
164+
return;
165+
}
166+
167+
let loadInfo = channel.loadInfo;
168+
is(
169+
loadInfo.triggeringFirstPartyClassificationFlags,
170+
expectedFirstPartyFlags,
171+
`Correct first party flags for ${url}`
172+
);
173+
is(
174+
loadInfo.triggeringThirdPartyClassificationFlags,
175+
expectedThirdPartyFlags,
176+
`Correct third party flags for ${url}`
177+
);
178+
179+
Services.obs.removeObserver(observer, "http-on-opening-request");
180+
resolve();
181+
},
182+
};
183+
Services.obs.addObserver(observer, "http-on-opening-request");
184+
});
185+
}
186+
187+
add_setup(async function () {
188+
await UrlClassifierTestUtils.addTestTrackers();
189+
190+
registerCleanupFunction(async _ => {
191+
UrlClassifierTestUtils.cleanupTestTrackers();
192+
193+
await new Promise(resolve => {
194+
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, () =>
195+
resolve()
196+
);
197+
});
198+
});
199+
});
200+
201+
// Test that the third party flags are set correctly when the request is made
202+
// from a third party iframe.
203+
add_task(async function test_third_party_flags() {
204+
// Open the test page and inject the tracking iframe
205+
let tab = await BrowserTestUtils.openNewForegroundTab(
206+
gBrowser,
207+
TEST_TOP_PAGE
208+
);
209+
210+
// Creating a tracking iframe.
211+
let trackingIframeBC = await SpecialPowers.spawn(
212+
tab.linkedBrowser,
213+
[TEST_3RD_PARTY_PAGE_HTTP],
214+
async iframeUrl => {
215+
let iframe = content.document.createElement("iframe");
216+
iframe.src = iframeUrl;
217+
content.document.body.appendChild(iframe);
218+
219+
await new content.Promise(resolve => {
220+
iframe.onload = resolve;
221+
});
222+
223+
return iframe.browsingContext;
224+
}
225+
);
226+
227+
for (const testCase of TEST_CASES) {
228+
info(`Running classification flags test for: ${testCase.name}`);
229+
230+
let obsPromise = observeAndCheck(
231+
testCase.url,
232+
0,
233+
Ci.nsIClassifiedChannel.CLASSIFIED_TRACKING
234+
);
235+
236+
// Call the testing function to make the request.
237+
await testCase.testFunc(trackingIframeBC, testCase.url);
238+
239+
await obsPromise;
240+
}
241+
242+
BrowserTestUtils.removeTab(tab);
243+
});
244+
245+
// Test that the first party flags are set correctly when the request is made
246+
// from an about:blank iframe in a tracking iframe.
247+
add_task(async function test_third_party_flags_in_about_blank_iframe() {
248+
// Open the test page and inject the tracking iframe
249+
let tab = await BrowserTestUtils.openNewForegroundTab(
250+
gBrowser,
251+
TEST_TOP_PAGE
252+
);
253+
254+
// Creating a tracking iframe.
255+
let trackingIframeBC = await SpecialPowers.spawn(
256+
tab.linkedBrowser,
257+
[TEST_3RD_PARTY_PAGE_HTTP],
258+
async iframeUrl => {
259+
let iframe = content.document.createElement("iframe");
260+
iframe.src = iframeUrl;
261+
content.document.body.appendChild(iframe);
262+
263+
await new content.Promise(resolve => {
264+
iframe.onload = resolve;
265+
});
266+
267+
return iframe.browsingContext;
268+
}
269+
);
270+
271+
// Open an about:blank iframe in the tracking iframe.
272+
let aboutBlankIframeBC = await SpecialPowers.spawn(
273+
trackingIframeBC,
274+
[],
275+
async () => {
276+
let iframe = content.document.createElement("iframe");
277+
content.document.body.appendChild(iframe);
278+
279+
return iframe.browsingContext;
280+
}
281+
);
282+
283+
for (const testCase of TEST_CASES) {
284+
info(`Running classification flags test for: ${testCase.name}`);
285+
286+
let obsPromise = observeAndCheck(
287+
testCase.url,
288+
0,
289+
Ci.nsIClassifiedChannel.CLASSIFIED_TRACKING
290+
);
291+
292+
// Call the testing function to make the request.
293+
await testCase.testFunc(aboutBlankIframeBC, testCase.url);
294+
295+
await obsPromise;
296+
}
297+
298+
BrowserTestUtils.removeTab(tab);
299+
});
300+
301+
// Test that the first party flags are set correctly when the request is made
302+
// from the top-level context loading a tracking domain.
303+
add_task(async function test_first_party_flags() {
304+
// Open the tab that loads a tracking domain.
305+
let tab = await BrowserTestUtils.openNewForegroundTab(
306+
gBrowser,
307+
TEST_3RD_PARTY_PAGE_HTTP
308+
);
309+
310+
for (const testCase of TEST_CASES) {
311+
info(`Running first-party classification flags test for: ${testCase.name}`);
312+
313+
let obsPromise = observeAndCheck(
314+
testCase.url,
315+
Ci.nsIClassifiedChannel.CLASSIFIED_TRACKING,
316+
0
317+
);
318+
319+
// Call the testing function to make the request.
320+
await testCase.testFunc(tab.linkedBrowser, testCase.url);
321+
322+
await obsPromise;
323+
}
324+
325+
BrowserTestUtils.removeTab(tab);
326+
});
327+
328+
// Test that the first party flags are set correctly when the request is made
329+
// from an about:blank iframe in the top-level context loading a tracking domain.
330+
add_task(async function test_first_party_flags_in_about_blank_iframe() {
331+
// Open the tab that loads a tracking domain.
332+
let tab = await BrowserTestUtils.openNewForegroundTab(
333+
gBrowser,
334+
TEST_3RD_PARTY_PAGE_HTTP
335+
);
336+
337+
// Open an about:blank iframe in the top-level context.
338+
let aboutBlankIframeBC = await SpecialPowers.spawn(
339+
tab.linkedBrowser,
340+
[],
341+
async () => {
342+
let iframe = content.document.createElement("iframe");
343+
content.document.body.appendChild(iframe);
344+
return iframe.browsingContext;
345+
}
346+
);
347+
348+
for (const testCase of TEST_CASES) {
349+
info(
350+
`Running first-party classification flags test (about:blank iframe) for: ${testCase.name}`
351+
);
352+
353+
let obsPromise = observeAndCheck(
354+
testCase.url,
355+
Ci.nsIClassifiedChannel.CLASSIFIED_TRACKING,
356+
0
357+
);
358+
359+
// Call the testing function to make the request.
360+
await testCase.testFunc(aboutBlankIframeBC, testCase.url);
361+
362+
await obsPromise;
363+
}
364+
365+
BrowserTestUtils.removeTab(tab);
366+
});
88.3 KB
Binary file not shown.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Cache-Control: no-store
2+
Access-Control-Allow-Origin: *

toolkit/components/antitracking/test/browser/fetch.html

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Access-Control-Allow-Origin: *
13.4 KB
Binary file not shown.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Cache-Control: no-store
2+
Access-Control-Allow-Origin: *

0 commit comments

Comments
 (0)