Skip to content

Add msw package to implement integration tests #59767

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

Merged
merged 14 commits into from
Jul 25, 2025
Merged

Add msw package to implement integration tests #59767

merged 14 commits into from
Jul 25, 2025

Conversation

gigitux
Copy link
Contributor

@gigitux gigitux commented Jul 18, 2025

Submission Review Guidelines:

Changes proposed in this Pull Request:

This PR adds MSW (Mock Service Worker) configuration to improve unit/integration testing infrastructure for blocks. MSW is a powerful API mocking library that intercepts network requests at the service worker level, enabling more realistic testing scenarios.

The only caveat to adding MSW is that we can't fake setTimeout: mswjs/msw#966. For this reason, I updated some unit test blocks to wait until the block is visible.

Screenshots or screen recordings:

How to test the changes in this Pull Request:

  1. Ensure that the CI doesn't fail.

Testing that has already taken place:

  • Dependencies have been added to package.json and verified to install correctly
  • Jest configuration has been updated to use the new test environment
  • Existing test suite has been run to ensure no regressions
  • MSW version 2.10.4 is a stable, well-tested version used in many production environments

Changelog entry

  • Automatically create a changelog entry from the details below.

  • This Pull Request does not require a changelog entry. (Comment required below)

Changelog Entry Details

Significance

  • Patch
  • Minor
  • Major

Type

  • Fix - Fixes an existing bug
  • Add - Adds functionality
  • Update - Update existing functionality
  • Dev - Development related task
  • Tweak - A minor adjustment to the codebase
  • Performance - Address performance issues
  • Enhancement - Improvement to existing functionality

Message

Add msw package to implement integration tests

Changelog Entry Comment

Comment

@github-actions github-actions bot added focus: monorepo infrastructure Issues and PRs related to monorepo tooling. plugin: woocommerce Issues related to the WooCommerce Core plugin. labels Jul 18, 2025
@gigitux gigitux closed this Jul 18, 2025
@gigitux gigitux reopened this Jul 18, 2025
@gigitux gigitux marked this pull request as ready for review July 18, 2025 15:33
@gigitux gigitux requested review from a team as code owners July 18, 2025 15:33
@gigitux gigitux requested review from ralucaStan and joshuatf and removed request for a team July 18, 2025 15:33
@gigitux gigitux self-assigned this Jul 18, 2025
Copy link
Contributor

github-actions bot commented Jul 18, 2025

Testing Guidelines

Hi @ralucaStan @dinhtungdu @joshuatf ,

Apart from reviewing the code changes, please make sure to review the testing instructions (Guide) and verify that relevant tests (E2E, Unit, Integration, etc.) have been added or updated as needed.

Reminder: PR reviewers are required to document testing performed. This includes:

  • 🖼️ Screenshots or screen recordings.
  • 📝 List of functionality tested / steps followed.
  • 🌐 Site details (environment attributes such as hosting type, plugins, theme, store size, store age, and relevant settings).
  • 🔍 Any analysis performed, such as assessing potential impacts on environment attributes and other plugins, conducting performance profiling, or using LLM/AI-based analysis.

⚠️ Within the testing details you provide, please ensure that no sensitive information (such as API keys, passwords, user data, etc.) is included in this public issue.

@woocommercebot woocommercebot requested review from a team and dinhtungdu and removed request for a team July 18, 2025 15:33
Copy link
Contributor

coderabbitai bot commented Jul 18, 2025

📝 Walkthrough

Walkthrough

This change replaces the use of jest-fetch-mock with Mock Service Worker (MSW) for HTTP request mocking across WooCommerce client blocks tests. It updates test setup, dependencies, TypeScript and Jest configurations, and refactors numerous test files to use MSW handlers and UI-based assertions. No exported or public APIs are altered.

Changes

File(s) Change Summary
.../client/blocks/assets/js/blocks/cart/test/block.js
.../cart/test/slots.js
.../mini-cart/test/block.js
.../checkout/test/block.tsx
.../cart-checkout-shared/payment-methods/test/payment-methods.js
.../checkout/test/editor-integration.tsx
.../cart/test/editor-integration.tsx
.../product-specifications/test/block.ts
.../stock-filter/test/block.tsx
.../data/payment/test/selectors.js
.../base/context/hooks/cart/test/use-store-cart-coupons.tsx
Refactored tests to replace jest-fetch-mock with MSW; updated setup/cleanup hooks; replaced fetch-based assertions with UI-based waits and checks; updated imports and request mocking logic accordingly.
.../client/blocks/package.json
.../changelog/59767-add-msw-package
Added msw and jest-fixed-jsdom as dev dependencies; removed jest-fetch-mock. Updated changelog to reflect MSW addition.
.../client/blocks/tests/js/config/msw-setup.js Added new MSW setup file: initializes and exports MSW server, HTTP utilities, and response helpers for use in tests.
.../client/blocks/tests/js/config/global-mocks.js Removed enabling of jest-fetch-mock global fetch mocks.
.../client/blocks/tests/js/jest.config.json Updated Jest config: added MSW setup, module name mappings, and switched test environment to jest-fixed-jsdom.
.../client/blocks/tsconfig.base.json Added TypeScript path alias for MSW test utilities.
.../client/blocks/tsconfig.json Included ./tests/js/**/* in TypeScript compilation scope.
.../client/blocks/assets/js/base/context/hooks/test/use-query-state.jsx Removed Jest environment directive comment.
.../client/blocks/assets/js/base/utils/test/errors.js Refined error message assertions and formatted mock Response instantiation.
.../client/blocks/tests/integration/helpers/with-fake-timers.ts Updated Jest fake timers setup to use modern mode and exclude setTimeout from faking.
.../client/legacy/js/frontend/test/address-autocomplete.js Changed Jest environment directive to jest-fixed-jsdom.

Sequence Diagram(s)

sequenceDiagram
    participant Test as Test File
    participant MSW as MSW Server
    participant API as WooCommerce API (Mocked)
    participant UI as UI Component

    Test->>MSW: Register HTTP request handler (e.g., GET/POST /wc/store/v1/cart)
    Test->>UI: Render component
    UI->>API: Makes HTTP request (fetch)
    MSW-->>UI: Intercepts and returns mocked response
    UI->>Test: Renders UI based on mocked data
    Test->>UI: Assert UI state/visibility based on mocked response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between df96dcb and 05cd499.

📒 Files selected for processing (2)
  • plugins/woocommerce/client/blocks/assets/js/base/context/hooks/cart/test/use-store-cart-coupons.tsx (18 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/slots.js (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/slots.js
  • plugins/woocommerce/client/blocks/assets/js/base/context/hooks/cart/test/use-store-cart-coupons.tsx
⏰ 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). (248)
  • GitHub Check: JavaScript - @woocommerce/block-library [unit]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: JavaScript - @woocommerce/experimental [unit]
  • GitHub Check: JavaScript - @woocommerce/customer-effort-score [unit]
  • GitHub Check: JavaScript - @woocommerce/block-templates [unit]
  • GitHub Check: JavaScript - @woocommerce/components [unit]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/blueprint [unit:php]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/email-editor-config [unit:php]
  • GitHub Check: Lint - @woocommerce/monorepo-utils
  • GitHub Check: JavaScript - @woocommerce/block-library [unit]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: JavaScript - @woocommerce/experimental [unit]
  • GitHub Check: JavaScript - @woocommerce/customer-effort-score [unit]
  • GitHub Check: JavaScript - @woocommerce/block-templates [unit]
  • GitHub Check: JavaScript - @woocommerce/components [unit]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/blueprint [unit:php]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/email-editor-config [unit:php]
  • GitHub Check: Lint - @woocommerce/monorepo-utils
  • GitHub Check: JavaScript - @woocommerce/block-library [unit]
  • GitHub Check: JavaScript - @woocommerce/admin-library [unit]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: JavaScript - @woocommerce/experimental [unit]
  • GitHub Check: JavaScript - @woocommerce/customer-effort-score [unit]
  • GitHub Check: JavaScript - @woocommerce/block-templates [unit]
  • GitHub Check: JavaScript - @woocommerce/components [unit]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/blueprint [unit:php]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/email-editor-config [unit:php]
  • GitHub Check: Lint - @woocommerce/monorepo-utils
  • GitHub Check: Core e2e tests 2/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 3/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/block-library [unit]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: Core e2e tests 1/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/admin-library [unit]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: JavaScript - @woocommerce/product-editor [unit]
  • GitHub Check: JavaScript - @woocommerce/remote-logging [unit]
  • GitHub Check: JavaScript - @woocommerce/date [unit]
  • GitHub Check: JavaScript - @woocommerce/experimental [unit]
  • GitHub Check: JavaScript - @woocommerce/customer-effort-score [unit]
  • GitHub Check: JavaScript - @woocommerce/components [unit]
  • GitHub Check: JavaScript - @woocommerce/currency [unit]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/blueprint [unit:php]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/email-editor-config [unit:php]
  • GitHub Check: Lint - @woocommerce/monorepo-utils
  • GitHub Check: Lint - @woocommerce/email-editor-config
  • GitHub Check: Lint - @woocommerce/csv-export
  • GitHub Check: Lint - @woocommerce/blueprint
  • GitHub Check: Core e2e tests - Gutenberg nightly 3/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 2/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 3/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 3/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 4/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 2/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/block-library [unit]
  • GitHub Check: Core e2e tests - Gutenberg nightly 1/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 6/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 1/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: Core e2e tests 1/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/admin-library [unit]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: JavaScript - @woocommerce/product-editor [unit]
  • GitHub Check: JavaScript - @woocommerce/remote-logging [unit]
  • GitHub Check: JavaScript - @woocommerce/date [unit]
  • GitHub Check: JavaScript - @woocommerce/experimental [unit]
  • GitHub Check: JavaScript - @woocommerce/customer-effort-score [unit]
  • GitHub Check: JavaScript - @woocommerce/components [unit]
  • GitHub Check: JavaScript - @woocommerce/currency [unit]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/blueprint [unit:php]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/email-editor-config [unit:php]
  • GitHub Check: Lint - @woocommerce/monorepo-utils
  • GitHub Check: Lint - @woocommerce/email-editor-config
  • GitHub Check: Lint - @woocommerce/csv-export
  • GitHub Check: Lint - @woocommerce/blueprint
  • GitHub Check: Core e2e tests - Gutenberg nightly 3/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 2/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 3/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 3/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 4/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg nightly 2/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/onboarding [unit]
  • GitHub Check: Core e2e tests 4/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 2/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/block-library [unit]
  • GitHub Check: Core e2e tests - Gutenberg nightly 1/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 6/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 5/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 1/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: Core e2e tests 1/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/admin-library [unit]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: JavaScript - @woocommerce/settings-editor [unit]
  • GitHub Check: JavaScript - @woocommerce/product-editor [unit]
  • GitHub Check: JavaScript - @woocommerce/remote-logging [unit]
  • GitHub Check: JavaScript - @woocommerce/date [unit]
  • GitHub Check: JavaScript - @woocommerce/experimental [unit]
  • GitHub Check: JavaScript - @woocommerce/customer-effort-score [unit]
  • GitHub Check: JavaScript - @woocommerce/components [unit]
  • GitHub Check: JavaScript - @woocommerce/currency [unit]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/blueprint [unit:php]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/email-editor-config [unit:php]
  • GitHub Check: Lint - @woocommerce/monorepo-utils
  • GitHub Check: Lint - @woocommerce/email-editor-config
  • GitHub Check: Lint - @woocommerce/csv-export
  • GitHub Check: Lint - @woocommerce/blueprint
  • GitHub Check: Core e2e tests - Gutenberg nightly 3/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 2/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 3/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 3/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 4/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg nightly 2/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/onboarding [unit]
  • GitHub Check: Core e2e tests 4/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 2/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/block-library [unit]
  • GitHub Check: Core e2e tests - Gutenberg nightly 1/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 6/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 5/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 1/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: Core e2e tests 1/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/admin-library [unit]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: JavaScript - @woocommerce/settings-editor [unit]
  • GitHub Check: JavaScript - @woocommerce/product-editor [unit]
  • GitHub Check: JavaScript - @woocommerce/remote-logging [unit]
  • GitHub Check: JavaScript - @woocommerce/date [unit]
  • GitHub Check: JavaScript - @woocommerce/experimental [unit]
  • GitHub Check: JavaScript - @woocommerce/customer-effort-score [unit]
  • GitHub Check: JavaScript - @woocommerce/components [unit]
  • GitHub Check: JavaScript - @woocommerce/currency [unit]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/blueprint [unit:php]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/email-editor-config [unit:php]
  • GitHub Check: Lint - @woocommerce/monorepo-utils
  • GitHub Check: Lint - @woocommerce/email-editor-config
  • GitHub Check: Lint - @woocommerce/csv-export
  • GitHub Check: Lint - @woocommerce/blueprint
  • GitHub Check: Core e2e tests - Gutenberg nightly 3/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 2/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 3/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 3/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 4/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg nightly 2/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/onboarding [unit]
  • GitHub Check: Core e2e tests 4/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 2/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/block-library [unit]
  • GitHub Check: Core e2e tests - Gutenberg nightly 1/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 6/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 5/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 1/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: Core e2e tests 1/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/admin-library [unit]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: JavaScript - @woocommerce/settings-editor [unit]
  • GitHub Check: JavaScript - @woocommerce/product-editor [unit]
  • GitHub Check: JavaScript - @woocommerce/remote-logging [unit]
  • GitHub Check: JavaScript - @woocommerce/date [unit]
  • GitHub Check: JavaScript - @woocommerce/experimental [unit]
  • GitHub Check: JavaScript - @woocommerce/customer-effort-score [unit]
  • GitHub Check: JavaScript - @woocommerce/components [unit]
  • GitHub Check: JavaScript - @woocommerce/currency [unit]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/blueprint [unit:php]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/email-editor-config [unit:php]
  • GitHub Check: Lint - @woocommerce/monorepo-utils
  • GitHub Check: Lint - @woocommerce/email-editor-config
  • GitHub Check: Lint - @woocommerce/csv-export
  • GitHub Check: Lint - @woocommerce/blueprint
  • GitHub Check: Core e2e tests - Gutenberg nightly 3/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 2/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 3/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 3/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 4/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg nightly 2/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/onboarding [unit]
  • GitHub Check: Core e2e tests 4/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 2/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/block-library [unit]
  • GitHub Check: Core e2e tests - Gutenberg nightly 1/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 6/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 5/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 1/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: Core e2e tests 1/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/admin-library [unit]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: JavaScript - @woocommerce/settings-editor [unit]
  • GitHub Check: JavaScript - @woocommerce/product-editor [unit]
  • GitHub Check: JavaScript - @woocommerce/remote-logging [unit]
  • GitHub Check: JavaScript - @woocommerce/date [unit]
  • GitHub Check: JavaScript - @woocommerce/experimental [unit]
  • GitHub Check: JavaScript - @woocommerce/customer-effort-score [unit]
  • GitHub Check: JavaScript - @woocommerce/components [unit]
  • GitHub Check: JavaScript - @woocommerce/currency [unit]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/blueprint [unit:php]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/email-editor-config [unit:php]
  • GitHub Check: Lint - @woocommerce/email-editor-config
  • GitHub Check: Lint - @woocommerce/csv-export
  • GitHub Check: Lint - @woocommerce/blueprint
  • GitHub Check: Core e2e tests - Gutenberg nightly 3/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 2/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 3/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 3/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 4/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg nightly 2/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/onboarding [unit]
  • GitHub Check: Core e2e tests 4/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 2/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/block-library [unit]
  • GitHub Check: Core e2e tests - Gutenberg nightly 1/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 6/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 5/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests - Gutenberg stable 1/4 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: Core e2e tests 1/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/admin-library [unit]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.2] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: JavaScript - @woocommerce/settings-editor [unit]
  • GitHub Check: JavaScript - @woocommerce/product-editor [unit]
  • GitHub Check: JavaScript - @woocommerce/remote-logging [unit]
  • GitHub Check: JavaScript - @woocommerce/date [unit]
  • GitHub Check: JavaScript - @woocommerce/experimental [unit]
  • GitHub Check: JavaScript - @woocommerce/customer-effort-score [unit]
  • GitHub Check: JavaScript - @woocommerce/components [unit]
  • GitHub Check: JavaScript - @woocommerce/currency [unit]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/blueprint [unit:php]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/email-editor-config [unit:php]
  • GitHub Check: Lint - @woocommerce/email-editor-config
  • GitHub Check: Lint - @woocommerce/csv-export
  • GitHub Check: Lint - @woocommerce/blueprint
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch add/msw-package

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

