Merge branch 'trunk' into e2e/e2e-shopper-calculate-shipping
This commit is contained in:
commit
2b82c60107
|
@ -1,5 +1,15 @@
|
|||
== Changelog ==
|
||||
|
||||
= 5.2.1 2021-04-14 =
|
||||
|
||||
**WooCommerce**
|
||||
|
||||
* Update - WooCommerce Blocks package 4.7.2. #29660
|
||||
|
||||
**WooCommerce Blocks - 4.7.2**
|
||||
|
||||
* Fix - Check if Cart and Checkout are registered before removing payment methods. ([4056](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4056))
|
||||
|
||||
= 5.2.0 2021-04-13 =
|
||||
|
||||
**WooCommerce**
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
"psr/container": "1.0.0",
|
||||
"woocommerce/action-scheduler": "3.1.6",
|
||||
"woocommerce/woocommerce-admin": "2.1.5",
|
||||
"woocommerce/woocommerce-blocks": "4.7.1"
|
||||
"woocommerce/woocommerce-blocks": "4.7.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"bamarni/composer-bin-plugin": "^1.4"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "5005eed74baf10300e2895e9b6a4f344",
|
||||
"content-hash": "aaad3b20adf49ba997d4be94865087c6",
|
||||
"packages": [
|
||||
{
|
||||
"name": "automattic/jetpack-autoloader",
|
||||
|
@ -579,16 +579,16 @@
|
|||
},
|
||||
{
|
||||
"name": "woocommerce/woocommerce-blocks",
|
||||
"version": "v4.7.1",
|
||||
"version": "v4.7.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/woocommerce/woocommerce-gutenberg-products-block.git",
|
||||
"reference": "841c49b8626f4eb717056a2d1e3eba6140f45e2c"
|
||||
"reference": "942e58553b1a299ad04842e7f0d7465d9e029ac3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/841c49b8626f4eb717056a2d1e3eba6140f45e2c",
|
||||
"reference": "841c49b8626f4eb717056a2d1e3eba6140f45e2c",
|
||||
"url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/942e58553b1a299ad04842e7f0d7465d9e029ac3",
|
||||
"reference": "942e58553b1a299ad04842e7f0d7465d9e029ac3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -624,9 +624,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues",
|
||||
"source": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/tree/v4.7.1"
|
||||
"source": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/tree/v4.7.2"
|
||||
},
|
||||
"time": "2021-04-02T11:18:50+00:00"
|
||||
"time": "2021-04-13T16:06:16+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
|
12
readme.txt
12
readme.txt
|
@ -4,7 +4,7 @@ Tags: e-commerce, store, sales, sell, woo, shop, cart, checkout, downloadable, d
|
|||
Requires at least: 5.5
|
||||
Tested up to: 5.7
|
||||
Requires PHP: 7.0
|
||||
Stable tag: 5.2.0
|
||||
Stable tag: 5.2.1
|
||||
License: GPLv3
|
||||
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
|
@ -160,6 +160,16 @@ WooCommerce comes with some sample data you can use to see how products look; im
|
|||
|
||||
== Changelog ==
|
||||
|
||||
= 5.2.1 2021-04-14 =
|
||||
|
||||
**WooCommerce**
|
||||
|
||||
* Update - WooCommerce Blocks package 4.7.2. #29660
|
||||
|
||||
**WooCommerce Blocks - 4.7.2**
|
||||
|
||||
* Fix - Check if Cart and Checkout are registered before removing payment methods. ([4056](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4056))
|
||||
|
||||
= 5.2.0 2021-04-13 =
|
||||
|
||||
**WooCommerce**
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
- Shopper Checkout Login Account
|
||||
- Shopper My Account Create Account
|
||||
- Shopper Cart Calculate Shipping
|
||||
- Shopper Cart Redirection
|
||||
|
||||
## Fixed
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ The functions to access the core tests are:
|
|||
- `runCheckoutLoginAccountTest` - Shopper can login to an account during checkout
|
||||
- `runMyAccountCreateAccountTest` - Shopper can create an account via my account page
|
||||
- `runCartCalculateShippingTest` - Shopper can calculate shipping in the cart
|
||||
- `runCartRedirectionTest` - Shopper is redirected to the cart page after adding to cart
|
||||
|
||||
### REST API
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ const runVariableProductUpdateTest = require( './shopper/front-end-variable-prod
|
|||
const runCheckoutCreateAccountTest = require( './shopper/front-end-checkout-create-account.test' );
|
||||
const runCheckoutLoginAccountTest = require( './shopper/front-end-checkout-login-account.test' );
|
||||
const runCartCalculateShippingTest = require( './shopper/front-end-cart-calculate-shipping.test' );
|
||||
const runCartRedirectionTest = require( './shopper/front-end-cart-redirection.test' );
|
||||
|
||||
// Merchant tests
|
||||
const runAddNewShippingZoneTest = require ( './merchant/wp-admin-settings-shipping-zones.test' );
|
||||
|
@ -71,6 +72,7 @@ const runShopperTests = () => {
|
|||
runCheckoutCreateAccountTest();
|
||||
runCheckoutLoginAccountTest();
|
||||
runCartCalculateShippingTest();
|
||||
runCartRedirectionTest();
|
||||
};
|
||||
|
||||
const runMerchantTests = () => {
|
||||
|
@ -147,5 +149,6 @@ module.exports = {
|
|||
runImportProductsTest,
|
||||
runCheckoutLoginAccountTest,
|
||||
runCartCalculateShippingTest,
|
||||
runCartRedirectionTest,
|
||||
runMyAccountCreateAccountTest,
|
||||
};
|
||||
|
|
|
@ -4,12 +4,186 @@
|
|||
*/
|
||||
const {
|
||||
merchant,
|
||||
verifyPublishAndTrash
|
||||
} = require( '@woocommerce/e2e-utils' );
|
||||
verifyPublishAndTrash,
|
||||
uiUnblocked
|
||||
} = require('@woocommerce/e2e-utils');
|
||||
const config = require('config');
|
||||
const {
|
||||
HTTPClientFactory,
|
||||
VariableProduct,
|
||||
GroupedProduct,
|
||||
SimpleProduct,
|
||||
ProductVariation,
|
||||
ExternalProduct
|
||||
} = require('@woocommerce/api');
|
||||
|
||||
const taxRates = [
|
||||
{
|
||||
name: 'Tax Rate Simple',
|
||||
rate: '10',
|
||||
class: 'tax-class-simple'
|
||||
},
|
||||
{
|
||||
name: 'Tax Rate Variable',
|
||||
rate: '20',
|
||||
class: 'tax-class-variable'
|
||||
},
|
||||
{
|
||||
name: 'Tax Rate External',
|
||||
rate: '30',
|
||||
class: 'tax-class-external'
|
||||
}
|
||||
];
|
||||
|
||||
const taxTotals = ['$10.00', '$40.00', '$240.00'];
|
||||
|
||||
const initProducts = async () => {
|
||||
const apiUrl = config.get('url');
|
||||
const adminUsername = config.get('users.admin.username');
|
||||
const adminPassword = config.get('users.admin.password');
|
||||
const httpClient = HTTPClientFactory.build(apiUrl)
|
||||
.withBasicAuth(adminUsername, adminPassword)
|
||||
.create();
|
||||
const taxClassesPath = '/wc/v3/taxes/classes';
|
||||
const taxClasses = [
|
||||
{
|
||||
name: 'Tax Class Simple',
|
||||
slug: 'tax-class-simple-698962'
|
||||
},
|
||||
{
|
||||
name: 'Tax Class Variable',
|
||||
slug: 'tax-class-variable-790238'
|
||||
},
|
||||
{
|
||||
name: 'Tax Class External',
|
||||
slug: 'tax-class-external-991321'
|
||||
}
|
||||
];
|
||||
|
||||
// Enable taxes in settings
|
||||
const enableTaxes = async () => {
|
||||
const path = '/wc/v3/settings/general/woocommerce_calc_taxes';
|
||||
const data = {
|
||||
value: 'yes'
|
||||
};
|
||||
await httpClient.put(path, data);
|
||||
};
|
||||
await enableTaxes();
|
||||
|
||||
// Initialize tax classes
|
||||
const initTaxClasses = async () => {
|
||||
for (const classToBeAdded of taxClasses) {
|
||||
await httpClient.post(taxClassesPath, classToBeAdded);
|
||||
}
|
||||
};
|
||||
await initTaxClasses();
|
||||
|
||||
// Initialize tax rates
|
||||
const initTaxRates = async () => {
|
||||
const path = '/wc/v3/taxes';
|
||||
|
||||
for (const rateToBeAdded of taxRates) {
|
||||
await httpClient.post(path, rateToBeAdded);
|
||||
}
|
||||
};
|
||||
await initTaxRates();
|
||||
|
||||
// Initialization functions per product type
|
||||
const initSimpleProduct = async () => {
|
||||
const repo = SimpleProduct.restRepository(httpClient);
|
||||
const simpleProduct = {
|
||||
name: 'Simple Product 273722',
|
||||
regularPrice: '100',
|
||||
taxClass: 'Tax Class Simple'
|
||||
};
|
||||
return await repo.create(simpleProduct);
|
||||
};
|
||||
const initVariableProduct = async () => {
|
||||
const variations = [
|
||||
{
|
||||
regularPrice: '200',
|
||||
attributes: [
|
||||
{
|
||||
name: 'Size',
|
||||
option: 'Small'
|
||||
},
|
||||
{
|
||||
name: 'Colour',
|
||||
option: 'Yellow'
|
||||
}
|
||||
],
|
||||
taxClass: 'Tax Class Variable'
|
||||
},
|
||||
{
|
||||
regularPrice: '300',
|
||||
attributes: [
|
||||
{
|
||||
name: 'Size',
|
||||
option: 'Medium'
|
||||
},
|
||||
{
|
||||
name: 'Colour',
|
||||
option: 'Magenta'
|
||||
}
|
||||
],
|
||||
taxClass: 'Tax Class Variable'
|
||||
}
|
||||
];
|
||||
const variableProductData = {
|
||||
name: 'Variable Product 024611',
|
||||
type: 'variable',
|
||||
taxClass: 'Tax Class Variable'
|
||||
};
|
||||
|
||||
const variationRepo = ProductVariation.restRepository(httpClient);
|
||||
const productRepo = VariableProduct.restRepository(httpClient);
|
||||
const variableProduct = await productRepo.create(variableProductData);
|
||||
for (const v of variations) {
|
||||
await variationRepo.create(variableProduct.id, v);
|
||||
}
|
||||
|
||||
return variableProduct;
|
||||
};
|
||||
const initGroupedProduct = async () => {
|
||||
const groupedRepo = GroupedProduct.restRepository(httpClient);
|
||||
const defaultGroupedData = config.get('products.grouped');
|
||||
const groupedProductData = {
|
||||
...defaultGroupedData,
|
||||
name: 'Grouped Product 858012'
|
||||
};
|
||||
|
||||
return await groupedRepo.create(groupedProductData);
|
||||
};
|
||||
const initExternalProduct = async () => {
|
||||
const repo = ExternalProduct.restRepository(httpClient);
|
||||
const defaultProps = config.get('products.external');
|
||||
const props = {
|
||||
...defaultProps,
|
||||
name: 'External product 786794',
|
||||
regularPrice: '800',
|
||||
taxClass: 'Tax Class External'
|
||||
};
|
||||
return await repo.create(props);
|
||||
};
|
||||
|
||||
// Create a product for each product type
|
||||
const simpleProduct = await initSimpleProduct();
|
||||
const variableProduct = await initVariableProduct();
|
||||
const groupedProduct = await initGroupedProduct();
|
||||
const externalProduct = await initExternalProduct();
|
||||
|
||||
return [simpleProduct, variableProduct, groupedProduct, externalProduct];
|
||||
};
|
||||
|
||||
let products;
|
||||
|
||||
const runCreateOrderTest = () => {
|
||||
describe('WooCommerce Orders > Add new order', () => {
|
||||
beforeAll(async () => {
|
||||
// Initialize products for each product type
|
||||
products = await initProducts();
|
||||
|
||||
// Login
|
||||
await merchant.login();
|
||||
});
|
||||
|
||||
|
@ -34,7 +208,75 @@ const runCreateOrderTest = () => {
|
|||
'1 order moved to the Trash.'
|
||||
);
|
||||
});
|
||||
|
||||
it('can create new complex order with multiple product types & tax classes', async () => {
|
||||
// Go to "add order" page
|
||||
await merchant.openNewOrder();
|
||||
|
||||
// Open modal window for adding line items
|
||||
await expect(page).toClick('button.add-line-item');
|
||||
await expect(page).toClick('button.add-order-item');
|
||||
await page.waitForSelector('.wc-backbone-modal-header');
|
||||
|
||||
// Search for each product to add, then verify that they are saved
|
||||
for (const { name } of products) {
|
||||
await expect(page).toClick(
|
||||
'.wc-backbone-modal-content tr:last-child .select2-selection__arrow'
|
||||
);
|
||||
await expect(page).toFill(
|
||||
'#wc-backbone-modal-dialog + .select2-container .select2-search__field',
|
||||
name
|
||||
);
|
||||
const firstResult = await page.waitForSelector(
|
||||
'li[data-selected]'
|
||||
);
|
||||
await firstResult.click();
|
||||
await expect(page).toMatchElement(
|
||||
'.wc-backbone-modal-content tr:nth-last-child(2) .wc-product-search option',
|
||||
name
|
||||
);
|
||||
}
|
||||
|
||||
// Save the line items
|
||||
await expect(page).toClick('.wc-backbone-modal-content #btn-ok');
|
||||
await uiUnblocked();
|
||||
|
||||
// Recalculate taxes
|
||||
await expect(page).toDisplayDialog(async () => {
|
||||
await expect(page).toClick('.calculate-action');
|
||||
});
|
||||
await page.waitForSelector('th.line_tax');
|
||||
|
||||
// Save the order and verify line items
|
||||
await expect(page).toClick('button.save_order');
|
||||
await page.waitForNavigation();
|
||||
for (const { name } of products) {
|
||||
await expect(page).toMatchElement('.wc-order-item-name', {
|
||||
text: name
|
||||
});
|
||||
}
|
||||
|
||||
// Verify that the names of each tax class were shown
|
||||
for (const { name } of taxRates) {
|
||||
await expect(page).toMatchElement('th.line_tax', {
|
||||
text: name
|
||||
});
|
||||
await expect(page).toMatchElement('.wc-order-totals td.label', {
|
||||
text: name
|
||||
});
|
||||
}
|
||||
|
||||
// Verify tax amounts
|
||||
for (const amount of taxTotals) {
|
||||
await expect(page).toMatchElement('td.line_tax', {
|
||||
text: amount
|
||||
});
|
||||
await expect(page).toMatchElement('.wc-order-totals td.total', {
|
||||
text: amount
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = runCreateOrderTest;
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/* eslint-disable jest/no-export, jest/no-disabled-tests, jest/expect-expect */
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
const {
|
||||
shopper,
|
||||
merchant,
|
||||
createSimpleProduct,
|
||||
setCheckbox,
|
||||
unsetCheckbox,
|
||||
settingsPageSaveChanges,
|
||||
} = require( '@woocommerce/e2e-utils' );
|
||||
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
const {
|
||||
it,
|
||||
describe,
|
||||
beforeAll,
|
||||
afterAll,
|
||||
} = require( '@jest/globals' );
|
||||
|
||||
const config = require( 'config' );
|
||||
const simpleProductName = config.get( 'products.simple.name' );
|
||||
|
||||
const runCartRedirectionTest = () => {
|
||||
describe('Cart > Redirect to cart from shop', () => {
|
||||
let simplePostIdValue;
|
||||
beforeAll(async () => {
|
||||
await merchant.login();
|
||||
simplePostIdValue = await createSimpleProduct();
|
||||
|
||||
// Set checkbox in settings to enable cart redirection
|
||||
await merchant.openSettings('products');
|
||||
await setCheckbox('#woocommerce_cart_redirect_after_add');
|
||||
await settingsPageSaveChanges();
|
||||
|
||||
await merchant.logout();
|
||||
});
|
||||
|
||||
it('can redirect user to cart from shop page', async () => {
|
||||
await shopper.goToShop();
|
||||
|
||||
// Add to cart from shop page
|
||||
const addToCartXPath = `//li[contains(@class, "type-product") and a/h2[contains(text(), "${ simpleProductName }")]]` +
|
||||
'//a[contains(@class, "add_to_cart_button") and contains(@class, "ajax_add_to_cart")';
|
||||
const [ addToCartButton ] = await page.$x( addToCartXPath + ']' );
|
||||
addToCartButton.click();
|
||||
await page.waitFor(1000); // to avoid flakiness
|
||||
|
||||
await shopper.productIsInCart(simpleProductName);
|
||||
await shopper.removeFromCart(simpleProductName);
|
||||
});
|
||||
|
||||
it('can redirect user to cart from detail page', async () => {
|
||||
await shopper.goToProduct(simplePostIdValue);
|
||||
|
||||
// Add to cart from detail page
|
||||
await shopper.addToCart();
|
||||
await page.waitFor(1000); // to avoid flakiness
|
||||
|
||||
await shopper.productIsInCart(simpleProductName);
|
||||
await shopper.removeFromCart(simpleProductName);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await merchant.login();
|
||||
await merchant.openSettings('products');
|
||||
await unsetCheckbox('#woocommerce_cart_redirect_after_add');
|
||||
await settingsPageSaveChanges();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = runCartRedirectionTest;
|
|
@ -147,6 +147,7 @@ To implement the Slackbot in your CI:
|
|||
- `files:write`
|
||||
- `incoming-webhook`
|
||||
- Add the app to your channel
|
||||
- Invite the Slack app user to your channel `/invite @your-slackbot-user`
|
||||
- In your CI environment
|
||||
- Add the environment variable `WC_E2E_SCREENSHOTS=1`
|
||||
- Add your app Oauth token to a CI secret `E2E_SLACK_TOKEN`
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
/*
|
||||
* Internal dependencies
|
||||
*/
|
||||
const { runCartRedirectionTest } = require( '@woocommerce/e2e-core-tests' );
|
||||
|
||||
runCartRedirectionTest();
|
Loading…
Reference in New Issue