Merge branch 'trunk' into add/plugin-upload-test-functionality

This commit is contained in:
Greg 2021-12-15 13:43:46 -07:00 committed by GitHub
commit 6e5005b0d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 2114 additions and 517 deletions

View File

@ -1,5 +1,110 @@
== Changelog ==
= 6.0.0 2021-12-14 =
**WooCommerce**
* Localization - Improve internationalization and add regions for Chile. ([#30875](https://github.com/woocommerce/woocommerce/pull/30875))
* Localization - Add 'GB' back to countries that are recommended to use automated taxes. ([#31100](https://github.com/woocommerce/woocommerce/pull/31100))
* Enhancement - Improve the performance of the filtering by attributes using the new lookup table. ([#31212](https://github.com/woocommerce/woocommerce/pull/31212))
* Enhancement - Stop using options table to store rate limits. ([#30960](https://github.com/woocommerce/woocommerce/pull/30960))
* Enhancement - Support for dynamic price period in in-app marketplace product cards. ([#31026](https://github.com/woocommerce/woocommerce/pull/31026))
* Enhancement - warning to developers to avoid gotcha with shipping rates. ([#30958](https://github.com/woocommerce/woocommerce/pull/30958))
* Enhancement - Add woocommerce_product_options_shipping_product_data hook to product data metabox. ([#30876](https://github.com/woocommerce/woocommerce/pull/30876))
* Enhancement - Ensure empty arrays can be cached. ([#31077](https://github.com/woocommerce/woocommerce/pull/31077))
* Tweak - Remove the need to invoke LookupDataStore->show_feature() to use the product attributes lookup table. ([#31228](https://github.com/woocommerce/woocommerce/pull/31228))
* Tweak - Add new action hook woocommerce_after_variations_table after the product variations table (within the add-to-cart form). ([#29642](https://github.com/woocommerce/woocommerce/pull/29642))
* Tweak - Email password reset link instead of password for new customers. ([#31257](https://github.com/woocommerce/woocommerce/pull/31257))
* Tweak - Disable autocomplete on quantity input field to prevent stale values in Firefox. ([#31196](https://github.com/woocommerce/woocommerce/pull/31196))
* Tweak - Correct the Iraqi Dinar (IQD) symbol. ([#31070](https://github.com/woocommerce/woocommerce/pull/31070))
* Tweak - Add Product Reviews filter for review comment type to the WordPress comment page. ([#31004](https://github.com/woocommerce/woocommerce/pull/31004))
* Tweak - has_block_template method: Add apply_filters to the function which will enable third-party plugins to override the return value. ([#30997](https://github.com/woocommerce/woocommerce/pull/30997))
* Tweak - Clarify tooltip for when the on-hold email is sent. ([#30970](https://github.com/woocommerce/woocommerce/pull/30970))
* Tweak - Perform check for has product archive if current theme is an FSE theme, and not just if it has current_theme_supports( 'woocommerce' ); ([#31094](https://github.com/woocommerce/woocommerce/pull/31094))
* Tweak - Remove the absolute path to the currency-info.php from within locale-info.php. ([#30935](https://github.com/woocommerce/woocommerce/pull/30935))
* Tweak - Update track properties to follow correct format. ([#30899](https://github.com/woocommerce/woocommerce/pull/30899))
* Tweak - Merge Marketplace and My Subscriptions pages back into one Extensions page. ([#31085](https://github.com/woocommerce/woocommerce/pull/31085))
* Fix - Fixes an issue that prevented database update notices from being dismissed. ([#31075](https://github.com/woocommerce/woocommerce/pull/31075))
* Fix - Duplicate coupon usage count when order is created via admin/API and status is changed. ([#31147](https://github.com/woocommerce/woocommerce/pull/31147))
* Fix - Corrects the display of negative refund values within the order editor screen. ([#30957](https://github.com/woocommerce/woocommerce/pull/30957))
* Fix - Fix bug when creating REST API keys with very long descriptions. ([#30901](https://github.com/woocommerce/woocommerce/pull/30901))
* Fix - Fix products API orderby slug and include. ([#30873](https://github.com/woocommerce/woocommerce/pull/30873))
* Dev - Remove defunct AJAX events. ([#30931](https://github.com/woocommerce/woocommerce/pull/30931))
**WooCommerce Admin - 2.9.0 & 2.9.1 & 2.9.2 **
* Dev - Remove task status endpoint ( [#7841](https://github.com/woocommerce/woocommerce-admin/issues/7841) )
* Fix - Fix ordering and styling issue with WooCommerce Payments payment method promotion. ( [#7943](https://github.com/woocommerce/woocommerce-admin/issues/7943) )
* Fix - Fix ExPlat PHP client ( [#7926](https://github.com/woocommerce/woocommerce-admin/issues/7926) )
* Fix - Fix marketing extensions tracks ( [#7908](https://github.com/woocommerce/woocommerce-admin/issues/7908) )
* Fix - Fix shipping task completion status ( [#8031](https://github.com/woocommerce/woocommerce-admin/issues/8031) )
* Update - Increased number of possible items in Recommended Extensions list from 6 to 9 ( [#7887](https://github.com/woocommerce/woocommerce-admin/issues/7887) )
* Update - Reverts addition of Marketplace and My Subscriptions pages to the Marketplace menu. ( [#7902](https://github.com/woocommerce/woocommerce-admin/issues/7902) )
* Update - Add marketing extensions back to onboarding wizard ( [#7831](https://github.com/woocommerce/woocommerce-admin/issues/7831) )
* Update - Add profile notes. ( [#7861](https://github.com/woocommerce/woocommerce-admin/issues/7861) )
* Update - Change CTA text for personalize store task after completion ( [#7852](https://github.com/woocommerce/woocommerce-admin/issues/7852) )
* Update - Refactor data source poller for re-usability. ( [#7671](https://github.com/woocommerce/woocommerce-admin/issues/7671) )
* Update - Update WC Pay card to include in-person information ( [#7830](https://github.com/woocommerce/woocommerce-admin/issues/7830) )
* Update - Updating navigation link colors ( [#7833](https://github.com/woocommerce/woocommerce-admin/issues/7833) )
* Tweak - Use page title Extensions for Marketplace and My Subscriptions pages. ( [#7901](https://github.com/woocommerce/woocommerce-admin/issues/7901) )
* Tweak - Remove the Spinner component to prevent undesired page flickering. ( [#7886](https://github.com/woocommerce/woocommerce-admin/issues/7886) )
* Tweak - Add route and layout for unmatched path ( [#7503](https://github.com/woocommerce/woocommerce-admin/issues/7503) )
* Tweak - Avoid caching extended info ( [#7819](https://github.com/woocommerce/woocommerce-admin/issues/7819) )
* Tweak - Minor design update for Marketing task. ( [#7732](https://github.com/woocommerce/woocommerce-admin/issues/7732) )
* Fix - Do not clear `current` class from the entire page when updating wp-admin's menu. ( [#7773](https://github.com/woocommerce/woocommerce-admin/issues/7773) )
* Fix - Fix calendar not being dismissed when clicking outside. ( [#7714](https://github.com/woocommerce/woocommerce-admin/issues/7714) )
* Fix - fixed warnings when using AdvancedFilters component. ( [#7704](https://github.com/woocommerce/woocommerce-admin/issues/7704) )
* Fix - Fix Tasklist UI illustrations styling ( [#7858](https://github.com/woocommerce/woocommerce-admin/issues/7858) )
* Fix - Revert experiment task titles back to original ( [#7853](https://github.com/woocommerce/woocommerce-admin/issues/7853) )
* Fix - Ensure homescreen defaults to single column layout. ( [#7969](https://github.com/woocommerce/woocommerce-admin/issues/7969) )
* Fix: Fix shipping task not offering step 3. ( [#7985](https://github.com/woocommerce/woocommerce-admin/issues/7985) )
* Add - Add Avalara to tax task ( [#7874](https://github.com/woocommerce/woocommerce-admin/issues/7874) )
* Add - Add 2col expirement. ( [#7872](https://github.com/woocommerce/woocommerce-admin/issues/7872) )
* Add - Added two column experimental task list ( [#7669](https://github.com/woocommerce/woocommerce-admin/issues/7669) )
* Add - Add header cards for all tasks in Tasklist UI experiment ( [#7838](https://github.com/woocommerce/woocommerce-admin/issues/7838) )
* Add - Add onboarding task docs ( [#7762](https://github.com/woocommerce/woocommerce-admin/issues/7762) )
* Dev - Add method to check for install status ( [#7808](https://github.com/woocommerce/woocommerce-admin/issues/7808) )
* Dev - Refactor tax task into separate components
* Dev - Update the task list to use the new task list REST API ( [#7736](https://github.com/woocommerce/woocommerce-admin/issues/7736) )
* Performance - Only load default tasks during REST requests ( [#7904](https://github.com/woocommerce/woocommerce-admin/issues/7904) )
**WooCommerce Blocks - 6.2.0 & 6.3.0 & 6.3.1 & 6.3.2**
* Enhancement - Legacy Template Block: allow users to delete the block. ( [#5176](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5176) )
* Enhancement - Add placeholder text when modifying product search input in the editor. ( [#5122](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5122) )
* Enhancement - FSE: Add basic product archive block template. ( [#5049](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5049) )
* Enhancement - FSE: Add basic taxonomy block templates. ( [#5063](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5063) )
* Enhancement - FSE: Add single product block template. ( [#5054](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5054) )
* Enhancement - FSE: Remove the do_action( woocommerce_sidebar ); action from the LegacyTemplate.php block. ( [#5097](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5097) )
* Enhancement - Fix duplicate queries in product grids. ( [#5002](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5002) )
* Enhancement - FSE: Add abstract block legacy template for core PHP templates. ( [#4991](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4991) )
* Enhancement - FSE: Add render logic to BlockTemplateController. ( [#4984](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4984) )
* Enhancement - Improve accessibility by using self-explaining edit button titles. ( [#5113](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5113) )
* Enhancement - Improve readability of terms and condition text by not displaying the text justified. ( [#5120](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5120) )
* Enhancement - Improve rendering performance for Single Product block. ( [#5107](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5107) )
* Enhancement - Improve the product images placeholder display by adding a light gray border to it. ( [#4950](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4950) )
* Enhancement - Deprecate the __experimental_woocommerce_blocks_checkout_update_order_from_request action in favour of woocommerce_blocks_checkout_update_order_from_request. ( [#5015](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5015) )
* Enhancement - Deprecate the __experimental_woocommerce_blocks_checkout_update_order_meta action in favour of woocommerce_blocks_checkout_update_order_meta. ( [#5017](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5017) )
* Enhancement - Deprecate the __experimental_woocommerce_blocks_checkout_order_processed action in favour of woocommerce_blocks_checkout_order_processed. ( [#5014](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5014) )
* Enhancement - Cart v2: The cart block, like checkout block, now supports inner blocks that allow for greater customizability. ( [#4973](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4973) )
* Enhancement - BlockTemplateController: Adds the ability to load and manage block template files. ( [#4981](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4981) )
* Enhancement - Improve accessibility for the editor view of the Product search block. ( [#4905](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4905) )
* Fix - Removed WooCommerce block templates from appearing in the template dropdown for a page or post. ( [#5167](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5167) )
* Fix - Fix Country is required error on the Cart block when updating shipping address ( [#5129](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5129) )
* Fix - Fix state validation to compare state codes, and only validate if a country is given ( [#5132](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5132) )
* Fix - Make order note block removable ( [#5139](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5139) )
* Fix - Fix label alignment of the product search in the editor. ( [#5072](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5072) )
* Fix - Fix sale badge alignment on smaller screen. ( [#5061](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5061) )
* Fix - FSE: Fix missing is_custom property for WooCommerce block template objects. ( [#5067](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5067) )
* Fix - Replace incorrect with correct text domain. ( [#5020](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5020) )
* Fix - Scripts using wc-settings or script that depend on it would be enqueued in the footer if theyre enqueued in the header. ( [#5059](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5059) )
* Fix - Fix custom classname support for inner checkout blocks. ( [#4978](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4978) )
* Fix - Fix a bug in free orders and trial subscription products. ( [#4955](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4955) )
* Fix - Remove duplicate attributes in saved block HTML. ( [#4941](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4941) )
* Fix - Fix render error of Filter by Attribute block when no attribute is selected. ( [#4847](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4847) )
* Fix - Store API Ensure returned customer address state is valid. ( [#4844](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4844) )
* Fix - fatal error in certain WP 5.9 pre-release versions. ( [#5183](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5183) )
= 5.9.0 2021-11-09 =
**WooCommerce**

View File

@ -20,6 +20,7 @@
"@automattic/nx-composer": "^0.1.0",
"@nrwl/cli": "latest",
"@nrwl/linter": "^13.1.4",
"@nrwl/devkit": "^13.1.4",
"@nrwl/tao": "latest",
"@nrwl/web": "^13.1.4",
"@nrwl/workspace": "latest",

View File

@ -1,31 +1,38 @@
{
"root": "packages/js/api-core-tests/",
"sourceRoot": "packages/js/api-core-tests",
"projectType": "library",
"targets": {
"test": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test"
}
},
"test-hello": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:hello"
}
},
"make-collection": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "make:collection"
}
},
"test-api": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:api"
}
}
}
"root": "packages/js/api-core-tests/",
"sourceRoot": "packages/js/api-core-tests",
"projectType": "library",
"targets": {
"changelog": {
"executor": "./tools/executors/changelogger:changelog",
"options": {
"action": "add",
"cwd": "packages/js/api-core-tests"
}
},
"test": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test"
}
},
"test-hello": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:hello"
}
},
"make-collection": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "make:collection"
}
},
"test-api": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:api"
}
}
}
}

View File

@ -1,43 +1,50 @@
{
"root": "packages/js/api/",
"sourceRoot": "packages/js/api/src",
"projectType": "library",
"targets": {
"build": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "build"
}
},
"clean": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "clean"
}
},
"compile": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "compile"
}
},
"prepare": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "prepare"
}
},
"lint": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "lint"
}
},
"test": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test"
}
}
}
"root": "packages/js/api/",
"sourceRoot": "packages/js/api/src",
"projectType": "library",
"targets": {
"changelog": {
"executor": "./tools/executors/changelogger:changelog",
"options": {
"action": "add",
"cwd": "packages/js/api"
}
},
"build": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "build"
}
},
"clean": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "clean"
}
},
"compile": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "compile"
}
},
"prepare": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "prepare"
}
},
"lint": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "lint"
}
},
"test": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test"
}
}
}
}

View File

@ -4,6 +4,7 @@
- A `specs/data` folder to store page element data.
- Tests to verify that different top-level menu and their associated sub-menus load successfully.
- Test scaffolding via `npx wc-e2e install @woocommerce/e2e-core-tests`
## Changed

View File

@ -20,6 +20,18 @@ Follow [E2E setup instructions](https://github.com/woocommerce/woocommerce/blob/
### Setting up core tests
#### Version 0.2.0 or newer
Version 0.2.0 added a test installer that will populate the `tests/e2e/specs` folder with test scripts for all the current core test suite. It also creates sample configuration files including all the configuration data needed to run the core tests.
- Install the e2e-environment `npm install @woocommerce/e2e-environment --save-dev`
- Run the installer `npx wc-e2e install @woocommerce/e2e-core-tests`
- Merge the sample configuration files:
- `tests/e2e/docker/woocommerce.e2e-core-tests.sh` => `initialize.sh`
- `tests/e2e/config/default-woocommerce.e2e-core-tests.json` => `default.json`
#### Version 0.1.X or other test runner
- Create the folder `tests/e2e/specs` in your repository if it does not exist.
- To add a core test to your test suite, create a new `.test.js` file within `tests/e2e/specs` . Example code to run all the shopper tests:
```js

View File

@ -0,0 +1,195 @@
{
"url": "http://localhost:8084/",
"users": {
"admin": {
"username": "admin",
"password": "password"
},
"customer": {
"username": "customer",
"password": "password"
}
},
"products": {
"simple": {
"name": "Simple product"
},
"variable": {
"name": "Variable Product with Three Attributes",
"defaultAttributes": [
{
"id": 0,
"name": "Size",
"option": "Medium"
},
{
"id": 0,
"name": "Colour",
"option": "Blue"
}
],
"attributes": [
{
"id": 0,
"name": "Colour",
"isVisibleOnProductPage": true,
"isForVariations": true,
"options": [
"Red",
"Green",
"Blue"
],
"sortOrder": 0
},
{
"id": 0,
"name": "Size",
"isVisibleOnProductPage": true,
"isForVariations": true,
"options": [
"Small",
"Medium",
"Large"
],
"sortOrder": 0
},
{
"id": 0,
"name": "Logo",
"isVisibleOnProductPage": true,
"isForVariations": true,
"options": [
"Woo",
"WordPress"
],
"sortOrder": 0
}
]
},
"variations": [
{
"regularPrice": "19.99",
"attributes": [
{
"name": "Size",
"option": "Large"
},
{
"name": "Colour",
"option": "Red"
}
]
},
{
"regularPrice": "18.99",
"attributes": [
{
"name": "Size",
"option": "Medium"
},
{
"name": "Colour",
"option": "Green"
}
]
},
{
"regularPrice": "17.99",
"attributes": [
{
"name": "Size",
"option": "Small"
},
{
"name": "Colour",
"option": "Blue"
}
]
}
],
"grouped": {
"name": "Grouped Product with Three Children",
"groupedProducts": [
{
"name": "Base Unit",
"regularPrice": "29.99"
},
{
"name": "Add-on A",
"regularPrice": "11.95"
},
{
"name": "Add-on B",
"regularPrice": "18.97"
}
]
},
"external": {
"name": "External product",
"regularPrice": "24.99",
"buttonText": "Buy now",
"externalUrl": "https://wordpress.org/plugins/woocommerce"
}
},
"coupons": {
"percentage": {
"code": "20percent",
"discountType": "percent",
"amount": "20.00"
}
},
"addresses": {
"admin": {
"store": {
"email": "admin@woocommercecoree2etestsuite.com",
"firstname": "John",
"lastname": "Doe",
"company": "Automattic",
"country": "United States (US)",
"addressfirstline": "addr 1",
"addresssecondline": "addr 2",
"countryandstate": "United States (US) — California",
"city": "San Francisco",
"state": "CA",
"postcode": "94107"
}
},
"customer": {
"billing": {
"firstname": "John",
"lastname": "Doe",
"company": "Automattic",
"country": "United States (US)",
"addressfirstline": "addr 1",
"addresssecondline": "addr 2",
"city": "San Francisco",
"state": "CA",
"postcode": "94107",
"phone": "123456789",
"email": "john.doe@example.com"
},
"shipping": {
"firstname": "John",
"lastname": "Doe",
"company": "Automattic",
"country": "United States (US)",
"addressfirstline": "addr 1",
"addresssecondline": "addr 2",
"city": "San Francisco",
"state": "CA",
"postcode": "94107"
}
}
},
"orders": {
"basicPaidOrder": {
"paymentMethod": "cod",
"status": "processing",
"billing": {
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com"
}
}
}
}

View File

@ -0,0 +1,5 @@
module.exports = {
testSpecs: 'installFiles/scaffold-tests.json',
defaultJson: 'installFiles/default-test-config.json',
initializeSh: 'installFiles/initialize.sh.default',
};

View File

@ -0,0 +1,25 @@
#!/bin/bash
echo "Initializing WooCommerce E2E"
# This is a workaround to accommodate different directory names.
wp plugin activate --all
wp plugin deactivate akismet
wp plugin deactivate hello
wp theme install twentynineteen --activate
wp user create customer customer@woocommercecoree2etestsuite.com \
--user_pass=password \
--role=subscriber \
--first_name='Jane' \
--last_name='Smith' \
--path=/var/www/html
# we cannot create API keys for the API, so we using basic auth, this plugin allows that.
wp plugin install https://github.com/WP-API/Basic-Auth/archive/master.zip --activate
# install the WP Mail Logging plugin to test emails
wp plugin install wp-mail-logging --activate
# initialize pretty permalinks
wp rewrite structure /%postname%/

View File

@ -0,0 +1,138 @@
{
"active": [
{
"name": "front-end",
"description": "Shopper tests",
"testFiles": [
{
"name": "cart-begin",
"functions": [ "runCartPageTest" ]
}, {
"name": "cart-calculate-shipping",
"functions": [ "runCartCalculateShippingTest" ]
}, {
"name": "cart-coupons",
"functions": [ "runCartApplyCouponsTest" ]
}, {
"name": "checkout-begin",
"functions": [ "runCheckoutPageTest" ]
}, {
"name": "checkout-coupons",
"functions": [ "runCheckoutApplyCouponsTest" ]
}, {
"name": "checkout-create-account",
"functions": [ "runCheckoutCreateAccountTest" ]
}, {
"name": "checkout-login-account",
"functions": [ "runCheckoutLoginAccountTest" ]
}, {
"name": "my-account-create-account",
"functions": [ "runMyAccountCreateAccountTest" ]
}, {
"name": "my-account-pay-order",
"functions": [ "runMyAccountPayOrderTest" ]
}, {
"name": "my-account",
"functions": [ "runMyAccountPageTest" ]
}, {
"name": "order-email-receiving",
"functions": [ "runOrderEmailReceivingTest" ]
}, {
"name": "product-browse-search-sort",
"functions": [ "runProductBrowseSearchSortTest" ]
}, {
"name": "single-product-page",
"functions": [ "runSingleProductPageTest" ]
}, {
"name": "variable-product-updates",
"functions": [ "runVariableProductUpdateTest" ]
}
]
}, {
"name": "rest-api",
"description": "REST API tests",
"testFiles": [
{
"name": "api",
"functions": [ "runApiTests" ]
}
]
}, {
"name": "wp-admin",
"description": "Merchant tests",
"testFiles": [
{
"name": "create-coupon",
"functions": [ "runCreateCouponTest" ]
}, {
"name": "create-order",
"functions": [ "runCreateOrderTest" ]
}, {
"name": "create-shipping-classes",
"functions": [ "runAddShippingClassesTest" ]
}, {
"name": "create-shipping-zones",
"functions": [ "runAddNewShippingZoneTest" ]
}, {
"name": "create-simple-product",
"functions": [ "runAddSimpleProductTest" ]
}, {
"name": "create-variable-product",
"functions": [ "runAddVariableProductTest" ]
}, {
"name": "order-coupon",
"functions": [ "runOrderApplyCouponTest" ]
}, {
"name": "order-customer-payment-page",
"functions": [ "runMerchantOrdersCustomerPaymentPage" ]
}, {
"name": "order-edit",
"functions": [ "runEditOrderTest" ]
}, {
"name": "order-emails",
"functions": [ "runMerchantOrderEmailsTest" ]
}, {
"name": "order-refund",
"functions": [ "runOrderRefundTest" ]
}, {
"name": "order-searching",
"functions": [ "runOrderSearchingTest" ]
}, {
"name": "order-status-filters",
"functions": [ "runOrderStatusFiltersTest" ]
}, {
"name": "product-edit",
"functions": [ "runProductEditDetailsTest" ]
}, {
"name": "product-import-csv",
"functions": [ "runImportProductsTest" ]
}, {
"name": "product-search",
"functions": [ "runProductSearchTest" ]
}, {
"name": "update-general-settings",
"functions": [ "runUpdateGeneralSettingsTest" ]
}, {
"name": "update-product-settings",
"functions": [ "runProductSettingsTest" ]
}, {
"name": "update-tax-settings",
"functions": [ "runTaxSettingsTest" ]
}, {
"name": "wccom-connect",
"functions": [ "runInitiateWccomConnectionTest" ]
}
]
}
],
"deprecated": [
{
"name": "example-folder",
"testFiles": [
{ "name": "any-filename-to-deprecate" }
]
}
]
}

View File

@ -1,5 +1,14 @@
{
"root": "packages/js/e2e-core-tests/",
"sourceRoot": "packages/js/e2e-core-tests",
"projectType": "library"
"root": "packages/js/e2e-core-tests/",
"sourceRoot": "packages/js/e2e-core-tests",
"projectType": "library",
"targets": {
"changelog": {
"executor": "./tools/executors/changelogger:changelog",
"options": {
"action": "add",
"cwd": "packages/js/e2e-core-tests"
}
}
}
}

View File

@ -5,10 +5,12 @@
- Added `await` for every call to `shopper.logout`
- Updated `getLatestReleaseZipUrl()` to allow passing in an authorization token and simplified arguments to just the repository name
- Added `upload.ini` which increases the limits for uploading files (such as for plugins) in the Docker environment
- Test setup, scaffolding, and removal via `wc-e2e install` and `wc-e2e uninstall`
## Fixed
- Updated the browserViewport in `jest.setup.js` to match the `defaultViewport` dimensions defined in `jest-puppeteer.config.js`
## Added
- Added quotes around `WORDPRESS_TITLE` value in .env file to address issue with docker compose 2 "key cannot contain a space" error.

View File

@ -9,6 +9,19 @@ npm install @woocommerce/e2e-environment --save
npm install jest --global
```
### Version 0.3.0 and newer
Version 0.3.0 added a test installer that will populate the `tests/e2e/*` folder with test scripts and configuration files. The installer will create test scripts for E2E test packages that include support for the installer.
- [Adding test scaffolding to E2E test packages](https://github.com/woocommerce/woocommerce/tree/trunk/packages/js/e2e-environment/test-packages.md)
#### Using the installer
- Install a default test environment: `npx wc-e2e install`
- Install test specs from an E2E tests package: `npx wc-e2e install @woocommerce-e2e-tests [--format cjs] [--ext spec.js]`
- The default test spec format and extension are `ES6` and `test.js`
- Remove test specs for an E2E tests package: `npx wc-e2e uninstall @woocommerce-e2e-tests`
## Configuration
The `@woocommerce/e2e-environment` package exports configuration objects that can be consumed in JavaScript config files in your project. Additionally, it includes a basic hosting container for running tests and includes instructions for creating your Travis CI setup.
@ -60,10 +73,10 @@ The E2E environment uses Jest as a test runner. Extending the base config is nec
```js
const path = require( 'path' );
const { useE2EJestConfig } = require( '@woocommerce/e2e-environment' );
const { useE2EJestConfig, resolveLocalE2ePath } = require( '@woocommerce/e2e-environment' );
const jestConfig = useE2EJestConfig( {
roots: [ path.resolve( __dirname, '../specs' ) ],
roots: [ resolveLocalE2ePath( 'specs' ) ],
} );
module.exports = jestConfig;

View File

@ -11,6 +11,7 @@ const {
getAppName,
getTestConfig,
resolveLocalE2ePath,
resolvePackagePath,
} = require( '../utils' );
const dockerArgs = [];
@ -63,7 +64,7 @@ if ( appPath ) {
if ( fs.existsSync( appInitFile ) ) {
fs.copyFileSync(
appInitFile,
path.resolve( __dirname, '../docker/wp-cli/initialize.sh' )
resolvePackagePath( 'docker/wp-cli/initialize.sh' )
);
console.log( 'Initializing ' + appInitFile );
}
@ -90,7 +91,7 @@ if ( ! process.env.WORDPRESS_URL ) {
}
// Ensure that the first Docker compose file loaded is from our local env.
dockerArgs.unshift( '-f', path.resolve( __dirname, '../docker-compose.yaml' ) );
dockerArgs.unshift( '-f', resolvePackagePath( 'docker-compose.yaml' ) );
const dockerProcess = spawnSync( 'docker-compose', dockerArgs, {
stdio: 'inherit',

View File

@ -4,7 +4,11 @@ const { spawnSync } = require( 'child_process' );
const program = require( 'commander' );
const path = require( 'path' );
const fs = require( 'fs' );
const { getAppRoot, resolveLocalE2ePath } = require( '../utils' );
const {
getAppRoot,
resolveLocalE2ePath,
resolvePackagePath,
} = require( '../utils' );
const {
WC_E2E_SCREENSHOTS,
JEST_PUPPETEER_CONFIG,
@ -30,7 +34,7 @@ if ( WC_E2E_SCREENSHOTS ) {
}
}
const nodeConfigDirs = [ path.resolve( __dirname, '../config' ) ];
const nodeConfigDirs = [ resolvePackagePath( 'config' ) ];
if ( appPath ) {
nodeConfigDirs.unshift( resolveLocalE2ePath( 'config' ) );
@ -51,10 +55,7 @@ if ( ! JEST_PUPPETEER_CONFIG ) {
// Use local Puppeteer config if there is one.
// Load test configuration file into an object.
const localJestConfigFile = resolveLocalE2ePath( 'config/jest-puppeteer.config.js' );
const jestConfigFile = path.resolve(
__dirname,
'../config/jest-puppeteer.config.js'
);
const jestConfigFile = resolvePackagePath( 'config/jest-puppeteer.config.js' );
testEnvVars.JEST_PUPPETEER_CONFIG = fs.existsSync( localJestConfigFile )
? localJestConfigFile
@ -88,7 +89,7 @@ if ( program.debug ) {
const envVars = Object.assign( {}, process.env, testEnvVars );
let configPath = path.resolve( __dirname, '../config/jest.config.js' );
let configPath = resolvePackagePath( 'config/jest.config.js' );
// Look for a Jest config in the dependent app's path.
if ( appPath ) {

View File

@ -0,0 +1,233 @@
#!/usr/bin/env node
/**
* External dependencies.
*/
const fs = require( 'fs' );
const path = require( 'path' );
const sprintf = require( 'sprintf-js' ).sprintf;
/**
* Internal dependencies.
*/
const {
resolvePackage,
resolvePackagePath,
} = require( '../utils' );
const {
createLocalE2ePath,
confirm,
confirmLocalCopy,
confirmLocalDelete,
getPackageData,
installDefaults
} = require( '../utils/scaffold' );
const args = process.argv.slice( 2 );
const [ command, packageName ] = args;
// Allow multiple spec file extensions and formats.
let testExtension = 'test.js';
let testFormat = '';
for ( let a = 2; a < args.length; a++ ) {
const nextArg = a + 1;
if ( nextArg >= args.length ) {
break;
}
switch ( args[ a ] ) {
case '--format':
testFormat = args[ nextArg ];
break;
case '--ext':
testExtension = args[ nextArg ];
break;
}
}
/**
* Install the test scripts and sample default.json configuration
*/
if ( command == 'install' ) {
// Install some environment defaults if no package is requested.
if ( ! packageName ) {
installDefaults();
return;
}
// `package` is a reserved word
const pkg = resolvePackage( packageName ).name;
if ( ! pkg.length ) {
//@todo add error message
return;
}
const { packageSlug, testSpecs, defaultJson, initializeSh } = getPackageData( pkg );
// Write sample default.json
if ( defaultJson ) {
const defaultJsonName = `config${path.sep}default-${packageSlug}.json`;
createLocalE2ePath( 'config' );
if ( confirmLocalCopy( defaultJsonName, defaultJson, pkg ) ) {
console.log( `Created sample test configuration to 'tests/e2e/${defaultJsonName}'.` );
}
}
// Write sample initialize.sh
if ( initializeSh ) {
const defaultInitName = `docker${path.sep}${packageSlug}.sh`;
createLocalE2ePath( 'docker' );
if ( confirmLocalCopy( defaultInitName, initializeSh, pkg ) ) {
console.log( `Created sample test container initialization script to 'tests/e2e/${defaultInitName}'.` );
}
}
if ( ! testSpecs ) {
return;
}
// Write test files
const testsSpecFile = resolvePackagePath( testSpecs, pkg );
const specs = fs.readFileSync( testsSpecFile );
const tests = JSON.parse( specs );
const { active, deprecated } = tests;
if ( active && active.length ) {
const blankLine = '';
const eol = "\n";
const autoGenerate = sprintf( '/* This file was auto-generated by the command `npx wc-e2e install %s`. */', packageName );
let importLineFormat;
let overwriteFiles;
let confirmPrompt;
if ( testFormat.toLowerCase() == 'cjs' ) {
importLineFormat = sprintf( "const {%%s} = require( '%s' );", pkg );
} else {
importLineFormat = sprintf( "import {%%s} from '%s';", pkg );
}
// Create the specs folder if not present
let specFolderPath = createLocalE2ePath( 'specs' );
// Loop through folders and files to write test scripts.
for ( let f = 0; f < active.length; f++ ) {
if ( overwriteFiles == 'q' ) {
overwriteFiles = '';
break;
}
const testFolder = active[ f ];
const { testFiles } = testFolder;
if ( ! testFiles || ! testFiles.length ) {
continue;
}
let specFolder;
if ( testFolder.name.length ) {
specFolder = createLocalE2ePath( `specs${path.sep}${testFolder.name}` );
} else {
specFolder = specFolderPath;
}
// Create the test files.
for ( let t = 0; t < testFiles.length; t++ ) {
const testFile = testFiles[ t ];
if ( ! testFile.functions.length ) {
continue;
}
const testFileName = `${testFolder.name}${path.sep}${testFile.name}.${testExtension}`;
const testFilePath = `${specFolder}${path.sep}${testFile.name}.${testExtension}`;
// Check to see if file exists.
if ( fs.existsSync( testFilePath ) ) {
if ( overwriteFiles != 'a' ) {
confirmPrompt = `${testFileName} already exists. Overwrite? [y]es/[n]o/[a]ll/[q]uit: `;
overwriteFiles = confirm( confirmPrompt, 'anqy' );
overwriteFiles = overwriteFiles.toLowerCase();
}
if ( overwriteFiles == 'q' ) {
break;
}
if ( overwriteFiles != 'a' && overwriteFiles != 'y' ) {
continue;
}
}
console.log( 'Writing tests/e2e/specs/' + testFileName );
let buffer = [ autoGenerate ];
let testSeparator, testTerminator, importPrefix;
// Add the import line.
if ( testFile.functions.length > 3 ) {
testSeparator = ',' + eol;
testTerminator = eol;
importPrefix = eol;
} else {
testSeparator = ', ';
testTerminator = ' ';
importPrefix = ' ';
}
const testImport = testFile.functions.join( testSeparator ) + testTerminator;
buffer.push( sprintf( importLineFormat, importPrefix + testImport ), blankLine );
// Add test function calls and write the file
let functionCalls = testFile.functions.map( functionName => functionName + '();' );
buffer.push( ...functionCalls, blankLine );
fs.writeFileSync( testFilePath, buffer.join( eol ) );
}
}
}
// @todo: deprecated files.
} else if ( command == 'uninstall' ) {
if ( ! packageName ) {
// @todo: write error message
return;
}
const pkg = resolvePackage( packageName ).name;
const { packageSlug, testSpecs, defaultJson, initializeSh } = getPackageData( pkg );
// Delete sample default.json
if ( defaultJson ) {
const defaultJsonName = `config${path.sep}default-${packageSlug}.json`;
confirmLocalDelete( defaultJsonName );
}
// Delete sample initialize.sh
if ( initializeSh ) {
const defaultInitName = `docker${path.sep}${packageSlug}.sh`;
confirmLocalDelete( defaultInitName );
}
if ( ! testSpecs ) {
return;
}
const testsSpecFile = resolvePackagePath( testSpecs, pkg );
const specs = fs.readFileSync( testsSpecFile );
const tests = JSON.parse( specs );
const { active } = tests;
if ( ! active || ! active.length ) {
return;
}
// Loop through folders and files to delete test scripts.
for ( let f = 0; f < active.length; f++ ) {
const testFolder = active[ f ];
const { testFiles } = testFolder;
if ( ! testFiles || ! testFiles.length ) {
continue;
}
const specFolder = testFolder.name.length ? `specs${path.sep}${testFolder.name}` : 'specs';
for ( let t = 0; t < testFiles.length; t++ ) {
const testFile = testFiles[ t ];
const testFilePath = `${specFolder}${path.sep}${testFile.name}.${testExtension}`;
confirmLocalDelete( testFilePath );
}
}
}

View File

@ -71,6 +71,10 @@ case $1 in
./bin/wait-for-build.sh && ./bin/e2e-test-integration.js --dev --debug $2
TESTRESULT=$?
;;
'install' | \
'uninstall')
./bin/scaffold.js $@
;;
*)
usage
;;

View File

@ -3,10 +3,12 @@
*/
const { E2E_RETRY_TIMES } = process.env;
const setupJestRetries = ( retries = 2 ) => {
const setupJestRetries = ( retries = 0 ) => {
const retryTimes = E2E_RETRY_TIMES ? E2E_RETRY_TIMES : retries;
jest.retryTimes( retryTimes );
if ( retryTimes > 0 ) {
jest.retryTimes( retryTimes );
}
};
// If more methods are added to setupJestObject, it should be include in the readme

View File

@ -0,0 +1,25 @@
#!/bin/bash
echo "Initializing WooCommerce E2E"
# This is a workaround to accommodate different directory names.
wp plugin activate --all
wp plugin deactivate akismet
wp plugin deactivate hello
wp theme install twentynineteen --activate
wp user create customer customer@woocommercecoree2etestsuite.com \
--user_pass=password \
--role=subscriber \
--first_name='Jane' \
--last_name='Smith' \
--path=/var/www/html
# we cannot create API keys for the API, so we using basic auth, this plugin allows that.
wp plugin install https://github.com/WP-API/Basic-Auth/archive/master.zip --activate
# install the WP Mail Logging plugin to test emails
wp plugin install wp-mail-logging --activate
# initialize pretty permalinks
wp rewrite structure /%postname%/

View File

@ -0,0 +1,8 @@
const path = require( 'path' );
const { useE2EJestConfig, getAppRoot } = require( '@woocommerce/e2e-environment' );
const jestConfig = useE2EJestConfig( {
roots: [ path.resolve( __dirname, '../specs' ) ],
} );
module.exports = jestConfig;

View File

@ -0,0 +1,80 @@
import {
clearLocalStorage,
setBrowserViewport,
withRestApi,
WP_ADMIN_LOGIN
} from '@woocommerce/e2e-utils';
const config = require( 'config' );
const { HTTPClientFactory } = require( '@woocommerce/api' );
const { addConsoleSuppression, updateReadyPageStatus } = require( '@woocommerce/e2e-environment' );
const { DEFAULT_TIMEOUT_OVERRIDE } = process.env;
// @todo: remove this once https://github.com/woocommerce/woocommerce-admin/issues/6992 has been addressed
addConsoleSuppression( 'woocommerce_shared_settings', false );
/**
* Uses the WordPress API to delete all existing posts
*/
async function trashExistingPosts() {
const apiUrl = config.get('url');
const wpPostsEndpoint = '/wp/v2/posts';
const adminUsername = config.get('users.admin.username');
const adminPassword = config.get('users.admin.password');
const client = HTTPClientFactory.build(apiUrl)
.withBasicAuth(adminUsername, adminPassword)
.create();
// List all existing posts
const response = await client.get(wpPostsEndpoint);
const posts = response.data;
// Delete each post
for (const post of posts) {
await client.delete(`${wpPostsEndpoint}/${post.id}`);
}
}
// Before every test suite run, delete all content created by the test. This ensures
// other posts/comments/etc. aren't dirtying tests and tests don't depend on
// each other's side-effects.
beforeAll(async () => {
if ( DEFAULT_TIMEOUT_OVERRIDE ) {
page.setDefaultNavigationTimeout( DEFAULT_TIMEOUT_OVERRIDE );
page.setDefaultTimeout( DEFAULT_TIMEOUT_OVERRIDE );
}
try {
// Update the ready page to prevent concurrent test runs
await updateReadyPageStatus('draft');
await trashExistingPosts();
await withRestApi.deleteAllProducts();
await withRestApi.deleteAllCoupons();
await withRestApi.deleteAllOrders();
} catch ( error ) {
// Prevent an error here causing tests to fail.
}
await page.goto(WP_ADMIN_LOGIN);
await clearLocalStorage();
await setBrowserViewport( {
width: 1280,
height: 800,
});
});
// Clear browser cookies and cache using DevTools.
// This is to ensure that each test ends with no user logged in.
afterAll(async () => {
// Reset the ready page to published to allow future test runs
try {
await updateReadyPageStatus('publish');
} catch ( error ) {
// Prevent an error here causing tests to fail.
}
const client = await page.target().createCDPSession();
await client.send('Network.clearBrowserCookies');
await client.send('Network.clearBrowserCache');
});

View File

@ -33,7 +33,9 @@
"jest-each": "25.5.0",
"jest-puppeteer": "^4.4.0",
"node-stream-zip": "^1.13.6",
"request": "^2.88.2"
"readline-sync": "^1.4.10",
"request": "^2.88.2",
"sprintf-js": "^1.1.2"
},
"devDependencies": {
"@babel/cli": "7.12.8",

View File

@ -1,79 +1,86 @@
{
"root": "packages/js/e2e-environment/",
"sourceRoot": "packages/js/e2e-environment/src",
"projectType": "library",
"targets": {
"build": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "build"
}
},
"lint": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "lint"
}
},
"clean": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "clean"
}
},
"compile": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "compile"
}
},
"prepare": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "prepare"
}
},
"docker-up": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "docker:up"
}
},
"docker-down": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "docker:down"
}
},
"docker-clear-all": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "docker:clear-all"
}
},
"docker-ssh": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "docker:ssh"
}
},
"test-e2e": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:e2e"
}
},
"test-e2e-debug": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:e2e-debug"
}
},
"test-e2e-dev": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:e2e-dev"
}
}
}
"root": "packages/js/e2e-environment/",
"sourceRoot": "packages/js/e2e-environment/src",
"projectType": "library",
"targets": {
"changelog": {
"executor": "./tools/executors/changelogger:changelog",
"options": {
"action": "add",
"cwd": "packages/js/e2e-environment"
}
},
"build": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "build"
}
},
"lint": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "lint"
}
},
"clean": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "clean"
}
},
"compile": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "compile"
}
},
"prepare": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "prepare"
}
},
"docker-up": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "docker:up"
}
},
"docker-down": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "docker:down"
}
},
"docker-clear-all": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "docker:clear-all"
}
},
"docker-ssh": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "docker:ssh"
}
},
"test-e2e": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:e2e"
}
},
"test-e2e-debug": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:e2e-debug"
}
},
"test-e2e-dev": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:e2e-dev"
}
}
}
}

View File

@ -0,0 +1,104 @@
# WooCommerce End-to-End Test Packages
There are two limitations which significantly impact the architecture of E2E test packages:
- Referencing the `jest` functions `describe`, `it`, `beforeAll`, etc. throws a fatal error outside the `jest` environment.
- `jest` will not scan for tests in any path containing `node_mdules`.
## Creating a tests package
The way to create a tests package with the above limitations is
- **In the tests package**, wrap each test in a function
```js
/**
* Require the necessary jest functions to prevent the package build from referencing them
* `import` references imported functions during package build
*/
const { describe, it, beforeAll } = require( '@jest/globals' );
const testMyCriticalFlow = () => {
describe( 'My Critical Flow', () => {
beforeAll( async () => {
// Test setup
} );
it( 'can complete first step', async () => {
// Do stuff
expect( someValue ).toBeTruthy();
} );
} );
};
modules.exports = testMyFlow;
```
- **In the `tests/e2e/specs` folder**, create a test spec that calls the test function
```js
import { testMyCriticalFlow } from 'MyTestsPackage';
testMyCriticalFlow();
```
## Adding the scaffolds for the test installer
To work with the limitations outlined above, the test installer needs to access the test scaffolding information without accessing the package index. As a result, the `installFiles` is a required path in the steps below
- Create an `installFiles` folder in the root of the package
- Add an `index.js` to the folder which exports an object with some or all of three properties
```js
module.exports = {
defaultJson: 'installFiles/default-test-config.json',
initializeSh: 'installFiles/initialize.sh.default',
testSpecs: 'installFiles/scaffold-tests.json',
};
```
- The value of each of the properties should be a relative path from the package `index.js`. The test installer will remove `dist`, `build`, and `build-modules` from the end of the package index path.
- `defaultJson`: Path to a JSON file containing all `default.json` entries needed for the tests in the package.
- `initializeSh`: Path to a bash script containing the WP CLI commands needed to initialize the `e2e-environment` test container.
- `testSpecs`: Path to a JSON file containing a nested object
```json
{
"active": [
{
"name": "first-folder-name",
"description": "First tests",
"testFiles": [
{
"name": "test-name-a",
"functions": [
"testMyCriticalFlow"
]
},
{
"name": "test-name-b",
"functions": [
"testSecondCriticalFlow",
"testThirdCriticalFlow"
]
}
]
},
{
"name": "second-folder-name",
"description": "Second tests",
"testFiles": [
....
]
}
]
}
```
The test installer uses the `testSpecs` nested object to create test specs. Using the example above, create `tests/e2e/specs/first-folder-name/test-name-b.test.js`:
```js
/* This file was auto-generated by the command `npx wc-e2e install your-package-name`. */
import { testSecondCriticalFlow, testThirdCriticalFlow } from 'your-package-name';
testSecondCriticalFlow();
testThirdCriticalFlow();
```

View File

@ -14,10 +14,7 @@ const StreamZip = require( 'node-stream-zip' );
*/
const getRemotePluginZip = async ( fileUrl, authorizationToken = '' ) => {
const appPath = getAppRoot();
const savePath = path.resolve(
appPath,
'plugins/woocommerce/tests/e2e/plugins'
);
const savePath = resolveLocalE2ePath( 'plugins' );
mkdirp.sync( savePath );
// Pull the version from the end of the URL and add .zip

View File

@ -2,6 +2,8 @@ const getAppRoot = require( './app-root' );
const { getAppName, getAppBase } = require( './app-name' );
const { getTestConfig, getAdminConfig, resolveLocalE2ePath } = require( './test-config' );
const { getRemotePluginZip, getLatestReleaseZipUrl, deleteDownloadedPluginFiles } = require('./get-plugin-zip');
const testConfig = require( './test-config' );
const { getRemotePluginZip, getLatestReleaseZipUrl } = require('./get-plugin-zip');
const takeScreenshotFor = require( './take-screenshot' );
const updateReadyPageStatus = require('./update-ready-page');
const consoleUtils = require( './filter-console' );
@ -10,13 +12,11 @@ module.exports = {
getAppBase,
getAppRoot,
getAppName,
getTestConfig,
getAdminConfig,
resolveLocalE2ePath,
getRemotePluginZip,
getLatestReleaseZipUrl,
deleteDownloadedPluginFiles,
takeScreenshotFor,
updateReadyPageStatus,
...testConfig,
...consoleUtils,
};

View File

@ -0,0 +1,124 @@
/**
* External dependencies.
*/
const fs = require( 'fs' );
const path = require( 'path' );
const readlineSync = require( 'readline-sync' );
/**
* Internal dependencies.
*/
const { resolveLocalE2ePath, resolvePackagePath } = require( './test-config' );
/**
* Create a path relative to the local `tests/e2e` folder.
* @param relativePath
* @return {string}
*/
const createLocalE2ePath = ( relativePath ) => {
let specFolderPath = '';
const folders = [ `..${path.sep}..${path.sep}tests`, `..${path.sep}e2e`, relativePath ];
folders.forEach( ( folder ) => {
specFolderPath = resolveLocalE2ePath( folder );
if ( ! fs.existsSync( specFolderPath ) ) {
console.log( `Creating folder ${specFolderPath}` );
fs.mkdirSync( specFolderPath );
}
} );
return specFolderPath;
};
/**
* Prompt the console for confirmation.
*
* @param {string} prompt Prompt for the user.
* @param {string} choices valid responses.
* @return {string}
*/
const confirm = ( prompt, choices ) => {
const answer = readlineSync.keyIn( prompt, choices );
return answer;
};
/**
*
* @param {string} localE2ePath Destination path
* @param {string} packageE2ePath Source path
* @param {string} packageName Source package. Default @woocommerce/e2e-environment package.
* @return {boolean}
*/
const confirmLocalCopy = ( localE2ePath, packageE2ePath, packageName = '' ) => {
const localPath = resolveLocalE2ePath( localE2ePath );
const packagePath = resolvePackagePath( packageE2ePath, packageName );
const confirmPrompt = `${localE2ePath} already exists. Overwrite? [Y]es/[n]o: `;
let overwriteFiles;
if ( fs.existsSync( localPath ) ) {
overwriteFiles = confirm( confirmPrompt, 'ny' );
overwriteFiles = overwriteFiles.toLowerCase();
} else {
overwriteFiles = 'y';
}
if ( overwriteFiles == 'y' ) {
fs.copyFileSync( packagePath, localPath );
return true;
}
return false;
};
/**
* Prompt for confirmation before deleting a local E2E file.
*
* @param {string} localE2ePath Relative path to local E2E file.
*/
const confirmLocalDelete = ( localE2ePath ) => {
const localPath = resolveLocalE2ePath( localE2ePath );
if ( ! fs.existsSync( localPath ) ) {
return;
}
const confirmPrompt = `${localE2ePath} exists. Delete? [y]es/[n]o: `;
const deleteFile = confirm( confirmPrompt, 'ny' );
if ( deleteFile == 'y' ) {
fs.unlinkSync( localPath );
}
};
/**
* Get the install data for a tests package.
*
* @param {string} packageName npm package name
* @return {string}
*/
const getPackageData = ( packageName ) => {
const packageSlug = packageName.replace( '@', '' ).replace( /\//g, '.' );
const installFiles = require( `${packageName}${path.sep}installFiles` );
return { packageSlug, ...installFiles };
};
/**
* Install test runner and test container defaults
*/
const installDefaults = () => {
createLocalE2ePath( 'docker' );
console.log( 'Writing tests/e2e/docker/initialize.sh' );
confirmLocalCopy( `docker${path.sep}initialize.sh`, `installFiles${path.sep}initialize.sh` );
createLocalE2ePath( 'config' );
console.log( 'Writing tests/e2e/config/jest.config.js' );
confirmLocalCopy( `config${path.sep}jest.config.js`, `installFiles${path.sep}jest.config.js` );
console.log( 'Writing tests/e2e/config/jest.setup.js' );
confirmLocalCopy( `config${path.sep}jest.setup.js`, `installFiles${path.sep}jest.setup.js` );
};
module.exports = {
createLocalE2ePath,
confirm,
confirmLocalCopy,
confirmLocalDelete,
getPackageData,
installDefaults,
};

View File

@ -19,15 +19,84 @@ const resolveLocalE2ePath = ( filename = '' ) => {
);
return resolvedPath;
}
};
/**
* Resolve a package name installable by npm install.
*
* @param {string} packageName Name of the installed package.
* @param {boolean} allowRecurse Allow a recursive call. Default true.
* @return {object}
*/
const resolvePackage = ( packageName, allowRecurse = true ) => {
const resolvedPackage = {};
try {
const resolvedPath = path.dirname( require.resolve( packageName ) );
const buildPaths = [ 'dist', 'build', 'build-modules' ];
// Remove build paths from the resolved path.
let resolvedParts = resolvedPath.split( path.sep );
for ( let rp = resolvedParts.length - 1; rp >= 0; rp-- ) {
if ( buildPaths.includes( resolvedParts[ rp ] ) ) {
resolvedParts = resolvedParts.slice( 0, -1 );
} else {
break;
}
}
resolvedPackage.path = resolvedParts.join( path.sep );
resolvedPackage.name = packageName;
} catch ( e ) {
// Package name installed is not the package name.
resolvedPackage.path = '';
resolvedPackage.name = '';
}
// Attempt to find the package through the project package lock file.
if ( ! resolvedPackage.path.length && allowRecurse ) {
const packageLockPath = path.resolve( appPath, 'package-lock.json' );
const packageLockContent = fs.readFileSync( packageLockPath );
const { dependencies } = JSON.parse( packageLockContent );
for ( const [ key, value ] of Object.entries( dependencies ) ) {
if ( value.version.indexOf( packageName ) == 0 ) {
resolvedPackage = resolvePackage( key, false );
break;
}
}
}
return resolvedPackage;
};
/**
* Resolve a file in a package.
*
* @param {string} filename Filename to append to the path.
* @param {string} packageName Name of the installed package. Default @woocommerce/e2e-environment.
* @return {string}
*/
const resolvePackagePath = ( filename, packageName = '' ) => {
let packagePath;
if ( ! packageName.length ) {
packagePath = path.resolve( __dirname, '../' );
} else {
const pkg = resolvePackage( packageName );
packagePath = pkg.path;
}
const resolvedPath = path.resolve(
packagePath,
filename.indexOf( '/' ) == 0 ? filename.slice( 1 ) : filename
);
return resolvedPath;
};
// Copy local test configuration file if it exists.
const localTestConfigFile = resolveLocalE2ePath( 'config/default.json' );
const defaultConfigFile = path.resolve(
__dirname,
'../config/default/default.json'
);
const testConfigFile = path.resolve( __dirname, '../config/default.json' );
const defaultConfigFile = resolvePackagePath( 'config/default/default.json' );
const testConfigFile = resolvePackagePath( 'config/default.json' );
if ( fs.existsSync( localTestConfigFile ) ) {
fs.copyFileSync( localTestConfigFile, testConfigFile );
@ -94,4 +163,6 @@ module.exports = {
getTestConfig,
getAdminConfig,
resolveLocalE2ePath,
resolvePackage,
resolvePackagePath,
};

View File

@ -1,37 +1,44 @@
{
"root": "packages/js/e2e-utils/",
"sourceRoot": "packages/js/e2e-utils/src",
"projectType": "library",
"targets": {
"build": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "build"
}
},
"clean": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "clean"
}
},
"compile": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "compile"
}
},
"prepare": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "prepare"
}
},
"lint": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "lint"
}
}
}
"root": "packages/js/e2e-utils/",
"sourceRoot": "packages/js/e2e-utils/src",
"projectType": "library",
"targets": {
"changelog": {
"executor": "./tools/executors/changelogger:changelog",
"options": {
"action": "add",
"cwd": "packages/js/e2e-utils"
}
},
"build": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "build"
}
},
"clean": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "clean"
}
},
"compile": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "compile"
}
},
"prepare": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "prepare"
}
},
"lint": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "lint"
}
}
}
}

View File

@ -78,7 +78,7 @@ export const withRestApi = {
};
const response = await client.put( onboardingProfileEndpoint, onboardingReset );
expect( response.status ).toEqual( 200 );
expect( response.statusCode ).toEqual( 200 );
},
/**
* Use api package to delete coupons.

View File

@ -21,7 +21,7 @@
"pelago/emogrifier": "3.1.0",
"psr/container": "1.0.0",
"woocommerce/action-scheduler": "3.4.0",
"woocommerce/woocommerce-admin": "2.9.2",
"woocommerce/woocommerce-admin": "2.9.4",
"woocommerce/woocommerce-blocks": "6.3.3"
},
"require-dev": {

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": "688f13d253b2879a5f0181eb7fbf0e38",
"content-hash": "d12a5b11e3d6dc2ac228efa1cd5efadc",
"packages": [
{
"name": "automattic/jetpack-autoloader",
@ -543,16 +543,16 @@
},
{
"name": "woocommerce/woocommerce-admin",
"version": "2.9.2",
"version": "2.9.4",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce-admin.git",
"reference": "0533358c160f58272d02ae1962e267a546a5c26c"
"reference": "0cc85981f2def42e604118c7f5032e2750056763"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/0533358c160f58272d02ae1962e267a546a5c26c",
"reference": "0533358c160f58272d02ae1962e267a546a5c26c",
"url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/0cc85981f2def42e604118c7f5032e2750056763",
"reference": "0cc85981f2def42e604118c7f5032e2750056763",
"shasum": ""
},
"require": {
@ -608,9 +608,9 @@
"homepage": "https://github.com/woocommerce/woocommerce-admin",
"support": {
"issues": "https://github.com/woocommerce/woocommerce-admin/issues",
"source": "https://github.com/woocommerce/woocommerce-admin/tree/v2.9.2"
"source": "https://github.com/woocommerce/woocommerce-admin/tree/v2.9.4"
},
"time": "2021-12-13T23:49:48+00:00"
"time": "2021-12-15T14:33:43+00:00"
},
{
"name": "woocommerce/woocommerce-blocks",
@ -2926,5 +2926,5 @@
"platform-overrides": {
"php": "7.0.33"
},
"plugin-api-version": "2.1.0"
"plugin-api-version": "2.0.0"
}

View File

@ -149,11 +149,10 @@ class WC_Geolocation {
}
if ( empty( $ip_address ) ) {
$ip_address = self::get_ip_address();
$ip_address = self::get_ip_address();
$country_code = self::get_country_code_from_headers();
}
$country_code = self::get_country_code_from_headers();
/**
* Get geolocation filter.
*

View File

@ -1,153 +1,160 @@
{
"root": "plugins/woocommerce/",
"sourceRoot": "plugins/woocommerce",
"projectType": "application",
"implicitDependencies": [ "woocommerce-legacy-assets" ],
"targets": {
"composer-install": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "composer install",
"cwd": "plugins/woocommerce"
}
},
"composer-install-no-dev": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "composer install --no-dev",
"cwd": "plugins/woocommerce"
}
},
"composer-dump-autoload": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "composer dump-autoload",
"cwd": "plugins/woocommerce"
}
},
"build": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "build"
}
},
"build-core": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "build:core"
}
},
"build-zip": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "build:zip"
}
},
"build-watch": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "grunt watch",
"cwd": "plugins/woocommerce/legacy"
}
},
"build-assets": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "pnpm nx build woocommerce-legacy-assets",
"cwd": "plugins/woocommerce"
}
},
"lint-js": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "lint:js"
}
},
"docker-up": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "docker:up"
}
},
"docker-down": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "docker:down"
}
},
"docker-ssh": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "docker:ssh"
}
},
"test-api": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:api"
}
},
"test-e2e": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:e2e"
}
},
"test-e2e-debug": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:e2e-debug"
}
},
"test-e2e-dev": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:e2e-dev"
}
},
"test-unit": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:unit"
}
},
"makepot": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "makepot"
}
},
"packages-fix-text-domain": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "packages:fix:textdomain"
}
},
"git-update-hooks": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "git:update-hooks"
}
},
"make-collection": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "make:collection"
}
},
"install-unit-test-db": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "bash tests/bin/install.sh woo_test root root 127.0.0.1 latest",
"cwd": "plugins/woocommerce"
}
},
"test-code-coverage": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "RUN_CODE_COVERAGE=1 bash tests/bin/phpunit.sh",
"cwd": "plugins/woocommerce"
}
}
}
"root": "plugins/woocommerce/",
"sourceRoot": "plugins/woocommerce",
"projectType": "application",
"implicitDependencies": [ "woocommerce-legacy-assets" ],
"targets": {
"changelog": {
"executor": "./tools/executors/changelogger:changelog",
"options": {
"action": "add",
"cwd": "plugins/woocommerce"
}
},
"composer-install": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "composer install",
"cwd": "plugins/woocommerce"
}
},
"composer-install-no-dev": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "composer install --no-dev",
"cwd": "plugins/woocommerce"
}
},
"composer-dump-autoload": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "composer dump-autoload",
"cwd": "plugins/woocommerce"
}
},
"build": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "build"
}
},
"build-core": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "build:core"
}
},
"build-zip": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "build:zip"
}
},
"build-watch": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "grunt watch",
"cwd": "plugins/woocommerce/legacy"
}
},
"build-assets": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "pnpm nx build woocommerce-legacy-assets",
"cwd": "plugins/woocommerce"
}
},
"lint-js": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "lint:js"
}
},
"docker-up": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "docker:up"
}
},
"docker-down": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "docker:down"
}
},
"docker-ssh": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "docker:ssh"
}
},
"test-api": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:api"
}
},
"test-e2e": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:e2e"
}
},
"test-e2e-debug": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:e2e-debug"
}
},
"test-e2e-dev": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:e2e-dev"
}
},
"test-unit": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "test:unit"
}
},
"makepot": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "makepot"
}
},
"packages-fix-text-domain": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "packages:fix:textdomain"
}
},
"git-update-hooks": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "git:update-hooks"
}
},
"make-collection": {
"executor": "@nrwl/workspace:run-script",
"options": {
"script": "make:collection"
}
},
"install-unit-test-db": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "bash tests/bin/install.sh woo_test root root 127.0.0.1 latest",
"cwd": "plugins/woocommerce"
}
},
"test-code-coverage": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "RUN_CODE_COVERAGE=1 bash tests/bin/phpunit.sh",
"cwd": "plugins/woocommerce"
}
}
}
}

View File

@ -4,7 +4,7 @@ Tags: e-commerce, store, sales, sell, woo, shop, cart, checkout, downloadable, d
Requires at least: 5.6
Tested up to: 5.8
Requires PHP: 7.0
Stable tag: 5.9.0
Stable tag: 6.0.0
License: GPLv3
License URI: https://www.gnu.org/licenses/gpl-3.0.html
@ -160,61 +160,6 @@ WooCommerce comes with some sample data you can use to see how products look; im
== Changelog ==
= 5.9.0 2021-11-09 =
**WooCommerce**
* Fix - Bug in the handling of remote file names for downloadable files.
* Fix - Remove the absolute path to the currency-info.php from within locale-info.php. #31036
* Fix - wc_get_price_excluding_tax when an order with no customer is passed. #31015
* Fix - Rename transient used to cache data for Featured page of In-App Marketplace. #31002
* Fix - Variable product price caching bug with VAT exemption. #30889
* Fix - Allow to pass null as the email for billing addresses in REST API. #30850
* Fix - Ensure woocommerce_cancel_unpaid_orders event is always re-scheduled. #30830
* Fix - Use a more standard way to check if the product attributes lookup table exists. #30745
* Fix - Undefined variable notice when trying to add product in orders without specifying a product. #30739
* Fix - Use proper location for taxes when adding products via admin. #30692
* Dev - Add mobile data to WCTracker. #30415
* Tweak - Remove hardcode category banners in Settings > Marketplace and use the WooCommerce.com API instead. #30938
* Tweak - Show a search again message when marketplace results are empty. #30642
* Tweak - Add promoted cards styling to marketplace section. #30861
* Enhancement - Add ratings, reviews and icons into Marketplace's Product Cards. #30840
* Enhancement - Update Storefront banner width and track links in the marketplace page. #30882
* Enhancement - Revamp the WooCommerce Marketplace page. #30900
**WooCommerce Admin - 2.8.0 **
* Fix - Issue where stock activity panel was not rendering correctly. #7817
* Fix - Increase CSS specificity to avoid conflicts and broken panel styling. #7813
* Fix - Updated link to WooCommerce Developers Blog in readme.txt. #7824
* Fix - Fixed navigation menu text color after Gutenberg 11.6.0. #7771
* Fix - Add status param to notes/delete/all REST endpoint, to correctly delete all notes. #7743
* Fix - Allow already installed marketing extensions to be activated. #7740
* Fix - Add missing title text for marketing task. #7640
* Fix - Assign parent order status as children order status if refund order. #7253
* Fix - Fix category lookup logic to update children correctly. #7709
* Fix - Fixing an unwanted page refresh when using Woo Navigation. #7615
* Fix - Fix naming of event names and properties. #7677
* Fix - Fix white screen for variation analytic data without a name. #7686
* Add - Store Profiler and Product task - include Subscriptions. #7734
* Update - Update WC pay supported country list for the default free extensions. #7873
* Update - Update back up copy of free extension for Google Listing & Ads plugin. #7798
* Update - Update Eway payment gateway capitalization (was eWAY). #7678
* Update - Enable Square in France. #7679
* Enhancement - Only load tasks during rest api requests. #7856
* Enhancement - Add experiment for promoting WooCommerce Payments in payment methods table. #7666
**WooCommerce Blocks - 6.0.0 & 6.0.1 & 6.0.2 & 6.1.0**
* Fix - Infinite recursion when removing an attribute filter from the Active filters block. #4816
* Fix - Update All Reviews block so it honors 'ratings enabled' and 'show avatars' preferences. #4764
* Fix - Products by Category: Moved renderEmptyResponsePlaceholder to separate method to prevent unnecessary rerender. #4751
* Fix - Calculation of number of reviews in the Reviews by Category block. #4729
* Fix - Dropdown list in Product Category List Block for nested categories #4920
* Fix - String translations within the All Products Block. #4897
* Fix - Filter By Price: Update aria values to be more representative of the actual values presented. #4839
* Fix - Filter button from Filter Products by Attribute block is not aligned with the input field. #4814
* Fix - Remove IntersectionObserver shim in favor of dropping IE11 support. #4808
* Enhancement - Added global styles to All Reviews, Reviews by Category and Reviews by Product blocks. Now it's possible to change the text color and font size of those blocks. #4323
= 6.1.0 2021-XX-XX =
[See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/changelog.txt).

View File

@ -40,7 +40,7 @@ async function trashExistingPosts() {
// each other's side-effects.
beforeAll(async () => {
setupJestRetries();
setupJestRetries( 2 );
if ( DEFAULT_TIMEOUT_OVERRIDE ) {
page.setDefaultNavigationTimeout( DEFAULT_TIMEOUT_OVERRIDE );

View File

@ -7,6 +7,7 @@ importers:
'@automattic/nx-composer': ^0.1.0
'@babel/core': 7.12.9
'@nrwl/cli': latest
'@nrwl/devkit': ^13.1.4
'@nrwl/linter': ^13.1.4
'@nrwl/tao': latest
'@nrwl/web': ^13.1.4
@ -34,11 +35,12 @@ importers:
wp-textdomain: 1.0.1
devDependencies:
'@automattic/nx-composer': 0.1.0
'@nrwl/cli': 13.2.3
'@nrwl/cli': 13.3.6
'@nrwl/devkit': 13.1.4
'@nrwl/linter': 13.1.4
'@nrwl/tao': 13.2.3
'@nrwl/tao': 13.3.6
'@nrwl/web': 13.1.4_42cab1dece2b2240094de84cfd414406
'@nrwl/workspace': 13.2.3_wp-prettier@2.2.1-beta-1
'@nrwl/workspace': 13.3.6_42cab1dece2b2240094de84cfd414406
'@types/node': 14.14.33
'@woocommerce/eslint-plugin': 1.3.0
'@wordpress/prettier-config': 1.1.1
@ -130,8 +132,10 @@ importers:
jest-puppeteer: ^4.4.0
ndb: ^1.1.5
node-stream-zip: ^1.13.6
readline-sync: ^1.4.10
request: ^2.88.2
semver: ^7.3.2
sprintf-js: ^1.1.2
dependencies:
'@automattic/puppeteer-utils': github.com/Automattic/puppeteer-utils/0f3ec50
'@jest/test-sequencer': 25.5.4
@ -145,7 +149,9 @@ importers:
jest-each: 25.5.0
jest-puppeteer: 4.4.0
node-stream-zip: 1.15.0
readline-sync: 1.4.10
request: 2.88.2
sprintf-js: 1.1.2
devDependencies:
'@babel/cli': 7.12.8_@babel+core@7.12.9
'@babel/core': 7.12.9
@ -381,7 +387,6 @@ packages:
/@babel/compat-data/7.15.0:
resolution: {integrity: sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==}
engines: {node: '>=6.9.0'}
dev: true
/@babel/compat-data/7.16.4:
resolution: {integrity: sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==}
@ -431,7 +436,6 @@ packages:
source-map: 0.5.7
transitivePeerDependencies:
- supports-color
dev: true
/@babel/core/7.16.0:
resolution: {integrity: sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ==}
@ -515,7 +519,6 @@ packages:
'@babel/helper-validator-option': 7.14.5
browserslist: 4.17.6
semver: 6.3.0
dev: true
/@babel/helper-compilation-targets/7.16.3_@babel+core@7.16.0:
resolution: {integrity: sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==}
@ -747,7 +750,6 @@ packages:
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.16.0
dev: true
/@babel/helper-module-imports/7.16.0:
resolution: {integrity: sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==}
@ -769,7 +771,6 @@ packages:
'@babel/types': 7.16.0
transitivePeerDependencies:
- supports-color
dev: true
/@babel/helper-module-transforms/7.16.0:
resolution: {integrity: sha512-My4cr9ATcaBbmaEa8M0dZNA74cfI6gitvUAskgDtAFmAqyFKDSHQo5YstxPbN+lzHl2D9l/YOEFqb2mtUh4gfA==}
@ -852,7 +853,6 @@ packages:
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.16.0
dev: true
/@babel/helper-simple-access/7.16.0:
resolution: {integrity: sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==}
@ -926,7 +926,6 @@ packages:
'@babel/types': 7.16.0
transitivePeerDependencies:
- supports-color
dev: true
/@babel/helpers/7.16.3:
resolution: {integrity: sha512-Xn8IhDlBPhvYTvgewPKawhADichOsbkZuzN7qz2BusOM0brChsyXMDJvldWaYMMUNiCQdQzNEioXTp3sC8Nt8w==}
@ -956,7 +955,6 @@ packages:
resolution: {integrity: sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==}
engines: {node: '>=6.0.0'}
hasBin: true
dev: true
/@babel/parser/7.16.4:
resolution: {integrity: sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng==}
@ -1529,7 +1527,6 @@ packages:
dependencies:
'@babel/core': 7.15.8
'@babel/helper-plugin-utils': 7.14.5
dev: true
/@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.16.0:
resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
@ -1548,6 +1545,14 @@ packages:
'@babel/helper-plugin-utils': 7.14.5
dev: false
/@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.15.8:
resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.15.8
'@babel/helper-plugin-utils': 7.14.5
/@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.16.0:
resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==}
peerDependencies:
@ -1555,6 +1560,7 @@ packages:
dependencies:
'@babel/core': 7.16.0
'@babel/helper-plugin-utils': 7.14.5
dev: true
/@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.12.9:
resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
@ -1571,7 +1577,6 @@ packages:
dependencies:
'@babel/core': 7.15.8
'@babel/helper-plugin-utils': 7.14.5
dev: true
/@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.16.0:
resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
@ -1671,6 +1676,14 @@ packages:
'@babel/helper-plugin-utils': 7.14.5
dev: false
/@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.15.8:
resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.15.8
'@babel/helper-plugin-utils': 7.14.5
/@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.16.0:
resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
peerDependencies:
@ -1678,6 +1691,7 @@ packages:
dependencies:
'@babel/core': 7.16.0
'@babel/helper-plugin-utils': 7.14.5
dev: true
/@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.12.9:
resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
@ -1694,7 +1708,6 @@ packages:
dependencies:
'@babel/core': 7.15.8
'@babel/helper-plugin-utils': 7.14.5
dev: true
/@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.16.0:
resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
@ -1739,7 +1752,6 @@ packages:
dependencies:
'@babel/core': 7.15.8
'@babel/helper-plugin-utils': 7.14.5
dev: true
/@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.16.0:
resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
@ -1764,7 +1776,6 @@ packages:
dependencies:
'@babel/core': 7.15.8
'@babel/helper-plugin-utils': 7.14.5
dev: true
/@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.16.0:
resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
@ -1789,7 +1800,6 @@ packages:
dependencies:
'@babel/core': 7.15.8
'@babel/helper-plugin-utils': 7.14.5
dev: true
/@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.16.0:
resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
@ -1814,7 +1824,6 @@ packages:
dependencies:
'@babel/core': 7.15.8
'@babel/helper-plugin-utils': 7.14.5
dev: true
/@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.16.0:
resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
@ -1839,7 +1848,6 @@ packages:
dependencies:
'@babel/core': 7.15.8
'@babel/helper-plugin-utils': 7.14.5
dev: true
/@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.16.0:
resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
@ -1864,7 +1872,6 @@ packages:
dependencies:
'@babel/core': 7.15.8
'@babel/helper-plugin-utils': 7.14.5
dev: true
/@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.16.0:
resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
@ -3423,7 +3430,6 @@ packages:
globals: 11.12.0
transitivePeerDependencies:
- supports-color
dev: true
/@babel/traverse/7.16.3:
resolution: {integrity: sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag==}
@ -3915,11 +3921,11 @@ packages:
exit: 0.1.2
glob: 7.2.0
graceful-fs: 4.2.8
istanbul-lib-coverage: 3.2.0
istanbul-lib-coverage: 3.0.1
istanbul-lib-instrument: 4.0.3
istanbul-lib-report: 3.0.0
istanbul-lib-source-maps: 4.0.1
istanbul-reports: 3.0.5
istanbul-lib-source-maps: 4.0.0
istanbul-reports: 3.0.3
jest-haste-map: 25.5.1
jest-resolve: 25.5.1
jest-util: 25.5.0
@ -4140,9 +4146,9 @@ packages:
resolution: {integrity: sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==}
engines: {node: '>= 8.3'}
dependencies:
'@babel/core': 7.16.0
'@babel/core': 7.15.8
'@jest/types': 25.5.0
babel-plugin-istanbul: 6.1.1
babel-plugin-istanbul: 6.0.0
chalk: 3.0.0
convert-source-map: 1.8.0
fast-json-stable-stringify: 2.1.0
@ -4271,11 +4277,11 @@ packages:
yargs-parser: 20.0.0
dev: true
/@nrwl/cli/13.2.3:
resolution: {integrity: sha512-4hrOYQ9MqhWOdjQTwuQqHTfPu8lYgdFCE39PVWAcePtoi67mUeba54HkyT6nkTHI1TbO7q8Kf+R73dRhhxDlpA==}
/@nrwl/cli/13.3.6:
resolution: {integrity: sha512-rTTadMSMM4GAf3ZwKXq+lasoPTF6n5RAF4ApzmB3MhXmKWIkjgF1oMY2ZBm/RS0x1aOsNDWdggDKJwMgnDZQgA==}
hasBin: true
dependencies:
'@nrwl/tao': 13.2.3
'@nrwl/tao': 13.3.6
chalk: 4.1.0
enquirer: 2.3.6
v8-compile-cache: 2.3.0
@ -4342,10 +4348,10 @@ packages:
tslib: 2.3.1
dev: true
/@nrwl/devkit/13.2.3:
resolution: {integrity: sha512-/cp8hFclOXSAjj9pwb6bOU8yw593HfelcCBi8o8Jhb0Luhn1RzLCOpmHNsOf2hWzSUPEr0BuI0R55ubCEB+k6A==}
/@nrwl/devkit/13.3.6:
resolution: {integrity: sha512-SBq1NLHomZiSj+Ayc8q3xxxnXuFpJz2jt7GHXR+Ls6WnJUBfAVc1b4qcteT7X5ncUk/tXyAxrJC/34Gada79nQ==}
dependencies:
'@nrwl/tao': 13.2.3
'@nrwl/tao': 13.3.6
ejs: 3.1.6
ignore: 5.1.9
rxjs: 6.6.7
@ -4397,12 +4403,12 @@ packages:
- utf-8-validate
dev: true
/@nrwl/jest/13.2.3:
resolution: {integrity: sha512-M9/x0uZNSVKkcyNHcA2+Muj23KRo9SDiCsTb7HnkHhtSbhIWMd1knKP45bOr8CjeeiKNPeervx7uiN5516z8JA==}
/@nrwl/jest/13.3.6:
resolution: {integrity: sha512-npzlPhcmOogky6gIClCjgUajgAGMj1CYU9MmGlfrUmrgiZa8DFQXBV+4v6jT+oD3CwLWKnhVMWyBmow1Rt9FfQ==}
dependencies:
'@jest/reporters': 27.2.2
'@jest/test-result': 27.2.2
'@nrwl/devkit': 13.2.3
'@nrwl/devkit': 13.3.6
chalk: 4.1.0
identity-obj-proxy: 3.0.0
jest-config: 27.2.2
@ -4458,12 +4464,13 @@ packages:
- utf-8-validate
dev: true
/@nrwl/linter/13.2.3:
resolution: {integrity: sha512-kdzPWYzR96XYghJ5yIaYSybDrtcAcSxgcscwP1UWvME19O2W8DHbhIj3AzBgjSG0X6hBEh6k9kpyQ49jNkUMCw==}
/@nrwl/linter/13.3.6_typescript@4.2.4:
resolution: {integrity: sha512-GYqyz2N6Sr9tRYe7dRimCSkuCXZqT8xTM0G2w+yWKktoHXaJvf/i50TsPFrvR5h5qIbYUk7HWQ8ktBG+EyePAg==}
dependencies:
'@nrwl/devkit': 13.2.3
'@nrwl/jest': 13.2.3
eslint: 7.32.0
'@nrwl/devkit': 13.3.6
'@nrwl/jest': 13.3.6
'@phenomnomnominal/tsquery': 4.1.1_typescript@4.2.4
eslint: 8.2.0
glob: 7.1.4
minimatch: 3.0.4
tmp: 0.2.1
@ -4474,6 +4481,7 @@ packages:
- node-notifier
- supports-color
- ts-node
- typescript
- utf-8-validate
dev: true
@ -4511,15 +4519,17 @@ packages:
yargs-parser: 20.0.0
dev: true
/@nrwl/tao/13.2.3:
resolution: {integrity: sha512-vn+GqvFVinqAXzvbHznPBtCg9OCfirh3hF68sZgY2C6jZ3m47XwST3mLTRSDTtSDy9QfUrSZ6p4uAk2Iht0yBQ==}
/@nrwl/tao/13.3.6:
resolution: {integrity: sha512-tv5JX3H9pg0J4Br/I1qHLwSUef97R3Tu8U47ZZ537AQa1fIrixGV2lzKoLSDKAdQsQcKF832tRyqOWhrNqP0Kg==}
hasBin: true
dependencies:
chalk: 4.1.0
enquirer: 2.3.6
fast-glob: 3.2.7
fs-extra: 9.1.0
ignore: 5.1.9
jsonc-parser: 3.0.0
nx: 13.2.3
nx: 13.3.6
rxjs: 6.6.7
rxjs-for-await: 0.0.2_rxjs@6.6.7
semver: 7.3.4
@ -4685,33 +4695,37 @@ packages:
- utf-8-validate
dev: true
/@nrwl/workspace/13.2.3_wp-prettier@2.2.1-beta-1:
resolution: {integrity: sha512-dFB6XXDLP4Nmh/Sw8Euwdt7f0tg1O6JxJNvXV2BfWG1rK3dmhTz4Q+8fgxl7AxsrToVrXDAh16mPyfAzpqH4pw==}
/@nrwl/workspace/13.3.6_42cab1dece2b2240094de84cfd414406:
resolution: {integrity: sha512-0Xk6PlW9FRBrl3XeXCKHHJAGQCDuqcn34jgcBEBf4uYGF8vI+ZJLiqhwRNqseh6OlNnkJZmVViE0i8wIFCitxw==}
peerDependencies:
prettier: ^2.3.0
peerDependenciesMeta:
prettier:
optional: true
dependencies:
'@nrwl/cli': 13.2.3
'@nrwl/devkit': 13.2.3
'@nrwl/jest': 13.2.3
'@nrwl/linter': 13.2.3
'@parcel/watcher': 2.0.0-alpha.11
'@nrwl/cli': 13.3.6
'@nrwl/devkit': 13.3.6
'@nrwl/jest': 13.3.6
'@nrwl/linter': 13.3.6_typescript@4.2.4
'@parcel/watcher': 2.0.4
chalk: 4.1.0
chokidar: 3.5.2
cosmiconfig: 4.0.0
dotenv: 10.0.0
enquirer: 2.3.6
figures: 3.2.0
flat: 5.0.2
fs-extra: 9.1.0
glob: 7.1.4
ignore: 5.1.9
ink: 3.2.0_react@17.0.2
ink-spinner: 4.0.3_ink@3.2.0+react@17.0.2
minimatch: 3.0.4
npm-run-all: 4.1.5
npm-run-path: 4.0.1
open: 7.4.2
prettier: /wp-prettier/2.2.1-beta-1
react: 17.0.2
rxjs: 6.6.7
semver: 7.3.4
strip-ansi: 6.0.0
@ -4720,11 +4734,13 @@ packages:
yargs: 15.4.1
yargs-parser: 20.0.0
transitivePeerDependencies:
- '@types/react'
- bufferutil
- canvas
- node-notifier
- supports-color
- ts-node
- typescript
- utf-8-validate
dev: true
@ -4737,6 +4753,24 @@ packages:
node-gyp-build: 4.3.0
dev: true
/@parcel/watcher/2.0.4:
resolution: {integrity: sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg==}
engines: {node: '>= 10.0.0'}
requiresBuild: true
dependencies:
node-addon-api: 3.2.1
node-gyp-build: 4.3.0
dev: true
/@phenomnomnominal/tsquery/4.1.1_typescript@4.2.4:
resolution: {integrity: sha512-jjMmK1tnZbm1Jq5a7fBliM4gQwjxMU7TFoRNwIyzwlO+eHPRCFv/Nv+H/Gi1jc3WR7QURG8D5d0Tn12YGrUqBQ==}
peerDependencies:
typescript: ^3 || ^4
dependencies:
esquery: 1.4.0
typescript: 4.2.4
dev: true
/@pmmmwh/react-refresh-webpack-plugin/0.5.1_92cb4b81c6b9f71cf92f0bdb85e4210c:
resolution: {integrity: sha512-ccap6o7+y5L8cnvkZ9h8UXCGyy2DqtwCD+/N3Yru6lxMvcdkPKtdx13qd7sAC9s5qZktOmWf9lfUjsGOvSdYhg==}
engines: {node: '>= 10.13'}
@ -5274,6 +5308,10 @@ packages:
'@types/yargs-parser': 20.2.1
dev: true
/@types/yoga-layout/1.9.2:
resolution: {integrity: sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw==}
dev: true
/@typescript-eslint/eslint-plugin/3.10.1_aab05197bc2ab2306ca58e96baf5381b:
resolution: {integrity: sha512-PQg0emRtzZFWq6PxBcdxRH3QIQiyFO3WCVpRL3fgj5oQS3CDs3AeAKfv4DxNhzn8ITdNJGJ4D3Qw8eAJf3lXeQ==}
engines: {node: ^10.12.0 || >=12.0.0}
@ -6877,6 +6915,11 @@ packages:
engines: {node: '>= 4.5.0'}
hasBin: true
/auto-bind/4.0.0:
resolution: {integrity: sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==}
engines: {node: '>=8'}
dev: true
/autoprefixer/10.4.0_postcss@8.3.0:
resolution: {integrity: sha512-7FdJ1ONtwzV1G43GDD0kpVMn/qbiNqyOPMFTX5nRffI+7vgWoFEc6DcXOxHJxrWNDXrZh18eDsZjvZGUljSRGA==}
engines: {node: ^10 || ^12 || >=14}
@ -7073,18 +7116,18 @@ packages:
- supports-color
dev: false
/babel-jest/25.5.1_@babel+core@7.16.0:
/babel-jest/25.5.1_@babel+core@7.15.8:
resolution: {integrity: sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==}
engines: {node: '>= 8.3'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
'@babel/core': 7.16.0
'@babel/core': 7.15.8
'@jest/transform': 25.5.1
'@jest/types': 25.5.0
'@types/babel__core': 7.1.16
babel-plugin-istanbul: 6.1.1
babel-preset-jest: 25.5.0_@babel+core@7.16.0
babel-preset-jest: 25.5.0_@babel+core@7.15.8
chalk: 3.0.0
graceful-fs: 4.2.8
slash: 3.0.0
@ -7161,6 +7204,18 @@ packages:
- supports-color
dev: false
/babel-plugin-istanbul/6.0.0:
resolution: {integrity: sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==}
engines: {node: '>=8'}
dependencies:
'@babel/helper-plugin-utils': 7.14.5
'@istanbuljs/load-nyc-config': 1.1.0
'@istanbuljs/schema': 0.1.3
istanbul-lib-instrument: 4.0.3
test-exclude: 6.0.0
transitivePeerDependencies:
- supports-color
/babel-plugin-istanbul/6.1.1:
resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==}
engines: {node: '>=8'}
@ -7304,23 +7359,23 @@ packages:
'@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.12.9
dev: false
/babel-preset-current-node-syntax/0.1.4_@babel+core@7.16.0:
/babel-preset-current-node-syntax/0.1.4_@babel+core@7.15.8:
resolution: {integrity: sha512-5/INNCYhUGqw7VbVjT/hb3ucjgkVHKXY7lX3ZjlN4gm565VyFmJUrJ/h+h16ECVB38R/9SF6aACydpKMLZ/c9w==}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
'@babel/core': 7.16.0
'@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.16.0
'@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.16.0
'@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.16.0
'@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.16.0
'@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.16.0
'@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.16.0
'@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.16.0
'@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.16.0
'@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.16.0
'@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.16.0
'@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.16.0
'@babel/core': 7.15.8
'@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.15.8
'@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.15.8
'@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.15.8
'@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.15.8
'@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.15.8
'@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.15.8
'@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.15.8
'@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.15.8
'@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.15.8
'@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.15.8
'@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.15.8
/babel-preset-current-node-syntax/1.0.1_@babel+core@7.16.0:
resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==}
@ -7364,15 +7419,15 @@ packages:
babel-preset-current-node-syntax: 0.1.4_@babel+core@7.12.9
dev: false
/babel-preset-jest/25.5.0_@babel+core@7.16.0:
/babel-preset-jest/25.5.0_@babel+core@7.15.8:
resolution: {integrity: sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==}
engines: {node: '>= 8.3'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
'@babel/core': 7.16.0
'@babel/core': 7.15.8
babel-plugin-jest-hoist: 25.5.0
babel-preset-current-node-syntax: 0.1.4_@babel+core@7.16.0
babel-preset-current-node-syntax: 0.1.4_@babel+core@7.15.8
/babel-preset-jest/27.2.0_@babel+core@7.16.0:
resolution: {integrity: sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==}
@ -7671,7 +7726,6 @@ packages:
escalade: 3.1.1
node-releases: 2.0.1
picocolors: 1.0.0
dev: true
/browserslist/4.18.1:
resolution: {integrity: sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ==}
@ -7869,7 +7923,6 @@ packages:
/caniuse-lite/1.0.30001278:
resolution: {integrity: sha512-mpF9KeH8u5cMoEmIic/cr7PNS+F5LWBk0t2ekGT60lFf0Wq+n9LspAj0g3P+o7DQhD3sUdlMln4YFAWhFYn9jg==}
dev: true
/caniuse-lite/1.0.30001280:
resolution: {integrity: sha512-kFXwYvHe5rix25uwueBxC569o53J6TpnGu0BEEn+6Lhl2vsnAumRFWEBhDft1fwyo6m1r4i+RqA4+163FpeFcA==}
@ -8122,6 +8175,11 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/cli-boxes/2.2.1:
resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==}
engines: {node: '>=6'}
dev: true
/cli-cursor/2.1.0:
resolution: {integrity: sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=}
engines: {node: '>=4'}
@ -8135,6 +8193,11 @@ packages:
dependencies:
restore-cursor: 3.1.0
/cli-spinners/2.6.1:
resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==}
engines: {node: '>=6'}
dev: true
/cli-truncate/0.2.1:
resolution: {integrity: sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=}
engines: {node: '>=0.10.0'}
@ -8143,6 +8206,14 @@ packages:
string-width: 1.0.2
dev: true
/cli-truncate/2.1.0:
resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==}
engines: {node: '>=8'}
dependencies:
slice-ansi: 3.0.0
string-width: 4.2.3
dev: true
/cli-width/2.2.1:
resolution: {integrity: sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==}
dev: true
@ -8204,6 +8275,13 @@ packages:
resolution: {integrity: sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=}
engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
/code-excerpt/3.0.0:
resolution: {integrity: sha512-VHNTVhd7KsLGOqfX3SyeO8RyYPMp1GJOg194VITk04WMYCv4plV68YWe6TJZxd9MhobjtpMRnVky01gqZsalaw==}
engines: {node: '>=10'}
dependencies:
convert-to-spaces: 1.0.2
dev: true
/code-point-at/1.1.0:
resolution: {integrity: sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=}
engines: {node: '>=0.10.0'}
@ -8405,6 +8483,11 @@ packages:
dependencies:
safe-buffer: 5.1.2
/convert-to-spaces/1.0.2:
resolution: {integrity: sha1-fj5Iu+bZl7FBfdyihoIEtNPYVxU=}
engines: {node: '>= 4'}
dev: true
/cookie-signature/1.0.6:
resolution: {integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=}
dev: true
@ -9331,7 +9414,6 @@ packages:
/electron-to-chromium/1.3.889:
resolution: {integrity: sha512-suEUoPTD1mExjL9TdmH7cvEiWJVM2oEiAi+Y1p0QKxI2HcRlT44qDTP2c1aZmVwRemIPYOpxmV7CxQCOWcm4XQ==}
dev: true
/electron-to-chromium/1.3.899:
resolution: {integrity: sha512-w16Dtd2zl7VZ4N4Db+FIa7n36sgPGCKjrKvUUmp5ialsikvcQLjcJR9RWnlYNxIyEHLdHaoIZEqKsPxU9MdyBg==}
@ -12422,6 +12504,57 @@ packages:
/ini/1.3.8:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
/ink-spinner/4.0.3_ink@3.2.0+react@17.0.2:
resolution: {integrity: sha512-uJ4nbH00MM9fjTJ5xdw0zzvtXMkeGb0WV6dzSWvFv2/+ks6FIhpkt+Ge/eLdh0Ah6Vjw5pLMyNfoHQpRDRVFbQ==}
engines: {node: '>=10'}
peerDependencies:
ink: '>=3.0.5'
react: '>=16.8.2'
dependencies:
cli-spinners: 2.6.1
ink: 3.2.0_react@17.0.2
react: 17.0.2
dev: true
/ink/3.2.0_react@17.0.2:
resolution: {integrity: sha512-firNp1q3xxTzoItj/eOOSZQnYSlyrWks5llCTVX37nJ59K3eXbQ8PtzCguqo8YI19EELo5QxaKnJd4VxzhU8tg==}
engines: {node: '>=10'}
peerDependencies:
'@types/react': '>=16.8.0'
react: '>=16.8.0'
peerDependenciesMeta:
'@types/react':
optional: true
dependencies:
ansi-escapes: 4.3.2
auto-bind: 4.0.0
chalk: 4.1.2
cli-boxes: 2.2.1
cli-cursor: 3.1.0
cli-truncate: 2.1.0
code-excerpt: 3.0.0
indent-string: 4.0.0
is-ci: 2.0.0
lodash: 4.17.21
patch-console: 1.0.0
react: 17.0.2
react-devtools-core: 4.22.0
react-reconciler: 0.26.2_react@17.0.2
scheduler: 0.20.2
signal-exit: 3.0.5
slice-ansi: 3.0.0
stack-utils: 2.0.5
string-width: 4.2.3
type-fest: 0.12.0
widest-line: 3.1.0
wrap-ansi: 6.2.0
ws: 7.5.5
yoga-layout-prebuilt: 1.10.0
transitivePeerDependencies:
- bufferutil
- utf-8-validate
dev: true
/inquirer/6.5.2:
resolution: {integrity: sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==}
engines: {node: '>=6.0.0'}
@ -13006,6 +13139,10 @@ packages:
engines: {node: '>=6'}
dev: false
/istanbul-lib-coverage/3.0.1:
resolution: {integrity: sha512-GvCYYTxaCPqwMjobtVcVKvSHtAGe48MNhGjpK8LtVF8K0ISX7hCKl85LgtuaSneWVyQmaGcW3iXVV3GaZSLpmQ==}
engines: {node: '>=8'}
/istanbul-lib-coverage/3.2.0:
resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==}
engines: {node: '>=8'}
@ -13115,6 +13252,16 @@ packages:
- supports-color
dev: false
/istanbul-lib-source-maps/4.0.0:
resolution: {integrity: sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==}
engines: {node: '>=8'}
dependencies:
debug: 4.3.2
istanbul-lib-coverage: 3.0.1
source-map: 0.6.1
transitivePeerDependencies:
- supports-color
/istanbul-lib-source-maps/4.0.1:
resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==}
engines: {node: '>=10'}
@ -13124,6 +13271,7 @@ packages:
source-map: 0.6.1
transitivePeerDependencies:
- supports-color
dev: true
/istanbul-reports/1.5.1:
resolution: {integrity: sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw==}
@ -13138,12 +13286,20 @@ packages:
html-escaper: 2.0.2
dev: false
/istanbul-reports/3.0.3:
resolution: {integrity: sha512-0i77ZFLsb9U3DHi22WzmIngVzfoyxxbQcZRqlF3KoKmCJGq9nhFHoGi8FqBztN2rE8w6hURnZghetn0xpkVb6A==}
engines: {node: '>=8'}
dependencies:
html-escaper: 2.0.2
istanbul-lib-report: 3.0.0
/istanbul-reports/3.0.5:
resolution: {integrity: sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==}
engines: {node: '>=8'}
dependencies:
html-escaper: 2.0.2
istanbul-lib-report: 3.0.0
dev: true
/istanbul/1.0.0-alpha.2:
resolution: {integrity: sha1-BglrwI6Yuq10Sq5Gli2N+frGPQg=}
@ -13352,10 +13508,10 @@ packages:
resolution: {integrity: sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==}
engines: {node: '>= 8.3'}
dependencies:
'@babel/core': 7.16.0
'@babel/core': 7.15.8
'@jest/test-sequencer': 25.5.4
'@jest/types': 25.5.0
babel-jest: 25.5.1_@babel+core@7.16.0
babel-jest: 25.5.1_@babel+core@7.15.8
chalk: 3.0.0
deepmerge: 4.2.2
glob: 7.2.0
@ -13738,7 +13894,7 @@ packages:
jest-worker: 25.5.0
micromatch: 4.0.4
sane: 4.1.0
walker: 1.0.8
walker: 1.0.7
which: 2.0.2
optionalDependencies:
fsevents: 2.3.2
@ -13791,7 +13947,7 @@ packages:
resolution: {integrity: sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==}
engines: {node: '>= 8.3'}
dependencies:
'@babel/traverse': 7.16.3
'@babel/traverse': 7.16.0
'@jest/environment': 25.5.0
'@jest/source-map': 25.5.0
'@jest/test-result': 25.5.0
@ -15344,6 +15500,11 @@ packages:
kind-of: 6.0.3
dev: true
/makeerror/1.0.11:
resolution: {integrity: sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=}
dependencies:
tmpl: 1.0.5
/makeerror/1.0.12:
resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
dependencies:
@ -16167,21 +16328,21 @@ packages:
resolution: {integrity: sha512-LpCfZCWsVEtmD2SI1j2KRaw1uIyn4DJ3eRzsjnDYitbq38aORpkvYO+L0zVMZRNDSYSRGTsuj0nHCS3OOxK/Cg==}
hasBin: true
dependencies:
'@nrwl/cli': 13.2.3
'@nrwl/cli': 13.3.6
dev: true
/nx/13.1.4:
resolution: {integrity: sha512-m2j3wymaFlEl/7EoGxlgRzdmgQV1Rsh42df1cM8xFzAzV8ZGtR3Zq19qK7r9SUabpq8jMzp1e6rLQTHewCJWig==}
hasBin: true
dependencies:
'@nrwl/cli': 13.2.3
'@nrwl/cli': 13.3.6
dev: true
/nx/13.2.3:
resolution: {integrity: sha512-aNRbPjArROZazOKAiUhG5uZAZmL1uXdsGoA3p5mDt5fCLSj/CX1V/myuRx+Js0qsAV78W6dSf2z6TiQeIgieXg==}
/nx/13.3.6:
resolution: {integrity: sha512-fQqW5NLDpIsOkOdY8/YDpu9Dx1OjiIEDnnPhLdjCWsLVLhv0i8zcgs7nVWv4vPHdOapoZ4tYZ6I9w6qvgki5Kg==}
hasBin: true
dependencies:
'@nrwl/cli': 13.2.3
'@nrwl/cli': 13.3.6
dev: true
/oauth-1.0a/2.2.6:
@ -16655,6 +16816,11 @@ packages:
resolution: {integrity: sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=}
engines: {node: '>=0.10.0'}
/patch-console/1.0.0:
resolution: {integrity: sha512-nxl9nrnLQmh64iTzMfyylSlRozL7kAXIaxw1fVcLYdyhNkJCRUzirRZTikXGJsg+hc4fqpneTK6iU2H1Q8THSA==}
engines: {node: '>=10'}
dev: true
/path-browserify/0.0.1:
resolution: {integrity: sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==}
dev: true
@ -17958,6 +18124,16 @@ packages:
strip-json-comments: 2.0.1
dev: true
/react-devtools-core/4.22.0:
resolution: {integrity: sha512-OYY2FO+z+w/N7kVZr2x0rVOD2QCGZoRThbs1diJ2Az0rqtMxyk0JJvsr7FS9+b5CJkWQ2Ro810BCnySygOt2pA==}
dependencies:
shell-quote: 1.7.3
ws: 7.5.5
transitivePeerDependencies:
- bufferutil
- utf-8-validate
dev: true
/react-dom/17.0.2_react@17.0.2:
resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==}
peerDependencies:
@ -17983,6 +18159,18 @@ packages:
whatwg-url-without-unicode: 8.0.0-3
dev: false
/react-reconciler/0.26.2_react@17.0.2:
resolution: {integrity: sha512-nK6kgY28HwrMNwDnMui3dvm3rCFjZrcGiuwLc5COUipBK5hWHLOxMJhSnSomirqWwjPBJKV1QcbkI0VJr7Gl1Q==}
engines: {node: '>=0.10.0'}
peerDependencies:
react: ^17.0.2
dependencies:
loose-envify: 1.4.0
object-assign: 4.1.1
react: 17.0.2
scheduler: 0.20.2
dev: true
/react-refresh/0.10.0:
resolution: {integrity: sha512-PgidR3wST3dDYKr6b4pJoqQFpPGNKDSCDx4cZoshjXipw3LzO7mG1My2pwEzz2JVkF+inx3xRpDeQLFQGH/hsQ==}
engines: {node: '>=0.10.0'}
@ -18005,7 +18193,6 @@ packages:
dependencies:
loose-envify: 1.4.0
object-assign: 4.1.1
dev: false
/read-cache/1.0.0:
resolution: {integrity: sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=}
@ -18087,6 +18274,11 @@ packages:
dependencies:
picomatch: 2.3.0
/readline-sync/1.4.10:
resolution: {integrity: sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==}
engines: {node: '>= 0.8.0'}
dev: false
/realpath-native/1.1.0:
resolution: {integrity: sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==}
engines: {node: '>=4'}
@ -18662,7 +18854,6 @@ packages:
dependencies:
loose-envify: 1.4.0
object-assign: 4.1.1
dev: false
/schema-utils/1.0.0:
resolution: {integrity: sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==}
@ -18927,6 +19118,15 @@ packages:
astral-regex: 1.0.0
is-fullwidth-code-point: 2.0.0
/slice-ansi/3.0.0:
resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==}
engines: {node: '>=8'}
dependencies:
ansi-styles: 4.3.0
astral-regex: 2.0.0
is-fullwidth-code-point: 3.0.0
dev: true
/slice-ansi/4.0.0:
resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==}
engines: {node: '>=10'}
@ -20351,6 +20551,11 @@ packages:
resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==}
engines: {node: '>=4'}
/type-fest/0.12.0:
resolution: {integrity: sha512-53RyidyjvkGpnWPMF9bQgFtWp+Sl8O2Rp13VavmJgfAP9WWG6q6TkrKU8iyJdnwnfgHI6k2hTlgqH4aSdjoTbg==}
engines: {node: '>=10'}
dev: true
/type-fest/0.18.1:
resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==}
engines: {node: '>=10'}
@ -20747,6 +20952,11 @@ packages:
- supports-color
dev: false
/walker/1.0.7:
resolution: {integrity: sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=}
dependencies:
makeerror: 1.0.11
/walker/1.0.8:
resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==}
dependencies:
@ -21107,6 +21317,13 @@ packages:
string-width: 2.1.1
dev: true
/widest-line/3.1.0:
resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==}
engines: {node: '>=8'}
dependencies:
string-width: 4.2.3
dev: true
/wildcard/2.0.0:
resolution: {integrity: sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==}
dev: true
@ -21398,6 +21615,13 @@ packages:
engines: {node: '>=10'}
dev: true
/yoga-layout-prebuilt/1.10.0:
resolution: {integrity: sha512-YnOmtSbv4MTf7RGJMK0FvZ+KD8OEe/J5BNnR0GHhD8J/XcG/Qvxgszm0Un6FTHWW4uHlTgP0IztiXQnGyIR45g==}
engines: {node: '>=8'}
dependencies:
'@types/yoga-layout': 1.9.2
dev: true
/zwitch/1.0.5:
resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==}
dev: true

View File

@ -0,0 +1,9 @@
{
"executors": {
"changelog": {
"implementation": "./impl",
"schema": "./schema.json",
"description": "Executes Jetpack Changelogger scripts."
}
}
}

View File

@ -0,0 +1,115 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
exports.__esModule = true;
var child_process_1 = require("child_process");
var path_1 = require("path");
var fs_1 = require("fs");
var chalk = require("chalk");
var changeloggerScriptPath = 'vendor/bin/changelogger';
function runChangelogger(_a) {
var action = _a.action, cwd = _a.cwd, extraArgs = __rest(_a, ["action", "cwd"]);
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_b) {
return [2 /*return*/, new Promise(function (resolve, reject) {
var args = [action].concat(
// Add any extra arguments supplied. NX camel cases and converts values to Numbers.
// Undo all that so arguments can be passed to Jetpack Changelogger unmodified.
Object.keys(extraArgs).map(function (key) {
return "--" + key.replace(/[A-Z]/g, function (m) { return '-' + m.toLowerCase(); }) + "=" + (Number(extraArgs[key]) && action === 'write'
? extraArgs[key].toFixed(1)
: extraArgs[key]);
}));
var changeloggerScript = (0, child_process_1.spawn)("./" + changeloggerScriptPath, args, {
stdio: 'inherit'
});
changeloggerScript.on('close', function (code) {
resolve({ code: code, error: undefined });
});
changeloggerScript.on('error', function (error) {
reject({ code: 1, error: error });
});
})];
});
});
}
function changelogExecutor(options, context) {
return __awaiter(this, void 0, void 0, function () {
var cwd, projectPath, _a, code, error;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
cwd = options.cwd;
projectPath = (0, path_1.join)(__dirname, '../../../', cwd);
console.info(chalk.cyan("\nExecuting Changelogger...\n"));
try {
process.chdir(projectPath);
console.log(chalk.yellow('Executing from directory: ' + process.cwd() + '\n'));
}
catch (error) {
console.error(chalk.bgRed('Unable to find project working directory'));
console.error(error);
return [2 /*return*/, { success: false }];
}
if (!(0, fs_1.existsSync)(changeloggerScriptPath)) {
console.error(chalk.bgRed('Changelogger scripts not found. Did you remember to `composer install` from project directory?'));
return [2 /*return*/, { success: false }];
}
return [4 /*yield*/, runChangelogger(options)];
case 1:
_a = _b.sent(), code = _a.code, error = _a.error;
if (error) {
console.error(chalk.bgRed(error));
return [2 /*return*/, { success: false }];
}
return [2 /*return*/, { success: code === 0 }];
}
});
});
}
exports["default"] = changelogExecutor;

View File

@ -0,0 +1,96 @@
/**
* External dependencies
*/
import { ExecutorContext } from '@nrwl/devkit';
import { spawn } from 'child_process';
import { join } from 'path';
import { existsSync } from 'fs';
import * as chalk from 'chalk';
export interface ChangelogExecutorOptions {
action: string;
cwd: string;
}
const changeloggerScriptPath = 'vendor/bin/changelogger';
async function runChangelogger( {
action,
cwd,
...extraArgs
}: ChangelogExecutorOptions ): Promise< { code: number; error: string } > {
return new Promise( ( resolve, reject ) => {
const args = [ action ].concat(
// Add any extra arguments supplied. NX camel cases and converts values to Numbers.
// Undo all that so arguments can be passed to Jetpack Changelogger unmodified.
Object.keys( extraArgs ).map(
( key ) =>
`--${ key.replace(
/[A-Z]/g,
( m ) => '-' + m.toLowerCase()
) }=${
Number( extraArgs[ key ] ) && action === 'write'
? extraArgs[ key ].toFixed( 1 )
: extraArgs[ key ]
}`
)
);
const changeloggerScript = spawn(
`./${ changeloggerScriptPath }`,
args,
{
stdio: 'inherit',
}
);
changeloggerScript.on( 'close', ( code ) => {
resolve( { code, error: undefined } );
} );
changeloggerScript.on( 'error', ( error ) => {
reject( { code: 1, error } );
} );
} );
}
export default async function changelogExecutor(
options: ChangelogExecutorOptions,
context: ExecutorContext
) {
const { cwd } = options;
const projectPath = join( __dirname, '../../../', cwd );
console.info( chalk.cyan( `\nExecuting Changelogger...\n` ) );
try {
process.chdir( projectPath );
console.log(
chalk.yellow( 'Executing from directory: ' + process.cwd() + '\n' )
);
} catch ( error ) {
console.error(
chalk.bgRed( 'Unable to find project working directory' )
);
console.error( error );
return { success: false };
}
if ( ! existsSync( changeloggerScriptPath ) ) {
console.error(
chalk.bgRed(
'Changelogger scripts not found. Did you remember to `composer install` from project directory?'
)
);
return { success: false };
}
const { code, error } = await runChangelogger( options );
if ( error ) {
console.error( chalk.bgRed( error ) );
return { success: false };
}
return { success: code === 0 };
}

View File

@ -0,0 +1,3 @@
{
"executors": "./executor.json"
}

View File

@ -0,0 +1,13 @@
{
"cli": "nx",
"id": "Changelogger",
"description": "Executes Jetpack Changelogger scripts.",
"type": "object",
"properties": {
"action": {
"type": "string",
"description": "Action to take"
}
},
"required": [ "action" ]
}