Merge pull request #29270 from woocommerce/add/merchant-order-email-flow
Add merchant order email flow e2e test
This commit is contained in:
commit
30d7b2ce9d
|
@ -24,6 +24,7 @@
|
||||||
- Merchant Orders Customer Checkout Page
|
- Merchant Orders Customer Checkout Page
|
||||||
- Shopper Cart Apply Coupon
|
- Shopper Cart Apply Coupon
|
||||||
- Shopper Variable product info updates on different variations
|
- Shopper Variable product info updates on different variations
|
||||||
|
- Merchant order emails flow
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ The functions to access the core tests are:
|
||||||
- `runProductEditDetailsTest` - Merchant can edit an existing product
|
- `runProductEditDetailsTest` - Merchant can edit an existing product
|
||||||
- `runProductSearchTest` - Merchant can search for a product and view it
|
- `runProductSearchTest` - Merchant can search for a product and view it
|
||||||
- `runMerchantOrdersCustomerPaymentPage` - Merchant can visit the customer payment page
|
- `runMerchantOrdersCustomerPaymentPage` - Merchant can visit the customer payment page
|
||||||
|
- `runMerchantOrderEmailsTest` - Merchant can receive order emails and resend emails by Order Actions
|
||||||
|
|
||||||
### Shopper
|
### Shopper
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ const runOrderApplyCouponTest = require( './merchant/wp-admin-order-apply-coupon
|
||||||
const runProductEditDetailsTest = require( './merchant/wp-admin-product-edit-details.test' );
|
const runProductEditDetailsTest = require( './merchant/wp-admin-product-edit-details.test' );
|
||||||
const runProductSearchTest = require( './merchant/wp-admin-product-search.test' );
|
const runProductSearchTest = require( './merchant/wp-admin-product-search.test' );
|
||||||
const runMerchantOrdersCustomerPaymentPage = require( './merchant/wp-admin-order-customer-payment-page.test' );
|
const runMerchantOrdersCustomerPaymentPage = require( './merchant/wp-admin-order-customer-payment-page.test' );
|
||||||
|
const runMerchantOrderEmailsTest = require( './merchant/wp-admin-order-emails.test' );
|
||||||
|
|
||||||
// REST API tests
|
// REST API tests
|
||||||
const runExternalProductAPITest = require( './api/external-product.test' );
|
const runExternalProductAPITest = require( './api/external-product.test' );
|
||||||
|
@ -112,6 +113,7 @@ module.exports = {
|
||||||
runProductEditDetailsTest,
|
runProductEditDetailsTest,
|
||||||
runProductSearchTest,
|
runProductSearchTest,
|
||||||
runMerchantOrdersCustomerPaymentPage,
|
runMerchantOrdersCustomerPaymentPage,
|
||||||
|
runMerchantOrderEmailsTest,
|
||||||
runMerchantTests,
|
runMerchantTests,
|
||||||
runProductBrowseSearchSortTest,
|
runProductBrowseSearchSortTest,
|
||||||
runApiTests,
|
runApiTests,
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
/* eslint-disable jest/no-export, jest/no-disabled-tests, jest/no-standalone-expect */
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
const {
|
||||||
|
merchant,
|
||||||
|
clickUpdateOrder,
|
||||||
|
createSimpleOrder,
|
||||||
|
selectOrderAction,
|
||||||
|
deleteAllEmailLogs,
|
||||||
|
} = require( '@woocommerce/e2e-utils' );
|
||||||
|
|
||||||
|
const config = require( 'config' );
|
||||||
|
const simpleProductName = config.get( 'products.simple.name' );
|
||||||
|
const customerEmail = config.get( 'addresses.customer.billing.email' );
|
||||||
|
const adminEmail = 'admin@woocommercecoree2etestsuite.com';
|
||||||
|
const storeName = 'WooCommerce Core E2E Test Suite';
|
||||||
|
|
||||||
|
let orderId;
|
||||||
|
|
||||||
|
const runMerchantOrderEmailsTest = () => {
|
||||||
|
|
||||||
|
describe('Merchant > Order Action emails received', () => {
|
||||||
|
beforeAll( async () => {
|
||||||
|
await merchant.login();
|
||||||
|
|
||||||
|
// Clear out the existing email logs if any
|
||||||
|
await deleteAllEmailLogs();
|
||||||
|
|
||||||
|
orderId = await createSimpleOrder( 'Processing' );
|
||||||
|
|
||||||
|
await Promise.all( [
|
||||||
|
// Select the billing email address field and add the customer billing email from the config
|
||||||
|
await page.click( 'div.order_data_column:nth-child(2) > h3:nth-child(1) > a:nth-child(1)' ),
|
||||||
|
await expect( page ).toFill( '#_billing_email', customerEmail ),
|
||||||
|
await clickUpdateOrder( 'Order updated.' ),
|
||||||
|
] );
|
||||||
|
} );
|
||||||
|
|
||||||
|
afterEach( async () => {
|
||||||
|
// Clear out any emails after each test
|
||||||
|
await deleteAllEmailLogs();
|
||||||
|
} );
|
||||||
|
|
||||||
|
// New order emails are sent automatically when we create the simple order above, so let's verify we get these emails
|
||||||
|
it('can receive new order email', async () => {
|
||||||
|
await merchant.openEmailLog();
|
||||||
|
await expect( page ).toMatchElement( '.column-receiver', { text: adminEmail } );
|
||||||
|
await expect( page ).toMatchElement( '.column-subject', { text: `[${storeName}]: New order #${orderId}` } );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it('can resend new order notification', async () => {
|
||||||
|
await merchant.goToOrder( orderId );
|
||||||
|
await selectOrderAction( 'send_order_details_admin' );
|
||||||
|
|
||||||
|
await merchant.openEmailLog();
|
||||||
|
await expect( page ).toMatchElement( '.column-receiver', { text: adminEmail } );
|
||||||
|
await expect( page ).toMatchElement( '.column-subject', { text: `[${storeName}]: New order #${orderId}` } );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it('can email invoice/order details to customer', async () => {
|
||||||
|
await merchant.goToOrder( orderId );
|
||||||
|
await selectOrderAction( 'send_order_details' );
|
||||||
|
|
||||||
|
await merchant.openEmailLog();
|
||||||
|
await expect( page ).toMatchElement( '.column-receiver', { text: customerEmail } );
|
||||||
|
await expect( page ).toMatchElement( '.column-subject', { text: `Invoice for order #${orderId} on ${storeName}` } );
|
||||||
|
} );
|
||||||
|
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = runMerchantOrderEmailsTest;
|
|
@ -8,3 +8,6 @@ wp user create customer customer@woocommercecoree2etestsuite.com --user_pass=pas
|
||||||
|
|
||||||
# we cannot create API keys for the API, so we using basic auth, this plugin allows that.
|
# we cannot create API keys for the API, so we using basic auth, this plugin allows that.
|
||||||
wp plugin install https://github.com/WP-API/Basic-Auth/archive/master.zip --activate
|
wp plugin install https://github.com/WP-API/Basic-Auth/archive/master.zip --activate
|
||||||
|
|
||||||
|
# install the WP Mail Logging plugin to test emails
|
||||||
|
wp plugin install wp-mail-logging --activate
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
- support for custom container name
|
- support for custom container name
|
||||||
- Insert a 12 hour delay in using new docker image tags
|
- Insert a 12 hour delay in using new docker image tags
|
||||||
- Package `bin` script `wc-e2e`
|
- Package `bin` script `wc-e2e`
|
||||||
|
- WP Mail Log plugin as part of container initialization
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
/*
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
const { runMerchantOrderEmailsTest } = require( '@woocommerce/e2e-core-tests' );
|
||||||
|
|
||||||
|
runMerchantOrderEmailsTest();
|
|
@ -20,6 +20,10 @@
|
||||||
- `createSimpleProductWithCategory` component which creates a simple product with categories, containing three parameters for title, price and category name.
|
- `createSimpleProductWithCategory` component which creates a simple product with categories, containing three parameters for title, price and category name.
|
||||||
- `applyCoupon( couponName )` util helper method which applies previously created coupon to cart or checkout
|
- `applyCoupon( couponName )` util helper method which applies previously created coupon to cart or checkout
|
||||||
- `removeCoupon()` util helper method that removes a single coupon within cart or checkout
|
- `removeCoupon()` util helper method that removes a single coupon within cart or checkout
|
||||||
|
- `selectOrderAction( action )` util helper method to select and initiate an order action in the Order Action postbox
|
||||||
|
- `merchant.openEmailLog()` go to the WP Mail Log page
|
||||||
|
- `deleteAllEmailLogs` delete all email logs in the WP Mail Log plugin
|
||||||
|
- `clickUpdateOrder( noticeText, waitForSave )` util helper that clicks the `Update` button on an order
|
||||||
|
|
||||||
## Changes
|
## Changes
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ describe( 'Cart page', () => {
|
||||||
| `openSettings` | | Go to WooCommerce -> Settings |
|
| `openSettings` | | Go to WooCommerce -> Settings |
|
||||||
| `runSetupWizard` | | Open the onboarding profiler |
|
| `runSetupWizard` | | Open the onboarding profiler |
|
||||||
| `updateOrderStatus` | `orderId, status` | Update the status of an order |
|
| `updateOrderStatus` | `orderId, status` | Update the status of an order |
|
||||||
|
| `openEmailLog` | | Open the WP Mail Log page |
|
||||||
|
|
||||||
### Shopper `shopper`
|
### Shopper `shopper`
|
||||||
|
|
||||||
|
@ -102,9 +103,11 @@ describe( 'Cart page', () => {
|
||||||
| `clickFilter` | `selector` | Click on a list page filter |
|
| `clickFilter` | `selector` | Click on a list page filter |
|
||||||
| `moveAllItemsToTrash` | | Moves all items in a list view to the Trash |
|
| `moveAllItemsToTrash` | | Moves all items in a list view to the Trash |
|
||||||
| `verifyAndPublish` | `noticeText` | Verify that an item can be published |
|
| `verifyAndPublish` | `noticeText` | Verify that an item can be published |
|
||||||
| `selectOptionInSelect2` | `selector, value` | helper method that searchs for select2 type fields and select plus insert value inside
|
| `selectOptionInSelect2` | `selector, value` | helper method that searchs for select2 type fields and select plus insert value inside |
|
||||||
| `applyCoupon` | `couponName` | helper method which applies a coupon in cart or checkout
|
| `applyCoupon` | `couponName` | helper method which applies a coupon in cart or checkout |
|
||||||
| `removeCoupon` | | helper method that removes a single coupon within cart or checkout
|
| `removeCoupon` | | helper method that removes a single coupon within cart or checkout |
|
||||||
|
| `selectOrderAction` | `action` | Helper method to select an order action in the `Order Actions` postbox |
|
||||||
|
| `clickUpdateOrder` | `noticeText`, `waitForSave` | Helper method to click the Update button on the order details page |
|
||||||
|
|
||||||
### Test Utilities
|
### Test Utilities
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { merchant } from './flows';
|
import { merchant } from './flows';
|
||||||
import { clickTab, uiUnblocked, verifyCheckboxIsUnset, evalAndClick, selectOptionInSelect2 } from './page-utils';
|
import { clickTab, uiUnblocked, verifyCheckboxIsUnset, evalAndClick, selectOptionInSelect2, setCheckbox } from './page-utils';
|
||||||
import factories from './factories';
|
import factories from './factories';
|
||||||
|
|
||||||
const config = require( 'config' );
|
const config = require( 'config' );
|
||||||
|
@ -473,6 +473,42 @@ const createCoupon = async ( couponAmount = '5', discountType = 'Fixed cart disc
|
||||||
return couponCode;
|
return couponCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Click the Update button on the order details page.
|
||||||
|
*
|
||||||
|
* @param noticeText The text that appears in the notice after updating the order.
|
||||||
|
* @param waitForSave Optionally wait for auto save.
|
||||||
|
*/
|
||||||
|
const clickUpdateOrder = async ( noticeText, waitForSave = false ) => {
|
||||||
|
if ( waitForSave ) {
|
||||||
|
await page.waitFor( 2000 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUpdate order
|
||||||
|
await expect( page ).toClick( 'button.save_order' );
|
||||||
|
await page.waitForSelector( '.updated.notice' );
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
await expect( page ).toMatchElement( '.updated.notice', { text: noticeText } );
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all email logs in the WP Mail Logging plugin page.
|
||||||
|
*/
|
||||||
|
const deleteAllEmailLogs = async () => {
|
||||||
|
await merchant.openEmailLog();
|
||||||
|
|
||||||
|
// Make sure we have emails to delete. If we don't, this selector will return null.
|
||||||
|
if ( await page.$( '#bulk-action-selector-top' ) !== null ) {
|
||||||
|
await setCheckbox( '#cb-select-all-1' );
|
||||||
|
await expect( page ).toSelect( '#bulk-action-selector-top', 'Delete' );
|
||||||
|
await Promise.all( [
|
||||||
|
page.click( '#doaction' ),
|
||||||
|
page.waitForNavigation( { waitUntil: 'networkidle0' } ),
|
||||||
|
] );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
completeOnboardingWizard,
|
completeOnboardingWizard,
|
||||||
createSimpleProduct,
|
createSimpleProduct,
|
||||||
|
@ -483,4 +519,6 @@ export {
|
||||||
addProductToOrder,
|
addProductToOrder,
|
||||||
createCoupon,
|
createCoupon,
|
||||||
createSimpleProductWithCategory,
|
createSimpleProductWithCategory,
|
||||||
|
clickUpdateOrder,
|
||||||
|
deleteAllEmailLogs,
|
||||||
};
|
};
|
||||||
|
|
|
@ -169,6 +169,12 @@ const merchant = {
|
||||||
await expect( page ).toMatchElement( 'label[for="customer_user"] a[href*=user-edit]', { text: 'Profile' } );
|
await expect( page ).toMatchElement( 'label[for="customer_user"] a[href*=user-edit]', { text: 'Profile' } );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
openEmailLog: async () => {
|
||||||
|
await page.goto( `${baseUrl}wp-admin/tools.php?page=wpml_plugin_log`, {
|
||||||
|
waitUntil: 'networkidle0',
|
||||||
|
} );
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = merchant;
|
module.exports = merchant;
|
||||||
|
|
|
@ -242,6 +242,20 @@ const removeCoupon = async ( couponCode ) => {
|
||||||
await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon has been removed.'});
|
await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon has been removed.'});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Select and perform an order action in the `Order actions` postbox.
|
||||||
|
*
|
||||||
|
* @param {string} action The action to take on the order.
|
||||||
|
*/
|
||||||
|
const selectOrderAction = async ( action ) => {
|
||||||
|
await page.select( 'select[name=wc_order_action]', action );
|
||||||
|
await Promise.all( [
|
||||||
|
page.click( '.wc-reload' ),
|
||||||
|
page.waitForNavigation( { waitUntil: 'networkidle0' } ),
|
||||||
|
] );
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
clearAndFillInput,
|
clearAndFillInput,
|
||||||
clickTab,
|
clickTab,
|
||||||
|
@ -260,4 +274,5 @@ export {
|
||||||
selectOptionInSelect2,
|
selectOptionInSelect2,
|
||||||
applyCoupon,
|
applyCoupon,
|
||||||
removeCoupon,
|
removeCoupon,
|
||||||
|
selectOrderAction,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue