@duckduckgo/autoconsent 16.48.0 → 16.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/.agents/skills/optimize-button-patterns/SKILL.md +145 -0
  2. package/.agents/skills/oxylabs-testing/SKILL.md +1 -1
  3. package/.claude/skills/optimize-button-patterns/SKILL.md +7 -0
  4. package/.github/workflows/release-labels.yml +2 -6
  5. package/AGENTS.md +2 -0
  6. package/CHANGELOG.md +77 -0
  7. package/data/Readme.md +6 -0
  8. package/data/labelled-button-texts.csv +7006 -0
  9. package/dist/addon-firefox/background.bundle.js +6 -1
  10. package/dist/addon-firefox/compact-rules.json +1 -1
  11. package/dist/addon-firefox/content.bundle.js +26 -13
  12. package/dist/addon-firefox/manifest.json +1 -1
  13. package/dist/addon-firefox/rule-index.json +1 -1
  14. package/dist/addon-firefox/rules.json +1 -1
  15. package/dist/addon-mv3/background.bundle.js +6 -1
  16. package/dist/addon-mv3/compact-rules.json +1 -1
  17. package/dist/addon-mv3/content.bundle.js +26 -13
  18. package/dist/addon-mv3/manifest.json +1 -1
  19. package/dist/addon-mv3/rule-index.json +1 -1
  20. package/dist/addon-mv3/rules.json +1 -1
  21. package/dist/autoconsent.cjs.js +26 -13
  22. package/dist/autoconsent.esm.js +26 -13
  23. package/dist/autoconsent.playwright.js +26 -13
  24. package/dist/autoconsent.standalone.js +27 -14
  25. package/dist/types/eval-snippets.d.ts +3 -0
  26. package/lib/eval-snippets.ts +7 -0
  27. package/lib/heuristic-patterns.ts +20 -11
  28. package/package.json +3 -1
  29. package/rules/autoconsent/amazon-hiring.json +16 -0
  30. package/rules/autoconsent/avada-cookie-consent.json +43 -0
  31. package/rules/autoconsent/axeptio.json +17 -4
  32. package/rules/autoconsent/bigcrunch.json +39 -0
  33. package/rules/autoconsent/borlabs.json +5 -0
  34. package/rules/autoconsent/bricklink.json +33 -0
  35. package/rules/autoconsent/ceneo.json +9 -0
  36. package/rules/autoconsent/conjointly.json +43 -0
  37. package/rules/autoconsent/consentmo.json +51 -7
  38. package/rules/autoconsent/cookie-popup-close-cookies.json +37 -0
  39. package/rules/autoconsent/cookieconsent2.json +6 -1
  40. package/rules/autoconsent/costco.json +27 -0
  41. package/rules/autoconsent/datasign.json +85 -0
  42. package/rules/autoconsent/dhbbank.json +13 -0
  43. package/rules/autoconsent/ee-consent-notice.json +40 -0
  44. package/rules/autoconsent/ensembleartsphilly.json +33 -0
  45. package/rules/autoconsent/evium.de.json +33 -0
  46. package/rules/autoconsent/fera-cookies.json +67 -0
  47. package/rules/autoconsent/iubenda.json +13 -7
  48. package/rules/autoconsent/la7-cmp.json +30 -0
  49. package/rules/autoconsent/laravel-cookie-consent.json +45 -0
  50. package/rules/autoconsent/legislation-gov-uk.json +43 -0
  51. package/rules/autoconsent/mackeeper.json +34 -0
  52. package/rules/autoconsent/ndl-go-jp.json +35 -0
  53. package/rules/autoconsent/pandectes.json +48 -15
  54. package/rules/autoconsent/passle.json +32 -0
  55. package/rules/autoconsent/paypal-us.json +3 -3
  56. package/rules/autoconsent/paypal.json +5 -2
  57. package/rules/autoconsent/primeconsent.json +39 -0
  58. package/rules/autoconsent/shinden.pl.json +34 -0
  59. package/rules/autoconsent/texas-instruments.json +17 -0
  60. package/rules/autoconsent/thegrandyork.json +46 -0
  61. package/rules/autoconsent/thenounproject.json +61 -0
  62. package/rules/autoconsent/toyota.json +16 -5
  63. package/rules/autoconsent/tri-table.json +14 -0
  64. package/rules/autoconsent/truevault-polaris.json +63 -0
  65. package/rules/autoconsent/uft-cookie-notice.json +15 -0
  66. package/rules/autoconsent/wbd-legal-terms.json +32 -0
  67. package/rules/autoconsent/webflow.json +1 -1
  68. package/rules/autoconsent/wix.json +90 -8
  69. package/rules/compact-rules.json +1 -1
  70. package/rules/rule-index.json +1 -1
  71. package/rules/rules.json +1 -1
  72. package/scripts/benchmark-button-classification.ts +75 -0
  73. package/scripts/button-text-benchmark.ts +102 -0
  74. package/tests/amazon-hiring.spec.ts +3 -0
  75. package/tests/avada-cookie-consent.spec.ts +9 -0
  76. package/tests/axeptio.spec.ts +8 -4
  77. package/tests/bigcrunch.spec.ts +16 -0
  78. package/tests/borlabs.spec.ts +7 -3
  79. package/tests/bricklink.spec.ts +3 -0
  80. package/tests/ceneo.spec.ts +3 -0
  81. package/tests/conjointly.spec.ts +3 -0
  82. package/tests/consentmo.spec.ts +1 -0
  83. package/tests/cookie-popup-close-cookies.spec.ts +10 -0
  84. package/tests/cookieconsent2.spec.ts +6 -1
  85. package/tests/costco.spec.ts +5 -0
  86. package/tests/datasign.spec.ts +8 -0
  87. package/tests/dhbbank.spec.ts +6 -0
  88. package/tests/ee-consent-notice.spec.ts +9 -0
  89. package/tests/ensembleartsphilly.spec.ts +6 -0
  90. package/tests/evium.de.spec.ts +5 -0
  91. package/tests/fera-cookies.spec.ts +6 -0
  92. package/tests/iubenda.spec.ts +6 -0
  93. package/tests/la7-cmp.spec.ts +6 -0
  94. package/tests/laravel-cookie-consent.spec.ts +10 -0
  95. package/tests/legislation-gov-uk.spec.ts +3 -0
  96. package/tests/mackeeper.spec.ts +3 -0
  97. package/tests/ndl-go-jp.spec.ts +8 -0
  98. package/tests/pandectes.spec.ts +20 -1
  99. package/tests/passle.spec.ts +8 -0
  100. package/tests/paypal-us.spec.ts +2 -3
  101. package/tests/primeconsent.spec.ts +11 -0
  102. package/tests/shinden.pl.spec.ts +5 -0
  103. package/tests/texas-instruments.spec.ts +3 -0
  104. package/tests/thegrandyork.spec.ts +3 -0
  105. package/tests/thenounproject.spec.ts +3 -0
  106. package/tests/tri-table.spec.ts +5 -0
  107. package/tests/truevault-polaris.spec.ts +9 -0
  108. package/tests/uft-cookie-notice.spec.ts +3 -0
  109. package/tests/wbd-legal-terms.spec.ts +18 -0
  110. package/tests/webflow.spec.ts +7 -1
  111. package/tests/wix.spec.ts +8 -1
  112. package/tests-wtr/heuristics/button-classification-accuracy.test.ts +41 -0
  113. package/tests-wtr/heuristics/heuristics-utils.test.ts +64 -0
  114. package/rules/autoconsent/paypal-cookieprefs.json +0 -29
  115. package/tests/paypal-cookieprefs.spec.ts +0 -7
