Add E2E test for third-party local pickup methods (https://github.com/woocommerce/woocommerce-blocks/pull/8543)
* Add third party local pickup method to woo-test-helper plugin * Add test to check for checkout with local pickup * Ensure local pickup is disabled when done with tests * Add a more reliable selector for the "use same address for billing" box * Prevent local pickup rates showing if local pickup is not enabled * Check billing details after placing local pickup order * Change local pickup unit test so rates dont show if localPickup disabled * Use existing const instead of getSetting * Update tests to mock constant from @woocommerce/block-settings --------- Co-authored-by: Niels Lange <info@nielslange.de>
This commit is contained in:
parent
4067541ac2
commit
f708214246
|
@ -6,6 +6,7 @@ import {
|
||||||
CartShippingRate,
|
CartShippingRate,
|
||||||
} from '@woocommerce/type-defs/cart';
|
} from '@woocommerce/type-defs/cart';
|
||||||
import { getSetting } from '@woocommerce/settings';
|
import { getSetting } from '@woocommerce/settings';
|
||||||
|
import { LOCAL_PICKUP_ENABLED } from '@woocommerce/block-settings';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of packages in a shippingRates array.
|
* Get the number of packages in a shippingRates array.
|
||||||
|
@ -36,6 +37,9 @@ export const isPackageRateCollectable = (
|
||||||
export const hasCollectableRate = (
|
export const hasCollectableRate = (
|
||||||
chosenRates: string[] | string
|
chosenRates: string[] | string
|
||||||
): boolean => {
|
): boolean => {
|
||||||
|
if ( ! LOCAL_PICKUP_ENABLED ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if ( Array.isArray( chosenRates ) ) {
|
if ( Array.isArray( chosenRates ) ) {
|
||||||
return !! chosenRates.find( ( rate ) =>
|
return !! chosenRates.find( ( rate ) =>
|
||||||
collectableMethodIds.includes( rate )
|
collectableMethodIds.includes( rate )
|
||||||
|
|
|
@ -6,20 +6,27 @@ import {
|
||||||
isPackageRateCollectable,
|
isPackageRateCollectable,
|
||||||
} from '@woocommerce/base-utils';
|
} from '@woocommerce/base-utils';
|
||||||
import { CartShippingRate } from '@woocommerce/type-defs/cart';
|
import { CartShippingRate } from '@woocommerce/type-defs/cart';
|
||||||
|
import * as blockSettings from '@woocommerce/block-settings';
|
||||||
|
|
||||||
jest.mock( '@woocommerce/settings', () => {
|
jest.mock( '@woocommerce/settings', () => {
|
||||||
return {
|
return {
|
||||||
|
__esModule: true,
|
||||||
...jest.requireActual( '@woocommerce/settings' ),
|
...jest.requireActual( '@woocommerce/settings' ),
|
||||||
getSetting: ( setting: string ) => {
|
getSetting: jest.fn().mockImplementation( ( setting: string ) => {
|
||||||
if ( setting === 'collectableMethodIds' ) {
|
if ( setting === 'collectableMethodIds' ) {
|
||||||
return [ 'local_pickup' ];
|
return [ 'local_pickup' ];
|
||||||
}
|
}
|
||||||
return jest
|
return jest
|
||||||
.requireActual( '@woocommerce/settings' )
|
.requireActual( '@woocommerce/settings' )
|
||||||
.getSetting( setting );
|
.getSetting( setting );
|
||||||
},
|
} ),
|
||||||
};
|
};
|
||||||
} );
|
} );
|
||||||
|
jest.mock( '@woocommerce/block-settings', () => ( {
|
||||||
|
__esModule: true,
|
||||||
|
...jest.requireActual( '@woocommerce/block-settings' ),
|
||||||
|
LOCAL_PICKUP_ENABLED: true,
|
||||||
|
} ) );
|
||||||
describe( 'hasCollectableRate', () => {
|
describe( 'hasCollectableRate', () => {
|
||||||
it( 'correctly identifies if an array contains a collectable rate', () => {
|
it( 'correctly identifies if an array contains a collectable rate', () => {
|
||||||
const ratesToTest = [ 'flat_rate', 'local_pickup' ];
|
const ratesToTest = [ 'flat_rate', 'local_pickup' ];
|
||||||
|
@ -27,6 +34,12 @@ describe( 'hasCollectableRate', () => {
|
||||||
const ratesToTest2 = [ 'flat_rate', 'free_shipping' ];
|
const ratesToTest2 = [ 'flat_rate', 'free_shipping' ];
|
||||||
expect( hasCollectableRate( ratesToTest2 ) ).toBe( false );
|
expect( hasCollectableRate( ratesToTest2 ) ).toBe( false );
|
||||||
} );
|
} );
|
||||||
|
it( 'returns false for all rates if local pickup is disabled', () => {
|
||||||
|
// Attempt to assign to const or readonly variable error on next line is OK because it is mocked by jest
|
||||||
|
blockSettings.LOCAL_PICKUP_ENABLED = false;
|
||||||
|
const ratesToTest = [ 'flat_rate', 'local_pickup' ];
|
||||||
|
expect( hasCollectableRate( ratesToTest ) ).toBe( false );
|
||||||
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
describe( 'isPackageRateCollectable', () => {
|
describe( 'isPackageRateCollectable', () => {
|
||||||
|
|
|
@ -15,7 +15,7 @@ import {
|
||||||
getToggleIdByLabel,
|
getToggleIdByLabel,
|
||||||
switchBlockInspectorTabWhenGutenbergIsInstalled,
|
switchBlockInspectorTabWhenGutenbergIsInstalled,
|
||||||
} from '@woocommerce/blocks-test-utils';
|
} from '@woocommerce/blocks-test-utils';
|
||||||
|
import { visitAdminPage } from '@wordpress/e2e-test-utils';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
|
@ -27,6 +27,7 @@ import {
|
||||||
SHIPPING_DETAILS,
|
SHIPPING_DETAILS,
|
||||||
SIMPLE_PHYSICAL_PRODUCT_NAME,
|
SIMPLE_PHYSICAL_PRODUCT_NAME,
|
||||||
SIMPLE_VIRTUAL_PRODUCT_NAME,
|
SIMPLE_VIRTUAL_PRODUCT_NAME,
|
||||||
|
BASE_URL,
|
||||||
} from '../../../../utils';
|
} from '../../../../utils';
|
||||||
|
|
||||||
import { createCoupon } from '../../../utils';
|
import { createCoupon } from '../../../utils';
|
||||||
|
@ -35,9 +36,92 @@ let coupon;
|
||||||
|
|
||||||
describe( 'Shopper → Checkout', () => {
|
describe( 'Shopper → Checkout', () => {
|
||||||
beforeAll( async () => {
|
beforeAll( async () => {
|
||||||
|
// Check that Woo Collection is enabled.
|
||||||
|
await page.goto(
|
||||||
|
`${ BASE_URL }?check_third_party_local_pickup_method`
|
||||||
|
);
|
||||||
|
// eslint-disable-next-line jest/no-standalone-expect
|
||||||
|
await expect( page ).toMatch( 'Woo Collection' );
|
||||||
|
|
||||||
await shopper.block.emptyCart();
|
await shopper.block.emptyCart();
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
describe( 'Local pickup', () => {
|
||||||
|
beforeAll( async () => {
|
||||||
|
// Enable local pickup.
|
||||||
|
await visitAdminPage(
|
||||||
|
'admin.php',
|
||||||
|
'page=wc-settings&tab=shipping§ion=pickup_location'
|
||||||
|
);
|
||||||
|
|
||||||
|
const localPickupCheckbox = await page.waitForXPath(
|
||||||
|
'//input[@name="local_pickup_enabled"]'
|
||||||
|
);
|
||||||
|
const isCheckboxChecked = await page.evaluate(
|
||||||
|
( checkbox ) => checkbox.checked,
|
||||||
|
localPickupCheckbox
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( isCheckboxChecked === true ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line jest/no-standalone-expect
|
||||||
|
await expect( page ).toClick( 'label', {
|
||||||
|
text: 'Enable local pickup',
|
||||||
|
} );
|
||||||
|
// eslint-disable-next-line jest/no-standalone-expect
|
||||||
|
await expect( page ).toClick( 'button', {
|
||||||
|
text: 'Save changes',
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
afterAll( async () => {
|
||||||
|
// Disable local pickup.
|
||||||
|
await visitAdminPage(
|
||||||
|
'admin.php',
|
||||||
|
'page=wc-settings&tab=shipping§ion=pickup_location'
|
||||||
|
);
|
||||||
|
|
||||||
|
const localPickupCheckbox = await page.waitForXPath(
|
||||||
|
'//input[@name="local_pickup_enabled"]'
|
||||||
|
);
|
||||||
|
const isCheckboxChecked = await page.evaluate(
|
||||||
|
( checkbox ) => checkbox.checked,
|
||||||
|
localPickupCheckbox
|
||||||
|
);
|
||||||
|
|
||||||
|
// Skip this if it's already unchecked.
|
||||||
|
if ( isCheckboxChecked === false ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line jest/no-standalone-expect
|
||||||
|
await expect( page ).toClick( 'label', {
|
||||||
|
text: 'Enable local pickup',
|
||||||
|
} );
|
||||||
|
// eslint-disable-next-line jest/no-standalone-expect
|
||||||
|
await expect( page ).toClick( 'button', {
|
||||||
|
text: 'Save changes',
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
it( 'The shopper can choose a local pickup option', async () => {
|
||||||
|
await shopper.block.emptyCart();
|
||||||
|
await shopper.block.goToShop();
|
||||||
|
await shopper.addToCartFromShopPage( SIMPLE_PHYSICAL_PRODUCT_NAME );
|
||||||
|
await shopper.block.goToCheckout();
|
||||||
|
await expect( page ).toClick(
|
||||||
|
'.wc-block-checkout__shipping-method-option-title',
|
||||||
|
{
|
||||||
|
text: 'Local Pickup',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
expect( page ).toMatch( 'Woo Collection' );
|
||||||
|
await shopper.block.fillBillingDetails( BILLING_DETAILS );
|
||||||
|
await shopper.block.placeOrder();
|
||||||
|
await shopper.block.verifyBillingDetails( BILLING_DETAILS );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
describe( 'Payment Methods', () => {
|
describe( 'Payment Methods', () => {
|
||||||
it( 'User can change payment methods', async () => {
|
it( 'User can change payment methods', async () => {
|
||||||
await shopper.block.emptyCart();
|
await shopper.block.emptyCart();
|
||||||
|
@ -94,8 +178,12 @@ describe( 'Shopper → Checkout', () => {
|
||||||
await shopper.block.goToShop();
|
await shopper.block.goToShop();
|
||||||
await shopper.addToCartFromShopPage( SIMPLE_PHYSICAL_PRODUCT_NAME );
|
await shopper.addToCartFromShopPage( SIMPLE_PHYSICAL_PRODUCT_NAME );
|
||||||
await shopper.block.goToCheckout();
|
await shopper.block.goToCheckout();
|
||||||
await page.waitForSelector( '#checkbox-control-0' );
|
await page.waitForSelector(
|
||||||
await unsetCheckbox( '#checkbox-control-0' );
|
'.wc-block-checkout__use-address-for-billing input[type="checkbox"]'
|
||||||
|
);
|
||||||
|
await unsetCheckbox(
|
||||||
|
'.wc-block-checkout__use-address-for-billing input[type="checkbox"]'
|
||||||
|
);
|
||||||
await shopper.block.fillShippingDetails( SHIPPING_DETAILS );
|
await shopper.block.fillShippingDetails( SHIPPING_DETAILS );
|
||||||
await shopper.block.fillBillingDetails( BILLING_DETAILS );
|
await shopper.block.fillBillingDetails( BILLING_DETAILS );
|
||||||
await shopper.block.placeOrder();
|
await shopper.block.placeOrder();
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* Plugin Name: Woo Test Helper
|
* Plugin Name: Woo Test Helper
|
||||||
* Description: A helper plugin to control settings within Woo e2e tests.
|
* Description: A helper plugin to control settings within Woo e2e tests.
|
||||||
* Version: 0.0.1
|
* Version: 0.0.2
|
||||||
* Author: Automattic
|
* Author: Automattic
|
||||||
* Author URI: https://automattic.com
|
* Author URI: https://automattic.com
|
||||||
* Text Domain: woo-test-helper
|
* Text Domain: woo-test-helper
|
||||||
|
@ -125,3 +125,125 @@ function setup_cross_sells() {
|
||||||
update_post_meta( $id_product->ID, '_crosssell_ids', wp_list_pluck( $id_cross_sells, 'ID' ) );
|
update_post_meta( $id_product->ID, '_crosssell_ids', wp_list_pluck( $id_cross_sells, 'ID' ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a third party local pickup method, this will have a different ID to the ones we add in the WC Settings.
|
||||||
|
*/
|
||||||
|
function register_third_party_local_pickup_method() {
|
||||||
|
/**
|
||||||
|
* This function initialises our local pickup method.
|
||||||
|
*/
|
||||||
|
function woo_collection_shipping_init() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom Local Pickup method.
|
||||||
|
*/
|
||||||
|
class Woo_Collection_Shipping_Method extends WC_Shipping_Method {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Min amount to be valid.
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
public $min_amount = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requires option.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $requires = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param int $instance_id Shipping method instance.
|
||||||
|
*/
|
||||||
|
public function __construct( $instance_id = 0 ) {
|
||||||
|
$this->id = 'woo_collection_shipping';
|
||||||
|
$this->instance_id = absint( $instance_id );
|
||||||
|
$this->title = 'Woo Collection';
|
||||||
|
$this->method_title = __( 'Woo Collection', 'woo-gutenberg-products-block' );
|
||||||
|
$this->method_description = __( 'Get your order shipped to an Woo Collection point.', 'woo-gutenberg-products-block' );
|
||||||
|
$this->supports = array(
|
||||||
|
'instance-settings',
|
||||||
|
'instance-settings-modal',
|
||||||
|
'local-pickup',
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Woo Collection shipping.
|
||||||
|
*/
|
||||||
|
public function init() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See if Woo Collection shipping is available based on the package and cart.
|
||||||
|
*
|
||||||
|
* @param array $package Shipping package.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function is_available( $package ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to calculate shipping rates for this method. Rates can be added using the add_rate() method.
|
||||||
|
*
|
||||||
|
* @param array $package Shipping package.
|
||||||
|
* @uses WC_Shipping_Method::add_rate()
|
||||||
|
*/
|
||||||
|
public function calculate_shipping( $package = array() ) {
|
||||||
|
$this->add_rate(
|
||||||
|
array(
|
||||||
|
'label' => $this->title,
|
||||||
|
'cost' => 0,
|
||||||
|
'taxes' => false,
|
||||||
|
'package' => $package,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use this hook to initialize your new custom method.
|
||||||
|
add_action( 'woocommerce_shipping_init', 'woo_collection_shipping_init' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the Woo Collection shipping method to the list of available methods in WooCommerce.
|
||||||
|
* @param array $methods The current list of methods.
|
||||||
|
* @return array The modified list of methods.
|
||||||
|
*/
|
||||||
|
function add_woo_collection_shipping( $methods ) {
|
||||||
|
$methods['woo_collection_shipping'] = 'Woo_Collection_Shipping_Method';
|
||||||
|
|
||||||
|
return $methods;
|
||||||
|
}
|
||||||
|
add_filter( 'woocommerce_shipping_methods', 'add_woo_collection_shipping' );
|
||||||
|
}
|
||||||
|
register_third_party_local_pickup_method();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define URL endpoint for setting up third party local pickup method.
|
||||||
|
*/
|
||||||
|
function check_third_party_local_pickup_method() {
|
||||||
|
// phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||||
|
if ( isset( $_GET['check_third_party_local_pickup_method'] ) ) {
|
||||||
|
add_action(
|
||||||
|
'woocommerce_blocks_loaded',
|
||||||
|
function () {
|
||||||
|
$method_titles = array_map(
|
||||||
|
function ( $method ) {
|
||||||
|
return $method->title;
|
||||||
|
},
|
||||||
|
wc()->shipping()->get_shipping_methods()
|
||||||
|
);
|
||||||
|
exit( wp_kses( implode( ', ', $method_titles ), array() ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add_action( 'plugins_loaded', 'check_third_party_local_pickup_method' );
|
||||||
|
|
Loading…
Reference in New Issue