@duckduckgo/autoconsent 16.43.2 → 16.44.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/lib/regional-testing/harness.mjs +536 -0
- package/.agents/skills/oxylabs-testing/SKILL.md +99 -0
- package/.agents/skills/oxylabs-testing/scripts/oxylabs.mjs +300 -0
- package/.agents/skills/oxylabs-testing/scripts/oxylabs.test.mjs +37 -0
- package/.agents/skills/proxy-testing/SKILL.md +5 -2
- package/.agents/skills/proxy-testing/scripts/regional-proxy.mjs +22 -471
- package/.claude/skills/oxylabs-testing/SKILL.md +6 -0
- package/.claude/skills/proxy-testing/SKILL.md +1 -1
- package/.claude/user-settings.json.TEMPLATE +2 -0
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +29 -0
- package/dist/addon-firefox/background.bundle.js +9 -3
- package/dist/addon-firefox/compact-rules.json +1 -1
- package/dist/addon-firefox/manifest.json +1 -1
- package/dist/addon-firefox/popup.bundle.js +9 -3
- package/dist/addon-firefox/rule-index.json +1 -1
- package/dist/addon-firefox/rules.json +1 -1
- package/dist/addon-mv3/background.bundle.js +9 -3
- package/dist/addon-mv3/compact-rules.json +1 -1
- package/dist/addon-mv3/manifest.json +1 -1
- package/dist/addon-mv3/popup.bundle.js +9 -3
- package/dist/addon-mv3/rule-index.json +1 -1
- package/dist/addon-mv3/rules.json +1 -1
- package/dist/autoconsent.standalone.js +1 -1
- package/package.json +2 -2
- package/readme.md +1 -1
- package/rules/autoconsent/bandcamp.json +42 -3
- package/rules/autoconsent/chatgpt.json +2 -2
- package/rules/autoconsent/elsevier.json +69 -0
- package/rules/autoconsent/fides.json +10 -2
- package/rules/autoconsent/lacoccinelle.json +97 -0
- package/rules/autoconsent/woo-commerce-com.json +28 -11
- package/rules/compact-rules.json +1 -1
- package/rules/rule-index.json +1 -1
- package/rules/rules.json +1 -1
- package/tests/bandcamp.spec.ts +7 -1
- package/tests/elsevier.spec.ts +3 -0
- package/tests/fides.spec.ts +7 -1
- package/tests/lacoccinelle.spec.ts +3 -0
- package/tests/woo-commerce-com.spec.ts +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@duckduckgo/autoconsent",
|
|
3
|
-
"version": "16.
|
|
3
|
+
"version": "16.44.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"types": "./dist/types/web.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@duckduckgo/eslint-config": "github:duckduckgo/eslint-config#v0.3.0",
|
|
46
46
|
"@esm-bundle/chai": "^4.3.4-fix.0",
|
|
47
47
|
"@octokit/rest": "^22.0.1",
|
|
48
|
-
"@playwright/test": "^1.
|
|
48
|
+
"@playwright/test": "^1.63.0",
|
|
49
49
|
"@types/chai": "^5.0.0",
|
|
50
50
|
"@types/chrome": "^0.1.0",
|
|
51
51
|
"@types/mocha": "^10.0.1",
|
package/readme.md
CHANGED
|
@@ -88,7 +88,7 @@ For more details on rule types, see [Rule Syntax Reference](docs/rule-syntax.md)
|
|
|
88
88
|
The agent skills in `.agents/skills/` need a few environment variables.
|
|
89
89
|
|
|
90
90
|
1. Copy the contents from [`.claude/user-settings.json.TEMPLATE`](.claude/user-settings.json.TEMPLATE) to your user settings (e.g. `~/.claude/settings.json`), in addition to your existing config. If your settings already have an `env` block, merge the entries into it: a second `env` key would silently override the first.
|
|
91
|
-
2. Replace the values in the template. Proxy values must be complete URLs with an `http://`, `https://`, or `socks5://` scheme, and without embedded credentials. `REGIONAL_PROXY_USERNAME` and `REGIONAL_PROXY_PASSWORD` are optional: they are only used for `https://` proxies, so remove them if your proxies don't need authentication.
|
|
91
|
+
2. Replace the values in the template. Proxy values must be complete URLs with an `http://`, `https://`, or `socks5://` scheme, and without embedded credentials. `REGIONAL_PROXY_USERNAME` and `REGIONAL_PROXY_PASSWORD` are optional: they are only used for `https://` proxies, so remove them if your proxies don't need authentication. `OXYLABS_USER` and `OXYLABS_PASSWORD` are optional too: they enable the `oxylabs-testing` skill for sites that show our proxies a bot wall, so remove them if you don't have an Oxylabs account.
|
|
92
92
|
3. Start a new Claude Code session: settings are only read at startup.
|
|
93
93
|
|
|
94
94
|
For other agents or plain shell use, `export` the same variables in your shell profile instead.
|
|
@@ -10,20 +10,59 @@
|
|
|
10
10
|
],
|
|
11
11
|
"detectPopup": [
|
|
12
12
|
{
|
|
13
|
-
"
|
|
13
|
+
"any": [
|
|
14
|
+
{
|
|
15
|
+
"visible": ".cookie-dialog-initial"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"visible": ["menu-bar", ".cookie-dialog-initial"]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"visible": ["page-footer", ".cookie-dialog-initial"]
|
|
22
|
+
}
|
|
23
|
+
]
|
|
14
24
|
}
|
|
15
25
|
],
|
|
16
26
|
"optIn": [
|
|
17
27
|
{
|
|
18
|
-
"
|
|
28
|
+
"any": [
|
|
29
|
+
{
|
|
30
|
+
"waitForThenClick": ".cookie-dialog-initial button.g-button[type=\"submit\"]",
|
|
31
|
+
"timeout": 500
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"waitForThenClick": ["menu-bar", ".cookie-dialog-initial button.g-button[type=\"submit\"]"],
|
|
35
|
+
"timeout": 500
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"waitForThenClick": ["page-footer", ".cookie-dialog-initial button.g-button[type=\"submit\"]"],
|
|
39
|
+
"timeout": 500
|
|
40
|
+
}
|
|
41
|
+
]
|
|
19
42
|
}
|
|
20
43
|
],
|
|
21
44
|
"optOut": [
|
|
22
45
|
{
|
|
23
|
-
"
|
|
46
|
+
"any": [
|
|
47
|
+
{
|
|
48
|
+
"waitForThenClick": ".cookie-dialog-initial button.g-button.outline",
|
|
49
|
+
"timeout": 500
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"waitForThenClick": ["menu-bar", ".cookie-dialog-initial button.g-button.outline"],
|
|
53
|
+
"timeout": 500
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"waitForThenClick": ["page-footer", ".cookie-dialog-initial button.g-button.outline"],
|
|
57
|
+
"timeout": 500
|
|
58
|
+
}
|
|
59
|
+
]
|
|
24
60
|
}
|
|
25
61
|
],
|
|
26
62
|
"test": [
|
|
63
|
+
{
|
|
64
|
+
"wait": 500
|
|
65
|
+
},
|
|
27
66
|
{
|
|
28
67
|
"cookieContains": "cookie_preferences=%7B%22allow%22%3A%5B%5D"
|
|
29
68
|
}
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"frame": false,
|
|
10
10
|
"urlPattern": "^https?://(\\w+\\.)?chatgpt\\.com/"
|
|
11
11
|
},
|
|
12
|
-
"comment": "Covers the server-rendered consent dialog. Once the app hydrates it swaps in a banner whose buttons are only distinguishable by text, which the heuristic rule handles better.",
|
|
13
|
-
"prehideSelectors": ["dialog[data-cookie-consent]:has(form[data-privacy-consent-form])"],
|
|
12
|
+
"comment": "Covers the server-rendered consent dialog. Once the app hydrates it swaps in a banner whose buttons are only distinguishable by text, which the heuristic rule handles better. Below 48rem the site reopens the dialog with showModal() and marks it aria-modal, so prehiding it would leave the page inert with nothing visible to dismiss.",
|
|
13
|
+
"prehideSelectors": ["dialog[data-cookie-consent]:not([aria-modal]):has(form[data-privacy-consent-form])"],
|
|
14
14
|
"detectCmp": [
|
|
15
15
|
{
|
|
16
16
|
"exists": "dialog[data-cookie-consent] form[data-privacy-consent-form] input[name=\"action\"][value=\"reject\"]"
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "elsevier",
|
|
3
|
+
"vendorUrl": "https://www.elsevier.com/",
|
|
4
|
+
"runContext": {
|
|
5
|
+
"urlPattern": "^https?://(\\w+\\.)?elsevier\\.(com|support)/"
|
|
6
|
+
},
|
|
7
|
+
"prehideSelectors": ["[data-testid=\"cookie-banner\"]"],
|
|
8
|
+
"detectCmp": [
|
|
9
|
+
{
|
|
10
|
+
"exists": "[data-testid=\"cookie-banner\"] [data-testid=\"cookie-settings-button\"]"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"detectPopup": [
|
|
14
|
+
{
|
|
15
|
+
"visible": "[data-testid=\"cookie-banner\"] [data-testid=\"cookie-settings-button\"]"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"optIn": [
|
|
19
|
+
{
|
|
20
|
+
"waitForThenClick": "[data-testid=\"accept-all-cookies-button\"]"
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"optOut": [
|
|
24
|
+
{
|
|
25
|
+
"if": {
|
|
26
|
+
"exists": "[data-testid=\"reject-all-cookies-button\"]"
|
|
27
|
+
},
|
|
28
|
+
"then": [
|
|
29
|
+
{
|
|
30
|
+
"comment": "the banner is rendered before React attaches its click handler, so a lost first click needs a retry",
|
|
31
|
+
"waitForThenClick": "[data-testid=\"reject-all-cookies-button\"]",
|
|
32
|
+
"retry": 3,
|
|
33
|
+
"retryInterval": 1000
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"else": [
|
|
37
|
+
{
|
|
38
|
+
"comment": "no reject button on the banner: open the OneTrust preference center it controls and reject there",
|
|
39
|
+
"waitForThenClick": "[data-testid=\"cookie-settings-button\"]",
|
|
40
|
+
"retry": 3,
|
|
41
|
+
"retryInterval": 1000
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"waitForVisible": "#onetrust-pc-sdk",
|
|
45
|
+
"timeout": 10000
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"waitForThenClick": "#onetrust-pc-sdk input.category-switch-handler:checked",
|
|
49
|
+
"all": true,
|
|
50
|
+
"optional": true
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"waitForThenClick": "#onetrust-pc-sdk .save-preference-btn-handler",
|
|
54
|
+
"timeout": 5000
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"waitForVisible": "[data-testid=\"cookie-banner\"]",
|
|
60
|
+
"check": "none",
|
|
61
|
+
"timeout": 10000
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"test": [
|
|
65
|
+
{
|
|
66
|
+
"cookieContains": "OptanonAlertBoxClosed"
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
}
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
{
|
|
12
12
|
"visible": "#fides-overlay-wrapper #fides-banner"
|
|
13
13
|
},
|
|
14
|
+
{
|
|
15
|
+
"visible": "#fides-overlay-wrapper .fides-banner-hidden",
|
|
16
|
+
"check": "none"
|
|
17
|
+
},
|
|
14
18
|
{
|
|
15
19
|
"eval": "EVAL_FIDES_DETECT_POPUP"
|
|
16
20
|
}
|
|
@@ -30,7 +34,9 @@
|
|
|
30
34
|
},
|
|
31
35
|
"then": [
|
|
32
36
|
{
|
|
33
|
-
"
|
|
37
|
+
"waitForThenClick": ".fides-banner:not(.fides-banner-hidden) .fides-reject-all-button",
|
|
38
|
+
"retry": 5,
|
|
39
|
+
"retryInterval": 500
|
|
34
40
|
}
|
|
35
41
|
],
|
|
36
42
|
"else": [
|
|
@@ -38,7 +44,9 @@
|
|
|
38
44
|
"click": "#fides-banner .fides-manage-preferences-button"
|
|
39
45
|
},
|
|
40
46
|
{
|
|
41
|
-
"waitForThenClick": ".fides-reject-all-button"
|
|
47
|
+
"waitForThenClick": ".fides-modal-content .fides-reject-all-button",
|
|
48
|
+
"retry": 5,
|
|
49
|
+
"retryInterval": 500
|
|
42
50
|
}
|
|
43
51
|
]
|
|
44
52
|
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lacoccinelle",
|
|
3
|
+
"vendorUrl": "https://www.lacoccinelle.net/",
|
|
4
|
+
"runContext": {
|
|
5
|
+
"urlPattern": "^https?://(\\w+\\.)?lacoccinelle\\.net/"
|
|
6
|
+
},
|
|
7
|
+
"prehideSelectors": ["#qc-cmp2-container"],
|
|
8
|
+
"detectCmp": [
|
|
9
|
+
{
|
|
10
|
+
"exists": "#qc-cmp2-container"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"detectPopup": [
|
|
14
|
+
{
|
|
15
|
+
"visible": "#qc-cmp2-ui, #qc-cmp2-usp",
|
|
16
|
+
"check": "any"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"optIn": [
|
|
20
|
+
{
|
|
21
|
+
"if": {
|
|
22
|
+
"exists": "#qc-cmp2-usp"
|
|
23
|
+
},
|
|
24
|
+
"then": [
|
|
25
|
+
{
|
|
26
|
+
"waitForThenClick": "#qc-cmp2-usp .qc-usp-close-icon"
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"else": [
|
|
30
|
+
{
|
|
31
|
+
"waitForThenClick": "#accept-btn"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"optOut": [
|
|
37
|
+
{
|
|
38
|
+
"if": {
|
|
39
|
+
"exists": "#qc-cmp2-usp"
|
|
40
|
+
},
|
|
41
|
+
"then": [
|
|
42
|
+
{
|
|
43
|
+
"waitForThenClick": "#qc-cmp2-usp .qc-cmp2-toggle-switch > button[aria-checked=\"false\"]",
|
|
44
|
+
"all": true,
|
|
45
|
+
"retry": 3
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"waitForThenClick": "#qc-cmp2-usp .qc-usp-ui-content button[mode=\"primary\"]"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"waitForThenClick": "#qc-cmp2-mspa-success-modal-button-footer-container button",
|
|
52
|
+
"timeout": 5000,
|
|
53
|
+
"optional": true
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
"else": [
|
|
57
|
+
{
|
|
58
|
+
"comment": "the \"more options\" button is repurposed as a paid offer, the partner list is the only free reject path",
|
|
59
|
+
"waitForThenClick": "#qc-cmp2-container button.qc-cmp2-link-inline"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"waitForThenClick": "#reject-all-btn"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"comment": "outside the EEA the choice is not saved automatically",
|
|
66
|
+
"waitForVisible": "#qc-cmp2-ui",
|
|
67
|
+
"check": "none",
|
|
68
|
+
"timeout": 1500,
|
|
69
|
+
"optional": true
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"if": {
|
|
73
|
+
"visible": "#save-and-exit",
|
|
74
|
+
"check": "any"
|
|
75
|
+
},
|
|
76
|
+
"then": [
|
|
77
|
+
{
|
|
78
|
+
"click": "#save-and-exit",
|
|
79
|
+
"all": true
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"waitForVisible": "#qc-cmp2-ui",
|
|
83
|
+
"check": "none",
|
|
84
|
+
"timeout": 5000
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
],
|
|
91
|
+
"test": [
|
|
92
|
+
{
|
|
93
|
+
"visible": "#qc-cmp2-ui, #qc-cmp2-usp",
|
|
94
|
+
"check": "none"
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
}
|
|
@@ -1,19 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "woo-commerce-com",
|
|
3
|
+
"comment": "The banner renders its buttons disabled until it is ready, and clicks before that are ignored, so every click waits for :not([disabled]).",
|
|
3
4
|
"prehideSelectors": [".wccom-comp-privacy-banner .wccom-privacy-banner"],
|
|
4
5
|
"detectCmp": [{ "exists": ".wccom-comp-privacy-banner .wccom-privacy-banner" }],
|
|
5
|
-
"detectPopup": [{ "
|
|
6
|
-
"optIn": [{ "
|
|
6
|
+
"detectPopup": [{ "visible": ".wccom-comp-privacy-banner .wccom-privacy-banner" }],
|
|
7
|
+
"optIn": [{ "waitForThenClick": ".wccom-privacy-banner__content-buttons button.is-style-primary:not([disabled])" }],
|
|
7
8
|
"optOut": [
|
|
8
9
|
{
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
10
|
+
"comment": "'Reject all' is only offered in some regions: it is the secondary button followed by another secondary ('Customize')",
|
|
11
|
+
"if": { "exists": ".wccom-privacy-banner__content-buttons button.is-style-secondary:has(+ button.is-style-secondary)" },
|
|
12
|
+
"then": [
|
|
13
|
+
{
|
|
14
|
+
"waitForThenClick": ".wccom-privacy-banner__content-buttons button.is-style-secondary:not([disabled]):has(+ button.is-style-secondary)"
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"else": [
|
|
18
|
+
{
|
|
19
|
+
"waitForThenClick": ".wccom-privacy-banner__content-buttons button.is-style-secondary:not([disabled]):has(+ button.is-style-primary)"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"waitForVisible": ".wccom-modal__footer button.is-style-primary"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"click": ".wccom-customize-privacy-checkbox input[type=checkbox]:checked:not([disabled])",
|
|
26
|
+
"all": true,
|
|
27
|
+
"optional": true
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"waitForThenClick": ".wccom-modal__footer button.is-style-primary:not([disabled])"
|
|
31
|
+
}
|
|
32
|
+
]
|
|
17
33
|
}
|
|
18
|
-
]
|
|
34
|
+
],
|
|
35
|
+
"test": [{ "cookieContains": "wccom_cookie_consent_analytics=denied" }]
|
|
19
36
|
}
|