@@ -78,6 +78,27 @@ describe('checkHeuristicPatterns', () => {
78
78
  });
79
79
  });
80
80
 
81
+ describe('checkHeuristicPatterns with a qualifier before "cookies"', () => {
82
+ it('detects "we use <qualifier> cookies" notices', () => {
83
+ const texts = [
84
+ // openrouter.ai
85
+ 'Cookie Preferences We use essential cookies for site functionality and optional cookies for analytics.',
86
+ 'We use optional cookies to measure traffic',
87
+ 'We use analytics cookies and similar technologies',
88
+ 'We serve necessary cookies only',
89
+ ];
90
+ for (const text of texts) {
91
+ expect(checkHeuristicPatterns(text).patterns.length, text).to.be.greaterThan(0);
92
+ }
93
+ });
94
+
95
+ it('does not match when "cookies" is further away', () => {
96
+ expect(checkHeuristicPatterns('We use the best chocolate in our cookies', [/we use(?: \w+)? cookies/gi]).patterns).to.have.length(
97
+ 0,
98
+ );
99
+ });
100
+ });
101
+
81
102
  describe('checkHeuristicPatterns with Russian popups', () => {
82
103
  it('detects Russian cookie notices', () => {
83
104
  const texts = [
@@ -103,6 +124,23 @@ describe('checkHeuristicPatterns with Russian popups', () => {
103
124
  });
104
125
  });
105
126
 
127
+ describe('checkHeuristicPatterns with Japanese popups', () => {
128
+ it('detects Japanese cookie notices', () => {
129
+ const texts = [
130
+ '当サイトはサービス改善のためCookieを使用しています。',
131
+ '当ウェブサイトではクッキーを利用しています',
132
+ 'このサイトはクッキー(Cookie)を使用しています',
133
+ ];
134
+ for (const text of texts) {
135
+ expect(checkHeuristicPatterns(text).patterns.length, text).to.be.greaterThan(0);
136
+ }
137
+ });
138
+
139
+ it('does not detect unrelated Japanese text', () => {
140
+ expect(checkHeuristicPatterns('全国の旧車イベント情報を集約しています').patterns).to.have.length(0);
141
+ });
142
+ });
143
+
106
144
  describe('isExcludedPopup', () => {
107
145
  it('flags doublelist-style age verification popups', () => {
108
146
  // Real-world text from the doublelist.com age gate (listings page)
@@ -188,6 +226,12 @@ describe('classifyButtonTextRegex', () => {
188
226
  expect(classifyButtonTextRegex('I do not accept the use of cookies')).to.equal('reject');
189
227
  });
190
228
 
229
+ it('matches CCPA "do not sell/share" variants', () => {
230
+ expect(classifyButtonTextRegex('Do Not Sell or Share My Personal Information')).to.equal('reject');
231
+ expect(classifyButtonTextRegex('Do Not Share My Personal Information')).to.equal('reject');
232
+ expect(classifyButtonTextRegex('Do not share my data')).to.equal('reject');
233
+ });
234
+
191
235
  it('matches German continue-without-accepting variants', () => {
192
236
  expect(classifyButtonTextRegex('Ohne Akzeptieren fortfahren')).to.equal('reject');
193
237
  expect(classifyButtonTextRegex('Ohne zu akzeptieren fortfahren')).to.equal('reject');
@@ -207,6 +251,7 @@ describe('classifyButtonTextRegex', () => {
207
251
  expect(classifyButtonTextRegex('Essential Only')).to.equal('reject');
208
252
  expect(classifyButtonTextRegex('Only use essential cookies')).to.equal('reject');
209
253
  expect(classifyButtonTextRegex('Only accept necessary cookies')).to.equal('reject');
254
+ expect(classifyButtonTextRegex('Essential only cookies')).to.equal('reject');
210
255
  });
211
256
 
212
257
  it('does not classify bare essential category labels as reject choices', () => {
@@ -228,6 +273,17 @@ describe('classifyButtonTextRegex', () => {
228
273
  expect(classifyButtonTextRegex('Не принимаю')).to.equal('reject');
229
274
  });
230
275
 
276
+ it('matches Japanese reject buttons', () => {
277
+ expect(classifyButtonTextRegex('拒否')).to.equal('reject');
278
+ expect(classifyButtonTextRegex('すべて拒否')).to.equal('reject');
279
+ expect(classifyButtonTextRegex('全て拒否する')).to.equal('reject');
280
+ expect(classifyButtonTextRegex('Cookieを拒否')).to.equal('reject');
281
+ expect(classifyButtonTextRegex('同意しない')).to.equal('reject');
282
+ expect(classifyButtonTextRegex('すべて 拒否')).to.equal('reject');
283
+ expect(classifyButtonTextRegex('同意しません')).to.equal('reject');
284
+ expect(classifyButtonTextRegex('同意して続ける')).not.to.equal('reject');
285
+ });
286
+
231
287
  it('matches Russian settings buttons', () => {
232
288
  expect(classifyButtonTextRegex('Настроить')).to.equal('settings');
233
289
  expect(classifyButtonTextRegex('Настройки')).to.equal('settings');
@@ -282,6 +338,14 @@ describe('classifyButtonTextRegex', () => {
282
338
  it('does not treat revoke links as reject buttons', () => {
283
339
  expect(classifyButtonTextRegex('Widerrufen')).to.equal('other');
284
340
  });
341
+
342
+ it('classifies accept-and-close buttons as accept', () => {
343
+ expect(classifyButtonTextRegex('Akzeptieren & Schließen')).to.equal('accept');
344
+ expect(classifyButtonTextRegex('Akzeptieren und schließen')).to.equal('accept');
345
+ expect(classifyButtonTextRegex('Zustimmen schliessen')).to.equal('accept');
346
+ expect(classifyButtonTextRegex('Accepter fermer')).to.equal('accept');
347
+ expect(classifyButtonTextRegex('Accepteren sluiten')).to.equal('accept');
348
+ });
285
349
  });
286
350
 
287
351
  describe('classifyButtons', () => {
@@ -1,29 +0,0 @@
1
- {
2
- "name": "paypal-cookieprefs",
3
- "comment": "Cookie preferences page (.privacy-sheet-content on desktop, #cookiePrefsModal on mobile). Only automate it when we got here from the banner's \"Manage your cookies\" link, which appends a query string; a user who opens the page themselves lands on it without one and must be left free to edit their own preferences.",
4
- "runContext": { "urlPattern": "^https://www\\.paypal\\.com/myaccount/privacy/cookiePrefs\\?" },
5
- "prehideSelectors": ["#cookiePrefsModal, .privacy-sheet-content"],
6
- "detectCmp": [{ "exists": "#cookiePrefsModal #formContent, .privacy-sheet-content #formContent" }],
7
- "detectPopup": [{ "visible": "#cookiePrefsModal #formContent, .privacy-sheet-content #formContent" }],
8
- "optIn": [
9
- {
10
- "click": "#formContent input[type='checkbox']:not(:checked)",
11
- "all": true,
12
- "optional": true
13
- },
14
- { "waitForThenClick": ".cookieAction #submitCookiesBtn", "timeout": 15000 }
15
- ],
16
- "optOut": [
17
- {
18
- "click": "#formContent input[type='checkbox']:checked",
19
- "all": true,
20
- "optional": true
21
- },
22
- {
23
- "comment": "In \"manage\" mode the submit button is present but its sticky bar stays hidden, so wait for existence rather than visibility.",
24
- "waitForThenClick": ".cookieAction #submitCookiesBtn",
25
- "timeout": 15000
26
- }
27
- ],
28
- "test": [{ "wait": 1000 }, { "cookieContains": "type%3Dexplicit" }]
29
- }
@@ -1,7 +0,0 @@
1
- import generateCMPTests from '../playwright/runner';
2
-
3
- // Only the banner's "Manage your cookies" link (which appends a locale query string) should be
4
- // automated. Opening the same page without a query string is a deliberate user visit and is left
5
- // untouched, so it is not covered here.
6
- generateCMPTests('paypal-cookieprefs', ['https://www.paypal.com/myaccount/privacy/cookiePrefs?locale=en_US'], {});
7
- generateCMPTests('paypal-cookieprefs', ['https://www.paypal.com/myaccount/privacy/cookiePrefs?locale=en_US'], { mobile: true });