Shopper → Checkout → Can apply single-use coupon once (https://github.com/woocommerce/woocommerce-blocks/pull/6174)
* Add "single-use" coupon to the fixture data * Create a first draft of the coupon e2e test * Create single use coupon code constant * Create "applyCouponFromCheckout" function * Remove the "single-use" coupon from the fixture data * Setup coupon creation using Woo's Rest API * Add single-use coupon E2E test * Move discount XPath definition to the expressions file * Clean comments * Remove unnecessary delay function * Refactor to a more human friendly check * Clear the setup in the afterAll branch (delete coupon) Co-authored-by: Saad Tarhi <saad.tarhi@automattic.com>
This commit is contained in:
parent
eb196226d8
commit
c636cb1bbe
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { withRestApi } from '@woocommerce/e2e-utils';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { shopper } from '../../../utils';
|
||||
import { createCoupon } from '../../utils';
|
||||
import { SIMPLE_PRODUCT_NAME } from '../../../utils/constants';
|
||||
|
||||
if ( process.env.WOOCOMMERCE_BLOCKS_PHASE < 2 )
|
||||
// eslint-disable-next-line jest/no-focused-tests
|
||||
test.only( `Skipping checkout tests`, () => {} );
|
||||
|
||||
let coupon;
|
||||
|
||||
beforeAll( async () => {
|
||||
coupon = await createCoupon( { usageLimit: 1 } );
|
||||
await shopper.block.emptyCart();
|
||||
} );
|
||||
|
||||
afterAll( async () => {
|
||||
await withRestApi.deleteCoupon( coupon.id );
|
||||
await shopper.block.emptyCart();
|
||||
} );
|
||||
|
||||
describe( 'Shopper → Checkout → Can apply single-use coupon once', () => {
|
||||
it( 'allows checkout to apply single-use coupon once', async () => {
|
||||
await shopper.goToShop();
|
||||
await shopper.addToCartFromShopPage( SIMPLE_PRODUCT_NAME );
|
||||
await shopper.block.goToCheckout();
|
||||
await shopper.block.applyCouponFromCheckout( coupon.code );
|
||||
|
||||
const discountBlockSelector = '.wc-block-components-totals-discount';
|
||||
const discountAppliedCouponCodeSelector =
|
||||
'.wc-block-components-totals-discount__coupon-list-item span.wc-block-components-chip__text';
|
||||
const discountValueSelector =
|
||||
'.wc-block-components-totals-discount .wc-block-components-totals-item__value';
|
||||
|
||||
// Verify that the discount had been applied correctly on the checkout page.
|
||||
await page.waitForSelector( discountBlockSelector );
|
||||
await expect( page ).toMatchElement( discountValueSelector, {
|
||||
text: coupon.amount,
|
||||
} );
|
||||
await expect( page ).toMatchElement(
|
||||
discountAppliedCouponCodeSelector,
|
||||
{
|
||||
text: coupon.code,
|
||||
}
|
||||
);
|
||||
|
||||
await shopper.block.placeOrder();
|
||||
await expect( page ).toMatch( 'Your order has been received.' );
|
||||
|
||||
// Verify that the discount had been applied correctly on the order confirmation page.
|
||||
await expect( page ).toMatchElement( `th`, { text: 'Discount' } );
|
||||
await expect( page ).toMatchElement( `span.woocommerce-Price-amount`, {
|
||||
text: coupon.amount,
|
||||
} );
|
||||
} );
|
||||
|
||||
it( 'Prevents checkout applying single-use coupon twice', async () => {
|
||||
await shopper.goToShop();
|
||||
await shopper.addToCartFromShopPage( SIMPLE_PRODUCT_NAME );
|
||||
await shopper.block.goToCheckout();
|
||||
await shopper.block.applyCouponFromCheckout( coupon.code );
|
||||
await expect( page ).toMatch( 'Coupon usage limit has been reached.' );
|
||||
} );
|
||||
} );
|
|
@ -1,6 +1,7 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { Coupon, HTTPClientFactory } from '@woocommerce/api';
|
||||
import config from 'config';
|
||||
import {
|
||||
activateTheme,
|
||||
|
@ -29,6 +30,11 @@ import { elementExists, getElementData, getTextContent } from './page-utils';
|
|||
*/
|
||||
|
||||
export const BASE_URL = config.get( 'url' );
|
||||
export const adminUsername = config.get( 'users.admin.username' );
|
||||
export const adminPassword = config.get( 'users.admin.password' );
|
||||
export const client = HTTPClientFactory.build( BASE_URL )
|
||||
.withBasicAuth( adminUsername, adminPassword )
|
||||
.create();
|
||||
export const GUTENBERG_EDITOR_CONTEXT =
|
||||
process.env.GUTENBERG_EDITOR_CONTEXT || 'core';
|
||||
export const DEFAULT_TIMEOUT = 30000;
|
||||
|
@ -352,3 +358,46 @@ export const addBlockToFSEArea = async ( blockName ) => {
|
|||
);
|
||||
await insertButton.click();
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a basic coupon with the provided coupon amount. Returns the coupon code.
|
||||
*
|
||||
* @param {Object} [coupon] Coupon object. Default to fixed cart type and amount = 5.
|
||||
* @param {string} [coupon.amount] Amount to be applied. Defaults to 5.
|
||||
* @param {string} [coupon.discountType] Type of a coupon. Defaults to Fixed cart discount.
|
||||
* @param {number} [coupon.usageLimit] How many times the coupon can be used in total. Defaults to -1.
|
||||
*/
|
||||
export const createCoupon = async ( coupon ) => {
|
||||
const {
|
||||
amount = '5',
|
||||
discountType = 'Fixed cart discount',
|
||||
usageLimit = -1,
|
||||
} = coupon || { amount: '5', discountType: 'Fixed cart discount' };
|
||||
|
||||
let couponType;
|
||||
switch ( discountType ) {
|
||||
case 'Fixed cart discount':
|
||||
couponType = 'fixed_cart';
|
||||
break;
|
||||
case 'Fixed product discount':
|
||||
couponType = 'fixed_product';
|
||||
break;
|
||||
case 'Percentage discount':
|
||||
couponType = 'percent';
|
||||
break;
|
||||
default:
|
||||
couponType = discountType;
|
||||
}
|
||||
|
||||
// Fill in coupon code
|
||||
const couponCode = 'code-' + couponType + new Date().getTime().toString();
|
||||
const repository = Coupon.restRepository( client );
|
||||
const createdCoupon = await repository.create( {
|
||||
code: couponCode,
|
||||
discountType: couponType,
|
||||
amount,
|
||||
usageLimit,
|
||||
} );
|
||||
|
||||
return createdCoupon;
|
||||
};
|
||||
|
|
|
@ -390,6 +390,20 @@ export const shopper = {
|
|||
|
||||
await expect( page.$x( cartItemXPath ) ).resolves.toHaveLength( 1 );
|
||||
},
|
||||
|
||||
applyCouponFromCheckout: async ( couponCode ) => {
|
||||
const couponInputSelector =
|
||||
'#wc-block-components-totals-coupon__input-0';
|
||||
const couponApplyButtonSelector =
|
||||
'.wc-block-components-totals-coupon__button';
|
||||
const couponExpandButtonSelector =
|
||||
'.wc-block-components-totals-coupon button';
|
||||
|
||||
await expect( page ).toClick( couponExpandButtonSelector );
|
||||
await expect( page ).toFill( couponInputSelector, couponCode );
|
||||
await expect( page ).toClick( couponApplyButtonSelector );
|
||||
await page.waitForNetworkIdle();
|
||||
},
|
||||
},
|
||||
|
||||
isLoggedIn: async () => {
|
||||
|
|
Loading…
Reference in New Issue