Merge branch 'trunk' into e2e/e2e-merchant-search-orders

This commit is contained in:
Veljko V 2021-03-06 12:13:18 +01:00 committed by GitHub
commit 1fb27ec3dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 180 additions and 17 deletions

View File

@ -2,7 +2,7 @@
/**
* Abstract payment tokens
*
* Generic payment tokens functionality which can be extended by idividual types of payment tokens.
* Generic payment tokens functionality which can be extended by individual types of payment tokens.
*
* @class WC_Payment_Token
* @package WooCommerce\Abstracts

View File

@ -907,7 +907,7 @@ class WC_Order extends WC_Abstract_Order {
$address = WC()->countries->get_formatted_address( $raw_address );
/**
* Filter orders formatterd billing address.
* Filter orders formatted billing address.
*
* @since 3.8.0
* @param string $address Formatted billing address string.
@ -933,7 +933,7 @@ class WC_Order extends WC_Abstract_Order {
}
/**
* Filter orders formatterd shipping address.
* Filter orders formatted shipping address.
*
* @since 3.8.0
* @param string $address Formatted billing address string.

View File

@ -25,6 +25,7 @@
- Shopper Cart Apply Coupon
- Merchant Order Searching
- Shopper Variable product info updates on different variations
- Merchant order emails flow
## Fixed

View File

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

View File

@ -74,10 +74,10 @@ const runCouponApiTest = () => {
it('can delete a coupon', async () => {
// Delete the coupon
const deletedCoupon = await repository.delete( coupon.id );
const status = await repository.delete( coupon.id );
// If the delete is successful, the response comes back truthy
expect( deletedCoupon ).toBeTruthy();
expect( status ).toBeTruthy();
});
});
};

View File

@ -69,6 +69,11 @@ const runExternalProductAPITest = () => {
const transformed = await repository.read( product.id );
expect( transformed ).toEqual( expect.objectContaining( transformedProperties ) );
});
it('can delete an external product', async () => {
const status = repository.delete( product.id );
expect( status ).toBeTruthy();
});
});
};

View File

@ -71,11 +71,16 @@ const runGroupedProductAPITest = () => {
expect( response.data ).toEqual( expect.objectContaining( rawProperties ) );
});
it('can retrieve a transformed external product', async () => {
it('can retrieve a transformed grouped product', async () => {
// Read product via the repository.
const transformed = await repository.read( product.id );
expect( transformed ).toEqual( expect.objectContaining( baseGroupedProduct ) );
});
it('can delete a grouped product', async () => {
const status = repository.delete( product.id );
expect( status ).toBeTruthy();
});
});
};

View File

@ -33,6 +33,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' );
@ -114,6 +115,7 @@ module.exports = {
runProductEditDetailsTest,
runProductSearchTest,
runMerchantOrdersCustomerPaymentPage,
runMerchantOrderEmailsTest,
runMerchantTests,
runOrderSearchingTest,
runProductBrowseSearchSortTest,

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

@ -21,6 +21,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`
@ -106,6 +107,8 @@ describe( 'Cart page', () => {
| `searchForOrder` | `value, orderId, customerName` | helper method that searchs for an order via many different terms
| `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' );
@ -476,6 +476,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,
@ -486,4 +522,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

@ -258,6 +258,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,
@ -277,4 +291,5 @@ export {
searchForOrder,
applyCoupon,
removeCoupon,
selectOrderAction,
};

View File

@ -141,7 +141,7 @@ class WC_Tests_Checkout extends WC_Unit_Test_Case {
}
/**
* Test usage limit for guest users uasge limit per user is set.
* Test usage limit for guest users usage limit per user is set.
*
* @throws Exception When unable to create order.
*/

View File

@ -18,7 +18,7 @@ class Dummy_Widget extends WC_Widget {
* Output widget.
*
* @param mixed $args Arguments.
* @param WP_Widget $instance Intance of WP_Widget.
* @param WP_Widget $instance Instance of WP_Widget.
* @return void
*/
public function widget( $args, $instance ) {

View File

@ -85,7 +85,7 @@ class WC_Stock_Functions_Tests extends \WC_Unit_Test_Case {
}
/**
* Test inventory count after order status transtions which reduces stock to another status which also reduces stock.
* Test inventory count after order status transitions which reduces stock to another status which also reduces stock.
* Stock should have reduced once already, and should not reduce again.
*/
public function test_status_transition_stock_reduce_to_stock_reduce() {
@ -97,7 +97,7 @@ class WC_Stock_Functions_Tests extends \WC_Unit_Test_Case {
}
/**
* Test inventory count after order status transtions which reduces stock to another status which restores stock.
* Test inventory count after order status transitions which reduces stock to another status which restores stock.
* Should should have already reduced once, and will increase again after transitioning.
*/
public function test_status_transition_stock_reduce_to_stock_restore() {
@ -109,7 +109,7 @@ class WC_Stock_Functions_Tests extends \WC_Unit_Test_Case {
}
/**
* Test inventory count after order status transtions which reduces stock to another status which don't affect inventory.
* Test inventory count after order status transitions which reduces stock to another status which don't affect inventory.
* Stock should have already reduced, and will not change on transitioning.
*/
public function test_status_transition_stock_reduce_to_stock_no_effect() {
@ -133,7 +133,7 @@ class WC_Stock_Functions_Tests extends \WC_Unit_Test_Case {
}
/**
* Test inventory count after order status transtions which restores stock to another status which also restores stock.
* Test inventory count after order status transitions which restores stock to another status which also restores stock.
* Stock should not have reduced, and will remain the same even after transition (i.e. should not be restocked again).
*/
public function test_status_transition_stock_restore_to_stock_restore() {
@ -145,7 +145,7 @@ class WC_Stock_Functions_Tests extends \WC_Unit_Test_Case {
}
/**
* Test inventory count after order status transtions which restores stock to another status which don't affect inventory.
* Test inventory count after order status transitions which restores stock to another status which don't affect inventory.
* Stock should not have reduced, and will remain the same even after transition.
*/
public function test_status_transition_stock_restore_to_stock_no_effect() {
@ -157,7 +157,7 @@ class WC_Stock_Functions_Tests extends \WC_Unit_Test_Case {
}
/**
* Test inventory count after order status transtions which don't affect inventory stock to another status which reduces stock.
* Test inventory count after order status transitions which don't affect inventory stock to another status which reduces stock.
* Stock would not have been affected, but will reduce after transition.
*/
public function test_status_transition_stock_no_effect_to_stock_reduce() {
@ -169,7 +169,7 @@ class WC_Stock_Functions_Tests extends \WC_Unit_Test_Case {
}
/**
* Test inventory count after order status transtions which don't affect inventory stock to another status which restores stock.
* Test inventory count after order status transitions which don't affect inventory stock to another status which restores stock.
* Stock would not have been affected, and will not be restored after transition (since it was not reduced to begin with).
*/
public function test_status_transition_stock_no_effect_to_stock_restore() {
@ -181,7 +181,7 @@ class WC_Stock_Functions_Tests extends \WC_Unit_Test_Case {
}
/**
* Test inventory count after order status transtions which don't affect inventory stock to another status which also don't affect inventory.
* Test inventory count after order status transitions which don't affect inventory stock to another status which also don't affect inventory.
* Stock levels will not change before or after the transition.
*/
public function test_status_transition_stock_no_effect_to_stock_no_effect() {