Merge branch 'trunk' into e2e/e2e-shopper-calculate-shipping

This commit is contained in:
Veljko V 2021-04-14 10:21:56 +02:00 committed by GitHub
commit 2b82c60107
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 362 additions and 12 deletions

View File

@ -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**

View File

@ -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"

14
composer.lock generated
View File

@ -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": [

View File

@ -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**

View File

@ -7,6 +7,7 @@
- Shopper Checkout Login Account
- Shopper My Account Create Account
- Shopper Cart Calculate Shipping
- Shopper Cart Redirection
## Fixed

View File

@ -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

View File

@ -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,
};

View File

@ -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;

View File

@ -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;

View File

@ -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`

View File

@ -0,0 +1,6 @@
/*
* Internal dependencies
*/
const { runCartRedirectionTest } = require( '@woocommerce/e2e-core-tests' );
runCartRedirectionTest();