@duckduckgo/autoconsent 14.68.0 → 14.69.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.
package/AGENTS.md CHANGED
@@ -41,6 +41,10 @@ npm run watch # auto-rebuild on changes to lib/, addon/, rules/
41
41
  | `npm run build-rules` | Rebuild `rules.json`, `consentomatic.json`, `compact-rules.json` |
42
42
  | `npm run create-rule` | Scaffold a new JSON rule + test spec |
43
43
 
44
+ ## Code Style
45
+
46
+ - **Preserve existing comments.** Do not remove JSDoc comments, TODO comments, or inline explanations unless the related code is also being removed. Rewriting a comment to reflect updated logic is fine.
47
+
44
48
  ## Working with Rules
45
49
 
46
50
  ### JSON Rules
@@ -55,7 +59,8 @@ JSON rules live in `rules/autoconsent/` (hand-maintained) and `rules/generated/`
55
59
  "detectPopup": [{ "visible": "#cookie-banner" }],
56
60
  "optIn": [{ "waitForThenClick": "#accept-all" }],
57
61
  "optOut": [{ "waitForThenClick": "#reject-all" }],
58
- "test": [{ "cookieContains": "consent=rejected" }]
62
+ "test": [{ "cookieContains": "consent=rejected" }],
63
+ "minimumRuleStepVersion": 1
59
64
  }
60
65
  ```
61
66
 
@@ -67,6 +72,16 @@ For the complete rule syntax reference (all step types, element selectors, condi
67
72
 
68
73
  Keep prehideSelectors **narrow** — they are applied across all matching rules simultaneously, so an overly broad selector (e.g. `body`) could hide the entire page during the 2-second window.
69
74
 
75
+ ### minimumRuleStepVersion
76
+
77
+ New step types are added to the autoconsent engine over time. `minimumRuleStepVersion` declares which version of the step format a rule requires. Clients that don't support the required version silently skip the rule, preventing failures on older app versions.
78
+
79
+ **Version history:**
80
+ - `1` (default) — all original step types (`exists`, `visible`, `waitFor`, `click`, `waitForThenClick`, `wait`, `hide`, `if`/`then`/`else`, `any`, `eval`, `cookieContains`, etc.)
81
+ - `2` — added `removeClass`, `setStyle`, `addStyle`
82
+
83
+ **When to set it:** Omit the field (or set to `1`) if the rule only uses original step types. Set to `2` if the rule uses `removeClass`, `setStyle`, or `addStyle`. When future versions add new step types, set accordingly.
84
+
70
85
  ### Code-Based Rules
71
86
 
72
87
  For CMPs requiring complex non-linear logic, CMP API interaction, or complex multi-path flows, use a TypeScript class extending `AutoConsentCMPBase` in `lib/cmps/`. Examples: `sourcepoint-frame.ts`, `onetrust.ts`, `cookiebot.ts`, `consentmanager.ts`.
@@ -97,16 +112,17 @@ When writing or reviewing selectors, also watch out for:
97
112
 
98
113
  ### Identifying Broken Rules
99
114
 
100
- 1. **Playwright test failures** are the primary signal. Run the specific test:
115
+ 1. **Use a real browser** to investigate. A real browser in a computer-use subagent is **highly preferred** over Playwright or Puppeteer-based scripts — cookie popups often behave differently in headless/automated browsers.
116
+ 2. **Playwright test failures** are a secondary signal. Run the specific test:
101
117
  ```bash
102
118
  npx playwright test tests/sirdata.spec.ts --project webkit
103
119
  ```
104
- 2. **Check test output** for which stage failed: `cmpDetected`, `popupFound`, `autoconsentDone`, `optOutResult`, `selfTestResult`.
105
- 3. **Use the test extension** (`dist/addon-mv3/`) for manual debugging. Load it in Chrome, visit the site, and check the devtools panel for step-by-step logs.
120
+ 3. **Check test output** for which stage failed: `cmpDetected`, `popupFound`, `autoconsentDone`, `optOutResult`, `selfTestResult`.
121
+ 4. **Use the test extension** (`dist/addon-mv3/`) for manual debugging. Load it in Chrome, visit the site, and check the devtools panel for step-by-step logs.
106
122
 
107
123
  ### Common Failure Modes
108
124
 
109
- **Race conditions:** Consent popups load asynchronously. Use `waitFor` / `waitForThenClick` / `waitForVisible` instead of bare `exists` / `click`. Add `{ "wait": 500 }` before critical actions when the CMP has known async initialization. In code-based rules, use `Promise.race()` for multiple possible UI states.
125
+ **Race conditions:** Consent popups load asynchronously. Use `waitFor` / `waitForThenClick` / `waitForVisible` instead of bare `exists` / `click`. Add `{ "wait": 500 }` before critical actions when the CMP has known async initialization. In code-based rules, use `Promise.race()` for multiple possible UI states. **Never** use `{ "wait": N }` in `detectCmp` or `detectPopup` — the engine handles retries internally.
110
126
 
111
127
  **Incorrect consent action selectors:** Generated rules sometimes target a privacy policy link instead of the reject button. Ensure `optOut` steps target an actual reject/decline button.
112
128
 
@@ -117,8 +133,11 @@ When writing or reviewing selectors, also watch out for:
117
133
  1. Read the existing rule to understand its current selectors and flow.
118
134
  2. Identify the broken step from test output or by inspecting the site.
119
135
  3. Edit the JSON file — apply the fix to every occurrence of the selector within the file (`detectCmp`, `detectPopup`, `optOut`, and `test` often use similar selectors).
120
- 4. For generated rules, the same CMP may appear across multiple region files (`auto_CH_*.json`, `auto_DE_*.json`, etc.). Apply the fix to all affected files.
121
- 5. Run `npm run lint` to validate.
136
+ 4. For site-specific rules, double-check if the popup is still site-specific. If not, consider if a generic rule is more appropriate.
137
+ 5. **Always update the corresponding test spec** in `tests/`. If no spec exists, create one.
138
+ 6. **Cross-check other rules** — search for the same selectors or CMP provider name across `rules/autoconsent/` and `rules/generated/` to find other rules that may need the same change.
139
+ 7. For generated rules, the same CMP may appear across multiple region files (`auto_CH_*.json`, `auto_DE_*.json`, etc.). Apply the fix to all affected files.
140
+ 8. Run `npm run lint` to validate.
122
141
 
123
142
  ### Fixing Code-Based Rules
124
143
 
@@ -151,11 +170,15 @@ Use `if`/`then`/`else` for region-dependent or variant-dependent flows:
151
170
  ## Adding New Rules
152
171
 
153
172
  1. Run `npm run create-rule` to scaffold the JSON + test spec.
154
- 2. Fill in `detectCmp`, `detectPopup`, `optOut`, `optIn` with stable selectors.
155
- 3. Add a `test` array prefer `cookieContains` when the CMP stores consent in cookies.
173
+ 2. **Check if the popup is from a third-party CMP provider** (e.g. OneTrust, Cookiebot, Sourcepoint). If so, prefer extending or fixing the existing generic rule rather than creating a site-specific one.
174
+ 3. Fill in `detectCmp`, `detectPopup`, `optOut`, `optIn` with stable selectors. Do **not** use `{ "wait": N }` steps in `detectCmp` or `detectPopup` detection must be fast and non-blocking (the engine retries automatically).
175
+ 4. Add a `test` array — prefer `cookieContains` when the CMP stores consent in cookies.
156
176
  - JSON rules can also use `{ "eval": "SNIPPET_NAME" }` steps to execute predefined JavaScript snippets from `lib/eval-snippets.ts`. Useful for calling CMP APIs (e.g., `window.Cookiebot`, `__cmp('getCMPData')`) in detection, opt-out, or test phases. Each snippet is a named function that returns a boolean. New snippets must be added to `lib/eval-snippets.ts` and referenced by name in the rule JSON.
157
- 4. Run `npm run lint` and `npm run test:lib`.
158
- 5. Test with Playwright: `npx playwright test tests/my-cmp.spec.ts --project webkit`.
177
+ 5. **Always create or update the corresponding test spec** in `tests/`.
178
+ 6. **Cross-check other rules** search for the same selectors or CMP provider name across `rules/autoconsent/` and `rules/generated/` to see if other rules need the same change or already cover this CMP.
179
+ 7. Use `data/coverage.json` to find example sites for testing. It contains per-CMP, per-region URLs: `{ "CmpName": { "REGION": { "exampleSites": [...] } } }`.
180
+ 8. Run `npm run lint` and `npm run test:lib`.
181
+ 9. Test with Playwright: `npx playwright test tests/my-cmp.spec.ts --project webkit`.
159
182
 
160
183
  ### When Generated Rules Need Fixes
161
184
 
@@ -234,6 +257,8 @@ If an **existing rule matched but failed**: identify the broken step from the lo
234
257
 
235
258
  If **no rule matched**: determine the CMP type. Check if the popup is from a known CMP (OneTrust, Sourcepoint, Cookiebot, etc.) by inspecting the banner's HTML, class names, and script sources. If it's a known CMP, the existing rule may need updated detection selectors. If it's unknown, create a new rule.
236
259
 
260
+ **Always check if the popup is from a third-party CMP provider.** If so, prefer creating or extending a generic rule rather than a site-specific one. Use `data/coverage.json` to find additional example sites for the same CMP to verify the rule works broadly.
261
+
237
262
  ### Step 3: Determine Rule Type
238
263
 
239
264
  - If the popup has a **reject/decline button** → create or fix a click-based rule
package/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ # v14.69.0 (Thu Apr 09 2026)
2
+
3
+ #### 🚀 Enhancement
4
+
5
+ - fix(hm.com): detect iOS cookie popup and add US opt-out flow [#1250](https://github.com/duckduckgo/autoconsent/pull/1250) ([@cursoragent](https://github.com/cursoragent) [@muodov](https://github.com/muodov))
6
+
7
+ #### 📝 Documentation
8
+
9
+ - Update docs and agent instructions [#1249](https://github.com/duckduckgo/autoconsent/pull/1249) ([@muodov](https://github.com/muodov))
10
+
11
+ #### Authors: 2
12
+
13
+ - Cursor Agent ([@cursoragent](https://github.com/cursoragent))
14
+ - Maxim Tsoy ([@muodov](https://github.com/muodov))
15
+
16
+ ---
17
+
1
18
  # v14.68.0 (Wed Apr 08 2026)
2
19
 
3
20
  #### 🚀 Enhancement