From 591ae26f199710da5654f18fc25d792017ce7a4f Mon Sep 17 00:00:00 2001 From: Eduardo Pittol Date: Sun, 12 Jul 2026 11:42:21 -0300 Subject: [PATCH 1/2] Make WooCommerceWebDriver DB-free: dissolve shared trait, drop WPDb guard WooCommerceWebDriver._initialize() now requires only WPWebDriver; the WPDb sibling check is gone since the browser layer no longer touches the database. WooCommerceModuleSupport is dissolved since nothing genuinely shared remained: wpDb() moves onto WooCommerceDb, and selector() plus the page-slug config accessors move onto WooCommerceWebDriver directly. WooCommerceConfig and its Config/ namespace are deleted now that slugs are plain config accessors. Closes #51 --- src/WooCommerce/Config/WooCommerceConfig.php | 30 ----------- src/WooCommerce/Method/CartMethods.php | 5 +- src/WooCommerce/Method/CheckoutMethods.php | 7 +-- .../Method/CustomerBrowserMethods.php | 5 +- src/WooCommerce/Module/WooCommerceDb.php | 10 +++- .../Module/WooCommerceModuleSupport.php | 54 ------------------- .../Module/WooCommerceWebDriver.php | 49 +++++++++++++---- .../Config/WooCommerceConfigTest.php | 29 ---------- .../Module/SiblingModuleCheckTest.php | 16 +----- .../WooCommerceWebDriverPageSlugTest.php | 45 +++++++++------- 10 files changed, 81 insertions(+), 169 deletions(-) delete mode 100644 src/WooCommerce/Config/WooCommerceConfig.php delete mode 100644 src/WooCommerce/Module/WooCommerceModuleSupport.php delete mode 100644 tests/unit/WooCommerce/Config/WooCommerceConfigTest.php diff --git a/src/WooCommerce/Config/WooCommerceConfig.php b/src/WooCommerce/Config/WooCommerceConfig.php deleted file mode 100644 index 82620f9..0000000 --- a/src/WooCommerce/Config/WooCommerceConfig.php +++ /dev/null @@ -1,30 +0,0 @@ -cartPageSlug; - } - - public function checkoutPageSlug(): string - { - return $this->checkoutPageSlug; - } - - public function myAccountPageSlug(): string - { - return $this->myAccountPageSlug; - } -} diff --git a/src/WooCommerce/Method/CartMethods.php b/src/WooCommerce/Method/CartMethods.php index de91b37..9f92f81 100644 --- a/src/WooCommerce/Method/CartMethods.php +++ b/src/WooCommerce/Method/CartMethods.php @@ -4,7 +4,6 @@ namespace Aztec\WPBrowser\WooCommerce\Method; -use Aztec\WPBrowser\WooCommerce\Config\WooCommerceConfig; use Aztec\WPBrowser\WooCommerce\PageObject\CartPageObject; use Aztec\WPBrowser\WooCommerce\PageObject\PageObjectProvider; use Codeception\Util\Locator; @@ -14,7 +13,7 @@ trait CartMethods { abstract protected function wpWebDriver(): WPWebDriver; - abstract protected function wooCommerceConfig(): WooCommerceConfig; + abstract protected function cartPageSlug(): string; abstract protected function pageObjectProvider(): PageObjectProvider; @@ -33,7 +32,7 @@ abstract protected function selector(mixed $value): string; */ public function amOnCartPage(): void { - $this->wpWebDriver()->amOnPage($this->wooCommerceConfig()->cartPageSlug()); + $this->wpWebDriver()->amOnPage($this->cartPageSlug()); } /** diff --git a/src/WooCommerce/Method/CheckoutMethods.php b/src/WooCommerce/Method/CheckoutMethods.php index 049816e..1d863a1 100644 --- a/src/WooCommerce/Method/CheckoutMethods.php +++ b/src/WooCommerce/Method/CheckoutMethods.php @@ -4,17 +4,14 @@ namespace Aztec\WPBrowser\WooCommerce\Method; -use Aztec\WPBrowser\WooCommerce\Config\WooCommerceConfig; use Aztec\WPBrowser\WooCommerce\PageObject\CheckoutPageObject; use Aztec\WPBrowser\WooCommerce\PageObject\PageObjectProvider; -use lucatume\WPBrowser\Module\WPDb; use lucatume\WPBrowser\Module\WPWebDriver; trait CheckoutMethods { abstract protected function wpWebDriver(): WPWebDriver; - abstract protected function wpDb(): WPDb; - abstract protected function wooCommerceConfig(): WooCommerceConfig; + abstract protected function checkoutPageSlug(): string; abstract protected function pageObjectProvider(): PageObjectProvider; abstract protected function selector(mixed $value): string; @@ -33,7 +30,7 @@ abstract protected function selector(mixed $value): string; */ public function amOnCheckoutPage(): void { - $this->wpWebDriver()->amOnPage($this->wooCommerceConfig()->checkoutPageSlug()); + $this->wpWebDriver()->amOnPage($this->checkoutPageSlug()); $this->wpWebDriver()->waitForElement('.wc-block-checkout'); } diff --git a/src/WooCommerce/Method/CustomerBrowserMethods.php b/src/WooCommerce/Method/CustomerBrowserMethods.php index 8c0f955..0e1d1a3 100644 --- a/src/WooCommerce/Method/CustomerBrowserMethods.php +++ b/src/WooCommerce/Method/CustomerBrowserMethods.php @@ -4,14 +4,13 @@ namespace Aztec\WPBrowser\WooCommerce\Method; -use Aztec\WPBrowser\WooCommerce\Config\WooCommerceConfig; use lucatume\WPBrowser\Module\WPWebDriver; trait CustomerBrowserMethods { abstract protected function wpWebDriver(): WPWebDriver; - abstract protected function wooCommerceConfig(): WooCommerceConfig; + abstract protected function myAccountPageSlug(): string; /** * Navigate to the WooCommerce My Account page. @@ -26,6 +25,6 @@ abstract protected function wooCommerceConfig(): WooCommerceConfig; */ public function amOnMyAccountPage(): void { - $this->wpWebDriver()->amOnPage($this->wooCommerceConfig()->myAccountPageSlug()); + $this->wpWebDriver()->amOnPage($this->myAccountPageSlug()); } } diff --git a/src/WooCommerce/Module/WooCommerceDb.php b/src/WooCommerce/Module/WooCommerceDb.php index 8e2b160..56e60ba 100644 --- a/src/WooCommerce/Module/WooCommerceDb.php +++ b/src/WooCommerce/Module/WooCommerceDb.php @@ -19,6 +19,7 @@ use Aztec\WPBrowser\WooCommerce\SubscriptionStorage\SubscriptionStorageInterface; use Codeception\Exception\ModuleException; use Codeception\Module; +use lucatume\WPBrowser\Module\WPDb; class WooCommerceDb extends Module { @@ -28,7 +29,6 @@ class WooCommerceDb extends Module use OrderMethods; use ProductMethods; use SubscriptionMethods; - use WooCommerceModuleSupport; public function _initialize(): void { @@ -40,6 +40,14 @@ public function _initialize(): void } } + protected function wpDb(): WPDb + { + $module = $this->getModule('WPDb'); + assert($module instanceof WPDb); + + return $module; + } + protected function isHposEnabled(): bool { return HposState::isEnabled($this->wpDb()); diff --git a/src/WooCommerce/Module/WooCommerceModuleSupport.php b/src/WooCommerce/Module/WooCommerceModuleSupport.php deleted file mode 100644 index 4a56f2f..0000000 --- a/src/WooCommerce/Module/WooCommerceModuleSupport.php +++ /dev/null @@ -1,54 +0,0 @@ -getModule('WPDb'); - assert($module instanceof WPDb); - - return $module; - } - - protected function wooCommerceConfig(): WooCommerceConfig - { - return new WooCommerceConfig( - $this->pageSlugConfig('cartPageSlug'), - $this->pageSlugConfig('checkoutPageSlug'), - $this->pageSlugConfig('myAccountPageSlug'), - ); - } - - private function pageSlugConfig(string $key): string - { - $value = $this->_getConfig($key); - - if (!is_string($value)) { - throw new ModuleException($this, "Config key \"{$key}\" must be a string slug (e.g. \"/cart\")."); - } - - return $value; - } - - /** - * Narrow a page-object selector constant to a string. - * - * Page objects expose their selectors as untyped class constants because - * the package targets PHP 8.0+, where typed class constants are not - * available. Reading such a constant through a (non-final, overridable) - * page-object instance therefore widens to mixed under static analysis. - * Selectors are always strings, so this safely narrows the value. - */ - protected function selector(mixed $value): string - { - return is_string($value) ? $value : ''; - } -} diff --git a/src/WooCommerce/Module/WooCommerceWebDriver.php b/src/WooCommerce/Module/WooCommerceWebDriver.php index 8ecba26..9502a29 100644 --- a/src/WooCommerce/Module/WooCommerceWebDriver.php +++ b/src/WooCommerce/Module/WooCommerceWebDriver.php @@ -19,7 +19,6 @@ class WooCommerceWebDriver extends Module use CheckoutMethods; use CustomerBrowserMethods; use OrderBrowserMethods; - use WooCommerceModuleSupport; /** @var array */ protected array $config = [ @@ -44,14 +43,6 @@ public function _initialize(): void 'WooCommerceWebDriver requires the WPWebDriver module to be enabled in the same suite.', ); } - - if (! $this->hasModule('WPDb')) { - throw new ModuleException( - $this, - 'WooCommerceWebDriver requires the WPDb module to be enabled in the same suite ' - . '(it reads product and cart data directly from the database).', - ); - } } protected function wpWebDriver(): WPWebDriver @@ -72,4 +63,44 @@ protected function pageObjectProvider(): PageObjectProvider return $this->pageObjectProvider; } + + protected function cartPageSlug(): string + { + return $this->pageSlugConfig('cartPageSlug'); + } + + protected function checkoutPageSlug(): string + { + return $this->pageSlugConfig('checkoutPageSlug'); + } + + protected function myAccountPageSlug(): string + { + return $this->pageSlugConfig('myAccountPageSlug'); + } + + private function pageSlugConfig(string $key): string + { + $value = $this->_getConfig($key); + + if (!is_string($value)) { + throw new ModuleException($this, "Config key \"{$key}\" must be a string slug (e.g. \"/cart\")."); + } + + return $value; + } + + /** + * Narrow a page-object selector constant to a string. + * + * Page objects expose their selectors as untyped class constants because + * the package targets PHP 8.0+, where typed class constants are not + * available. Reading such a constant through a (non-final, overridable) + * page-object instance therefore widens to mixed under static analysis. + * Selectors are always strings, so this safely narrows the value. + */ + protected function selector(mixed $value): string + { + return is_string($value) ? $value : ''; + } } diff --git a/tests/unit/WooCommerce/Config/WooCommerceConfigTest.php b/tests/unit/WooCommerce/Config/WooCommerceConfigTest.php deleted file mode 100644 index 6c57847..0000000 --- a/tests/unit/WooCommerce/Config/WooCommerceConfigTest.php +++ /dev/null @@ -1,29 +0,0 @@ -assertSame('/cart', $config->cartPageSlug()); - $this->assertSame('/checkout', $config->checkoutPageSlug()); - $this->assertSame('/my-account', $config->myAccountPageSlug()); - } - - public function testReturnsPerSlugOverridesVerbatim(): void - { - $config = new WooCommerceConfig('/basket', '/pay', '/account'); - - $this->assertSame('/basket', $config->cartPageSlug()); - $this->assertSame('/pay', $config->checkoutPageSlug()); - $this->assertSame('/account', $config->myAccountPageSlug()); - } -} diff --git a/tests/unit/WooCommerce/Module/SiblingModuleCheckTest.php b/tests/unit/WooCommerce/Module/SiblingModuleCheckTest.php index 9119f26..dc02381 100644 --- a/tests/unit/WooCommerce/Module/SiblingModuleCheckTest.php +++ b/tests/unit/WooCommerce/Module/SiblingModuleCheckTest.php @@ -44,24 +44,10 @@ public function testWooCommerceWebDriverThrowsWhenWpWebDriverIsMissing(): void $module->_initialize(); } - public function testWooCommerceWebDriverThrowsWhenWpDbIsMissing(): void + public function testWooCommerceWebDriverInitializesWhenWpWebDriverIsPresent(): void { $module = $this->moduleWithSiblings(WooCommerceWebDriver::class, [ 'WPWebDriver' => true, - 'WPDb' => false, - ]); - - $this->expectException(ModuleException::class); - $this->expectExceptionMessage('WPDb'); - - $module->_initialize(); - } - - public function testWooCommerceWebDriverInitializesWhenBothSiblingsArePresent(): void - { - $module = $this->moduleWithSiblings(WooCommerceWebDriver::class, [ - 'WPWebDriver' => true, - 'WPDb' => true, ]); $this->expectNotToPerformAssertions(); diff --git a/tests/unit/WooCommerce/Module/WooCommerceWebDriverPageSlugTest.php b/tests/unit/WooCommerce/Module/WooCommerceWebDriverPageSlugTest.php index 199c2f3..2147029 100644 --- a/tests/unit/WooCommerce/Module/WooCommerceWebDriverPageSlugTest.php +++ b/tests/unit/WooCommerce/Module/WooCommerceWebDriverPageSlugTest.php @@ -4,7 +4,6 @@ namespace Aztec\WPBrowser\Tests\Unit\WooCommerce\Module; -use Aztec\WPBrowser\WooCommerce\Config\WooCommerceConfig; use Aztec\WPBrowser\WooCommerce\Module\WooCommerceWebDriver; use Codeception\Test\Unit; use PHPUnit\Framework\MockObject\MockObject; @@ -15,11 +14,11 @@ class WooCommerceWebDriverPageSlugTest extends Unit { public function testDefaultsToWooCommerceConventionSlugs(): void { - $config = $this->wooCommerceConfigOf($this->module()); + $module = $this->module(); - $this->assertSame('/cart', $config->cartPageSlug()); - $this->assertSame('/checkout', $config->checkoutPageSlug()); - $this->assertSame('/my-account', $config->myAccountPageSlug()); + $this->assertSame('/cart', $this->invoke($module, 'cartPageSlug')); + $this->assertSame('/checkout', $this->invoke($module, 'checkoutPageSlug')); + $this->assertSame('/my-account', $this->invoke($module, 'myAccountPageSlug')); } public function testEachSlugIsIndependentlyOverridable(): void @@ -28,11 +27,28 @@ public function testEachSlugIsIndependentlyOverridable(): void 'checkoutPageSlug' => '/finalizar-compra', ]); - $config = $this->wooCommerceConfigOf($module); + $this->assertSame('/cart', $this->invoke($module, 'cartPageSlug'), 'untouched slug keeps its default'); + $this->assertSame( + '/finalizar-compra', + $this->invoke($module, 'checkoutPageSlug'), + 'overridden slug wins', + ); + $this->assertSame( + '/my-account', + $this->invoke($module, 'myAccountPageSlug'), + 'untouched slug keeps its default', + ); + } + + private function invoke(WooCommerceWebDriver $module, string $method): string + { + $reflection = new ReflectionMethod($module, $method); + $reflection->setAccessible(true); - $this->assertSame('/cart', $config->cartPageSlug(), 'untouched slug keeps its default'); - $this->assertSame('/finalizar-compra', $config->checkoutPageSlug(), 'overridden slug wins'); - $this->assertSame('/my-account', $config->myAccountPageSlug(), 'untouched slug keeps its default'); + $value = $reflection->invoke($module); + assert(is_string($value)); + + return $value; } /** @@ -56,15 +72,4 @@ private function module(array $overrides = []): WooCommerceWebDriver return $module; } - - private function wooCommerceConfigOf(WooCommerceWebDriver $module): WooCommerceConfig - { - $method = new ReflectionMethod($module, 'wooCommerceConfig'); - $method->setAccessible(true); - - $config = $method->invoke($module); - assert($config instanceof WooCommerceConfig); - - return $config; - } } From 6423a6d93be38e507076adb1bace9f3163aca239 Mon Sep 17 00:00:00 2001 From: Eduardo Pittol Date: Sun, 12 Jul 2026 12:47:09 -0300 Subject: [PATCH 2/2] Use PHPUnit assertIsString instead of native assert() in test Native assert() silently no-ops when zend.assertions is disabled, which defeats the point of a test assertion; PHPUnit's assertIsString always runs and reports a proper failure. --- .../WooCommerce/Module/WooCommerceWebDriverPageSlugTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/WooCommerce/Module/WooCommerceWebDriverPageSlugTest.php b/tests/unit/WooCommerce/Module/WooCommerceWebDriverPageSlugTest.php index 2147029..5963288 100644 --- a/tests/unit/WooCommerce/Module/WooCommerceWebDriverPageSlugTest.php +++ b/tests/unit/WooCommerce/Module/WooCommerceWebDriverPageSlugTest.php @@ -46,7 +46,7 @@ private function invoke(WooCommerceWebDriver $module, string $method): string $reflection->setAccessible(true); $value = $reflection->invoke($module); - assert(is_string($value)); + $this->assertIsString($value); return $value; }