Page Prep
adobe/skills
Prepare any webpage for clean interaction by detecting and removing disruptive overlays (cookie banners, GDPR consent, modals, popups, newsletter signups, paywalls, login walls).
Automated cookie consent validation using Selenium and Playwright.
$ npx skills add mukul975/Privacy-Data-Protection-Skills --skill cookie-consent-testing -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install mukul975/Privacy-Data-Protection-Skills cookie-consent-testing --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/mukul975/Privacy-Data-Protection-Skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/privacy/cookie-consent-testing .claude/skills/cookie-consent-testing && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "cookie-consent-testing" agent skill from https://github.com/mukul975/Privacy-Data-Protection-Skills/tree/main/skills/privacy/cookie-consent-testing into .claude/skills/cookie-consent-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cookie-consent-testing", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/mukul975/Privacy-Data-Protection-Skills/tree/main/skills/privacy/cookie-consent-testingType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add mukul975/Privacy-Data-Protection-Skills --skill cookie-consent-testing -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install mukul975/Privacy-Data-Protection-Skills cookie-consent-testing --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mukul975/Privacy-Data-Protection-Skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/privacy/cookie-consent-testing .agents/skills/cookie-consent-testing && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "cookie-consent-testing" agent skill from https://github.com/mukul975/Privacy-Data-Protection-Skills/tree/main/skills/privacy/cookie-consent-testing into .agents/skills/cookie-consent-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cookie-consent-testing", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add mukul975/Privacy-Data-Protection-Skills --skill cookie-consent-testing -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install mukul975/Privacy-Data-Protection-Skills cookie-consent-testing --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mukul975/Privacy-Data-Protection-Skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/privacy/cookie-consent-testing .cursor/skills/cookie-consent-testing && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "cookie-consent-testing" agent skill from https://github.com/mukul975/Privacy-Data-Protection-Skills/tree/main/skills/privacy/cookie-consent-testing into .cursor/skills/cookie-consent-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cookie-consent-testing", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/mukul975/Privacy-Data-Protection-Skills.git --path skills/privacy/cookie-consent-testing--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add mukul975/Privacy-Data-Protection-Skills --skill cookie-consent-testing -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install mukul975/Privacy-Data-Protection-Skills cookie-consent-testing --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mukul975/Privacy-Data-Protection-Skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/privacy/cookie-consent-testing .gemini/skills/cookie-consent-testing && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "cookie-consent-testing" agent skill from https://github.com/mukul975/Privacy-Data-Protection-Skills/tree/main/skills/privacy/cookie-consent-testing into .gemini/skills/cookie-consent-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cookie-consent-testing", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install mukul975/Privacy-Data-Protection-Skills cookie-consent-testingInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add mukul975/Privacy-Data-Protection-Skills --skill cookie-consent-testing -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/mukul975/Privacy-Data-Protection-Skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/privacy/cookie-consent-testing .github/skills/cookie-consent-testing && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "cookie-consent-testing" agent skill from https://github.com/mukul975/Privacy-Data-Protection-Skills/tree/main/skills/privacy/cookie-consent-testing into .github/skills/cookie-consent-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cookie-consent-testing", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add mukul975/Privacy-Data-Protection-Skills --skill cookie-consent-testing -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install mukul975/Privacy-Data-Protection-Skills cookie-consent-testing --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mukul975/Privacy-Data-Protection-Skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/privacy/cookie-consent-testing .opencode/skills/cookie-consent-testing && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "cookie-consent-testing" agent skill from https://github.com/mukul975/Privacy-Data-Protection-Skills/tree/main/skills/privacy/cookie-consent-testing into .opencode/skills/cookie-consent-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cookie-consent-testing", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
cookie-consent-testingAutomated cookie consent validation using Selenium and Playwright.
Cookie Consent Testing is an agent skill from mukul975/Privacy-Data-Protection-Skills. Automated cookie consent validation using Selenium and Playwright. Covers banner interaction testing, consent state verification, tag firing audit after consent choices, regression testing for cookie compliance, and CI/CD pipeline integration.
Its SKILL.md is about 4.8k tokens, which your agent loads only when the skill is triggered. The skill folder holds 7 other files, including scripts, reference files and assets (for example `assets/template.md`, `references/standards.md` and `references/workflows.md`).
It sits in Testing & QA, covering Privacy and GDPR and Browser testing. It works with Playwright and Selenium. The repository describes itself as: 282+ structured privacy & data protection skills for AI agents. GDPR, CCPA, EU AI Act, HIPAA, LGPD, PIPL, DPDP Act. The licence is Apache-2.0.
Read from SKILL.md and the folder at commit 9b2ef9e. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 1 file in scripts/ (Python), which the agent can run.
From the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
staging.pinnacle-ecommerce.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Cookie Consent Testing loads about 4.8k tokens when it runs, and up to ~5.8k if it reads all its reference files. Until then it costs about 67 tokens; SKILL.md has 347 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from mukul975/Privacy-Data-Protection-Skills at commit 9b2ef9e, republished under its Apache-2.0 licence (© mukul975). 347 words, ~4,811 tokens.
.claude/skills/cookie-consent-testing/SKILL.md (or your agent's skills folder). This skill also uses 4 other files; get the full folder from GitHub.Manual cookie consent testing is insufficient for modern web applications where deployments occur multiple times daily and third-party scripts update independently. Automated testing using browser automation frameworks — Selenium and Playwright — enables continuous verification that the cookie consent banner functions correctly, that non-essential cookies are blocked before consent, that consent choices are respected, and that tag firing aligns with the user's consent state. Integrating these tests into the CI/CD pipeline ensures that every deployment is verified for cookie compliance before reaching production.
| Category | What It Tests | When to Run |
|---|---|---|
| Banner display | Banner appears on first visit; correct layout and text | Every deployment |
| Pre-consent blocking | No non-essential cookies/tags before user interaction | Every deployment |
| Consent acceptance | Accept All sets correct cookies and fires correct tags | Every deployment |
| Consent rejection | Reject All blocks all non-essential cookies and tags | Every deployment |
| Granular consent | Per-category toggles work correctly | Every deployment |
| Consent persistence | Consent state survives page navigation and browser restart | Daily |
| Consent withdrawal | Changing consent removes cookies and stops tags | Weekly |
| Consent expiry | Banner re-appears after consent expires | Monthly |
| GPC signal | GPC header triggers automatic opt-out | Every deployment |
| Regression | New cookies not introduced without documentation | Every deployment |
Playwright Configuration for Pinnacle E-Commerce Ltd:
// playwright.config.js
const { defineConfig, devices } = require('@playwright/test');
module.exports = defineConfig({
testDir: './tests/cookie-consent',
timeout: 30000,
retries: 1,
use: {
baseURL: 'https://staging.pinnacle-ecommerce.com',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
{
name: 'mobile-chrome',
use: { ...devices['Pixel 5'] },
},
{
name: 'mobile-safari',
use: { ...devices['iPhone 13'] },
},
],
});Verify that no non-essential cookies are set before the user interacts with the consent banner.
// tests/cookie-consent/pre-consent-blocking.spec.js
const { test, expect } = require('@playwright/test');
const ESSENTIAL_COOKIES = [
'session_id',
'csrf_token',
'consent_state',
'load_balancer',
'pinnacle_consent_eu',
'pinnacle_consent_uk',
'pinnacle_consent_ccpa',
];
const NON_ESSENTIAL_COOKIES = [
'_ga',
'_ga_',
'_gid',
'_fbp',
'_fbc',
'_gcl_au',
'_hjSession',
'_hjSessionUser',
'IDE',
'fr',
'NID',
];
test.describe('Pre-Consent Cookie Blocking', () => {
test('no non-essential cookies are set on page load before consent', async ({ page }) => {
// Navigate to homepage without any prior consent
await page.goto('/');
// Wait for page to fully load including all third-party scripts
await page.waitForLoadState('networkidle');
// Get all cookies
const cookies = await page.context().cookies();
const cookieNames = cookies.map(c => c.name);
// Verify no non-essential cookies exist
for (const nonEssential of NON_ESSENTIAL_COOKIES) {
const found = cookieNames.filter(name => name.startsWith(nonEssential));
expect(found, `Non-essential cookie ${nonEssential} found before consent`).toHaveLength(0);
}
});
test('no analytics network requests before consent', async ({ page }) => {
const analyticsRequests = [];
// Monitor network requests
page.on('request', request => {
const url = request.url();
if (
url.includes('google-analytics.com') ||
url.includes('analytics.google.com') ||
url.includes('facebook.com/tr') ||
url.includes('connect.facebook.net') ||
url.includes('hotjar.com')
) {
analyticsRequests.push(url);
}
});
await page.goto('/');
await page.waitForLoadState('networkidle');
expect(analyticsRequests, 'Analytics requests fired before consent').toHaveLength(0);
});
test('no localStorage tracking entries before consent', async ({ page }) => {
await page.goto('/');
await page.waitForLoadState('networkidle');
const trackingKeys = await page.evaluate(() => {
const suspicious = [];
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key.startsWith('_hj') || key.startsWith('_ga') || key.includes('fb_')) {
suspicious.push(key);
}
}
return suspicious;
});
expect(trackingKeys, 'Tracking localStorage entries found before consent').toHaveLength(0);
});
});// tests/cookie-consent/banner-display.spec.js
const { test, expect } = require('@playwright/test');
test.describe('Cookie Banner Display', () => {
test('banner appears on first visit', async ({ page }) => {
await page.goto('/');
// Banner should be visible
const banner = page.locator('[data-testid="cookie-banner"]');
await expect(banner).toBeVisible();
});
test('banner has Accept All button', async ({ page }) => {
await page.goto('/');
const acceptButton = page.locator('[data-testid="cookie-accept-all"]');
await expect(acceptButton).toBeVisible();
await expect(acceptButton).toHaveText(/Accept All/i);
});
test('banner has Reject All button with equal prominence', async ({ page }) => {
await page.goto('/');
const acceptButton = page.locator('[data-testid="cookie-accept-all"]');
const rejectButton = page.locator('[data-testid="cookie-reject-all"]');
await expect(rejectButton).toBeVisible();
await expect(rejectButton).toHaveText(/Reject All/i);
// Verify equal visual prominence (same size)
const acceptBox = await acceptButton.boundingBox();
const rejectBox = await rejectButton.boundingBox();
expect(Math.abs(acceptBox.width - rejectBox.width)).toBeLessThan(10);
expect(Math.abs(acceptBox.height - rejectBox.height)).toBeLessThan(5);
});
test('banner has Customise/Manage Preferences option', async ({ page }) => {
await page.goto('/');
const customiseButton = page.locator('[data-testid="cookie-customise"]');
await expect(customiseButton).toBeVisible();
});
test('banner does not reappear after making a choice', async ({ page }) => {
await page.goto('/');
await page.locator('[data-testid="cookie-accept-all"]').click();
// Navigate to another page
await page.goto('/products');
await page.waitForLoadState('networkidle');
const banner = page.locator('[data-testid="cookie-banner"]');
await expect(banner).not.toBeVisible();
});
test('banner is keyboard accessible', async ({ page }) => {
await page.goto('/');
await page.keyboard.press('Tab');
// Focus should be within the banner
const focusedElement = await page.evaluate(() => {
const el = document.activeElement;
return el ? el.closest('[data-testid="cookie-banner"]') !== null : false;
});
expect(focusedElement).toBe(true);
});
});// tests/cookie-consent/consent-state.spec.js
const { test, expect } = require('@playwright/test');
test.describe('Consent State Verification', () => {
test('Accept All sets all consent categories to granted', async ({ page }) => {
await page.goto('/');
await page.locator('[data-testid="cookie-accept-all"]').click();
await page.waitForLoadState('networkidle');
const cookies = await page.context().cookies();
const consentCookie = cookies.find(c => c.name === 'pinnacle_consent_eu');
expect(consentCookie).toBeTruthy();
const consentState = JSON.parse(decodeURIComponent(consentCookie.value));
expect(consentState.analytics).toBe(true);
expect(consentState.advertising).toBe(true);
expect(consentState.functionality).toBe(true);
});
test('Reject All sets all consent categories to denied', async ({ page }) => {
await page.goto('/');
await page.locator('[data-testid="cookie-reject-all"]').click();
await page.waitForLoadState('networkidle');
const cookies = await page.context().cookies();
const consentCookie = cookies.find(c => c.name === 'pinnacle_consent_eu');
expect(consentCookie).toBeTruthy();
const consentState = JSON.parse(decodeURIComponent(consentCookie.value));
expect(consentState.analytics).toBe(false);
expect(consentState.advertising).toBe(false);
expect(consentState.functionality).toBe(false);
});
test('Reject All blocks GA4 cookies', async ({ page }) => {
await page.goto('/');
await page.locator('[data-testid="cookie-reject-all"]').click();
await page.waitForLoadState('networkidle');
// Navigate to multiple pages to give GA4 time to attempt cookie setting
await page.goto('/products');
await page.waitForLoadState('networkidle');
await page.goto('/about');
await page.waitForLoadState('networkidle');
const cookies = await page.context().cookies();
const gaCookies = cookies.filter(c => c.name.startsWith('_ga'));
expect(gaCookies).toHaveLength(0);
});
test('Granular consent: analytics only sets only analytics cookies', async ({ page }) => {
await page.goto('/');
// Open customisation layer
await page.locator('[data-testid="cookie-customise"]').click();
// Enable only analytics
const analyticsToggle = page.locator('[data-testid="consent-toggle-analytics"]');
await analyticsToggle.click();
// Ensure advertising is off
const advertisingToggle = page.locator('[data-testid="consent-toggle-advertising"]');
const isAdvertisingChecked = await advertisingToggle.isChecked();
expect(isAdvertisingChecked).toBe(false);
// Confirm choices
await page.locator('[data-testid="cookie-confirm-choices"]').click();
await page.waitForLoadState('networkidle');
const cookies = await page.context().cookies();
const cookieNames = cookies.map(c => c.name);
// GA cookies should be present
expect(cookieNames.some(n => n.startsWith('_ga'))).toBe(true);
// Advertising cookies should NOT be present
expect(cookieNames.some(n => n === '_fbp')).toBe(false);
expect(cookieNames.some(n => n === '_gcl_au')).toBe(false);
});
});// tests/cookie-consent/tag-firing.spec.js
const { test, expect } = require('@playwright/test');
test.describe('Tag Firing Audit', () => {
test('GA4 tag fires only after analytics consent', async ({ page }) => {
let ga4Fired = false;
page.on('request', request => {
if (request.url().includes('google-analytics.com/g/collect') ||
request.url().includes('analytics.google.com/g/collect')) {
ga4Fired = true;
}
});
// Load page — GA4 should not fire
await page.goto('/');
await page.waitForLoadState('networkidle');
expect(ga4Fired, 'GA4 fired before consent').toBe(false);
// Accept analytics
await page.locator('[data-testid="cookie-customise"]').click();
await page.locator('[data-testid="consent-toggle-analytics"]').click();
await page.locator('[data-testid="cookie-confirm-choices"]').click();
await page.waitForLoadState('networkidle');
// Navigate to trigger a pageview
await page.goto('/products');
await page.waitForLoadState('networkidle');
expect(ga4Fired, 'GA4 did not fire after analytics consent').toBe(true);
});
test('Meta Pixel does not fire when advertising is rejected', async ({ page }) => {
let metaPixelFired = false;
page.on('request', request => {
if (request.url().includes('facebook.com/tr') ||
request.url().includes('connect.facebook.net')) {
metaPixelFired = true;
}
});
await page.goto('/');
await page.locator('[data-testid="cookie-reject-all"]').click();
await page.waitForLoadState('networkidle');
await page.goto('/products');
await page.waitForLoadState('networkidle');
await page.goto('/products/widget-pro');
await page.waitForLoadState('networkidle');
expect(metaPixelFired, 'Meta Pixel fired after reject all').toBe(false);
});
test('Google Consent Mode sends correct consent state', async ({ page }) => {
const consentPings = [];
page.on('request', request => {
const url = request.url();
if (url.includes('google-analytics.com') && url.includes('gcs=')) {
const gcsMatch = url.match(/gcs=([^&]+)/);
if (gcsMatch) consentPings.push(gcsMatch[1]);
}
});
await page.goto('/');
await page.locator('[data-testid="cookie-reject-all"]').click();
await page.waitForLoadState('networkidle');
// Navigate to trigger consent mode ping
await page.goto('/products');
await page.waitForLoadState('networkidle');
// If consent mode pings are sent, verify denied state
if (consentPings.length > 0) {
for (const gcs of consentPings) {
// G100 = all denied, G111 = all granted
expect(gcs).toContain('100');
}
}
});
});// tests/cookie-consent/regression.spec.js
const { test, expect } = require('@playwright/test');
const fs = require('fs');
// Baseline of known cookies — update when new cookies are intentionally added
const KNOWN_COOKIES = new Set([
'session_id',
'csrf_token',
'consent_state',
'pinnacle_consent_eu',
'load_balancer',
'_ga',
'_ga_PINNACLE',
'_gid',
'_fbp',
'_fbc',
'_gcl_au',
'_hjSessionUser',
'_hjSession',
'locale',
'currency',
'recently_viewed',
'cart_session',
'auth_token',
]);
test.describe('Cookie Regression Detection', () => {
test('no unknown cookies after Accept All', async ({ page }) => {
await page.goto('/');
await page.locator('[data-testid="cookie-accept-all"]').click();
await page.waitForLoadState('networkidle');
// Visit several pages to trigger all tag scenarios
const pages = ['/', '/products', '/products/widget-pro', '/cart', '/about', '/blog'];
for (const path of pages) {
await page.goto(path);
await page.waitForLoadState('networkidle');
}
const cookies = await page.context().cookies();
const unknownCookies = cookies.filter(c => {
// Check if cookie name matches any known prefix
return !Array.from(KNOWN_COOKIES).some(known =>
c.name === known || c.name.startsWith(known)
);
});
if (unknownCookies.length > 0) {
const unknownNames = unknownCookies.map(c => `${c.name} (domain: ${c.domain}, expires: ${c.expires})`);
console.error('Unknown cookies detected:', unknownNames);
// Write to report file for review
fs.writeFileSync(
'test-results/unknown-cookies.json',
JSON.stringify(unknownCookies, null, 2)
);
}
expect(unknownCookies, `Unknown cookies found: ${unknownCookies.map(c => c.name).join(', ')}`).toHaveLength(0);
});
});// tests/cookie-consent/gpc-signal.spec.js
const { test, expect } = require('@playwright/test');
test.describe('Global Privacy Control Signal', () => {
test('GPC signal triggers automatic opt-out for California users', async ({ browser }) => {
// Create context with GPC header
const context = await browser.newContext({
extraHTTPHeaders: {
'Sec-GPC': '1',
},
locale: 'en-US',
geolocation: { latitude: 34.0522, longitude: -118.2437 }, // Los Angeles
permissions: ['geolocation'],
});
const page = await context.newPage();
await page.goto('/');
await page.waitForLoadState('networkidle');
// Verify advertising cookies are not set
const cookies = await context.cookies();
const adCookies = cookies.filter(c =>
c.name === '_fbp' || c.name === '_gcl_au' || c.name.startsWith('IDE')
);
expect(adCookies, 'Advertising cookies set despite GPC signal').toHaveLength(0);
await context.close();
});
});name: Cookie Consent Compliance Tests
on:
push:
branches: [main, staging]
pull_request:
branches: [main]
schedule:
- cron: '0 6 * * 1' # Weekly Monday 6 AM UTC
jobs:
cookie-consent-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Install Playwright browsers
run: npx playwright install --with-deps
- name: Run cookie consent tests
run: npx playwright test tests/cookie-consent/
env:
BASE_URL: ${{ vars.STAGING_URL }}
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: cookie-consent-test-results
path: |
test-results/
playwright-report/
- name: Post results to Slack
if: failure()
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "Cookie consent tests FAILED on ${{ github.ref }}. Review: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_PRIVACY_WEBHOOK }}© mukul975, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 4 other files (scripts, references, assets) in skills/privacy/cookie-consent-testing of mukul975/Privacy-Data-Protection-Skills.
Open the folder on GitHubat commit 9b2ef9e
Cookie Consent Testing next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Cookie Consent Testing this skillmukul975/Privacy-Data-Protection-Skills | 295 | — | ~4.8k | Automated safety check: Pass | Apache-2.0 | |
| Page Prepadobe/skills | 196 | — | ~2.1k | Automated safety check: Pass | Apache-2.0 | |
| RStudio Selenium to Playwright Migrationrstudio/rstudio | 5.1k | — | ~3.6k | Automated safety check: Pass | Custom licence | |
| Playwright Stealth Verifyliarjsdev/liarjs-skills | 518 | 1 repos | ~1.3k | Automated safety check: Notes | MIT | |
| Brightdata Proxybrightdata/skills | 264 | — | ~5.1k | Automated safety check: Pass | MIT | |
| Open BrowserJasonHonKL/Openbrowser | 114 | — | ~1.6k | Automated safety check: Pass | MIT |
adobe/skills
Prepare any webpage for clean interaction by detecting and removing disruptive overlays (cookie banners, GDPR consent, modals, popups, newsletter signups, paywalls, login walls).
rstudio/rstudio
Converts RStudio Python Selenium electron tests into TypeScript Playwright tests, checking each against a live RStudio before counting it as migrated.
liarjsdev/liarjs-skills
Check whether a Playwright, Puppeteer, Selenium or CDP-driven browser presents a coherent fingerprint, using liarjs as a library against a Page you already have - navigator.webdriver, HeadlessChrome…
brightdata/skills
Generate working code that routes HTTP requests through Bright Data proxy networks (Datacenter, ISP, Residential, Mobile) and help users decide which network and IP pool type to use (shared pool…
JasonHonKL/Openbrowser
A skill your agent uses whenever the task involves browsing web pages, extracting page content, clicking forms, or completing web workflows.
fugazi/test-automation-skills-agents
Author and maintain versioned Selenium WebDriver tests with Java and JUnit 5.
mukul975/Privacy-Data-Protection-Skills
Implements age-gating mechanisms for online services to restrict access based on user age.
mukul975/Privacy-Data-Protection-Skills
Manages AI model retention and machine unlearning requirements.
mukul975/Privacy-Data-Protection-Skills
Structures risk mitigation planning and residual risk tracking for Data Protection Impact Assessments under GDPR Article 35(7)(d).
mukul975/Privacy-Data-Protection-Skills
Guides implementation of the GDPR accountability principle under Articles 5(2) and 24, including documentation requirements for policies, DPIAs, RoPA, training records, and breach logs.
mukul975/Privacy-Data-Protection-Skills
Conducts pre-DPIA threshold screening to determine whether a full Data Protection Impact Assessment is required under GDPR Article 35.
mukul975/Privacy-Data-Protection-Skills
Designs and implements data retention schedules compliant with GDPR Article 5(1)(e) storage limitation principle.
Works with
Categories
Automated cookie consent validation using Selenium and Playwright. Cookie Consent Testing is an agent skill from mukul975/Privacy-Data-Protection-Skills. Automated cookie consent validation using Selenium and Playwright.
Cookie Consent Testing fits situations like: tasks that involve Privacy and GDPR; tasks that involve Browser testing.
Run `npx skills add mukul975/Privacy-Data-Protection-Skills --skill cookie-consent-testing -a claude-code`. Or copy the skill folder (skills/privacy/cookie-consent-testing in mukul975/Privacy-Data-Protection-Skills) into .claude/skills/cookie-consent-testing in your project. Claude Code loads it when a task matches its description.
Run `npx skills add mukul975/Privacy-Data-Protection-Skills --skill cookie-consent-testing -a codex`. Or copy the skill folder (skills/privacy/cookie-consent-testing in mukul975/Privacy-Data-Protection-Skills) into .agents/skills/cookie-consent-testing in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add mukul975/Privacy-Data-Protection-Skills --skill cookie-consent-testing -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/cookie-consent-testing, .gemini/skills/cookie-consent-testing, .github/skills/cookie-consent-testing and .opencode/skills/cookie-consent-testing in your project.
Going by SKILL.md and its folder, Cookie Consent Testing needs Python for the scripts in its folder. Our summary lists: Python 3.
SKILL.md names 1 domain. In commands or code: staging.pinnacle-ecommerce.com; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Cookie Consent Testing is published under the Apache-2.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.8k tokens (SKILL.md is roughly 19k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 946 tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Cookie Consent Testing: Page Prep (adobe/skills, 196 stars), RStudio Selenium to Playwright Migration (rstudio/rstudio, 5.1k stars), Playwright Stealth Verify (liarjsdev/liarjs-skills, 518 stars) and Brightdata Proxy (brightdata/skills, 264 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
mukul975 (a GitHub user) maintains it in mukul975/Privacy-Data-Protection-Skills, which has 295 GitHub stars. The repository holds 278 skills in this directory. The repository was last updated on March 16, 2026.
Source: mukul975/Privacy-Data-Protection-Skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.