-
Notifications
You must be signed in to change notification settings - Fork 214
All/e2e fix #2960
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
All/e2e fix #2960
Conversation
…ptions and streamline methods
- Improved error handling in the AbuseReportsPage to continue execution despite AJAX failures, providing fallback options for selecting filters and handling bulk actions. - Updated selectors in the selectors.ts file for better flexibility in identifying report elements. - Added comprehensive checks in VendorReportsPage for rendering, navigation, and data validation, including responsiveness and accessibility tests. - Introduced new methods for filtering and exporting reports, ensuring robust interaction with the analytics dashboard. - Adjusted test cases to use safer actions and improved logging for better traceability during test execution.
- Updated `clickAndWaitForResponseAndLoadState` method to specify 'load' state for better synchronization. - Modified `viewBookingProduct` method to directly click without waiting for load state. - Enhanced test timeout to 45 seconds for faster execution. - Implemented exponential backoff for API product creation retries and added error handling for critical setup operations. - Streamlined cleanup operations with error handling to ensure test stability. - Organized tests into parallel and sequential categories for improved execution flow.
* fix: Shortcode templates fields not exists issue. * fix: update coupon section text for consistency.
…dation. (#2872) * fix: Coupon creation execution by ensuring proper load state and validation. * fix: update coupon selector text for consistency in the marketplace
refactor: enhance abuse reports and vendor reports functionality
fix: update env:setup script in package.json to include NO_SETUP flag…
…ity checks - Changed visibility check for admin notices container to a more specific selector. - Updated the dashboard text selector to use a normalized space query for consistency. - Modified the expectTotalNotices method to remove the count parameter and focus on visibility of a specific notice. - Skipped the vendor analytics test suite for future implementation.
refactor: update admin notice page and selectors for improved visibil…
test: skip Product AI test suite and add tag to product title test
Fix/follow store test
… tests - Refactored CouponsPage class to improve structure and readability. - Added new methods for navigating and managing coupons, including creating, searching, and verifying coupons. - Updated e2e tests to utilize the refactored CouponsPage class, ensuring better organization and clarity in test cases for admin, vendor, and customer coupon functionalities.
…ure and data handling - Refactored coupon management tests to utilize a centralized test data structure for better maintainability. - Implemented cleanup logic to remove test coupons after all tests are completed. - Updated test cases for admin and vendor coupon functionalities to improve clarity and organization. - Ensured consistent usage of Playwright's page interactions across all test scenarios.
- Updated the CouponsPage class to include additional locators and methods for better organization and maintainability. - Refactored test cases to utilize the new CouponsPage methods, improving clarity and reducing redundancy. - Ensured consistent handling of coupon creation, verification, and management across admin and vendor functionalities. - Improved test data structure for easier updates and maintenance.
refactor: restructure CouponsPage class and enhance coupon management…
feat: enhance environment variable typing in testData.ts for better t…
- Restored and organized selectors for category selection, radius slider, and search button in the selectors.ts file. - Removed outdated merge conflict markers to ensure clean code.
- Temporarily disabled the background color assertion for the menu switcher to address potential test flakiness.
- Temporarily commented out the upgradePlan selector to improve code readability and maintainability.
- Upgraded @faker-js/faker to version 10.0.0 and @playwright/test to version 1.57.0 to leverage new features and enhancements. - This change ensures compatibility with the latest testing frameworks and libraries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @tests/pw/package.json:
- Around line 181-182: Update the package.json engines.node constraint to match
@faker-js/faker v10's requirement: change the Node version spec in the
package.json "engines" field from ">=16.0.0" to ">=20.19.0" so the installed
Node runtime is compatible with the new "@faker-js/faker": "^10.0.0" dependency;
ensure any CI/workflow configs respect this updated engines requirement.
🧹 Nitpick comments (3)
tests/pw/package.json (3)
7-10: Consider updating minimum Node.js version requirement.Node.js 16 reached end-of-life in September 2023. For security and compatibility with modern tooling, consider updating the minimum to Node 18 (LTS) or Node 20:
"engines": { - "node": ">=16.0.0", + "node": ">=18.0.0", "npm": ">=8.0.0" },
68-68: Extract complex inline script to a separate file for maintainability.This inline script is difficult to read, debug, and maintain. Consider extracting it to a dedicated script file like
scripts/create-admin.js:-"create:admin": "node -e \"require('dotenv').config(); const {execSync} = require('child_process'); const user = process.env.ADMIN || 'shohan'; ...", +"create:admin": "node scripts/create-admin.js",This would improve:
- Readability and syntax highlighting
- Debuggability with proper stack traces
- Testability of the script logic
- Easier maintenance and code review
124-128: Unix-specific commands limit cross-platform compatibility.These verification scripts use
grep,cut,jq,xargs, andwcwhich are not available on Windows without WSL. If Windows support is needed, consider using Node.js scripts or documenting the WSL/Unix requirement.Also, the credential extraction in
check:modules(grep ADMIN= .env | cut -d= -f2) is fragile and may fail if values contain=characters or if the .env format varies.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
tests/pw/package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: e2e tests (1, 3)
- GitHub Check: e2e tests (3, 3)
- GitHub Check: e2e tests (2, 3)
- GitHub Check: api tests (1, 1)
🔇 Additional comments (2)
tests/pw/package.json (2)
143-163: LGTM! Clean deprecation pattern with backwards compatibility.The deprecation wrappers that echo warnings and redirect to new commands is a user-friendly approach. This gives developers time to migrate while maintaining backwards compatibility.
2-6: LGTM! Good metadata additions.Adding
"private": trueprevents accidental npm publication, and the explicit versioning (2.0.0) properly signals this is a major restructuring of the test suite.
| "@faker-js/faker": "^10.0.0", | ||
| "@playwright/test": "^1.57.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
@faker-js/faker version 10 breaking changes migration guide
💡 Result:
Summary of the important breaking changes in @faker-js/faker v10 and quick migration steps:
Key breaking changes
- Node/engine: v10 requires Node >= 20.19.0 (or 22.13.0 / 24.0.0); Node 18 is not supported. [1]
- ESM-first: package is ESM-only (but can still be used from CJS on recent Node versions via Node's ESM require support). If using CJS ensure Node >= 20.19 or 22.13. [1][2]
- TypeScript/moduleResolution: v10 only supports "Bundler", "Node20" or "NodeNext" for moduleResolution; using "Node20" requires TS >= 5.9.0. [1]
- Jest incompatibility: Jest module resolution may break with v10 + CJS — keep v9 or follow workarounds. [1]
- Removal of deprecated APIs: many methods deprecated in v9 were removed in v10 (e.g., faker.address.* → faker.location., faker.name. → faker.person.*, internet.userName → internet.username; several image/finance methods removed). Check mapping in the guide. [1]
- Word module behavior: default resolution strategy changed to "fail" (methods now throw when no words match length/criteria). To restore v9 behavior use strategy: 'any-length' in word calls. [1]
Quick migration checklist
- Read the official v10 upgrade guide and changelog. [1][2]
- First upgrade to the latest v9 and fix all deprecation warnings in your code (recommended before moving to v10). [1]
- Ensure your runtime/build: Node >= 20.19 (or 22.13+) and TypeScript >= 5.9 if using Node20 moduleResolution. Update tsconfig.moduleResolution accordingly. [1]
- Replace removed APIs with their v10 equivalents (address → location, name → person, userName → username, etc.). Use the guide’s removal/replacement table. [1]
- Update any word.* calls that relied on v9 forgiving behavior to pass { strategy: 'any-length' } or adjust criteria. [1]
- If you use CommonJS or Jest, test thoroughly and consider staying on v9 until you can adopt the recommended Node/TS versions or apply documented workarounds. [1]
- Run your test suite and look for ERR_REQUIRE_ESM or other module-resolution errors; adjust imports/tsconfig or Node version as needed. [1][2]
References
- Official "Upgrading to v10" migration guide. [1]
- faker-js/faker GitHub releases (v10 changelog). [2]
Would you like me to produce a concrete diff / find-and-replace list for your codebase (e.g., map all faker.name.* → faker.person.*) if you paste a snippet or list of usages?
🏁 Script executed:
# Search for faker usage in the test files
find tests -name "*.js" -o -name "*.ts" -o -name "*.jsx" -o -name "*.tsx" | head -20Repository: getdokan/dokan
Length of output: 671
🏁 Script executed:
# Look for any faker imports or usage
rg "@faker-js/faker|from.*faker|import.*faker" tests/ --type ts --type jsRepository: getdokan/dokan
Length of output: 193
🏁 Script executed:
cat -n tests/pw/utils/payloads.tsRepository: getdokan/dokan
Length of output: 50371
🏁 Script executed:
cat -n tests/pw/utils/testData.tsRepository: getdokan/dokan
Length of output: 50371
🏁 Script executed:
# Check if there's a .npmrc or package.json for Node version requirements
cat tests/pw/package.json | grep -A 5 -B 5 "engines\|node"Repository: getdokan/dokan
Length of output: 3390
Critical: Node version requirement is incompatible with faker-js v10.
The upgrade to @faker-js/faker v10.0.0 requires Node >= 20.19.0, but the package.json specifies "node": ">=16.0.0". Update the Node version requirement to >=20.19.0 to ensure compatibility. The API usage in the test suite appears compatible (correctly using faker.person.firstName() instead of deprecated faker.name.firstName()), but the environment constraint must be met.
🤖 Prompt for AI Agents
In @tests/pw/package.json around lines 181 - 182, Update the package.json
engines.node constraint to match @faker-js/faker v10's requirement: change the
Node version spec in the package.json "engines" field from ">=16.0.0" to
">=20.19.0" so the installed Node runtime is compatible with the new
"@faker-js/faker": "^10.0.0" dependency; ensure any CI/workflow configs respect
this updated engines requirement.
…d testing environment - Updated package-lock.json to reflect changes in package versions, including upgrading @faker-js/faker to 10.2.0 and @playwright/test to 1.57.0 for enhanced functionality and compatibility. - Modified .wp-env.override.json to include local plugin mappings, ensuring a smoother setup for testing with Dokan Pro and WooCommerce extensions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tests/pw/package.json (1)
156-179: Updateenginesconstraint to reflect Playwright 1.57.0 compatibility.The current
enginesfield specifies>=16.0.0, but Playwright 1.57.0 requires Node.js 20.x or later (Node versions 20, 22, and 24 are officially supported; Node 14+ is no longer supported). Update the constraint to"node": ">=20.0.0"to prevent installation on incompatible Node versions.
🤖 Fix all issues with AI agents
In `@tests/pw/.wp-env.override.json`:
- Around line 1-27: The committed tests/pw/.wp-env.override.json contains
machine-specific relative paths (e.g., "../../../dokan-pro",
"../../../woocommerce-bookings" and mappings like
"wp-content/plugins/dokan-pro") and should be ignored and replaced with a
template; update the repository by adding tests/pw/.wp-env.override.json to
.gitignore and create tests/pw/.wp-env.override.json.example containing the same
keys (env, tests, plugins, config, mappings) but with placeholder paths and
comments so developers can copy and customize locally while keeping the real
override out of version control.
♻️ Duplicate comments (3)
tests/pw/package.json (3)
66-66: Extract the inlinecreate:adminscript into a file.
The inline Node script is hard to maintain and review in JSON; moving it toscripts/create-admin.jswill improve readability and reuse.♻️ Package.json update
- "create:admin": "node -e \"require('dotenv').config(); const {execSync} = require('child_process'); ...\"", + "create:admin": "node scripts/create-admin.js",
7-10: Update Node engine to match@faker-js/fakerv10 requirements.
If faker v10 enforces Node ≥ 20.19, the current>=16.0.0range will allow unsupported runtimes and break installs/tests. Please verify the requirement and alignengines.node(and CI) accordingly.🔧 Proposed update
- "node": ">=16.0.0", + "node": ">=20.19.0",What is the Node.js engine requirement for `@faker-js/faker` v10?
117-117:check:modulesis Unix-only—consider a Node script or docs.
grep/cut/curl/jq/wcwill fail on Windows shells. Either add a small Node script or document the Unix-only requirement.💡 Package.json update (if you add a Node script)
- "check:modules": "curl -s http://localhost:9999/?rest_route=/dokan/v1/admin/modules -u $(grep ADMIN= .env | cut -d= -f2):$(grep ADMIN_PASSWORD= .env | cut -d= -f2) | jq -r '.[] | select(.active == true) | .id' | wc -l | xargs echo 'Active modules:'", + "check:modules": "node scripts/check-modules.js",
| { | ||
| "env": { | ||
| "tests": { | ||
| "plugins": [ | ||
| "https://github.com/WP-API/Basic-Auth/archive/master.zip", | ||
| "https://downloads.wordpress.org/plugin/woocommerce.latest-stable.zip", | ||
| "../../", | ||
| "../../../dokan-pro", | ||
| "../../../woocommerce-bookings", | ||
| "../../../woocommerce-product-addons", | ||
| "../../../woocommerce-simple-auctions", | ||
| "../../../woocommerce-subscriptions" | ||
| ], | ||
| "config": { | ||
| "WP_MEMORY_LIMIT": "1024M", | ||
| "WP_MAX_MEMORY_LIMIT": "1024M" | ||
| }, | ||
| "mappings": { | ||
| "wp-data": "./wp-data", | ||
| "wp-content/debug.log": "./wp-data/debug.log", | ||
| "wp-content/mu-plugins": "./mu-plugins", | ||
| "wp-content/plugins/dokan-lite": "../../", | ||
| "wp-content/plugins/dokan-pro": "../../../dokan-pro" | ||
| } | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if .wp-env.override.json is in .gitignore
echo "=== Checking .gitignore for wp-env override patterns ==="
rg -n "wp-env.override" .gitignore 2>/dev/null || echo "No wp-env.override pattern found in .gitignore"
# Check for any .example template files
echo -e "\n=== Checking for existing template files ==="
fd -t f "wp-env.*example" tests/pw/ 2>/dev/null || echo "No template files found"
# Check what the base .wp-env.json looks like
echo -e "\n=== Contents of base .wp-env.json ==="
cat tests/pw/.wp-env.json 2>/dev/null || echo "Base file not found"
# Check if the override file itself exists in the repo
echo -e "\n=== Checking if override file exists ==="
ls -la tests/pw/.wp-env.override.json 2>/dev/null || echo "Override file not found"
# Check .gitignore patterns more broadly for wp-env files
echo -e "\n=== Broader .gitignore patterns for wp-env files ==="
rg -n "\.wp-env" .gitignore 2>/dev/null || echo "No .wp-env patterns found in .gitignore"Repository: getdokan/dokan
Length of output: 1428
This override file contains machine-specific paths and must be gitignored.
The .wp-env.override.json file is currently committed to the repository but contains relative paths like ../../../dokan-pro, ../../../woocommerce-bookings, etc., that assume a specific local directory structure. These paths won't exist in CI environments or on other developers' machines, causing build failures and setup issues.
Required fixes:
- Add
tests/pw/.wp-env.override.jsonto.gitignore - Create a
.wp-env.override.json.exampletemplate file that developers can copy and customize locally
The base .wp-env.json file already provides the standard plugin configurations; the override should remain machine-specific and out of version control.
🧰 Tools
🪛 GitHub Actions: Inspections
[error] 1-1: The file 'tests/pw/.wp-env.override' does not exist. (Command: vendor/bin/phpcs ... | cs2pr ..., exit code 2)
🤖 Prompt for AI Agents
In `@tests/pw/.wp-env.override.json` around lines 1 - 27, The committed
tests/pw/.wp-env.override.json contains machine-specific relative paths (e.g.,
"../../../dokan-pro", "../../../woocommerce-bookings" and mappings like
"wp-content/plugins/dokan-pro") and should be ignored and replaced with a
template; update the repository by adding tests/pw/.wp-env.override.json to
.gitignore and create tests/pw/.wp-env.override.json.example containing the same
keys (env, tests, plugins, config, mappings) but with placeholder paths and
comments so developers can copy and customize locally while keeping the real
override out of version control.
… environment - Introduced a new `SETUP-GUIDE.md` file detailing step-by-step instructions for setting up the Dokan development environment, including prerequisites, installation of dependencies, environment configuration, and Docker setup. - Included troubleshooting tips and a quick command reference to facilitate smoother onboarding for new developers. - Emphasized the importance of building assets and ensuring all required plugins are active for successful test execution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@tests/pw/SETUP-GUIDE.md`:
- Around line 36-45: Update the navigation step in SETUP-GUIDE.md to clarify the
starting directory for the cd tests/pw command by adding a short
parent-directory context (e.g., "from plugin root: dokan-lite/" and an
alternative "from WordPress root: wp-content/plugins/dokan-lite/") so readers
know where to run cd tests/pw; modify the comment line above the cd tests/pw
entry in the tests/pw section accordingly (the block containing the cd tests/pw
command).
- Around line 16-28: The setup guide's "cd wp-content/plugins/dokan-lite" step
is ambiguous about the current working directory; update SETUP-GUIDE.md to
explicitly state the assumed starting location (WordPress installation root) and
provide an alternative command or guidance for users starting from the
repository root (e.g., an alternate cd path or how to reach the WordPress root),
and add a brief "Directory Structure" note listing WordPress root and plugin
paths so users know where to run the commands.
🧹 Nitpick comments (2)
tests/pw/SETUP-GUIDE.md (2)
49-81: Reference the.env.examplefile for consistency.The guide provides a manual .env configuration example, but based on the AI summary, there's a
.env.examplefile in the repository attests/pw/.env.example. Consider directing users to copy and modify the example file rather than manually creating the configuration, which reduces errors and ensures consistency with the actual template.📝 Proposed improvement
## Step 3: Configure Environment -Create a `.env` file in `tests/pw/` directory: +Copy the example environment file and configure it: + +```bash +# From tests/pw/ directory +cp .env.example .env +``` + +Then edit `.env` with your configuration: ```env # Admin Configuration (REQUIRED)Alternatively, add a note like:
> 💡 **Tip:** You can copy `.env.example` as a starting point: `cp .env.example .env`
195-203: Add language identifier to fenced code block.The code block is missing a language specification, which affects syntax highlighting and accessibility.
📝 Proposed fix
If you see: -``` +```text ✖ Error while running docker compose command. Warning: Failed to activate plugin. Dokan Pro requires Dokan Lite</details> Based on static analysis findings. </blockquote></details> </blockquote></details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
| ```bash | ||
| # Navigate to plugin root | ||
| cd wp-content/plugins/dokan-lite | ||
|
|
||
| # Install PHP dependencies | ||
| composer install && composer dump-autoload --optimize | ||
|
|
||
| # Install JavaScript dependencies | ||
| npm install | ||
|
|
||
| # Build plugin assets (REQUIRED!) | ||
| npm run build | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarify the starting directory for path navigation.
The instruction assumes users are starting from the WordPress root directory, but this isn't explicitly stated. New users might be in the repository root, project root, or elsewhere, leading to "no such file or directory" errors.
📝 Proposed fix to clarify starting location
```bash
-# Navigate to plugin root
+# Navigate to plugin root (from WordPress installation root)
cd wp-content/plugins/dokan-lite
+
+# OR if you're in the repository root:
+# cd ../../ # adjust based on your directory structure
# Install PHP dependencies
composer install && composer dump-autoload --optimizeAlternatively, consider adding a section at the beginning that explicitly states:
## Directory Structure
This guide assumes the following structure:
- WordPress root: `/path/to/wordpress/`
- Dokan plugin: `/path/to/wordpress/wp-content/plugins/dokan-lite/`
- Tests: `/path/to/wordpress/wp-content/plugins/dokan-lite/tests/pw/`🤖 Prompt for AI Agents
In `@tests/pw/SETUP-GUIDE.md` around lines 16 - 28, The setup guide's "cd
wp-content/plugins/dokan-lite" step is ambiguous about the current working
directory; update SETUP-GUIDE.md to explicitly state the assumed starting
location (WordPress installation root) and provide an alternative command or
guidance for users starting from the repository root (e.g., an alternate cd path
or how to reach the WordPress root), and add a brief "Directory Structure" note
listing WordPress root and plugin paths so users know where to run the commands.
| ```bash | ||
| # Navigate to test directory | ||
| cd tests/pw | ||
|
|
||
| # Install test dependencies | ||
| npm install | ||
|
|
||
| # Install Playwright browsers | ||
| npx playwright install chromium | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Specify the starting directory for test navigation.
Similar to Step 1, the path tests/pw needs clarification about the starting directory.
📝 Proposed fix
```bash
-# Navigate to test directory
+# Navigate to test directory (from plugin root: dokan-lite/)
cd tests/pw
+
+# OR from WordPress root:
+# cd wp-content/plugins/dokan-lite/tests/pw
# Install test dependencies
npm install🤖 Prompt for AI Agents
In `@tests/pw/SETUP-GUIDE.md` around lines 36 - 45, Update the navigation step in
SETUP-GUIDE.md to clarify the starting directory for the cd tests/pw command by
adding a short parent-directory context (e.g., "from plugin root: dokan-lite/"
and an alternative "from WordPress root: wp-content/plugins/dokan-lite/") so
readers know where to run cd tests/pw; modify the comment line above the cd
tests/pw entry in the tests/pw section accordingly (the block containing the cd
tests/pw command).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🤖 Fix all issues with AI agents
In `@tests/pw/pages/vendorBookingPage.ts`:
- Around line 950-952: The comment above the method is incorrect—it's labeled
"add product linked products" but the method is removeProductLinkedProducts;
update the comment to accurately describe the method's purpose (e.g., "remove
product linked products" or "remove linked products for a product") to match the
removeProductLinkedProducts(productName, linkedProducts, choice) method
signature and intent; ensure any surrounding comments/docblocks referencing this
method are similarly corrected for clarity.
- Around line 736-742: The top-of-function comment is incorrect: update the
comment above the removeProductShipping method to accurately describe its
behavior (e.g., change "add product shipping" to "remove product shipping" or a
similar brief phrase). Locate the removeProductShipping function and replace the
misleading comment so it matches the method name and actions
(goToBookingProductEditById, uncheck(productsVendor.shipping.requiresShipping),
saveProduct, notToBeChecked). Ensure no other comments around that block still
say "add".
- Around line 36-49: In disableBookingModule(), the final assertion incorrectly
calls toBeVisible for selector.customer.cMyAccount.menus.bookings; change this
to assert the menu is not visible by using the notToBeVisible helper for
selector.customer.cMyAccount.menus.bookings so the method consistently verifies
the booking menu is hidden when the booking module is disabled.
- Around line 296-306: The top-line comment above the editBookingResource method
is incorrect ("add booking resource"); update or replace it to accurately
describe the method (e.g., "edit booking resource" or "update booking resource")
so the comment matches the function behavior in editBookingResource, ensuring it
reflects that the method navigates to manage resources and updates an existing
resource.
- Around line 270-276: The leading comment above the duplicateBookingProduct
method is incorrect ("delete booking product"); update or remove it so it
correctly reflects the method's behavior—e.g., change to "duplicate booking
product" or delete the misleading comment. Locate the comment immediately before
the duplicateBookingProduct function and adjust it to match the function name
and behavior (duplicateBookingProduct, bookingProductsVendor.duplicate,
dokanSuccessMessage).
🧹 Nitpick comments (1)
tests/pw/pages/vendorBookingPage.ts (1)
354-360: Consider renaming parameterproductNametoproductIdfor clarity.The parameter
productNameis passed togoToBookingProductEditById, which expects a product ID. This naming pattern is inconsistent and appears throughout many methods in this class (e.g.,addProductAccommodationBookingOptions,addProductCategory, etc.).♻️ Example fix for this method
- async addProductTitle(productName: string, title: string): Promise<void> { - await this.goToBookingProductEditById(productName); + async addProductTitle(productId: string, title: string): Promise<void> { + await this.goToBookingProductEditById(productId);
| // disable booking module | ||
| async disableBookingModule() { | ||
| // vendor dashboard menu | ||
| await this.goto(data.subUrls.frontend.vDashboard.dashboard); | ||
| await this.notToBeVisible(selector.vendor.vDashboard.menus.primary.booking); | ||
|
|
||
| // vendor dashboard menu page | ||
| await this.goto(data.subUrls.frontend.vDashboard.booking); | ||
| await this.notToBeVisible(selector.vendor.vDashboard.dashboardDiv); | ||
|
|
||
| // customer dashboard menu | ||
| await this.goto(data.subUrls.frontend.myAccount); | ||
| await this.toBeVisible(selector.customer.cMyAccount.menus.bookings); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Incorrect assertion in disableBookingModule - should verify menu is NOT visible.
On line 48, toBeVisible is called for selector.customer.cMyAccount.menus.bookings, but when disabling the booking module, the customer bookings menu should NOT be visible. This appears to be a copy-paste error from the enableBookingModule method.
🐛 Proposed fix
// customer dashboard menu
await this.goto(data.subUrls.frontend.myAccount);
- await this.toBeVisible(selector.customer.cMyAccount.menus.bookings);
+ await this.notToBeVisible(selector.customer.cMyAccount.menus.bookings);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // disable booking module | |
| async disableBookingModule() { | |
| // vendor dashboard menu | |
| await this.goto(data.subUrls.frontend.vDashboard.dashboard); | |
| await this.notToBeVisible(selector.vendor.vDashboard.menus.primary.booking); | |
| // vendor dashboard menu page | |
| await this.goto(data.subUrls.frontend.vDashboard.booking); | |
| await this.notToBeVisible(selector.vendor.vDashboard.dashboardDiv); | |
| // customer dashboard menu | |
| await this.goto(data.subUrls.frontend.myAccount); | |
| await this.toBeVisible(selector.customer.cMyAccount.menus.bookings); | |
| } | |
| // disable booking module | |
| async disableBookingModule() { | |
| // vendor dashboard menu | |
| await this.goto(data.subUrls.frontend.vDashboard.dashboard); | |
| await this.notToBeVisible(selector.vendor.vDashboard.menus.primary.booking); | |
| // vendor dashboard menu page | |
| await this.goto(data.subUrls.frontend.vDashboard.booking); | |
| await this.notToBeVisible(selector.vendor.vDashboard.dashboardDiv); | |
| // customer dashboard menu | |
| await this.goto(data.subUrls.frontend.myAccount); | |
| await this.notToBeVisible(selector.customer.cMyAccount.menus.bookings); | |
| } |
🤖 Prompt for AI Agents
In `@tests/pw/pages/vendorBookingPage.ts` around lines 36 - 49, In
disableBookingModule(), the final assertion incorrectly calls toBeVisible for
selector.customer.cMyAccount.menus.bookings; change this to assert the menu is
not visible by using the notToBeVisible helper for
selector.customer.cMyAccount.menus.bookings so the method consistently verifies
the booking menu is hidden when the booking module is disabled.
| // delete booking product | ||
| async duplicateBookingProduct(productName: string) { | ||
| await this.searchBookingProduct(productName); | ||
| await this.hover(bookingProductsVendor.productCell(productName)); | ||
| await this.clickAndWaitForResponseAndLoadState(data.subUrls.frontend.vDashboard.booking, bookingProductsVendor.duplicate(productName)); | ||
| await this.toContainText(bookingProductsVendor.dokanSuccessMessage, 'Product successfully duplicated'); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix incorrect comment: method is duplicateBookingProduct, not delete.
The comment on line 270 says "delete booking product" but the method actually duplicates the product.
📝 Proposed fix
- // delete booking product
+ // duplicate booking product
async duplicateBookingProduct(productName: string) {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // delete booking product | |
| async duplicateBookingProduct(productName: string) { | |
| await this.searchBookingProduct(productName); | |
| await this.hover(bookingProductsVendor.productCell(productName)); | |
| await this.clickAndWaitForResponseAndLoadState(data.subUrls.frontend.vDashboard.booking, bookingProductsVendor.duplicate(productName)); | |
| await this.toContainText(bookingProductsVendor.dokanSuccessMessage, 'Product successfully duplicated'); | |
| } | |
| // duplicate booking product | |
| async duplicateBookingProduct(productName: string) { | |
| await this.searchBookingProduct(productName); | |
| await this.hover(bookingProductsVendor.productCell(productName)); | |
| await this.clickAndWaitForResponseAndLoadState(data.subUrls.frontend.vDashboard.booking, bookingProductsVendor.duplicate(productName)); | |
| await this.toContainText(bookingProductsVendor.dokanSuccessMessage, 'Product successfully duplicated'); | |
| } |
🤖 Prompt for AI Agents
In `@tests/pw/pages/vendorBookingPage.ts` around lines 270 - 276, The leading
comment above the duplicateBookingProduct method is incorrect ("delete booking
product"); update or remove it so it correctly reflects the method's
behavior—e.g., change to "duplicate booking product" or delete the misleading
comment. Locate the comment immediately before the duplicateBookingProduct
function and adjust it to match the function name and behavior
(duplicateBookingProduct, bookingProductsVendor.duplicate, dokanSuccessMessage).
|
|
||
| // add booking resource | ||
| async editBookingResource(resource: bookingResource) { | ||
| await this.goIfNotThere(data.subUrls.frontend.vDashboard.manageResources); | ||
| await this.clickAndWaitForLoadState(bookingProductsVendor.manageResources.resource.editResource(resource.name)); | ||
|
|
||
| await this.clearAndType(bookingProductsVendor.manageResources.resource.resourceTitle, resource.name); | ||
| await this.clearAndType(bookingProductsVendor.manageResources.resource.availableQuantity, resource.quantity); | ||
| await this.clickAndWaitForResponseAndLoadState(data.subUrls.frontend.vDashboard.manageResources, bookingProductsVendor.manageResources.resource.saveResource); | ||
| await this.toContainText(selector.vendor.product.updatedSuccessMessage, 'Success! The Resource has been updated successfully.'); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix incorrect comment: method is editBookingResource, not add.
The comment on line 297 says "add booking resource" but the method edits an existing resource.
📝 Proposed fix
- // add booking resource
+ // edit booking resource
async editBookingResource(resource: bookingResource) {🤖 Prompt for AI Agents
In `@tests/pw/pages/vendorBookingPage.ts` around lines 296 - 306, The top-line
comment above the editBookingResource method is incorrect ("add booking
resource"); update or replace it to accurately describe the method (e.g., "edit
booking resource" or "update booking resource") so the comment matches the
function behavior in editBookingResource, ensuring it reflects that the method
navigates to manage resources and updates an existing resource.
| // add product shipping | ||
| async removeProductShipping(productName: string): Promise<void> { | ||
| await this.goToBookingProductEditById(productName); | ||
| await this.uncheck(productsVendor.shipping.requiresShipping); | ||
| await this.saveProduct(); | ||
| await this.notToBeChecked(productsVendor.shipping.requiresShipping); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix incorrect comment: method is removeProductShipping, not add.
📝 Proposed fix
- // add product shipping
+ // remove product shipping
async removeProductShipping(productName: string): Promise<void> {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // add product shipping | |
| async removeProductShipping(productName: string): Promise<void> { | |
| await this.goToBookingProductEditById(productName); | |
| await this.uncheck(productsVendor.shipping.requiresShipping); | |
| await this.saveProduct(); | |
| await this.notToBeChecked(productsVendor.shipping.requiresShipping); | |
| } | |
| // remove product shipping | |
| async removeProductShipping(productName: string): Promise<void> { | |
| await this.goToBookingProductEditById(productName); | |
| await this.uncheck(productsVendor.shipping.requiresShipping); | |
| await this.saveProduct(); | |
| await this.notToBeChecked(productsVendor.shipping.requiresShipping); | |
| } |
🤖 Prompt for AI Agents
In `@tests/pw/pages/vendorBookingPage.ts` around lines 736 - 742, The
top-of-function comment is incorrect: update the comment above the
removeProductShipping method to accurately describe its behavior (e.g., change
"add product shipping" to "remove product shipping" or a similar brief phrase).
Locate the removeProductShipping function and replace the misleading comment so
it matches the method name and actions (goToBookingProductEditById,
uncheck(productsVendor.shipping.requiresShipping), saveProduct, notToBeChecked).
Ensure no other comments around that block still say "add".
|
|
||
| // add product linked products | ||
| async removeProductLinkedProducts(productName: string, linkedProducts: product['productInfo']['linkedProducts'], choice: string): Promise<void> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix incorrect comment: method is removeProductLinkedProducts, not add.
📝 Proposed fix
- // add product linked products
+ // remove product linked products
async removeProductLinkedProducts(productName: string, linkedProducts: product['productInfo']['linkedProducts'], choice: string): Promise<void> {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // add product linked products | |
| async removeProductLinkedProducts(productName: string, linkedProducts: product['productInfo']['linkedProducts'], choice: string): Promise<void> { | |
| // remove product linked products | |
| async removeProductLinkedProducts(productName: string, linkedProducts: product['productInfo']['linkedProducts'], choice: string): Promise<void> { |
🤖 Prompt for AI Agents
In `@tests/pw/pages/vendorBookingPage.ts` around lines 950 - 952, The comment
above the method is incorrect—it's labeled "add product linked products" but the
method is removeProductLinkedProducts; update the comment to accurately describe
the method's purpose (e.g., "remove product linked products" or "remove linked
products for a product") to match the removeProductLinkedProducts(productName,
linkedProducts, choice) method signature and intent; ensure any surrounding
comments/docblocks referencing this method are similarly corrected for clarity.
- Revised the .env.example file to provide default admin credentials for Docker/wp-env setups, enhancing clarity for local configurations. - Introduced a new plugin, Force .htaccess Creation, to ensure the .htaccess file is created automatically for proper REST API functionality. - Added a command to flush rewrite rules after plugin activation in the e2e tests to ensure consistent permalink structure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@tests/pw/mu-plugins/force-htaccess.php`:
- Line 22: Remove the unused variable by deleting the assignment to $home_path
in the function that prepares the .htaccess file; the code writes to
$htaccess_file (using ABSPATH) so keep $htaccess_file and any logic that uses
ABSPATH and remove the lone $home_path = get_home_path() statement to avoid an
unused variable.
In `@tests/pw/utils/testData.ts`:
- Line 2913: Replace the invalid plugin slug 'master' used for basicAuth with
the actual cloned plugin path so activation succeeds: locate the basicAuth value
(used by data.commands.wpcli.activatePlugin and set in
tests/pw/utils/testData.ts) and change it from 'master' to the correct plugin
path matching the cloneBasicAuth command and pluginList entry (e.g.,
'Basic-Auth-master/basic-auth') so the call
data.commands.wpcli.activatePlugin(data.installWp.plugins.basicAuth) runs
against the real plugin slug.
- Around line 2110-2119: Update the module stats in tests/pw/utils/testData.ts
so they reflect the actual 38 modules and correct category breakdown: change
totalModules from 42 to 38 and adjust each category count (modulesVideoLink,
productManagement, integration, uiUx, shipping, storeManagement, payment,
orderManagement, vendorManagement) to match the categorization of the 38-module
list shown later in the file (lines referenced in the review); this will align
the test data with the assertions in modulesPage.ts (toHaveCount checks around
lines 40-57) and prevent count mismatches.
- Line 1201: productDetails currently hardcodes the category segment as
"uncategorized" which breaks navigation if a product is moved; update the
productDetails helper to accept an optional categorySlug parameter (e.g.,
productDetails(productName: string, categorySlug = 'uncategorized')) or accept a
product object and derive its primary category, and update all call sites to
pass the real category where appropriate (or document and restrict use to
uncategorized-only tests); reference the productDetails function in
tests/pw/utils/testData.ts and ensure callers that create or reassign products
(e.g., tests that use clothings or CATEGORY_ID) are updated to pass the correct
category slug.
| editAccountCustomer: 'my-account/edit-account', | ||
| becomeVendor: 'my-account/account-migration', | ||
| productDetails: (productName: string) => `product/${productName}`, | ||
| productDetails: (productName: string) => `shop/uncategorized/${productName}`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for productDetails usage and check if any tests use non-uncategorized products
rg -n "productDetails" tests/pw --type ts -C 2
# Check for products created with specific categories
rg -n "category:" tests/pw/utils/testData.ts | head -20Repository: getdokan/dokan
Length of output: 23552
🏁 Script executed:
#!/bin/bash
# Search for any product URL patterns to understand how WooCommerce structures them
rg -n "shop\/" tests/pw --type ts | head -20
# Look for any URL expectations or assertions about product paths
rg -n "toHaveURL" tests/pw --type ts -A 1 | head -20
# Search for any tests that check product URLs
rg -n "product/" tests/pw --type ts | head -20
# Check if there are products with specific categories being tested
rg -n "CATEGORY_ID" tests/pw/utils/testData.ts -B 5 -A 5
# Look for any product URL construction with categories
rg -n "product.*category" tests/pw --type ts -iRepository: getdokan/dokan
Length of output: 32259
🏁 Script executed:
#!/bin/bash
# Look for the old product URL pattern to understand what changed
rg -n "product/" tests/pw/utils/testData.ts -B 2 -A 2
# Check if there are any test failures or comments about URL patterns
rg -n "shop/.*productName" tests/pw --type ts
# Look for how products are categorized in actual test scenarios
rg -n "clothings" tests/pw/tests/e2e --type ts -B 2 -A 2
# Search for any reference to category URL slugs
rg -n "product.*slug|slug.*product" tests/pw --type ts -i | head -15
# Check if productDetails is used with any products that have specific categories
rg -n "goToProductDetails\|productDetails(" tests/pw/tests/e2e --type ts -B 1 -A 1 | head -30Repository: getdokan/dokan
Length of output: 5255
🏁 Script executed:
#!/bin/bash
# Check if there's any URL structure info about categories in the codebase
fd -e ts -e js | xargs grep -l "shop.*category\|category.*slug" | head -10
# Look for the actual product page implementation or test that navigates to products
rg -n "expect.*toHaveURL.*productDetails" tests/pw --type ts -A 2 -B 2
# Check the stripeExpressPage reference which uses /product/ directly
rg -n "stripeExpressPage\|/product/" tests/pw/pages --type ts -B 2 -A 2 | head -40
# Search for any tests that verify product URLs work correctly
rg -n "product.*page.*url\|navigate.*product" tests/pw/tests/e2e --type ts -i | head -20
# Look for any test that might verify products in different categories
rg -n "clothings.*product\|productDetails" tests/pw/tests/e2e/productsDetails.spec.ts -B 2 -A 2Repository: getdokan/dokan
Length of output: 798
🏁 Script executed:
#!/bin/bash
# Check git history to see when this URL pattern changed
git log --oneline --all -- tests/pw/utils/testData.ts | head -20
# Look for any hardcoded product URLs in tests
rg -n "shop/uncategorized\|/shop/" tests/pw --type ts
# Check if there are tests that specifically test products in clothings category
rg -n "clothings" tests/pw/tests/e2e --type ts -B 3 -A 3 | head -50
# Look for the product category structure in actual test execution
rg -n "category.*clothings\|clothings.*product" tests/pw/utils/testData.ts -B 2 -A 2Repository: getdokan/dokan
Length of output: 4756
🏁 Script executed:
#!/bin/bash
# Check if there are any tests that navigate to products after changing their category
rg -n "addProductCategory.*productDetails\|productDetails.*after.*category" tests/pw/tests/e2e --type ts -i
# Look at the complete productsDetails.spec.ts test to understand the flow
head -200 tests/pw/tests/e2e/productsDetails.spec.ts | tail -100
# Check if products created with clothings category are later navigated to
rg -n "goToProductDetails\|productDetails\(" tests/pw/tests/e2e/productsDetails.spec.ts -B 5 -A 5
# Look for WooCommerce product URL structure - check if there's any documentation in comments
rg -n "uncategorized\|shop.*category" tests/pw --type ts -i | grep -i commentRepository: getdokan/dokan
Length of output: 5674
🏁 Script executed:
#!/bin/bash
# Check the git diff to see what changed in the productDetails URL
git log -p --all -- tests/pw/utils/testData.ts | grep -A 10 -B 10 "productDetails.*uncategorized" | head -50
# Search for any old URL patterns that might have been replaced
git log -p --all -- tests/pw/utils/testData.ts | grep -A 5 -B 5 "productDetails.*product" | head -50
# Check if there are comments in the test files about this URL structure
rg -n "uncategorized\|shop.*product" tests/pw/tests/e2e --type ts | grep -i "test\|comment\|describe" | head -20
# Look for any configuration or setup that affects product URLs
rg -n "permalink\|slug\|rewrite" tests/pw/utils --type ts | head -20Repository: getdokan/dokan
Length of output: 40
🏁 Script executed:
#!/bin/bash
# Check if productDetails is used after products are assigned to non-uncategorized categories
rg -n "clothings\|CATEGORY_ID" tests/pw/tests/e2e --type ts -A 10 | grep -E "productDetails|goToProductDetails|vendor\." | head -30
# Check what the actual WooCommerce product URL structure should be by looking at test setup
rg -n "product.*name\|productName.*slug" tests/pw/pages/productsPage.ts | head -20
# Look for any product navigation after category assignment
rg -n "addProductCategory\|removeProductCategory" tests/pw/tests/e2e --type ts -A 15 | head -50
# Check if there's any mention of how product permalinks work in shop context
rg -n "shop\|product.*permalink" tests/pw/utils/testData.ts -i | head -20
# Try to understand the current URL structure by looking for toHaveURL assertions
rg -n "toHaveURL.*productDetails" tests/pw --type ts -B 2 -A 2Repository: getdokan/dokan
Length of output: 767
🏁 Script executed:
#!/bin/bash
# Look at the actual productsPage.ts test to see the context of the toHaveURL assertion
sed -n '760,790p' tests/pw/pages/productsPage.ts
# Check what happens after addProductCategory - are products navigated to?
rg -n "addProductCategory" tests/pw/tests/e2e/productsDetails.spec.ts -A 5
# Look for any actual test failures or known issues related to URLs
rg -n "FIXME|TODO|BUG|SKIP|xfail" tests/pw/tests/e2e/productsDetails.spec.ts | head -10
# Check if there are products being created with specific categories and then navigated to
rg -n "createProduct.*categories.*clothings\|CATEGORY_ID" tests/pw/tests/e2e --type ts -A 10 | grep -E "goToProductDetails|productDetails|vendor\." | head -40
# Look for the actual product slug/URL construction logic
rg -n "slugify\|slug.*product" tests/pw/utils --type ts -B 2 -A 2 | head -30Repository: getdokan/dokan
Length of output: 3535
🏁 Script executed:
#!/bin/bash
# Check if productIdFull or productIdBasic are later navigated to after category change
rg -n "productIdFull\|productIdBasic" tests/pw/tests/e2e/productsDetails.spec.ts -B 5 -A 15 | grep -E "viewProduct|goToProductDetails|productDetails|addProductCategory" | head -40
# Check if there are any skipped or failing tests related to product category navigation
rg -n "skip\|todo\|xfail\|test.only" tests/pw/tests/e2e/productsDetails.spec.ts -i
# Look for the complete test setup - where productIdFull is created
head -50 tests/pw/tests/e2e/productsDetails.spec.ts
# Check if WooCommerce uses category slugs in product URLs
rg -n "shop.*clothings\|clothings.*product" tests/pw --type ts -i
# Search for any reference to how products are accessed by URL in the codebase
rg -n "product.*URL\|URL.*product\|href.*product" tests/pw --type ts -i | head -20Repository: getdokan/dokan
Length of output: 2294
🏁 Script executed:
#!/bin/bash
# Check if there are tests that navigate to products AFTER changing their category
rg -n "addProductCategory\|removeProductCategory" tests/pw/tests/e2e/productsDetails.spec.ts -A 20 | grep -E "viewProduct|goToProductDetails|productDetails\(" | head -20
# Look for the shop page setup to understand the URL structure
rg -n "shop\|permalink" tests/pw/utils/testData.ts -B 3 -A 3 | head -40
# Check if there's any comment or documentation about WooCommerce URL structure
rg -n "woocommerce\|product.*url\|url.*structure" tests/pw --type ts -i | grep -i "comment\|todo\|note" | head -10
# Look for how the frontend base URL is set up
rg -n "subUrls.*frontend\|frontend.*subUrls" tests/pw/utils/testData.ts -B 2 -A 10 | head -50
# Check what other subUrls are defined to understand the URL pattern
rg -n "frontend:" tests/pw/utils/testData.ts -A 30 | head -50Repository: getdokan/dokan
Length of output: 1551
🏁 Script executed:
#!/bin/bash
# Get the complete frontend subUrls section
sed -n '1161,1220p' tests/pw/utils/testData.ts
# Check if there are any other products being navigated to after category assignment
rg -n "viewProduct\|goToProductDetails" tests/pw/tests/e2e/productsDetails.spec.ts -B 5 -A 5
# Search for any known issues or comments about product category URLs
git log --all --oneline --grep="uncategorized\|category\|product.*url" | head -20
# Check the actual store setup to see what URL structure is configured
rg -n "shop\|category" tests/pw/utils/dbData.ts | head -30Repository: getdokan/dokan
Length of output: 4768
🏁 Script executed:
#!/bin/bash
# Look for evidence that product URLs change based on category assignment
# Check if there are any tests that fail or skip because of category URL changes
rg -n "test.*skip\|skip.*category\|category.*skip\|xfail" tests/pw/tests/e2e/productsDetails.spec.ts -i
# Check if products in the test data with specific categories have different expected URLs
rg -n "createProduct\|createAuctionProduct" tests/pw/utils/payloads.ts -A 15 | head -40
# Look for any test that creates a product with clothings category and verifies its URL
rg -n "clothings.*product\|product.*clothings" tests/pw/tests/e2e --type ts -B 3 -A 10 | head -50
# Check if the toHaveURL assertion uses dynamic category slugs anywhere
rg -n "toHaveURL.*shop.*productDetails" tests/pw --type ts
# Look for any recent changes or commits that might explain the hardcoded uncategorized
git log --oneline --all -- tests/pw/utils/testData.ts | grep -i "category\|uncategorized\|product.*url" | head -10Repository: getdokan/dokan
Length of output: 40
🏁 Script executed:
#!/bin/bash
# Let me check if there's a way products get their category slug in the URL
# First, see if there's any code that dynamically builds product URLs based on category
rg -n "product.*category.*url\|url.*category.*product\|shop.*category.*slug" tests/pw --type ts -i
# Check what happens when we navigate to a product - does it redirect?
rg -n "navigation\|redirect\|waitForURL" tests/pw/pages/productsPage.ts | head -20
# Look at the actual test to see if viewProduct is called and passes
rg -n "viewProduct" tests/pw/tests/e2e/productsDetails.spec.ts -B 2 -A 2
# Check if any test actually navigates to a product in clothings category
rg -n "clothings\|CATEGORY_ID" tests/pw/tests/e2e/productsDetails.spec.ts -A 20 | grep -i "product\|navigate\|view" | head -20
# Search for how product URLs are constructed in WooCommerce context
rg -n "product.*slug\|slug.*product" tests/pw/pages --type ts -B 2 -A 2 | head -30Repository: getdokan/dokan
Length of output: 40
🏁 Script executed:
#!/bin/bash
# Final check: Look for any test failures or error logs mentioning product URL issues
rg -n "404\|not.*found\|product.*not.*found\|url.*mismatch" tests/pw/tests --type ts -i
# Check if there are any environment-specific configurations for product URLs
rg -n "production\|staging\|development\|DOKAN_PRO" tests/pw/utils/testData.ts | head -20
# Look for any test that might be skipped due to URL issues
grep -r "skip\|todo\|xfail\|pending" tests/pw/tests/e2e/*.spec.ts | grep -i "category\|product\|url" | head -20
# Check the actual WordPress/WooCommerce URL structure being used
rg -n "wp-json\|rest.*api\|wc-api" tests/pw/utils/apiEndPoints.ts | head -10
# See if there's a test that verifies the product actually exists at the uncategorized URL
rg -n "200\|success\|found\|exists" tests/pw/tests/e2e/productsDetails.spec.ts
# Check if the shop uses a custom product base or category base
rg -n "product.*base\|category.*base\|rewrite.*rule" tests/pw/utils --type ts -iRepository: getdokan/dokan
Length of output: 2983
🏁 Script executed:
#!/bin/bash
# Let me check if there are any actual navigation tests after product category changes
# Look at the complete test flow for category changes
sed -n '114,145p' tests/pw/tests/e2e/productsDetails.spec.ts
# Check if products assigned to other categories are actually navigated to in other test files
rg -n "addProductCategory\|removeProductCategory" tests/pw/tests/e2e --type ts -A 30 | grep -E "goToProductDetails|productDetails\(|viewProduct"
# Check if the hardcoded uncategorized path works for products in any category (WooCommerce default behavior)
rg -n "product.*accessible\|accessible.*product\|canonical.*url" tests/pw --type ts -i
# Look for the stripeExpressPage which uses /product/ directly - see if that's a different URL structure
sed -n '215,225p' tests/pw/pages/stripeExpressPage.ts
# Check if there are any comments explaining why uncategorized is used
rg -n "uncategorized" tests/pw/utils/testData.ts -B 5 -A 5Repository: getdokan/dokan
Length of output: 3919
Consider using dynamic category slug in productDetails URL or verify all navigations use uncategorized path.
The productDetails URL at line 1201 hardcodes shop/uncategorized/${productName}, which assumes all test products are accessible via the uncategorized category. While most test data uses uncategorized products, tests do create and modify products in other categories (e.g., clothings, CATEGORY_ID). If navigation tests are later added that access products after category reassignment, this path would fail. Either make the URL dynamic based on the product's primary category, or document that this URL is only valid for uncategorized products and ensure tests don't navigate to recategorized products using this function.
🤖 Prompt for AI Agents
In `@tests/pw/utils/testData.ts` at line 1201, productDetails currently hardcodes
the category segment as "uncategorized" which breaks navigation if a product is
moved; update the productDetails helper to accept an optional categorySlug
parameter (e.g., productDetails(productName: string, categorySlug =
'uncategorized')) or accept a product object and derive its primary category,
and update all call sites to pass the real category where appropriate (or
document and restrict use to uncategorized-only tests); reference the
productDetails function in tests/pw/utils/testData.ts and ensure callers that
create or reassign products (e.g., tests that use clothings or CATEGORY_ID) are
updated to pass the correct category slug.
| totalModules: 42, | ||
| modulesVideoLink: 19, | ||
| productManagement: 15, | ||
| integration: 6, | ||
| uiUx: 2, | ||
| shipping: 3, | ||
| storeManagement: 10, | ||
| payment: 6, | ||
| storeManagement: 11, | ||
| payment: 7, | ||
| orderManagement: 2, | ||
| vendorManagement: 1, | ||
| vendorManagement: 2, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# First, run the provided script to find moduleStats usage
rg -n "moduleStats" tests/pw --type ts -C 3Repository: getdokan/dokan
Length of output: 4479
🏁 Script executed:
#!/bin/bash
# Check the specific file to see the full context of these module stats
cat -n tests/pw/utils/testData.ts | sed -n '2100,2130p'Repository: getdokan/dokan
Length of output: 1097
🏁 Script executed:
#!/bin/bash
# Search for assertions or tests that use these module counts
rg -n "totalModules.*42|storeManagement.*11|payment.*7|vendorManagement.*2" tests/pw --type ts -C 2Repository: getdokan/dokan
Length of output: 2479
🏁 Script executed:
#!/bin/bash
# Check for any comments or documentation about module counts
rg -n "module|dokan" tests/pw/utils/testData.ts -i -C 5 | head -100Repository: getdokan/dokan
Length of output: 5284
🏁 Script executed:
#!/bin/bash
# Look for any README or documentation about modules
fd -i "readme|doc" tests/pw -x cat {} \; 2>/dev/null | head -200Repository: getdokan/dokan
Length of output: 4386
🏁 Script executed:
#!/bin/bash
# Check the full modules list in testData to understand the actual module count
cat -n tests/pw/utils/testData.ts | sed -n '2122,2180p'Repository: getdokan/dokan
Length of output: 2248
🏁 Script executed:
#!/bin/bash
# Search for any comments about Dokan Pro modules
rg -i "dokan.*pro.*module|module.*dokan" tests/pw --type ts | head -20Repository: getdokan/dokan
Length of output: 2128
🏁 Script executed:
#!/bin/bash
# Count the actual modules in the list
cat -n tests/pw/utils/testData.ts | sed -n '2122,2161p' | grep -oP "'\K[^']+(?=')" | wc -lRepository: getdokan/dokan
Length of output: 60
🏁 Script executed:
#!/bin/bash
# Get the complete module list to verify count
cat -n tests/pw/utils/testData.ts | sed -n '2122,2161p' | grep -oP "'\K[^']+(?=')"Repository: getdokan/dokan
Length of output: 544
🏁 Script executed:
#!/bin/bash
# Search for any test that verifies or lists Dokan Pro modules
rg -i "dokan.*module|module.*count" tests/pw --type ts -C 2 | head -60Repository: getdokan/dokan
Length of output: 4295
Update module stats counts to match the actual module list.
The test data contains incorrect module counts. There are 38 actual modules in the list, but totalModules is set to 42, and category counts sum to 48. The assertions in modulesPage.ts:40-57 use these counts with toHaveCount(), so mismatched values will cause test failures. Update the stats to reflect:
- totalModules: 38 (not 42)
- Category counts to match the actual categorization of the 38 modules listed at lines 2122-2161
🤖 Prompt for AI Agents
In `@tests/pw/utils/testData.ts` around lines 2110 - 2119, Update the module stats
in tests/pw/utils/testData.ts so they reflect the actual 38 modules and correct
category breakdown: change totalModules from 42 to 38 and adjust each category
count (modulesVideoLink, productManagement, integration, uiUx, shipping,
storeManagement, payment, orderManagement, vendorManagement) to match the
categorization of the 38-module list shown later in the file (lines referenced
in the review); this will align the test data with the assertions in
modulesPage.ts (toHaveCount checks around lines 40-57) and prevent count
mismatches.
| // plugins | ||
| plugins: { | ||
| basicAuth: 'Basic-Auth', | ||
| basicAuth: 'master', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, let's check the file size and read around line 2913
wc -l tests/pw/utils/testData.tsRepository: getdokan/dokan
Length of output: 89
🏁 Script executed:
# Read the specific section around line 2913
sed -n '2910,2920p' tests/pw/utils/testData.tsRepository: getdokan/dokan
Length of output: 461
🏁 Script executed:
# Check how basicAuth is used in activation commands
rg -n "plugins\.basicAuth" tests/pw --type ts -C 2Repository: getdokan/dokan
Length of output: 1191
🏁 Script executed:
# Check the plugin list for the expected format around the basicAuth definition
rg -n "basicAuth" tests/pw/utils/testData.ts -C 3Repository: getdokan/dokan
Length of output: 1467
🏁 Script executed:
# Also check the clone command mentioned at line 2947
sed -n '2945,2955p' tests/pw/utils/testData.tsRepository: getdokan/dokan
Length of output: 934
Fix invalid plugin slug: replace 'master' with the correct Basic-Auth plugin path.
The basicAuth value is used in plugin activation at line 2913. When data.commands.wpcli.activatePlugin(data.installWp.plugins.basicAuth) executes, passing 'master' generates wp plugin activate master, which fails because it's not a valid WordPress plugin identifier.
The cloneBasicAuth command clones the plugin from GitHub into a Basic-Auth directory. The correct plugin slug should match the cloned directory structure. Based on pluginList at line 170, which correctly defines it as 'Basic-Auth-master/basic-auth', update line 2913 to use the proper plugin path instead of 'master'.
🤖 Prompt for AI Agents
In `@tests/pw/utils/testData.ts` at line 2913, Replace the invalid plugin slug
'master' used for basicAuth with the actual cloned plugin path so activation
succeeds: locate the basicAuth value (used by data.commands.wpcli.activatePlugin
and set in tests/pw/utils/testData.ts) and change it from 'master' to the
correct plugin path matching the cloneBasicAuth command and pluginList entry
(e.g., 'Basic-Auth-master/basic-auth') so the call
data.commands.wpcli.activatePlugin(data.installWp.plugins.basicAuth) runs
against the real plugin slug.
- Changed WP_DEBUG_DISPLAY setting to false in .wp-env.json for improved error handling during testing. - Added a check in the force-htaccess.php plugin to skip execution when running in WP-CLI, preventing unnecessary operations in command line environments.
- Enhanced the README.md to provide a clearer overview of testing practices, including PHPUnit and Playwright tests. - Added detailed sections for E2E and API tests, including setup instructions and features. - Removed outdated `e2eReadme.md` and `SETUP-GUIDE.md` files to streamline documentation. - Updated `.gitignore` to include the `.env` file for better security practices. - Improved organization of the tests directory documentation for easier navigation and understanding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@tests/pw/README.MD`:
- Around line 470-471: tests/pw/README.MD contains broken links to DEPLOYMENT.md
and CHANGELOG.md; fix by either (A) creating a DEPLOYMENT.md at the repo root
and updating the links in tests/pw/README.MD to point to ../../DEPLOYMENT.md and
../../CHANGELOG.md, or (B) if no deployment doc is needed, remove or replace the
DEPLOYMENT.md entry and change the existing CHANGELOG link to ../../CHANGELOG.md
so it correctly references the repository root; update the links in
tests/pw/README.MD accordingly.
🧹 Nitpick comments (1)
tests/pw/README.MD (1)
235-235: Optional: Specify language for fenced code block.The code block at line 235 (project structure) lacks a language identifier. While it's formatted as a directory tree, adding a language identifier improves rendering consistency.
📝 Suggested improvement
-``` +```text tests/pw/ ├── tests/ ...
- Added package-lock.json to .gitignore to prevent tracking of dependency changes. - Deleted the package-lock.json file to streamline the project and avoid potential conflicts with dependency management.
Remove links to non-existent DEPLOYMENT.md and CHANGELOG.md files from the test README to resolve broken references.
# Conflicts: # package-lock.json
Eliminated the line attributing the project to the Dokan Team in the README.md file to streamline the documentation.
…ress E2E tests - Set WP_DEBUG, SCRIPT_DEBUG, and WP_DEBUG_LOG to false in .wp-env.json for a cleaner testing environment. - Introduced new E2E tests for Stripe Express functionality, including admin and vendor interactions, in stripeExpress.spec.ts. - Created stripeExpressPage.ts to encapsulate page interactions and locators for Stripe Express tests.
- Added NO_SETUP=false to the .env.example file to clarify Docker setup requirements while maintaining CI=true for consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@tests/pw/.wp-env.json`:
- Around line 7-8: composer.json currently pins the Composer platform PHP
version to 7.4; update the "platform" -> "php" constraint to match the test
environment by changing it to 8.2 (so Composer resolves deps for PHP 8.2). In
.wp-env.json, replace the Basic-Auth plugin URL that ends with master.zip with a
URL that points to a specific tagged release (a `refs/tags/vX.Y.Z.zip` tag)
instead of master to ensure reproducible tests; leave the WooCommerce
"latest-stable" entry as-is.
In `@tests/pw/tests/e2e/stripe-express/stripeExpress.spec.ts`:
- Around line 22-23: The test suite is running in parallel and mutates shared DB
state; replace the current test.describe call with a serialized describe so
tests run sequentially (e.g., change test.describe('Stripe Express Tests', ...)
to test.describe.serial('Stripe Express Tests', ...) or call
test.describe.configure({ mode: 'serial' }) before the suite) to prevent
shared-state race conditions in the admin/vendor/customer flows.
🧹 Nitpick comments (2)
tests/pw/README.MD (2)
233-250: Add a language identifier to the fenced code block.The “Project Structure” block is missing a language tag, which violates MD040.
✅ Suggested fix
-``` +```text tests/pw/ ├── tests/ │ ├── e2e/ # E2E test specifications @@ └── package.json # Dependencies & scripts -``` +```
300-302: Avoid bare URLs in tables.Markdownlint flags these as bare URLs; consider wrapping them in Markdown links.
✅ Suggested fix
-| WordPress Site | http://localhost:9999 | - | -| WP Admin | http://localhost:9999/wp-admin | From `.env` | -| Dokan Dashboard | http://localhost:9999/dashboard | Vendor users | +| WordPress Site | [http://localhost:9999](http://localhost:9999) | - | +| WP Admin | [http://localhost:9999/wp-admin](http://localhost:9999/wp-admin) | From `.env` | +| Dokan Dashboard | [http://localhost:9999/dashboard](http://localhost:9999/dashboard) | Vendor users |
| "phpVersion": "8.2", | ||
| "plugins": ["https://github.com/WP-API/Basic-Auth/archive/master.zip", "https://downloads.wordpress.org/plugin/woocommerce.latest-stable.zip" ], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check for composer.json and PHP version requirements
fd -g 'composer.json' -x cat {} \; 2>/dev/null | head -100Repository: getdokan/dokan
Length of output: 2645
🏁 Script executed:
#!/bin/bash
# Search for PHP version requirements in README and docs
rg -i "php.*version|requires.*php|minimum.*php" --type markdown --type txt 2>/dev/null | head -20Repository: getdokan/dokan
Length of output: 735
🏁 Script executed:
#!/bin/bash
# Check package.json or other configuration files for environment setup details
fd -g 'package.json' -x cat {} \; 2>/dev/null | head -100Repository: getdokan/dokan
Length of output: 6885
🏁 Script executed:
#!/bin/bash
# Look for any test configuration or CI/CD files that might specify PHP version
fd -g '.github' -type f 2>/dev/null && \
fd -E 'node_modules' -g '*.yml' -g '*.yaml' -g '.wp-env.json' | head -20Repository: getdokan/dokan
Length of output: 40
🏁 Script executed:
#!/bin/bash
# Check the actual wp-env.json file to understand full context
cat tests/pw/.wp-env.json 2>/dev/null || echo "File not found at tests/pw/.wp-env.json"Repository: getdokan/dokan
Length of output: 1028
Update composer.json platform constraint and pin Basic-Auth to a stable release.
The codebase already supports PHP 8.2 (per CHANGELOG), but composer.json has its platform constraint set to 7.4 while .wp-env.json uses 8.2. Update the platform constraint in composer.json to match the test environment.
Additionally, while WooCommerce correctly uses latest-stable, the Basic-Auth plugin pulls from master.zip, which retrieves unstable code. Use a tagged release instead for reproducible test environments.
🤖 Prompt for AI Agents
In `@tests/pw/.wp-env.json` around lines 7 - 8, composer.json currently pins the
Composer platform PHP version to 7.4; update the "platform" -> "php" constraint
to match the test environment by changing it to 8.2 (so Composer resolves deps
for PHP 8.2). In .wp-env.json, replace the Basic-Auth plugin URL that ends with
master.zip with a URL that points to a specific tagged release (a
`refs/tags/vX.Y.Z.zip` tag) instead of master to ensure reproducible tests;
leave the WooCommerce "latest-stable" entry as-is.
| test.describe('Stripe Express Tests', () => { | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, let's locate and examine the test file
find . -type f -name "stripeExpress.spec.ts" 2>/dev/null | head -20Repository: getdokan/dokan
Length of output: 115
🏁 Script executed:
# Read the test file to understand its structure
cat -n tests/pw/tests/e2e/stripe-express/stripeExpress.spec.ts | head -100Repository: getdokan/dokan
Length of output: 3817
🏁 Script executed:
# Check if there are global variables or shared state patterns
cat -n tests/pw/tests/e2e/stripe-express/stripeExpress.spec.ts | tail -n +1Repository: getdokan/dokan
Length of output: 3817
🏁 Script executed:
# Search for admin module, toggles, and state mutations in this directory
rg -i "admin|toggle|vendor|customer|mutate|shared" tests/pw/tests/e2e/stripe-express/ -A 2 -B 2Repository: getdokan/dokan
Length of output: 16487
🏁 Script executed:
# Check if there are other similar test suites with potential shared-state issues
find tests/pw/tests/e2e -name "*.spec.ts" -type f | xargs grep -l "test.describe" | head -10Repository: getdokan/dokan
Length of output: 431
🏁 Script executed:
# Check if any other test files already use .serial() for describe blocks
rg "test\.describe\.serial" tests/pw/tests/e2e/ --type tsRepository: getdokan/dokan
Length of output: 40
Serialize this test suite to prevent shared-state race conditions.
The admin module toggling and vendor/customer workflows create execution dependencies and mutate shared database state. Parallel execution will cause flaky results when tests interleave (e.g., admin deactivation running during vendor operations, or product state races).
Suggested change
-test.describe('Stripe Express Tests', () => {
+test.describe.serial('Stripe Express Tests', () => {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| test.describe('Stripe Express Tests', () => { | |
| test.describe.serial('Stripe Express Tests', () => { |
🤖 Prompt for AI Agents
In `@tests/pw/tests/e2e/stripe-express/stripeExpress.spec.ts` around lines 22 -
23, The test suite is running in parallel and mutates shared DB state; replace
the current test.describe call with a serialized describe so tests run
sequentially (e.g., change test.describe('Stripe Express Tests', ...) to
test.describe.serial('Stripe Express Tests', ...) or call
test.describe.configure({ mode: 'serial' }) before the suite) to prevent
shared-state race conditions in the admin/vendor/customer flows.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@tests/pw/.env.example`:
- Line 24: The NO_SETUP setting in the .env example is inconsistent: the comment
says "MUST be true for Docker" while the value is NO_SETUP=false; decide which
is correct for the Docker flow and make them consistent—either set NO_SETUP=true
when the Docker setup requires skipping tests/initial setup (update the value of
NO_SETUP to true) or update the comment to reflect that NO_SETUP=false is
required for Docker; ensure the change is applied to the NO_SETUP entry so the
example and comment match.
- Around line 1-6: Replace the weak default ADMIN_PASSWORD value and strengthen
the comment: remove the explicit "password" literal, set ADMIN_PASSWORD to an
empty placeholder (or a note like "<GENERATE_STRONG_PASSWORD>"), and update the
surrounding comment to clearly warn that these values are for local
Docker/wp-env only and must not be used in staging/production—reference the
ADMIN, ADMIN_PASSWORD and ADMIN_EMAIL variables so reviewers can find and update
the example accordingly.
| # Admin Configuration (wp-env default admin credentials) | ||
| # For Docker/wp-env, use: admin / password / [email protected] | ||
| # For local setup, replace with your admin credentials | ||
| ADMIN=admin | ||
| ADMIN_PASSWORD=password | ||
| [email protected] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strengthen security warnings for weak admin credentials.
Similar to the database credentials concern flagged in the previous review, ADMIN_PASSWORD=password is a weak default. While appropriate for local Docker/wp-env testing, if someone copies this configuration to a non-local environment, it creates a security risk.
📝 Suggested improvement
# Admin Configuration (wp-env default admin credentials)
-# For Docker/wp-env, use: admin / password / [email protected]
-# For local setup, replace with your admin credentials
+# WARNING: These credentials are for LOCAL TESTING ONLY. Never use in production!
+# For Docker/wp-env: admin / password / [email protected]
+# For other setups: replace with secure credentials
ADMIN=admin
-ADMIN_PASSWORD=password
+ADMIN_PASSWORD=password # INSECURE: Only for local Docker testing
[email protected]📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Admin Configuration (wp-env default admin credentials) | |
| # For Docker/wp-env, use: admin / password / [email protected] | |
| # For local setup, replace with your admin credentials | |
| ADMIN=admin | |
| ADMIN_PASSWORD=password | |
| [email protected] | |
| # Admin Configuration (wp-env default admin credentials) | |
| # WARNING: These credentials are for LOCAL TESTING ONLY. Never use in production! | |
| # For Docker/wp-env: admin / password / [email protected] | |
| # For other setups: replace with secure credentials | |
| ADMIN=admin | |
| ADMIN_PASSWORD=password # INSECURE: Only for local Docker testing | |
| [email protected] |
🧰 Tools
🪛 dotenv-linter (4.0.0)
[warning] 6-6: [UnorderedKey] The ADMIN_EMAIL key should go before the ADMIN_PASSWORD key
(UnorderedKey)
🤖 Prompt for AI Agents
In `@tests/pw/.env.example` around lines 1 - 6, Replace the weak default
ADMIN_PASSWORD value and strengthen the comment: remove the explicit "password"
literal, set ADMIN_PASSWORD to an empty placeholder (or a note like
"<GENERATE_STRONG_PASSWORD>"), and update the surrounding comment to clearly
warn that these values are for local Docker/wp-env only and must not be used in
staging/production—reference the ADMIN, ADMIN_PASSWORD and ADMIN_EMAIL variables
so reviewers can find and update the example accordingly.
| BASE_URL=http://localhost:9999 | ||
| HEADLESS=false | ||
| CI=true | ||
| NO_SETUP=false # MUST be true for Docker |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix contradictory comment and value for NO_SETUP.
The comment states "MUST be true for Docker" but the value is set to false. The commit message indicates NO_SETUP=false was intentionally added for Docker configuration. This contradiction will confuse users about the correct setting.
Please clarify:
- Should
NO_SETUP=truefor Docker (comment is correct, value is wrong)? - Should
NO_SETUP=falsefor Docker (value is correct, comment is wrong)?
💡 Suggested fix if value is correct
-NO_SETUP=false # MUST be true for Docker
+NO_SETUP=false # Set to false for Docker wp-env setup📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| NO_SETUP=false # MUST be true for Docker | |
| NO_SETUP=false # Set to false for Docker wp-env setup |
🧰 Tools
🪛 dotenv-linter (4.0.0)
[warning] 24-24: [ValueWithoutQuotes] This value needs to be surrounded in quotes
(ValueWithoutQuotes)
🤖 Prompt for AI Agents
In `@tests/pw/.env.example` at line 24, The NO_SETUP setting in the .env example
is inconsistent: the comment says "MUST be true for Docker" while the value is
NO_SETUP=false; decide which is correct for the Docker flow and make them
consistent—either set NO_SETUP=true when the Docker setup requires skipping
tests/initial setup (update the value of NO_SETUP to true) or update the comment
to reflect that NO_SETUP=false is required for Docker; ensure the change is
applied to the NO_SETUP entry so the example and comment match.
- Updated stripeExpress.spec.ts to improve test organization and added new test cases for verifying Stripe Express functionality. - Refactored stripeExpressPage.ts to streamline page interactions and selectors, enhancing maintainability and readability. - Introduced session storage variables for better context management during tests. - Improved navigation and assertion methods for admin and vendor interactions with Stripe Express.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@tests/pw/tests/e2e/stripe-express/stripeExpressPage.ts`:
- Around line 15-31: The admin/vendor objects hardcode base URLs and transient
query params (stripeExpressSettingsUrl, stripeExpressOnboardingUrl, seller_id=3,
_wpnonce) causing environment brittleness; change these to store only path
fragments (e.g., stripeExpressSettingsPath, stripeExpressOnboardingPath) and
read the base URL and dynamic params (sellerId, wpNonce) from environment/config
at runtime, then update navigation helpers (e.g., goToStripeExpressSettings, any
method using visitExpressDashboardButton) to construct full URLs via
`${this.baseUrl}${this.admin.stripeExpressSettingsPath}` or by appending
`?seller_id=${this.config.sellerId}&_wpnonce=${this.auth.wpNonce}` (or retrieve
a fresh nonce via an API/helper) so tests run reliably across environments.
🧹 Nitpick comments (8)
tests/pw/tests/e2e/stripe-express/stripeExpressPage.ts (4)
86-100: ReplacewaitForTimeoutwith explicit wait conditions.Using
waitForTimeoutis a Playwright anti-pattern that leads to flaky tests. Lines 89, 94, and 99 use arbitrary timeouts that may be too short (causing failures) or too long (slowing tests unnecessarily).♻️ Proposed refactor using explicit waits
async goToModulesPage() { await this.page.goto(this.admin.modulesUrl); await this.page.waitForLoadState('networkidle'); - await this.page.waitForTimeout(2000); // Wait for modules to load + await this.page.waitForSelector(this.admin.moduleCard, { state: 'visible' }); } async searchModule(moduleName: string) { await this.page.fill(this.admin.searchBox, moduleName); - await this.page.waitForTimeout(1000); // Wait for search results + // Wait for search filtering to complete + await this.page.waitForFunction(() => document.querySelectorAll('.module-card').length > 0); } async clearSearch() { await this.page.click(this.admin.clearSearchButton); - await this.page.waitForTimeout(1000); + await this.page.waitForSelector(this.admin.moduleCard, { state: 'visible' }); }
72-74: Empty placeholder methods add maintenance burden without value.Multiple methods (
adminLogin,vendorLogin,customerLogin,connectStripeExpress,disconnectStripeExpress) are empty placeholders. These create confusion for test authors who may expect them to work, and add dead code to maintain.Either implement these methods or remove them until needed. If they're planned for future work, consider adding
TODOcomments with issue references.💡 Option: Remove or mark as not implemented
// Admin Methods -async adminLogin(username: string, password: string) { - // Add admin login logic here -} +async adminLogin(_username: string, _password: string): Promise<void> { + // TODO(`#ISSUE`): Implement admin login - currently using storageState instead + throw new Error('Not implemented - use storageState for authentication'); +}Also applies to: 155-157, 181-192
81-84: Remove unnecessaryawaitbefore locator creation.In Playwright,
this.page.locator()returns aLocatorsynchronously - no promise is involved. Theawaiton line 82 is unnecessary and can be removed.♻️ Proposed fix
async isStripeExpressEnabled(): Promise<boolean> { - const checkbox = await this.page.locator(this.admin.stripeExpressEnabledCheckbox); + const checkbox = this.page.locator(this.admin.stripeExpressEnabledCheckbox); return await checkbox.isChecked(); }
129-132:waitForTimeoutafter toggle click may cause flaky behavior.Line 131 uses a hardcoded 1500ms timeout after clicking the toggle. If the save operation takes longer, the test may proceed before the state is persisted, causing downstream failures.
♻️ Proposed fix: Wait for network or UI indicator
if (isCurrentlyEnabled !== enable) { const slider = card.locator(this.admin.moduleSlider); await slider.click(); - await this.page.waitForTimeout(1500); // Wait for toggle animation and save + // Wait for the toggle state to be saved + await this.page.waitForLoadState('networkidle'); }tests/pw/tests/e2e/stripe-express/stripeExpress.spec.ts (4)
1-1: Remove unusedPageimport.The
Pagetype is imported but never used in this file. Test functions receivebrowserfixture, notpage.♻️ Proposed fix
-import { test, expect, Page } from '@playwright/test'; +import { test, expect } from '@playwright/test';
48-60: Remove or implement placeholder tests.Test Cases 2 and 5 are placeholder tests with no meaningful assertions or actions. Placeholder tests:
- Add noise to test reports
- May be forgotten and never implemented
- Increase test suite execution time
Either implement them with real test logic or remove them. If they represent planned work, create issues/tickets instead.
🗑️ Remove placeholders
- test('Test Case 2 - Placeholder', async ({ browser }) => { - test.skip(!isStripeExpressEnabled, 'Stripe Express is not enabled - skipping test'); - - // Example: Using vendor 1 session storage - const context = await browser.newContext({ storageState: v1 }); - const vendorPage = await context.newPage(); - const vendorStripeExpressPage = new StripeExpressPage(vendorPage); - - // TODO: Add test steps here - - await vendorPage.close(); - await context.close(); - });- test('Test Case 5 - Placeholder', async ({ browser }) => { - test.skip(!isStripeExpressEnabled, 'Stripe Express is not enabled - skipping test'); - - // TODO: Add test steps - });Also applies to: 123-127
29-46: Add try-finally to ensure context cleanup on test failure.If an assertion or action fails before lines 44-45, the browser context and page will not be closed, potentially causing resource leaks and affecting subsequent tests.
♻️ Proposed fix with try-finally
test('Test Case 1 - Verify Stripe Express is Enabled', async ({ browser }) => { // Using admin session storage const context = await browser.newContext({ storageState: a1 }); const adminPage = await context.newPage(); - const stripeExpressPage = new StripeExpressPage(adminPage); - - // Navigate to Stripe Express settings page - await stripeExpressPage.goToStripeExpressSettings(); - - // Check if Stripe Express is enabled - isStripeExpressEnabled = await stripeExpressPage.isStripeExpressEnabled(); - - // Assert that Stripe Express is enabled - expect(isStripeExpressEnabled, 'Stripe Express must be enabled to run tests').toBe(true); - - await adminPage.close(); - await context.close(); + + try { + const stripeExpressPage = new StripeExpressPage(adminPage); + + // Navigate to Stripe Express settings page + await stripeExpressPage.goToStripeExpressSettings(); + + // Check if Stripe Express is enabled + isStripeExpressEnabled = await stripeExpressPage.isStripeExpressEnabled(); + + // Assert that Stripe Express is enabled + expect(isStripeExpressEnabled, 'Stripe Express must be enabled to run tests').toBe(true); + } finally { + await adminPage.close(); + await context.close(); + } });Apply similar pattern to other tests (62-98, 100-121).
8-11: Variable naming is cryptic and reduces readability.The session storage path variables
a1,v1,v2,c1are not self-documenting. While comments explain them, more descriptive names would improve code maintainability.♻️ Proposed naming improvement
-const a1 = path.join(__dirname, '../../../playwright/.auth/adminStorageState.json'); // Admin session storage -const v1 = path.join(__dirname, '../../../playwright/.auth/vendorStorageState.json'); // Vendor 1 session storage -const v2 = path.join(__dirname, '../../../playwright/.auth/vendor2StorageState.json'); // Vendor 2 session storage -const c1 = path.join(__dirname, '../../../playwright/.auth/customerStorageState.json'); // Customer 1 session storage +const adminStorageState = path.join(__dirname, '../../../playwright/.auth/adminStorageState.json'); +const vendor1StorageState = path.join(__dirname, '../../../playwright/.auth/vendorStorageState.json'); +const vendor2StorageState = path.join(__dirname, '../../../playwright/.auth/vendor2StorageState.json'); +const customerStorageState = path.join(__dirname, '../../../playwright/.auth/customerStorageState.json');
| admin = { | ||
| stripeExpressSettingsUrl: 'http://localhost:9999/wp-admin/admin.php?page=wc-settings&tab=checkout§ion=dokan_stripe_express&from=WCADMIN_PAYMENT_SETTINGS', | ||
| stripeExpressEnabledCheckbox: '#woocommerce_dokan_stripe_express_enabled', | ||
| modulesUrl: 'http://localhost:9999/wp-admin/admin.php?page=dokan#/modules', | ||
| searchBox: "div[class='search-box'] input", | ||
| clearSearchButton: "div[class='search-box'] svg", | ||
| moduleSlider: '.slider.round', | ||
| moduleCard: '.module-card', | ||
| moduleTitle: '.module-card h3', | ||
| moduleToggle: '.switch input[type="checkbox"]' | ||
| }; | ||
|
|
||
| // Vendor Selectors | ||
| vendor = { | ||
| stripeExpressOnboardingUrl: 'http://localhost:9999/dashboard/settings/payment-manage-dokan_stripe_express/?action=stripe_express_onboarding&seller_id=3&_wpnonce=b3f06f28bd', | ||
| visitExpressDashboardButton: '#dokan-stripe-express-dashboard-login' | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardcoded URLs and credentials will cause test failures across environments.
The admin and vendor URLs contain hardcoded localhost:9999 base URLs. Additionally, line 29 has a hardcoded seller_id=3 and _wpnonce value that will expire or be invalid in different test runs.
These should be constructed dynamically using environment variables or a configuration object.
🔧 Proposed fix using environment variables
+ private baseUrl = process.env.BASE_URL || 'http://localhost:9999';
+
// Admin Selectors
admin = {
- stripeExpressSettingsUrl: 'http://localhost:9999/wp-admin/admin.php?page=wc-settings&tab=checkout§ion=dokan_stripe_express&from=WCADMIN_PAYMENT_SETTINGS',
+ stripeExpressSettingsPath: '/wp-admin/admin.php?page=wc-settings&tab=checkout§ion=dokan_stripe_express&from=WCADMIN_PAYMENT_SETTINGS',
stripeExpressEnabledCheckbox: '#woocommerce_dokan_stripe_express_enabled',
- modulesUrl: 'http://localhost:9999/wp-admin/admin.php?page=dokan#/modules',
+ modulesPath: '/wp-admin/admin.php?page=dokan#/modules',
searchBox: "div[class='search-box'] input",
clearSearchButton: "div[class='search-box'] svg",
moduleSlider: '.slider.round',
moduleCard: '.module-card',
moduleTitle: '.module-card h3',
moduleToggle: '.switch input[type="checkbox"]'
};
// Vendor Selectors
vendor = {
- stripeExpressOnboardingUrl: 'http://localhost:9999/dashboard/settings/payment-manage-dokan_stripe_express/?action=stripe_express_onboarding&seller_id=3&_wpnonce=b3f06f28bd',
+ stripeExpressOnboardingPath: '/dashboard/settings/payment-manage-dokan_stripe_express/',
visitExpressDashboardButton: '#dokan-stripe-express-dashboard-login'
};Then update navigation methods to construct full URLs:
async goToStripeExpressSettings() {
await this.page.goto(`${this.baseUrl}${this.admin.stripeExpressSettingsPath}`);
await this.page.waitForLoadState('networkidle');
}🤖 Prompt for AI Agents
In `@tests/pw/tests/e2e/stripe-express/stripeExpressPage.ts` around lines 15 - 31,
The admin/vendor objects hardcode base URLs and transient query params
(stripeExpressSettingsUrl, stripeExpressOnboardingUrl, seller_id=3, _wpnonce)
causing environment brittleness; change these to store only path fragments
(e.g., stripeExpressSettingsPath, stripeExpressOnboardingPath) and read the base
URL and dynamic params (sellerId, wpNonce) from environment/config at runtime,
then update navigation helpers (e.g., goToStripeExpressSettings, any method
using visitExpressDashboardButton) to construct full URLs via
`${this.baseUrl}${this.admin.stripeExpressSettingsPath}` or by appending
`?seller_id=${this.config.sellerId}&_wpnonce=${this.auth.wpNonce}` (or retrieve
a fresh nonce via an API/helper) so tests run reliably across environments.
- Enhanced stripeExpress.spec.ts with additional test cases for verifying the visibility of the "Visit Express Dashboard" button for Vendor 1 and Vendor 2. - Updated stripeExpressPage.ts to support vendor-specific onboarding URLs and added methods for navigating to the shop and checkout pages. - Implemented product addition to the cart and order placement functionality in the new tests, improving coverage of Stripe Express payment interactions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@tests/pw/tests/e2e/stripe-express/stripeExpressPage.ts`:
- Around line 340-353: The loop assumes frameLocator =
this.page.locator(...).contentFrame() is non-null; update the loop over
allStripeFrames to await contentFrame(), check for null, and continue if null
before calling locator/count: i.e., after computing frameLocator (or better
named maybe frame) do if (!frameLocator) continue; (or add a small retry/wait)
so that hasCardInput, stripeFrame and stripeFrameName are only used when
contentFrame() returned a non-null Frame; ensure you reference the existing
variables allStripeFrames, frameLocator, hasCardInput, stripeFrame and
stripeFrameName when applying the null check.
🧹 Nitpick comments (5)
tests/pw/tests/e2e/stripe-express/stripeExpressPage.ts (5)
42-43: Prefer CSS selectors over XPath for maintainability.Line 42 uses XPath (
//a[@aria-label='...']) while line 43 uses CSS (a[aria-label='...']). CSS selectors are generally more readable and performant. Consider using CSS consistently.♻️ Proposed fix
- addToCartProduct1: "//a[`@aria-label`='Add to cart: \"p1_v1 (simple)\"']", + addToCartProduct1: "a[aria-label='Add to cart: \"p1_v1 (simple)\"']",
99-113: ReplacewaitForTimeoutwith condition-based waits.Fixed timeouts (
waitForTimeout) create flaky tests and slow execution. Prefer waiting for specific conditions like element visibility, network idle, or custom predicates.♻️ Example refactor for searchModule
async searchModule(moduleName: string) { await this.page.fill(this.admin.searchBox, moduleName); - await this.page.waitForTimeout(1000); // Wait for search results + // Wait for modules to filter based on search + await this.page.waitForFunction( + (name) => document.querySelectorAll('.module-card').length > 0, + moduleName + ); }
260-272: Remove console.log statements and avoid empty catch blocks.Production test code should use Playwright's built-in reporters instead of
console.log. The emptycatch {}block at line 268 silently suppresses errors, making debugging difficult.♻️ Proposed fix
for (const button of cardButtons) { - try { - if (await button.isVisible({ timeout: 1000 })) { - await button.click(); - console.log('Clicked Card button on main page'); - await this.page.waitForTimeout(2000); - break; - } - } catch {} + const isVisible = await button.isVisible({ timeout: 1000 }).catch(() => false); + if (isVisible) { + await button.click(); + await this.page.waitForLoadState('domcontentloaded'); + break; + } } - } catch (e) { - console.log('No Card button found on main page'); - } + } catch { + // Card button may not be present in all checkout configurations + }
382-404: Extract hardcoded test card details totestDataobject.The test card number
4242 4242 4242 4242and other card details are hardcoded throughout the method. Move these to thetestDataobject for better maintainability and reusability.♻️ Proposed fix
testData = { + stripeTestCard: { + number: '4242 4242 4242 4242', + expiry: '11 / 29', + cvc: '111' + }, admin: { // Add admin test data here },Then use
this.testData.stripeTestCard.numberinstead of the hardcoded value.
85-87: Empty placeholder methods should have TODO comments or be removed.Multiple methods (
adminLogin,vendorLogin,customerLogin,connectStripeExpress,disconnectStripeExpress) are empty placeholders. Add TODO comments explaining the intended functionality, or remove them if authentication is handled elsewhere (e.g., via storage state).♻️ Example: Add TODO comments
async adminLogin(username: string, password: string) { - // Add admin login logic here + // TODO: Implement if needed. Currently, tests use storageState for authentication. + // See: tests/pw/tests/e2e/stripe-express/stripeExpress.spec.ts }Also applies to: 168-170, 197-199, 446-452
| for (const frameName of allStripeFrames) { | ||
| const frameLocator = this.page.locator(`iframe[name="${frameName}"]`).contentFrame(); | ||
|
|
||
| // Check if this frame contains card input fields | ||
| const hasCardInput = await frameLocator.locator('input[name="number"], input[id*="numberInput"], #payment-numberInput').count().catch(() => 0); | ||
| console.log(`Frame ${frameName} has ${hasCardInput} card inputs`); | ||
|
|
||
| if (hasCardInput > 0) { | ||
| stripeFrame = frameLocator; | ||
| stripeFrameName = frameName; | ||
| console.log('✓ Found Stripe card form iframe:', frameName); | ||
| break; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add null check for contentFrame() return value.
contentFrame() can return null if the frame is not loaded. The code at lines 341, 344 uses frameLocator without checking for null, which will cause runtime errors.
🛡️ Proposed fix
for (const frameName of allStripeFrames) {
- const frameLocator = this.page.locator(`iframe[name="${frameName}"]`).contentFrame();
+ const frameLocator = await this.page.locator(`iframe[name="${frameName}"]`).contentFrame();
+
+ if (!frameLocator) {
+ continue;
+ }
// Check if this frame contains card input fields
const hasCardInput = await frameLocator.locator('input[name="number"], input[id*="numberInput"], `#payment-numberInput`').count().catch(() => 0);🤖 Prompt for AI Agents
In `@tests/pw/tests/e2e/stripe-express/stripeExpressPage.ts` around lines 340 -
353, The loop assumes frameLocator = this.page.locator(...).contentFrame() is
non-null; update the loop over allStripeFrames to await contentFrame(), check
for null, and continue if null before calling locator/count: i.e., after
computing frameLocator (or better named maybe frame) do if (!frameLocator)
continue; (or add a small retry/wait) so that hasCardInput, stripeFrame and
stripeFrameName are only used when contentFrame() returned a non-null Frame;
ensure you reference the existing variables allStripeFrames, frameLocator,
hasCardInput, stripeFrame and stripeFrameName when applying the null check.
- Modified stripeExpressPage.ts to replace hardcoded URLs with a dynamic BASE_URL variable, improving flexibility for different environments. - Ensured all relevant URLs for admin, vendor, and customer interactions now utilize the BASE_URL for better maintainability.
- Introduced a new SETUP.md file detailing the complete setup process for the Dokan development and testing environment. - Included prerequisites, step-by-step installation instructions for plugin and test suite dependencies, environment configuration, and Docker setup. - Provided troubleshooting tips and a quick command reference to streamline the setup and testing process.
All Submissions:
Changes proposed in this Pull Request:
Related Pull Request(s)
Closes
How to test the changes in this Pull Request:
Changelog entry
Refactored test suite documentation with professional README, deployment guide, security fixes, and cleanup of redundant files
Detailed Description of the pull request. What was previous behaviour
and what will be changed in this PR.
Before Changes
Describe the issue before changes with screenshots(s).
After Changes
Describe the issue after changes with screenshot(s).
Feature Video (optional)
Link of detailed video if this PR is for a feature.
PR Self Review Checklist:
FOR PR REVIEWER ONLY:
Summary by CodeRabbit
New Features
Tests
Documentation
Chores