-
Notifications
You must be signed in to change notification settings - Fork 210
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
Add ACH E2E tests #3931
Add ACH E2E tests #3931
Changes from 36 commits
971bdb5
030cce4
b32f102
c0a14fb
83b6acc
165312b
fccca46
9d36ce5
1bdb34a
614bb0d
2f37dcf
be6c210
ec749e4
012600f
58f0284
b8cac3a
1e7f1df
71c6c49
8df527c
7962be3
aa1a5cf
28d2e62
d609d43
a602a76
33c3ae0
7dc27ac
38e72b8
0db0ca6
611235e
f4d9648
2af2187
6dbb42d
6ff6cfc
aa3d9de
99fa8eb
c123216
103fdec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import { test, expect } from '@playwright/test'; | ||
import config from 'config'; | ||
import { admin, payments, api, user } from '../../../../utils'; | ||
|
||
const { | ||
emptyCart, | ||
setupCart, | ||
setupBlocksCheckout, | ||
fillACHBankDetails, | ||
setupACHCheckout, | ||
} = payments; | ||
|
||
test.describe( 'ACH payment tests @blocks', () => { | ||
let username, userEmail; | ||
|
||
test.beforeAll( async ( { browser } ) => { | ||
await test.step( 'Setup test environment', async () => { | ||
// Create test user | ||
const randomString = Date.now(); | ||
userEmail = | ||
randomString + '+' + config.get( 'users.customer.email' ); | ||
username = | ||
randomString + '.' + config.get( 'users.customer.username' ); | ||
|
||
const testUser = { | ||
...config.get( 'users.customer' ), | ||
...config.get( 'addresses.customer' ), | ||
email: userEmail, | ||
username, | ||
}; | ||
await api.create.customer( testUser ); | ||
|
||
// Enable ACH in admin | ||
await admin.togglePaymentMethod( | ||
browser, | ||
'ACH Direct Debit', | ||
true | ||
); | ||
Comment on lines
+34
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I decided not to disable ACH after the tests because another file (the shortcode tests) uses it. If one test disables the payment method in the middle of another test execution, it could cause issues. Since test environments aren’t intended to be reusable, this is acceptable. |
||
} ); | ||
} ); | ||
|
||
test.describe.configure( { mode: 'parallel' } ); | ||
|
||
test( 'customer can pay with ACH using valid bank details @smoke', async ( { | ||
page, | ||
} ) => { | ||
await setupACHCheckout( page, 'blocks' ); | ||
await fillACHBankDetails( page ); | ||
await page.locator( 'text=Place order' ).click(); | ||
await page.waitForURL( '**/checkout/order-received/**' ); | ||
await expect( page.locator( 'h1.entry-title' ) ).toHaveText( | ||
'Order received' | ||
); | ||
} ); | ||
|
||
test( 'customer can save and reuse ACH payment method @smoke', async ( { | ||
page, | ||
} ) => { | ||
// First order - Save the payment method | ||
await test.step( | ||
'Save payment method during first checkout', | ||
async () => { | ||
await user.login( | ||
page, | ||
username, | ||
config.get( 'users.customer.password' ) | ||
); | ||
await setupACHCheckout( page, 'blocks' ); | ||
await fillACHBankDetails( page ); | ||
await page | ||
.locator( | ||
'.wc-block-components-payment-methods__save-card-info' | ||
) | ||
.click(); | ||
await page.locator( 'text=Place order' ).click(); | ||
await page.waitForURL( '**/checkout/order-received/**' ); | ||
await expect( page.locator( 'h1.entry-title' ) ).toHaveText( | ||
'Order received' | ||
); | ||
} | ||
); | ||
|
||
// Second order - Use saved payment method | ||
await test.step( | ||
'Use saved payment method for second checkout', | ||
async () => { | ||
await emptyCart( page ); | ||
await setupCart( page ); | ||
await setupBlocksCheckout( | ||
page, | ||
config.get( 'addresses.customer.billing' ) | ||
); | ||
await page | ||
.locator( 'label' ) | ||
.filter( { hasText: 'Checking account ending in' } ) | ||
.click(); | ||
await page.locator( 'text=Place order' ).click(); | ||
await page.waitForURL( '**/checkout/order-received/**' ); | ||
await expect( page.locator( 'h1.entry-title' ) ).toHaveText( | ||
'Order received' | ||
); | ||
} | ||
); | ||
} ); | ||
} ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import { test, expect } from '@playwright/test'; | ||
import config from 'config'; | ||
import { admin, payments, api, user } from '../../../../utils'; | ||
|
||
const { | ||
emptyCart, | ||
setupCart, | ||
setupShortcodeCheckout, | ||
fillACHBankDetails, | ||
setupACHCheckout, | ||
} = payments; | ||
|
||
test.describe( 'ACH payment tests @shortcode', () => { | ||
let username, userEmail; | ||
|
||
test.beforeAll( async ( { browser } ) => { | ||
await test.step( 'Setup test environment', async () => { | ||
// Create test user | ||
const randomString = Date.now(); | ||
userEmail = | ||
randomString + '+' + config.get( 'users.customer.email' ); | ||
username = | ||
randomString + '.' + config.get( 'users.customer.username' ); | ||
|
||
const testUser = { | ||
...config.get( 'users.customer' ), | ||
...config.get( 'addresses.customer' ), | ||
email: userEmail, | ||
username, | ||
}; | ||
await api.create.customer( testUser ); | ||
|
||
// Enable ACH in admin | ||
await admin.togglePaymentMethod( | ||
browser, | ||
'ACH Direct Debit', | ||
true | ||
); | ||
} ); | ||
} ); | ||
|
||
test.describe.configure( { mode: 'parallel' } ); | ||
|
||
test( 'customer can pay with ACH using valid bank details @smoke', async ( { | ||
page, | ||
} ) => { | ||
await setupACHCheckout( page, 'shortcode' ); | ||
await fillACHBankDetails( page ); | ||
await page.locator( 'text=Place order' ).click(); | ||
await page.waitForURL( '**/checkout/order-received/**' ); | ||
await expect( page.locator( 'h1.entry-title' ) ).toHaveText( | ||
'Order received' | ||
); | ||
} ); | ||
|
||
test( 'customer can save and reuse ACH payment method @smoke', async ( { | ||
page, | ||
} ) => { | ||
// First order - Save the payment method | ||
await test.step( | ||
'Save payment method during first checkout', | ||
async () => { | ||
await user.login( | ||
page, | ||
username, | ||
config.get( 'users.customer.password' ) | ||
); | ||
await setupACHCheckout( page, 'shortcode' ); | ||
await fillACHBankDetails( page ); | ||
await page | ||
.getByRole( 'checkbox', { | ||
name: 'Save payment information to', | ||
} ) | ||
.click(); | ||
await page.locator( 'text=Place order' ).click(); | ||
await page.waitForURL( '**/checkout/order-received/**' ); | ||
await expect( page.locator( 'h1.entry-title' ) ).toHaveText( | ||
'Order received' | ||
); | ||
} | ||
); | ||
|
||
// Second order - Use saved payment method | ||
await test.step( | ||
'Use saved payment method for second checkout', | ||
async () => { | ||
await emptyCart( page ); | ||
await setupCart( page ); | ||
await setupShortcodeCheckout( | ||
page, | ||
config.get( 'addresses.customer.billing' ) | ||
); | ||
await page.getByText( 'ACH Direct Debit' ).click(); | ||
await page.waitForTimeout( 1000 ); | ||
await page | ||
.locator( '.woocommerce-SavedPaymentMethods-token' ) | ||
.first() | ||
.click(); | ||
await page.locator( 'text=Place order' ).click(); | ||
await page.waitForURL( '**/checkout/order-received/**' ); | ||
await expect( page.locator( 'h1.entry-title' ) ).toHaveText( | ||
'Order received' | ||
); | ||
} | ||
); | ||
} ); | ||
} ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,8 @@ setup( 'Disable legacy checkout experience', async ( { browser } ) => { | |
await expect( | ||
page.getByTestId( 'legacy-checkout-experience-checkbox' ) | ||
).not.toBeChecked(); | ||
|
||
await adminContext.close(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you run the tests in headed mode, these pages never closed. This fixes that issue. |
||
} ); | ||
|
||
setup( 'enable Link', async ( { browser } ) => { | ||
|
@@ -36,4 +38,6 @@ setup( 'enable Link', async ( { browser } ) => { | |
|
||
await expect( page.getByText( 'Settings saved.' ) ).toBeDefined(); | ||
await expect( page.getByLabel( 'Link by Stripe Input' ) ).toBeChecked(); | ||
|
||
await adminContext.close(); | ||
} ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { expect } from '@playwright/test'; | ||
|
||
/** | ||
* Get a new admin page with admin context. | ||
* @param {Browser} browser Playwright browser fixture. | ||
* @returns {Promise<{context: BrowserContext, page: Page}>} The admin context and page. | ||
*/ | ||
export const getAdminPage = async ( browser ) => { | ||
const context = await browser.newContext( { | ||
storageState: process.env.ADMINSTATE, | ||
} ); | ||
const page = await context.newPage(); | ||
return { context, page }; | ||
}; | ||
|
||
/** | ||
* Enable or disable a payment method in Stripe settings. | ||
* @param {Browser} browser Playwright browser fixture. | ||
* @param {string} methodName The payment method name as shown in admin. | ||
* @param {boolean} enable Whether to enable or disable the payment method. | ||
*/ | ||
export const togglePaymentMethod = async ( | ||
browser, | ||
methodName, | ||
enable = true | ||
) => { | ||
const { context, page } = await getAdminPage( browser ); | ||
|
||
try { | ||
await page.goto( | ||
'/wp-admin/admin.php?page=wc-settings&tab=checkout§ion=stripe&panel=methods' | ||
); | ||
|
||
const checkbox = page.getByRole( 'checkbox', { | ||
name: methodName, | ||
} ); | ||
const isChecked = await checkbox.isChecked(); | ||
|
||
if ( ( enable && ! isChecked ) || ( ! enable && isChecked ) ) { | ||
await checkbox.click(); | ||
|
||
// When disabling, we need to click the remove button | ||
if ( ! enable ) { | ||
await page.getByRole( 'button', { name: 'Remove' } ).click(); | ||
} | ||
|
||
await page.click( 'text=Save changes' ); | ||
await expect( page.getByText( 'Settings saved.' ) ).toBeDefined(); | ||
} | ||
} finally { | ||
await context.close(); | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Locally, the environment variables are defined in
"$E2E_ROOT"/config/local.env
, but in CI they’re set in the workflow configuration. We need these variables to start the Stripe listener container.