diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e43a095c..724050e1 100755 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -20,3 +20,23 @@ updates: labels: - "dependencies" - "automerge" + + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + target-branch: "develop" + labels: + - "dependencies" + - "automerge" + + - package-ecosystem: "npm" + directory: "/tests/e2e" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + target-branch: "develop" + labels: + - "dependencies" + - "automerge" diff --git a/.harness.json b/.harness.json index 317b1c6d..8a2893a5 100644 --- a/.harness.json +++ b/.harness.json @@ -3,6 +3,6 @@ "mode": "enforce", "ratchet": { "phpstan_level": 5, - "phpstan_baseline": 66 + "phpstan_baseline": 58 } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bd2498d..cd6771b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,21 @@ All notable changes to the Pollora framework will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased](https://github.com/Pollora/framework/compare/v13.39.0...develop) +## [Unreleased](https://github.com/Pollora/framework/compare/v13.39.1...develop) + +## [v13.39.1](https://github.com/Pollora/framework/compare/v13.39.0...v13.39.1) - 2026-10-28 + +### Changed +- **WP Rocket moved to its own package, `pollora/wp-rocket`. Install it if the project runs WP Rocket: `composer require pollora/wp-rocket`.** The framework no longer registers `WpRocketServiceProvider`, which kept WP Rocket from writing its rules into `.htaccess` and from setting `WP_CACHE` (both off unless `wordpress.wprocket.generate_htaccess` / `set_cache_constant` say otherwise). Without the package, an active WP Rocket does both on its own. The old class name `Pollora\ThirdParty\WpRocket\WpRocketServiceProvider` still resolves once the package is installed, and `wordpress.wprocket` is unchanged +- `pollora:doctor` and Site Health check that WP Rocket, when active, has its Pollora integration installed; `pollora/wp-rocket` is suggested in `composer.json` +- **`pollora/colt` `^11.0`** (it was `^10.0.1`): Colt 11 requires PHP 8.3, declares strict types and adds return types to its public methods, so a model that extends one of Colt's and overrides a method must be compatible. `pollora/block-bindings` is required as `^0.2` (it needs Colt 11) and `pollora/query` as `^2.0 || ^3.0` (3.0 only raises its PHP requirement to 8.3) +- `laravel/prompts` is updated to `^0.3.26` +- Dependabot watches the npm lock files (`/` and `tests/e2e`) and opens its pull requests, security updates included, against `develop`: a security update used to target `main`, which broke the Gitflow + +### Fixed +- The end-to-end test of the module list no longer fails when WordPress shows its own warning notice, as it does while a core update is available +- `tests/e2e/package-lock.json` is refreshed with `npm audit fix` (`zod` 4.6.7, `puppeteer-core` 25.16.0 and their dependencies) to fix known vulnerabilities in these development dependencies +- `fast-uri` is updated to 3.1.9 in `package-lock.json` and `tests/e2e/package-lock.json` to fix known vulnerabilities in these development dependencies ## [v13.39.0](https://github.com/Pollora/framework/compare/v13.38.1...v13.39.0) - 2026-10-27 diff --git a/composer.json b/composer.json index 3659a436..cc98a1b1 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ "pollora/ajax": "^1.1", "pollora/assets": "^0.1", "pollora/attributes": "^0.1.1 || ^1.0", - "pollora/block-bindings": "^0.1", + "pollora/block-bindings": "^0.2", "pollora/discovery": "^0.1 || ^1.0", "pollora/entity": "^1.2", "pollora/media": "^0.8", @@ -46,16 +46,16 @@ "pollora/wp-rest": "^0.1 || ^0.2 || ^1.0", "watson/rememberable": "^7.1", "cweagans/composer-patches": "^2.0", - "pollora/colt": "^10.0.1", + "pollora/colt": "^11.0", "log1x/sage-directives": "^2.0", "roots/bedrock-autoloader": "^1.1", - "pollora/query": "^1.0 || ^2.0", + "pollora/query": "^2.0 || ^3.0", "spatie/php-structure-discoverer": "^2.4", "coduo/php-humanizer": "5.0.3", "nwidart/laravel-modules": "^13.0", "symfony/process": "^7.4 || ^8.0", "illuminate/config": "^13.39", - "laravel/prompts": "^0.3.25" + "laravel/prompts": "^0.3.26" }, "autoload": { "psr-4": { @@ -107,7 +107,8 @@ } }, "suggest": { - "pollora/woocommerce": "WooCommerce's Blade templates, Route::wp() conditions, Coming Soon page and events" + "pollora/woocommerce": "WooCommerce's Blade templates, Route::wp() conditions, Coming Soon page and events", + "pollora/wp-rocket": "Keeps WP Rocket from writing .htaccess and setting WP_CACHE unless the project asks for it" }, "require-dev": { "driftingly/rector-laravel": "^2.6", diff --git a/package-lock.json b/package-lock.json index 9424a8e1..6859656d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1210,9 +1210,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz", - "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.9.tgz", + "integrity": "sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==", "dev": true, "funding": [ { diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index ef480656..3e78a904 100755 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -54,12 +54,6 @@ parameters: count: 3 path: src/Events/WordPress/Plugins/GravityForms/GravityFormsEventDispatcher.php - - - message: '#^Access to an undefined property Illuminate\\Database\\Eloquent\\Model\:\:\$meta_value\.$#' - identifier: property.notFound - count: 1 - path: src/Models/Attachment.php - - message: '#^Call to an undefined method Illuminate\\Container\\Container\:\:getCachedConfigPath\(\)\.$#' identifier: method.notFound diff --git a/src/Doctor/Infrastructure/Checks/WpRocketPackageCheck.php b/src/Doctor/Infrastructure/Checks/WpRocketPackageCheck.php new file mode 100644 index 00000000..65478073 --- /dev/null +++ b/src/Doctor/Infrastructure/Checks/WpRocketPackageCheck.php @@ -0,0 +1,70 @@ +packageInstalled instanceof Closure + ? ($this->packageInstalled)() + : InstalledVersions::isInstalled(self::PACKAGE); + + if ($installed) { + return CheckResult::ok(self::PACKAGE.' is installed.'); + } + + return CheckResult::warning( + 'WP Rocket is active, but its Pollora integration is not installed.', + [ + 'The framework no longer ships it: without '.self::PACKAGE.', WP Rocket writes its rules into .htaccess and sets WP_CACHE on its own.', + ], + 'composer require '.self::PACKAGE, + ); + } +} diff --git a/src/Doctor/Infrastructure/Providers/DoctorServiceProvider.php b/src/Doctor/Infrastructure/Providers/DoctorServiceProvider.php index e7edb2dc..bc806ae4 100644 --- a/src/Doctor/Infrastructure/Providers/DoctorServiceProvider.php +++ b/src/Doctor/Infrastructure/Providers/DoctorServiceProvider.php @@ -22,6 +22,7 @@ use Pollora\Doctor\Infrastructure\Checks\TemplatePlaceholdersCheck; use Pollora\Doctor\Infrastructure\Checks\WooCommercePackageCheck; use Pollora\Doctor\Infrastructure\Checks\WordPressCorePatchCheck; +use Pollora\Doctor\Infrastructure\Checks\WpRocketPackageCheck; use Pollora\Doctor\UI\Console\DoctorCommand; use Pollora\Doctor\UI\Http\SiteHealthTests; use Pollora\Hook\Domain\Contract\Filter; @@ -55,6 +56,7 @@ class DoctorServiceProvider extends ServiceProvider BlockRegistrationCheck::class, PublicRootCheck::class, WooCommercePackageCheck::class, + WpRocketPackageCheck::class, ]; public function register(): void diff --git a/src/Providers/PolloraServiceProvider.php b/src/Providers/PolloraServiceProvider.php index 49911a9a..1965d8cf 100755 --- a/src/Providers/PolloraServiceProvider.php +++ b/src/Providers/PolloraServiceProvider.php @@ -39,7 +39,6 @@ use Pollora\Schedule\SchedulerServiceProvider; use Pollora\Taxonomy\Infrastructure\Providers\TaxonomyServiceProvider; use Pollora\Theme\Infrastructure\Providers\ThemeServiceProvider; -use Pollora\ThirdParty\WpRocket\WpRocketServiceProvider; use Pollora\VersionCheck\Infrastructure\Providers\VersionCheckServiceProvider; use Pollora\View\Infrastructure\Providers\TemplateHierarchyServiceProvider; use Pollora\View\ViewServiceProvider; @@ -117,7 +116,6 @@ public function register(): void $this->app->register(ConfigServiceProvider::class); $this->app->register(QueryServiceProvider::class); $this->app->register(SageDirectivesServiceProvider::class); - $this->app->register(WpRocketServiceProvider::class); $this->app->register(WordPressEventServiceProvider::class); $this->app->register(TemplateHierarchyServiceProvider::class); $this->app->register(RouteServiceProvider::class); diff --git a/src/ThirdParty/WpRocket/WpRocketServiceProvider.php b/src/ThirdParty/WpRocket/WpRocketServiceProvider.php deleted file mode 100755 index 94f16e66..00000000 --- a/src/ThirdParty/WpRocket/WpRocketServiceProvider.php +++ /dev/null @@ -1,26 +0,0 @@ -bindFilters(); - } - - private function bindFilters(): void - { - $config = config('wordpress.wprocket'); - - add_filter('rocket_init_cache_dir_generate_htaccess', $config['generate_htaccess'] ?? false ? static fn (): true => true : static fn (): false => false); - add_filter('rocket_set_wp_cache_constant', $config['set_cache_constant'] ?? false ? static fn (): true => true : static fn (): false => false); - } -} diff --git a/tests/Feature/Doctor/WpRocketPackageCheckTest.php b/tests/Feature/Doctor/WpRocketPackageCheckTest.php new file mode 100644 index 00000000..c714d37e --- /dev/null +++ b/tests/Feature/Doctor/WpRocketPackageCheckTest.php @@ -0,0 +1,58 @@ +justReturn(0); + + $result = (new WpRocketPackageCheck)->run(RunContext::Console); + + expect($result->status)->toBe(CheckStatus::Skipped); + }); + + test('is skipped when WP Rocket is not active', function (): void { + Functions\when('did_action')->justReturn(1); + + $result = (new WpRocketPackageCheck(fn (): bool => false))->run(RunContext::Console); + + expect($result->status)->toBe(CheckStatus::Skipped) + ->and($result->summary)->toContain('not active'); + }); + + test('warns, and says what to install, when the package is missing', function (): void { + Functions\when('did_action')->justReturn(1); + declareWpRocket(); + + $result = (new WpRocketPackageCheck(fn (): bool => false))->run(RunContext::Console); + + expect($result->status)->toBe(CheckStatus::Warning) + ->and($result->fix)->toBe('composer require pollora/wp-rocket'); + }); + + test('is ok when the package is installed', function (): void { + Functions\when('did_action')->justReturn(1); + declareWpRocket(); + + $result = (new WpRocketPackageCheck(fn (): bool => true))->run(RunContext::Console); + + expect($result->status)->toBe(CheckStatus::Ok); + }); + + test('runs in the console and in Site Health', function (): void { + expect((new WpRocketPackageCheck)->runsIn())->toBe([RunContext::Console, RunContext::Http]); + }); +}); diff --git a/tests/Unit/ThirdParty/WpRocket/WpRocketServiceProviderTest.php b/tests/Unit/ThirdParty/WpRocket/WpRocketServiceProviderTest.php deleted file mode 100644 index 38ea49f3..00000000 --- a/tests/Unit/ThirdParty/WpRocket/WpRocketServiceProviderTest.php +++ /dev/null @@ -1,75 +0,0 @@ -originalContainer = Container::getInstance(); - $this->app = new Container; - Container::setInstance($this->app); - $this->registeredFilters = []; - - // Override Brain Monkey's add_filter stub to capture calls - Brain\Monkey\Functions\when('add_filter')->alias(function ($hook, $callback): true { - $this->registeredFilters[$hook] = $callback; - - return true; - }); - }); - - afterEach(function (): void { - Container::setInstance($this->originalContainer); - }); - - it('registers htaccess filter as true when config enabled', function (): void { - $this->app->instance('config', new Repository([ - 'wordpress' => ['wprocket' => ['generate_htaccess' => true, 'set_cache_constant' => false]], - ])); - - (new WpRocketServiceProvider($this->app))->boot(); - - expect($this->registeredFilters)->toHaveKey('rocket_init_cache_dir_generate_htaccess'); - expect($this->registeredFilters['rocket_init_cache_dir_generate_htaccess']())->toBeTrue(); - expect($this->registeredFilters['rocket_set_wp_cache_constant']())->toBeFalse(); - }); - - it('registers cache constant filter as true when config enabled', function (): void { - $this->app->instance('config', new Repository([ - 'wordpress' => ['wprocket' => ['generate_htaccess' => false, 'set_cache_constant' => true]], - ])); - - (new WpRocketServiceProvider($this->app))->boot(); - - expect($this->registeredFilters['rocket_init_cache_dir_generate_htaccess']())->toBeFalse(); - expect($this->registeredFilters['rocket_set_wp_cache_constant']())->toBeTrue(); - }); - - it('defaults to false when config keys are missing', function (): void { - $this->app->instance('config', new Repository([ - 'wordpress' => ['wprocket' => []], - ])); - - (new WpRocketServiceProvider($this->app))->boot(); - - expect($this->registeredFilters['rocket_init_cache_dir_generate_htaccess']())->toBeFalse(); - expect($this->registeredFilters['rocket_set_wp_cache_constant']())->toBeFalse(); - }); - - it('registers exactly two filters', function (): void { - $this->app->instance('config', new Repository([ - 'wordpress' => ['wprocket' => ['generate_htaccess' => true, 'set_cache_constant' => true]], - ])); - - (new WpRocketServiceProvider($this->app))->boot(); - - expect($this->registeredFilters)->toHaveCount(2); - expect($this->registeredFilters)->toHaveKeys([ - 'rocket_init_cache_dir_generate_htaccess', - 'rocket_set_wp_cache_constant', - ]); - }); -}); diff --git a/tests/e2e/package-lock.json b/tests/e2e/package-lock.json index 36bc3014..7ff89157 100644 --- a/tests/e2e/package-lock.json +++ b/tests/e2e/package-lock.json @@ -219,13 +219,13 @@ } }, "node_modules/@puppeteer/browsers": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.2.3.tgz", - "integrity": "sha512-2Bt3m6dDAJqmZehn0wiXSYyQmuhyiHHZ7FjvrVaS1W2RoFGV6eCK71UvKYkNJjkwC1Q9nobjhvTMhLQztFVINA==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.2.6.tgz", + "integrity": "sha512-MJP29gVoHznmqmwhH1tlZqzfeQ3aylTpSSa6WKZXtkwYUH02i9imBmWGTyZrbnAou5paX78SE4jMAUqnEPf8ug==", "dev": true, "license": "Apache-2.0", "dependencies": { - "modern-tar": "^0.8.4", + "modern-tar": "^0.8.6", "yargs": "^18.0.0" }, "bin": { @@ -248,9 +248,9 @@ } }, "node_modules/@puppeteer/browsers/node_modules/ansi-regex": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", - "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.4.0.tgz", + "integrity": "sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==", "dev": true, "license": "MIT", "engines": { @@ -314,9 +314,9 @@ "license": "MIT" }, "node_modules/@puppeteer/browsers/node_modules/string-width": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz", - "integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.3.0.tgz", + "integrity": "sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==", "dev": true, "license": "MIT", "dependencies": { @@ -714,14 +714,14 @@ } }, "node_modules/chromium-bidi": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-17.0.2.tgz", - "integrity": "sha512-5v9GQFhTktFvotn/OFNJBmKLKRAb6n9r0bVCwf7sHgWc3/JryK0bj1nn93L3pHFrfgcsu6Be6EWsDi+1XHTGDg==", + "version": "157.0.8090-0", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-157.0.8090-0.tgz", + "integrity": "sha512-KJw7IQgqXwxpJgJlEIPg5mr2ZoqA+jkTRtc5EABI7sUJ3bu3cpI7NuEBoj4Gn1AsF78CaT9So5WQWspK3/wYag==", "dev": true, "license": "Apache-2.0", "dependencies": { "mitt": "^3.0.1", - "zod": "^3.24.1" + "zod": "^4.6.5" }, "engines": { "node": ">=20.19.0 <22.0.0 || >=22.12.0" @@ -938,9 +938,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz", - "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.9.tgz", + "integrity": "sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==", "dev": true, "funding": [ { @@ -1238,9 +1238,9 @@ "license": "MIT" }, "node_modules/modern-tar": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/modern-tar/-/modern-tar-0.8.5.tgz", - "integrity": "sha512-snEhs+6G5Tjd4I7tLCDOaoln2RgE0bD19RzEKgvgK2hZ5VKy3MpLhLTZ2fWpXSTg4K2cyPwp+VHATFJhxfnOeA==", + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/modern-tar/-/modern-tar-0.8.6.tgz", + "integrity": "sha512-LYSks0tNVqbtez/9OB0YFP6qLRSqkdAxJWOQpVaR67lNTbj2zNLyYpowkRMia5lXLCZKzxwoxkxH2MbbBR2aEg==", "dev": true, "license": "MIT", "engines": { @@ -1353,27 +1353,34 @@ } }, "node_modules/puppeteer-core": { - "version": "25.12.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-25.12.0.tgz", - "integrity": "sha512-z6LQUt5SH7jwGtGA+nMtJuEjZIsqPiwQ+EFHCYuVDQrJpvifNmmGuyDvTzAKPyFzihxgHc5f3aMzu2kn8Ps37A==", + "version": "25.16.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-25.16.0.tgz", + "integrity": "sha512-VA5Pf54N8shfopNkZZXCdiiwfnnY8ZJYAMqFQRhlH5mGUhfwf53Ar770GPtdpTDLUqvQeYpIBtC9/G2Jij2IJw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "3.2.3", - "chromium-bidi": "17.0.2", - "devtools-protocol": "0.0.1687809", - "typed-query-selector": "^2.12.2", - "webdriver-bidi-protocol": "0.4.3", - "ws": "^8.21.3" + "@puppeteer/browsers": "3.2.6", + "chromium-bidi": "157.0.8090-0", + "devtools-protocol": "0.0.1704951", + "typed-query-selector": "^2.12.3", + "webdriver-bidi-protocol": "1.0.1", + "ws": "^8.22.0" }, "engines": { "node": ">=22.12.0" } }, + "node_modules/puppeteer-core/node_modules/devtools-protocol": { + "version": "0.0.1704951", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1704951.tgz", + "integrity": "sha512-GQhQOs9u/Mvm1zMtJIH872JS4AskuZdUSsPNPk4ChahtWAUqgz6atEtIsMt+nO7MqF1Ic4HxII/k8Cu36JivNg==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/puppeteer-core/node_modules/ws": { - "version": "8.21.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", - "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.22.0.tgz", + "integrity": "sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==", "dev": true, "license": "MIT", "engines": { @@ -1564,9 +1571,9 @@ } }, "node_modules/typed-query-selector": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.2.tgz", - "integrity": "sha512-EOPFbyIub4ngnEdqi2yOcNeDLaX/0jcE1JoAXQDDMIthap7FoN795lc/SHfIq2d416VufXpM8z/lD+WRm2gfOQ==", + "version": "2.12.3", + "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.3.tgz", + "integrity": "sha512-/dtuMZyutHLlrxWhhC1uib00ELUr2dZ8C9B8YzZYsJmeE3V56OxRblrSM2UaF142pcMtak7ehZ6+poWGeehNIg==", "dev": true, "license": "MIT" }, @@ -1612,9 +1619,9 @@ "license": "Apache-2.0" }, "node_modules/webdriver-bidi-protocol": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.3.tgz", - "integrity": "sha512-uuN0goWfxP22B7J/uAgBpOYNPttC+XVseYE+rSY5+rQ+YBeVz/VORw8WbmLVcqW78zNg5A4qnjNXYUWR3il2ig==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-1.0.1.tgz", + "integrity": "sha512-WXWs/aXF2a6Al1Z2/V/7Gp2oPZOAAmHjJOTmv4KCXRJ122IMj3tSSMc6a4q3K4QOmhQbse/Ahr+oTVJOU2dUiw==", "dev": true, "license": "Apache-2.0" }, @@ -1718,9 +1725,9 @@ } }, "node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "version": "4.6.7", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.7.tgz", + "integrity": "sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==", "dev": true, "license": "MIT", "funding": { diff --git a/tests/e2e/specs/modules.spec.ts b/tests/e2e/specs/modules.spec.ts index b2c6fd3d..e6c86749 100644 --- a/tests/e2e/specs/modules.spec.ts +++ b/tests/e2e/specs/modules.spec.ts @@ -61,6 +61,7 @@ test.describe('Plugins › Modules', () => { test('warns that the JSON file does not survive a deployment', async ({ admin, page }) => { await admin.visitAdminPage('plugins.php', 'page=pollora-modules'); - await expect(page.locator('.notice-warning')).toContainText('Stored in modules_statuses.json — the next deployment resets it.'); + // Not every .notice-warning of the page: WordPress adds its own when a core update is available. + await expect(page.locator('.notice-warning', { hasText: 'Stored in modules_statuses.json' })).toContainText('the next deployment resets it.'); }); });