Plugin-aware Codeception modules for WordPress acceptance testing, built as composition extensions over wp-browser. One pair of modules per supported WordPress plugin (one for the DB layer, one for the browser layer); modules compose Method Traits to assemble actor methods.
Plugin Module:
A Codeception module dedicated to one WordPress plugin's domain (e.g., WooCommerceDb, WooCommerceWebDriver); always extends \Codeception\Module and reaches wp-browser via getModule().
Avoid: WP module, plugin extension, aztec module.
Method Trait:
A PHP trait providing public actor methods for one cohesive domain within a plugin (e.g., CouponMethods); composed into a Plugin Module via use.
Avoid: Helper trait, trait module.
Plugin Subnamespace:
A top-level namespace under Aztec\WPBrowser\ dedicated to one WordPress plugin or shared library (e.g., Aztec\WPBrowser\WooCommerce\, Aztec\WPBrowser\ActionScheduler\); contains that plugin's Plugin Modules, Method Traits, and Page Objects.
Avoid: Plugin folder, plugin namespace (ambiguous with raw PHP namespaces).
Class Alias Trick:
The composer files-autoload mechanism that registers Codeception\Module\X as an alias for a Plugin Module's real class, so suite.yml can reference it by short name; lives in src/aliases.php with a safeguard against namespace squatting.
Avoid: Module shim, alias bridge.
Sibling Module:
A Codeception module enabled in the same suite, accessed by a Plugin Module via $this->getModule(); for this library, the relevant siblings are WPDb and WPWebDriver from wp-browser.
Avoid: Dependency module, parent module.
Actor:
The test pseudo-user ($I in Cest files), assembled by Codeception from the public methods of all enabled modules — including the library's Plugin Modules and their composed Method Traits.
Avoid: Tester (reserved for the concrete class name AcceptanceTester).
HPOS:
WooCommerce's High-Performance Order Storage feature — orders persisted in custom tables (wp_wc_orders family) rather than wp_posts/wp_postmeta. Handled per layer: WooCommerceDb detects it from the database; WooCommerceWebDriver must never query the database, so it is told the order-storage mode via a single config flag (legacyOrderStorage, default false) that governs every HPOS-dependent browser behavior. Never exposed as a public actor method.
Avoid: Custom orders table, COT, HPOS mode.
First-class library: The project's stated quality target — equipped with level-max static analysis, semver-disciplined releases, polished README, and CI gates from day one, even though external adoption is deferred. Avoid: Production-ready (vague), enterprise-grade (marketing).
- A Plugin Subnamespace contains one or more Plugin Modules plus all their Method Traits and any Page Objects.
- A Plugin Module is composed of one or more Method Traits via
usestatements. - A Plugin Module declares Sibling Module requirements in
_initialize()and accesses them viagetModule(). - The Class Alias Trick maps
\Codeception\Module\Xto a Plugin Module's real class so consumers reference it by short name. - HPOS handling is split by layer:
WooCommerceDbdetects it from the database, whileWooCommerceWebDriveris declared the order-storage mode through one config flag (legacyOrderStorage) and never queries the DB. A single flag — not per-screen flags — so an impossible mixed state (one screen HPOS, another legacy) cannot be expressed. Neither layer exposes HPOS on the public actor API.
Contributor: "I want to add Easy Digital Downloads (EDD) support. Should I add traits to
WooCommerceDb?"Maintainer: "No — separate plugin, separate Plugin Subnamespace. Create
Aztec\WPBrowser\Edd\containing anEddDbandEddWebDriverPlugin Module, with Method Traits underAztec\WPBrowser\Edd\Method\. BothEddDbandWooCommerceDbindependently usegetModule('WPDb')for the Sibling wp-browser module."Contributor: "What if I need a method that creates a WooCommerce order and an EDD download in one shot?"
Maintainer: "Don't. Cross-plugin orchestration belongs in the consumer's Cest, not in the library. Compose
$I->haveOrderInDatabase(...)followed by$I->haveDownloadInDatabase(...)in the test. Each Plugin Module stays focused on its plugin's concern."Contributor: "Why is there no
$I->isHposEnabled()?"Maintainer: "HPOS stays off the actor — there's no
$I->isHposEnabled(). The DB layer detects it from the database; the browser layer can't touch the database, so it's told the order-storage mode once via thelegacyOrderStorageconfig flag and routes admin URLs from that. One flag for the whole browser layer, never a public actor method."
- "Module" (generic Codeception term) vs. Plugin Module (this library's plugin-flavored modules) — when ambiguous, default to Plugin Module.
- "Trait" (generic PHP construct) vs. Method Trait (this library's actor-method-providing traits in
src/{Plugin}/Method/) — default to the qualified term. - "HPOS detection" — implementation detail; never expose as part of the actor or any module's public API.