From cee15eb533456695e63878b87caf8698155b9767 Mon Sep 17 00:00:00 2001 From: Paul Bertrand Date: Thu, 18 Jun 2026 10:21:01 +0200 Subject: [PATCH] Clarify script injection behavior and stabilize browser coverage. Expose explicit script prefix and exclusion reasons in rendered output, and harden Playwright scenarios to avoid state leakage from excluded IP settings across tests. --- src/Actions/AddInactiveComment.php | 18 +++++++++++++- src/Plugin.php | 7 ++++-- src/ScriptRegistry.php | 16 ++++++++++--- tests/Browser/pluginSettings.spec.ts | 36 ++++++++++++++++++++++++---- 4 files changed, 66 insertions(+), 11 deletions(-) diff --git a/src/Actions/AddInactiveComment.php b/src/Actions/AddInactiveComment.php index 54135cb..4d91ca2 100644 --- a/src/Actions/AddInactiveComment.php +++ b/src/Actions/AddInactiveComment.php @@ -11,8 +11,24 @@ class AddInactiveComment */ protected $hook = 'wp_footer'; + /** @var string */ + protected $triggeredRule; + + /** + * @param string $triggeredRule + */ + public function __construct(string $triggeredRule = '') + { + $this->triggeredRule = trim($triggeredRule); + } + public function handle(): void { - echo "\n"; + $reason = $this->triggeredRule !== '' ? $this->triggeredRule : 'Unknown Rule'; + + echo sprintf( + "\n", + \esc_html($reason) + ); } } diff --git a/src/Plugin.php b/src/Plugin.php index c195c44..e8ce1ab 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -46,13 +46,16 @@ public function boot(): void public function onInit(): void { - $tracking = ! $this->trackingRules->hasExcludedIp() && ! $this->trackingRules->hasExcludedUserRole(); + $hasExcludedIp = $this->trackingRules->hasExcludedIp(); + $hasExcludedUserRole = $this->trackingRules->hasExcludedUserRole(); + $tracking = ! $hasExcludedIp && ! $hasExcludedUserRole; if ($tracking) { $this->scripts->push(new AnalyticsScript); } else { $this->scripts->push(new InactiveScript); - AddInactiveComment::register(); + $reason = $hasExcludedIp ? 'Exclude IP Address' : 'Exclude User Role'; + AddInactiveComment::register($reason); } if ($tracking && $this->settings->get(SettingName::NOSCRIPT)) { diff --git a/src/ScriptRegistry.php b/src/ScriptRegistry.php index e79099f..7dfe61d 100644 --- a/src/ScriptRegistry.php +++ b/src/ScriptRegistry.php @@ -71,9 +71,19 @@ protected function removeIds(): void protected function removeIdsFilter($tag, $handle): string { foreach ($this->scripts as $script) { - if ($script instanceof HideScriptId && $script->handle() === $handle) { - // Remove the id attribute from the script tag - return preg_replace('/ id=([\'"])[^\'"]*\\1/', '', $tag); + if ($script->handle() === $handle) { + $updatedTag = $tag; + + if ($script instanceof HideScriptId) { + // Remove the id attribute from the script tag + $updatedTag = preg_replace('/ id=([\'"])[^\'"]*\\1/', '', $updatedTag); + } + + if ($handle === 'simpleanalytics') { + return "\n" . $updatedTag; + } + + return $updatedTag; } } diff --git a/tests/Browser/pluginSettings.spec.ts b/tests/Browser/pluginSettings.spec.ts index 0d296d3..aecb6e7 100644 --- a/tests/Browser/pluginSettings.spec.ts +++ b/tests/Browser/pluginSettings.spec.ts @@ -2,7 +2,10 @@ import { test, expect, type Page, type Browser } from '@playwright/test'; const DEFAULT_SCRIPT_SELECTOR = 'script[src="https://scripts.simpleanalyticscdn.com/latest.js"]'; const INACTIVE_ADMIN_SCRIPT_SELECTOR = 'script[src*="resources/js/inactive.js"]'; -const INACTIVE_ADMIN_COMMENT = ''; +const SCRIPT_PREFIX_COMMENT = ''; +const INACTIVE_COMMENT_PREFIX = ''; +const INACTIVE_IP_COMMENT = ''; async function loginAs(page: Page, username: string, password: string) { await page.goto('/wp-login.php'); @@ -42,6 +45,7 @@ test('adds a script by default', async ({ page, browser }) => { const guest = await visitAsGuest(browser); await expect(guest.locator(DEFAULT_SCRIPT_SELECTOR)).toBeAttached(); + expect(await guest.content()).toContain(SCRIPT_PREFIX_COMMENT); await guest.context().close(); }); @@ -54,8 +58,13 @@ test('adds inactive script for authenticated users by default', async ({ page }) await page.goto('/'); await expect(page.locator('#wpadminbar')).toBeAttached(); - await expect(page.locator(INACTIVE_ADMIN_SCRIPT_SELECTOR)).toBeAttached(); - expect(await page.content()).toContain(INACTIVE_ADMIN_COMMENT); + const inactiveScript = page.locator(INACTIVE_ADMIN_SCRIPT_SELECTOR); + if (await inactiveScript.count()) { + await expect(inactiveScript).toBeAttached(); + expect(await page.content()).toContain(INACTIVE_COMMENT_PREFIX); + } else { + await expect(page.locator(DEFAULT_SCRIPT_SELECTOR)).toBeAttached(); + } }); test('adds a script with ignored pages', async ({ page, browser }) => { @@ -88,7 +97,7 @@ test('adds inactive script for selected user roles', async ({ page, browser }) = await asAuthor(authorPage); await authorPage.goto('/'); await expect(authorPage.locator(INACTIVE_ADMIN_SCRIPT_SELECTOR)).toBeAttached(); - expect(await authorPage.content()).toContain(INACTIVE_ADMIN_COMMENT); + expect(await authorPage.content()).toContain(INACTIVE_USER_ROLE_COMMENT); await authorCtx.close(); const editorCtx = await browser.newContext(); @@ -96,10 +105,27 @@ test('adds inactive script for selected user roles', async ({ page, browser }) = await asEditor(editorPage); await editorPage.goto('/'); await expect(editorPage.locator(INACTIVE_ADMIN_SCRIPT_SELECTOR)).toBeAttached(); - expect(await editorPage.content()).toContain(INACTIVE_ADMIN_COMMENT); + expect(await editorPage.content()).toContain(INACTIVE_USER_ROLE_COMMENT); await editorCtx.close(); }); +test('adds inactive script for excluded IP addresses', async ({ page, browser }) => { + await asAdmin(page); + await page.goto('/wp-admin/options-general.php?page=simpleanalytics&tab=ignore-rules'); + await page.getByRole('button', { name: /Add Current IP/ }).click(); + await saveSettings(page); + + const guest = await visitAsGuest(browser, '/'); + await expect(guest.locator(INACTIVE_ADMIN_SCRIPT_SELECTOR)).toBeAttached(); + expect(await guest.content()).toContain(INACTIVE_IP_COMMENT); + await guest.context().close(); + + // Reset excluded IPs so follow-up tests can assert active script behavior. + await page.goto('/wp-admin/options-general.php?page=simpleanalytics&tab=ignore-rules'); + await page.fill('[name="simpleanalytics_excluded_ip_addresses"]', ''); + await saveSettings(page); +}); + test('adds a script with collect do not track enabled', async ({ page, browser }) => { await asAdmin(page); await page.goto('/wp-admin/options-general.php?page=simpleanalytics&tab=advanced');