From 572201086972f4712c1b7bfd63915193ad083838 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun Date: Wed, 13 Jan 2021 14:13:36 +0200 Subject: [PATCH 01/17] MC-37418: [Safari browser] Popup not closed with a configuration. --- .../adminhtml/web/catalog/product/composite/configure.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js index 4040ff9d684f4..d460c93714b3d 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js @@ -47,10 +47,14 @@ define([ * Initialize object */ initialize: function () { - var self = this; + var self = this, + popupDialog = jQuery('#product_composite_configure'); this._initWindowElements(); jQuery.async('#product_composite_configure', function (el) { + if (el !== popupDialog[0]) { + el = popupDialog[0]; + } self.dialog = jQuery(el).modal({ title: jQuery.mage.__('Configure Product'), type: 'slide', From 6d470880d9133d05900f20512c95855abd470be3 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun Date: Mon, 18 Jan 2021 16:56:52 +0200 Subject: [PATCH 02/17] MC-37418: [Safari browser] Popup not closed with a configuration. --- .../catalog/product/composite/configure.js | 6 +- ...minCustomerEditWishlistItemActionGroup.xml | 25 ++++ .../Section/AdminCustomerWishlistSection.xml | 3 + ...AdminConfigureCustomerWishListItemTest.xml | 120 ++++++++++++++++++ .../layout/customer_index_wishlist.xml | 1 - 5 files changed, 149 insertions(+), 6 deletions(-) create mode 100644 app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerEditWishlistItemActionGroup.xml create mode 100644 app/code/Magento/Wishlist/Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml diff --git a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js index d460c93714b3d..4040ff9d684f4 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js @@ -47,14 +47,10 @@ define([ * Initialize object */ initialize: function () { - var self = this, - popupDialog = jQuery('#product_composite_configure'); + var self = this; this._initWindowElements(); jQuery.async('#product_composite_configure', function (el) { - if (el !== popupDialog[0]) { - el = popupDialog[0]; - } self.dialog = jQuery(el).modal({ title: jQuery.mage.__('Configure Product'), type: 'slide', diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerEditWishlistItemActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerEditWishlistItemActionGroup.xml new file mode 100644 index 0000000000000..05c75a4cdb909 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerEditWishlistItemActionGroup.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml index 39a67968c66e4..f4760daef7d6e 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml @@ -14,5 +14,8 @@ + + + diff --git a/app/code/Magento/Wishlist/Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml b/app/code/Magento/Wishlist/Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml new file mode 100644 index 0000000000000..4bb0972782d3e --- /dev/null +++ b/app/code/Magento/Wishlist/Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml @@ -0,0 +1,120 @@ + + + + + + + + + + <description value="Admin should be able to configure items from customer wishlist"/> + <severity value="MAJOR"/> + <testCaseId value="MC-40455"/> + <group value="wishlist"/> + </annotations> + <before> + <createData entity="SimpleSubCategory" stepKey="createCategory"/> + <!-- Create the configurable product based on the data in the /data folder --> + <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + + <!-- Make the configurable product have two options, that are children of the default attribute set --> + <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> + <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getConfigAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + + <!-- Create the 2 children that will be a part of the configurable product --> + <createData entity="ApiSimpleOne" stepKey="createConfigChildProduct1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + </createData> + <createData entity="ApiSimpleTwo" stepKey="createConfigChildProduct2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + + <!-- Assign the two products to the configurable product --> + <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild1"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct1"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild2"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct2"/> + </createData> + <createData entity="Simple_US_Customer" stepKey="createCustomer"/> + </before> + <after> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> + <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> + <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> + <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutOfAdmin"/> + <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> + <argument name="indices" value=""/> + </actionGroup> + </after> + + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefrontAccount"> + <argument name="Customer" value="$createCustomer$"/> + </actionGroup> + <actionGroup ref="OpenProductFromCategoryPageActionGroup" stepKey="openProductFromCategory"> + <argument name="category" value="$createCategory$"/> + <argument name="product" value="$createConfigProduct$"/> + </actionGroup> + <actionGroup ref="StorefrontCustomerAddProductToWishlistActionGroup" stepKey="addToWishlistProduct"> + <argument name="productVar" value="$createConfigProduct$"/> + </actionGroup> + <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logout"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="adminLogoutBeforeCheck"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <actionGroup ref="OpenEditCustomerFromAdminActionGroup" stepKey="navigateToCustomerEditPage"> + <argument name="customer" value="$createCustomer$"/> + </actionGroup> + <actionGroup ref="AdminNavigateCustomerWishlistTabActionGroup" stepKey="navigateToWishlistTab"/> + <actionGroup ref="AdminCustomerFindWishlistItemActionGroup" stepKey="findWishlistItem"> + <argument name="productName" value="$createConfigProduct.name$"/> + </actionGroup> + <actionGroup ref="AdminCustomerEditWishlistItemActionGroup" stepKey="deleteItem"> + <argument name="title" value="$createConfigProductAttribute.attribute[frontend_labels][0][label]$"/> + <argument name="option" value="$getConfigAttributeOption1.label$"/> + <argument name="quantity" value="2"/> + </actionGroup> + <click selector="{{AdminCustomerMainActionsSection.saveButton}}" stepKey="saveCustomer"/> + <seeElement selector="{{AdminCustomerMessagesSection.successMessage}}" stepKey="assertSuccessMessage"/> + <actionGroup ref="OpenEditCustomerFromAdminActionGroup" stepKey="navigateToCustomerEditPage2"> + <argument name="customer" value="$createCustomer$"/> + </actionGroup> + <actionGroup ref="AdminNavigateCustomerWishlistTabActionGroup" stepKey="navigateToWishlistTabAgain"/> + <waitForElementVisible selector="{{AdminCustomerWishlistSection.productQty}}" stepKey="waitForProductQuantityVisible"/> + <see selector="{{AdminCustomerWishlistSection.productQty}}" userInput="2" stepKey="assertProductQuantity"/> + </test> +</tests> diff --git a/app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_wishlist.xml b/app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_wishlist.xml index 0ee4233029105..cc5ef6b3ab554 100644 --- a/app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_wishlist.xml +++ b/app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_wishlist.xml @@ -112,6 +112,5 @@ </arguments> </block> </block> - <block class="Magento\Catalog\Block\Adminhtml\Product\Composite\Configure" template="Magento_Catalog::catalog/product/composite/configure.phtml" name="configure.popup"/> </container> </layout> From 35a73ea6e71b6817dd595f9dd66ae0f6d2ba6da9 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Tue, 19 Jan 2021 13:06:52 +0200 Subject: [PATCH 03/17] MC-37418: [Safari browser] Popup not closed with a configuration. --- .../ActionGroup/AdminCustomerEditWishlistItemActionGroup.xml | 4 ++-- .../Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerEditWishlistItemActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerEditWishlistItemActionGroup.xml index 05c75a4cdb909..184e730bbf8fb 100644 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerEditWishlistItemActionGroup.xml +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerEditWishlistItemActionGroup.xml @@ -17,8 +17,8 @@ <click selector="{{AdminCustomerWishlistSection.configureButton}}" stepKey="clickConfigureButton"/> <waitForAjaxLoad stepKey="waitForPopupLoad"/> <waitForElementVisible selector="{{AdminCustomerWishlistSection.productAttributeOptionsDropDown(title)}}" stepKey="waitForConfigurableOption"/> - <selectOption selector="{{AdminCustomerWishlistSection.productAttributeOptionsDropDown(title)}}" userInput="option" stepKey="selectConfigurableOption"/> - <fillField userInput="{{quantity}}" selector="{{AdminOrderFormConfigureProductSection.quantity}}" stepKey="fillQty"/> + <selectOption selector="{{AdminCustomerWishlistSection.productAttributeOptionsDropDown(title)}}" userInput="{{option}}" stepKey="selectConfigurableOption"/> + <fillField selector="{{AdminOrderFormConfigureProductSection.quantity}}" userInput="{{quantity}}" stepKey="fillQty"/> <click selector="{{AdminOrderFormConfigureProductSection.ok}}" stepKey="confirmSave"/> <waitForAjaxLoad stepKey="waitForPopupClose"/> </actionGroup> diff --git a/app/code/Magento/Wishlist/Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml b/app/code/Magento/Wishlist/Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml index 4bb0972782d3e..e39f6e89db770 100644 --- a/app/code/Magento/Wishlist/Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml +++ b/app/code/Magento/Wishlist/Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml @@ -103,7 +103,7 @@ <actionGroup ref="AdminCustomerFindWishlistItemActionGroup" stepKey="findWishlistItem"> <argument name="productName" value="$createConfigProduct.name$"/> </actionGroup> - <actionGroup ref="AdminCustomerEditWishlistItemActionGroup" stepKey="deleteItem"> + <actionGroup ref="AdminCustomerEditWishlistItemActionGroup" stepKey="editItem"> <argument name="title" value="$createConfigProductAttribute.attribute[frontend_labels][0][label]$"/> <argument name="option" value="$getConfigAttributeOption1.label$"/> <argument name="quantity" value="2"/> From 426737203c3cab75011f4dab3db7511cb17801ed Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Thu, 21 Jan 2021 12:53:41 +0200 Subject: [PATCH 04/17] MC-37418: [Safari browser] Popup not closed with a configuration. --- ...tomerWishlistConfigureItemActionGroup.xml} | 10 +++---- .../Section/AdminCustomerWishlistSection.xml | 4 +-- ...AdminConfigureCustomerWishListItemTest.xml | 29 +++++++------------ 3 files changed, 17 insertions(+), 26 deletions(-) rename app/code/Magento/Customer/Test/Mftf/ActionGroup/{AdminCustomerEditWishlistItemActionGroup.xml => AdminCustomerWishlistConfigureItemActionGroup.xml} (75%) diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerEditWishlistItemActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerWishlistConfigureItemActionGroup.xml similarity index 75% rename from app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerEditWishlistItemActionGroup.xml rename to app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerWishlistConfigureItemActionGroup.xml index 184e730bbf8fb..3584684d8cbc4 100644 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerEditWishlistItemActionGroup.xml +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerWishlistConfigureItemActionGroup.xml @@ -8,18 +8,16 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminCustomerEditWishlistItemActionGroup"> + <actionGroup name="AdminCustomerWishlistConfigureItemActionGroup"> <arguments> - <argument name="title" type="string"/> - <argument name="option" type="string"/> - <argument name="quantity" type="string"/> + <argument name="title" type="string" defaultValue="{{Attribute.label}}"/> + <argument name="option" type="string" defaultValue="option1"/> + <argument name="quantity" type="string" defaultValue="2"/> </arguments> <click selector="{{AdminCustomerWishlistSection.configureButton}}" stepKey="clickConfigureButton"/> - <waitForAjaxLoad stepKey="waitForPopupLoad"/> <waitForElementVisible selector="{{AdminCustomerWishlistSection.productAttributeOptionsDropDown(title)}}" stepKey="waitForConfigurableOption"/> <selectOption selector="{{AdminCustomerWishlistSection.productAttributeOptionsDropDown(title)}}" userInput="{{option}}" stepKey="selectConfigurableOption"/> <fillField selector="{{AdminOrderFormConfigureProductSection.quantity}}" userInput="{{quantity}}" stepKey="fillQty"/> <click selector="{{AdminOrderFormConfigureProductSection.ok}}" stepKey="confirmSave"/> - <waitForAjaxLoad stepKey="waitForPopupClose"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml index f4760daef7d6e..c691f34777b57 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml @@ -14,8 +14,8 @@ <element name="deleteButton" type="text" selector="//*[@id='wishlistGrid_table']//*[@data-column='action']//*[text()='Delete']"/> <element name="deleteConfirm" type="button" selector=".modal-popup.confirm .action-primary.action-accept"/> <element name="gridTable" type="text" selector="#wishlistGrid_table"/> - <element name="configureButton" type="text" selector="//*[@id='wishlistGrid_table']//*[@data-column='action']//*[text()='Configure']"/> + <element name="configureButton" type="text" selector="//table[@id='wishlistGrid_table']//td[@data-column='action']//a[@class='configure-item-link']" timeout="30"/> <element name="productAttributeOptionsDropDown" type="text" selector="//label[contains(.,'{{var1}}')]/following::div[contains(@class,'control')]//select" parameterized="true"/> - <element name="productQty" type="text" selector="td.col-qty"/> + <element name="productQty" type="text" selector="//table[@id='wishlistGrid_table']//td[@data-column='qty' and contains(@class, 'col-number')]"/> </section> </sections> diff --git a/app/code/Magento/Wishlist/Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml b/app/code/Magento/Wishlist/Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml index e39f6e89db770..fcb21054badde 100644 --- a/app/code/Magento/Wishlist/Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml +++ b/app/code/Magento/Wishlist/Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml @@ -12,18 +12,16 @@ <annotations> <features value="Wishlist"/> <stories value="Wishlist item configuration"/> - <title value="Admin configures an item from customer wishlist"/> + <title value="Admin can configure a customer wishlist item"/> <description value="Admin should be able to configure items from customer wishlist"/> <severity value="MAJOR"/> <testCaseId value="MC-40455"/> + <useCaseId value="MC-36575"/> <group value="wishlist"/> </annotations> <before> - <createData entity="SimpleSubCategory" stepKey="createCategory"/> <!-- Create the configurable product based on the data in the /data folder --> - <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> - <requiredEntity createDataKey="createCategory"/> - </createData> + <createData entity="ApiConfigurableProductWithOutCategory" stepKey="createConfigProduct"/> <!-- Make the configurable product have two options, that are children of the default attribute set --> <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> @@ -69,32 +67,26 @@ <requiredEntity createDataKey="createConfigChildProduct2"/> </createData> <createData entity="Simple_US_Customer" stepKey="createCustomer"/> + <magentoCron groups="index" stepKey="reindexBrokenIndices"/> </before> <after> - <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logout"/> <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutOfAdmin"/> - <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> - <argument name="indices" value=""/> - </actionGroup> + <magentoCron groups="index" stepKey="reindexBrokenIndices"/> </after> <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefrontAccount"> <argument name="Customer" value="$createCustomer$"/> </actionGroup> - <actionGroup ref="OpenProductFromCategoryPageActionGroup" stepKey="openProductFromCategory"> - <argument name="category" value="$createCategory$"/> - <argument name="product" value="$createConfigProduct$"/> - </actionGroup> + <amOnPage url="{{StorefrontProductPage.url($createConfigProduct.custom_attributes[url_key]$)}}" stepKey="goToProductPage"/> <actionGroup ref="StorefrontCustomerAddProductToWishlistActionGroup" stepKey="addToWishlistProduct"> <argument name="productVar" value="$createConfigProduct$"/> </actionGroup> - <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logout"/> - <actionGroup ref="AdminLogoutActionGroup" stepKey="adminLogoutBeforeCheck"/> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <actionGroup ref="OpenEditCustomerFromAdminActionGroup" stepKey="navigateToCustomerEditPage"> <argument name="customer" value="$createCustomer$"/> @@ -103,13 +95,14 @@ <actionGroup ref="AdminCustomerFindWishlistItemActionGroup" stepKey="findWishlistItem"> <argument name="productName" value="$createConfigProduct.name$"/> </actionGroup> - <actionGroup ref="AdminCustomerEditWishlistItemActionGroup" stepKey="editItem"> + <actionGroup ref="AdminCustomerWishlistConfigureItemActionGroup" stepKey="editItem"> <argument name="title" value="$createConfigProductAttribute.attribute[frontend_labels][0][label]$"/> <argument name="option" value="$getConfigAttributeOption1.label$"/> <argument name="quantity" value="2"/> </actionGroup> - <click selector="{{AdminCustomerMainActionsSection.saveButton}}" stepKey="saveCustomer"/> - <seeElement selector="{{AdminCustomerMessagesSection.successMessage}}" stepKey="assertSuccessMessage"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="saveCustomer"/> + <waitForElementVisible selector="{{AdminMessagesSection.success}}" stepKey="waitForSuccessMessage"/> + <seeElement selector="{{AdminMessagesSection.success}}" stepKey="assertSuccessMessage"/> <actionGroup ref="OpenEditCustomerFromAdminActionGroup" stepKey="navigateToCustomerEditPage2"> <argument name="customer" value="$createCustomer$"/> </actionGroup> From 23b554008332387f01c35982b5fae730cb603e49 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Fri, 22 Jan 2021 13:41:29 +0200 Subject: [PATCH 05/17] MC-37418: [Safari browser] Popup not closed with a configuration. --- ...AdminCustomerWishlistConfigureItemActionGroup.xml | 3 ++- .../Mftf/Section/AdminCustomerWishlistSection.xml | 2 +- .../Test/AdminConfigureCustomerWishListItemTest.xml | 12 ++++++------ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerWishlistConfigureItemActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerWishlistConfigureItemActionGroup.xml index 3584684d8cbc4..de126e6cc6585 100644 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerWishlistConfigureItemActionGroup.xml +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerWishlistConfigureItemActionGroup.xml @@ -13,8 +13,9 @@ <argument name="title" type="string" defaultValue="{{Attribute.label}}"/> <argument name="option" type="string" defaultValue="option1"/> <argument name="quantity" type="string" defaultValue="2"/> + <argument name="productName" type="string" defaultValue="{{ApiConfigurableProductWithOutCategory.name}}"/> </arguments> - <click selector="{{AdminCustomerWishlistSection.configureButton}}" stepKey="clickConfigureButton"/> + <click selector="{{AdminCustomerWishlistSection.configureButton(productName)}}" stepKey="clickConfigureButton"/> <waitForElementVisible selector="{{AdminCustomerWishlistSection.productAttributeOptionsDropDown(title)}}" stepKey="waitForConfigurableOption"/> <selectOption selector="{{AdminCustomerWishlistSection.productAttributeOptionsDropDown(title)}}" userInput="{{option}}" stepKey="selectConfigurableOption"/> <fillField selector="{{AdminOrderFormConfigureProductSection.quantity}}" userInput="{{quantity}}" stepKey="fillQty"/> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml index c691f34777b57..6e2b678f6d43a 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml @@ -14,7 +14,7 @@ <element name="deleteButton" type="text" selector="//*[@id='wishlistGrid_table']//*[@data-column='action']//*[text()='Delete']"/> <element name="deleteConfirm" type="button" selector=".modal-popup.confirm .action-primary.action-accept"/> <element name="gridTable" type="text" selector="#wishlistGrid_table"/> - <element name="configureButton" type="text" selector="//table[@id='wishlistGrid_table']//td[@data-column='action']//a[@class='configure-item-link']" timeout="30"/> + <element name="configureButton" type="text" selector="//table[@id='wishlistGrid_table']//tbody//td[@data-column='product_name' and contains(text(),'{{var1}}')]/parent::tr//td[@data-column='action']//a[@class='configure-item-link']" timeout="30" parameterized="true"/> <element name="productAttributeOptionsDropDown" type="text" selector="//label[contains(.,'{{var1}}')]/following::div[contains(@class,'control')]//select" parameterized="true"/> <element name="productQty" type="text" selector="//table[@id='wishlistGrid_table']//td[@data-column='qty' and contains(@class, 'col-number')]"/> </section> diff --git a/app/code/Magento/Wishlist/Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml b/app/code/Magento/Wishlist/Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml index fcb21054badde..6c4ddf2bfd006 100644 --- a/app/code/Magento/Wishlist/Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml +++ b/app/code/Magento/Wishlist/Test/Mftf/Test/AdminConfigureCustomerWishListItemTest.xml @@ -16,7 +16,7 @@ <description value="Admin should be able to configure items from customer wishlist"/> <severity value="MAJOR"/> <testCaseId value="MC-40455"/> - <useCaseId value="MC-36575"/> + <useCaseId value="MC-37418"/> <group value="wishlist"/> </annotations> <before> @@ -68,6 +68,7 @@ </createData> <createData entity="Simple_US_Customer" stepKey="createCustomer"/> <magentoCron groups="index" stepKey="reindexBrokenIndices"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> </before> <after> <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> @@ -83,22 +84,21 @@ <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefrontAccount"> <argument name="Customer" value="$createCustomer$"/> </actionGroup> - <amOnPage url="{{StorefrontProductPage.url($createConfigProduct.custom_attributes[url_key]$)}}" stepKey="goToProductPage"/> + <actionGroup ref="StorefrontOpenProductPageActionGroup" stepKey="openProductPage"> + <argument name="productUrl" value="$createConfigProduct.custom_attributes[url_key]$"/> + </actionGroup> <actionGroup ref="StorefrontCustomerAddProductToWishlistActionGroup" stepKey="addToWishlistProduct"> <argument name="productVar" value="$createConfigProduct$"/> </actionGroup> - <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <actionGroup ref="OpenEditCustomerFromAdminActionGroup" stepKey="navigateToCustomerEditPage"> <argument name="customer" value="$createCustomer$"/> </actionGroup> <actionGroup ref="AdminNavigateCustomerWishlistTabActionGroup" stepKey="navigateToWishlistTab"/> - <actionGroup ref="AdminCustomerFindWishlistItemActionGroup" stepKey="findWishlistItem"> - <argument name="productName" value="$createConfigProduct.name$"/> - </actionGroup> <actionGroup ref="AdminCustomerWishlistConfigureItemActionGroup" stepKey="editItem"> <argument name="title" value="$createConfigProductAttribute.attribute[frontend_labels][0][label]$"/> <argument name="option" value="$getConfigAttributeOption1.label$"/> <argument name="quantity" value="2"/> + <argument name="productName" value="$createConfigProduct.name$"/> </actionGroup> <click selector="{{AdminMainActionsSection.save}}" stepKey="saveCustomer"/> <waitForElementVisible selector="{{AdminMessagesSection.success}}" stepKey="waitForSuccessMessage"/> From 6fb183fe3c0e4e505665f3266dbd84b6cd9b55fa Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Mon, 25 Jan 2021 14:50:45 +0200 Subject: [PATCH 06/17] MC-37418: [Safari browser] Popup not closed with a configuration. --- .../Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml index 6e2b678f6d43a..bb060499ed638 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml @@ -16,6 +16,6 @@ <element name="gridTable" type="text" selector="#wishlistGrid_table"/> <element name="configureButton" type="text" selector="//table[@id='wishlistGrid_table']//tbody//td[@data-column='product_name' and contains(text(),'{{var1}}')]/parent::tr//td[@data-column='action']//a[@class='configure-item-link']" timeout="30" parameterized="true"/> <element name="productAttributeOptionsDropDown" type="text" selector="//label[contains(.,'{{var1}}')]/following::div[contains(@class,'control')]//select" parameterized="true"/> - <element name="productQty" type="text" selector="//table[@id='wishlistGrid_table']//td[@data-column='qty' and contains(@class, 'col-number')]"/> + <element name="productQty" type="text" selector="table#wishlistGrid_table td.col-number[data-column=qty]"/> </section> </sections> From a89cc477312bb2cf472a7fc083c48b2a756d6c1a Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Tue, 26 Jan 2021 12:42:58 +0200 Subject: [PATCH 07/17] MC-37418: [Safari browser] Popup not closed with a configuration. --- .../Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml index bb060499ed638..0a44149cb067b 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerWishlistSection.xml @@ -14,7 +14,7 @@ <element name="deleteButton" type="text" selector="//*[@id='wishlistGrid_table']//*[@data-column='action']//*[text()='Delete']"/> <element name="deleteConfirm" type="button" selector=".modal-popup.confirm .action-primary.action-accept"/> <element name="gridTable" type="text" selector="#wishlistGrid_table"/> - <element name="configureButton" type="text" selector="//table[@id='wishlistGrid_table']//tbody//td[@data-column='product_name' and contains(text(),'{{var1}}')]/parent::tr//td[@data-column='action']//a[@class='configure-item-link']" timeout="30" parameterized="true"/> + <element name="configureButton" type="text" selector="//table[@id='wishlistGrid_table']//tbody//td[@data-column='product_name' and contains(text(),'{{productName}}')]/parent::tr//td[@data-column='action']//a[@class='configure-item-link']" timeout="30" parameterized="true"/> <element name="productAttributeOptionsDropDown" type="text" selector="//label[contains(.,'{{var1}}')]/following::div[contains(@class,'control')]//select" parameterized="true"/> <element name="productQty" type="text" selector="table#wishlistGrid_table td.col-number[data-column=qty]"/> </section> From 8c1575be073a4e25e1380099fd5b0fe1975996f1 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Thu, 28 Jan 2021 11:25:33 +0200 Subject: [PATCH 08/17] MC-24725: Cyclic ajax requests to cart section in shopping cart --- app/code/Magento/Checkout/view/frontend/web/js/model/totals.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js b/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js index aba0c31b998d1..2b59be2569b85 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js @@ -22,7 +22,7 @@ define([ quoteItems(newValue.items); }); - if (quoteSubtotal !== subtotalAmount) { + if (quoteSubtotal !== subtotalAmount && !isNaN(subtotalAmount)) { customerData.reload(['cart'], false); } From f081032b8023dbf02f94fdba5a8fca5fa3adb42b Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Tue, 2 Feb 2021 16:00:32 +0200 Subject: [PATCH 09/17] MC-24725: Cyclic ajax requests to cart section in shopping cart --- .../view/frontend/web/js/model/totals.js | 2 +- .../Checkout/frontend/js/model/totals.test.js | 89 +++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/totals.test.js diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js b/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js index 2b59be2569b85..fe525bddc02f3 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js @@ -22,7 +22,7 @@ define([ quoteItems(newValue.items); }); - if (quoteSubtotal !== subtotalAmount && !isNaN(subtotalAmount)) { + if (!isNaN(subtotalAmount) && quoteSubtotal !== subtotalAmount) { customerData.reload(['cart'], false); } diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/totals.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/totals.test.js new file mode 100644 index 0000000000000..771d746dc4279 --- /dev/null +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/totals.test.js @@ -0,0 +1,89 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/* eslint-disable max-nested-callbacks */ +/*jscs:disable jsDoc*/ +define([ + 'squire', 'jquery', 'ko' +], function (Squire, $, ko) { + 'use strict'; + + var injector = new Squire(), + cartData = { + 'subtotalAmount': 10 + }, + cart = ko.observable(cartData), + cartDataTwo = { + 'subtotalAmount': NaN + }, + cartTwo = ko.observable(cartDataTwo), + mocks = { + 'Magento_Checkout/js/model/quote': { + totals: ko.observable({ + 'subtotal': 4 + }) + }, + 'Magento_Customer/js/customer-data': { + get: function () { + return cart; + }, + reload: jasmine.createSpy(), + getInitCustomerData: function () {} + } + }, + mocksTwo = { + 'Magento_Checkout/js/model/quote': { + totals: ko.observable({ + 'subtotal': 10 + }) + }, + 'Magento_Customer/js/customer-data': { + get: function () { + return cartTwo; + }, + reload: jasmine.createSpy(), + getInitCustomerData: function () {} + } + }, + totals; + + afterEach(function () { + try { + injector.clean(); + injector.remove(); + } catch (e) {} + }); + + describe('Test that customer data is reloaded when quote subtotal and cart subtotal are different', function () { + beforeEach(function (done) { + injector.mock(mocks); + injector.require(['Magento_Checkout/js/model/totals'], function (Totals) { + totals = Totals; + done(); + }); + }); + it('Test that customer data is reloaded when quote subtotal and cart subtotal are different', function () { + expect(mocks['Magento_Checkout/js/model/quote'].totals().subtotal).toBe(4); + expect(cart().subtotalAmount).toBe(10); + expect(mocks['Magento_Customer/js/customer-data'].reload).toHaveBeenCalled(); + }); + }); + + describe('Test that customer data is not reloaded when cart subtotal is NaN', function () { + beforeEach(function (done) { + injector.mock(mocksTwo); + injector.require(['Magento_Checkout/js/model/totals'], function (Totals) { + totals = Totals; + done(); + }); + }); + it('Test that customer data is not reloaded when cart subtotal is NaN', function () { + expect(mocksTwo['Magento_Checkout/js/model/quote'].totals().subtotal).toBe(10); + expect(cartTwo().subtotalAmount).toBeNaN(); + expect(mocksTwo['Magento_Customer/js/customer-data'].reload).not.toHaveBeenCalled(); + }); + }); +}); + From 8c6dd037d6f055c0f06b582507677b7847c86680 Mon Sep 17 00:00:00 2001 From: engcom-Echo <engcom-vendorworker-echo@adobe.com> Date: Wed, 3 Feb 2021 11:32:48 +0200 Subject: [PATCH 10/17] MC-40702: Order currency is used instead of bas currency in the shipping label for form --- .../Block/Adminhtml/Order/Packaging.php | 2 +- .../Adminhtml/Order/AddToPackageTest.php | 89 +++++++++++++------ ...h_carrier_data_different_currency_code.php | 50 +++++++++++ ..._data_different_currency_code_rollback.php | 9 ++ 4 files changed, 120 insertions(+), 30 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Shipping/_files/shipping_with_carrier_data_different_currency_code.php create mode 100644 dev/tests/integration/testsuite/Magento/Shipping/_files/shipping_with_carrier_data_different_currency_code_rollback.php diff --git a/app/code/Magento/Shipping/Block/Adminhtml/Order/Packaging.php b/app/code/Magento/Shipping/Block/Adminhtml/Order/Packaging.php index ce4521c9baa51..f66b37a9cd34f 100644 --- a/app/code/Magento/Shipping/Block/Adminhtml/Order/Packaging.php +++ b/app/code/Magento/Shipping/Block/Adminhtml/Order/Packaging.php @@ -380,7 +380,7 @@ public function getContentTypes() public function getCustomValueCurrencyCode() { $orderInfo = $this->getShipment()->getOrder(); - return $orderInfo->getBaseCurrency()->getCurrencyCode(); + return $orderInfo->getOrderCurrency()->getCurrencyCode(); } /** diff --git a/dev/tests/integration/testsuite/Magento/Shipping/Block/Adminhtml/Order/AddToPackageTest.php b/dev/tests/integration/testsuite/Magento/Shipping/Block/Adminhtml/Order/AddToPackageTest.php index fbbc6ef25cc09..692a1a6af9e49 100644 --- a/dev/tests/integration/testsuite/Magento/Shipping/Block/Adminhtml/Order/AddToPackageTest.php +++ b/dev/tests/integration/testsuite/Magento/Shipping/Block/Adminhtml/Order/AddToPackageTest.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Shipping\Block\Adminhtml\Order; use Magento\Backend\Block\Template; @@ -28,12 +30,19 @@ class AddToPackageTest extends TestCase */ private $orderRepository; - /** @var ObjectManagerInterface */ + /** + * @var ObjectManagerInterface + */ private $objectManager; - /** @var Registry */ + /** + * @var Registry + */ private $registry; + /** + * @inheritDoc + */ protected function setUp(): void { $this->objectManager = Bootstrap::getObjectManager(); @@ -42,30 +51,43 @@ protected function setUp(): void } /** - * Loads order entity by provided order increment ID. + * Test that Packaging popup renders * - * @param string $incrementId - * @return OrderInterface + * @magentoDataFixture Magento/Shipping/_files/shipping_with_carrier_data.php */ - private function getOrderByIncrementId(string $incrementId) : OrderInterface + public function testGetCommentsHtml(): void { - /** @var SearchCriteria $searchCriteria */ - $searchCriteria = $this->objectManager->get(SearchCriteriaBuilder::class) - ->addFilter('increment_id', $incrementId) - ->create(); - - $items = $this->orderRepository->getList($searchCriteria) - ->getItems(); + $expectedNeedle = "packaging.setItemQtyCallback(function(itemId){ + var item = $$('[name=\"shipment[items]['+itemId+']\"]')[0], + itemTitle = $('order_item_' + itemId + '_title'); + if (!itemTitle && !item) { + return 0; + } + if (item && !isNaN(item.value)) { + return item.value; + } + });"; + $this->assertStringContainsString($expectedNeedle, $this->getHtml()); + } - return array_pop($items); + /** + * Verify currency code on custom value field + * + * @magentoDataFixture Magento/Shipping/_files/shipping_with_carrier_data_different_currency_code.php + */ + public function testGetCurrencyCodeCustomValue () + { + $expectedCurrencyCode = '<span class="customs-value-currency"> + FR </span>'; + $this->assertStringContainsString($expectedCurrencyCode, $this->getHtml()); } /** - * Test that Packaging popup renders + * Get html for packaging popup * - * @magentoDataFixture Magento/Shipping/_files/shipping_with_carrier_data.php + * @return string */ - public function testGetCommentsHtml() + private function getHtml() { /** @var Template $block */ $block = $this->objectManager->get(Packaging::class); @@ -78,17 +100,26 @@ public function testGetCommentsHtml() $this->registry->register('current_shipment', $shipment); $block->setTemplate('Magento_Shipping::order/packaging/popup.phtml'); - $html = $block->toHtml(); - $expectedNeedle = "packaging.setItemQtyCallback(function(itemId){ - var item = $$('[name=\"shipment[items]['+itemId+']\"]')[0], - itemTitle = $('order_item_' + itemId + '_title'); - if (!itemTitle && !item) { - return 0; - } - if (item && !isNaN(item.value)) { - return item.value; - } - });"; - $this->assertStringContainsString($expectedNeedle, $html); + + return $block->toHtml(); + } + + /** + * Loads order entity by provided order increment ID. + * + * @param string $incrementId + * @return OrderInterface + */ + private function getOrderByIncrementId(string $incrementId) : OrderInterface + { + /** @var SearchCriteria $searchCriteria */ + $searchCriteria = $this->objectManager->get(SearchCriteriaBuilder::class) + ->addFilter('increment_id', $incrementId) + ->create(); + + $items = $this->orderRepository->getList($searchCriteria) + ->getItems(); + + return array_pop($items); } } diff --git a/dev/tests/integration/testsuite/Magento/Shipping/_files/shipping_with_carrier_data_different_currency_code.php b/dev/tests/integration/testsuite/Magento/Shipping/_files/shipping_with_carrier_data_different_currency_code.php new file mode 100644 index 0000000000000..2a7655d6bad4a --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Shipping/_files/shipping_with_carrier_data_different_currency_code.php @@ -0,0 +1,50 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Sales\Api\Data\OrderInterfaceFactory; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\ShipmentFactory; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; +use Magento\Framework\DB\Transaction; + +Resolver::getInstance()->requireDataFixture('Magento/Sales/_files/order_with_customer.php'); + +$objectManager = Bootstrap::getObjectManager(); +/** @var Transaction $transaction */ +$transaction = $objectManager->get(Transaction::class); +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->create(ProductRepositoryInterface::class); +$product = $productRepository->get('simple'); +/** @var Order $order */ +$order = $objectManager->get(OrderInterfaceFactory::class)->create()->loadByIncrementId('100000001'); +$order->setShippingDescription('UPS Next Day Air') + ->setShippingMethod('ups_11') + ->setOrderCurrencyCode('FR') + ->setShippingAmount(0) + ->setCouponCode('1234567890') + ->setDiscountDescription('1234567890'); + +/** @var OrderRepositoryInterface $orderRepository */ +$orderRepository = $objectManager->create(OrderRepositoryInterface::class); +$orderRepository->save($order); + +$shipmentItems = []; +foreach ($order->getItems() as $orderItem) { + $shipmentItems[$orderItem->getId()] = $orderItem->getQtyOrdered(); +} +$tracking = [ + 'carrier_code' => 'ups', + 'title' => 'United Parcel Service', + 'number' => '987654321' +]; + +$shipment = $objectManager->get(ShipmentFactory::class)->create($order, $shipmentItems, [$tracking]); +$shipment->register(); +$transaction->addObject($shipment)->addObject($order)->save(); diff --git a/dev/tests/integration/testsuite/Magento/Shipping/_files/shipping_with_carrier_data_different_currency_code_rollback.php b/dev/tests/integration/testsuite/Magento/Shipping/_files/shipping_with_carrier_data_different_currency_code_rollback.php new file mode 100644 index 0000000000000..bbb90e0326aec --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Shipping/_files/shipping_with_carrier_data_different_currency_code_rollback.php @@ -0,0 +1,9 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\TestFramework\Workaround\Override\Fixture\Resolver; + +Resolver::getInstance()->requireDataFixture('Magento/Sales/_files/order_with_customer_rollback.php'); From 7d639eccd2ae9cf3f4fa15c3b13b24e84e760df0 Mon Sep 17 00:00:00 2001 From: engcom-Echo <engcom-vendorworker-echo@adobe.com> Date: Wed, 3 Feb 2021 14:22:57 +0200 Subject: [PATCH 11/17] MC-40702: Order currency is used instead of bas currency in the shipping label for form --- .../Shipping/Block/Adminhtml/Order/AddToPackageTest.php | 8 +++++--- ...shipping_with_carrier_data_different_currency_code.php | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Shipping/Block/Adminhtml/Order/AddToPackageTest.php b/dev/tests/integration/testsuite/Magento/Shipping/Block/Adminhtml/Order/AddToPackageTest.php index 692a1a6af9e49..ebda955569e52 100644 --- a/dev/tests/integration/testsuite/Magento/Shipping/Block/Adminhtml/Order/AddToPackageTest.php +++ b/dev/tests/integration/testsuite/Magento/Shipping/Block/Adminhtml/Order/AddToPackageTest.php @@ -77,9 +77,11 @@ public function testGetCommentsHtml(): void */ public function testGetCurrencyCodeCustomValue () { - $expectedCurrencyCode = '<span class="customs-value-currency"> - FR </span>'; - $this->assertStringContainsString($expectedCurrencyCode, $this->getHtml()); + $template = '/<span class="customs-value-currency">\s*?(?<currency>[A-Za-z]+)\s*?<\/span>/'; + $matches = []; + preg_match($template, $this->getHtml(), $matches); + $currency = $matches['currency'] ?? null; + $this->assertEquals('FR',$currency ); } /** diff --git a/dev/tests/integration/testsuite/Magento/Shipping/_files/shipping_with_carrier_data_different_currency_code.php b/dev/tests/integration/testsuite/Magento/Shipping/_files/shipping_with_carrier_data_different_currency_code.php index 2a7655d6bad4a..ac54274ba0262 100644 --- a/dev/tests/integration/testsuite/Magento/Shipping/_files/shipping_with_carrier_data_different_currency_code.php +++ b/dev/tests/integration/testsuite/Magento/Shipping/_files/shipping_with_carrier_data_different_currency_code.php @@ -20,7 +20,7 @@ /** @var Transaction $transaction */ $transaction = $objectManager->get(Transaction::class); /** @var ProductRepositoryInterface $productRepository */ -$productRepository = $objectManager->create(ProductRepositoryInterface::class); +$productRepository = $objectManager->get(ProductRepositoryInterface::class); $product = $productRepository->get('simple'); /** @var Order $order */ $order = $objectManager->get(OrderInterfaceFactory::class)->create()->loadByIncrementId('100000001'); @@ -42,7 +42,7 @@ $tracking = [ 'carrier_code' => 'ups', 'title' => 'United Parcel Service', - 'number' => '987654321' + 'number' => '987654321', ]; $shipment = $objectManager->get(ShipmentFactory::class)->create($order, $shipmentItems, [$tracking]); From 1705f1d32924c9c26b02304053d4a33de51bfadc Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Wed, 3 Feb 2021 14:36:22 +0200 Subject: [PATCH 12/17] MC-24725: Cyclic ajax requests to cart section in shopping cart --- .../Magento/Checkout/frontend/js/model/totals.test.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/totals.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/totals.test.js index 771d746dc4279..b411bd457b548 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/totals.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/model/totals.test.js @@ -46,8 +46,7 @@ define([ reload: jasmine.createSpy(), getInitCustomerData: function () {} } - }, - totals; + }; afterEach(function () { try { @@ -59,8 +58,7 @@ define([ describe('Test that customer data is reloaded when quote subtotal and cart subtotal are different', function () { beforeEach(function (done) { injector.mock(mocks); - injector.require(['Magento_Checkout/js/model/totals'], function (Totals) { - totals = Totals; + injector.require(['Magento_Checkout/js/model/totals'], function () { done(); }); }); @@ -74,8 +72,7 @@ define([ describe('Test that customer data is not reloaded when cart subtotal is NaN', function () { beforeEach(function (done) { injector.mock(mocksTwo); - injector.require(['Magento_Checkout/js/model/totals'], function (Totals) { - totals = Totals; + injector.require(['Magento_Checkout/js/model/totals'], function () { done(); }); }); From 55e8d992650ebefa0aed930a1ea7b7dac3760059 Mon Sep 17 00:00:00 2001 From: mastiuhin-olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Thu, 4 Feb 2021 01:05:35 +0200 Subject: [PATCH 13/17] MC-39272: Rest api PUT /V1/products/:sku/links calls does not update indexer by Save --- ...indexAfterDeleteByIdProductLinksPlugin.php | 57 ++++++++ .../ReindexAfterSaveProductLinksPlugin.php | 56 +++++++ .../Magento/Catalog/etc/webapi_rest/di.xml | 4 + .../Magento/Catalog/etc/webapi_soap/di.xml | 4 + .../Api/ProductLinkRepositoryTest.php | 138 +++++++++++++++--- .../_files/empty_grouped_product.php | 28 ++++ .../_files/empty_grouped_product_rollback.php | 23 +++ 7 files changed, 292 insertions(+), 18 deletions(-) create mode 100644 app/code/Magento/Catalog/Plugin/Api/ProductLinkRepositoryInterface/ReindexAfterDeleteByIdProductLinksPlugin.php create mode 100644 app/code/Magento/Catalog/Plugin/Api/ProductLinkRepositoryInterface/ReindexAfterSaveProductLinksPlugin.php create mode 100644 dev/tests/integration/testsuite/Magento/GroupedProduct/_files/empty_grouped_product.php create mode 100644 dev/tests/integration/testsuite/Magento/GroupedProduct/_files/empty_grouped_product_rollback.php diff --git a/app/code/Magento/Catalog/Plugin/Api/ProductLinkRepositoryInterface/ReindexAfterDeleteByIdProductLinksPlugin.php b/app/code/Magento/Catalog/Plugin/Api/ProductLinkRepositoryInterface/ReindexAfterDeleteByIdProductLinksPlugin.php new file mode 100644 index 0000000000000..91e8629ec212a --- /dev/null +++ b/app/code/Magento/Catalog/Plugin/Api/ProductLinkRepositoryInterface/ReindexAfterDeleteByIdProductLinksPlugin.php @@ -0,0 +1,57 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Plugin\Api\ProductLinkRepositoryInterface; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Api\ProductLinkRepositoryInterface; +use Magento\Catalog\Model\Indexer\Product\Full as FullProductIndexer; + +/** + * Product reindexing after delete by id links plugin. + */ +class ReindexAfterDeleteByIdProductLinksPlugin +{ + /** + * @var FullProductIndexer + */ + private $fullProductIndexer; + + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @param FullProductIndexer $fullProductIndexer + * @param ProductRepositoryInterface $productRepository + */ + public function __construct(FullProductIndexer $fullProductIndexer, ProductRepositoryInterface $productRepository) + { + $this->fullProductIndexer = $fullProductIndexer; + $this->productRepository = $productRepository; + } + + /** + * Complex reindex after product links has been deleted. + * + * @param ProductLinkRepositoryInterface $subject + * @param bool $result + * @param string $sku + * @param string $type + * @param string $linkedProductSku + * @return bool + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterDeleteById(ProductLinkRepositoryInterface $subject, bool $result, $sku): bool + { + $product = $this->productRepository->get($sku); + $this->fullProductIndexer->executeRow($product->getId()); + + return $result; + } +} diff --git a/app/code/Magento/Catalog/Plugin/Api/ProductLinkRepositoryInterface/ReindexAfterSaveProductLinksPlugin.php b/app/code/Magento/Catalog/Plugin/Api/ProductLinkRepositoryInterface/ReindexAfterSaveProductLinksPlugin.php new file mode 100644 index 0000000000000..480399035a7a3 --- /dev/null +++ b/app/code/Magento/Catalog/Plugin/Api/ProductLinkRepositoryInterface/ReindexAfterSaveProductLinksPlugin.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Plugin\Api\ProductLinkRepositoryInterface; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Api\ProductLinkRepositoryInterface; +use Magento\Catalog\Api\Data\ProductLinkInterface; +use Magento\Catalog\Model\Indexer\Product\Full as FullProductIndexer; + +/** + * Product reindexing after save links plugin. + */ +class ReindexAfterSaveProductLinksPlugin +{ + /** + * @var FullProductIndexer + */ + private $fullProductIndexer; + + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @param FullProductIndexer $fullProductIndexer + * @param ProductRepositoryInterface $productRepository + */ + public function __construct(FullProductIndexer $fullProductIndexer, ProductRepositoryInterface $productRepository) + { + $this->fullProductIndexer = $fullProductIndexer; + $this->productRepository = $productRepository; + } + + /** + * Complex reindex after product links has been saved. + * + * @param ProductLinkRepositoryInterface $subject + * @param bool $result + * @param ProductLinkInterface $entity + * @return bool + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterSave(ProductLinkRepositoryInterface $subject, bool $result, ProductLinkInterface $entity): bool + { + $product = $this->productRepository->get($entity->getSku()); + $this->fullProductIndexer->executeRow($product->getId()); + + return $result; + } +} diff --git a/app/code/Magento/Catalog/etc/webapi_rest/di.xml b/app/code/Magento/Catalog/etc/webapi_rest/di.xml index 1fd47fde304ec..a33c3a19e1e4f 100644 --- a/app/code/Magento/Catalog/etc/webapi_rest/di.xml +++ b/app/code/Magento/Catalog/etc/webapi_rest/di.xml @@ -40,4 +40,8 @@ <argument name="deserializer" xsi:type="object">Magento\Catalog\Model\Product\Webapi\Rest\RequestTypeBasedDeserializer</argument> </arguments> </type> + <type name="Magento\Catalog\Api\ProductLinkRepositoryInterface"> + <plugin name="reindex_after_save_product_links" type="Magento\Catalog\Plugin\Api\ProductLinkRepositoryInterface\ReindexAfterSaveProductLinksPlugin"/> + <plugin name="reindex_after_delete_by_id_product_links" type="Magento\Catalog\Plugin\Api\ProductLinkRepositoryInterface\ReindexAfterDeleteByIdProductLinksPlugin"/> + </type> </config> diff --git a/app/code/Magento/Catalog/etc/webapi_soap/di.xml b/app/code/Magento/Catalog/etc/webapi_soap/di.xml index a709f23d8c12b..03671ba0bb2e0 100644 --- a/app/code/Magento/Catalog/etc/webapi_soap/di.xml +++ b/app/code/Magento/Catalog/etc/webapi_soap/di.xml @@ -40,4 +40,8 @@ <argument name="deserializer" xsi:type="object">Magento\Framework\Webapi\Rest\Request\Deserializer\Xml</argument> </arguments> </type> + <type name="Magento\Catalog\Api\ProductLinkRepositoryInterface"> + <plugin name="reindex_after_save_product_links" type="Magento\Catalog\Plugin\Api\ProductLinkRepositoryInterface\ReindexAfterSaveProductLinksPlugin"/> + <plugin name="reindex_after_delete_by_id_product_links" type="Magento\Catalog\Plugin\Api\ProductLinkRepositoryInterface\ReindexAfterDeleteByIdProductLinksPlugin"/> + </type> </config> diff --git a/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkRepositoryTest.php index efa7341c36a40..c6394ad9561f7 100644 --- a/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkRepositoryTest.php @@ -4,14 +4,18 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\GroupedProduct\Api; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\Indexer\Model\Config; +use Magento\Catalog\Api\ProductLinkManagementInterface; use Magento\Framework\Indexer\IndexerRegistry; use Magento\Framework\Webapi\Rest\Request; +use Magento\Indexer\Model\Config; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\WebapiAbstract; -class ProductLinkRepositoryTest extends \Magento\TestFramework\TestCase\WebapiAbstract +class ProductLinkRepositoryTest extends WebapiAbstract { const SERVICE_NAME = 'catalogProductLinkRepositoryV1'; const SERVICE_VERSION = 'V1'; @@ -55,7 +59,7 @@ public function testSave(): void 'linked_product_sku' => 'simple-1', 'position' => 3, 'extension_attributes' => [ - 'qty' => (float) 300.0000, + 'qty' => (float)300.0000, ], ]; @@ -72,12 +76,15 @@ public function testSave(): void ]; $this->_webApiCall($serviceInfo, ['entity' => $productData]); - /** @var \Magento\Catalog\Api\ProductLinkManagementInterface $linkManagement */ - $linkManagement = $this->objectManager->get(\Magento\Catalog\Api\ProductLinkManagementInterface::class); + /** @var ProductLinkManagementInterface $linkManagement */ + $linkManagement = $this->objectManager->get(ProductLinkManagementInterface::class); $actual = $linkManagement->getLinkedItemsByType($productSku, $linkType); - array_walk($actual, function (&$item) { - $item = $item->__toArray(); - }); + array_walk( + $actual, + function (&$item) { + $item = $item->__toArray(); + } + ); $this->assertEquals($productData, $actual[2]); } @@ -98,7 +105,7 @@ public function testLinkWithScheduledIndex(): void 'linked_product_sku' => $productSimple, 'position' => 3, 'extension_attributes' => [ - 'qty' => (float) 300.0000, + 'qty' => (float)300.0000, ], ]; $serviceInfo = [ @@ -124,6 +131,101 @@ public function testLinkWithScheduledIndex(): void $this->restoreIndexMode(); } + /** + * Verify empty out of stock grouped product is in stock after child has been added. + * + * @return void + * @magentoApiDataFixture Magento/GroupedProduct/_files/empty_grouped_product.php + * @magentoApiDataFixture Magento/Catalog/_files/product_virtual.php + */ + public function testGroupedProductIsInStockAfterAddChild(): void + { + $productSku = 'grouped-product'; + self::assertFalse($this->isProductInStock($productSku)); + $items = [ + 'sku' => $productSku, + 'link_type' => 'associated', + 'linked_product_type' => 'virtual', + 'linked_product_sku' => 'virtual-product', + 'position' => 3, + 'extension_attributes' => [ + 'qty' => 1, + ], + ]; + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH . $productSku . '/links', + 'httpMethod' => Request::HTTP_METHOD_PUT, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_NAME . 'Save', + ], + ]; + $this->_webApiCall($serviceInfo, ['entity' => $items]); + self::assertTrue($this->isProductInStock($productSku)); + } + + /** + * Verify in stock grouped product is out stock after children have been removed. + * + * @return void + * @magentoApiDataFixture Magento/GroupedProduct/_files/product_grouped_with_simple.php + */ + public function testGroupedProductIsOutOfStockAfterRemoveChild(): void + { + $productSku = 'grouped'; + $childrenSkus = [ + 'simple_11', + 'simple_22', + ]; + self::assertTrue($this->isProductInStock($productSku)); + + foreach ($childrenSkus as $childSku) { + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH . $productSku . '/links/associated/' . $childSku, + 'httpMethod' => Request::HTTP_METHOD_DELETE, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_NAME . 'DeleteById', + ], + ]; + $requestData = ['sku' => $productSku, 'type' => 'associated', 'linkedProductSku' => $childSku]; + $this->_webApiCall($serviceInfo, $requestData); + } + + self::assertFalse($this->isProductInStock($productSku)); + } + + + /** + * Check product stock status. + * + * @param string $productSku + * @return bool + */ + private function isProductInStock(string $productSku): bool + { + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => '/V1/stockStatuses/' . $productSku, + 'httpMethod' => Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => 'catalogInventoryStockRegistryV1', + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => 'catalogInventoryStockRegistryV1getStockStatusBySku', + ], + ]; + $result = $this->_webApiCall($serviceInfo, ['productSku' => $productSku]); + + return (bool)$result['stock_status']; + } + /** * @param string $productSku * @return array @@ -139,11 +241,11 @@ private function buildSearchCriteria(string $productSku): array [ 'field' => 'search_term', 'value' => $productSku, - ] - ] - ] - ] - ] + ], + ], + ], + ], + ], ]; } @@ -156,13 +258,13 @@ private function buildSearchServiceInfo(array $searchCriteria): array return [ 'rest' => [ 'resourcePath' => self::RESOURCE_PATH_SEARCH . '?' . http_build_query($searchCriteria), - 'httpMethod' => Request::HTTP_METHOD_GET + 'httpMethod' => Request::HTTP_METHOD_GET, ], 'soap' => [ 'service' => self::SERVICE_NAME_SEARCH, 'serviceVersion' => self::SERVICE_VERSION, - 'operation' => self::SERVICE_NAME_SEARCH . 'Search' - ] + 'operation' => self::SERVICE_NAME_SEARCH . 'Search', + ], ]; } diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/empty_grouped_product.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/empty_grouped_product.php new file mode 100644 index 0000000000000..d02894866fb33 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/empty_grouped_product.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Attribute\Source\Status; +use Magento\Catalog\Model\Product\Visibility; +use Magento\GroupedProduct\Model\Product\Type\Grouped; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); +$productRepository = $objectManager->get(ProductRepositoryInterface::class); +$product = Bootstrap::getObjectManager()->create(Product::class); +$product->isObjectNew(true); +$product->setTypeId(Grouped::TYPE_CODE) + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setName('Grouped Product') + ->setSku('grouped-product') + ->setPrice(100) + ->setTaxClassId(0) + ->setVisibility(Visibility::VISIBILITY_BOTH) + ->setStatus(Status::STATUS_ENABLED) + ->setStockData(['use_config_manage_stock' => 1, 'qty' => 0, 'is_in_stock' => 1]) + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/empty_grouped_product_rollback.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/empty_grouped_product_rollback.php new file mode 100644 index 0000000000000..522579ae5469c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/empty_grouped_product_rollback.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Registry; +use Magento\TestFramework\Helper\Bootstrap; + +$registry = Bootstrap::getObjectManager()->get(Registry::class); +$productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); +try { + $groupedProduct = $productRepository->get('grouped-product', false, null, true); + $groupedProduct->delete(); +} catch (NoSuchEntityException $e) { + //already deleted +} +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); From 834ecfd3fd0e46fbfb2111f5b2daacff2136429a Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Thu, 4 Feb 2021 14:16:39 +0200 Subject: [PATCH 14/17] MC-37418: [Safari browser] Popup not closed with a configuration. --- .../adminhtml/web/catalog/product/composite/configure.js | 6 +++++- .../view/adminhtml/layout/customer_index_wishlist.xml | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js index 4040ff9d684f4..d460c93714b3d 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js @@ -47,10 +47,14 @@ define([ * Initialize object */ initialize: function () { - var self = this; + var self = this, + popupDialog = jQuery('#product_composite_configure'); this._initWindowElements(); jQuery.async('#product_composite_configure', function (el) { + if (el !== popupDialog[0]) { + el = popupDialog[0]; + } self.dialog = jQuery(el).modal({ title: jQuery.mage.__('Configure Product'), type: 'slide', diff --git a/app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_wishlist.xml b/app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_wishlist.xml index cc5ef6b3ab554..0ee4233029105 100644 --- a/app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_wishlist.xml +++ b/app/code/Magento/Wishlist/view/adminhtml/layout/customer_index_wishlist.xml @@ -112,5 +112,6 @@ </arguments> </block> </block> + <block class="Magento\Catalog\Block\Adminhtml\Product\Composite\Configure" template="Magento_Catalog::catalog/product/composite/configure.phtml" name="configure.popup"/> </container> </layout> From bd5a4fcb30665f57db1b92490f509404d40e6d6c Mon Sep 17 00:00:00 2001 From: SmVladyslav <vlatame.tsg@gmail.com> Date: Mon, 8 Feb 2021 10:58:36 +0200 Subject: [PATCH 15/17] MC-39784: Not able to save product after creating a future staging update with end date from the Downloadable Product page --- .../Downloadable/Model/Link/DeleteHandler.php | 6 ++++- .../Downloadable/Model/Link/ReadHandler.php | 9 ++++---- ...nkOnDownloadableProductPageActionGroup.xml | 22 +++++++++++++++++++ ...nkOnDownloadableProductPageActionGroup.xml | 22 +++++++++++++++++++ .../StorefrontDownloadableProductSection.xml | 1 + 5 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AssertStorefrontLinkOnDownloadableProductPageActionGroup.xml create mode 100644 app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AssertStorefrontNoLinkOnDownloadableProductPageActionGroup.xml diff --git a/app/code/Magento/Downloadable/Model/Link/DeleteHandler.php b/app/code/Magento/Downloadable/Model/Link/DeleteHandler.php index 399550e5f33c0..c2a3b20ff9e36 100644 --- a/app/code/Magento/Downloadable/Model/Link/DeleteHandler.php +++ b/app/code/Magento/Downloadable/Model/Link/DeleteHandler.php @@ -9,7 +9,7 @@ use Magento\Framework\EntityManager\Operation\ExtensionInterface; /** - * Class DeleteHandler + * Delete Handler for Downloadable Product Links. */ class DeleteHandler implements ExtensionInterface { @@ -27,6 +27,8 @@ public function __construct(LinkRepository $linkRepository) } /** + * Delete Downloadable Links for the provided Product. + * * @param object $entity * @param array $arguments * @return \Magento\Catalog\Api\Data\ProductInterface|object @@ -41,6 +43,8 @@ public function execute($entity, $arguments = []) foreach ($this->linkRepository->getList($entity->getSku()) as $link) { $this->linkRepository->delete($link->getId()); } + $entity->setDownloadableLinks(null); + return $entity; } } diff --git a/app/code/Magento/Downloadable/Model/Link/ReadHandler.php b/app/code/Magento/Downloadable/Model/Link/ReadHandler.php index a11b38ee3afd8..d3a2349739c26 100644 --- a/app/code/Magento/Downloadable/Model/Link/ReadHandler.php +++ b/app/code/Magento/Downloadable/Model/Link/ReadHandler.php @@ -9,7 +9,7 @@ use Magento\Framework\EntityManager\Operation\ExtensionInterface; /** - * Class ReadHandler + * Read Handler for Downloadable Product Links. */ class ReadHandler implements ExtensionInterface { @@ -27,6 +27,8 @@ public function __construct(LinkRepository $linkRepository) } /** + * Read Downloadable Links for the provided Product. + * * @param object $entity * @param array $arguments * @return \Magento\Catalog\Api\Data\ProductInterface|object @@ -40,10 +42,9 @@ public function execute($entity, $arguments = []) } $entityExtension = $entity->getExtensionAttributes(); $links = $this->linkRepository->getLinksByProduct($entity); - if ($links) { - $entityExtension->setDownloadableProductLinks($links); - } + $entityExtension->setDownloadableProductLinks($links); $entity->setExtensionAttributes($entityExtension); + return $entity; } } diff --git a/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AssertStorefrontLinkOnDownloadableProductPageActionGroup.xml b/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AssertStorefrontLinkOnDownloadableProductPageActionGroup.xml new file mode 100644 index 0000000000000..978fff04938f0 --- /dev/null +++ b/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AssertStorefrontLinkOnDownloadableProductPageActionGroup.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AssertStorefrontLinkOnDownloadableProductPageActionGroup"> + <annotations> + <description>Validates that the provided Link Title is present on Downloadable Product details page.</description> + </annotations> + <arguments> + <argument name="linkTitle" type="string" defaultValue="{{downloadableLink.title}}"/> + </arguments> + + <waitForElementVisible selector="{{StorefrontDownloadableProductSection.downloadableLinksListSection}}" stepKey="waitForDownloadableLinksList"/> + <see selector="{{StorefrontDownloadableProductSection.downloadableLinksListSection}}" userInput="{{linkTitle}}" stepKey="seeDownloadableLink"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AssertStorefrontNoLinkOnDownloadableProductPageActionGroup.xml b/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AssertStorefrontNoLinkOnDownloadableProductPageActionGroup.xml new file mode 100644 index 0000000000000..8b71839669876 --- /dev/null +++ b/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AssertStorefrontNoLinkOnDownloadableProductPageActionGroup.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AssertStorefrontNoLinkOnDownloadableProductPageActionGroup"> + <annotations> + <description>Validates that the provided Link Title is NOT present on Downloadable Product details page.</description> + </annotations> + <arguments> + <argument name="linkTitle" type="string" defaultValue="{{downloadableLink.title}}"/> + </arguments> + + <waitForElementVisible selector="{{StorefrontDownloadableProductSection.downloadableLinksListSection}}" stepKey="waitForDownloadableLinksList"/> + <dontSee selector="{{StorefrontDownloadableProductSection.downloadableLinksListSection}}" userInput="{{linkTitle}}" stepKey="dontSeeDownloadableLink"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Section/StorefrontDownloadableProductSection.xml b/app/code/Magento/Downloadable/Test/Mftf/Section/StorefrontDownloadableProductSection.xml index dc2a58be138e7..e3302c7337e09 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Section/StorefrontDownloadableProductSection.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Section/StorefrontDownloadableProductSection.xml @@ -16,5 +16,6 @@ <element name="downloadableSampleLabel" type="text" selector="//a[contains(.,normalize-space('{{title}}'))]" parameterized="true" timeout="30"/> <element name="downloadableLinkSelectAllCheckbox" type="checkbox" selector="#links_all" /> <element name="downloadableLinkSelectAllLabel" type="text" selector="label[for='links_all']" /> + <element name="downloadableLinksListSection" type="text" selector="#downloadable-links-list" timeout="30"/> </section> </sections> From df329deab69ff93ecdac7e81f5075af9fc5999bf Mon Sep 17 00:00:00 2001 From: SmVladyslav <vlatame.tsg@gmail.com> Date: Tue, 9 Feb 2021 14:28:57 +0200 Subject: [PATCH 16/17] MC-40271: Can't Proceed to Checkout from Shopping Cart page on Staging preview with Bundle product --- .../view/frontend/templates/onepage/link.phtml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/link.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/link.phtml index b667764ac7bba..c2f99c03c8f4c 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/onepage/link.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/link.phtml @@ -4,21 +4,27 @@ * See COPYING.txt for license details. */ -/** @var $block \Magento\Checkout\Block\Onepage\Link */ +use Magento\Checkout\Block\Onepage\Link; +use Magento\Framework\Escaper; + +/** + * @var Link $block + * @var Escaper $escaper + */ ?> -<?php if ($block->isPossibleOnepageCheckout()) :?> +<?php if ($block->isPossibleOnepageCheckout()): ?> <button type="button" data-role="proceed-to-checkout" - title="<?= $block->escapeHtmlAttr(__('Proceed to Checkout')) ?>" + title="<?= $escaper->escapeHtmlAttr(__('Proceed to Checkout')) ?>" data-mage-init='{ "Magento_Checkout/js/proceed-to-checkout":{ - "checkoutUrl":"<?= $block->escapeJs($block->escapeUrl($block->getCheckoutUrl())) ?>" + "checkoutUrl":"<?= $escaper->escapeJs($block->getCheckoutUrl()) ?>" } }' class="action primary checkout<?= ($block->isDisabled()) ? ' disabled' : '' ?>" - <?php if ($block->isDisabled()) :?> + <?php if ($block->isDisabled()): ?> disabled="disabled" <?php endif; ?>> - <span><?= $block->escapeHtml(__('Proceed to Checkout')) ?></span> + <span><?= $escaper->escapeHtml(__('Proceed to Checkout')) ?></span> </button> <?php endif?> From 43d67e91c4f23f800a6a90b64eccd48740b52683 Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Tue, 9 Feb 2021 16:18:32 +0200 Subject: [PATCH 17/17] MC-38226: Unexpected behavior on the PayPal express review page during loading --- .../frontend/templates/express/review.phtml | 83 +++++++++---------- .../view/frontend/web/js/order-review.js | 5 +- 2 files changed, 42 insertions(+), 46 deletions(-) diff --git a/app/code/Magento/Paypal/view/frontend/templates/express/review.phtml b/app/code/Magento/Paypal/view/frontend/templates/express/review.phtml index 69c7c8179850a..afd1e91c6e588 100644 --- a/app/code/Magento/Paypal/view/frontend/templates/express/review.phtml +++ b/app/code/Magento/Paypal/view/frontend/templates/express/review.phtml @@ -4,9 +4,14 @@ * See COPYING.txt for license details. */ +use Magento\Framework\Escaper; +use Magento\Framework\View\Helper\SecureHtmlRenderer; +use Magento\Paypal\Block\Express\Review; + /** - * @var \Magento\Paypal\Block\Express\Review $block - * @var \Magento\Framework\View\Helper\SecureHtmlRenderer $secureRenderer + * @var Review $block + * @var Escaper $escaper + * @var SecureHtmlRenderer $secureRenderer */ ?> <div class="paypal-review view"> @@ -15,11 +20,11 @@ <?php if ($block->getShippingAddress()): ?> <div class="box box-order-shipping-method"> <strong class="box-title"> - <span><?= $block->escapeHtml(__('Shipping Method')) ?></span> + <span><?= $escaper->escapeHtml(__('Shipping Method')) ?></span> </strong> <div class="box-content"> <form method="post" id="shipping-method-form" - action="<?= $block->escapeUrl($block->getShippingMethodSubmitUrl()) ?>" + action="<?= $escaper->escapeUrl($block->getShippingMethodSubmitUrl()) ?>" class="form"> <?php if ($block->canEditShippingMethod()): ?> <?php if ($groups = $block->getShippingRateGroups()): ?> @@ -28,11 +33,14 @@ <select name="shipping_method" id="shipping-method" class="select"> <?php if (!$currentRate): ?> <option value=""> - <?= $block->escapeHtml(__('Please select a shipping method...')); ?> + <?= $escaper->escapeHtml( + __('Please select a shipping method...') + ); ?> </option> <?php endif; ?> <?php foreach ($groups as $code => $rates): ?> - <optgroup label="<?= $block->escapeHtml($block->getCarrierName($code)); + <optgroup label="<?= + $escaper->escapeHtml($block->getCarrierName($code)); ?>"> <?php foreach ($rates as $rate): ?> <option value="<?= @@ -51,19 +59,10 @@ <?php endforeach; ?> </select> </div> - <div class="actions-toolbar"> - <div class="primary"> - <button id="update-shipping-method-submit" type="submit" - class="action update primary"> - <span> - <?= $block->escapeHtml(__('Update Shipping Method')) ?> - </span> - </button> - </div> - </div> + <div class="actions-toolbar"></div> <?php else: ?> <p> - <?= $block->escapeHtml(__( + <?= $escaper->escapeHtml(__( 'Sorry, no quotes are available for this order right now.' )); ?> </p> @@ -80,40 +79,40 @@ </div> <div class="box box-order-shipping-address"> <strong class="box-title"> - <span><?= $block->escapeHtml(__('Shipping Address')) ?></span> + <span><?= $escaper->escapeHtml(__('Shipping Address')) ?></span> </strong> <div class="box-content"> <address> - <?= $block->escapeHtml( + <?= $escaper->escapeHtml( $block->renderAddress($block->getShippingAddress()), ['br'] - );?> + ); ?> </address> </div> <?php if ($block->getCanEditShippingAddress()): ?> <div class="box-actions"> - <a href="<?= $block->escapeUrl($block->getEditUrl()) ?>" class="action edit"> - <span><?= $block->escapeHtml(__('Edit')) ?></span> + <a href="<?= $escaper->escapeUrl($block->getEditUrl()) ?>" class="action edit"> + <span><?= $escaper->escapeHtml(__('Edit')) ?></span> </a> </div> <?php endif; ?> </div> <?php endif; ?> <div class="box box-order-billing-address"> - <strong class="box-title"><span><?= $block->escapeHtml(__('Payment Method')) ?></span></strong> + <strong class="box-title"><span><?= $escaper->escapeHtml(__('Payment Method')) ?></span></strong> <div class="box-content"> - <?= $block->escapeHtml($block->getPaymentMethodTitle()) ?><br> - <?= $block->escapeHtml($block->getEmail()) ?> <br> + <?= $escaper->escapeHtml($block->getPaymentMethodTitle()) ?><br> + <?= $escaper->escapeHtml($block->getEmail()) ?> <br> <img src="https://www.paypalobjects.com/webstatic/en_US/i/buttons/pp-acceptance-medium.png" alt="<?= $block->escapeHtml(__('Buy now with PayPal')) ?>"/> </div> - <?php if ($block->getEditUrl()): ?> - <div class="box-actions"> - <a href="<?= $block->escapeUrl($block->getEditUrl()) ?>" class="action edit"> - <span><?= $block->escapeHtml(__('Edit Payment Information')) ?></span> - </a> - </div> - <?php endif ?> + <?php if ($block->getEditUrl()): ?> + <div class="box-actions"> + <a href="<?= $escaper->escapeUrl($block->getEditUrl()) ?>" class="action edit"> + <span><?= $escaper->escapeHtml(__('Edit Payment Information')) ?></span> + </a> + </div> + <?php endif ?> </div> </div> </div> @@ -124,29 +123,29 @@ <div class="paypal-review-items"> <div class="paypal-review-title"> - <strong><?= $block->escapeHtml(__('Items in Your Shopping Cart')) ?></strong> - <a href="<?= $block->escapeUrl($block->getUrl('checkout/cart')) ?>" class="action edit"> - <span><?= $block->escapeHtml(__('Edit Shopping Cart')) ?></span> + <strong><?= $escaper->escapeHtml(__('Items in Your Shopping Cart')) ?></strong> + <a href="<?= $escaper->escapeUrl($block->getUrl('checkout/cart')) ?>" class="action edit"> + <span><?= $escaper->escapeHtml(__('Edit Shopping Cart')) ?></span> </a> </div> <?= $block->getChildHtml('details') ?> - <form method="post" id="order-review-form" action="<?= $block->escapeUrl($block->getPlaceOrderUrl()) ?>" + <form method="post" id="order-review-form" action="<?= $escaper->escapeUrl($block->getPlaceOrderUrl()) ?>" class="form order-review-form"> <?= $block->getChildHtml('agreements') ?> <div class="actions-toolbar" id="review-buttons-container"> <div class="primary"> <button type="button" id="review-button" class="action checkout primary" - value="<?= $block->escapeHtml(__('Place Order')) ?>"> - <span><?= $block->escapeHtml(__('Place Order')) ?></span> + value="<?= $escaper->escapeHtml(__('Place Order')) ?>"> + <span><?= $escaper->escapeHtml(__('Place Order')) ?></span> </button> </div> <span class="please-wait load indicator" id="review-please-wait" - data-text="<?= $block->escapeHtml(__('Submitting order information...')) ?>"> - <span><?= $block->escapeHtml(__('Submitting order information...')) ?></span> + data-text="<?= $escaper->escapeHtml(__('Submitting order information...')) ?>"> + <span><?= $escaper->escapeHtml(__('Submitting order information...')) ?></span> </span> - <?= /* @noEscape */ $secureRenderer->renderStyleAsTag("display: none;", 'span#review-please-wait')?> + <?= /* @noEscape */ $secureRenderer->renderStyleAsTag("display: none;", 'span#review-please-wait') ?> </div> </form> </div> @@ -158,7 +157,7 @@ "orderReview": { "shippingSubmitFormSelector": "#shipping-method-form", "shippingSelector": "#shipping-method", - "shippingMethodUpdateUrl": "<?= $block->escapeUrl($block->getUpdateShippingMethodsUrl()) ?>", + "shippingMethodUpdateUrl": "<?= $escaper->escapeJs($block->getUpdateShippingMethodsUrl()) ?>", "isAjax": <?= /* @noEscape */ $block->getUseAjax() ? 'true' : 'false' ?>, "canEditShippingMethod": <?= /* @noEscape */ $block->canEditShippingMethod() ? 'true' : 'false' ?> } diff --git a/app/code/Magento/Paypal/view/frontend/web/js/order-review.js b/app/code/Magento/Paypal/view/frontend/web/js/order-review.js index e3db1010693ee..6a3914ed19d59 100644 --- a/app/code/Magento/Paypal/view/frontend/web/js/order-review.js +++ b/app/code/Magento/Paypal/view/frontend/web/js/order-review.js @@ -25,7 +25,6 @@ define([ shippingMethodContainer: '#shipping-method-container', agreementSelector: 'div.checkout-agreements input', isAjax: false, - updateShippingMethodSubmitSelector: '#update-shipping-method-submit', shippingMethodUpdateUrl: null, updateOrderSubmitUrl: null, canEditShippingMethod: false @@ -55,14 +54,12 @@ define([ this.options.updateOrderSubmitUrl, this.options.updateContainerSelector ) - ).find(this.options.updateOrderSelector).on('click', $.proxy(this._updateOrderHandler, this)).end() - .find(this.options.updateShippingMethodSubmitSelector).hide().end(); + ).find(this.options.updateOrderSelector).on('click', $.proxy(this._updateOrderHandler, this)).end(); this._shippingTobilling(); if ($(this.options.shippingSubmitFormSelector).length && this.options.canEditShippingMethod) { this.isShippingSubmitForm = true; $(this.options.shippingSubmitFormSelector) - .find(this.options.updateShippingMethodSubmitSelector).hide().end() .on('change', this.options.shippingSelector, $.proxy(