Skip to content
Merged
Show file tree
Hide file tree
Changes from 84 commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
5940c8a
[E2E][QIT] Migrate remaining shopper specs
mgascam Dec 3, 2025
8832b55
Add changelog entry
mgascam Dec 3, 2025
774085a
Fix Alipay and pay-for-order test failures
mgascam Dec 3, 2025
7977468
Skip Alipay tests due to QIT environment limitation
mgascam Dec 3, 2025
61d20ed
Skip cardTestingPreventionEnabled: true case in pay-for-order test
mgascam Dec 3, 2025
1de9aa1
Merge branch 'develop' into dev/qit-e2e-shopper-remaining-specs
mgascam Dec 3, 2025
698a093
Remove unused emptyCart import
mgascam Dec 3, 2025
1b5c186
add test package
Nov 20, 2025
5a5874e
remove development files
Nov 20, 2025
c21f5c9
fix failing tests
Nov 21, 2025
33c7a61
chore: update woocommerce/qit-cli to dev-trunk and add .gitignore for…
mgascam Dec 1, 2025
f65a0fa
rename tests folder
mgascam Dec 1, 2025
ca9195a
Rename parent folder
mgascam Dec 1, 2025
698ac2f
feat: add .nvmrc file and update setup script for WooPayments E2E tests
mgascam Dec 1, 2025
4ee499e
feat: update test configuration and add shopper subpackage for WooPay…
mgascam Dec 1, 2025
9626216
fix: update home page test to verify visibility of site title
mgascam Dec 1, 2025
de9cfaa
chore: remove outdated migration guide for QIT test packages
mgascam Dec 1, 2025
d147c6d
fix: update QIT test package path and clean up environment configuration
mgascam Dec 1, 2025
3d95523
fix: update plugin entries in QIT test package configuration
mgascam Dec 1, 2025
5696698
feat: add QIT test package configuration and E2E test scripts
mgascam Dec 2, 2025
0c525a2
Move wc blocks tests
mgascam Dec 2, 2025
4efa989
Remove QIT custom E2E configuration.
mgascam Dec 2, 2025
a0f8100
fix: improve reliability of save payment method interaction in WC Blo…
mgascam Dec 2, 2025
92e4117
docs: update README for WooPayments QIT tests setup and execution ins…
mgascam Dec 2, 2025
a3f67df
remove comment
mgascam Dec 2, 2025
f3580e4
revert qit-cli to stable version for CI compatibility
mgascam Dec 2, 2025
0831dbe
Remove comment
mgascam Dec 2, 2025
5b19283
docs: add note about dev version of qit-cli requirement for E2E tests
mgascam Dec 2, 2025
1d9a361
Fix internal dependencies comment
mgascam Dec 2, 2025
0b6d0b8
Remove migration readme
mgascam Dec 2, 2025
c8ff3a6
Amend test instructions
mgascam Dec 2, 2025
beebe58
refactor: simplify E2E test command and update README instructions
mgascam Dec 3, 2025
3597932
fix: update test directory path for shopper project in Playwright config
mgascam Dec 3, 2025
7355c44
Migrate remaining shopper tests
mgascam Dec 3, 2025
dfccf99
Merge branch 'develop' into dev/qit-use-test-packages
mgascam Dec 9, 2025
c3d144c
update: change version of woocommerce/qit-cli to dev-trunk in compose…
mgascam Dec 9, 2025
9db1b35
update: add package-lock.json for QIT dependency management
mgascam Dec 9, 2025
776edb0
refactor: move user data to a separate users.ts file and remove users…
mgascam Dec 10, 2025
6bf1fa4
update: rename project from 'chromium' to 'default' in Playwright config
mgascam Dec 10, 2025
1561fd6
Merge branch 'develop' into dev/qit-use-test-packages
mgascam Dec 11, 2025
6b838ed
update: enhance E2E testing setup with troubleshooting guidance and c…
mgascam Dec 11, 2025
7c8994f
update: improve reliability of payment method setup and card details …
mgascam Dec 11, 2025
aa71d84
update: specify qit-cli version in composer files and enhance E2E tes…
mgascam Dec 11, 2025
cae9695
update: include tests/qit/e2e directory in ESLint ignore file
mgascam Dec 11, 2025
5b98fe3
refactor: remove obsolete e2e tests for payment methods and multi-cur…
mgascam Dec 11, 2025
2af0f5f
Add changelog
mgascam Dec 11, 2025
e0fd01f
update: modify Jest config to adjust module path ignore patterns for …
mgascam Dec 11, 2025
c1d9c17
update: allow installation of qit-cli and other dependencies without …
mgascam Dec 12, 2025
315353a
Merge branch 'develop' into dev/qit-use-test-packages
mgascam Dec 12, 2025
92c1d4b
update: modify composer install command to exclude development depend…
mgascam Dec 12, 2025
ce5e467
Merge branch 'develop' into dev/qit-use-test-packages
mgascam Dec 12, 2025
eaf26a3
Merge branch 'develop' into dev/qit-use-test-packages
mgascam Dec 12, 2025
6157a4f
Merge branch 'develop' into dev/qit-use-test-packages
mgascam Dec 15, 2025
164660b
Merge branch 'develop' into dev/qit-use-test-packages
mgascam Dec 15, 2025
d87fba1
fix: update plugins format in qit-test.json
mgascam Dec 15, 2025
7902f44
fix: add package name for qit-helpers in package-lock.json
mgascam Dec 15, 2025
6180954
feat: add merchant subpackage to QIT test-package infrastructure
mgascam Dec 15, 2025
8d0b840
feat: add instructions for running specific E2E test projects in READ…
mgascam Dec 15, 2025
ae2c051
fix: update TODO comments to include issue references for merchant ac…
mgascam Dec 15, 2025
fa4cda3
Add 12 additional merchant E2E test specs to QIT test-package
mgascam Dec 15, 2025
73bcd90
fix: resolve strict mode violation for duplicate snackbars
mgascam Dec 15, 2025
8fb584a
fix: use exact match for 'Complete' text in wp-admin access test
mgascam Dec 15, 2025
cfeeb63
fix: add stability wait for dispute challenge form state
mgascam Dec 15, 2025
683c5e5
Merge branch 'develop' into dev/qit-use-test-packages
mgascam Dec 15, 2025
5f1f7e4
fix: remove redundant form state sanity-check in dispute test
mgascam Dec 15, 2025
875acec
fix: rewrite dialog handler to properly await async operations
mgascam Dec 15, 2025
9653d8f
fix: remove mandatory dialog assertion in refund failure tests
mgascam Dec 16, 2025
f9acd28
fix: add delay after dispute evidence save for Stripe API
mgascam Dec 16, 2025
446cf62
docs: enhance README with detailed instructions for retrieving Jetpac…
mgascam Dec 16, 2025
0b1edb8
docs: update README with tip for exporting environment variables in s…
mgascam Dec 16, 2025
19d7372
Merge remote-tracking branch 'origin/develop' into dev/qit-use-test-p…
mgascam Dec 16, 2025
61e0077
Merge branch 'dev/qit-use-test-packages' into dev/qit-merchant-tests
mgascam Dec 16, 2025
da7670f
fix: update tags for account balance test to reflect implementation s…
mgascam Dec 16, 2025
4ab2030
fix: simplify order processing click logic in ensureOrderIsProcessed …
mgascam Dec 16, 2025
9b49e32
fix: use constant for default theme fallback in getActiveThemeSlug fu…
mgascam Dec 16, 2025
24083ed
Merge remote-tracking branch 'origin' into dev/qit-merchant-tests
mgascam Dec 16, 2025
fee4df2
Add changelog
mgascam Dec 17, 2025
8c54a93
Merge branch 'develop' into dev/qit-merchant-tests
mgascam Dec 17, 2025
15cdf8d
refactor: remove multi-currency checks from full refund test for cons…
mgascam Dec 19, 2025
3cc78e5
refactor: streamline dialog handling in refund failure tests
mgascam Dec 19, 2025
623bc90
Merge branch 'develop' into dev/qit-merchant-tests
mgascam Dec 19, 2025
5278ad0
docs: add troubleshooting section for GitHub token errors during comp…
mgascam Dec 19, 2025
f174752
Merge dev/qit-merchant-tests into dev/qit-merchant-tests-pr3
mgascam Dec 19, 2025
0b814fd
refactor: enhance refund message verification with regex and improve …
mgascam Dec 19, 2025
5af7a6c
Merge remote-tracking branch 'origin' into dev/qit-merchant-tests-pr3
mgascam Dec 23, 2025
002f9d5
fix: remove unnecessary flag from rate limiter option update
mgascam Dec 23, 2025
4c01d5f
refactor: simplify ensureOrderIsProcessed function and remove orderId…
mgascam Dec 23, 2025
3678c11
refactor: update ensureOrderIsProcessed to use direct PHP eval for sy…
mgascam Dec 23, 2025
c9f4bd7
refactor: simplify retry mechanism for analytics data check
mgascam Dec 23, 2025
24bad97
Merge branch 'develop' into dev/qit-merchant-tests-pr3
mgascam Dec 23, 2025
d53c341
add changelog
mgascam Dec 24, 2025
60ce4b1
Merge branch 'develop' into dev/qit-merchant-tests-pr3
mgascam Dec 29, 2025
8301878
Merge branch 'develop' into dev/qit-merchant-tests-pr3
mgascam Jan 7, 2026
58ad3af
Merge branch 'develop' into dev/qit-merchant-tests-pr3
mgascam Jan 8, 2026
401890a
Merge branch 'develop' into dev/qit-merchant-tests-pr3
frosso Jan 8, 2026
0459ae9
Fix missing await
mgascam Jan 8, 2026
151b186
fix: update expected text for admin page access test
mgascam Jan 8, 2026
913074a
Merge branch 'develop' into dev/qit-merchant-tests-pr3
mgascam Jan 8, 2026
cb7fe65
Merge branch 'develop' into dev/qit-merchant-tests-pr3
mgascam Jan 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog/dev-qit-merchant-tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Significance: patch
Type: dev
Comment: Migration of merchant E2E tests to QIT Test Packages feature. No production code is affected.
28 changes: 28 additions & 0 deletions tests/qit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ E2E_JP_SITE_ID='<value>' E2E_JP_BLOG_TOKEN='<value>' E2E_JP_USER_TOKEN='<value>'

# Run tests filtered by tag (e.g., @blocks, @shopper)
E2E_JP_SITE_ID='<value>' E2E_JP_BLOG_TOKEN='<value>' E2E_JP_USER_TOKEN='<value>' npm run test:qit-e2e -- -- --grep "@blocks"

# Run a specific test project (e.g., merchant, shopper)
E2E_JP_SITE_ID='<value>' E2E_JP_BLOG_TOKEN='<value>' E2E_JP_USER_TOKEN='<value>' npm run test:qit-e2e -- -- --project=merchant
# Available projects are defined in playwright.config.js
```

> [!TIP]
Expand All @@ -93,3 +97,27 @@ npm run test:qit-e2e
#### "Card testing attempt detected" errors

If checkout tests fail with "Card testing attempt detected" errors, the test account may need server-side configuration to disable fraud protection for E2E testing. Contact the payments team for assistance.

#### GitHub token errors during `composer install`

When running `composer install`, you may encounter:

```text
Could not fetch https://api.github.com/repos/woocommerce/qit-cli/zipball/...
please review your configured GitHub OAuth token
```

**Solution:** Use a fine-grained GitHub token with read-only access to public repositories.

1. Go to GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens
2. Create a new token with:
- **Repository access:** Public repositories (read-only)
- No additional permissions required
3. Configure Composer to use the token:

```bash
composer config --global github-oauth.github.com YOUR_TOKEN
```

> [!NOTE]
> Classic PAT tokens may not work for accessing woocommerce repos. Fine-grained tokens with public repo read access are sufficient.
7 changes: 6 additions & 1 deletion tests/qit/test-package/playwright.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,12 @@ export default defineConfig( {
testDir: './tests/woopayments/shopper',
use: { ...devices[ 'Desktop Chrome' ] },
},
// Additional projects for merchant and subscriptions subpackages
{
name: 'merchant',
testDir: './tests/woopayments/merchant',
use: { ...devices[ 'Desktop Chrome' ] },
},
// Additional project for subscriptions subpackage
// will be added when those tests are migrated.
],
} );
9 changes: 9 additions & 0 deletions tests/qit/test-package/qit-test.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@
"run": ["npx playwright test --project=shopper"]
}
}
},
"woocommerce-payments/merchant": {
"description": "Merchant admin tests for WooPayments",
"tags": ["woopayments", "merchant", "admin"],
"test": {
"phases": {
"run": ["npx playwright test --project=merchant"]
}
}
}
},
"timeout": 1800
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/**
* External dependencies
*/
import { test, expect } from '../../../fixtures/auth';

/**
* Internal dependencies
*/
import { goToPaymentsOverview, dataHasLoaded } from '../../../utils/merchant';

// Optional currency symbol, followed by one or more digits, decimal separator, or comma.
const formattedCurrencyRegex = /[^\d.,]*[\d.,]+/;

test.describe(
'Merchant account balance overview',
{ tag: '@merchant' },
() => {
test(
'View the total and available account balance for a single deposit currency',
{
tag: '@critical',
},
async ( { adminPage } ) => {
await test.step(
'Navigate to the Payments Overview screen',
async () => {
await goToPaymentsOverview( adminPage );
await dataHasLoaded( adminPage );
}
);

await test.step(
'Observe the total account balance, ensuring it has a formatted currency value',
async () => {
const totalBalanceValue = adminPage.getByLabel(
'Total balance',
{
exact: true,
}
);

await expect( totalBalanceValue ).toHaveText(
formattedCurrencyRegex
);
}
);

await test.step(
'Observe the available account balance, ensuring it has a formatted currency value',
async () => {
const availableFundsValue = adminPage.getByLabel(
'Available funds',
{
exact: true,
}
);

await expect( availableFundsValue ).toHaveText(
formattedCurrencyRegex
);
}
);
}
);

// @critical tag intentionally omitted until test is fully implemented.
// Unimplemented tests should not be marked critical as they provide false confidence in coverage.
test(
'View the total and available account balance for multiple deposit currencies',
{
tag: '@todo',
annotation: [
{
type: 'issue',
description:
'https://github.com/Automattic/woocommerce-payments/issues/9188',
},
{
type: 'description',
description:
'Test requirements not yet met: A merchant account with multiple deposit currencies must be available in our e2e environment',
},
],
},
async () => {
await test.step(
'Navigate to the Payments Overview screen',
() => {
// @todo https://github.com/Automattic/woocommerce-payments/issues/9188
}
);

await test.step(
'Select a deposit currency using the currency select input',
async () => {
// @todo https://github.com/Automattic/woocommerce-payments/issues/9188
}
);

await test.step(
'Observe the total account balance for the selected currency, ensuring it is correctly formatted with the currency symbol',
async () => {
// @todo https://github.com/Automattic/woocommerce-payments/issues/9188
}
);

await test.step(
'Observe the available account balance the selected currency, ensuring it is correctly formatted with the currency symbol',
async () => {
// @todo https://github.com/Automattic/woocommerce-payments/issues/9188
}
);

await test.step(
'Select a second deposit currency using the currency select input',
async () => {
// @todo https://github.com/Automattic/woocommerce-payments/issues/9188
}
);

await test.step(
'Observe the total account balance for the selected currency, ensuring it is correctly formatted with the currency symbol',
async () => {
// @todo https://github.com/Automattic/woocommerce-payments/issues/9188
}
);

await test.step(
'Observe the available account balance the selected currency, ensuring it is correctly formatted with the currency symbol',
async () => {
// @todo https://github.com/Automattic/woocommerce-payments/issues/9188
}
);
}
);
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* Internal dependencies
*/
import { test, expect } from '../../../fixtures/auth';
import {
activateMulticurrency,
ensureOrderIsProcessed,
isMulticurrencyEnabled,
tableDataHasLoaded,
waitAndSkipTourComponent,
goToOrderAnalytics,
} from '../../../utils/merchant';
import { placeOrderWithCurrency } from '../../../utils/shopper';

test.describe( 'Admin order analytics', { tag: '@merchant' }, () => {
let orderId: string;

// Extend timeout for the entire test suite to allow order processing
test.setTimeout( 120000 );

test.beforeAll( async ( { adminPage, customerPage } ) => {
// Set explicit timeout for this beforeAll hook
test.setTimeout( 120000 );

// Ensure multi-currency is enabled for the analytics tests
if ( false === ( await isMulticurrencyEnabled( adminPage ) ) ) {
await activateMulticurrency( adminPage );
}

// Place an order to ensure the analytics data is correct
orderId = await placeOrderWithCurrency( customerPage, 'USD' );
await ensureOrderIsProcessed( adminPage, orderId );

// Give analytics more time to process the order data
await adminPage.waitForTimeout( 2000 );
} );

test( 'should load without any errors', async ( { adminPage } ) => {
await goToOrderAnalytics( adminPage );
await tableDataHasLoaded( adminPage );
await waitAndSkipTourComponent(
adminPage,
'.woocommerce-revenue-report-date-tour'
);

const ordersTitle = adminPage.getByRole( 'heading', {
name: 'Orders',
level: 1,
exact: true,
} );
await expect( ordersTitle ).toBeVisible();

// Check for analytics data with retry mechanism
let hasData = false;
let attempts = 0;
const maxAttempts = 3;

while ( ! hasData && attempts < maxAttempts ) {
const noDataText = adminPage.getByText( 'No data to display' );
const noDataCount = await noDataText.count();

if ( noDataCount === 0 ) {
hasData = true;
break;
}

// If no data on first check, try refreshing
if ( attempts < maxAttempts - 1 ) {
await adminPage.reload();
await tableDataHasLoaded( adminPage );
await waitAndSkipTourComponent(
adminPage,
'.woocommerce-revenue-report-date-tour'
);
// Wait a bit more for data to load after refresh
await adminPage.waitForTimeout( 2000 );
}

attempts++;
}

// Verify that we have analytics data from the order created in beforeAll
const finalNoDataText = adminPage.getByText( 'No data to display' );
await expect( finalNoDataText ).toHaveCount( 0 );

// TODO: This visual regression test is flaky, we should revisit the approach.
// await expect( adminPage ).toHaveScreenshot();
} );

test( 'orders table should have the customer currency column', async ( {
adminPage,
} ) => {
await goToOrderAnalytics( adminPage );
await tableDataHasLoaded( adminPage );
await waitAndSkipTourComponent(
adminPage,
'.woocommerce-revenue-report-date-tour'
);

const columnToggle = adminPage.getByTitle(
'Choose which values to display'
);
await columnToggle.click();
const customerCurrencyToggle = adminPage.getByRole(
'menuitemcheckbox',
{
name: 'Customer Currency',
}
);
await expect( customerCurrencyToggle ).toBeVisible();
await customerCurrencyToggle.click();
const customerCurrencyColumn = adminPage.getByRole( 'columnheader', {
name: 'Customer Currency',
} );
await expect( customerCurrencyColumn ).toBeVisible();
} );
} );
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Internal dependencies
*/
import { test, expect } from '../../../fixtures/auth';

test.describe( 'Merchant deposits', { tag: '@merchant' }, () => {
test( 'Load the deposits list page', async ( { adminPage } ) => {
await adminPage.goto(
'/wp-admin/admin.php?page=wc-admin&path=/payments/payouts'
);

// Wait for the deposits table to load.
await adminPage
.locator( '.woocommerce-table__table.is-loading' )
.waitFor( { state: 'hidden' } );

expect(
adminPage.getByRole( 'heading', {
name: 'Payout history',
} )
).toBeVisible();
} );

test( 'Select deposits list advanced filters', async ( { adminPage } ) => {
await adminPage.goto(
'/wp-admin/admin.php?page=wc-admin&path=/payments/payouts'
);

// Wait for the deposits table to load.
await adminPage
.locator( '.woocommerce-table__table.is-loading' )
.waitFor( { state: 'hidden' } );

// Open the advanced filters.
await adminPage.getByRole( 'button', { name: 'All payouts' } ).click();
await adminPage
.getByRole( 'button', { name: 'Advanced filters' } )
.click();

// Select a filter
await adminPage.getByRole( 'button', { name: 'Add a Filter' } ).click();
await adminPage.getByRole( 'button', { name: 'Status' } ).click();

// Select a filter option
await adminPage
.getByLabel( 'Select a payout status', {
exact: true,
} )
.selectOption( 'Pending' );

// Scroll to the top to ensure the sticky header doesn't cover the filters.
await adminPage.evaluate( () => {
window.scrollTo( 0, 0 );
} );
// TODO: This visual regression test is not flaky, but we should revisit the approach.
// await expect(
// adminPage.locator( '.woocommerce-filters' ).last()
// ).toHaveScreenshot();
} );
} );
Loading