Merge pull request #29270 from woocommerce/add/merchant-order-email-flow

Add merchant order email flow e2e test
This commit is contained in:
Ron Rennick 2021-03-05 11:21:13 -04:00 committed by GitHub
commit 30d7b2ce9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 158 additions and 5 deletions

View File

@ -24,6 +24,7 @@
- Merchant Orders Customer Checkout Page
- Shopper Cart Apply Coupon
- Shopper Variable product info updates on different variations
- Merchant order emails flow
## Fixed

View File

@ -58,6 +58,7 @@ The functions to access the core tests are:
- `runProductEditDetailsTest` - Merchant can edit an existing product
- `runProductSearchTest` - Merchant can search for a product and view it
- `runMerchantOrdersCustomerPaymentPage` - Merchant can visit the customer payment page
- `runMerchantOrderEmailsTest` - Merchant can receive order emails and resend emails by Order Actions
### Shopper

View File

@ -32,6 +32,7 @@ const runOrderApplyCouponTest = require( './merchant/wp-admin-order-apply-coupon
const runProductEditDetailsTest = require( './merchant/wp-admin-product-edit-details.test' );
const runProductSearchTest = require( './merchant/wp-admin-product-search.test' );
const runMerchantOrdersCustomerPaymentPage = require( './merchant/wp-admin-order-customer-payment-page.test' );
const runMerchantOrderEmailsTest = require( './merchant/wp-admin-order-emails.test' );
// REST API tests
const runExternalProductAPITest = require( './api/external-product.test' );
@ -112,6 +113,7 @@ module.exports = {
runProductEditDetailsTest,
runProductSearchTest,
runMerchantOrdersCustomerPaymentPage,
runMerchantOrderEmailsTest,
runMerchantTests,
runProductBrowseSearchSortTest,
runApiTests,

View File

@ -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;

View File

@ -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.
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

View File

@ -11,6 +11,7 @@
- support for custom container name
- Insert a 12 hour delay in using new docker image tags
- Package `bin` script `wc-e2e`
- WP Mail Log plugin as part of container initialization
## Fixed

View File

@ -0,0 +1,6 @@
/*
* Internal dependencies
*/
const { runMerchantOrderEmailsTest } = require( '@woocommerce/e2e-core-tests' );
runMerchantOrderEmailsTest();

View File

@ -20,6 +20,10 @@
- `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
- `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

View File

@ -54,6 +54,7 @@ describe( 'Cart page', () => {
| `openSettings` | | Go to WooCommerce -> Settings |
| `runSetupWizard` | | Open the onboarding profiler |
| `updateOrderStatus` | `orderId, status` | Update the status of an order |
| `openEmailLog` | | Open the WP Mail Log page |
### Shopper `shopper`
@ -102,9 +103,11 @@ describe( 'Cart page', () => {
| `clickFilter` | `selector` | Click on a list page filter |
| `moveAllItemsToTrash` | | Moves all items in a list view to the Trash |
| `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
| `applyCoupon` | `couponName` | helper method which applies a coupon in cart or checkout
| `removeCoupon` | | helper method that removes a single coupon within cart or checkout
| `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 |
| `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

View File

@ -6,7 +6,7 @@
* Internal dependencies
*/
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';
const config = require( 'config' );
@ -473,6 +473,42 @@ const createCoupon = async ( couponAmount = '5', discountType = 'Fixed cart disc
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 {
completeOnboardingWizard,
createSimpleProduct,
@ -483,4 +519,6 @@ export {
addProductToOrder,
createCoupon,
createSimpleProductWithCategory,
clickUpdateOrder,
deleteAllEmailLogs,
};

View File

@ -169,6 +169,12 @@ const merchant = {
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;

View File

@ -242,6 +242,20 @@ const removeCoupon = async ( couponCode ) => {
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 {
clearAndFillInput,
clickTab,
@ -260,4 +274,5 @@ export {
selectOptionInSelect2,
applyCoupon,
removeCoupon,
selectOrderAction,
};