2019-09-24 09:47:47 +00:00
|
|
|
/**
|
|
|
|
* @format
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
2021-04-09 19:15:00 +00:00
|
|
|
import { merchant, IS_RETEST_MODE } from './flows';
|
2021-03-31 20:26:36 +00:00
|
|
|
import {
|
|
|
|
uiUnblocked,
|
|
|
|
verifyCheckboxIsUnset,
|
|
|
|
setCheckbox,
|
2021-04-08 10:41:02 +00:00
|
|
|
unsetCheckbox,
|
|
|
|
evalAndClick,
|
2021-04-26 15:18:40 +00:00
|
|
|
backboneUnblocked,
|
2021-04-27 18:41:50 +00:00
|
|
|
waitForSelectorWithoutThrow,
|
2021-03-31 20:26:36 +00:00
|
|
|
} from './page-utils';
|
2020-09-21 18:22:43 +00:00
|
|
|
import factories from './factories';
|
2021-09-29 21:57:33 +00:00
|
|
|
import { waitForTimeout } from './flows/utils';
|
2021-11-01 20:40:03 +00:00
|
|
|
import { withRestApi } from './flows/with-rest-api';
|
2021-08-20 18:52:29 +00:00
|
|
|
import { Coupon, Order } from '@woocommerce/api';
|
2019-09-24 09:47:47 +00:00
|
|
|
|
2021-04-21 17:45:45 +00:00
|
|
|
const client = factories.api.withDefaultPermalinks;
|
2019-12-06 15:06:48 +00:00
|
|
|
const config = require( 'config' );
|
|
|
|
const simpleProductName = config.get( 'products.simple.name' );
|
2020-12-27 22:18:31 +00:00
|
|
|
const simpleProductPrice = config.has('products.simple.price') ? config.get('products.simple.price') : '9.99';
|
2021-06-05 12:48:38 +00:00
|
|
|
const defaultVariableProduct = config.get('products.variable');
|
2021-06-09 09:08:45 +00:00
|
|
|
const defaultGroupedProduct = config.get('products.grouped');
|
2019-12-06 15:06:48 +00:00
|
|
|
|
2021-01-20 23:19:07 +00:00
|
|
|
/**
|
|
|
|
* Verify and publish
|
|
|
|
*
|
|
|
|
* @param noticeText The text that appears in the notice after publishing.
|
|
|
|
*/
|
|
|
|
const verifyAndPublish = async ( noticeText ) => {
|
2019-09-24 09:47:47 +00:00
|
|
|
// Wait for auto save
|
2021-09-29 21:57:33 +00:00
|
|
|
await waitForTimeout( 2000 );
|
2019-09-24 09:47:47 +00:00
|
|
|
|
|
|
|
// Publish product
|
|
|
|
await expect( page ).toClick( '#publish' );
|
|
|
|
await page.waitForSelector( '.updated.notice' );
|
|
|
|
|
|
|
|
// Verify
|
2021-01-20 23:19:07 +00:00
|
|
|
await expect( page ).toMatchElement( '.updated.notice', { text: noticeText } );
|
2019-09-24 09:47:47 +00:00
|
|
|
};
|
|
|
|
|
2021-01-26 20:59:40 +00:00
|
|
|
/**
|
|
|
|
* Wait for primary button to be enabled and click.
|
|
|
|
*
|
|
|
|
* @param waitForNetworkIdle - Wait for network idle after click
|
|
|
|
* @returns {Promise<void>}
|
|
|
|
*/
|
|
|
|
const waitAndClickPrimary = async ( waitForNetworkIdle = true ) => {
|
|
|
|
// Wait for "Continue" button to become active
|
|
|
|
await page.waitForSelector( 'button.is-primary:not(:disabled)' );
|
|
|
|
await page.click( 'button.is-primary' );
|
|
|
|
if ( waitForNetworkIdle ) {
|
|
|
|
await page.waitForNavigation( { waitUntil: 'networkidle0' } );
|
|
|
|
}
|
|
|
|
};
|
2020-03-27 21:45:20 +00:00
|
|
|
/**
|
|
|
|
* Complete onboarding wizard.
|
|
|
|
*/
|
|
|
|
const completeOnboardingWizard = async () => {
|
|
|
|
// Store Details section
|
2021-04-27 18:41:50 +00:00
|
|
|
await merchant.runSetupWizard();
|
2020-03-27 21:45:20 +00:00
|
|
|
|
|
|
|
// Fill store's address - first line
|
|
|
|
await expect( page ).toFill( '#inspector-text-control-0', config.get( 'addresses.admin.store.addressfirstline' ) );
|
|
|
|
|
|
|
|
// Fill store's address - second line
|
|
|
|
await expect( page ).toFill( '#inspector-text-control-1', config.get( 'addresses.admin.store.addresssecondline' ) );
|
|
|
|
|
|
|
|
// Fill country and state where the store is located
|
|
|
|
await expect( page ).toFill( '.woocommerce-select-control__control-input', config.get( 'addresses.admin.store.countryandstate' ) );
|
|
|
|
|
|
|
|
// Fill the city where the store is located
|
|
|
|
await expect( page ).toFill( '#inspector-text-control-2', config.get( 'addresses.admin.store.city' ) );
|
|
|
|
|
|
|
|
// Fill postcode of the store
|
|
|
|
await expect( page ).toFill( '#inspector-text-control-3', config.get( 'addresses.admin.store.postcode' ) );
|
|
|
|
|
|
|
|
// Verify that checkbox next to "I'm setting up a store for a client" is not selected
|
|
|
|
await verifyCheckboxIsUnset( '.components-checkbox-control__input' );
|
|
|
|
|
2020-03-31 00:12:39 +00:00
|
|
|
// Wait for "Continue" button to become active
|
2020-03-30 17:31:56 +00:00
|
|
|
await page.waitForSelector( 'button.is-primary:not(:disabled)' );
|
2020-03-27 21:45:20 +00:00
|
|
|
|
2020-04-08 21:34:04 +00:00
|
|
|
// Click on "Continue" button to move to the next step
|
|
|
|
await page.click( 'button.is-primary', { text: 'Continue' } );
|
|
|
|
|
2021-04-09 19:15:00 +00:00
|
|
|
// Wait for usage tracking pop-up window to appear on a new site
|
2021-04-27 18:41:50 +00:00
|
|
|
const usageTrackingHeader = await page.$('.components-modal__header-heading');
|
|
|
|
if ( usageTrackingHeader ) {
|
2021-04-09 19:15:00 +00:00
|
|
|
await expect(page).toMatchElement(
|
|
|
|
'.components-modal__header-heading', {text: 'Build a better WooCommerce'}
|
|
|
|
);
|
2020-04-08 21:34:04 +00:00
|
|
|
|
2021-08-09 17:25:13 +00:00
|
|
|
// Query for "No Thanks" buttons
|
|
|
|
const continueButtons = await page.$$( '.woocommerce-usage-modal__actions button.is-secondary' );
|
|
|
|
expect( continueButtons ).toHaveLength( 1 );
|
2020-03-27 21:45:20 +00:00
|
|
|
|
2021-08-09 17:25:13 +00:00
|
|
|
await continueButtons[0].click();
|
2021-04-09 19:15:00 +00:00
|
|
|
}
|
|
|
|
await page.waitForNavigation( { waitUntil: 'networkidle0' } );
|
2020-03-27 21:45:20 +00:00
|
|
|
|
|
|
|
// Industry section
|
|
|
|
|
2020-03-31 00:12:39 +00:00
|
|
|
// Query for the industries checkboxes
|
|
|
|
const industryCheckboxes = await page.$$( '.components-checkbox-control__input' );
|
2020-09-30 19:00:14 +00:00
|
|
|
expect( industryCheckboxes ).toHaveLength( 8 );
|
2020-03-27 21:45:20 +00:00
|
|
|
|
2020-03-31 00:12:39 +00:00
|
|
|
// Select all industries including "Other"
|
2020-09-30 19:00:14 +00:00
|
|
|
for ( let i = 0; i < 8; i++ ) {
|
2020-03-31 00:12:39 +00:00
|
|
|
await industryCheckboxes[i].click();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fill "Other" industry
|
|
|
|
await expect( page ).toFill( '.components-text-control__input', config.get( 'onboardingwizard.industry' ) );
|
|
|
|
|
|
|
|
// Wait for "Continue" button to become active
|
2021-01-26 20:59:40 +00:00
|
|
|
await waitAndClickPrimary();
|
2020-03-27 21:45:20 +00:00
|
|
|
|
|
|
|
// Product types section
|
|
|
|
|
2020-03-31 00:12:39 +00:00
|
|
|
// Query for the product types checkboxes
|
|
|
|
const productTypesCheckboxes = await page.$$( '.components-checkbox-control__input' );
|
2020-09-02 23:14:25 +00:00
|
|
|
expect( productTypesCheckboxes ).toHaveLength( 7 );
|
2020-03-31 00:12:39 +00:00
|
|
|
|
2020-03-31 14:00:43 +00:00
|
|
|
// Select Physical and Downloadable products
|
2020-08-05 11:49:42 +00:00
|
|
|
for ( let i = 1; i < 2; i++ ) {
|
2020-03-31 00:12:39 +00:00
|
|
|
await productTypesCheckboxes[i].click();
|
|
|
|
}
|
2020-03-27 21:45:20 +00:00
|
|
|
|
2020-03-31 00:12:39 +00:00
|
|
|
// Wait for "Continue" button to become active
|
2021-01-26 20:59:40 +00:00
|
|
|
await waitAndClickPrimary();
|
2020-03-27 21:45:20 +00:00
|
|
|
|
|
|
|
// Business Details section
|
|
|
|
|
2021-06-18 10:19:27 +00:00
|
|
|
// Temporarily add delay to reduce test flakiness
|
|
|
|
await page.waitFor( 2000 );
|
|
|
|
|
2020-03-30 17:31:56 +00:00
|
|
|
// Query for the <SelectControl>s
|
|
|
|
const selectControls = await page.$$( '.woocommerce-select-control' );
|
|
|
|
expect( selectControls ).toHaveLength( 2 );
|
2020-03-31 00:12:39 +00:00
|
|
|
|
2020-03-27 21:45:20 +00:00
|
|
|
// Fill the number of products you plan to sell
|
2020-03-30 17:31:56 +00:00
|
|
|
await selectControls[0].click();
|
2020-07-27 21:38:43 +00:00
|
|
|
await page.waitForSelector( '.woocommerce-select-control__control' );
|
2020-03-30 17:31:56 +00:00
|
|
|
await expect( page ).toClick( '.woocommerce-select-control__option', { text: config.get( 'onboardingwizard.numberofproducts' ) } );
|
2020-03-27 21:45:20 +00:00
|
|
|
|
|
|
|
// Fill currently selling elsewhere
|
2020-03-30 17:31:56 +00:00
|
|
|
await selectControls[1].click();
|
2020-07-27 21:38:43 +00:00
|
|
|
await page.waitForSelector( '.woocommerce-select-control__control' );
|
2020-03-30 17:31:56 +00:00
|
|
|
await expect( page ).toClick( '.woocommerce-select-control__option', { text: config.get( 'onboardingwizard.sellingelsewhere' ) } );
|
2020-03-27 21:45:20 +00:00
|
|
|
|
2020-03-31 00:12:39 +00:00
|
|
|
// Wait for "Continue" button to become active
|
2021-01-26 20:59:40 +00:00
|
|
|
await waitAndClickPrimary( false );
|
2020-03-27 21:45:20 +00:00
|
|
|
|
2021-01-26 20:59:40 +00:00
|
|
|
// Skip installing extensions
|
2021-03-31 20:26:36 +00:00
|
|
|
await unsetCheckbox( '.components-checkbox-control__input' );
|
|
|
|
await verifyCheckboxIsUnset( '.components-checkbox-control__input' );
|
2021-01-26 20:59:40 +00:00
|
|
|
await waitAndClickPrimary();
|
2020-03-31 00:12:39 +00:00
|
|
|
|
|
|
|
// Theme section
|
2021-01-26 20:59:40 +00:00
|
|
|
await waitAndClickPrimary();
|
2020-04-08 21:34:04 +00:00
|
|
|
|
|
|
|
// End of onboarding wizard
|
2021-04-09 19:39:30 +00:00
|
|
|
if ( IS_RETEST_MODE ) {
|
2021-04-09 19:15:00 +00:00
|
|
|
// Home screen modal can't be reset via the rest api.
|
|
|
|
return;
|
|
|
|
}
|
2020-03-31 00:12:39 +00:00
|
|
|
|
2020-08-21 15:03:02 +00:00
|
|
|
// Wait for homescreen welcome modal to appear
|
2021-04-27 18:41:50 +00:00
|
|
|
let welcomeHeader = await waitForSelectorWithoutThrow( '.woocommerce__welcome-modal__page-content' );
|
|
|
|
if ( ! welcomeHeader ) {
|
|
|
|
return;
|
|
|
|
}
|
2020-08-21 15:03:02 +00:00
|
|
|
|
2021-04-27 18:41:50 +00:00
|
|
|
// Click two Next buttons
|
|
|
|
for ( let b = 0; b < 2; b++ ) {
|
|
|
|
await page.waitForSelector('button.components-guide__forward-button');
|
|
|
|
await page.click('button.components-guide__forward-button');
|
|
|
|
}
|
2020-08-21 15:03:02 +00:00
|
|
|
// Wait for "Let's go" button to become active
|
|
|
|
await page.waitForSelector( 'button.components-guide__finish-button' );
|
|
|
|
await page.click( 'button.components-guide__finish-button' );
|
2020-03-27 21:45:20 +00:00
|
|
|
};
|
|
|
|
|
2019-09-24 09:47:47 +00:00
|
|
|
/**
|
|
|
|
* Create simple product.
|
2021-02-18 20:53:30 +00:00
|
|
|
*
|
2021-11-19 21:24:35 +00:00
|
|
|
* @param {string} productTitle Defaults to Simple Product. Customizable title.
|
|
|
|
* @param {string} productPrice Defaults to $9.99. Customizable pricing.
|
|
|
|
* @param {Object} additionalProps Defaults to nothing. Additional product properties.
|
2019-09-24 09:47:47 +00:00
|
|
|
*/
|
2021-11-19 21:24:35 +00:00
|
|
|
const createSimpleProduct = async (
|
|
|
|
productTitle = simpleProductName,
|
|
|
|
productPrice = simpleProductPrice,
|
|
|
|
additionalProps = {}
|
|
|
|
) => {
|
|
|
|
const newProduct = {
|
2021-02-18 20:53:30 +00:00
|
|
|
name: productTitle,
|
2021-11-09 18:09:26 +00:00
|
|
|
regularPrice: productPrice,
|
2021-11-19 21:24:35 +00:00
|
|
|
...additionalProps,
|
|
|
|
};
|
|
|
|
const product = await factories.products.simple.create( newProduct );
|
2020-09-25 20:49:54 +00:00
|
|
|
return product.id;
|
2021-11-19 21:24:35 +00:00
|
|
|
};
|
2019-09-24 09:47:47 +00:00
|
|
|
|
2021-02-04 13:44:23 +00:00
|
|
|
/**
|
|
|
|
* Create simple product with categories
|
|
|
|
*
|
|
|
|
* @param productName Product's name which can be changed when writing a test
|
|
|
|
* @param productPrice Product's price which can be changed when writing a test
|
|
|
|
* @param categoryName Product's category which can be changed when writing a test
|
|
|
|
*/
|
|
|
|
const createSimpleProductWithCategory = async ( productName, productPrice, categoryName ) => {
|
2021-10-29 21:19:14 +00:00
|
|
|
// Get the category ID so we can add it to the product below
|
|
|
|
const categoryId = await withRestApi.createProductCategory( categoryName );
|
|
|
|
|
2021-03-09 02:39:30 +00:00
|
|
|
const product = await factories.products.simple.create( {
|
|
|
|
name: productName,
|
|
|
|
regularPrice: productPrice,
|
|
|
|
categories: [
|
|
|
|
{
|
2021-10-29 21:19:14 +00:00
|
|
|
id: categoryId,
|
2021-03-09 02:39:30 +00:00
|
|
|
}
|
|
|
|
],
|
|
|
|
isVirtual: true,
|
|
|
|
} );
|
2021-02-04 13:44:23 +00:00
|
|
|
|
2021-03-09 02:39:30 +00:00
|
|
|
return product.id;
|
2021-02-04 13:44:23 +00:00
|
|
|
};
|
|
|
|
|
2019-09-24 09:47:47 +00:00
|
|
|
/**
|
|
|
|
* Create variable product.
|
2021-06-07 08:11:41 +00:00
|
|
|
* Also, create variations for all attributes.
|
2021-06-05 12:48:38 +00:00
|
|
|
*
|
2021-06-03 11:16:20 +00:00
|
|
|
* @param varProduct Defaults to the variable product object in `default.json`
|
|
|
|
* @returns the ID of the created variable product
|
2019-09-24 09:47:47 +00:00
|
|
|
*/
|
2021-06-05 12:48:38 +00:00
|
|
|
const createVariableProduct = async (varProduct = defaultVariableProduct) => {
|
|
|
|
const { attributes } = varProduct;
|
2021-06-09 09:08:45 +00:00
|
|
|
const { id } = await factories.products.variable.create(varProduct); // create the variable product
|
2021-06-05 12:48:38 +00:00
|
|
|
const variations = [];
|
|
|
|
const buffer = []; // accumulated attributes while looping
|
|
|
|
const aIdx = 0; // attributes[] index
|
|
|
|
|
|
|
|
// Create variation for all attributes
|
|
|
|
const createVariation = (aIdx) => {
|
|
|
|
const { name, options } = attributes[aIdx];
|
|
|
|
const isLastAttribute = aIdx === attributes.length - 1;
|
|
|
|
|
|
|
|
// Add each attribute value to the buffer.
|
|
|
|
options.forEach((opt) => {
|
|
|
|
buffer.push({
|
|
|
|
name: name,
|
|
|
|
option: opt
|
|
|
|
});
|
|
|
|
|
|
|
|
if (isLastAttribute) {
|
|
|
|
// If this is the last attribute, it means the variation is now complete.
|
|
|
|
// Save whatever's been accumulated in the buffer to the `variations[]` array.
|
|
|
|
variations.push({
|
|
|
|
attributes: [...buffer]
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
// Otherwise, move to the next attribute first
|
|
|
|
// before proceeding to the next value in this attribute.
|
|
|
|
createVariation(aIdx + 1);
|
|
|
|
}
|
2019-09-24 09:47:47 +00:00
|
|
|
|
2021-06-05 12:48:38 +00:00
|
|
|
buffer.pop();
|
|
|
|
});
|
|
|
|
};
|
|
|
|
createVariation(aIdx);
|
|
|
|
|
|
|
|
// Set some properties of 1st variation
|
|
|
|
variations[0].regularPrice = '9.99';
|
|
|
|
variations[0].virtual = true;
|
|
|
|
|
|
|
|
// Set some properties of 2nd variation
|
|
|
|
variations[1].regularPrice = '11.99';
|
|
|
|
variations[1].virtual = true;
|
|
|
|
|
|
|
|
// Set some properties of 3rd variation
|
|
|
|
variations[2].regularPrice = '20';
|
|
|
|
variations[2].weight = '200';
|
|
|
|
variations[2].dimensions = {
|
|
|
|
length: '10',
|
|
|
|
width: '20',
|
|
|
|
height: '15'
|
|
|
|
};
|
|
|
|
variations[2].manage_stock = true;
|
|
|
|
|
|
|
|
// Use API to create each variation
|
|
|
|
for (const v of variations) {
|
2021-06-02 13:12:31 +00:00
|
|
|
await factories.products.variation.create({
|
2021-06-05 12:48:38 +00:00
|
|
|
productId: id,
|
2021-06-03 11:16:20 +00:00
|
|
|
variation: v
|
2021-06-02 13:12:31 +00:00
|
|
|
});
|
2019-09-24 09:47:47 +00:00
|
|
|
}
|
|
|
|
|
2021-06-05 12:48:38 +00:00
|
|
|
return id;
|
2019-09-24 09:47:47 +00:00
|
|
|
};
|
|
|
|
|
2021-01-19 17:20:04 +00:00
|
|
|
/**
|
|
|
|
* Create grouped product.
|
2021-08-09 17:25:13 +00:00
|
|
|
*
|
2021-06-09 09:08:45 +00:00
|
|
|
* @param groupedProduct Defaults to the grouped product object in `default.json`
|
2021-06-07 09:41:36 +00:00
|
|
|
* @returns ID of the grouped product
|
2021-01-19 17:20:04 +00:00
|
|
|
*/
|
2021-06-09 09:08:45 +00:00
|
|
|
const createGroupedProduct = async (groupedProduct = defaultGroupedProduct) => {
|
|
|
|
const { name, groupedProducts } = groupedProduct;
|
|
|
|
const simpleProductIds = [];
|
|
|
|
let groupedProductRequest;
|
|
|
|
|
|
|
|
// Using the api, create simple products to be grouped
|
|
|
|
for (const simpleProduct of groupedProducts) {
|
|
|
|
const { id } = await factories.products.simple.create(simpleProduct);
|
|
|
|
simpleProductIds.push(id);
|
|
|
|
}
|
2021-01-19 17:20:04 +00:00
|
|
|
|
2021-06-09 09:08:45 +00:00
|
|
|
// Using the api, create the grouped product
|
|
|
|
groupedProductRequest = {
|
|
|
|
name: name,
|
|
|
|
groupedProducts: simpleProductIds
|
|
|
|
};
|
|
|
|
const { id } = await factories.products.grouped.create(
|
|
|
|
groupedProductRequest
|
|
|
|
);
|
2021-06-07 09:41:36 +00:00
|
|
|
|
|
|
|
return id;
|
|
|
|
};
|
2021-01-19 17:20:04 +00:00
|
|
|
|
2021-08-17 22:43:22 +00:00
|
|
|
/**
|
|
|
|
* Use the API to create an order with the provided details.
|
|
|
|
*
|
|
|
|
* @param {object} orderOptions
|
|
|
|
* @returns {Promise<number>} ID of the created order.
|
|
|
|
*/
|
|
|
|
const createOrder = async ( orderOptions = {} ) => {
|
2021-08-20 18:52:29 +00:00
|
|
|
const newOrder = {
|
2021-11-19 21:24:35 +00:00
|
|
|
...( orderOptions.status && { status: orderOptions.status } ),
|
|
|
|
...( orderOptions.customerId && {
|
|
|
|
customer_id: orderOptions.customerId,
|
|
|
|
} ),
|
|
|
|
...( orderOptions.customerBilling && {
|
|
|
|
billing: orderOptions.customerBilling,
|
|
|
|
} ),
|
|
|
|
...( orderOptions.customerShipping && {
|
|
|
|
shipping: orderOptions.customerShipping,
|
|
|
|
} ),
|
|
|
|
...( orderOptions.productId && {
|
|
|
|
line_items: [ { product_id: orderOptions.productId } ],
|
|
|
|
} ),
|
|
|
|
...( orderOptions.lineItems && {
|
|
|
|
line_items: orderOptions.lineItems,
|
|
|
|
} ),
|
2021-08-20 18:52:29 +00:00
|
|
|
};
|
2021-08-17 22:43:22 +00:00
|
|
|
|
2021-08-20 18:52:29 +00:00
|
|
|
const repository = Order.restRepository( client );
|
|
|
|
const order = await repository.create( newOrder );
|
2021-08-17 22:43:22 +00:00
|
|
|
|
2021-08-20 18:52:29 +00:00
|
|
|
return order.id;
|
2021-11-19 21:24:35 +00:00
|
|
|
};
|
2021-08-17 22:43:22 +00:00
|
|
|
|
2020-11-27 21:49:20 +00:00
|
|
|
/**
|
|
|
|
* Create a basic order with the provided order status.
|
|
|
|
*
|
|
|
|
* @param orderStatus Status of the new order. Defaults to `Pending payment`.
|
|
|
|
*/
|
|
|
|
const createSimpleOrder = async ( orderStatus = 'Pending payment' ) => {
|
|
|
|
// Go to 'Add new order' page
|
2020-12-22 13:59:16 +00:00
|
|
|
await merchant.openNewOrder();
|
2020-11-27 21:49:20 +00:00
|
|
|
|
|
|
|
// Make sure we're on the add order page
|
|
|
|
await expect( page.title() ).resolves.toMatch( 'Add new order' );
|
|
|
|
|
|
|
|
// Set order status
|
|
|
|
await expect( page ).toSelect( '#order_status', orderStatus );
|
|
|
|
|
|
|
|
// Wait for auto save
|
|
|
|
await page.waitFor( 2000 );
|
|
|
|
|
|
|
|
// Create the order
|
|
|
|
await expect( page ).toClick( 'button.save_order' );
|
|
|
|
await page.waitForSelector( '#message' );
|
|
|
|
|
|
|
|
// Verify
|
|
|
|
await expect( page ).toMatchElement( '#message', { text: 'Order updated.' } );
|
2020-12-11 04:27:04 +00:00
|
|
|
|
|
|
|
const variablePostId = await page.$( '#post_ID' );
|
|
|
|
let variablePostIdValue = ( await ( await variablePostId.getProperty( 'value' ) ).jsonValue() );
|
|
|
|
return variablePostIdValue;
|
2020-11-27 21:49:20 +00:00
|
|
|
};
|
|
|
|
|
2021-06-30 10:48:10 +00:00
|
|
|
/**
|
|
|
|
* Creates a batch of orders from the given `statuses`
|
|
|
|
* using the "Batch Create Order" API.
|
2021-09-29 21:57:33 +00:00
|
|
|
*
|
2021-06-30 10:48:10 +00:00
|
|
|
* @param statuses Array of order statuses
|
|
|
|
*/
|
|
|
|
const batchCreateOrders = async (statuses) => {
|
|
|
|
const defaultOrder = config.get('orders.basicPaidOrder');
|
|
|
|
const path = '/wc/v3/orders/batch';
|
|
|
|
|
|
|
|
// Create an order per status
|
|
|
|
const orders = statuses.map((s) => {
|
|
|
|
return {
|
|
|
|
...defaultOrder,
|
|
|
|
status: s
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
// Set the request payload from the created orders.
|
|
|
|
// Then send the API request.
|
|
|
|
const payload = { create: orders };
|
2021-10-14 21:45:39 +00:00
|
|
|
const response = await client.post(path, payload);
|
|
|
|
expect( response.status ).toEqual(200);
|
2021-06-30 10:48:10 +00:00
|
|
|
};
|
|
|
|
|
2020-12-11 04:27:04 +00:00
|
|
|
/**
|
2020-12-22 13:59:16 +00:00
|
|
|
* Adds a product to an order in the merchant.
|
2020-12-11 04:27:04 +00:00
|
|
|
*
|
|
|
|
* @param orderId ID of the order to add the product to.
|
|
|
|
* @param productName Name of the product being added to the order.
|
|
|
|
*/
|
|
|
|
const addProductToOrder = async ( orderId, productName ) => {
|
2020-12-22 13:59:16 +00:00
|
|
|
await merchant.goToOrder( orderId );
|
2020-12-11 04:27:04 +00:00
|
|
|
|
|
|
|
// Add a product to the order
|
|
|
|
await expect( page ).toClick( 'button.add-line-item' );
|
|
|
|
await expect( page ).toClick( 'button.add-order-item' );
|
|
|
|
await page.waitForSelector( '.wc-backbone-modal-header' );
|
|
|
|
await expect( page ).toClick( '.wc-backbone-modal-content .wc-product-search' );
|
2021-04-27 20:45:21 +00:00
|
|
|
await expect( page ).toFill('#wc-backbone-modal-dialog + .select2-container .select2-search__field', productName);
|
|
|
|
await page.waitForSelector( 'li[aria-selected="true"]', { timeout: 10000 } );
|
2020-12-11 04:27:04 +00:00
|
|
|
await expect( page ).toClick( 'li[aria-selected="true"]' );
|
|
|
|
await page.click( '.wc-backbone-modal-content #btn-ok' );
|
|
|
|
|
2021-04-26 15:18:40 +00:00
|
|
|
await backboneUnblocked();
|
2020-12-11 04:27:04 +00:00
|
|
|
|
|
|
|
// Verify the product we added shows as a line item now
|
|
|
|
await expect( page ).toMatchElement( '.wc-order-item-name', { text: productName } );
|
|
|
|
}
|
|
|
|
|
2020-12-16 03:14:02 +00:00
|
|
|
/**
|
|
|
|
* Creates a basic coupon with the provided coupon amount. Returns the coupon code.
|
|
|
|
*
|
|
|
|
* @param couponAmount Amount to be applied. Defaults to 5.
|
2021-01-06 16:08:29 +00:00
|
|
|
* @param discountType Type of a coupon. Defaults to Fixed cart discount.
|
2020-12-16 03:14:02 +00:00
|
|
|
*/
|
2021-01-06 16:08:29 +00:00
|
|
|
const createCoupon = async ( couponAmount = '5', discountType = 'Fixed cart discount' ) => {
|
2021-04-21 17:45:45 +00:00
|
|
|
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:
|
2021-04-27 20:45:21 +00:00
|
|
|
couponType = discountType;
|
2021-04-21 17:45:45 +00:00
|
|
|
}
|
2020-12-16 03:14:02 +00:00
|
|
|
|
|
|
|
// Fill in coupon code
|
2021-04-21 17:45:45 +00:00
|
|
|
let couponCode = 'code-' + couponType + new Date().getTime().toString();
|
|
|
|
const repository = Coupon.restRepository( client );
|
|
|
|
await repository.create( {
|
|
|
|
code: couponCode,
|
|
|
|
discountType: couponType,
|
|
|
|
amount: couponAmount,
|
|
|
|
});
|
2020-12-16 03:14:02 +00:00
|
|
|
|
|
|
|
return couponCode;
|
|
|
|
};
|
|
|
|
|
2021-02-11 16:47:58 +00:00
|
|
|
/**
|
|
|
|
* Adds a shipping zone along with a shipping method.
|
|
|
|
*
|
|
|
|
* @param zoneName Shipping zone name.
|
2021-03-31 08:01:41 +00:00
|
|
|
* @param zoneLocation Shiping zone location. Defaults to country:US. For states use: state:US:CA
|
2021-02-12 17:19:48 +00:00
|
|
|
* @param zipCode Shipping zone zip code. Defaults to empty one space.
|
2021-02-12 15:10:23 +00:00
|
|
|
* @param zoneMethod Shipping method type. Defaults to flat_rate (use also: free_shipping or local_pickup)
|
2021-02-11 16:47:58 +00:00
|
|
|
*/
|
2021-03-31 08:01:41 +00:00
|
|
|
const addShippingZoneAndMethod = async ( zoneName, zoneLocation = 'country:US', zipCode = ' ', zoneMethod = 'flat_rate' ) => {
|
2021-02-11 16:47:58 +00:00
|
|
|
await merchant.openNewShipping();
|
2021-03-17 17:48:06 +00:00
|
|
|
|
2021-02-11 16:47:58 +00:00
|
|
|
// Fill shipping zone name
|
2021-02-12 16:43:01 +00:00
|
|
|
await page.waitForSelector('input#zone_name');
|
2021-02-11 16:47:58 +00:00
|
|
|
await expect(page).toFill('input#zone_name', zoneName);
|
|
|
|
|
|
|
|
// Select shipping zone location
|
2021-03-31 08:01:41 +00:00
|
|
|
await expect(page).toSelect('select[name="zone_locations"]', zoneLocation);
|
2021-02-11 16:47:58 +00:00
|
|
|
|
2021-08-25 22:15:06 +00:00
|
|
|
await uiUnblocked();
|
|
|
|
|
2021-02-12 16:43:01 +00:00
|
|
|
// Fill shipping zone postcode if needed otherwise just put empty space
|
2021-03-05 10:27:39 +00:00
|
|
|
await page.waitForSelector('a.wc-shipping-zone-postcodes-toggle');
|
2021-02-12 16:43:01 +00:00
|
|
|
await expect(page).toClick('a.wc-shipping-zone-postcodes-toggle');
|
|
|
|
await expect(page).toFill('#zone_postcodes', zipCode);
|
2021-02-13 08:59:14 +00:00
|
|
|
await expect(page).toMatchElement('#zone_postcodes', zipCode);
|
2021-02-12 16:43:01 +00:00
|
|
|
await expect(page).toClick('button#submit');
|
|
|
|
|
2021-08-25 22:15:06 +00:00
|
|
|
await uiUnblocked();
|
|
|
|
|
2021-02-11 16:47:58 +00:00
|
|
|
// Add shipping zone method
|
2021-03-31 08:01:41 +00:00
|
|
|
await page.waitFor(1000);
|
2021-02-12 16:43:01 +00:00
|
|
|
await expect(page).toClick('button.wc-shipping-zone-add-method', {text:'Add shipping method'});
|
2021-03-17 17:48:06 +00:00
|
|
|
await page.waitForSelector('.wc-shipping-zone-method-selector');
|
2021-02-11 16:47:58 +00:00
|
|
|
await expect(page).toSelect('select[name="add_method_id"]', zoneMethod);
|
|
|
|
await expect(page).toClick('button#btn-ok');
|
|
|
|
await page.waitForSelector('#zone_locations');
|
2021-08-25 22:15:06 +00:00
|
|
|
|
|
|
|
await uiUnblocked();
|
2021-02-11 16:47:58 +00:00
|
|
|
};
|
|
|
|
|
2021-03-03 16:45:16 +00:00
|
|
|
/**
|
2021-03-03 17:49:06 +00:00
|
|
|
* Click the Update button on the order details page.
|
2021-03-03 16:45:16 +00:00
|
|
|
*
|
|
|
|
* @param noticeText The text that appears in the notice after updating the order.
|
2021-03-03 17:52:50 +00:00
|
|
|
* @param waitForSave Optionally wait for auto save.
|
2021-03-03 16:45:16 +00:00
|
|
|
*/
|
2021-03-03 17:52:50 +00:00
|
|
|
const clickUpdateOrder = async ( noticeText, waitForSave = false ) => {
|
|
|
|
if ( waitForSave ) {
|
|
|
|
await page.waitFor( 2000 );
|
|
|
|
}
|
2021-03-03 16:45:16 +00:00
|
|
|
|
2021-03-12 23:00:10 +00:00
|
|
|
// Update order
|
2021-03-03 16:45:16 +00:00
|
|
|
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' } ),
|
|
|
|
] );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-04-08 10:41:02 +00:00
|
|
|
/**
|
|
|
|
* Delete all the existing shipping zones.
|
|
|
|
*/
|
|
|
|
const deleteAllShippingZones = async () => {
|
|
|
|
await merchant.openSettings('shipping');
|
2021-04-08 13:09:59 +00:00
|
|
|
|
2021-04-08 10:41:02 +00:00
|
|
|
// Delete existing shipping zones.
|
|
|
|
try {
|
|
|
|
let zone = await page.$( '.wc-shipping-zone-delete' );
|
|
|
|
if ( zone ) {
|
|
|
|
// WP action links aren't clickable because they are hidden with a left=-9999 style.
|
|
|
|
await page.evaluate(() => {
|
|
|
|
document.querySelector('.wc-shipping-zone-name .row-actions')
|
|
|
|
.style
|
|
|
|
.left = '0';
|
|
|
|
});
|
|
|
|
while ( zone ) {
|
|
|
|
await evalAndClick( '.wc-shipping-zone-delete' );
|
|
|
|
await uiUnblocked();
|
|
|
|
zone = await page.$( '.wc-shipping-zone-delete' );
|
|
|
|
};
|
|
|
|
};
|
|
|
|
} catch (error) {
|
|
|
|
// Prevent an error here causing the test to fail.
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2020-02-11 16:29:48 +00:00
|
|
|
export {
|
2020-03-27 21:45:20 +00:00
|
|
|
completeOnboardingWizard,
|
2020-02-11 16:29:48 +00:00
|
|
|
createSimpleProduct,
|
|
|
|
createVariableProduct,
|
2021-01-19 17:20:04 +00:00
|
|
|
createGroupedProduct,
|
2020-11-27 21:49:20 +00:00
|
|
|
createSimpleOrder,
|
2020-02-11 16:29:48 +00:00
|
|
|
verifyAndPublish,
|
2020-12-11 04:27:04 +00:00
|
|
|
addProductToOrder,
|
2020-12-16 03:14:02 +00:00
|
|
|
createCoupon,
|
2021-02-11 16:47:58 +00:00
|
|
|
addShippingZoneAndMethod,
|
2021-02-04 13:44:23 +00:00
|
|
|
createSimpleProductWithCategory,
|
2021-03-07 14:46:03 +00:00
|
|
|
clickUpdateOrder,
|
2021-03-03 16:45:16 +00:00
|
|
|
deleteAllEmailLogs,
|
2021-04-08 10:41:02 +00:00
|
|
|
deleteAllShippingZones,
|
2021-08-31 11:36:51 +00:00
|
|
|
batchCreateOrders,
|
2021-08-20 18:52:29 +00:00
|
|
|
createOrder,
|
2020-02-11 16:29:48 +00:00
|
|
|
};
|