summaryrefslogtreecommitdiffstats
path: root/toolkit/components/antitracking/bouncetrackingprotection/test/browser/browser_bouncetracking_simple.js
blob: cdc21eb788ff35a2792fb33e3b751c8daed0a9e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

add_setup(async function () {
  await SpecialPowers.pushPrefEnv({
    set: [
      ["privacy.bounceTrackingProtection.requireStatefulBounces", false],
      ["privacy.bounceTrackingProtection.bounceTrackingGracePeriodSec", 0],
    ],
  });
});

// Tests a stateless bounce via client redirect.
add_task(async function test_client_bounce_simple() {
  await runTestBounce({ bounceType: "client" });
});

// Tests a stateless bounce via server redirect.
add_task(async function test_server_bounce_simple() {
  await runTestBounce({ bounceType: "server" });
});

// Tests a chained redirect consisting of a server and a client redirect.
add_task(async function test_bounce_chain() {
  Assert.equal(
    bounceTrackingProtection.testGetBounceTrackerCandidateHosts({}).length,
    0,
    "No bounce tracker hosts initially."
  );
  Assert.equal(
    bounceTrackingProtection.testGetUserActivationHosts({}).length,
    0,
    "No user activation hosts initially."
  );

  await BrowserTestUtils.withNewTab(
    getBaseUrl(ORIGIN_A) + "file_start.html",
    async browser => {
      let promiseRecordBounces = waitForRecordBounces(browser);

      // The final destination after the bounces.
      let targetURL = new URL(getBaseUrl(ORIGIN_B) + "file_start.html");

      // Construct last hop.
      let bounceChainUrlEnd = getBounceURL({ bounceType: "server", targetURL });
      // Construct first hop, nesting last hop.
      let bounceChainUrlFull = getBounceURL({
        bounceType: "client",
        redirectDelayMS: 100,
        bounceOrigin: ORIGIN_TRACKER_B,
        targetURL: bounceChainUrlEnd,
      });

      info("bounceChainUrl: " + bounceChainUrlFull.href);

      // Navigate through the bounce chain.
      await navigateLinkClick(browser, bounceChainUrlFull);

      // Wait for the final site to be loaded which complete the BounceTrackingRecord.
      await BrowserTestUtils.browserLoaded(browser, false, targetURL);

      // Navigate again with user gesture which triggers
      // BounceTrackingProtection::RecordStatefulBounces. We could rely on the
      // timeout (mClientBounceDetectionTimeout) here but that can cause races
      // in debug where the load is quite slow.
      await navigateLinkClick(
        browser,
        new URL(getBaseUrl(ORIGIN_C) + "file_start.html")
      );

      await promiseRecordBounces;

      Assert.deepEqual(
        bounceTrackingProtection
          .testGetBounceTrackerCandidateHosts({})
          .map(entry => entry.siteHost)
          .sort(),
        [SITE_TRACKER_B, SITE_TRACKER].sort(),
        `Identified all bounce trackers in the redirect chain.`
      );
      Assert.deepEqual(
        bounceTrackingProtection
          .testGetUserActivationHosts({})
          .map(entry => entry.siteHost)
          .sort(),
        [SITE_A, SITE_B].sort(),
        "Should only have user activation for sites where we clicked links."
      );

      bounceTrackingProtection.clearAll();
    }
  );
});