github-actions bot commented Jul 18, 2025

Size Change: +6 B (0%)

Total Size: 5.91 MB

compressed-size-action

Copy link
Contributor

github-actions bot commented Jul 18, 2025

Test using WordPress Playground

The changes in this pull request can be previewed and tested using a WordPress Playground instance.
WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Test this pull request with WordPress Playground.

Note that this URL is valid for 30 days from when this comment was last updated. You can update it by closing/reopening the PR or pushing a new commit.

Copy link
Member

@tyxla tyxla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using MSW here makes sense IMO - it intercepts real network requests, which leads to more realistic tests and consistent mocks across development and testing environments. I personally like the syntax, it can be quite less verbose than other tools like nock or manual jest.fn() stubs.

await waitFor( () => {
expect(
screen.getByLabelText( /Block: Filled Cart$/i )
).toBeInTheDocument();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generally recommend toBeVisible() when it's about locating an element that is visible to the user. While the difference is subtle, the test sees it, but not necessary the user, right? So if we want to be sure the user sees it, we should prefer toBeVisible().

Note that this is only for positive queries (the element is visible). When the element doesn't exist, we should still be using .not.toBeInTheDocument() since toBeVisible() will throw errors.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense! Addressed with ce57669

"wp-types": "3.63.0"
"wp-types": "3.63.0",
"msw": "2.10.4",
"jest-fixed-jsdom": "0.0.9"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need jest-fixed-jsdom? What Node globals are we using?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we using any of those built-in globals? If not, this might be unnecessary in the end.

Copy link
Contributor Author

@gigitux gigitux Jul 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is necessary for msw. If I update Jest configuration removing jest-fixed-jsdom, I got this error:
image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting - good to know, and thanks for clarifying!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gigitux
Copy link
Contributor Author

gigitux commented Jul 22, 2025

@kmanijak Related to this #59790 (comment) I migrated all the tests to MSW, but some of them are failing. Tomorrow I will try to take another look.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
plugins/woocommerce/client/blocks/assets/js/blocks/checkout/test/block.tsx (1)

508-508: Remove .only() from test - critical issue

The it.only() will cause all other tests in this suite to be skipped. This should be changed to it() before merging.

-	it.only( "Ensures hidden postcode fields don't block Checkout", async () => {
+	it( "Ensures hidden postcode fields don't block Checkout", async () => {
🧹 Nitpick comments (2)
plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/slots.js (1)

46-51: Remove debug console.log statement

The MSW handler setup is correct, but the console.log on line 48 appears to be debug code that should be removed before merging.

	server.use(
		http.get( '/wc/store/v1/cart/', () => {
-			console.log( 'previewCart', previewCart );
			return HttpResponse.json( previewCart );
		} )
	);
plugins/woocommerce/client/blocks/assets/js/blocks/checkout/test/block.tsx (1)

172-174: Consider explicit MSW handler cleanup for consistency

While the comment mentions automatic reset in global setup, explicit server.resetHandlers() in afterEach would be more consistent with other test files and provide better test isolation guarantees.

 	afterEach( () => {
-		// MSW handlers are reset automatically in the global setup
+		server.resetHandlers();
 	} );
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 43203aa and a39c04a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • plugins/woocommerce/client/blocks/assets/js/base/context/hooks/cart/test/use-store-cart-coupons.tsx (18 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/test/payment-methods.js (3 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js (7 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/slots.js (3 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/checkout/test/block.tsx (8 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/test/block.js (10 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/stock-filter/test/block.tsx (2 hunks)
  • plugins/woocommerce/client/blocks/assets/js/data/payment/test/selectors.js (5 hunks)
  • plugins/woocommerce/client/blocks/package.json (1 hunks)
  • plugins/woocommerce/client/blocks/tests/js/config/global-mocks.js (0 hunks)
  • plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (1 hunks)
  • plugins/woocommerce/client/blocks/tests/js/jest.config.json (3 hunks)
  • plugins/woocommerce/client/blocks/tsconfig.base.json (1 hunks)
  • plugins/woocommerce/client/blocks/tsconfig.json (1 hunks)
📓 Path-based instructions (2)
**/*.{php,js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/code-quality.mdc)

**/*.{php,js,jsx,ts,tsx}: Guard against unexpected inputs
Sanitize and validate any potentially dangerous inputs
Ensure code is backwards compatible
Write code that is readable and intuitive
Ensure code has unit or E2E tests where applicable

Files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/test/payment-methods.js
  • plugins/woocommerce/client/blocks/assets/js/blocks/stock-filter/test/block.tsx
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/slots.js
  • plugins/woocommerce/client/blocks/assets/js/data/payment/test/selectors.js
  • plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js
  • plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/test/block.js
  • plugins/woocommerce/client/blocks/assets/js/blocks/checkout/test/block.tsx
  • plugins/woocommerce/client/blocks/assets/js/base/context/hooks/cart/test/use-store-cart-coupons.tsx
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js
**/*.{php,js,ts,jsx,tsx}

⚙️ CodeRabbit Configuration File

**/*.{php,js,ts,jsx,tsx}: Don't trust that extension developers will follow the best practices, make sure the code:

  • Guards against unexpected inputs.
  • Sanitizes and validates any potentially dangerous inputs.
  • Is backwards compatible.
  • Is readable and intuitive.
  • Has unit or E2E tests where applicable.

Files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/test/payment-methods.js
  • plugins/woocommerce/client/blocks/assets/js/blocks/stock-filter/test/block.tsx
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/slots.js
  • plugins/woocommerce/client/blocks/assets/js/data/payment/test/selectors.js
  • plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js
  • plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/test/block.js
  • plugins/woocommerce/client/blocks/assets/js/blocks/checkout/test/block.tsx
  • plugins/woocommerce/client/blocks/assets/js/base/context/hooks/cart/test/use-store-cart-coupons.tsx
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/generate-pr-description.mdc:0-0
Timestamp: 2025-07-21T05:22:46.417Z
Learning: Provide clear, step-by-step instructions for how to test the changes in the PR description.
Learnt from: jorgeatorres
PR: woocommerce/woocommerce#59675
File: .github/workflows/release-bump-as-requirement.yml:48-65
Timestamp: 2025-07-15T15:39:21.856Z
Learning: In WooCommerce core repository, changelog entries for all PRs live in `plugins/woocommerce/changelog/` directory and are processed during releases, not at the repository root level.
Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/code-quality.mdc:0-0
Timestamp: 2025-07-18T14:54:36.232Z
Learning: Applies to **/*.{php,js,jsx,ts,tsx} : Ensure code has unit or E2E tests where applicable
plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/test/payment-methods.js (15)

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx:43-50
Timestamp: 2025-06-18T07:56:06.961Z
Learning: In plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx, the user vladolaru prefers to keep the current setUpPlugin function signature with optional positional context parameter rather than refactoring to an options object or making context required.

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/components/stepper/index.tsx:57-67
Timestamp: 2025-06-20T13:08:44.017Z
Learning: For WooCommerce Payments onboarding step tracking in useEffect hooks, only include the active step in the dependency array, not the context object. The sessionEntryPoint is static throughout the onboarding session and tracking should only fire on actual step navigation, not context changes.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the shouldAnimate flag is expected to be false only on initial render and may remain true after the first edit; it does not need to be reset.

Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.

Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/woo-build.mdc:0-0
Timestamp: 2025-07-18T14:55:02.778Z
Learning: To watch for changes during development, use 'pnpm --filter=@woocommerce/plugin-woocommerce watch:build' to ensure experimental features are active.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:78-96
Timestamp: 2025-06-18T06:05:25.472Z
Learning: In WooCommerce mini cart implementation, the cart state is server-populated before JavaScript initialization, so wooStoreState.cart and wooStoreState.cart.totals will be available on first render without requiring null-safe guards.

Learnt from: mreishus
PR: #58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: gigitux
PR: #58785
File: plugins/woocommerce/client/blocks/package.json:0-0
Timestamp: 2025-06-17T10:25:36.686Z
Learning: Do not suggest using cross-env in the WooCommerce repository as it's deprecated/archived and the team is working to remove it from blocks commands to reduce the dependency tree. Instead, inline environment variables like WP_EXPERIMENTAL_MODULES=true knip should work fine in supported environments.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPayments/WooPaymentsServiceTest.php:360-373
Timestamp: 2025-06-25T15:39:25.166Z
Learning: Test mocks should accurately simulate the behavior of the functions they replace, including return value semantics. For WordPress functions like update_option, the mock should properly return false when the value hasn't changed and true when it has, to avoid masking logic errors in tests.

plugins/woocommerce/client/blocks/assets/js/blocks/stock-filter/test/block.tsx (9)

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the shouldAnimate flag is expected to be false only on initial render and may remain true after the first edit; it does not need to be reset.

Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/woo-build.mdc:0-0
Timestamp: 2025-07-18T14:55:02.778Z
Learning: To watch for changes during development, use 'pnpm --filter=@woocommerce/plugin-woocommerce watch:build' to ensure experimental features are active.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.

Learnt from: gigitux
PR: #58785
File: plugins/woocommerce/client/blocks/package.json:0-0
Timestamp: 2025-06-17T10:25:36.686Z
Learning: Do not suggest using cross-env in the WooCommerce repository as it's deprecated/archived and the team is working to remove it from blocks commands to reduce the dependency tree. Instead, inline environment variables like WP_EXPERIMENTAL_MODULES=true knip should work fine in supported environments.

plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/slots.js (14)

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:78-96
Timestamp: 2025-06-18T06:05:25.472Z
Learning: In WooCommerce mini cart implementation, the cart state is server-populated before JavaScript initialization, so wooStoreState.cart and wooStoreState.cart.totals will be available on first render without requiring null-safe guards.

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the shouldAnimate flag is expected to be false only on initial render and may remain true after the first edit; it does not need to be reset.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx:43-50
Timestamp: 2025-06-18T07:56:06.961Z
Learning: In plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx, the user vladolaru prefers to keep the current setUpPlugin function signature with optional positional context parameter rather than refactoring to an options object or making context required.

Learnt from: mreishus
PR: #58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/components/stepper/index.tsx:57-67
Timestamp: 2025-06-20T13:08:44.017Z
Learning: For WooCommerce Payments onboarding step tracking in useEffect hooks, only include the active step in the dependency array, not the context object. The sessionEntryPoint is static throughout the onboarding session and tracking should only fire on actual step navigation, not context changes.

Learnt from: gigitux
PR: #58785
File: plugins/woocommerce/client/blocks/package.json:0-0
Timestamp: 2025-06-17T10:25:36.686Z
Learning: Do not suggest using cross-env in the WooCommerce repository as it's deprecated/archived and the team is working to remove it from blocks commands to reduce the dependency tree. Instead, inline environment variables like WP_EXPERIMENTAL_MODULES=true knip should work fine in supported environments.

Learnt from: triple0t
PR: #59186
File: packages/js/email-editor/src/store/initial-state.ts:9-10
Timestamp: 2025-06-26T12:13:32.062Z
Learning: In WooCommerce email editor store initialization (packages/js/email-editor/src/store/initial-state.ts), the current_post_id and current_post_type from window.WooCommerceEmailEditor are required parameters that should cause explicit errors if missing, rather than using fallback values or optional chaining. The design preference is to fail fast when critical initialization data is unavailable.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be initialized BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation:

const responsePromise = page.waitForResponse('**/api/endpoint');
await triggerAction();
await responsePromise;

This pattern prevents missing rapid responses and is the standard approach for reliable E2E tests.

plugins/woocommerce/client/blocks/assets/js/data/payment/test/selectors.js (16)

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx:43-50
Timestamp: 2025-06-18T07:56:06.961Z
Learning: In plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx, the user vladolaru prefers to keep the current setUpPlugin function signature with optional positional context parameter rather than refactoring to an options object or making context required.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/components/stepper/index.tsx:57-67
Timestamp: 2025-06-20T13:08:44.017Z
Learning: For WooCommerce Payments onboarding step tracking in useEffect hooks, only include the active step in the dependency array, not the context object. The sessionEntryPoint is static throughout the onboarding session and tracking should only fire on actual step navigation, not context changes.

Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/src/Internal/Admin/Settings/Payments.php:431-439
Timestamp: 2025-06-17T14:19:30.933Z
Learning: In plugins/woocommerce/src/Internal/Admin/Settings/Payments.php, the process_payment_provider_states() method intentionally filters out payment providers that don't have a _suggestion_id. This is by design to only track state changes for gateways from partner extensions, not core WooCommerce gateways or other installed gateways.

Learnt from: gigitux
PR: #58785
File: plugins/woocommerce/client/blocks/package.json:0-0
Timestamp: 2025-06-17T10:25:36.686Z
Learning: Do not suggest using cross-env in the WooCommerce repository as it's deprecated/archived and the team is working to remove it from blocks commands to reduce the dependency tree. Instead, inline environment variables like WP_EXPERIMENTAL_MODULES=true knip should work fine in supported environments.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:78-96
Timestamp: 2025-06-18T06:05:25.472Z
Learning: In WooCommerce mini cart implementation, the cart state is server-populated before JavaScript initialization, so wooStoreState.cart and wooStoreState.cart.totals will be available on first render without requiring null-safe guards.

Learnt from: mreishus
PR: #58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPayments/WooPaymentsServiceTest.php:360-373
Timestamp: 2025-06-25T15:39:25.166Z
Learning: Test mocks should accurately simulate the behavior of the functions they replace, including return value semantics. For WordPress functions like update_option, the mock should properly return false when the value hasn't changed and true when it has, to avoid masking logic errors in tests.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be initialized BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation:

const responsePromise = page.waitForResponse('**/api/endpoint');
await triggerAction();
await responsePromise;

This pattern prevents missing rapid responses and is the standard approach for reliable E2E tests.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be called BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation: const responsePromise = page.waitForResponse(...); await triggerAction(); await responsePromise;

plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (5)

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.

Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/woo-build.mdc:0-0
Timestamp: 2025-07-18T14:55:02.778Z
Learning: To watch for changes during development, use 'pnpm --filter=@woocommerce/plugin-woocommerce watch:build' to ensure experimental features are active.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx:43-50
Timestamp: 2025-06-18T07:56:06.961Z
Learning: In plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx, the user vladolaru prefers to keep the current setUpPlugin function signature with optional positional context parameter rather than refactoring to an options object or making context required.

plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/test/block.js (15)

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:78-96
Timestamp: 2025-06-18T06:05:25.472Z
Learning: In WooCommerce mini cart implementation, the cart state is server-populated before JavaScript initialization, so wooStoreState.cart and wooStoreState.cart.totals will be available on first render without requiring null-safe guards.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: mreishus
PR: #58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the shouldAnimate flag is expected to be false only on initial render and may remain true after the first edit; it does not need to be reset.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/components/cart-checkout/product-details/style.scss:21-26
Timestamp: 2025-06-13T15:24:45.923Z
Learning: In WooCommerce blocks, bold styling for .wc-block-components-product-details__name should be scoped only to the Cart block (.wc-block-cart__main); on the Checkout block, product names are not bold because prices are highlighted instead.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/components/stepper/index.tsx:57-67
Timestamp: 2025-06-20T13:08:44.017Z
Learning: For WooCommerce Payments onboarding step tracking in useEffect hooks, only include the active step in the dependency array, not the context object. The sessionEntryPoint is static throughout the onboarding session and tracking should only fire on actual step navigation, not context changes.

Learnt from: triple0t
PR: #59186
File: packages/js/email-editor/src/store/initial-state.ts:9-10
Timestamp: 2025-06-26T12:13:32.062Z
Learning: In WooCommerce email editor store initialization (packages/js/email-editor/src/store/initial-state.ts), the current_post_id and current_post_type from window.WooCommerceEmailEditor are required parameters that should cause explicit errors if missing, rather than using fallback values or optional chaining. The design preference is to fail fast when critical initialization data is unavailable.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPayments/WooPaymentsServiceTest.php:360-373
Timestamp: 2025-06-25T15:39:25.166Z
Learning: Test mocks should accurately simulate the behavior of the functions they replace, including return value semantics. For WordPress functions like update_option, the mock should properly return false when the value hasn't changed and true when it has, to avoid masking logic errors in tests.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be called BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation: const responsePromise = page.waitForResponse(...); await triggerAction(); await responsePromise;

plugins/woocommerce/client/blocks/assets/js/blocks/checkout/test/block.tsx (14)

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the shouldAnimate flag is expected to be false only on initial render and may remain true after the first edit; it does not need to be reset.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx:43-50
Timestamp: 2025-06-18T07:56:06.961Z
Learning: In plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx, the user vladolaru prefers to keep the current setUpPlugin function signature with optional positional context parameter rather than refactoring to an options object or making context required.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/components/stepper/index.tsx:57-67
Timestamp: 2025-06-20T13:08:44.017Z
Learning: For WooCommerce Payments onboarding step tracking in useEffect hooks, only include the active step in the dependency array, not the context object. The sessionEntryPoint is static throughout the onboarding session and tracking should only fire on actual step navigation, not context changes.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:78-96
Timestamp: 2025-06-18T06:05:25.472Z
Learning: In WooCommerce mini cart implementation, the cart state is server-populated before JavaScript initialization, so wooStoreState.cart and wooStoreState.cart.totals will be available on first render without requiring null-safe guards.

Learnt from: triple0t
PR: #59186
File: packages/js/email-editor/src/store/initial-state.ts:9-10
Timestamp: 2025-06-26T12:13:32.062Z
Learning: In WooCommerce email editor store initialization (packages/js/email-editor/src/store/initial-state.ts), the current_post_id and current_post_type from window.WooCommerceEmailEditor are required parameters that should cause explicit errors if missing, rather than using fallback values or optional chaining. The design preference is to fail fast when critical initialization data is unavailable.

Learnt from: gigitux
PR: #58785
File: plugins/woocommerce/client/blocks/package.json:0-0
Timestamp: 2025-06-17T10:25:36.686Z
Learning: Do not suggest using cross-env in the WooCommerce repository as it's deprecated/archived and the team is working to remove it from blocks commands to reduce the dependency tree. Instead, inline environment variables like WP_EXPERIMENTAL_MODULES=true knip should work fine in supported environments.

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be initialized BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation:

const responsePromise = page.waitForResponse('**/api/endpoint');
await triggerAction();
await responsePromise;

This pattern prevents missing rapid responses and is the standard approach for reliable E2E tests.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be called BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation: const responsePromise = page.waitForResponse(...); await triggerAction(); await responsePromise;

plugins/woocommerce/client/blocks/assets/js/base/context/hooks/cart/test/use-store-cart-coupons.tsx (12)

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx:43-50
Timestamp: 2025-06-18T07:56:06.961Z
Learning: In plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx, the user vladolaru prefers to keep the current setUpPlugin function signature with optional positional context parameter rather than refactoring to an options object or making context required.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/components/stepper/index.tsx:57-67
Timestamp: 2025-06-20T13:08:44.017Z
Learning: For WooCommerce Payments onboarding step tracking in useEffect hooks, only include the active step in the dependency array, not the context object. The sessionEntryPoint is static throughout the onboarding session and tracking should only fire on actual step navigation, not context changes.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/woo-build.mdc:0-0
Timestamp: 2025-07-18T14:55:02.778Z
Learning: To watch for changes during development, use 'pnpm --filter=@woocommerce/plugin-woocommerce watch:build' to ensure experimental features are active.

Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/code-quality.mdc:0-0
Timestamp: 2025-07-18T14:54:36.232Z
Learning: Applies to **/*.{php,js,jsx,ts,tsx} : Ensure code has unit or E2E tests where applicable

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPayments/WooPaymentsServiceTest.php:360-373
Timestamp: 2025-06-25T15:39:25.166Z
Learning: Test mocks should accurately simulate the behavior of the functions they replace, including return value semantics. For WordPress functions like update_option, the mock should properly return false when the value hasn't changed and true when it has, to avoid masking logic errors in tests.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be initialized BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation:

const responsePromise = page.waitForResponse('**/api/endpoint');
await triggerAction();
await responsePromise;

This pattern prevents missing rapid responses and is the standard approach for reliable E2E tests.

plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js (13)

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:78-96
Timestamp: 2025-06-18T06:05:25.472Z
Learning: In WooCommerce mini cart implementation, the cart state is server-populated before JavaScript initialization, so wooStoreState.cart and wooStoreState.cart.totals will be available on first render without requiring null-safe guards.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: mreishus
PR: #58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the shouldAnimate flag is expected to be false only on initial render and may remain true after the first edit; it does not need to be reset.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/components/cart-checkout/product-details/style.scss:21-26
Timestamp: 2025-06-13T15:24:45.923Z
Learning: In WooCommerce blocks, bold styling for .wc-block-components-product-details__name should be scoped only to the Cart block (.wc-block-cart__main); on the Checkout block, product names are not bold because prices are highlighted instead.

Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be called BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation: const responsePromise = page.waitForResponse(...); await triggerAction(); await responsePromise;

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/components/stepper/index.tsx:57-67
Timestamp: 2025-06-20T13:08:44.017Z
Learning: For WooCommerce Payments onboarding step tracking in useEffect hooks, only include the active step in the dependency array, not the context object. The sessionEntryPoint is static throughout the onboarding session and tracking should only fire on actual step navigation, not context changes.

🧬 Code Graph Analysis (6)
plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/test/payment-methods.js (2)
plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (1)
  • server (8-8)
plugins/woocommerce/client/blocks/assets/js/previews/cart.ts (1)
  • previewCart (35-599)
plugins/woocommerce/client/blocks/assets/js/blocks/stock-filter/test/block.tsx (1)
plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (1)
  • server (8-8)
plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/slots.js (4)
plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (1)
  • server (8-8)
plugins/woocommerce/client/blocks/assets/js/previews/cart.ts (1)
  • previewCart (35-599)
plugins/woocommerce/client/blocks/assets/js/data/cart/default-state.ts (1)
  • defaultCartState (55-106)
plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js (1)
  • CartBlock (40-72)
plugins/woocommerce/client/blocks/assets/js/data/payment/test/selectors.js (2)
plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (1)
  • server (8-8)
plugins/woocommerce/client/blocks/assets/js/previews/cart.ts (1)
  • previewCart (35-599)
plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/test/block.js (3)
plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (1)
  • server (8-8)
plugins/woocommerce/client/blocks/assets/js/data/cart/default-state.ts (1)
  • defaultCartState (55-106)
plugins/woocommerce/client/blocks/assets/js/previews/cart.ts (1)
  • previewCart (35-599)
plugins/woocommerce/client/blocks/assets/js/blocks/checkout/test/block.tsx (2)
plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (1)
  • server (8-8)
plugins/woocommerce/client/blocks/assets/js/previews/cart.ts (1)
  • previewCart (35-599)
💤 Files with no reviewable changes (1)
  • plugins/woocommerce/client/blocks/tests/js/config/global-mocks.js
✅ Files skipped from review due to trivial changes (2)
  • plugins/woocommerce/client/blocks/tsconfig.json
  • plugins/woocommerce/client/blocks/tsconfig.base.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • plugins/woocommerce/client/blocks/package.json
  • plugins/woocommerce/client/blocks/tests/js/jest.config.json
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{php,js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/code-quality.mdc)

**/*.{php,js,jsx,ts,tsx}: Guard against unexpected inputs
Sanitize and validate any potentially dangerous inputs
Ensure code is backwards compatible
Write code that is readable and intuitive
Ensure code has unit or E2E tests where applicable

Files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/test/payment-methods.js
  • plugins/woocommerce/client/blocks/assets/js/blocks/stock-filter/test/block.tsx
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/slots.js
  • plugins/woocommerce/client/blocks/assets/js/data/payment/test/selectors.js
  • plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js
  • plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/test/block.js
  • plugins/woocommerce/client/blocks/assets/js/blocks/checkout/test/block.tsx
  • plugins/woocommerce/client/blocks/assets/js/base/context/hooks/cart/test/use-store-cart-coupons.tsx
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js
**/*.{php,js,ts,jsx,tsx}

⚙️ CodeRabbit Configuration File

**/*.{php,js,ts,jsx,tsx}: Don't trust that extension developers will follow the best practices, make sure the code:

  • Guards against unexpected inputs.
  • Sanitizes and validates any potentially dangerous inputs.
  • Is backwards compatible.
  • Is readable and intuitive.
  • Has unit or E2E tests where applicable.

Files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/test/payment-methods.js
  • plugins/woocommerce/client/blocks/assets/js/blocks/stock-filter/test/block.tsx
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/slots.js
  • plugins/woocommerce/client/blocks/assets/js/data/payment/test/selectors.js
  • plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js
  • plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/test/block.js
  • plugins/woocommerce/client/blocks/assets/js/blocks/checkout/test/block.tsx
  • plugins/woocommerce/client/blocks/assets/js/base/context/hooks/cart/test/use-store-cart-coupons.tsx
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/generate-pr-description.mdc:0-0
Timestamp: 2025-07-21T05:22:46.417Z
Learning: Provide clear, step-by-step instructions for how to test the changes in the PR description.
Learnt from: jorgeatorres
PR: woocommerce/woocommerce#59675
File: .github/workflows/release-bump-as-requirement.yml:48-65
Timestamp: 2025-07-15T15:39:21.856Z
Learning: In WooCommerce core repository, changelog entries for all PRs live in `plugins/woocommerce/changelog/` directory and are processed during releases, not at the repository root level.
Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/code-quality.mdc:0-0
Timestamp: 2025-07-18T14:54:36.232Z
Learning: Applies to **/*.{php,js,jsx,ts,tsx} : Ensure code has unit or E2E tests where applicable
plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/test/payment-methods.js (15)

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx:43-50
Timestamp: 2025-06-18T07:56:06.961Z
Learning: In plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx, the user vladolaru prefers to keep the current setUpPlugin function signature with optional positional context parameter rather than refactoring to an options object or making context required.

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/components/stepper/index.tsx:57-67
Timestamp: 2025-06-20T13:08:44.017Z
Learning: For WooCommerce Payments onboarding step tracking in useEffect hooks, only include the active step in the dependency array, not the context object. The sessionEntryPoint is static throughout the onboarding session and tracking should only fire on actual step navigation, not context changes.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the shouldAnimate flag is expected to be false only on initial render and may remain true after the first edit; it does not need to be reset.

Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.

Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/woo-build.mdc:0-0
Timestamp: 2025-07-18T14:55:02.778Z
Learning: To watch for changes during development, use 'pnpm --filter=@woocommerce/plugin-woocommerce watch:build' to ensure experimental features are active.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:78-96
Timestamp: 2025-06-18T06:05:25.472Z
Learning: In WooCommerce mini cart implementation, the cart state is server-populated before JavaScript initialization, so wooStoreState.cart and wooStoreState.cart.totals will be available on first render without requiring null-safe guards.

Learnt from: mreishus
PR: #58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: gigitux
PR: #58785
File: plugins/woocommerce/client/blocks/package.json:0-0
Timestamp: 2025-06-17T10:25:36.686Z
Learning: Do not suggest using cross-env in the WooCommerce repository as it's deprecated/archived and the team is working to remove it from blocks commands to reduce the dependency tree. Instead, inline environment variables like WP_EXPERIMENTAL_MODULES=true knip should work fine in supported environments.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPayments/WooPaymentsServiceTest.php:360-373
Timestamp: 2025-06-25T15:39:25.166Z
Learning: Test mocks should accurately simulate the behavior of the functions they replace, including return value semantics. For WordPress functions like update_option, the mock should properly return false when the value hasn't changed and true when it has, to avoid masking logic errors in tests.

plugins/woocommerce/client/blocks/assets/js/blocks/stock-filter/test/block.tsx (9)

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the shouldAnimate flag is expected to be false only on initial render and may remain true after the first edit; it does not need to be reset.

Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/woo-build.mdc:0-0
Timestamp: 2025-07-18T14:55:02.778Z
Learning: To watch for changes during development, use 'pnpm --filter=@woocommerce/plugin-woocommerce watch:build' to ensure experimental features are active.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.

Learnt from: gigitux
PR: #58785
File: plugins/woocommerce/client/blocks/package.json:0-0
Timestamp: 2025-06-17T10:25:36.686Z
Learning: Do not suggest using cross-env in the WooCommerce repository as it's deprecated/archived and the team is working to remove it from blocks commands to reduce the dependency tree. Instead, inline environment variables like WP_EXPERIMENTAL_MODULES=true knip should work fine in supported environments.

plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/slots.js (14)

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:78-96
Timestamp: 2025-06-18T06:05:25.472Z
Learning: In WooCommerce mini cart implementation, the cart state is server-populated before JavaScript initialization, so wooStoreState.cart and wooStoreState.cart.totals will be available on first render without requiring null-safe guards.

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the shouldAnimate flag is expected to be false only on initial render and may remain true after the first edit; it does not need to be reset.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx:43-50
Timestamp: 2025-06-18T07:56:06.961Z
Learning: In plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx, the user vladolaru prefers to keep the current setUpPlugin function signature with optional positional context parameter rather than refactoring to an options object or making context required.

Learnt from: mreishus
PR: #58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/components/stepper/index.tsx:57-67
Timestamp: 2025-06-20T13:08:44.017Z
Learning: For WooCommerce Payments onboarding step tracking in useEffect hooks, only include the active step in the dependency array, not the context object. The sessionEntryPoint is static throughout the onboarding session and tracking should only fire on actual step navigation, not context changes.

Learnt from: gigitux
PR: #58785
File: plugins/woocommerce/client/blocks/package.json:0-0
Timestamp: 2025-06-17T10:25:36.686Z
Learning: Do not suggest using cross-env in the WooCommerce repository as it's deprecated/archived and the team is working to remove it from blocks commands to reduce the dependency tree. Instead, inline environment variables like WP_EXPERIMENTAL_MODULES=true knip should work fine in supported environments.

Learnt from: triple0t
PR: #59186
File: packages/js/email-editor/src/store/initial-state.ts:9-10
Timestamp: 2025-06-26T12:13:32.062Z
Learning: In WooCommerce email editor store initialization (packages/js/email-editor/src/store/initial-state.ts), the current_post_id and current_post_type from window.WooCommerceEmailEditor are required parameters that should cause explicit errors if missing, rather than using fallback values or optional chaining. The design preference is to fail fast when critical initialization data is unavailable.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be initialized BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation:

const responsePromise = page.waitForResponse('**/api/endpoint');
await triggerAction();
await responsePromise;

This pattern prevents missing rapid responses and is the standard approach for reliable E2E tests.

plugins/woocommerce/client/blocks/assets/js/data/payment/test/selectors.js (16)

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx:43-50
Timestamp: 2025-06-18T07:56:06.961Z
Learning: In plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx, the user vladolaru prefers to keep the current setUpPlugin function signature with optional positional context parameter rather than refactoring to an options object or making context required.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/components/stepper/index.tsx:57-67
Timestamp: 2025-06-20T13:08:44.017Z
Learning: For WooCommerce Payments onboarding step tracking in useEffect hooks, only include the active step in the dependency array, not the context object. The sessionEntryPoint is static throughout the onboarding session and tracking should only fire on actual step navigation, not context changes.

Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/src/Internal/Admin/Settings/Payments.php:431-439
Timestamp: 2025-06-17T14:19:30.933Z
Learning: In plugins/woocommerce/src/Internal/Admin/Settings/Payments.php, the process_payment_provider_states() method intentionally filters out payment providers that don't have a _suggestion_id. This is by design to only track state changes for gateways from partner extensions, not core WooCommerce gateways or other installed gateways.

Learnt from: gigitux
PR: #58785
File: plugins/woocommerce/client/blocks/package.json:0-0
Timestamp: 2025-06-17T10:25:36.686Z
Learning: Do not suggest using cross-env in the WooCommerce repository as it's deprecated/archived and the team is working to remove it from blocks commands to reduce the dependency tree. Instead, inline environment variables like WP_EXPERIMENTAL_MODULES=true knip should work fine in supported environments.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:78-96
Timestamp: 2025-06-18T06:05:25.472Z
Learning: In WooCommerce mini cart implementation, the cart state is server-populated before JavaScript initialization, so wooStoreState.cart and wooStoreState.cart.totals will be available on first render without requiring null-safe guards.

Learnt from: mreishus
PR: #58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPayments/WooPaymentsServiceTest.php:360-373
Timestamp: 2025-06-25T15:39:25.166Z
Learning: Test mocks should accurately simulate the behavior of the functions they replace, including return value semantics. For WordPress functions like update_option, the mock should properly return false when the value hasn't changed and true when it has, to avoid masking logic errors in tests.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be initialized BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation:

const responsePromise = page.waitForResponse('**/api/endpoint');
await triggerAction();
await responsePromise;

This pattern prevents missing rapid responses and is the standard approach for reliable E2E tests.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be called BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation: const responsePromise = page.waitForResponse(...); await triggerAction(); await responsePromise;

plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (5)

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.

Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/woo-build.mdc:0-0
Timestamp: 2025-07-18T14:55:02.778Z
Learning: To watch for changes during development, use 'pnpm --filter=@woocommerce/plugin-woocommerce watch:build' to ensure experimental features are active.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx:43-50
Timestamp: 2025-06-18T07:56:06.961Z
Learning: In plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx, the user vladolaru prefers to keep the current setUpPlugin function signature with optional positional context parameter rather than refactoring to an options object or making context required.

plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/test/block.js (15)

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:78-96
Timestamp: 2025-06-18T06:05:25.472Z
Learning: In WooCommerce mini cart implementation, the cart state is server-populated before JavaScript initialization, so wooStoreState.cart and wooStoreState.cart.totals will be available on first render without requiring null-safe guards.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: mreishus
PR: #58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the shouldAnimate flag is expected to be false only on initial render and may remain true after the first edit; it does not need to be reset.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/components/cart-checkout/product-details/style.scss:21-26
Timestamp: 2025-06-13T15:24:45.923Z
Learning: In WooCommerce blocks, bold styling for .wc-block-components-product-details__name should be scoped only to the Cart block (.wc-block-cart__main); on the Checkout block, product names are not bold because prices are highlighted instead.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/components/stepper/index.tsx:57-67
Timestamp: 2025-06-20T13:08:44.017Z
Learning: For WooCommerce Payments onboarding step tracking in useEffect hooks, only include the active step in the dependency array, not the context object. The sessionEntryPoint is static throughout the onboarding session and tracking should only fire on actual step navigation, not context changes.

Learnt from: triple0t
PR: #59186
File: packages/js/email-editor/src/store/initial-state.ts:9-10
Timestamp: 2025-06-26T12:13:32.062Z
Learning: In WooCommerce email editor store initialization (packages/js/email-editor/src/store/initial-state.ts), the current_post_id and current_post_type from window.WooCommerceEmailEditor are required parameters that should cause explicit errors if missing, rather than using fallback values or optional chaining. The design preference is to fail fast when critical initialization data is unavailable.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPayments/WooPaymentsServiceTest.php:360-373
Timestamp: 2025-06-25T15:39:25.166Z
Learning: Test mocks should accurately simulate the behavior of the functions they replace, including return value semantics. For WordPress functions like update_option, the mock should properly return false when the value hasn't changed and true when it has, to avoid masking logic errors in tests.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be called BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation: const responsePromise = page.waitForResponse(...); await triggerAction(); await responsePromise;

plugins/woocommerce/client/blocks/assets/js/blocks/checkout/test/block.tsx (14)

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the shouldAnimate flag is expected to be false only on initial render and may remain true after the first edit; it does not need to be reset.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx:43-50
Timestamp: 2025-06-18T07:56:06.961Z
Learning: In plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx, the user vladolaru prefers to keep the current setUpPlugin function signature with optional positional context parameter rather than refactoring to an options object or making context required.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/components/stepper/index.tsx:57-67
Timestamp: 2025-06-20T13:08:44.017Z
Learning: For WooCommerce Payments onboarding step tracking in useEffect hooks, only include the active step in the dependency array, not the context object. The sessionEntryPoint is static throughout the onboarding session and tracking should only fire on actual step navigation, not context changes.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:78-96
Timestamp: 2025-06-18T06:05:25.472Z
Learning: In WooCommerce mini cart implementation, the cart state is server-populated before JavaScript initialization, so wooStoreState.cart and wooStoreState.cart.totals will be available on first render without requiring null-safe guards.

Learnt from: triple0t
PR: #59186
File: packages/js/email-editor/src/store/initial-state.ts:9-10
Timestamp: 2025-06-26T12:13:32.062Z
Learning: In WooCommerce email editor store initialization (packages/js/email-editor/src/store/initial-state.ts), the current_post_id and current_post_type from window.WooCommerceEmailEditor are required parameters that should cause explicit errors if missing, rather than using fallback values or optional chaining. The design preference is to fail fast when critical initialization data is unavailable.

Learnt from: gigitux
PR: #58785
File: plugins/woocommerce/client/blocks/package.json:0-0
Timestamp: 2025-06-17T10:25:36.686Z
Learning: Do not suggest using cross-env in the WooCommerce repository as it's deprecated/archived and the team is working to remove it from blocks commands to reduce the dependency tree. Instead, inline environment variables like WP_EXPERIMENTAL_MODULES=true knip should work fine in supported environments.

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be initialized BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation:

const responsePromise = page.waitForResponse('**/api/endpoint');
await triggerAction();
await responsePromise;

This pattern prevents missing rapid responses and is the standard approach for reliable E2E tests.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be called BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation: const responsePromise = page.waitForResponse(...); await triggerAction(); await responsePromise;

plugins/woocommerce/client/blocks/assets/js/base/context/hooks/cart/test/use-store-cart-coupons.tsx (12)

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx:43-50
Timestamp: 2025-06-18T07:56:06.961Z
Learning: In plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx, the user vladolaru prefers to keep the current setUpPlugin function signature with optional positional context parameter rather than refactoring to an options object or making context required.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/components/stepper/index.tsx:57-67
Timestamp: 2025-06-20T13:08:44.017Z
Learning: For WooCommerce Payments onboarding step tracking in useEffect hooks, only include the active step in the dependency array, not the context object. The sessionEntryPoint is static throughout the onboarding session and tracking should only fire on actual step navigation, not context changes.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/woo-build.mdc:0-0
Timestamp: 2025-07-18T14:55:02.778Z
Learning: To watch for changes during development, use 'pnpm --filter=@woocommerce/plugin-woocommerce watch:build' to ensure experimental features are active.

Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/code-quality.mdc:0-0
Timestamp: 2025-07-18T14:54:36.232Z
Learning: Applies to **/*.{php,js,jsx,ts,tsx} : Ensure code has unit or E2E tests where applicable

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPayments/WooPaymentsServiceTest.php:360-373
Timestamp: 2025-06-25T15:39:25.166Z
Learning: Test mocks should accurately simulate the behavior of the functions they replace, including return value semantics. For WordPress functions like update_option, the mock should properly return false when the value hasn't changed and true when it has, to avoid masking logic errors in tests.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be initialized BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation:

const responsePromise = page.waitForResponse('**/api/endpoint');
await triggerAction();
await responsePromise;

This pattern prevents missing rapid responses and is the standard approach for reliable E2E tests.

plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js (13)

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:78-96
Timestamp: 2025-06-18T06:05:25.472Z
Learning: In WooCommerce mini cart implementation, the cart state is server-populated before JavaScript initialization, so wooStoreState.cart and wooStoreState.cart.totals will be available on first render without requiring null-safe guards.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: mreishus
PR: #58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the shouldAnimate flag is expected to be false only on initial render and may remain true after the first edit; it does not need to be reset.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/components/cart-checkout/product-details/style.scss:21-26
Timestamp: 2025-06-13T15:24:45.923Z
Learning: In WooCommerce blocks, bold styling for .wc-block-components-product-details__name should be scoped only to the Cart block (.wc-block-cart__main); on the Checkout block, product names are not bold because prices are highlighted instead.

Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be called BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation: const responsePromise = page.waitForResponse(...); await triggerAction(); await responsePromise;

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/components/stepper/index.tsx:57-67
Timestamp: 2025-06-20T13:08:44.017Z
Learning: For WooCommerce Payments onboarding step tracking in useEffect hooks, only include the active step in the dependency array, not the context object. The sessionEntryPoint is static throughout the onboarding session and tracking should only fire on actual step navigation, not context changes.

🧬 Code Graph Analysis (6)
plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/test/payment-methods.js (2)
plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (1)
  • server (8-8)
plugins/woocommerce/client/blocks/assets/js/previews/cart.ts (1)
  • previewCart (35-599)
plugins/woocommerce/client/blocks/assets/js/blocks/stock-filter/test/block.tsx (1)
plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (1)
  • server (8-8)
plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/slots.js (4)
plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (1)
  • server (8-8)
plugins/woocommerce/client/blocks/assets/js/previews/cart.ts (1)
  • previewCart (35-599)
plugins/woocommerce/client/blocks/assets/js/data/cart/default-state.ts (1)
  • defaultCartState (55-106)
plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js (1)
  • CartBlock (40-72)
plugins/woocommerce/client/blocks/assets/js/data/payment/test/selectors.js (2)
plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (1)
  • server (8-8)
plugins/woocommerce/client/blocks/assets/js/previews/cart.ts (1)
  • previewCart (35-599)
plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/test/block.js (3)
plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (1)
  • server (8-8)
plugins/woocommerce/client/blocks/assets/js/data/cart/default-state.ts (1)
  • defaultCartState (55-106)
plugins/woocommerce/client/blocks/assets/js/previews/cart.ts (1)
  • previewCart (35-599)
plugins/woocommerce/client/blocks/assets/js/blocks/checkout/test/block.tsx (2)
plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (1)
  • server (8-8)
plugins/woocommerce/client/blocks/assets/js/previews/cart.ts (1)
  • previewCart (35-599)
⏰ 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). (10)
  • GitHub Check: Blocks e2e tests 10/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 10/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 10/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 10/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 10/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 10/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 10/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 10/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 10/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 10/10 - @woocommerce/plugin-woocommerce [e2e]
🔇 Additional comments (31)
plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/test/payment-methods.js (3)

8-8: LGTM - Clean MSW import

The import correctly uses the centralized MSW utilities from the test-utils package, providing a consistent testing infrastructure across the codebase.


128-133: Excellent MSW handler setup

The migration from fetchMock.mockResponse to MSW handlers is clean and maintains the same test behavior while providing better request interception. The handler correctly intercepts the cart endpoint and returns the expected mock data.


146-147: Correct cleanup delegation to global MSW setup

The removal of explicit cleanup is appropriate since the centralized MSW setup in plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js handles server.resetHandlers() in its afterEach hook.

plugins/woocommerce/client/blocks/assets/js/blocks/stock-filter/test/block.tsx (2)

10-19: Clean import reorganization and MSW integration

The addition of MSW server import and minor reorganization of testing-library imports maintains code clarity while integrating the new testing infrastructure.


227-227: Proper MSW cleanup implementation

The migration from fetchMock.resetMocks() to server.resetHandlers() correctly implements the MSW cleanup pattern, ensuring test isolation between test cases.

plugins/woocommerce/client/blocks/assets/js/data/payment/test/selectors.js (3)

19-19: Correct MSW utilities import

The import follows the established pattern for MSW integration across the test suite.


181-186: Proper MSW setup and cleanup in first test suite

The MSW handler setup correctly intercepts the cart endpoint and returns the expected mock data. The cleanup properly resets handlers to ensure test isolation.

Also applies to: 199-199


263-268: Consistent MSW pattern in second test suite

The MSW setup and cleanup in the second describe block follows the same clean pattern as the first, maintaining consistency across the test file.

Also applies to: 281-281

plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (1)

1-29: Excellent MSW setup foundation

This centralized MSW configuration file follows all best practices:

  • Proper lifecycle management: Server starts before all tests, resets handlers after each test, and closes after all tests
  • Appropriate configuration: Using 'bypass' for unhandled requests allows partial mocking while letting other requests pass through
  • Clean exports: Provides server, http, and HttpResponse utilities for test files
  • Test isolation: The afterEach handler reset ensures no cross-test contamination

This provides a solid foundation for the MSW migration across the entire test suite.

plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/slots.js (3)

9-9: Correct MSW utilities import

The import follows the established MSW pattern consistently with other test files.


61-61: Excellent MSW cleanup and test-specific handler setup

The cleanup pattern and the test-specific MSW handler that modifies the cart data demonstrate proper MSW usage. The handler correctly overrides the default setup to provide specific test data.

Also applies to: 65-77


80-84: Improved test assertions using UI verification

The shift from verifying fetch call counts to waiting for actual DOM content represents a better testing approach. This ensures the mocked data is properly rendered and the component behaves correctly.

plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/test/block.js (4)

16-16: LGTM: Clean MSW migration for imports

The import correctly brings in the necessary MSW utilities from the centralized test setup, replacing the previous jest-fetch-mock dependency.


41-55: Excellent MSW handler implementation

The mock functions correctly migrate from jest-fetch-mock to MSW:

  • Proper use of server.use() with http.get() handlers
  • Correct endpoint patterns with wildcards for flexibility
  • Appropriate JSON response formatting with HttpResponse.json()
  • Maintains existing mock data consistency

67-68: Proper MSW cleanup implementation

Using server.resetHandlers() is the correct way to reset MSW handlers between tests, ensuring proper test isolation.


82-86: Improved test assertions focusing on user experience

The migration from testing fetch calls to testing UI elements is excellent:

  • Uses waitFor() properly to handle async rendering
  • Tests actual user-visible elements (cart count labels, empty cart messages)
  • More meaningful assertions that verify the complete data flow from API to UI
  • Aligns with testing best practices of testing behavior rather than implementation

Also applies to: 96-100, 113-117, 149-153, 169-173, 195-199, 221-225, 235-239

plugins/woocommerce/client/blocks/assets/js/blocks/checkout/test/block.tsx (4)

15-15: Consistent MSW import pattern

The import correctly follows the established pattern for MSW migration across the codebase.


141-146: Well-documented MSW setup in beforeEach

The MSW handler setup is correct:

  • Proper use of server.use() with http.get()
  • Correct endpoint path and response format
  • Clear documentation comment explaining the purpose

289-294: Proper use of dynamic MSW handler overrides

The test-specific handler overrides are well-implemented:

  • Correctly uses server.use() to temporarily override default handlers
  • Provides appropriate cart data for specific test scenarios
  • Enables testing different cart states without cross-test contamination

Also applies to: 377-382


179-181: Improved test assertions with user-focused verification

The migration to UI-based assertions is excellent:

  • Tests meaningful user interface elements ("Place Order", "Edit shipping address")
  • Proper use of waitFor() for async operations
  • Verifies complete data flow from API to rendered components
  • More robust and maintainable than testing internal implementation details

Also applies to: 298-302, 386-390, 475-481, 512-514, 597-602

plugins/woocommerce/client/blocks/assets/js/base/context/hooks/cart/test/use-store-cart-coupons.tsx (5)

5-5: Consistent MSW import implementation

The import correctly follows the established pattern for MSW migration across the WooCommerce blocks test suite.


27-29: Proper MSW test isolation setup

The beforeEach cleanup correctly resets MSW handlers between tests with clear documentation, ensuring proper test isolation.


34-73: Excellent request capturing pattern with MSW

The request capturing approach is well-implemented:

  • Captures comprehensive request details (url, method, headers, body)
  • Uses proper async handling for request body parsing
  • Returns appropriate mock responses
  • More explicit and reliable than previous fetchMock call inspection

110-173: Robust multiple request handling

The approach for testing multiple API calls is well-structured:

  • Uses array to capture sequential requests properly
  • Comprehensive verification of both individual requests and total count
  • Clear separation between request capture and assertion logic
  • Thorough testing of coupon code variations

175-222: Comprehensive error handling test coverage

The error handling test is well-implemented:

  • Returns realistic HTTP 400 error with proper WooCommerce error structure
  • Verifies graceful error handling (returns false)
  • Ensures API calls are still attempted and captured
  • Tests resilience without throwing exceptions
plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js (6)

8-8: Consistent MSW import pattern

The import correctly follows the established pattern for MSW migration across the WooCommerce blocks test suite.


76-81: Proper MSW setup with clear documentation

The MSW handler setup correctly follows established patterns:

  • Uses proper server.use() with http.get() pattern
  • Returns appropriate mock data (previewCart)
  • Includes clear documentation comment

89-91: Correct MSW cleanup implementation

Using server.resetHandlers() is the proper way to ensure test isolation by resetting MSW handlers between tests.


171-175: Effective use of dynamic MSW handler overrides

The test-specific handler overrides are well-implemented:

  • Properly uses server.use() to override default handlers for specific tests
  • Provides appropriate cart data for different test scenarios (empty cart, custom currency)
  • Enables comprehensive testing of various cart states

Also applies to: 204-208


96-100: Excellent migration to user-focused test assertions

The test assertions have been properly migrated to focus on user experience:

  • Uses waitFor() to handle async rendering appropriately
  • Tests meaningful UI elements (buttons, text content, form inputs)
  • Verifies complete data flow from API responses to rendered components
  • More maintainable and reliable than testing internal fetch mechanics
  • Covers various scenarios including currency formatting and quantity updates

Also applies to: 113-115, 122-124, 131-133, 144-146, 164-166, 178-180, 212-216, 235-241, 248-254, 284-288


159-161: Good catch on missing attribute

Adding the checkoutPageId: 0 attribute ensures consistency with other similar tests and prevents potential issues with missing required props.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a39c04a and 9029258.

📒 Files selected for processing (5)
  • plugins/woocommerce/client/blocks/assets/js/base/context/hooks/test/use-query-state.jsx (0 hunks)
  • plugins/woocommerce/client/blocks/assets/js/base/utils/test/errors.js (2 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js (8 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-specifications/test/block.ts (2 hunks)
  • plugins/woocommerce/client/legacy/js/frontend/test/address-autocomplete.js (1 hunks)
📓 Path-based instructions (2)
**/*.{php,js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/code-quality.mdc)

**/*.{php,js,jsx,ts,tsx}: Guard against unexpected inputs
Sanitize and validate any potentially dangerous inputs
Ensure code is backwards compatible
Write code that is readable and intuitive
Ensure code has unit or E2E tests where applicable

Files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-specifications/test/block.ts
  • plugins/woocommerce/client/blocks/assets/js/base/utils/test/errors.js
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js
**/*.{php,js,ts,jsx,tsx}

⚙️ CodeRabbit Configuration File

**/*.{php,js,ts,jsx,tsx}: Don't trust that extension developers will follow the best practices, make sure the code:

  • Guards against unexpected inputs.
  • Sanitizes and validates any potentially dangerous inputs.
  • Is backwards compatible.
  • Is readable and intuitive.
  • Has unit or E2E tests where applicable.

Files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-specifications/test/block.ts
  • plugins/woocommerce/client/blocks/assets/js/base/utils/test/errors.js
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/generate-pr-description.mdc:0-0
Timestamp: 2025-07-21T05:22:46.417Z
Learning: Provide clear, step-by-step instructions for how to test the changes in the PR description.
Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/code-quality.mdc:0-0
Timestamp: 2025-07-18T14:54:36.232Z
Learning: Applies to **/*.{php,js,jsx,ts,tsx} : Ensure code has unit or E2E tests where applicable
plugins/woocommerce/client/blocks/assets/js/blocks/product-specifications/test/block.ts (11)

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the shouldAnimate flag is expected to be false only on initial render and may remain true after the first edit; it does not need to be reset.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: gigitux
PR: #58902
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-specifications/edit.tsx:205-206
Timestamp: 2025-06-17T12:40:54.118Z
Learning: In WordPress blocks, when there's a styling mismatch between editor and frontend, check if the PHP renderer (like in ProductSpecifications.php) adds specific classes to the output. If so, add those same classes to the useBlockProps className in the editor component (like in edit.tsx) to ensure consistent styling. For example, adding wp-block-table class to both frontend and editor ensures core table styles and theme customizations apply consistently.

Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/generate-pr-description.mdc:0-0
Timestamp: 2025-07-21T05:22:46.417Z
Learning: Provide clear, step-by-step instructions for how to test the changes in the PR description.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: Aljullu
PR: #58809
File: plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php:222-225
Timestamp: 2025-06-13T17:11:13.732Z
Learning: In plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php, the team intentionally relies on toggling the disabled CSS class (via data-wp-class--disabled) instead of binding the disabled attribute, to mirror the behavior of the classic WooCommerce template.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/components/cart-checkout/product-details/style.scss:21-26
Timestamp: 2025-06-13T15:24:45.923Z
Learning: In WooCommerce blocks, bold styling for .wc-block-components-product-details__name should be scoped only to the Cart block (.wc-block-cart__main); on the Checkout block, product names are not bold because prices are highlighted instead.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be called BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation: const responsePromise = page.waitForResponse(...); await triggerAction(); await responsePromise;

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be initialized BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation:

const responsePromise = page.waitForResponse('**/api/endpoint');
await triggerAction();
await responsePromise;

This pattern prevents missing rapid responses and is the standard approach for reliable E2E tests.

plugins/woocommerce/client/blocks/assets/js/base/utils/test/errors.js (5)

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: lysyjan
PR: #59632
File: packages/js/email-editor/src/layouts/flex-email.tsx:116-122
Timestamp: 2025-07-14T10:41:46.200Z
Learning: In WooCommerce projects, formatting suggestions should respect the project's Prettier configuration and linting rules. Changes that would break the lint job should be avoided, even if they appear to improve readability.

Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx:43-50
Timestamp: 2025-06-18T07:56:06.961Z
Learning: In plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx, the user vladolaru prefers to keep the current setUpPlugin function signature with optional positional context parameter rather than refactoring to an options object or making context required.

Learnt from: triple0t
PR: #59186
File: packages/js/email-editor/src/store/initial-state.ts:9-10
Timestamp: 2025-06-26T12:13:32.062Z
Learning: In WooCommerce email editor store initialization (packages/js/email-editor/src/store/initial-state.ts), the current_post_id and current_post_type from window.WooCommerceEmailEditor are required parameters that should cause explicit errors if missing, rather than using fallback values or optional chaining. The design preference is to fail fast when critical initialization data is unavailable.

plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js (15)

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:78-96
Timestamp: 2025-06-18T06:05:25.472Z
Learning: In WooCommerce mini cart implementation, the cart state is server-populated before JavaScript initialization, so wooStoreState.cart and wooStoreState.cart.totals will be available on first render without requiring null-safe guards.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: mreishus
PR: #58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/components/cart-checkout/product-details/style.scss:21-26
Timestamp: 2025-06-13T15:24:45.923Z
Learning: In WooCommerce blocks, bold styling for .wc-block-components-product-details__name should be scoped only to the Cart block (.wc-block-cart__main); on the Checkout block, product names are not bold because prices are highlighted instead.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the shouldAnimate flag is expected to be false only on initial render and may remain true after the first edit; it does not need to be reset.

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: samueljseay
PR: #59142
File: plugins/woocommerce/src/Blocks/BlockTypes/MiniCart.php:594-602
Timestamp: 2025-06-25T06:51:41.381Z
Learning: WooCommerce block templates have a predictable structure where each block has one top-level div with wp-block-woocommerce- class containing arbitrary nested content that should be preserved.

Learnt from: gigitux
PR: #58785
File: plugins/woocommerce/client/blocks/package.json:0-0
Timestamp: 2025-06-17T10:25:36.686Z
Learning: Do not suggest using cross-env in the WooCommerce repository as it's deprecated/archived and the team is working to remove it from blocks commands to reduce the dependency tree. Instead, inline environment variables like WP_EXPERIMENTAL_MODULES=true knip should work fine in supported environments.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/components/stepper/index.tsx:57-67
Timestamp: 2025-06-20T13:08:44.017Z
Learning: For WooCommerce Payments onboarding step tracking in useEffect hooks, only include the active step in the dependency array, not the context object. The sessionEntryPoint is static throughout the onboarding session and tracking should only fire on actual step navigation, not context changes.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be called BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation: const responsePromise = page.waitForResponse(...); await triggerAction(); await responsePromise;

🧬 Code Graph Analysis (1)
plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js (3)
plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (1)
  • server (8-8)
plugins/woocommerce/client/blocks/assets/js/previews/cart.ts (1)
  • previewCart (35-599)
plugins/woocommerce/client/blocks/assets/js/data/cart/default-state.ts (1)
  • defaultCartState (55-106)
🪛 Biome (1.9.4)
plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js

[error] 223-223: Don't focus the test.

The 'only' method is often used for debugging or during implementation. It should be removed before deploying to production.
Consider removing 'only' to ensure all tests are executed.
Unsafe fix: Remove focus from test.

(lint/suspicious/noFocusedTests)

💤 Files with no reviewable changes (1)
  • plugins/woocommerce/client/blocks/assets/js/base/context/hooks/test/use-query-state.jsx
✅ Files skipped from review due to trivial changes (1)
  • plugins/woocommerce/client/legacy/js/frontend/test/address-autocomplete.js
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{php,js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/code-quality.mdc)

**/*.{php,js,jsx,ts,tsx}: Guard against unexpected inputs
Sanitize and validate any potentially dangerous inputs
Ensure code is backwards compatible
Write code that is readable and intuitive
Ensure code has unit or E2E tests where applicable

Files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-specifications/test/block.ts
  • plugins/woocommerce/client/blocks/assets/js/base/utils/test/errors.js
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js
**/*.{php,js,ts,jsx,tsx}

⚙️ CodeRabbit Configuration File

**/*.{php,js,ts,jsx,tsx}: Don't trust that extension developers will follow the best practices, make sure the code:

  • Guards against unexpected inputs.
  • Sanitizes and validates any potentially dangerous inputs.
  • Is backwards compatible.
  • Is readable and intuitive.
  • Has unit or E2E tests where applicable.

Files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-specifications/test/block.ts
  • plugins/woocommerce/client/blocks/assets/js/base/utils/test/errors.js
  • plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/generate-pr-description.mdc:0-0
Timestamp: 2025-07-21T05:22:46.417Z
Learning: Provide clear, step-by-step instructions for how to test the changes in the PR description.
Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/code-quality.mdc:0-0
Timestamp: 2025-07-18T14:54:36.232Z
Learning: Applies to **/*.{php,js,jsx,ts,tsx} : Ensure code has unit or E2E tests where applicable
plugins/woocommerce/client/blocks/assets/js/blocks/product-specifications/test/block.ts (11)

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the shouldAnimate flag is expected to be false only on initial render and may remain true after the first edit; it does not need to be reset.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: gigitux
PR: #58902
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-specifications/edit.tsx:205-206
Timestamp: 2025-06-17T12:40:54.118Z
Learning: In WordPress blocks, when there's a styling mismatch between editor and frontend, check if the PHP renderer (like in ProductSpecifications.php) adds specific classes to the output. If so, add those same classes to the useBlockProps className in the editor component (like in edit.tsx) to ensure consistent styling. For example, adding wp-block-table class to both frontend and editor ensures core table styles and theme customizations apply consistently.

Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/generate-pr-description.mdc:0-0
Timestamp: 2025-07-21T05:22:46.417Z
Learning: Provide clear, step-by-step instructions for how to test the changes in the PR description.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: Aljullu
PR: #58809
File: plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php:222-225
Timestamp: 2025-06-13T17:11:13.732Z
Learning: In plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php, the team intentionally relies on toggling the disabled CSS class (via data-wp-class--disabled) instead of binding the disabled attribute, to mirror the behavior of the classic WooCommerce template.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/components/cart-checkout/product-details/style.scss:21-26
Timestamp: 2025-06-13T15:24:45.923Z
Learning: In WooCommerce blocks, bold styling for .wc-block-components-product-details__name should be scoped only to the Cart block (.wc-block-cart__main); on the Checkout block, product names are not bold because prices are highlighted instead.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be called BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation: const responsePromise = page.waitForResponse(...); await triggerAction(); await responsePromise;

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be initialized BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation:

const responsePromise = page.waitForResponse('**/api/endpoint');
await triggerAction();
await responsePromise;

This pattern prevents missing rapid responses and is the standard approach for reliable E2E tests.

plugins/woocommerce/client/blocks/assets/js/base/utils/test/errors.js (5)

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: lysyjan
PR: #59632
File: packages/js/email-editor/src/layouts/flex-email.tsx:116-122
Timestamp: 2025-07-14T10:41:46.200Z
Learning: In WooCommerce projects, formatting suggestions should respect the project's Prettier configuration and linting rules. Changes that would break the lint job should be avoided, even if they appear to improve readability.

Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx:43-50
Timestamp: 2025-06-18T07:56:06.961Z
Learning: In plugins/woocommerce/client/admin/client/settings-payments/components/other-payment-gateways/other-payment-gateways.tsx, the user vladolaru prefers to keep the current setUpPlugin function signature with optional positional context parameter rather than refactoring to an options object or making context required.

Learnt from: triple0t
PR: #59186
File: packages/js/email-editor/src/store/initial-state.ts:9-10
Timestamp: 2025-06-26T12:13:32.062Z
Learning: In WooCommerce email editor store initialization (packages/js/email-editor/src/store/initial-state.ts), the current_post_id and current_post_type from window.WooCommerceEmailEditor are required parameters that should cause explicit errors if missing, rather than using fallback values or optional chaining. The design preference is to fail fast when critical initialization data is unavailable.

plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js (15)

Learnt from: samueljseay
PR: #59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; } - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:78-96
Timestamp: 2025-06-18T06:05:25.472Z
Learning: In WooCommerce mini cart implementation, the cart state is server-populated before JavaScript initialization, so wooStoreState.cart and wooStoreState.cart.totals will be available on first render without requiring null-safe guards.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.

Learnt from: mreishus
PR: #58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().

Learnt from: samueljseay
PR: #58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Learnt from: gigitux
PR: #59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.508Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (as) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using Partial<> wrappers, and export the unified type to help third-party extenders. For example: type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>.

Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/base/components/cart-checkout/product-details/style.scss:21-26
Timestamp: 2025-06-13T15:24:45.923Z
Learning: In WooCommerce blocks, bold styling for .wc-block-components-product-details__name should be scoped only to the Cart block (.wc-block-cart__main); on the Checkout block, product names are not bold because prices are highlighted instead.

Learnt from: ralucaStan
PR: #58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the shouldAnimate flag is expected to be false only on initial render and may remain true after the first edit; it does not need to be reset.

Learnt from: gigitux
PR: #58846
File: plugins/woocommerce/client/blocks/tests/e2e/tests/all-products/all-products.block_theme.spec.ts:41-52
Timestamp: 2025-06-16T09:20:22.981Z
Learning: In WooCommerce E2E tests, the database is reset to the initial state for each test, so there's no need to manually restore global template changes (like clearing the header template) as the test infrastructure handles cleanup automatically.

Learnt from: samueljseay
PR: #59142
File: plugins/woocommerce/src/Blocks/BlockTypes/MiniCart.php:594-602
Timestamp: 2025-06-25T06:51:41.381Z
Learning: WooCommerce block templates have a predictable structure where each block has one top-level div with wp-block-woocommerce- class containing arbitrary nested content that should be preserved.

Learnt from: gigitux
PR: #58785
File: plugins/woocommerce/client/blocks/package.json:0-0
Timestamp: 2025-06-17T10:25:36.686Z
Learning: Do not suggest using cross-env in the WooCommerce repository as it's deprecated/archived and the team is working to remove it from blocks commands to reduce the dependency tree. Instead, inline environment variables like WP_EXPERIMENTAL_MODULES=true knip should work fine in supported environments.

Learnt from: vladolaru
PR: #59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Learnt from: vladolaru
PR: #58784
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/components/stepper/index.tsx:57-67
Timestamp: 2025-06-20T13:08:44.017Z
Learning: For WooCommerce Payments onboarding step tracking in useEffect hooks, only include the active step in the dependency array, not the context object. The sessionEntryPoint is static throughout the onboarding session and tracking should only fire on actual step navigation, not context changes.

Learnt from: gigitux
PR: #58899
File: plugins/woocommerce/tests/e2e-pw/tests/customize-store/assembler/font-picker.spec.js:250-265
Timestamp: 2025-06-17T08:14:15.688Z
Learning: In Playwright E2E tests, page.waitForResponse() should be called BEFORE the triggering action (like clicks) to ensure the response is not missed. This is the recommended pattern per Playwright documentation: const responsePromise = page.waitForResponse(...); await triggerAction(); await responsePromise;

🧬 Code Graph Analysis (1)
plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js (3)
plugins/woocommerce/client/blocks/tests/js/config/msw-setup.js (1)
  • server (8-8)
plugins/woocommerce/client/blocks/assets/js/previews/cart.ts (1)
  • previewCart (35-599)
plugins/woocommerce/client/blocks/assets/js/data/cart/default-state.ts (1)
  • defaultCartState (55-106)
🪛 Biome (1.9.4)
plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js

[error] 223-223: Don't focus the test.

The 'only' method is often used for debugging or during implementation. It should be removed before deploying to production.
Consider removing 'only' to ensure all tests are executed.
Unsafe fix: Remove focus from test.

(lint/suspicious/noFocusedTests)

⏰ 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). (53)
  • GitHub Check: JavaScript - @woocommerce/explat [unit]
  • GitHub Check: PHPStan: PHP 7.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: PHPStan: PHP 8.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: JavaScript - @woocommerce/monorepo-utils [unit]
  • GitHub Check: Lint - @woocommerce/integrate-plugin
  • GitHub Check: JavaScript - @woocommerce/explat [unit]
  • GitHub Check: PHPStan: PHP 7.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: PHPStan: PHP 8.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: JavaScript - @woocommerce/monorepo-utils [unit]
  • GitHub Check: Lint - @woocommerce/integrate-plugin
  • GitHub Check: JavaScript - @woocommerce/explat [unit]
  • GitHub Check: PHPStan: PHP 7.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: PHPStan: PHP 8.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: JavaScript - @woocommerce/monorepo-utils [unit]
  • GitHub Check: Lint - @woocommerce/integrate-plugin
  • GitHub Check: JavaScript - @woocommerce/explat [unit]
  • GitHub Check: PHPStan: PHP 7.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: PHPStan: PHP 8.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: JavaScript - @woocommerce/monorepo-utils [unit]
  • GitHub Check: Lint - @woocommerce/integrate-plugin
  • GitHub Check: JavaScript - @woocommerce/explat [unit]
  • GitHub Check: PHPStan: PHP 7.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: PHPStan: PHP 8.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: JavaScript - @woocommerce/monorepo-utils [unit]
  • GitHub Check: Lint - @woocommerce/integrate-plugin
  • GitHub Check: JavaScript - @woocommerce/explat [unit]
  • GitHub Check: PHPStan: PHP 7.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: PHPStan: PHP 8.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: JavaScript - @woocommerce/monorepo-utils [unit]
  • GitHub Check: Lint - @woocommerce/integrate-plugin
  • GitHub Check: JavaScript - @woocommerce/explat [unit]
  • GitHub Check: PHPStan: PHP 7.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: PHPStan: PHP 8.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: JavaScript - @woocommerce/monorepo-utils [unit]
  • GitHub Check: Lint - @woocommerce/integrate-plugin
  • GitHub Check: JavaScript - @woocommerce/explat [unit]
  • GitHub Check: PHPStan: PHP 7.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: PHPStan: PHP 8.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: JavaScript - @woocommerce/monorepo-utils [unit]
  • GitHub Check: Lint - @woocommerce/integrate-plugin
  • GitHub Check: JavaScript - @woocommerce/explat [unit]
  • GitHub Check: JavaScript - @woocommerce/customer-effort-score [unit]
  • GitHub Check: PHPStan: PHP 7.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: PHPStan: PHP 8.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: JavaScript - @woocommerce/monorepo-utils [unit]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/blueprint [unit:php]
  • GitHub Check: Lint - @woocommerce/integrate-plugin
  • GitHub Check: JavaScript - @woocommerce/explat [unit]
  • GitHub Check: JavaScript - @woocommerce/customer-effort-score [unit]
  • GitHub Check: PHPStan: PHP 7.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: PHPStan: PHP 8.4 - @woocommerce/email-editor-config [unit]
  • GitHub Check: JavaScript - @woocommerce/monorepo-utils [unit]
  • GitHub Check: PHP: 8.1 WP: latest [WP latest] - @woocommerce/blueprint [unit:php]
🔇 Additional comments (14)
plugins/woocommerce/client/blocks/assets/js/base/utils/test/errors.js (2)

24-26: LGTM! Improved code formatting.

The multi-line formatting of the Response constructor parameters improves readability and follows modern JavaScript conventions.


44-44: LGTM! More precise error message assertion.

The specific error message expectation improves test reliability by validating the exact JSON parsing error format, making the test more deterministic and robust.

plugins/woocommerce/client/blocks/assets/js/blocks/product-specifications/test/block.ts (4)

6-6: Good addition of waitFor import for async test improvements.

The addition of waitFor to the Testing Library imports aligns with the broader MSW migration and improves test reliability by enabling proper asynchronous assertions.


33-37: Excellent improvement to test reliability with asynchronous waiting.

The addition of waitFor with toBeVisible() assertion ensures the display settings button is fully rendered and visible before proceeding with test interactions. This prevents race conditions and aligns with the broader MSW migration improvements across WooCommerce block tests.


35-35: Minor consistency improvement in regex patterns.

The change from uppercase to lowercase in the regex patterns (/display settings/i) maintains functionality while improving consistency. The case-insensitive flag ensures the tests continue to work regardless of the actual button text casing.

Also applies to: 40-40


33-42: Well-executed test reliability improvements.

The changes in this file successfully enhance test stability by properly handling asynchronous UI interactions. The implementation follows Testing Library best practices and aligns perfectly with the broader MSW migration effort described in the PR objectives. The test coverage and functionality remain intact while gaining improved reliability.

plugins/woocommerce/client/blocks/assets/js/blocks/cart/test/block.js (8)

8-8: LGTM: Correct MSW imports for the migration.

The import statement properly brings in the necessary MSW utilities to replace jest-fetch-mock.


34-37: LGTM: Good addition of console spies for enhanced test validation.

These imports enable proper assertion of React warnings and errors, improving test robustness.


80-85: LGTM: Proper MSW request handler setup.

The MSW handler correctly replaces the previous fetchMock setup with the standard server.use() pattern and appropriate response format.


94-94: LGTM: Correct MSW handler cleanup.

Using server.resetHandlers() properly ensures test isolation by cleaning up custom handlers between tests.


100-104: LGTM: Proper asynchronous testing with waitFor.

The consistent use of waitFor() correctly handles the asynchronous nature of MSW request interception and component rendering. Testing for visible user elements is the right approach.

Also applies to: 117-119, 126-128, 135-137, 148-150, 168-170, 182-184, 216-220, 238-244, 251-257, 287-291


164-164: LGTM: Good addition of missing attribute.

Adding the checkoutPageId: 0 attribute ensures the test props are complete and consistent with the component's expected interface.


189-212: LGTM: Excellent example of test-specific MSW handler customization.

The test correctly demonstrates how to override the default handler with custom cart data for specific test scenarios. The currency formatting test case is well-structured.


297-308: LGTM: Consistent console error validation.

Adding console error assertions for the findDOMNode deprecation warning maintains consistency with other tests and improves test robustness.

Copy link
Member

@dinhtungdu dinhtungdu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some failing tests that I can reproduce locally, but this is looking good already.

I can see some duplication in setting up the test and improvement for error handling, but I think we should address them in follow-up PRs. This is already a big one.

Here is the suggestion by Claude Code


⏺ Here are comprehensive examples for creating MSW test utilities to reduce code duplication:

  1. Request Capture Utilities

  Create: tests/js/config/msw-helpers.js

  /**
   * Creates a request capture utility for MSW tests
   * @param {Object} responseOverride - Custom response data
   * @returns {Object} Handler and getter for captured request
   */
  export const createRequestCapture = (responseOverride = {}) => {
      let capturedRequest = null;

      const handler = async ({ request }) => {
          const headers = {};
          request.headers.forEach((value, key) => {
              headers[key] = value;
          });

          capturedRequest = {
              url: request.url,
              method: request.method,
              headers,
              body: await request.text()
          };

          const defaultResponse = {
              responses: [{ status: 200, body: {} }]
          };

          return HttpResponse.json({
              ...defaultResponse,
              ...responseOverride
          });
      };

      return {
          handler,
          getCaptured: () => capturedRequest,
          reset: () => { capturedRequest = null; }
      };
  };

  /**
   * Creates a multi-request capture utility
   * @param {Object} responseOverride - Custom response data
   * @returns {Object} Handler and getter for all captured requests
   */
  export const createMultiRequestCapture = (responseOverride = {}) => {
      const capturedRequests = [];

      const handler = async ({ request }) => {
          const headers = {};
          request.headers.forEach((value, key) => {
              headers[key] = value;
          });

          const requestData = {
              url: request.url,
              method: request.method,
              headers,
              body: await request.text(),
              timestamp: Date.now()
          };

          capturedRequests.push(requestData);

          const defaultResponse = {
              responses: [{ status: 200, body: {} }]
          };

          return HttpResponse.json({
              ...defaultResponse,
              ...responseOverride
          });
      };

      return {
          handler,
          getCaptured: () => capturedRequests,
          getLatest: () => capturedRequests[capturedRequests.length - 1],
          getCount: () => capturedRequests.length,
          reset: () => { capturedRequests.length = 0; }
      };
  };

  2. WooCommerce-Specific Response Factories

  Create: tests/js/config/msw-factories.js

  import { HttpResponse } from 'msw';

  /**
   * Creates a WooCommerce batch response
   */
  export const createBatchResponse = (responses = []) => {
      const defaultResponses = responses.length ? responses : [
          { status: 200, body: {} }
      ];

      return HttpResponse.json({
          responses: defaultResponses
      });
  };

  /**
   * Creates a WooCommerce cart response
   */
  export const createCartResponse = (overrides = {}) => {
      const defaultCart = {
          items: [],
          coupons: [],
          totals: {
              total_price: '0',
              total_discount: '0'
          },
          needs_shipping: false,
          shipping_address: {},
          billing_address: {}
      };

      return HttpResponse.json({
          ...defaultCart,
          ...overrides
      });
  };

  /**
   * Creates WooCommerce error responses
   */
  export const createWooCommerceError = (code, message, status = 400, details = {}) => {
      return HttpResponse.json({
          code,
          message,
          data: {
              status,
              details
          }
      }, { status });
  };

  /**
   * Common WooCommerce error types
   */
  export const WooCommerceErrors = {
      COUPON_NOT_FOUND: (couponCode) => createWooCommerceError(
          'woocommerce_rest_cart_coupon_error',
          `Coupon "${couponCode}" does not exist!`,
          400,
          { cart: `Coupon "${couponCode}" does not exist!` }
      ),

      COUPON_EXPIRED: (couponCode) => createWooCommerceError(
          'woocommerce_rest_cart_coupon_expired',
          `This coupon has expired`,
          400,
          { cart: 'This coupon has expired' }
      ),

      INVALID_COUPON_CODE: () => createWooCommerceError(
          'woocommerce_rest_invalid_coupon_code',
          'Please enter a valid coupon code',
          400
      ),

      NETWORK_ERROR: () => HttpResponse.error(),

      SERVER_ERROR: (message = 'Internal server error') =>
          HttpResponse.json({ message }, { status: 500 }),

      TIMEOUT: () => HttpResponse.json({}, { status: 408 })
  };

  3. High-Level Test Utilities

  Create: tests/js/config/msw-test-utils.js

  import { server, http } from '@woocommerce/test-utils/msw';
  import { createRequestCapture, createMultiRequestCapture } from './msw-helpers';
  import { createBatchResponse, WooCommerceErrors } from './msw-factories';

  /**
   * Mock a successful coupon application
   */
  export const mockSuccessfulCouponApplication = (couponCode, cartOverrides = {}) => {
      const capture = createRequestCapture({
          responses: [{
              status: 200,
              body: {
                  items: [],
                  coupons: [{
                      code: couponCode,
                      discount_type: 'fixed_cart'
                  }],
                  totals: {
                      total_price: '4500',
                      total_discount: '500'
                  },
                  ...cartOverrides
              }
          }]
      });

      server.use(
          http.post('/wc/store/v1/batch', capture.handler)
      );

      return capture;
  };

  /**
   * Mock a failed coupon application
   */
  export const mockFailedCouponApplication = (couponCode, errorType = 'COUPON_NOT_FOUND') => {
      const capture = createRequestCapture();

      server.use(
          http.post('/wc/store/v1/batch', ({ request }) => {
              capture.handler({ request }); // Still capture the request
              return WooCommerceErrors[errorType](couponCode);
          })
      );

      return capture;
  };

  /**
   * Mock multiple coupon applications
   */
  export const mockMultipleCouponApplications = (responses = []) => {
      const capture = createMultiRequestCapture();

      const defaultResponse = {
          responses: [{ status: 200, body: {} }]
      };

      let responseIndex = 0;

      server.use(
          http.post('/wc/store/v1/batch', async ({ request }) => {
              await capture.handler({ request });

              const response = responses[responseIndex] || defaultResponse;
              responseIndex++;

              return HttpResponse.json(response);
          })
      );

      return capture;
  };

  /**
   * Mock cart API with various scenarios
   */
  export const mockCartAPI = {
      empty: () => {
          server.use(
              http.get('/wc/store/v1/cart', () =>
                  createCartResponse()
              )
          );
      },

      withItems: (items) => {
          server.use(
              http.get('/wc/store/v1/cart', () =>
                  createCartResponse({ items })
              )
          );
      },

      withCoupons: (coupons) => {
          server.use(
              http.get('/wc/store/v1/cart', () =>
                  createCartResponse({ coupons })
              )
          );
      }
  };

  /**
   * Assertion helpers for captured requests
   */
  export const assertRequest = {
      wasMade: (capture, expectedPath) => {
          const captured = capture.getCaptured();
          expect(captured).not.toBeNull();
          expect(captured.url).toContain(expectedPath);
      },

      hasMethod: (capture, method) => {
          const captured = capture.getCaptured();
          expect(captured.method).toBe(method);
      },

      hasHeader: (capture, headerName, expectedValue) => {
          const captured = capture.getCaptured();
          expect(captured.headers[headerName]).toContain(expectedValue);
      },

      hasBodyContent: (capture, content) => {
          const captured = capture.getCaptured();
          expect(captured.body).toContain(content);
      },

      hasCouponCode: (capture, couponCode) => {
          const captured = capture.getCaptured();
          const parsedBody = JSON.parse(captured.body);
          expect(parsedBody.requests[0].data.code).toBe(couponCode);
      }
  };

  4. Usage Examples in Tests

  After creating these utilities, the original test becomes much cleaner:

  Before (original verbose approach):
  it('calls the correct API endpoint when applying a coupon', async () => {
      // Track the request details
      let capturedRequest: any = null;

      // Mock a successful response using MSW
      server.use(
          http.post(
              '/wc/store/v1/batch',
              async ({ request }: { request: Request }) => {
                  capturedRequest = {
                      url: request.url,
                      method: request.method,
                      contentType: request.headers.get('content-type'),
                      body: await request.text(),
                  };

                  return HttpResponse.json({
                      responses: [{
                          status: 200,
                          body: {
                              items: [],
                              coupons: [{
                                  code: 'TEST5',
                                  discount_type: 'fixed_cart',
                              }],
                              totals: {
                                  total_price: '4500',
                                  total_discount: '500',
                              },
                              needs_shipping: false,
                              shipping_address: {},
                              billing_address: {},
                          },
                      }],
                  });
              }
          )
      );

      const { result } = renderHook(() =>
          useStoreCartCoupons('wc/checkout')
      );

      await act(async () => {
          await result.current.applyCoupon('TEST5');
      });

      // Verify the request was made
      expect(capturedRequest).not.toBeNull();
      expect(capturedRequest.url).toContain('/wc/store/v1/batch');
      expect(capturedRequest.method).toBe('POST');
      expect(capturedRequest.contentType).toContain('application/json');
      expect(capturedRequest.body).toContain('apply-coupon');

      // Verify the request body contains the coupon code
      const parsedBody = JSON.parse(capturedRequest.body);
      expect(parsedBody.requests).toHaveLength(1);
      expect(parsedBody.requests[0].path).toBe('/wc/store/v1/cart/apply-coupon');
      expect(parsedBody.requests[0].data.code).toBe('TEST5');
  });

  After (using utilities):
  it('calls the correct API endpoint when applying a coupon', async () => {
      const capture = mockSuccessfulCouponApplication('TEST5');

      const { result } = renderHook(() =>
          useStoreCartCoupons('wc/checkout')
      );

      await act(async () => {
          await result.current.applyCoupon('TEST5');
      });

      // Clean assertions using helpers
      assertRequest.wasMade(capture, '/wc/store/v1/batch');
      assertRequest.hasMethod(capture, 'POST');
      assertRequest.hasHeader(capture, 'content-type', 'application/json');
      assertRequest.hasBodyContent(capture, 'apply-coupon');
      assertRequest.hasCouponCode(capture, 'TEST5');
  });

  Error handling test becomes:
  it('handles API errors correctly', async () => {
      const capture = mockFailedCouponApplication('INVALID', 'COUPON_NOT_FOUND');

      const { result } = renderHook(() =>
          useStoreCartCoupons('wc/checkout')
      );

      await act(async () => {
          await result.current.applyCoupon('INVALID');
      });

      assertRequest.wasMade(capture, '/wc/store/v1/batch');
      assertRequest.hasCouponCode(capture, 'INVALID');
  });

  5. TypeScript Interfaces

  Create: tests/js/config/msw-types.ts

  export interface CapturedRequest {
      url: string;
      method: string;
      headers: Record<string, string>;
      body: string;
      timestamp?: number;
  }

  export interface WooCommerceCartItem {
      id: number;
      name: string;
      quantity: number;
      prices: {
          price: string;
          regular_price: string;
      };
  }

  export interface WooCommerceCoupon {
      code: string;
      discount_type: string;
      amount: string;
  }

  export interface WooCommerceCart {
      items: WooCommerceCartItem[];
      coupons: WooCommerceCoupon[];
      totals: {
          total_price: string;
          total_discount: string;
      };
      needs_shipping: boolean;
      shipping_address: Record<string, any>;
      billing_address: Record<string, any>;
  }

code: 'TEST5',
discount_type: 'fixed_cart',
// Track the request details
let capturedRequest: any = null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future, we should type this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added types otherwise ESlint complains: 05cd499

@gigitux
Copy link
Contributor Author

gigitux commented Jul 24, 2025

All unit test are green now! Thanks @ralucaStan! The PR is ready to be reviewed again!

Copy link
Member

@dinhtungdu dinhtungdu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for updating the tests! This is LGTM now.

@gigitux gigitux merged commit c53f822 into trunk Jul 25, 2025
239 of 242 checks passed
@gigitux gigitux deleted the add/msw-package branch July 25, 2025 07:41
@github-actions github-actions bot added this to the 10.2.0 milestone Jul 25, 2025
@kalessil
Copy link
Contributor

Many thanks for the proper migration of the mocking library here @gigitux!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
focus: monorepo infrastructure Issues and PRs related to monorepo tooling. plugin: woocommerce Issues related to the WooCommerce Core plugin.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants