Skip to content

Conversation

@mgascam
Copy link
Contributor

@mgascam mgascam commented Dec 2, 2025

Summary

This PR migrates the QIT E2E tests infrastructure to use Test Packages, the recommended approach for QIT. This replaces the previous custom E2E setup and adds comprehensive shopper test coverage.

Key changes:

  • Migrate existing shopper checkout specs to test packages structure
  • Add new shopper test specs for multi-currency, saved cards, payment methods, and alternative payment methods
  • Remove legacy custom E2E infrastructure (tests/qit/e2e/, qit.yml, e2e-runner.sh)
  • Add QIT test package configuration (qit.json, qit-test.json)
  • Clean up dead code in test utilities
  • Fix flaky test in WC Blocks checkout (save payment method checkbox race condition)
  • Add automatic re-authentication for expired sessions in protected pages
  • Update README documentation

Test Coverage

Basic Checkout

  • ✅ Checkout cart coupon
  • ✅ Checkout failures
  • ✅ Checkout purchase
  • ✅ Checkout purchase site editor
  • ✅ Checkout purchase with UPE methods
  • ✅ Checkout save card and purchase

WC Blocks Checkout

  • ✅ WC Blocks checkout failures
  • ✅ WC Blocks checkout purchase
  • ✅ WC Blocks saved card checkout and usage

Multi-Currency

  • ✅ Multi-currency checkout (USD/EUR)
  • ✅ Multi-currency widget

My Account

  • ✅ Saved cards management
  • ✅ Payment methods add fail (declined cards)
  • ✅ Pay for order

Alternative Payment Methods

  • ✅ Alipay checkout
  • ✅ Klarna checkout
  • ✅ BNPL checkout

Key Improvements

Auth Persistence Fix

Added ensureAuthAfterNavigation helper in shopper-navigation.ts that automatically re-authenticates customers when WooCommerce session expires during long test runs. This prevents flaky test failures due to auth state becoming stale.

Test Utilities

  • Centralized navigation functions with built-in auth verification
  • Improved error handling for card decline scenarios
  • Condition-based waiting helpers to eliminate race conditions

Testing

Refer to tests/qit/README.md for setup instructions.

# Run all E2E tests
npm run test:qit-e2e

# Run tests matching a pattern
npm run test:qit-e2e:args -- --grep "@shopper"
npm run test:qit-e2e:args -- --grep "shopper-checkout-purchase"
npm run test:qit-e2e:args -- --grep "multi-currency"

All tests should pass ✅

Context

This is part of the ongoing effort to migrate E2E tests from a custom Docker-based environment to QIT. Previous work established the QIT foundation (#11133, #11146). After QIT released the Test Packages feature, we paused migration to adopt this new approach which offers better isolation and simpler configuration.

🤖 Generated with Claude Code

@mgascam mgascam marked this pull request as draft December 2, 2025 18:52
@mgascam mgascam requested a review from Copilot December 2, 2025 19:13
Copilot finished reviewing on behalf of mgascam December 2, 2025 19:16
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR migrates the QIT E2E tests infrastructure from a custom Docker-based setup to the recommended Test Packages approach. The migration modernizes the test infrastructure with better isolation, simpler configuration, and alignment with QIT best practices.

Key changes:

  • Adopts Test Packages structure with dedicated test package directory (tests/qit/test-package/)
  • Removes legacy custom E2E infrastructure (Docker volumes, custom runner scripts, qit.yml)
  • Implements QIT-native configuration with qit.json and qit-test.json manifests
  • Updates test utilities to use the new @qit/helpers module
  • Fixes race condition in WC Blocks checkout save payment checkbox

Reviewed changes

Copilot reviewed 31 out of 42 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/qit/test-package/** New test package infrastructure with Playwright tests, utilities, fixtures, and configuration
tests/qit/test-package/bootstrap/*.sh Bootstrap scripts for WordPress/WooCommerce setup and Jetpack connection
tests/qit/test-package/qit-helpers/** QIT helper module for WP-CLI operations and test utilities
tests/qit/qit.json Main QIT configuration defining SUT, environments, and test packages
tests/qit/qit.yml Removed legacy QIT configuration for custom tests
tests/qit/e2e-runner.sh Removed legacy custom test runner script
tests/qit/e2e/utils/helpers.ts Removed legacy helper functions replaced by test package utilities
tests/qit/e2e/.eslintrc.js Removed legacy ESLint configuration
package.json Updated npm scripts to use QIT CLI directly with new configuration
composer.json Updated QIT CLI to dev-trunk for test packages support
.eslintignore, .prettierignore Added test-package directory to ignore lists
tests/qit/README.md Updated documentation with test packages approach

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 2, 2025

Test the build

Option 1. Jetpack Beta

  • Install and activate Jetpack Beta.
  • Use this build by searching for PR number 11175 or branch name dev/qit-use-test-packages in your-test.site/wp-admin/admin.php?page=jetpack-beta&plugin=woocommerce-payments

Option 2. Jurassic Ninja - available for logged-in A12s

🚀 Launch a JN site with this branch 🚀

ℹ️ Install this Tampermonkey script to get more options.


Build info:

  • Latest commit: 7355c44
  • Build time: 2025-12-03 19:20:22 UTC

Note: the build is updated when a new commit is pushed to this PR.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 2, 2025

Size Change: 0 B

Total Size: 877 kB

ℹ️ View Unchanged
Filename Size
release/woocommerce-payments/assets/css/admin.css 1.45 kB
release/woocommerce-payments/assets/css/admin.rtl.css 1.45 kB
release/woocommerce-payments/assets/css/success.css 1.06 kB
release/woocommerce-payments/assets/css/success.rtl.css 1.06 kB
release/woocommerce-payments/dist/blocks-checkout-rtl.css 3.05 kB
release/woocommerce-payments/dist/blocks-checkout.css 3.05 kB
release/woocommerce-payments/dist/blocks-checkout.js 54.6 kB
release/woocommerce-payments/dist/cart-block-rtl.css 113 B
release/woocommerce-payments/dist/cart-block.css 112 B
release/woocommerce-payments/dist/cart-block.js 16.7 kB
release/woocommerce-payments/dist/cart.js 5.27 kB
release/woocommerce-payments/dist/checkout-rtl.css 1.13 kB
release/woocommerce-payments/dist/checkout.css 1.13 kB
release/woocommerce-payments/dist/checkout.js 34.6 kB
release/woocommerce-payments/dist/express-checkout-rtl.css 367 B
release/woocommerce-payments/dist/express-checkout.css 367 B
release/woocommerce-payments/dist/express-checkout.js 16.8 kB
release/woocommerce-payments/dist/frontend-tracks.js 833 B
release/woocommerce-payments/dist/index-rtl.css 21.2 kB
release/woocommerce-payments/dist/index.css 21.3 kB
release/woocommerce-payments/dist/index.js 155 kB
release/woocommerce-payments/dist/multi-currency-analytics.js 1.08 kB
release/woocommerce-payments/dist/multi-currency-rtl.css 3.82 kB
release/woocommerce-payments/dist/multi-currency-switcher-block.js 18.2 kB
release/woocommerce-payments/dist/multi-currency.css 3.83 kB
release/woocommerce-payments/dist/multi-currency.js 24.7 kB
release/woocommerce-payments/dist/order-rtl.css 740 B
release/woocommerce-payments/dist/order.css 740 B
release/woocommerce-payments/dist/order.js 21.3 kB
release/woocommerce-payments/dist/plugins-page-rtl.css 484 B
release/woocommerce-payments/dist/plugins-page.css 484 B
release/woocommerce-payments/dist/plugins-page.js 2.64 kB
release/woocommerce-payments/dist/product-details-rtl.css 433 B
release/woocommerce-payments/dist/product-details.css 436 B
release/woocommerce-payments/dist/product-details.js 12.3 kB
release/woocommerce-payments/dist/settings-rtl.css 11.8 kB
release/woocommerce-payments/dist/settings.css 11.7 kB
release/woocommerce-payments/dist/settings.js 141 kB
release/woocommerce-payments/dist/subscription-edit-page.js 703 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal-rtl.css 527 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal.css 527 B
release/woocommerce-payments/dist/subscription-product-onboarding-modal.js 1.98 kB
release/woocommerce-payments/dist/subscription-product-onboarding-toast.js 730 B
release/woocommerce-payments/dist/subscriptions-empty-state-rtl.css 120 B
release/woocommerce-payments/dist/subscriptions-empty-state.css 120 B
release/woocommerce-payments/dist/subscriptions-empty-state.js 1.9 kB
release/woocommerce-payments/dist/success.js 6.03 kB
release/woocommerce-payments/dist/tos-rtl.css 235 B
release/woocommerce-payments/dist/tos.css 235 B
release/woocommerce-payments/dist/tos.js 3 kB
release/woocommerce-payments/dist/woopay-direct-checkout.js 5.68 kB
release/woocommerce-payments/dist/woopay-express-button.js 22.8 kB
release/woocommerce-payments/dist/woopay-rtl.css 4.27 kB
release/woocommerce-payments/dist/woopay.css 4.25 kB
release/woocommerce-payments/dist/woopay.js 70.8 kB
release/woocommerce-payments/includes/subscriptions/assets/css/plugin-page.css 625 B
release/woocommerce-payments/includes/subscriptions/assets/js/plugin-page.js 814 B
release/woocommerce-payments/vendor/automattic/jetpack-assets/build/i18n-loader.js 2.46 kB
release/woocommerce-payments/vendor/automattic/jetpack-assets/build/jetpack-script-data.js 957 B
release/woocommerce-payments/vendor/automattic/jetpack-assets/src/js/i18n-loader.js 1.02 kB
release/woocommerce-payments/vendor/automattic/jetpack-assets/src/js/script-data.js 69 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/babel.config.js 163 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/identity-crisis.css 2.47 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/identity-crisis.js 14.3 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/identity-crisis.rtl.css 2.47 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-connection.css 10.1 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-connection.js 29.7 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-connection.rtl.css 10.1 kB
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-admin-create-user.css 198 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-admin-create-user.js 280 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-admin-create-user.rtl.css 198 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-login.css 625 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-login.js 333 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-login.rtl.css 626 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-sso-users.js 417 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/jetpack-users-connection.js 161 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/tracks-ajax.js 521 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/dist/tracks-callables.js 585 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-admin-create-user.css 215 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-admin-create-user.js 521 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-login.css 721 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-login.js 412 B
release/woocommerce-payments/vendor/automattic/jetpack-connection/src/sso/jetpack-sso-users.js 625 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/about.css 1.04 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin-empty-state.css 294 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin-order-statuses.css 408 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/admin.css 3.59 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/checkout.css 301 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/modal.css 746 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/view-subscription.css 574 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/css/wcs-upgrade.css 414 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/admin-pointers.js 543 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/admin.js 9.4 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/jstz.js 6.78 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/jstz.min.js 3.84 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/meta-boxes-coupon.js 545 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/meta-boxes-subscription.js 2.52 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/moment.js 22.2 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/moment.min.js 11.7 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/payment-method-restrictions.js 1.29 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/admin/wcs-meta-boxes-order.js 507 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/payment-methods.js 358 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/single-product.js 428 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/view-subscription.js 1.38 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/frontend/wcs-cart.js 782 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/modal.js 1.09 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/assets/js/wcs-upgrade.js 1.26 kB
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/build/index.css 391 B
release/woocommerce-payments/vendor/woocommerce/subscriptions-core/build/index.js 3.04 kB

compressed-size-action

@mgascam mgascam requested a review from Copilot December 3, 2025 09:36
Copilot finished reviewing on behalf of mgascam December 3, 2025 09:39
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 30 out of 41 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

tests/qit/test-package/bootstrap/setup.sh:109

  • The user creation commands reference emails that don't match those in the configuration file. For example, line 95 creates a user with email [email protected], but the config file (tests/qit/test-package/config/users.json) specifies [email protected]. This inconsistency could lead to issues if the tests expect specific email addresses. The same issue exists for subscriptions-customer (line 102) and editor (line 109).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

mgascam and others added 6 commits December 3, 2025 10:50
Migrates 8 shopper test specs to QIT:

My Account:
- My account payment methods add failures
- My account saved cards management

Multicurrency & Pay for Order:
- Multi-currency checkout
- Multi-currency widget
- Pay for order flow

Alternative Payment Methods:
- Alipay checkout purchase
- Klarna checkout purchase
- BNPLs (Buy Now Pay Later) checkout

Tests cover shopper flows for account management, currency
switching, and alternative payment methods.
- Alipay: Disable multi-currency before tests (like Klarna does)
- Alipay: Use URL check for redirect instead of page text
- Pay for order: Handle both 'card was declined' and 'payment was not processed' errors
Alipay payments require specific Stripe account configuration that
is not available in the QIT test environment. The payment method can
be enabled in settings but checkout fails with 'Invalid or missing
payment details'.
The QIT devtools implementation uses WP-CLI to set options directly,
but the card testing protection feature relies on filters/hooks from
the Dev Tools plugin (option_wcpay_account_data, woocommerce_payments_account_refreshed)
that aren't available in the QIT environment.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@mgascam mgascam force-pushed the dev/qit-use-test-packages branch from 52eeeb6 to 3597932 Compare December 3, 2025 15:00
@mgascam mgascam changed the base branch from develop to dev/qit-e2e-shopper-remaining-specs December 3, 2025 19:21
@mgascam mgascam marked this pull request as ready for review December 3, 2025 19:35
@mgascam mgascam requested review from a team and Copilot December 3, 2025 19:35
Copilot finished reviewing on behalf of mgascam December 3, 2025 19:37
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 36 out of 49 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (4)

tests/qit/test-package/tests/woopayments/shopper/shopper-multi-currency-widget.spec.ts:25

  • The timeout is set within test.beforeAll which only affects the setup hook, not the actual tests. The comment on line 7-8 indicates the intention is to increase the "per-test timeout", but this placement only affects the beforeAll hook timeout. To set the test timeout for all tests in the suite, move test.setTimeout(60000) outside the beforeAll hook, placing it at the suite level (e.g., right after the test.describe call).
    tests/qit/test-package/tests/woopayments/shopper/shopper-wc-blocks-checkout-failures.spec.ts:33
  • The error messages use different regex patterns (/Your card.s expiration year is in the past\./ and /Your card.s security code is incomplete\./) which escape the apostrophe with .s instead of 's. This is likely intended to handle both straight apostrophes (') and curly apostrophes ('), but the pattern .s would also match other characters like as, bs, etc. Consider using a more specific pattern like ['']s to only match apostrophe characters, or verify if the literal string matching was working before and if the regex is actually necessary.
    tests/qit/test-package/bootstrap/setup.sh:11
  • The comment states "Ensure environment is marked as development so dev-only CLI commands are available." but ends with a period before "so", making it grammatically inconsistent with the pattern used in other comments. For consistency, either remove the period or rephrase to use a full sentence structure.
    tests/qit/test-package/utils/shopper-navigation.ts:32
  • The ensureAuthAfterNavigation function re-authenticates and navigates again if the login form is shown, but there's no protection against infinite loops if the re-authentication itself fails or the navigation continues to show the login form. Consider adding a retry limit or better error handling to detect authentication failures and fail gracefully instead of potentially looping indefinitely.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +23 to +30
* @param {string} hostname - The hostname or full URL of the server.
* @param {string} path - The path of the endpoint.
* @param {Object} data - The data to send in the POST request.
* @returns {Promise<Object>} - Resolves with the response object.
*/
async function makePostRequest(hostname, path, data) {
try {
let finalHost = hostname;
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

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

[nitpick] The function makePostRequest has a potential issue: when hostname is not provided and getDomain() is called, if getDomain() returns a URL with a protocol (like http://localhost:8080), the logic at lines 36-37 will correctly identify it has a protocol. However, the variable name hostname is misleading since it can actually be a full URL. Consider renaming the parameter to hostOrUrl for clarity, or add a comment explaining that this parameter can be either a hostname or a full URL.

Suggested change
* @param {string} hostname - The hostname or full URL of the server.
* @param {string} path - The path of the endpoint.
* @param {Object} data - The data to send in the POST request.
* @returns {Promise<Object>} - Resolves with the response object.
*/
async function makePostRequest(hostname, path, data) {
try {
let finalHost = hostname;
* @param {string} hostOrUrl - The hostname or full URL of the server.
* @param {string} path - The path of the endpoint.
* @param {Object} data - The data to send in the POST request.
* @returns {Promise<Object>} - Resolves with the response object.
*/
async function makePostRequest(hostOrUrl, path, data) {
try {
let finalHost = hostOrUrl;

Copilot uses AI. Check for mistakes.
if (typeof response.body.status === 'undefined' || typeof response.body.stdout === 'undefined' || typeof response.body.stderr === 'undefined') {
console.error(command);
console.error(response);
throw new Error('Invalid response: "status", "stdout" or "stderr" not found.');
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

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

The error message states "Invalid response: 'status', 'stdout' or 'stderr' not found." but uses quotes that could be clearer. Consider using backticks for the field names to improve readability: Invalid response: 'status', 'stdout', or 'stderr' not found. Also, add the Oxford comma before "or" for grammatical correctness.

Suggested change
throw new Error('Invalid response: "status", "stdout" or "stderr" not found.');
throw new Error('Invalid response: `status`, `stdout`, or `stderr` not found.');

Copilot uses AI. Check for mistakes.
# Run specific test file
npm run test:qit-e2e tests/qit/e2e/specs/woopayments/shopper/shopper-checkout-purchase.spec.ts
# Run specific test file (passthrough to Playwright)
E2E_JP_SITE_ID='<value>' E2E_JP_BLOG_TOKEN='<value>' E2E_JP_USER_TOKEN='<value>' npm run test:qit-e2e -- -- shopper-checkout-purchase.spec.ts
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

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

[nitpick] The command shown uses double dashes -- -- which may be confusing. The first -- is npm's argument separator to pass arguments to the underlying script, and the second -- is likely Playwright's separator. Consider adding a brief explanation or simplifying the example to make it clearer for users, such as:

# Run specific test file
npm run test:qit-e2e -- -- shopper-checkout-purchase.spec.ts
# The first -- passes args to npm script, second -- passes to Playwright

Copilot uses AI. Check for mistakes.
Base automatically changed from dev/qit-e2e-shopper-remaining-specs to develop December 4, 2025 13:09
@MrJnrman
Copy link

MrJnrman commented Dec 5, 2025

@mgascam Did you add the binary from the root of https://github.com/woocommerce/qit-cli? It seems its still set to use the latest released version which doesn't support test packages yet.

"./bootstrap/setup.sh"
],
"setup": [
"npm ci",
Copy link

Choose a reason for hiding this comment

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

This throws an error because there's no package lock. We should either generate one or switch to npm install

@MrJnrman
Copy link

MrJnrman commented Dec 8, 2025

I ended up running it with the binary from trunk and only got 7 failed tests
https://qit.woo.com/?qit_results=4934250.U1YrLTO4l0FGLoCimxfgjpqU8X6UZlcHlTlknOUzEJtg1vZctxgPGQ9QAGAMw7dd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants