From c5a27cbd5586fd1d7cb8acc0bc90f9ee5581dd10 Mon Sep 17 00:00:00 2001 From: Fernando Marichal Date: Fri, 13 Jan 2023 17:04:02 -0300 Subject: [PATCH] Add advanced setting option (#36380) * Modify feature flag * Add tooltip to WC > Settings > Advanced > Features * Add Settings option * Add `optional_features` and `beta_features` option * Add changelog * Fix lint * Fix lint * Add `new_product_management` to legacy features * Fix escaped tooltip * Fix `Analytics pages` e2e tests * Fix `Payment setup task` e2e tests Co-authored-by: Fernando Marichal --- .../add-36163_advanced_setting_option | 4 + .../woocommerce/client/admin/config/core.json | 2 +- .../client/admin/config/development.json | 2 +- .../woocommerce/client/legacy/css/admin.scss | 5 + .../admin/class-wc-admin-settings.php | 1 + .../src/Admin/Features/Features.php | 12 +- .../NewProductManagementExperience.php | 5 + .../Internal/Features/FeaturesController.php | 23 +++- .../tests/admin-analytics/analytics.spec.js | 4 +- .../e2e-pw/tests/admin-tasks/payment.spec.js | 122 +++++++++--------- 10 files changed, 109 insertions(+), 71 deletions(-) create mode 100644 plugins/woocommerce/changelog/add-36163_advanced_setting_option diff --git a/plugins/woocommerce/changelog/add-36163_advanced_setting_option b/plugins/woocommerce/changelog/add-36163_advanced_setting_option new file mode 100644 index 00000000000..ec1ce1cee44 --- /dev/null +++ b/plugins/woocommerce/changelog/add-36163_advanced_setting_option @@ -0,0 +1,4 @@ +Significance: minor +Type: dev + +Add advanced setting option diff --git a/plugins/woocommerce/client/admin/config/core.json b/plugins/woocommerce/client/admin/config/core.json index f798a3ab4a9..e9966a18156 100644 --- a/plugins/woocommerce/client/admin/config/core.json +++ b/plugins/woocommerce/client/admin/config/core.json @@ -14,7 +14,7 @@ "minified-js": false, "mobile-app-banner": true, "navigation": true, - "new-product-management-experience": false, + "new-product-management-experience": true, "onboarding": true, "onboarding-tasks": true, "product-variation-management": false, diff --git a/plugins/woocommerce/client/admin/config/development.json b/plugins/woocommerce/client/admin/config/development.json index 3f717d83e0d..71a4f00d30c 100644 --- a/plugins/woocommerce/client/admin/config/development.json +++ b/plugins/woocommerce/client/admin/config/development.json @@ -14,7 +14,7 @@ "minified-js": true, "mobile-app-banner": true, "navigation": true, - "new-product-management-experience": false, + "new-product-management-experience": true, "onboarding": true, "onboarding-tasks": true, "payment-gateway-suggestions": true, diff --git a/plugins/woocommerce/client/legacy/css/admin.scss b/plugins/woocommerce/client/legacy/css/admin.scss index 1b20c18b198..e0d69f3b7db 100644 --- a/plugins/woocommerce/client/legacy/css/admin.scss +++ b/plugins/woocommerce/client/legacy/css/admin.scss @@ -4375,6 +4375,11 @@ img.help_tip { top: 20px; } + td.help-tooltip { + white-space: nowrap; + width: 8px; + } + .select2-container { vertical-align: top; margin-bottom: 3px; diff --git a/plugins/woocommerce/includes/admin/class-wc-admin-settings.php b/plugins/woocommerce/includes/admin/class-wc-admin-settings.php index d10e7cc649a..1bcb512c5d3 100644 --- a/plugins/woocommerce/includes/admin/class-wc-admin-settings.php +++ b/plugins/woocommerce/includes/admin/class-wc-admin-settings.php @@ -492,6 +492,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) : ?> +
array( 'default' => 'no' ), - 'navigation' => array( 'default' => 'no' ), - 'settings' => array( 'default' => 'no' ), - 'analytics' => array( 'default' => 'yes' ), - 'remote-inbox-notifications' => array( 'default' => 'yes' ), + 'multichannel-marketing' => array( 'default' => 'no' ), + 'navigation' => array( 'default' => 'no' ), + 'settings' => array( 'default' => 'no' ), + 'new-product-management-experience' => array( 'default' => 'no' ), + 'analytics' => array( 'default' => 'yes' ), + 'remote-inbox-notifications' => array( 'default' => 'yes' ), ); /** @@ -41,6 +42,7 @@ class Features { protected static $beta_features = array( 'multichannel-marketing', 'navigation', + 'new-product-management-experience', 'settings', ); diff --git a/plugins/woocommerce/src/Admin/Features/NewProductManagementExperience.php b/plugins/woocommerce/src/Admin/Features/NewProductManagementExperience.php index cb27b95b337..8480f1b0be9 100644 --- a/plugins/woocommerce/src/Admin/Features/NewProductManagementExperience.php +++ b/plugins/woocommerce/src/Admin/Features/NewProductManagementExperience.php @@ -13,6 +13,11 @@ use \Automattic\WooCommerce\Internal\Admin\Loader; */ class NewProductManagementExperience { + /** + * Option name used to toggle this feature. + */ + const TOGGLE_OPTION_NAME = 'woocommerce_new_product_management_enabled'; + /** * Constructor */ diff --git a/plugins/woocommerce/src/Internal/Features/FeaturesController.php b/plugins/woocommerce/src/Internal/Features/FeaturesController.php index bf2622df5c2..5fe17a80970 100644 --- a/plugins/woocommerce/src/Internal/Features/FeaturesController.php +++ b/plugins/woocommerce/src/Internal/Features/FeaturesController.php @@ -8,6 +8,7 @@ namespace Automattic\WooCommerce\Internal\Features; use Automattic\Jetpack\Constants; use Automattic\WooCommerce\Internal\Admin\Analytics; use Automattic\WooCommerce\Admin\Features\Navigation\Init; +use Automattic\WooCommerce\Admin\Features\NewProductManagementExperience; use Automattic\WooCommerce\Internal\Traits\AccessiblePrivateMethods; use Automattic\WooCommerce\Proxies\LegacyProxy; use Automattic\WooCommerce\Utilities\ArrayUtil; @@ -89,25 +90,31 @@ class FeaturesController { */ public function __construct() { $features = array( - 'analytics' => array( + 'analytics' => array( 'name' => __( 'Analytics', 'woocommerce' ), 'description' => __( 'Enables WooCommerce Analytics', 'woocommerce' ), 'is_experimental' => false, 'enabled_by_default' => true, ), - 'new_navigation' => array( + 'new_navigation' => array( 'name' => __( 'Navigation', 'woocommerce' ), 'description' => __( 'Adds the new WooCommerce navigation experience to the dashboard', 'woocommerce' ), 'is_experimental' => false, ), - 'custom_order_tables' => array( + 'new_product_management' => array( + 'name' => __( 'New product editor', 'woocommerce' ), + 'description' => __( 'Try the new product editor (Beta)', 'woocommerce' ), + 'tooltip' => __( 'Enable to try the new, simplified product editor (currently in development and only available for simple products). No extension support yet.', 'woocommerce' ), + 'is_experimental' => false, + ), + 'custom_order_tables' => array( 'name' => __( 'High-Performance order storage (COT)', 'woocommerce' ), 'description' => __( 'Enable the high performance order storage feature.', 'woocommerce' ), 'is_experimental' => true, ), ); - $this->legacy_feature_ids = array( 'analytics', 'new_navigation' ); + $this->legacy_feature_ids = array( 'analytics', 'new_navigation', 'new_product_management' ); $this->init_features( $features ); @@ -393,6 +400,8 @@ class FeaturesController { return Analytics::TOGGLE_OPTION_NAME; } elseif ( 'new_navigation' === $feature_id ) { return Init::TOGGLE_OPTION_NAME; + } elseif ( 'new_product_management' === $feature_id ) { + return NewProductManagementExperience::TOGGLE_OPTION_NAME; } return "woocommerce_feature_${feature_id}_enabled"; @@ -450,7 +459,7 @@ class FeaturesController { $matches = array(); $success = preg_match( '/^woocommerce_feature_([a-zA-Z0-9_]+)_enabled$/', $option, $matches ); - if ( ! $success && Analytics::TOGGLE_OPTION_NAME !== $option && Init::TOGGLE_OPTION_NAME !== $option ) { + if ( ! $success && Analytics::TOGGLE_OPTION_NAME !== $option && Init::TOGGLE_OPTION_NAME !== $option && NewProductManagementExperience::TOGGLE_OPTION_NAME !== $option ) { return; } @@ -462,6 +471,8 @@ class FeaturesController { $feature_id = 'analytics'; } elseif ( Init::TOGGLE_OPTION_NAME === $option ) { $feature_id = 'new_navigation'; + } elseif ( NewProductManagementExperience::TOGGLE_OPTION_NAME === $option ) { + $feature_id = 'new_product_management'; } else { $feature_id = $matches[1]; } @@ -590,6 +601,7 @@ class FeaturesController { $description = $feature['description']; $disabled = false; $desc_tip = ''; + $tooltip = isset( $feature['tooltip'] ) ? $feature['tooltip'] : ''; if ( ( 'analytics' === $feature_id || 'new_navigation' === $feature_id ) && $admin_features_disabled ) { $disabled = true; @@ -675,6 +687,7 @@ class FeaturesController { 'id' => $this->feature_enable_option_name( $feature_id ), 'disabled' => $disabled && ! $this->force_allow_enabling_features, 'desc_tip' => $desc_tip, + 'tooltip' => $tooltip, 'default' => $this->feature_is_enabled_by_default( $feature_id ) ? 'yes' : 'no', ); } diff --git a/plugins/woocommerce/tests/e2e-pw/tests/admin-analytics/analytics.spec.js b/plugins/woocommerce/tests/e2e-pw/tests/admin-analytics/analytics.spec.js index 6d42ce0419a..7f301af5eb8 100644 --- a/plugins/woocommerce/tests/e2e-pw/tests/admin-analytics/analytics.spec.js +++ b/plugins/woocommerce/tests/e2e-pw/tests/admin-analytics/analytics.spec.js @@ -23,7 +23,9 @@ test.describe( 'Analytics pages', () => { await page.goto( `/wp-admin/admin.php?page=wc-admin&path=%2Fanalytics%2F${ urlTitle }` ); - const pageTitle = page.locator( 'h1' ); + const pageTitle = page.locator( + '.woocommerce-layout__header-wrapper > h1' + ); await expect( pageTitle ).toContainText( aPages ); await expect( page.locator( '#woocommerce-layout__primary' ) diff --git a/plugins/woocommerce/tests/e2e-pw/tests/admin-tasks/payment.spec.js b/plugins/woocommerce/tests/e2e-pw/tests/admin-tasks/payment.spec.js index b21e4cbe5a4..79168eca6c7 100644 --- a/plugins/woocommerce/tests/e2e-pw/tests/admin-tasks/payment.spec.js +++ b/plugins/woocommerce/tests/e2e-pw/tests/admin-tasks/payment.spec.js @@ -1,85 +1,91 @@ -const { test, expect } = require('@playwright/test'); -const wcApi = require('@woocommerce/woocommerce-rest-api').default; +const { test, expect } = require( '@playwright/test' ); +const wcApi = require( '@woocommerce/woocommerce-rest-api' ).default; -test.describe('Payment setup task', () => { - test.use({ storageState: process.env.ADMINSTATE }); +test.describe( 'Payment setup task', () => { + test.use( { storageState: process.env.ADMINSTATE } ); - test.beforeEach(async ({ page }) => { - await page.goto('wp-admin/admin.php?page=wc-admin&path=/setup-wizard'); - await page.click('text=Skip setup store details'); - await page.click('text=No thanks'); - await page.waitForLoadState('networkidle'); - }); + test.beforeEach( async ( { page } ) => { + await page.goto( + 'wp-admin/admin.php?page=wc-admin&path=/setup-wizard' + ); + await page.click( 'text=Skip setup store details' ); + await page.click( 'text=No thanks' ); + await page.waitForLoadState( 'networkidle' ); + } ); - test.afterAll(async ({ baseURL }) => { - const api = new wcApi({ + test.afterAll( async ( { baseURL } ) => { + const api = new wcApi( { url: baseURL, consumerKey: process.env.CONSUMER_KEY, consumerSecret: process.env.CONSUMER_SECRET, version: 'wc/v3', - }); - await api.put('payment_gateways/bacs', { + } ); + await api.put( 'payment_gateways/bacs', { enabled: false, - }); - await api.put('payment_gateways/cod', { + } ); + await api.put( 'payment_gateways/cod', { enabled: false, - }); - }); + } ); + } ); - test('Can visit the payment setup task from the homescreen if the setup wizard has been skipped', async ({ + test( 'Can visit the payment setup task from the homescreen if the setup wizard has been skipped', async ( { page, - }) => { - await page.goto('wp-admin/admin.php?page=wc-admin'); - await page.click('text=Set up payments'); - await expect(page.locator('h1')).toHaveText('Set up payments'); - }); + } ) => { + await page.goto( 'wp-admin/admin.php?page=wc-admin' ); + await page.click( 'text=Set up payments' ); + await expect( + page.locator( '.woocommerce-layout__header-wrapper > h1' ) + ).toHaveText( 'Set up payments' ); + } ); - test('Saving valid bank account transfer details enables the payment method', async ({ + test( 'Saving valid bank account transfer details enables the payment method', async ( { page, - }) => { + } ) => { // load the bank transfer page await page.goto( 'wp-admin/admin.php?page=wc-admin&task=payments&id=bacs' ); // purposely no await -- close the help dialog if/when it appears - page.locator('.components-button.is-small.has-icon') + page.locator( '.components-button.is-small.has-icon' ) .click() - .catch(() => {}); + .catch( () => {} ); // fill in bank transfer form - await page.fill('//input[@placeholder="Account name"]', 'Savings'); - await page.fill('//input[@placeholder="Account number"]', '1234'); - await page.fill('//input[@placeholder="Bank name"]', 'Test Bank'); - await page.fill('//input[@placeholder="Sort code"]', '12'); - await page.fill('//input[@placeholder="IBAN"]', '12 3456 7890'); - await page.fill('//input[@placeholder="BIC / Swift"]', 'ABBA'); - await page.click('text=Save'); + await page.fill( '//input[@placeholder="Account name"]', 'Savings' ); + await page.fill( '//input[@placeholder="Account number"]', '1234' ); + await page.fill( '//input[@placeholder="Bank name"]', 'Test Bank' ); + await page.fill( '//input[@placeholder="Sort code"]', '12' ); + await page.fill( '//input[@placeholder="IBAN"]', '12 3456 7890' ); + await page.fill( '//input[@placeholder="BIC / Swift"]', 'ABBA' ); + await page.click( 'text=Save' ); // check that bank transfers were set up await expect( - page.locator('div.components-snackbar__content') - ).toContainText('Direct bank transfer details added successfully'); + page.locator( 'div.components-snackbar__content' ) + ).toContainText( 'Direct bank transfer details added successfully' ); - await page.goto('wp-admin/admin.php?page=wc-settings&tab=checkout'); + await page.goto( 'wp-admin/admin.php?page=wc-settings&tab=checkout' ); await expect( - page.locator('//tr[@data-gateway_id="bacs"]/td[@class="status"]/a') - ).toHaveClass('wc-payment-gateway-method-toggle-enabled'); - }); + page.locator( + '//tr[@data-gateway_id="bacs"]/td[@class="status"]/a' + ) + ).toHaveClass( 'wc-payment-gateway-method-toggle-enabled' ); + } ); - test('Enabling cash on delivery enables the payment method', async ({ + test( 'Enabling cash on delivery enables the payment method', async ( { page, baseURL, - }) => { + } ) => { // Payments page differs if located outside of a WCPay-supported country, so make sure we aren't. - const api = new wcApi({ + const api = new wcApi( { url: baseURL, consumerKey: process.env.CONSUMER_KEY, consumerSecret: process.env.CONSUMER_SECRET, version: 'wc/v3', - }); + } ); // ensure store address is US - await api.post('settings/general/batch', { + await api.post( 'settings/general/batch', { update: [ { id: 'woocommerce_store_address', @@ -98,28 +104,28 @@ test.describe('Payment setup task', () => { value: '94107', }, ], - }); - await page.goto('wp-admin/admin.php?page=wc-admin&task=payments'); + } ); + await page.goto( 'wp-admin/admin.php?page=wc-admin&task=payments' ); // purposely no await -- close the help dialog if/when it appears - page.locator('.components-button.is-small.has-icon') + page.locator( '.components-button.is-small.has-icon' ) .click() - .catch(() => {}); - await page.waitForLoadState('networkidle'); + .catch( () => {} ); + await page.waitForLoadState( 'networkidle' ); // purposely no await again - page.click('button.toggle-button'); + page.click( 'button.toggle-button' ); // enable COD payment option await page.click( 'div.woocommerce-task-payment-cod > div.woocommerce-task-payment__footer > button' ); - await page.waitForLoadState('networkidle'); + await page.waitForLoadState( 'networkidle' ); - await page.goto('wp-admin/admin.php?page=wc-settings&tab=checkout'); + await page.goto( 'wp-admin/admin.php?page=wc-settings&tab=checkout' ); await expect( - page.locator('//tr[@data-gateway_id="cod"]/td[@class="status"]/a') - ).toHaveClass('wc-payment-gateway-method-toggle-enabled'); - }); -}); + page.locator( '//tr[@data-gateway_id="cod"]/td[@class="status"]/a' ) + ).toHaveClass( 'wc-payment-gateway-method-toggle-enabled' ); + } ); +} );