From 594fc93cdc92ca5648564718ce7a079d6afabdd8 Mon Sep 17 00:00:00 2001 From: Benoit Xylo Date: Thu, 31 Oct 2019 12:55:55 +0100 Subject: [PATCH 001/132] Set e-mail address for the PayPal guest quote's customer model This change sets an e-mail address on the customer model assigned to the guest quote prepared for further processing by PayPal module. It circumvents inability to place a guest order with PayPal Express when Automatic Asignment to Customer Group is enabled. Fixes #25399 --- app/code/Magento/Paypal/Model/Express/Checkout.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Paypal/Model/Express/Checkout.php b/app/code/Magento/Paypal/Model/Express/Checkout.php index 389f20c757ae1..2b829086ac62e 100644 --- a/app/code/Magento/Paypal/Model/Express/Checkout.php +++ b/app/code/Magento/Paypal/Model/Express/Checkout.php @@ -1159,6 +1159,9 @@ protected function prepareGuestQuote() ->setCustomerEmail($quote->getBillingAddress()->getEmail()) ->setCustomerIsGuest(true) ->setCustomerGroupId(\Magento\Customer\Model\Group::NOT_LOGGED_IN_ID); + if ($quote->getCustomer()->getEmail() === null) { + $quote->getCustomer()->setEmail($quote->getBillingAddress()->getEmail()); + } return $this; } } From a99d980cebbfa1495de25aa91b9c70d86b2da7a6 Mon Sep 17 00:00:00 2001 From: joe Date: Thu, 7 Nov 2019 11:44:24 +0000 Subject: [PATCH 002/132] Fix for issue 25147 - Totals Information Management - setting quote shipping method when address method is not null --- .../Checkout/Model/TotalsInformationManagement.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/Model/TotalsInformationManagement.php b/app/code/Magento/Checkout/Model/TotalsInformationManagement.php index efb638d299864..a27a11ca22b78 100644 --- a/app/code/Magento/Checkout/Model/TotalsInformationManagement.php +++ b/app/code/Magento/Checkout/Model/TotalsInformationManagement.php @@ -52,9 +52,11 @@ public function calculate( $quote->setBillingAddress($addressInformation->getAddress()); } else { $quote->setShippingAddress($addressInformation->getAddress()); - $quote->getShippingAddress()->setCollectShippingRates(true)->setShippingMethod( - $addressInformation->getShippingCarrierCode() . '_' . $addressInformation->getShippingMethodCode() - ); + if ($addressInformation->getShippingCarrierCode() && $addressInformation->getShippingMethodCode()) { + $quote->getShippingAddress()->setCollectShippingRates(true)->setShippingMethod( + $addressInformation->getShippingCarrierCode().'_'.$addressInformation->getShippingMethodCode() + ); + } } $quote->collectTotals(); From 042df4153f29e6dfb18604ac0ca72c4a0671ef58 Mon Sep 17 00:00:00 2001 From: vadim Date: Tue, 21 Jan 2020 14:37:22 +0200 Subject: [PATCH 003/132] #7720 --- .../Catalog/Model/ProductRepository.php | 4 +++- .../Catalog/Model/ProductRepositoryTest.php | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index d656a0a9ac5b4..ce6c2657836bb 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -543,7 +543,9 @@ public function save(ProductInterface $product, $saveOptions = false) if (!$ignoreLinksFlag && $ignoreLinksFlag !== null) { $productLinks = $product->getProductLinks(); } - $productDataArray['store_id'] = (int)$this->storeManager->getStore()->getId(); + if (!isset($productDataArray['store_id'])) { + $productDataArray['store_id'] = (int) $this->storeManager->getStore()->getId(); + } $product = $this->initializeProductData($productDataArray, empty($existingProduct)); $this->processLinks($product, $productLinks); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php index fb07d08faca58..a1b869dcf785d 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php @@ -233,4 +233,24 @@ public function testCustomLayout(): void } $this->assertTrue($caughtException); } + + /** + * Tests product repository update should use provided store code. + * + * @magentoDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testProductUpdate(): void + { + $sku = 'simple'; + $nameUpdated = 'updated'; + + $product = $this->productRepository->get($sku, false, 0); + $product->setName($nameUpdated); + $this->productRepository->save($product); + $product = $this->productRepository->get($sku, false, 0); + self::assertEquals( + $nameUpdated, + $product->getName() + ); + } } From a039ff41d4938d06e507778aaac4983e12ae8421 Mon Sep 17 00:00:00 2001 From: vadim Date: Tue, 21 Jan 2020 14:37:22 +0200 Subject: [PATCH 004/132] 7720 --- .../Catalog/Model/ProductRepository.php | 8 ++- .../Test/Unit/Model/ProductRepositoryTest.php | 65 ++++++++++++++++++- .../Catalog/Model/ProductRepositoryTest.php | 20 ++++++ 3 files changed, 89 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index d656a0a9ac5b4..3979a6566966a 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -30,7 +30,8 @@ use Magento\Framework\Exception\ValidatorException; /** - * Product Repository. + * @inheritdoc + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyFields) */ @@ -543,7 +544,9 @@ public function save(ProductInterface $product, $saveOptions = false) if (!$ignoreLinksFlag && $ignoreLinksFlag !== null) { $productLinks = $product->getProductLinks(); } - $productDataArray['store_id'] = (int)$this->storeManager->getStore()->getId(); + if (!isset($productDataArray['store_id'])) { + $productDataArray['store_id'] = (int) $this->storeManager->getStore()->getId(); + } $product = $this->initializeProductData($productDataArray, empty($existingProduct)); $this->processLinks($product, $productLinks); @@ -735,6 +738,7 @@ private function getCollectionProcessor() { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + // phpstan:ignore "Class Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor not found." \Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor::class ); } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php index 0dc294e139d3e..02920a9797188 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php @@ -46,8 +46,8 @@ use PHPUnit_Framework_MockObject_MockObject as MockObject; /** - * Class ProductRepositoryTest - * @package Magento\Catalog\Test\Unit\Model + * Test for \Magento\Catalog\Model\ProductRepository. + * * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) @@ -291,6 +291,7 @@ protected function setUp() ->disableOriginalConstructor() ->setMethods([]) ->getMockForAbstractClass(); + $storeMock->method('getId')->willReturn('1'); $storeMock->expects($this->any())->method('getWebsiteId')->willReturn('1'); $storeMock->expects($this->any())->method('getCode')->willReturn(Store::ADMIN_CODE); $this->storeManager->expects($this->any())->method('getStore')->willReturn($storeMock); @@ -345,6 +346,66 @@ function ($value) { $this->objectManager->setBackwardCompatibleProperty($this->model, 'mediaProcessor', $mediaProcessor); } + /** + * Test save product with store id 0 + * + * @param array $productData + * @return void + * @dataProvider getProductData + */ + public function testSaveForAllStoreViewScope(array $productData): void + { + $this->productFactory->method('create')->willReturn($this->product); + $this->product->method('getSku')->willReturn($productData['sku']); + $this->extensibleDataObjectConverter + ->expects($this->once()) + ->method('toNestedArray') + ->willReturn($productData); + $this->resourceModel->method('getIdBySku')->willReturn(100); + $this->resourceModel->expects($this->once())->method('validate')->willReturn(true); + $this->product->expects($this->at(14))->method('setData')->with('store_id', $productData['store_id']); + + $this->model->save($this->product); + } + + /** + * Product data provider + * + * @return array + */ + public function getProductData(): array + { + return [ + [ + [ + 'sku' => 'sku', + 'name' => 'product', + 'store_id' => 0, + ], + ], + ]; + } + + /** + * Test save product without store + * + * @return void + */ + public function testSaveWithoutStoreId(): void + { + $this->productFactory->method('create')->willReturn($this->product); + $this->product->method('getSku')->willReturn($this->productData['sku']); + $this->extensibleDataObjectConverter + ->expects($this->once()) + ->method('toNestedArray') + ->willReturn($this->productData); + $this->resourceModel->method('getIdBySku')->willReturn(100); + $this->resourceModel->expects($this->once())->method('validate')->willReturn(true); + $this->product->expects($this->at(15))->method('setData')->with('store_id', 1); + + $this->model->save($this->product); + } + /** * @expectedException \Magento\Framework\Exception\NoSuchEntityException * @expectedExceptionMessage The product that was requested doesn't exist. Verify the product and try again. diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php index fb07d08faca58..e85837eb59ae4 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php @@ -233,4 +233,24 @@ public function testCustomLayout(): void } $this->assertTrue($caughtException); } + + /** + * Tests product repository update should use provided store code. + * + * @magentoDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testProductUpdate(): void + { + $sku = 'simple'; + $nameUpdated = 'updated'; + + $product = $this->productRepository->get($sku, false, 0); + $product->setName($nameUpdated); + $this->productRepository->save($product); + $product = $this->productRepository->get($sku, false, 0); + $this->assertEquals( + $nameUpdated, + $product->getName() + ); + } } From 13af48ab3e53f9ec4d2d29dec28d39cffd7c9e3b Mon Sep 17 00:00:00 2001 From: vadim Date: Mon, 27 Jan 2020 11:34:41 +0200 Subject: [PATCH 005/132] #7720 fix cs --- .../Test/Unit/Model/ProductRepositoryTest.php | 30 +++++--- .../Catalog/Model/ProductRepositoryTest.php | 68 +++++++++++++++---- 2 files changed, 74 insertions(+), 24 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php index 02920a9797188..792557f14a5bc 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php @@ -54,6 +54,16 @@ */ class ProductRepositoryTest extends TestCase { + private const STUB_STORE_ID = 1; + + private const STUB_STORE_ID_GLOBAL = 0; + + private const STUB_PRODUCT_ID = 100; + + private const STUB_PRODUCT_NAME = 'name'; + + private const STUB_PRODUCT_SKU = 'sku'; + /** * @var Product|MockObject */ @@ -291,7 +301,7 @@ protected function setUp() ->disableOriginalConstructor() ->setMethods([]) ->getMockForAbstractClass(); - $storeMock->method('getId')->willReturn('1'); + $storeMock->method('getId')->willReturn(self::STUB_STORE_ID); $storeMock->expects($this->any())->method('getWebsiteId')->willReturn('1'); $storeMock->expects($this->any())->method('getCode')->willReturn(Store::ADMIN_CODE); $this->storeManager->expects($this->any())->method('getStore')->willReturn($storeMock); @@ -347,7 +357,7 @@ function ($value) { } /** - * Test save product with store id 0 + * Test save product with global store id * * @param array $productData * @return void @@ -361,9 +371,10 @@ public function testSaveForAllStoreViewScope(array $productData): void ->expects($this->once()) ->method('toNestedArray') ->willReturn($productData); - $this->resourceModel->method('getIdBySku')->willReturn(100); + $this->resourceModel->method('getIdBySku')->willReturn(self::STUB_PRODUCT_ID); $this->resourceModel->expects($this->once())->method('validate')->willReturn(true); - $this->product->expects($this->at(14))->method('setData')->with('store_id', $productData['store_id']); + $this->product->expects($this->at(14))->method('setData') + ->with('store_id', $productData['store_id']); $this->model->save($this->product); } @@ -378,9 +389,9 @@ public function getProductData(): array return [ [ [ - 'sku' => 'sku', - 'name' => 'product', - 'store_id' => 0, + 'sku' => self::STUB_PRODUCT_SKU, + 'name' => self::STUB_PRODUCT_NAME, + 'store_id' => self::STUB_STORE_ID_GLOBAL, ], ], ]; @@ -399,9 +410,10 @@ public function testSaveWithoutStoreId(): void ->expects($this->once()) ->method('toNestedArray') ->willReturn($this->productData); - $this->resourceModel->method('getIdBySku')->willReturn(100); + $this->resourceModel->method('getIdBySku')->willReturn(self::STUB_PRODUCT_ID); $this->resourceModel->expects($this->once())->method('validate')->willReturn(true); - $this->product->expects($this->at(15))->method('setData')->with('store_id', 1); + $this->product->expects($this->at(15))->method('setData') + ->with('store_id', self::STUB_STORE_ID); $this->model->save($this->product); } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php index e85837eb59ae4..a63d4c5f02d7e 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductRepositoryTest.php @@ -7,15 +7,12 @@ namespace Magento\Catalog\Model; -use Magento\Backend\Model\Auth; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\ResourceModel\Product as ProductResource; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\Exception\LocalizedException; use Magento\TestFramework\Catalog\Model\ProductLayoutUpdateManager; use Magento\TestFramework\Helper\Bootstrap; -use Magento\TestFramework\Bootstrap as TestBootstrap; -use Magento\Framework\Acl\Builder; /** * Provide tests for ProductRepository model. @@ -26,6 +23,16 @@ */ class ProductRepositoryTest extends \PHPUnit\Framework\TestCase { + private const STUB_STORE_ID = 1; + + private const STUB_STORE_ID_GLOBAL = 0; + + private const STUB_PRODUCT_NAME = 'Simple Product'; + + private const STUB_UPDATED_PRODUCT_NAME = 'updated'; + + private const STUB_PRODUCT_SKU = 'simple'; + /** * Test subject. * @@ -235,22 +242,53 @@ public function testCustomLayout(): void } /** - * Tests product repository update should use provided store code. + * Tests product repository update * + * @dataProvider productUpdateDataProvider * @magentoDataFixture Magento/Catalog/_files/product_simple.php + * @param int $storeId + * @param int $checkStoreId + * @param string $expectedNameStore + * @param string $expectedNameCheckedStore */ - public function testProductUpdate(): void - { - $sku = 'simple'; - $nameUpdated = 'updated'; + public function testProductUpdate( + int $storeId, + int $checkStoreId, + string $expectedNameStore, + string $expectedNameCheckedStore + ): void { + $sku = self::STUB_PRODUCT_SKU; - $product = $this->productRepository->get($sku, false, 0); - $product->setName($nameUpdated); + $product = $this->productRepository->get($sku, false, $storeId); + $product->setName(self::STUB_UPDATED_PRODUCT_NAME); $this->productRepository->save($product); - $product = $this->productRepository->get($sku, false, 0); - $this->assertEquals( - $nameUpdated, - $product->getName() - ); + $productNameStoreId = $this->productRepository->get($sku, false, $storeId)->getName(); + $productNameCheckedStoreId = $this->productRepository->get($sku, false, $checkStoreId)->getName(); + + $this->assertEquals($expectedNameStore, $productNameStoreId); + $this->assertEquals($expectedNameCheckedStore, $productNameCheckedStoreId); + } + + /** + * Product update data provider + * + * @return array + */ + public function productUpdateDataProvider(): array + { + return [ + 'Updating for global store' => [ + self::STUB_STORE_ID_GLOBAL, + self::STUB_STORE_ID, + self::STUB_UPDATED_PRODUCT_NAME, + self::STUB_UPDATED_PRODUCT_NAME, + ], + 'Updating for store' => [ + self::STUB_STORE_ID, + self::STUB_STORE_ID_GLOBAL, + self::STUB_UPDATED_PRODUCT_NAME, + self::STUB_PRODUCT_NAME, + ], + ]; } } From 156b3c285baba8df7ec04853746fbf44e8ed6d83 Mon Sep 17 00:00:00 2001 From: "vadim.malesh" Date: Mon, 10 Feb 2020 12:00:33 +0200 Subject: [PATCH 006/132] magento/magento2#7720: fix integration test --- .../Type/MultiStoreConfigurableViewOnProductPageTest.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/View/Type/MultiStoreConfigurableViewOnProductPageTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/View/Type/MultiStoreConfigurableViewOnProductPageTest.php index c1adf0ef1d2be..28c21254c7d9d 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/View/Type/MultiStoreConfigurableViewOnProductPageTest.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/View/Type/MultiStoreConfigurableViewOnProductPageTest.php @@ -17,6 +17,7 @@ use Magento\Store\Model\StoreManagerInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Store\ExecuteInStoreContext; +use Magento\Store\Api\StoreRepositoryInterface; use PHPUnit\Framework\TestCase; /** @@ -47,6 +48,9 @@ class MultiStoreConfigurableViewOnProductPageTest extends TestCase /** @var ExecuteInStoreContext */ private $executeInStoreContext; + /** @var StoreRepositoryInterface */ + private $storeRepository; + /** * @inheritdoc */ @@ -62,6 +66,7 @@ protected function setUp() $this->serializer = $this->objectManager->get(SerializerInterface::class); $this->productResource = $this->objectManager->get(ProductResource::class); $this->executeInStoreContext = $this->objectManager->get(ExecuteInStoreContext::class); + $this->storeRepository = $this->objectManager->get(StoreRepositoryInterface::class); } /** @@ -182,9 +187,11 @@ public function assertProductConfig($expectedProducts): void */ private function prepareConfigurableProduct(string $sku, string $storeCode): void { + $storeId = $this->storeRepository->get($storeCode)->getId(); $product = $this->productRepository->get($sku, false, null, true); $productToUpdate = $product->getTypeInstance()->getUsedProductCollection($product) - ->setPageSize(1)->getFirstItem(); + ->addStoreFilter($storeId)->setPageSize(1)->getFirstItem(); + $this->assertNotEmpty($productToUpdate->getData(), 'Configurable product does not have a child'); $this->executeInStoreContext->execute($storeCode, [$this, 'setProductDisabled'], $productToUpdate); } From 28b5d9d59803825e0bc9e340716cd269c7e26b6a Mon Sep 17 00:00:00 2001 From: "vadim.malesh" Date: Mon, 10 Feb 2020 15:38:19 +0200 Subject: [PATCH 007/132] magento/magento2#7720: improve integration test fix --- .../Type/MultiStoreConfigurableViewOnProductPageTest.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/View/Type/MultiStoreConfigurableViewOnProductPageTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/View/Type/MultiStoreConfigurableViewOnProductPageTest.php index 28c21254c7d9d..167a32fcb2f45 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/View/Type/MultiStoreConfigurableViewOnProductPageTest.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/View/Type/MultiStoreConfigurableViewOnProductPageTest.php @@ -17,7 +17,6 @@ use Magento\Store\Model\StoreManagerInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Store\ExecuteInStoreContext; -use Magento\Store\Api\StoreRepositoryInterface; use PHPUnit\Framework\TestCase; /** @@ -48,9 +47,6 @@ class MultiStoreConfigurableViewOnProductPageTest extends TestCase /** @var ExecuteInStoreContext */ private $executeInStoreContext; - /** @var StoreRepositoryInterface */ - private $storeRepository; - /** * @inheritdoc */ @@ -66,7 +62,6 @@ protected function setUp() $this->serializer = $this->objectManager->get(SerializerInterface::class); $this->productResource = $this->objectManager->get(ProductResource::class); $this->executeInStoreContext = $this->objectManager->get(ExecuteInStoreContext::class); - $this->storeRepository = $this->objectManager->get(StoreRepositoryInterface::class); } /** @@ -187,10 +182,10 @@ public function assertProductConfig($expectedProducts): void */ private function prepareConfigurableProduct(string $sku, string $storeCode): void { - $storeId = $this->storeRepository->get($storeCode)->getId(); + $store = $this->storeManager->getStore($storeCode); $product = $this->productRepository->get($sku, false, null, true); $productToUpdate = $product->getTypeInstance()->getUsedProductCollection($product) - ->addStoreFilter($storeId)->setPageSize(1)->getFirstItem(); + ->addStoreFilter($store)->setPageSize(1)->getFirstItem(); $this->assertNotEmpty($productToUpdate->getData(), 'Configurable product does not have a child'); $this->executeInStoreContext->execute($storeCode, [$this, 'setProductDisabled'], $productToUpdate); From c56eb37dfa0bae801957f2549e6888cd0a579816 Mon Sep 17 00:00:00 2001 From: Dmitri Mackert Date: Fri, 27 Mar 2020 18:41:00 +0100 Subject: [PATCH 008/132] MAGETWO-2745: added appEmulation to the obserber --- app/code/Magento/Sitemap/Model/Observer.php | 22 +++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sitemap/Model/Observer.php b/app/code/Magento/Sitemap/Model/Observer.php index ce74d738c4bc3..a87cb864532d9 100644 --- a/app/code/Magento/Sitemap/Model/Observer.php +++ b/app/code/Magento/Sitemap/Model/Observer.php @@ -3,11 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Sitemap\Model; -use Magento\Sitemap\Model\EmailNotification as SitemapEmail; +use Magento\Framework\App\Area; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Sitemap\Model\EmailNotification as SitemapEmail; use Magento\Sitemap\Model\ResourceModel\Sitemap\CollectionFactory; +use Magento\Store\Model\App\Emulation; use Magento\Store\Model\ScopeInterface; /** @@ -61,20 +65,28 @@ class Observer */ private $emailNotification; + /** + * @var Emulation + */ + private $appEmulation; + /** * Observer constructor. * @param ScopeConfigInterface $scopeConfig * @param CollectionFactory $collectionFactory * @param EmailNotification $emailNotification + * @param Emulation $appEmulation */ public function __construct( ScopeConfigInterface $scopeConfig, CollectionFactory $collectionFactory, - SitemapEmail $emailNotification + SitemapEmail $emailNotification, + Emulation $appEmulation ) { $this->scopeConfig = $scopeConfig; $this->collectionFactory = $collectionFactory; $this->emailNotification = $emailNotification; + $this->appEmulation = $appEmulation; } /** @@ -105,7 +117,13 @@ public function scheduledGenerateSitemaps() foreach ($collection as $sitemap) { /* @var $sitemap \Magento\Sitemap\Model\Sitemap */ try { + $this->appEmulation->startEnvironmentEmulation( + $sitemap->getStoreId(), + Area::AREA_FRONTEND, + true + ); $sitemap->generateXml(); + $this->appEmulation->stopEnvironmentEmulation(); } catch (\Exception $e) { $errors[] = $e->getMessage(); } From 2b86774ff29f132f7e89982695d13d4b3378c5ee Mon Sep 17 00:00:00 2001 From: Evgeny Levinsky Date: Tue, 7 Apr 2020 09:52:34 +0300 Subject: [PATCH 009/132] Created action group for cancel created orders --- .../Test/CheckCheckoutSuccessPageTest.xml | 8 ++- ...nOrderChangeByCustomerEmailActionGroup.xml | 61 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderChangeByCustomerEmailActionGroup.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml index eb49f53921ea4..5fbe30fb93c80 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml @@ -27,10 +27,16 @@ + + + + + + + - diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderChangeByCustomerEmailActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderChangeByCustomerEmailActionGroup.xml new file mode 100644 index 0000000000000..186d8bffbd502 --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderChangeByCustomerEmailActionGroup.xml @@ -0,0 +1,61 @@ + + + + + + + Goes to the Admin Orders grid page and changes all orders found by Customer Email field. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 83a4f097281860eaa59425feffb988f16000f0c9 Mon Sep 17 00:00:00 2001 From: Evgeny Levinsky Date: Tue, 7 Apr 2020 10:23:43 +0300 Subject: [PATCH 010/132] Moved going to order page and clearing the filters outside action group --- .../Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml | 2 ++ .../AdminOrderChangeByCustomerEmailActionGroup.xml | 13 +------------ 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml index 5fbe30fb93c80..55871ae23ac5d 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml @@ -29,6 +29,8 @@ + + diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderChangeByCustomerEmailActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderChangeByCustomerEmailActionGroup.xml index 186d8bffbd502..b74fcab2c095f 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderChangeByCustomerEmailActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderChangeByCustomerEmailActionGroup.xml @@ -10,7 +10,7 @@ - Goes to the Admin Orders grid page and changes all orders found by Customer Email field. + Changes all orders found by Customer Email field. @@ -18,17 +18,6 @@ - - - - - - Date: Tue, 7 Apr 2020 10:42:27 +0300 Subject: [PATCH 011/132] Created new action group to show new column in admin grid --- .../Test/CheckCheckoutSuccessPageTest.xml | 3 +++ ...nOrderChangeByCustomerEmailActionGroup.xml | 14 +---------- .../AdminGridColumnShowActionGroup.xml | 25 +++++++++++++++++++ 3 files changed, 29 insertions(+), 13 deletions(-) create mode 100644 app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminGridColumnShowActionGroup.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml index 55871ae23ac5d..07ece70c157e2 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml @@ -31,6 +31,9 @@ + + + diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderChangeByCustomerEmailActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderChangeByCustomerEmailActionGroup.xml index b74fcab2c095f..b2796cb5733aa 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderChangeByCustomerEmailActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderChangeByCustomerEmailActionGroup.xml @@ -10,7 +10,7 @@ - Changes all orders found by Customer Email field. + Changes all orders found by Customer Email field on Admin Order Grid page. @@ -18,18 +18,6 @@ - - - - - - + + + + + + Shows new column on Admin Grid page. + + + + + + + + + + + + From 24f9954c57deaa5d61ff6a77609b0fb36aa9fe51 Mon Sep 17 00:00:00 2001 From: Evgeny Levinsky Date: Fri, 10 Apr 2020 10:49:10 +0300 Subject: [PATCH 012/132] Created action group for massive actions in order admin grid --- .../Mftf/Test/CheckCheckoutSuccessPageTest.xml | 7 +++++-- ...=> AdminOrderBulkActionOnGridActionGroup.xml} | 16 ++-------------- 2 files changed, 7 insertions(+), 16 deletions(-) rename app/code/Magento/Sales/Test/Mftf/ActionGroup/{AdminOrderChangeByCustomerEmailActionGroup.xml => AdminOrderBulkActionOnGridActionGroup.xml} (58%) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml index 07ece70c157e2..7c5aa014bb375 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml @@ -34,9 +34,12 @@ - - + + + + + diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderChangeByCustomerEmailActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderBulkActionOnGridActionGroup.xml similarity index 58% rename from app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderChangeByCustomerEmailActionGroup.xml rename to app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderBulkActionOnGridActionGroup.xml index b2796cb5733aa..1a2aebef763a0 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderChangeByCustomerEmailActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderBulkActionOnGridActionGroup.xml @@ -7,28 +7,16 @@ --> - + - Changes all orders found by Customer Email field on Admin Order Grid page. + Massive action for all rows on Admin Order Grid page. - - - - - - - - From fd3e8133f7b8cd541d6305ce0f2722817ba98d2d Mon Sep 17 00:00:00 2001 From: Evgeny Levinsky Date: Fri, 10 Apr 2020 16:59:44 +0300 Subject: [PATCH 013/132] Moved bulk action group to Ui module to use in any admin grid --- .../Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml | 4 +++- .../Test/Mftf/ActionGroup/AdminGridBulkActionGroup.xml} | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) rename app/code/Magento/{Sales/Test/Mftf/ActionGroup/AdminOrderBulkActionOnGridActionGroup.xml => Ui/Test/Mftf/ActionGroup/AdminGridBulkActionGroup.xml} (79%) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml index 7c5aa014bb375..d836d6b046d3b 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml @@ -39,7 +39,9 @@ - + + + diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderBulkActionOnGridActionGroup.xml b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminGridBulkActionGroup.xml similarity index 79% rename from app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderBulkActionOnGridActionGroup.xml rename to app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminGridBulkActionGroup.xml index 1a2aebef763a0..9db9ea7becfc8 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderBulkActionOnGridActionGroup.xml +++ b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminGridBulkActionGroup.xml @@ -7,18 +7,18 @@ --> - + - Massive action for all rows on Admin Order Grid page. + Massive action for all rows on Admin Grid page. - + - + From 939ced035ae447f69bc31435ab7e3068503d1af4 Mon Sep 17 00:00:00 2001 From: Evgeny Levinsky Date: Fri, 10 Apr 2020 18:04:07 +0300 Subject: [PATCH 014/132] Cancel created orders after CheckCheckoutSuccessPageAsGuestTest --- .../Mftf/Test/CheckCheckoutSuccessPageTest.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml index d836d6b046d3b..7d0176eb309db 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml @@ -163,7 +163,23 @@ + + + + + + + + + + + + + + + + From 756f2dce55fd40c534fc00c131a9cc599a0f837a Mon Sep 17 00:00:00 2001 From: Evgeny Levinsky Date: Sat, 11 Apr 2020 13:15:46 +0300 Subject: [PATCH 015/132] Updated CheckCheckoutSuccessPageAsGuestTest after update branch --- .../CheckCheckoutSuccessPageAsGuestTest.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest/CheckCheckoutSuccessPageAsGuestTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest/CheckCheckoutSuccessPageAsGuestTest.xml index febeaa05be43e..d6a3cc791d6e0 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest/CheckCheckoutSuccessPageAsGuestTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest/CheckCheckoutSuccessPageAsGuestTest.xml @@ -23,7 +23,23 @@ + + + + + + + + + + + + + + + + From d63b5d8ebf71d461dea07ecac508790127064e65 Mon Sep 17 00:00:00 2001 From: Evgeny Levinsky Date: Sat, 11 Apr 2020 13:41:40 +0300 Subject: [PATCH 016/132] Added wait action in the end of AdminOrdersGridClearFiltersActionGroup --- .../Backend/Test/Mftf/Test/AdminDashboardWithChartsChart.xml | 1 - .../Test/AssociatedProductToConfigurableOutOfStockTest.xml | 3 --- .../CheckCheckoutSuccessPageAsGuestTest.xml | 1 - .../CheckCheckoutSuccessPageAsRegisterCustomerTest.xml | 1 - .../ActionGroup/AdminOrdersGridClearFiltersActionGroup.xml | 1 + .../Mftf/Test/AdminMassOrdersCancelCompleteAndClosedTest.xml | 3 --- .../Mftf/Test/AdminMassOrdersCancelProcessingAndClosedTest.xml | 3 --- .../Sales/Test/Mftf/Test/AdminMassOrdersHoldOnCompleteTest.xml | 3 --- .../Test/AdminMassOrdersHoldOnPendingAndProcessingTest.xml | 3 --- .../Test/Mftf/Test/AdminMassOrdersReleasePendingOrderTest.xml | 3 --- .../Mftf/Test/AdminMassOrdersUpdateCancelPendingOrderTest.xml | 3 --- .../Test/Mftf/Test/AdminOrdersReleaseInUnholdStatusTest.xml | 3 --- 12 files changed, 1 insertion(+), 27 deletions(-) diff --git a/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsChart.xml b/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsChart.xml index 147f2fa1dfaed..efe62d23191ce 100644 --- a/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsChart.xml +++ b/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsChart.xml @@ -34,7 +34,6 @@ - diff --git a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml index b291fb46ae71c..1f82a78d498c2 100644 --- a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml +++ b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml @@ -115,11 +115,8 @@ - - - diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest/CheckCheckoutSuccessPageAsGuestTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest/CheckCheckoutSuccessPageAsGuestTest.xml index d6a3cc791d6e0..3b15b9b4e0449 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest/CheckCheckoutSuccessPageAsGuestTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest/CheckCheckoutSuccessPageAsGuestTest.xml @@ -26,7 +26,6 @@ - diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest/CheckCheckoutSuccessPageAsRegisterCustomerTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest/CheckCheckoutSuccessPageAsRegisterCustomerTest.xml index 66967ad95bf40..fefab1a240f34 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest/CheckCheckoutSuccessPageAsRegisterCustomerTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest/CheckCheckoutSuccessPageAsRegisterCustomerTest.xml @@ -29,7 +29,6 @@ - diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrdersGridClearFiltersActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrdersGridClearFiltersActionGroup.xml index b301864212c8b..877f7946d7609 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrdersGridClearFiltersActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrdersGridClearFiltersActionGroup.xml @@ -16,5 +16,6 @@ + diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersCancelCompleteAndClosedTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersCancelCompleteAndClosedTest.xml index a89e9f7ce6ebe..b19b0cd31a9ca 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersCancelCompleteAndClosedTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersCancelCompleteAndClosedTest.xml @@ -63,10 +63,7 @@ - - - diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersCancelProcessingAndClosedTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersCancelProcessingAndClosedTest.xml index 45cbe23042e03..b8455cc5ea71f 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersCancelProcessingAndClosedTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersCancelProcessingAndClosedTest.xml @@ -63,10 +63,7 @@ - - - diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersHoldOnCompleteTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersHoldOnCompleteTest.xml index 22b2d69a73090..e0c03d1f915f5 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersHoldOnCompleteTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersHoldOnCompleteTest.xml @@ -50,10 +50,7 @@ - - - diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersHoldOnPendingAndProcessingTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersHoldOnPendingAndProcessingTest.xml index 4b690a00ee9ed..47dc3bfb089bd 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersHoldOnPendingAndProcessingTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersHoldOnPendingAndProcessingTest.xml @@ -60,10 +60,7 @@ - - - diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersReleasePendingOrderTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersReleasePendingOrderTest.xml index e1d934f794142..ebe3644901aa4 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersReleasePendingOrderTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersReleasePendingOrderTest.xml @@ -47,10 +47,7 @@ - - - diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersUpdateCancelPendingOrderTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersUpdateCancelPendingOrderTest.xml index 86a3e381cb237..543f282bd59b2 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersUpdateCancelPendingOrderTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminMassOrdersUpdateCancelPendingOrderTest.xml @@ -46,10 +46,7 @@ - - - diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminOrdersReleaseInUnholdStatusTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminOrdersReleaseInUnholdStatusTest.xml index bfd75a69b81d6..e7bb7ec01ccc2 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminOrdersReleaseInUnholdStatusTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminOrdersReleaseInUnholdStatusTest.xml @@ -52,10 +52,7 @@ - - - From 303bd64e3c1a7281be08d3b73feb995ef580e61d Mon Sep 17 00:00:00 2001 From: Ievgen Shakhsuvarov Date: Tue, 5 May 2020 16:30:26 -0500 Subject: [PATCH 017/132] magento/magento2#28116: RequireJS resolver sometimes fails to detect blocked resources --- lib/web/mage/requirejs/resolver.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/web/mage/requirejs/resolver.js b/lib/web/mage/requirejs/resolver.js index 5ba1f1351bcf6..8e1757d30f572 100644 --- a/lib/web/mage/requirejs/resolver.js +++ b/lib/web/mage/requirejs/resolver.js @@ -37,6 +37,16 @@ define([ return registry[module.id] && (registry[module.id].inited || registry[module.id].error); } + /** + * Checks if provided module had path fallback triggered. + * + * @param {Object} module - Module to be checked. + * @return {Boolean} + */ + function isPathFallback(module) { + return registry[module.id] && registry[module.id].events.error; + } + /** * Checks if provided module has unresolved dependencies. * @@ -48,7 +58,8 @@ define([ return false; } - return module.depCount > _.filter(module.depMaps, isRejected).length; + return module.depCount > + (_.filter(module.depMaps, isRejected).length + _.filter(module.depMaps, isPathFallback).length); } /** From 44d88e64f70134280616bcc9471f74283fdef44f Mon Sep 17 00:00:00 2001 From: Pieter Zandbergen Date: Sun, 26 Jul 2020 10:23:30 +0200 Subject: [PATCH 018/132] Update Curl to respect case-insensitive headers According to RFC 2616 header names are case-insensitive: "Each header field consists of a name followed by a colon (":") and the field value. Field names are case-insensitive." - see https://tools.ietf.org/html/rfc2616#section-4.2 The "Set-Cookie" comparison in the previous version is case-sensitive and can cause problems with some (rare) HTTP servers. --- lib/internal/Magento/Framework/HTTP/Client/Curl.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/HTTP/Client/Curl.php b/lib/internal/Magento/Framework/HTTP/Client/Curl.php index 60825e231504d..d20dbf2142ec7 100644 --- a/lib/internal/Magento/Framework/HTTP/Client/Curl.php +++ b/lib/internal/Magento/Framework/HTTP/Client/Curl.php @@ -453,11 +453,11 @@ protected function parseHeaders($ch, $data) } if (strlen($name)) { - if ("Set-Cookie" == $name) { - if (!isset($this->_responseHeaders[$name])) { - $this->_responseHeaders[$name] = []; + if ("set-cookie" == strtolower($name)) { + if (!isset($this->_responseHeaders['Set-Cookie'])) { + $this->_responseHeaders['Set-Cookie'] = []; } - $this->_responseHeaders[$name][] = $value; + $this->_responseHeaders['Set-Cookie'][] = $value; } else { $this->_responseHeaders[$name] = $value; } From 375b129374fb83ba4993c67cb893835da91032ec Mon Sep 17 00:00:00 2001 From: Ihor Sviziev Date: Wed, 29 Jul 2020 09:12:06 +0300 Subject: [PATCH 019/132] magento/magento2#28117 RequireJS resolver sometimes fails to detect blocked resources Fix static tests --- lib/web/mage/requirejs/resolver.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/mage/requirejs/resolver.js b/lib/web/mage/requirejs/resolver.js index 8e1757d30f572..9818bc00c1343 100644 --- a/lib/web/mage/requirejs/resolver.js +++ b/lib/web/mage/requirejs/resolver.js @@ -59,7 +59,7 @@ define([ } return module.depCount > - (_.filter(module.depMaps, isRejected).length + _.filter(module.depMaps, isPathFallback).length); + _.filter(module.depMaps, isRejected).length + _.filter(module.depMaps, isPathFallback).length; } /** From ba6513fa9b8777dd5a1a89a9b542ec54978ef534 Mon Sep 17 00:00:00 2001 From: Pieter Zandbergen Date: Wed, 29 Jul 2020 21:12:40 +0200 Subject: [PATCH 020/132] Update lib/internal/Magento/Framework/HTTP/Client/Curl.php Co-authored-by: Ihor Sviziev --- lib/internal/Magento/Framework/HTTP/Client/Curl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/HTTP/Client/Curl.php b/lib/internal/Magento/Framework/HTTP/Client/Curl.php index d20dbf2142ec7..195ce3a63a231 100644 --- a/lib/internal/Magento/Framework/HTTP/Client/Curl.php +++ b/lib/internal/Magento/Framework/HTTP/Client/Curl.php @@ -453,7 +453,7 @@ protected function parseHeaders($ch, $data) } if (strlen($name)) { - if ("set-cookie" == strtolower($name)) { + if ("set-cookie" === strtolower($name)) { if (!isset($this->_responseHeaders['Set-Cookie'])) { $this->_responseHeaders['Set-Cookie'] = []; } From 552e0c1fbd1367e7ecb7fb421b8057060663a3af Mon Sep 17 00:00:00 2001 From: Pieter Zandbergen Date: Sun, 2 Aug 2020 09:41:01 +0200 Subject: [PATCH 021/132] Updated cUrl client to accept case-insensitive Set-Cookie headers including tests --- .../Magento/Framework/HTTP/Client/Curl.php | 8 +- .../HTTP/Test/Unit/Client/CurlMockTest.php | 86 +++++++++++++++++++ .../Unit/Client/_files/curl_exec_mock.php | 51 +++++++++++ .../Client/_files/curl_response_cookies.txt | 14 +++ 4 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 lib/internal/Magento/Framework/HTTP/Test/Unit/Client/CurlMockTest.php create mode 100644 lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_exec_mock.php create mode 100644 lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_response_cookies.txt diff --git a/lib/internal/Magento/Framework/HTTP/Client/Curl.php b/lib/internal/Magento/Framework/HTTP/Client/Curl.php index 60825e231504d..4d78712175156 100644 --- a/lib/internal/Magento/Framework/HTTP/Client/Curl.php +++ b/lib/internal/Magento/Framework/HTTP/Client/Curl.php @@ -453,11 +453,11 @@ protected function parseHeaders($ch, $data) } if (strlen($name)) { - if ("Set-Cookie" == $name) { - if (!isset($this->_responseHeaders[$name])) { - $this->_responseHeaders[$name] = []; + if ('set-cookie' === strtolower($name)) { + if (!isset($this->_responseHeaders['Set-Cookie'])) { + $this->_responseHeaders['Set-Cookie'] = []; } - $this->_responseHeaders[$name][] = $value; + $this->_responseHeaders['Set-Cookie'][] = $value; } else { $this->_responseHeaders[$name] = $value; } diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/CurlMockTest.php b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/CurlMockTest.php new file mode 100644 index 0000000000000..acb068b581e02 --- /dev/null +++ b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/CurlMockTest.php @@ -0,0 +1,86 @@ +model = new CurlMock(); + } + + /** + * Handle Curl response + * + * @param string $response + * @return string + */ + private function handleResponse(string $response): string + { + // Make sure we use valid newlines + $response = explode("\r\n\r\n", str_replace("\n", "\r\n", $response), 2); + + // Parse headers + $headers = explode("\r\n", $response[0]); + foreach ($headers as $header) { + call_user_func([$this->model, 'parseHeaders'], $this->model->getResource(), $header); + } + + // Return body + return $response[1] ?? ''; + } + + /** + * Check that HTTP client parses cookies. + * + * @param string $response + * @dataProvider cookiesDataProvider + */ + public function testCookies($response) + { + self::$curlExectClosure = function () use ($response) { + $this->handleResponse($response); + }; + $this->model->get('http://127.0.0.1/test'); + $cookies = $this->model->getCookies(); + $this->assertIsArray($cookies); + $this->assertEquals([ + 'Normal' => 'OK', + 'Uppercase' => 'OK', + 'Lowercase' => 'OK', + ], $cookies); + } + + /** + * @return array + */ + public function cookiesDataProvider() + { + return [ + [file_get_contents(__DIR__ . '/_files/curl_response_cookies.txt')], + ]; + } +} diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_exec_mock.php b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_exec_mock.php new file mode 100644 index 0000000000000..95e035d9366ba --- /dev/null +++ b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_exec_mock.php @@ -0,0 +1,51 @@ +_ch; + } +} diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_response_cookies.txt b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_response_cookies.txt new file mode 100644 index 0000000000000..d68d286bb4de8 --- /dev/null +++ b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_response_cookies.txt @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +Server: Apache +X-Frame-Options: SAMEORIGIN +Strict-Transport-Security: max-age=14400 +Strict-Transport-Security: max-age=14400 +Content-Type: text/html; charset=UTF-8 +Date: Mon, 22 Apr 2013 09:52:36 GMT +Content-Length: 8 +Connection: keep-alive +Set-Cookie: Normal=OK +SET-COOKIE: Uppercase=OK +set-cookie: Lowercase=OK + +VERIFIED From e43e45fac11c585855d2da5a5bb6c2a58d28fb68 Mon Sep 17 00:00:00 2001 From: engcom-Echo Date: Thu, 6 Aug 2020 12:21:30 +0300 Subject: [PATCH 022/132] fix static --- .../Framework/HTTP/Test/Unit/Client/_files/curl_exec_mock.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_exec_mock.php b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_exec_mock.php index 95e035d9366ba..83453de58f30a 100644 --- a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_exec_mock.php +++ b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_exec_mock.php @@ -26,6 +26,7 @@ function curl_exec($resource) */ class CurlMock extends Curl { + // @codingStandardsIgnoreStart /** * Unfortunately, it is necessary for the tests to set this function public. * @@ -38,6 +39,7 @@ public function parseHeaders($ch, $data) { return parent::parseHeaders($ch, $data); } + // @codingStandardsIgnoreEnd /** * Return Curl resource, only used for testing. From 7341b4f3acb4fbca10b6b5dc76e560b8415e81d6 Mon Sep 17 00:00:00 2001 From: Ejaz Alam Date: Wed, 12 Aug 2020 13:08:38 +0500 Subject: [PATCH 023/132] System configuration Validation This field should be save empty, but incorrect validation was applied. Because of that, admin user couldn't save the empty value. --- app/code/Magento/Integration/etc/adminhtml/system.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Integration/etc/adminhtml/system.xml b/app/code/Magento/Integration/etc/adminhtml/system.xml index 6ef569a1d8a2f..2b15852563b20 100644 --- a/app/code/Magento/Integration/etc/adminhtml/system.xml +++ b/app/code/Magento/Integration/etc/adminhtml/system.xml @@ -16,7 +16,7 @@ We will disable this feature if the value is empty. - required-entry validate-zero-or-greater validate-number + validate-zero-or-greater validate-number From 4328a2d67191648c352b156f3a0aecc56870d1ad Mon Sep 17 00:00:00 2001 From: Marvin Hinz <35603466+marvinhinz@users.noreply.github.com> Date: Fri, 14 Aug 2020 13:54:07 +0200 Subject: [PATCH 024/132] Fix Parameter Tokenizer omitting first char of key --- .../Magento/Framework/Filter/Template/Tokenizer/Parameter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Filter/Template/Tokenizer/Parameter.php b/lib/internal/Magento/Framework/Filter/Template/Tokenizer/Parameter.php index 624d6107bb6b8..84f747ef456bd 100644 --- a/lib/internal/Magento/Framework/Filter/Template/Tokenizer/Parameter.php +++ b/lib/internal/Magento/Framework/Filter/Template/Tokenizer/Parameter.php @@ -19,7 +19,7 @@ public function tokenize() { $parameters = []; $parameterName = ''; - while ($this->next()) { + do { if ($this->isWhiteSpace()) { continue; } elseif ($this->char() != '=') { @@ -28,7 +28,7 @@ public function tokenize() $parameters[$parameterName] = $this->getValue(); $parameterName = ''; } - } + } while ($this->next()); return $parameters; } From 9570f8f0efe9cb77fe7a430843167ad5f879682a Mon Sep 17 00:00:00 2001 From: Pieter Zandbergen Date: Sat, 15 Aug 2020 09:13:24 +0200 Subject: [PATCH 025/132] Updates for static tests, removed Set-Cookie array initialization --- .../Magento/Framework/HTTP/Client/Curl.php | 3 -- .../HTTP/Test/Unit/Client/CurlMockTest.php | 2 +- .../HTTP/Test/Unit/Client/Mock/CurlMock.php | 41 +++++++++++++++++++ .../Unit/Client/_files/curl_exec_mock.php | 31 -------------- 4 files changed, 42 insertions(+), 35 deletions(-) create mode 100644 lib/internal/Magento/Framework/HTTP/Test/Unit/Client/Mock/CurlMock.php diff --git a/lib/internal/Magento/Framework/HTTP/Client/Curl.php b/lib/internal/Magento/Framework/HTTP/Client/Curl.php index 4d78712175156..5379d481289f5 100644 --- a/lib/internal/Magento/Framework/HTTP/Client/Curl.php +++ b/lib/internal/Magento/Framework/HTTP/Client/Curl.php @@ -454,9 +454,6 @@ protected function parseHeaders($ch, $data) if (strlen($name)) { if ('set-cookie' === strtolower($name)) { - if (!isset($this->_responseHeaders['Set-Cookie'])) { - $this->_responseHeaders['Set-Cookie'] = []; - } $this->_responseHeaders['Set-Cookie'][] = $value; } else { $this->_responseHeaders[$name] = $value; diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/CurlMockTest.php b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/CurlMockTest.php index acb068b581e02..3658f9ca8208c 100644 --- a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/CurlMockTest.php +++ b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/CurlMockTest.php @@ -8,7 +8,7 @@ namespace Magento\Framework\HTTP\Test\Unit\Client; -use Magento\Framework\HTTP\Client\CurlMock; +use Magento\Framework\HTTP\Test\Unit\Client\Mock\CurlMock; use PHPUnit\Framework\TestCase; /** diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/Mock/CurlMock.php b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/Mock/CurlMock.php new file mode 100644 index 0000000000000..c5111cbaa2b9d --- /dev/null +++ b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/Mock/CurlMock.php @@ -0,0 +1,41 @@ +_ch; + } +} diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_exec_mock.php b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_exec_mock.php index 83453de58f30a..69e87914f9bcf 100644 --- a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_exec_mock.php +++ b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_exec_mock.php @@ -20,34 +20,3 @@ function curl_exec($resource) { return call_user_func(CurlMockTest::$curlExectClosure); } - -/** - * Extended Curl class with modifications for testing - */ -class CurlMock extends Curl -{ - // @codingStandardsIgnoreStart - /** - * Unfortunately, it is necessary for the tests to set this function public. - * - * @param resource $ch curl handle, not needed - * @param string $data - * @return int - * @throws \Exception - */ - public function parseHeaders($ch, $data) - { - return parent::parseHeaders($ch, $data); - } - // @codingStandardsIgnoreEnd - - /** - * Return Curl resource, only used for testing. - * - * @return resource - */ - public function getResource() - { - return $this->_ch; - } -} From 9db1f830052f990103845b1ecac03b45091c51cb Mon Sep 17 00:00:00 2001 From: Pieter Zandbergen Date: Sat, 15 Aug 2020 09:25:27 +0200 Subject: [PATCH 026/132] Updated files to alter test sequence --- .../HTTP/Test/Unit/{Client => ClientMock}/CurlMockTest.php | 4 ++-- .../HTTP/Test/Unit/{Client => ClientMock}/Mock/CurlMock.php | 2 +- .../Unit/{Client => ClientMock}/_files/curl_exec_mock.php | 2 +- .../{Client => ClientMock}/_files/curl_response_cookies.txt | 0 4 files changed, 4 insertions(+), 4 deletions(-) rename lib/internal/Magento/Framework/HTTP/Test/Unit/{Client => ClientMock}/CurlMockTest.php (94%) rename lib/internal/Magento/Framework/HTTP/Test/Unit/{Client => ClientMock}/Mock/CurlMock.php (93%) rename lib/internal/Magento/Framework/HTTP/Test/Unit/{Client => ClientMock}/_files/curl_exec_mock.php (86%) rename lib/internal/Magento/Framework/HTTP/Test/Unit/{Client => ClientMock}/_files/curl_response_cookies.txt (100%) diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/CurlMockTest.php b/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/CurlMockTest.php similarity index 94% rename from lib/internal/Magento/Framework/HTTP/Test/Unit/Client/CurlMockTest.php rename to lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/CurlMockTest.php index 3658f9ca8208c..bf386a2387d71 100644 --- a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/CurlMockTest.php +++ b/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/CurlMockTest.php @@ -6,9 +6,9 @@ declare(strict_types=1); -namespace Magento\Framework\HTTP\Test\Unit\Client; +namespace Magento\Framework\HTTP\Test\Unit\ClientMock; -use Magento\Framework\HTTP\Test\Unit\Client\Mock\CurlMock; +use Magento\Framework\HTTP\Test\Unit\ClientMock\Mock\CurlMock; use PHPUnit\Framework\TestCase; /** diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/Mock/CurlMock.php b/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/Mock/CurlMock.php similarity index 93% rename from lib/internal/Magento/Framework/HTTP/Test/Unit/Client/Mock/CurlMock.php rename to lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/Mock/CurlMock.php index c5111cbaa2b9d..03d786a7ec73c 100644 --- a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/Mock/CurlMock.php +++ b/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/Mock/CurlMock.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\Framework\HTTP\Test\Unit\Client\Mock; +namespace Magento\Framework\HTTP\Test\Unit\ClientMock\Mock; use Magento\Framework\HTTP\Client\Curl; diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_exec_mock.php b/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/_files/curl_exec_mock.php similarity index 86% rename from lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_exec_mock.php rename to lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/_files/curl_exec_mock.php index 69e87914f9bcf..019f4889530d8 100644 --- a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_exec_mock.php +++ b/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/_files/curl_exec_mock.php @@ -7,7 +7,7 @@ namespace Magento\Framework\HTTP\Client; -use Magento\Framework\HTTP\Test\Unit\Client\CurlMockTest; +use Magento\Framework\HTTP\Test\Unit\ClientMock\CurlMockTest; /** * Override global PHP function diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_response_cookies.txt b/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/_files/curl_response_cookies.txt similarity index 100% rename from lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_response_cookies.txt rename to lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/_files/curl_response_cookies.txt From fdb4b7f5eba6441d453e26f41e36c0e1935bf865 Mon Sep 17 00:00:00 2001 From: Ejaz Alam Date: Wed, 19 Aug 2020 01:31:47 +0500 Subject: [PATCH 027/132] Incorrect required validation. Removed invalid "Required Validation" for both admin token and customer token. --- app/code/Magento/Integration/etc/adminhtml/system.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Integration/etc/adminhtml/system.xml b/app/code/Magento/Integration/etc/adminhtml/system.xml index 2b15852563b20..3d465a9642805 100644 --- a/app/code/Magento/Integration/etc/adminhtml/system.xml +++ b/app/code/Magento/Integration/etc/adminhtml/system.xml @@ -21,7 +21,7 @@ We will disable this feature if the value is empty. - required-entry validate-zero-or-greater validate-number + validate-zero-or-greater validate-number From 8344b1193b33ec89457b3717362dd923f4a7c97d Mon Sep 17 00:00:00 2001 From: Shankar Konar Date: Wed, 19 Aug 2020 13:34:51 +0530 Subject: [PATCH 028/132] Removed fileinfo extension dependency from CMS module --- .../Magento/Cms/Model/Wysiwyg/Images/Storage.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php b/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php index ae88b24bd2682..0e64515e69fd5 100644 --- a/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php +++ b/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php @@ -152,6 +152,11 @@ class Storage extends \Magento\Framework\DataObject */ private $ioFile; + /** + * @var \Magento\Framework\File\Mime|null + */ + private $mime; + /** * Construct * @@ -197,6 +202,7 @@ public function __construct( array $data = [], \Magento\Framework\Filesystem\DriverInterface $file = null, \Magento\Framework\Filesystem\Io\File $ioFile = null, + \Magento\Framework\File\Mime $mime = null, \Psr\Log\LoggerInterface $logger = null ) { $this->_session = $session; @@ -217,6 +223,7 @@ public function __construct( $this->_dirs = $dirs; $this->file = $file ?: ObjectManager::getInstance()->get(\Magento\Framework\Filesystem\Driver\File::class); $this->ioFile = $ioFile ?: ObjectManager::getInstance()->get(\Magento\Framework\Filesystem\Io\File::class); + $this->mime = $mime ?: ObjectManager::getInstance()->get(\Magento\Framework\File\Mime::class); parent::__construct($data); } @@ -362,7 +369,7 @@ public function getFilesCollection($path, $type = null) $item->setUrl($this->_cmsWysiwygImages->getCurrentUrl() . $item->getBasename()); $itemStats = $this->file->stat($item->getFilename()); $item->setSize($itemStats['size']); - $item->setMimeType(\mime_content_type($item->getFilename())); + $item->setMimeType($this->mime->getMimeType($item->getFilename())); if ($this->isImage($item->getBasename())) { $thumbUrl = $this->getThumbnailUrl($item->getFilename(), true); @@ -647,7 +654,7 @@ public function resizeFile($source, $keepRatio = true) $image->keepAspectRatio($keepRatio); list($imageWidth, $imageHeight) = $this->getResizedParams($source); - + $image->resize($imageWidth, $imageHeight); $dest = $targetDir . '/' . $this->ioFile->getPathInfo($source)['basename']; $image->save($dest); @@ -670,7 +677,7 @@ private function getResizedParams(string $source): array //phpcs:ignore Generic.PHP.NoSilencedErrors list($imageWidth, $imageHeight) = @getimagesize($source); - + if ($imageWidth && $imageHeight) { $imageWidth = $configWidth > $imageWidth ? $imageWidth : $configWidth; $imageHeight = $configHeight > $imageHeight ? $imageHeight : $configHeight; @@ -679,7 +686,7 @@ private function getResizedParams(string $source): array } return [$configWidth, $configHeight]; } - + /** * Resize images on the fly in controller action * From 8da5e70859784f0cf097fae1bcbaa240db55fb85 Mon Sep 17 00:00:00 2001 From: Shankar Konar Date: Wed, 19 Aug 2020 14:27:55 +0530 Subject: [PATCH 029/132] Fixed Static tests --- app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php b/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php index 0e64515e69fd5..e70a3b5da63c0 100644 --- a/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php +++ b/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php @@ -22,6 +22,7 @@ * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) + * @SuppressWarnings(PHPMD.CyclomaticComplexity) * * @api * @since 100.0.2 @@ -178,6 +179,7 @@ class Storage extends \Magento\Framework\DataObject * @param array $data * @param \Magento\Framework\Filesystem\DriverInterface $file * @param \Magento\Framework\Filesystem\Io\File|null $ioFile + * @param \Magento\Framework\File\Mime $mime * @param \Psr\Log\LoggerInterface|null $logger * * @throws \Magento\Framework\Exception\FileSystemException From 9b9d12351b679d72987d7f6799d07a1faa9cf216 Mon Sep 17 00:00:00 2001 From: "vadim.malesh" Date: Thu, 20 Aug 2020 12:48:01 +0300 Subject: [PATCH 030/132] improve test --- .../Type/MultiStoreConfigurableViewOnProductPageTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/View/Type/MultiStoreConfigurableViewOnProductPageTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/View/Type/MultiStoreConfigurableViewOnProductPageTest.php index fb174dd8fc5d2..cd206ec8ec273 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/View/Type/MultiStoreConfigurableViewOnProductPageTest.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/View/Type/MultiStoreConfigurableViewOnProductPageTest.php @@ -182,10 +182,11 @@ public function assertProductConfig($expectedProducts): void */ private function prepareConfigurableProduct(string $sku, string $storeCode): void { - $store = $this->storeManager->getStore($storeCode); $product = $this->productRepository->get($sku, false, null, true); $productToUpdate = $product->getTypeInstance()->getUsedProductCollection($product) - ->addStoreFilter($store)->setPageSize(1)->getFirstItem(); + ->addStoreFilter($storeCode) + ->setPageSize(1) + ->getFirstItem(); $this->assertNotEmpty($productToUpdate->getData(), 'Configurable product does not have a child'); $this->executeInStoreContext->execute($storeCode, [$this, 'setProductDisabled'], $productToUpdate); From d312ab5f63f22329c3dde98cbcebb2347c8f077c Mon Sep 17 00:00:00 2001 From: Shankar Konar Date: Thu, 20 Aug 2020 18:33:04 +0530 Subject: [PATCH 031/132] Moved mime optional parameter at the end of parameter list --- app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php b/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php index e70a3b5da63c0..5ce512c249630 100644 --- a/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php +++ b/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php @@ -179,8 +179,8 @@ class Storage extends \Magento\Framework\DataObject * @param array $data * @param \Magento\Framework\Filesystem\DriverInterface $file * @param \Magento\Framework\Filesystem\Io\File|null $ioFile - * @param \Magento\Framework\File\Mime $mime * @param \Psr\Log\LoggerInterface|null $logger + * @param \Magento\Framework\File\Mime $mime * * @throws \Magento\Framework\Exception\FileSystemException * @SuppressWarnings(PHPMD.ExcessiveParameterList) @@ -204,8 +204,8 @@ public function __construct( array $data = [], \Magento\Framework\Filesystem\DriverInterface $file = null, \Magento\Framework\Filesystem\Io\File $ioFile = null, - \Magento\Framework\File\Mime $mime = null, - \Psr\Log\LoggerInterface $logger = null + \Psr\Log\LoggerInterface $logger = null, + \Magento\Framework\File\Mime $mime = null ) { $this->_session = $session; $this->_backendUrl = $backendUrl; From 55a15434c4208a631aef8d6a9f474987ed8a901e Mon Sep 17 00:00:00 2001 From: "vadim.malesh" Date: Fri, 21 Aug 2020 09:15:00 +0300 Subject: [PATCH 032/132] fix abstractTokenizer; cover by test --- .../Template/Tokenizer/ParameterTest.php | 59 ++++++++++++++----- .../Template/Tokenizer/AbstractTokenizer.php | 2 +- .../Filter/Template/Tokenizer/Parameter.php | 4 +- 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Filter/Template/Tokenizer/ParameterTest.php b/dev/tests/integration/testsuite/Magento/Framework/Filter/Template/Tokenizer/ParameterTest.php index 8d4ebc40128d1..8919182263a41 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Filter/Template/Tokenizer/ParameterTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Filter/Template/Tokenizer/ParameterTest.php @@ -3,20 +3,33 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Framework\Filter\Template\Tokenizer; -class ParameterTest extends \PHPUnit\Framework\TestCase +use Magento\Catalog\Block\Product\Widget\NewWidget; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Test for \Magento\Framework\Filter\Template\Tokenizer\Parameter. + */ +class ParameterTest extends TestCase { /** + * Test for getValue + * + * @dataProvider getValueDataProvider + * * @param string $string * @param array $values - * @dataProvider getValueDataProvider + * @return void */ - public function testGetValue($string, $values) + public function testGetValue($string, $values): void { - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - /** @var \Magento\Framework\Filter\Template\Tokenizer\Parameter $parameter */ - $parameter = $objectManager->create(\Magento\Framework\Filter\Template\Tokenizer\Parameter::class); + $objectManager = Bootstrap::getObjectManager(); + /** @var Parameter $parameter */ + $parameter = $objectManager->create(Parameter::class); $parameter->setString($string); foreach ($values as $value) { @@ -25,30 +38,36 @@ public function testGetValue($string, $values) } /** + * Test for tokenize + * * @dataProvider tokenizeDataProvider + * * @param string $string * @param array $params + * @return void */ - public function testTokenize($string, $params) + public function testTokenize($string, $params): void { - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - /** @var \Magento\Framework\Filter\Template\Tokenizer\Parameter $parameter */ - $parameter = $objectManager->create(\Magento\Framework\Filter\Template\Tokenizer\Parameter::class); + $objectManager = Bootstrap::getObjectManager(); + $parameter = $objectManager->create(Parameter::class); $parameter->setString($string); + $this->assertEquals($params, $parameter->tokenize()); } /** + * DataProvider for testTokenize + * * @return array */ - public function tokenizeDataProvider() + public function tokenizeDataProvider(): array { return [ [ ' type="Magento\\Catalog\\Block\\Product\\Widget\\NewWidget" display_type="all_products"' . ' products_count="10" template="product/widget/new/content/new_grid.phtml"', [ - 'type' => \Magento\Catalog\Block\Product\Widget\NewWidget::class, + 'type' => NewWidget::class, 'display_type' => 'all_products', 'products_count' => 10, 'template' => 'product/widget/new/content/new_grid.phtml' @@ -58,12 +77,24 @@ public function tokenizeDataProvider() ' type="Magento\Catalog\Block\Product\Widget\NewWidget" display_type="all_products"' . ' products_count="10" template="product/widget/new/content/new_grid.phtml"', [ - 'type' => \Magento\Catalog\Block\Product\Widget\NewWidget::class, + 'type' => NewWidget::class, 'display_type' => 'all_products', 'products_count' => 10, 'template' => 'product/widget/new/content/new_grid.phtml' ] - ] + ], + [ + sprintf( + 'type="%s" display_type="all_products" products_count="1" template="content/new_grid.phtml"', + NewWidget::class + ), + [ + 'type' => NewWidget::class, + 'display_type' => 'all_products', + 'products_count' => 1, + 'template' => 'content/new_grid.phtml' + ], + ], ]; } diff --git a/lib/internal/Magento/Framework/Filter/Template/Tokenizer/AbstractTokenizer.php b/lib/internal/Magento/Framework/Filter/Template/Tokenizer/AbstractTokenizer.php index b72305c6f5bdc..9afbe8672e1af 100644 --- a/lib/internal/Magento/Framework/Filter/Template/Tokenizer/AbstractTokenizer.php +++ b/lib/internal/Magento/Framework/Filter/Template/Tokenizer/AbstractTokenizer.php @@ -115,7 +115,7 @@ public function reset() */ public function isWhiteSpace() { - return trim($this->char()) != $this->char(); + return $this->_string === '' ?: trim($this->char()) !== $this->char(); } /** diff --git a/lib/internal/Magento/Framework/Filter/Template/Tokenizer/Parameter.php b/lib/internal/Magento/Framework/Filter/Template/Tokenizer/Parameter.php index 84f747ef456bd..61fdd2ea1b283 100644 --- a/lib/internal/Magento/Framework/Filter/Template/Tokenizer/Parameter.php +++ b/lib/internal/Magento/Framework/Filter/Template/Tokenizer/Parameter.php @@ -22,7 +22,9 @@ public function tokenize() do { if ($this->isWhiteSpace()) { continue; - } elseif ($this->char() != '=') { + } + + if ($this->char() !== '=') { $parameterName .= $this->char(); } else { $parameters[$parameterName] = $this->getValue(); From 1b322f4310292ab933f1e801b3281c1964effa64 Mon Sep 17 00:00:00 2001 From: "vadim.malesh" Date: Fri, 21 Aug 2020 09:18:25 +0300 Subject: [PATCH 033/132] add strict type --- .../Framework/Filter/Template/Tokenizer/ParameterTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Filter/Template/Tokenizer/ParameterTest.php b/dev/tests/integration/testsuite/Magento/Framework/Filter/Template/Tokenizer/ParameterTest.php index 8919182263a41..aad47165a470a 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Filter/Template/Tokenizer/ParameterTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Filter/Template/Tokenizer/ParameterTest.php @@ -46,7 +46,7 @@ public function testGetValue($string, $values): void * @param array $params * @return void */ - public function testTokenize($string, $params): void + public function testTokenize(string $string, array $params): void { $objectManager = Bootstrap::getObjectManager(); $parameter = $objectManager->create(Parameter::class); From 1f137fcb340fdba58cc85ab25a9100392e180c44 Mon Sep 17 00:00:00 2001 From: Alexander Steshuk Date: Fri, 21 Aug 2020 10:57:23 +0300 Subject: [PATCH 034/132] MFTF test. --- .../Page/AdminConfigServicesOauthPage.xml | 12 +++++++ ...dminConfigAccessTokenExpirationSection.xml | 17 +++++++++ .../Test/AdminConfigSaveEmptySettingsTest.xml | 35 +++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 app/code/Magento/Integration/Test/Mftf/Page/AdminConfigServicesOauthPage.xml create mode 100644 app/code/Magento/Integration/Test/Mftf/Section/AdminConfigAccessTokenExpirationSection.xml create mode 100644 app/code/Magento/Integration/Test/Mftf/Test/AdminConfigSaveEmptySettingsTest.xml diff --git a/app/code/Magento/Integration/Test/Mftf/Page/AdminConfigServicesOauthPage.xml b/app/code/Magento/Integration/Test/Mftf/Page/AdminConfigServicesOauthPage.xml new file mode 100644 index 0000000000000..85f20c3617e1d --- /dev/null +++ b/app/code/Magento/Integration/Test/Mftf/Page/AdminConfigServicesOauthPage.xml @@ -0,0 +1,12 @@ + + + + +
+ + diff --git a/app/code/Magento/Integration/Test/Mftf/Section/AdminConfigAccessTokenExpirationSection.xml b/app/code/Magento/Integration/Test/Mftf/Section/AdminConfigAccessTokenExpirationSection.xml new file mode 100644 index 0000000000000..0f18c1e75979e --- /dev/null +++ b/app/code/Magento/Integration/Test/Mftf/Section/AdminConfigAccessTokenExpirationSection.xml @@ -0,0 +1,17 @@ + + + +
+ + + + + + +
+
diff --git a/app/code/Magento/Integration/Test/Mftf/Test/AdminConfigSaveEmptySettingsTest.xml b/app/code/Magento/Integration/Test/Mftf/Test/AdminConfigSaveEmptySettingsTest.xml new file mode 100644 index 0000000000000..ad1b27e7a0843 --- /dev/null +++ b/app/code/Magento/Integration/Test/Mftf/Test/AdminConfigSaveEmptySettingsTest.xml @@ -0,0 +1,35 @@ + + + + + + + + + + <description value="Save settings 'Customer Token Lifetime' and 'Admin Token Lifetime' with empty values without validations."/> + <severity value="MINOR"/> + <group value="configuration"/> + </annotations> + <before> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + </before> + <after> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + </after> + <amOnPage url="{{AdminConfigServicesOauthPage.url}}" stepKey="navigateToConfigurationPage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <conditionalClick selector="{{AdminConfigAccessTokenExpirationSection.tabAccessTokenLifetime}}" dependentSelector="{{AdminConfigAccessTokenExpirationSection.CheckIfTabExpand}}" visible="true" stepKey="expandTab"/> + <waitForAjaxLoad stepKey="waitForAjax"/> + <uncheckOption selector="{{AdminConfigAccessTokenExpirationSection.systemValueForTokenLifetime}}" stepKey="uncheckUseSystemValue"/> + <fillField selector="{{AdminConfigAccessTokenExpirationSection.valueForTokenLifetime}}" userInput="" stepKey="valueForTokenLifetime"/> + <uncheckOption selector="{{AdminConfigAccessTokenExpirationSection.systemValueForTokenLifetimeAdmin}}" stepKey="uncheckUseSystemValueAdmin"/> + <fillField selector="{{AdminConfigAccessTokenExpirationSection.valueForTokenLifetimeAdmin}}" userInput="" stepKey="valueForTokenLifetimeAdmin"/> + <actionGroup ref="AdminSaveConfigActionGroup" stepKey="saveConfig"/> + </test> +</tests> From 04aefed742087fbe1238bfb54ce45da2d4427d94 Mon Sep 17 00:00:00 2001 From: Oleh Usik <o.usik@atwix.com> Date: Mon, 24 Aug 2020 21:38:45 +0300 Subject: [PATCH 035/132] removed redundant action group --- .../AdminNavigateToPageGridActionGroup.xml | 19 ------------------- .../Test/Mftf/Test/AdminCreateCmsPageTest.xml | 2 +- .../Test/Mftf/Test/AdminDeleteCmsPageTest.xml | 2 +- ...MediaGalleryCmsUiUsedInPagesFilterTest.xml | 10 +++++----- 4 files changed, 7 insertions(+), 26 deletions(-) delete mode 100644 app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminNavigateToPageGridActionGroup.xml diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminNavigateToPageGridActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminNavigateToPageGridActionGroup.xml deleted file mode 100644 index 7dc68e7a5a891..0000000000000 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminNavigateToPageGridActionGroup.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?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="AdminNavigateToPageGridActionGroup"> - <annotations> - <description>Navigates to CMS page grid.</description> - </annotations> - - <amOnPage url="{{CmsPagesPage.url}}" stepKey="amOnPagePagesGrid"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateCmsPageTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateCmsPageTest.xml index 90da152e7a7b1..f82ae3eed5de6 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateCmsPageTest.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateCmsPageTest.xml @@ -25,7 +25,7 @@ <after> <actionGroup ref="AdminLogoutActionGroup" stepKey="adminLogout"/> </after> - <actionGroup ref="AdminNavigateToPageGridActionGroup" stepKey="navigateToCmsPageGrid" /> + <actionGroup ref="AdminOpenCMSPagesGridActionGroup" stepKey="navigateToCmsPageGrid" /> <actionGroup ref="CreateNewPageWithBasicValues" stepKey="createNewPageWithBasicValues" /> <actionGroup ref="SaveCmsPageActionGroup" stepKey="clickSaveCmsPageButton" /> <actionGroup ref="VerifyCreatedCmsPage" stepKey="verifyCmsPage" /> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminDeleteCmsPageTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminDeleteCmsPageTest.xml index 3687bb4fe5743..e80f6010b6c69 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminDeleteCmsPageTest.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminDeleteCmsPageTest.xml @@ -21,7 +21,7 @@ <before> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> - <actionGroup ref="AdminNavigateToPageGridActionGroup" stepKey="navigateToCmsPageGrid"/> + <actionGroup ref="AdminOpenCMSPagesGridActionGroup" stepKey="navigateToCmsPageGrid"/> <actionGroup ref="ClearFiltersAdminDataGridActionGroup" stepKey="clearGridSearchFilters"/> <actionGroup ref="CreateNewPageWithBasicValues" stepKey="createNewPageWithBasicValues"/> <actionGroup ref="SaveCmsPageActionGroup" stepKey="clickSaveCmsPageButton"/> diff --git a/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryCmsUiUsedInPagesFilterTest.xml b/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryCmsUiUsedInPagesFilterTest.xml index a6bfdb781a734..47f828d60a1b6 100644 --- a/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryCmsUiUsedInPagesFilterTest.xml +++ b/app/code/Magento/MediaGalleryCmsUi/Test/Mftf/Test/AdminMediaGalleryCmsUiUsedInPagesFilterTest.xml @@ -21,14 +21,14 @@ <before> <actionGroup ref="AdminLoginActionGroup" stepKey="login"/> </before> - + <actionGroup ref="AdminOpenCreateNewCMSPageActionGroup" stepKey="navigateToCreateNewPage"/> <actionGroup ref="FillOutCustomCMSPageContentActionGroup" stepKey="fillBasicPageDataForPageWithDefaultStore"> <argument name="title" value="Unique page title MediaGalleryUi"/> <argument name="content" value="MediaGalleryUI content"/> <argument name="identifier" value="test-page-1"/> </actionGroup> - + <actionGroup ref="AdminOpenMediaGalleryFromPageNoEditorActionGroup" stepKey="openMediaGalleryForPage"/> <waitForPageLoad stepKey="waitForPageLoad" /> <actionGroup ref="AdminEnhancedMediaGalleryUploadImageActionGroup" stepKey="uploadImage"> @@ -39,7 +39,7 @@ </actionGroup> <actionGroup ref="AdminMediaGalleryClickAddSelectedActionGroup" stepKey="clickAddSelectedContentImage"/> <click selector="{{CmsNewPagePageActionsSection.saveAndContinueEdit}}" stepKey="savePage"/> - + <actionGroup ref="AdminOpenStandaloneMediaGalleryActionGroup" stepKey="openStandaloneMediaGallery"/> <actionGroup ref="AdminEnhancedMediaGalleryExpandFilterActionGroup" stepKey="expandFilters"/> <actionGroup ref="AdminEnhancedMediaGallerySelectUsedInFilterActionGroup" stepKey="setUsedInFilter"> @@ -56,8 +56,8 @@ <argument name="imageName" value="{{ImageMetadata.title}}"/> </actionGroup> <actionGroup ref="AdminEnhancedMediaGalleryClickDeleteImagesButtonActionGroup" stepKey="clikDeleteSelectedButton"/> - - <actionGroup ref="AdminNavigateToPageGridActionGroup" stepKey="navigateToCmsPageGrid"/> + + <actionGroup ref="AdminOpenCMSPagesGridActionGroup" stepKey="navigateToCmsPageGrid"/> <actionGroup ref="AdminSearchCmsPageInGridByUrlKeyActionGroup" stepKey="findCreatedCmsPage"> <argument name="urlKey" value="test-page-1"/> </actionGroup> From 18d82a36fdf370fb45183011e49cdedb086b7325 Mon Sep 17 00:00:00 2001 From: Oleh Usik <o.usik@atwix.com> Date: Mon, 24 Aug 2020 22:06:38 +0300 Subject: [PATCH 036/132] use action group to go to customer account --- .../Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml | 3 +-- .../Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml | 3 +-- ...ontVerifyShoppingCartPersistenceUnderLongTermCookieTest.xml | 2 +- .../Mftf/Test/AdminCreateCreditMemoBankTransferPaymentTest.xml | 3 +-- .../Test/Mftf/Test/AdminCreateCreditMemoPartialRefundTest.xml | 3 +-- .../Mftf/Test/AdminCreateCreditMemoWithCashOnDeliveryTest.xml | 3 +-- .../Mftf/Test/AdminCreateCreditMemoWithPurchaseOrderTest.xml | 3 +-- .../Test/AssignCustomOrderStatusNotVisibleOnStorefrontTest.xml | 3 +-- .../Test/Mftf/Test/CreateInvoiceAndCheckInvoiceOrderTest.xml | 3 +-- .../Test/CreateInvoiceWithCashOnDeliveryPaymentMethodTest.xml | 3 +-- .../CreateInvoiceWithShipmentAndCheckInvoicedOrderTest.xml | 3 +-- .../Mftf/Test/CreateInvoiceWithZeroSubtotalCheckoutTest.xml | 3 +-- .../Sales/Test/Mftf/Test/StorefrontOrderPagerDisplayedTest.xml | 3 +-- .../Sales/Test/Mftf/Test/StorefrontOrderPagerIsAbsentTest.xml | 3 +-- 14 files changed, 14 insertions(+), 27 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml index f9e1326e474af..a519aac72d1b5 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml @@ -214,8 +214,7 @@ </assertEquals> <!-- Assert order total --> - <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="navigateToCustomerDashboardPage"/> - <waitForPageLoad stepKey="waitForCustomerDashboardPageLoad"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="navigateToCustomerDashboardPage"/> <see selector="{{StorefrontCustomerRecentOrdersSection.orderTotal}}" userInput="$613.23" stepKey="checkOrderTotalInStorefront"/> <!-- Go to Address Book --> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml index 81208da18373c..130e1ba6723ae 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml @@ -186,8 +186,7 @@ <argument name="productVar" value="$$createDownloadableProduct1$$"/> </actionGroup> - <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="amOnMyAccountDashboard1"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="amOnMyAccountDashboard1"/> <actionGroup ref="StorefrontClearCompareActionGroup" stepKey="clearComparedProducts1"/> </test> diff --git a/app/code/Magento/Persistent/Test/Mftf/Test/StorefrontVerifyShoppingCartPersistenceUnderLongTermCookieTest.xml b/app/code/Magento/Persistent/Test/Mftf/Test/StorefrontVerifyShoppingCartPersistenceUnderLongTermCookieTest.xml index 80ca7a2eb90c7..74460f40b37eb 100644 --- a/app/code/Magento/Persistent/Test/Mftf/Test/StorefrontVerifyShoppingCartPersistenceUnderLongTermCookieTest.xml +++ b/app/code/Magento/Persistent/Test/Mftf/Test/StorefrontVerifyShoppingCartPersistenceUnderLongTermCookieTest.xml @@ -131,7 +131,7 @@ <see selector="{{StorefrontMinicartSection.productCount}}" userInput="2" stepKey="miniCartContainsTwoProductForGuest"/> <!-- 10. Go to My Account section --> - <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="amOnCustomerAccountPage"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="amOnCustomerAccountPage"/> <seeInCurrentUrl url="{{StorefrontCustomerSignInPage.url}}" stepKey="redirectToCustomerAccountLoginPage"/> <seeElement selector="{{StorefrontCustomerSignInFormSection.customerLoginBlock}}" stepKey="checkSystemRequiresToLogIn"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoBankTransferPaymentTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoBankTransferPaymentTest.xml index c4656e394d349..ac91000ae8bc9 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoBankTransferPaymentTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoBankTransferPaymentTest.xml @@ -129,8 +129,7 @@ </actionGroup> <!-- Assert refunded Grand Total on frontend --> - <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="onAccountPage"/> - <waitForPageLoad stepKey="waitForPage"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="onAccountPage"/> <scrollTo selector="{{StorefrontCustomerResentOrdersSection.blockResentOrders}}" stepKey="scrollToResent"/> <click selector="{{StorefrontCustomerResentOrdersSection.viewOrder({$grabOrderId})}}" stepKey="clickOnOrder"/> <waitForPageLoad stepKey="waitForViewOrder"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoPartialRefundTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoPartialRefundTest.xml index eb3d4ad991915..bae07ae20c9a6 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoPartialRefundTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoPartialRefundTest.xml @@ -123,8 +123,7 @@ </actionGroup> <!-- Assert refunded Grand Total on frontend --> - <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="onAccountPage"/> - <waitForPageLoad stepKey="waitForPage"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="onAccountPage"/> <scrollTo selector="{{StorefrontCustomerResentOrdersSection.blockResentOrders}}" stepKey="scrollToResent"/> <click selector="{{StorefrontCustomerResentOrdersSection.viewOrder({$grabOrderId})}}" stepKey="clickOnOrder"/> <waitForPageLoad stepKey="waitForViewOrder"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithCashOnDeliveryTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithCashOnDeliveryTest.xml index 4383820ba6bee..c8d5682bd9b25 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithCashOnDeliveryTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithCashOnDeliveryTest.xml @@ -116,8 +116,7 @@ </actionGroup> <!-- Assert refunded Grand Total on frontend --> - <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="onAccountPage"/> - <waitForPageLoad stepKey="waitForPage"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="onAccountPage"/> <scrollTo selector="{{StorefrontCustomerResentOrdersSection.blockResentOrders}}" stepKey="scrollToResent"/> <click selector="{{StorefrontCustomerResentOrdersSection.viewOrder({$grabOrderId})}}" stepKey="clickOnOrder"/> <waitForPageLoad stepKey="waitForViewOrder"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithPurchaseOrderTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithPurchaseOrderTest.xml index 56399401b205e..7ba8cc28a4a15 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithPurchaseOrderTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithPurchaseOrderTest.xml @@ -115,8 +115,7 @@ </actionGroup> <!-- Assert refunded Grand Total on frontend --> - <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="onAccountPage"/> - <waitForPageLoad stepKey="waitForPage"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="onAccountPage"/> <scrollTo selector="{{StorefrontCustomerResentOrdersSection.blockResentOrders}}" stepKey="scrollToResent"/> <click selector="{{StorefrontCustomerResentOrdersSection.viewOrder({$grabOrderId})}}" stepKey="clickOnOrder"/> <waitForPageLoad stepKey="waitForViewOrder"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AssignCustomOrderStatusNotVisibleOnStorefrontTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AssignCustomOrderStatusNotVisibleOnStorefrontTest.xml index 885f019b864de..a5d210a9765ad 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AssignCustomOrderStatusNotVisibleOnStorefrontTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AssignCustomOrderStatusNotVisibleOnStorefrontTest.xml @@ -99,8 +99,7 @@ <waitForPageLoad stepKey="waitForCustomerLogin"/> <!-- Open My Orders --> - <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="goToCustomerDashboardPage"/> - <waitForPageLoad stepKey="waitForCustomerDashboardPageLoad"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="goToCustomerDashboardPage"/> <actionGroup ref="StorefrontCustomerGoToSidebarMenu" stepKey="goToMyOrdersPage"> <argument name="menu" value="My Orders"/> </actionGroup> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceAndCheckInvoiceOrderTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceAndCheckInvoiceOrderTest.xml index d0c1b51008684..b1ba83b85a69f 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceAndCheckInvoiceOrderTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceAndCheckInvoiceOrderTest.xml @@ -133,8 +133,7 @@ <waitForPageLoad stepKey="waitForCustomerLogin"/> <!-- Open My Account > My Orders --> - <amOnPage stepKey="goToMyAccountPage" url="{{StorefrontCustomerDashboardPage.url}}"/> - <waitForPageLoad stepKey="waitForPageLoad"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="goToMyAccountPage"/> <actionGroup ref="StorefrontCustomerGoToSidebarMenu" stepKey="goToSidebarMenu"> <argument name="menu" value="My Orders"/> </actionGroup> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithCashOnDeliveryPaymentMethodTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithCashOnDeliveryPaymentMethodTest.xml index e5cfd5dc4afa0..c36cf72418382 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithCashOnDeliveryPaymentMethodTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithCashOnDeliveryPaymentMethodTest.xml @@ -100,8 +100,7 @@ <waitForPageLoad stepKey="waitForCustomerLogin"/> <!-- Open My Account > My Orders --> - <amOnPage stepKey="goToMyAccountPage" url="{{StorefrontCustomerDashboardPage.url}}"/> - <waitForPageLoad stepKey="waitForPageLoad"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="goToMyAccountPage"/> <actionGroup ref="StorefrontCustomerGoToSidebarMenu" stepKey="goToSidebarMenu"> <argument name="menu" value="My Orders"/> </actionGroup> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithShipmentAndCheckInvoicedOrderTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithShipmentAndCheckInvoicedOrderTest.xml index 12b956be22cfb..cbf972faf2b65 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithShipmentAndCheckInvoicedOrderTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithShipmentAndCheckInvoicedOrderTest.xml @@ -124,8 +124,7 @@ <waitForPageLoad stepKey="waitForCustomerLogin"/> <!-- Open My Account > My Orders --> - <amOnPage stepKey="goToMyAccountPage" url="{{StorefrontCustomerDashboardPage.url}}"/> - <waitForPageLoad stepKey="waitForPageLoad"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="goToMyAccountPage"/> <actionGroup ref="StorefrontCustomerGoToSidebarMenu" stepKey="goToSidebarMenu"> <argument name="menu" value="My Orders"/> </actionGroup> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithZeroSubtotalCheckoutTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithZeroSubtotalCheckoutTest.xml index 780bffd359ba7..7209ee4e03842 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithZeroSubtotalCheckoutTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithZeroSubtotalCheckoutTest.xml @@ -107,8 +107,7 @@ <waitForPageLoad stepKey="waitForCustomerLogin"/> <!-- Open My Account > My Orders --> - <amOnPage stepKey="goToMyAccountPage" url="{{StorefrontCustomerDashboardPage.url}}"/> - <waitForPageLoad stepKey="waitForPageLoad"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="goToMyAccountPage"/> <actionGroup ref="StorefrontCustomerGoToSidebarMenu" stepKey="goToSidebarMenu"> <argument name="menu" value="My Orders"/> </actionGroup> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontOrderPagerDisplayedTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontOrderPagerDisplayedTest.xml index e99ffa95495ff..6b6b0b2ef4a16 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontOrderPagerDisplayedTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontOrderPagerDisplayedTest.xml @@ -213,8 +213,7 @@ <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="grabOrderNumber"/> <!-- Go to My Account > My Orders page --> - <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="onMyAccount"/> - <waitForPageLoad stepKey="waitForAccountPage"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="onMyAccount"/> <click selector="{{StorefrontCustomerSidebarSection.sidebarTab('My Orders')}}" stepKey="clickOnMyOrders"/> <waitForPageLoad stepKey="waitForOrdersLoad"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontOrderPagerIsAbsentTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontOrderPagerIsAbsentTest.xml index cba141e2ab271..9fba25688702d 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontOrderPagerIsAbsentTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontOrderPagerIsAbsentTest.xml @@ -199,8 +199,7 @@ <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="grabOrderNumber"/> <!-- Go to My Account > My Orders page --> - <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="onMyAccount"/> - <waitForPageLoad stepKey="waitForAccountPage"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="onMyAccount"/> <click selector="{{StorefrontCustomerSidebarSection.sidebarTab('My Orders')}}" stepKey="clickOnMyOrders"/> <waitForPageLoad stepKey="waitForOrdersLoad"/> From f7503ea597d79ed29b544daf169c7ced14ba42f9 Mon Sep 17 00:00:00 2001 From: "vadim.malesh" <engcom-vendorworker-charlie@adobe.com> Date: Thu, 27 Aug 2020 09:47:30 +0300 Subject: [PATCH 037/132] fix static --- app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php b/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php index 5ce512c249630..0cc108e5bed8b 100644 --- a/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php +++ b/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php @@ -22,7 +22,7 @@ * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) - * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * * @api * @since 100.0.2 From e912bdf9fe115d7f9cf48d41502d0d6d16713c08 Mon Sep 17 00:00:00 2001 From: Pieter Zandbergen <pmzandbergen@86id.nl> Date: Sun, 30 Aug 2020 13:59:18 +0200 Subject: [PATCH 038/132] Updated tests --- .../HTTP/Test/Unit/Client/CurlTest.php | 53 ++++++++++++ .../Test/Unit/Client/_files/curl_headers.txt | 5 ++ .../Test/Unit/ClientMock/CurlMockTest.php | 86 ------------------- .../Test/Unit/ClientMock/Mock/CurlMock.php | 41 --------- .../Unit/ClientMock/_files/curl_exec_mock.php | 22 ----- .../_files/curl_response_cookies.txt | 14 --- 6 files changed, 58 insertions(+), 163 deletions(-) create mode 100644 lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_headers.txt delete mode 100644 lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/CurlMockTest.php delete mode 100644 lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/Mock/CurlMock.php delete mode 100644 lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/_files/curl_exec_mock.php delete mode 100644 lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/_files/curl_response_cookies.txt diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/CurlTest.php b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/CurlTest.php index 17b88e398230e..22fed9cfc7467 100644 --- a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/CurlTest.php +++ b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/CurlTest.php @@ -26,4 +26,57 @@ public function testInvalidProtocol() $client = new Curl(); $client->get('telnet://127.0.0.1/test'); } + + /** + * Check the HTTP client ability to parse headers case-insensitive. + */ + public function testParseHeaders() + { + // Prepare protected parseHeaders method + $curl = new Curl(); + $parseHeaders = new \ReflectionMethod( + $curl, + 'parseHeaders' + ); + $parseHeaders->setAccessible(true); + + // Parse headers + foreach ($this->headersDataProvider() as $header) { + $parseHeaders->invoke($curl, null, $header); + } + + // Validate headers + $headers = $curl->getHeaders(); + $this->assertIsArray($headers); + $this->assertEquals([ + 'Content-Type' => 'text/html; charset=utf-8', + 'Set-Cookie' => [ + 'Normal=OK', + 'Uppercase=OK', + 'Lowercase=OK', + ] + ], $headers); + + // Validate status + $status = $curl->getStatus(); + $this->assertIsInt($status); + $this->assertEquals(200, $status); + + // Validate cookies + $cookies = $curl->getCookies(); + $this->assertIsArray($cookies); + $this->assertEquals([ + 'Normal' => 'OK', + 'Uppercase' => 'OK', + 'Lowercase' => 'OK', + ], $cookies); + } + + /** + * @return array + */ + public function headersDataProvider() + { + return array_filter(explode(PHP_EOL, file_get_contents(__DIR__ . '/_files/curl_headers.txt'))); + } } diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_headers.txt b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_headers.txt new file mode 100644 index 0000000000000..48a2d6fbcf0b7 --- /dev/null +++ b/lib/internal/Magento/Framework/HTTP/Test/Unit/Client/_files/curl_headers.txt @@ -0,0 +1,5 @@ +Status: 200 OK +Content-Type: text/html; charset=utf-8 +Set-Cookie: Normal=OK +SET-COOKIE: Uppercase=OK +set-cookie: Lowercase=OK diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/CurlMockTest.php b/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/CurlMockTest.php deleted file mode 100644 index bf386a2387d71..0000000000000 --- a/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/CurlMockTest.php +++ /dev/null @@ -1,86 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\Framework\HTTP\Test\Unit\ClientMock; - -use Magento\Framework\HTTP\Test\Unit\ClientMock\Mock\CurlMock; -use PHPUnit\Framework\TestCase; - -/** - * Test HTTP client based on cUrl (mocked curl_exec). - */ -class CurlMockTest extends TestCase -{ - /** - * @var CurlMock - */ - protected $model; - - /** - * @var \Closure - */ - public static $curlExectClosure; - - protected function setUp(): void - { - require_once __DIR__ . '/_files/curl_exec_mock.php'; - $this->model = new CurlMock(); - } - - /** - * Handle Curl response - * - * @param string $response - * @return string - */ - private function handleResponse(string $response): string - { - // Make sure we use valid newlines - $response = explode("\r\n\r\n", str_replace("\n", "\r\n", $response), 2); - - // Parse headers - $headers = explode("\r\n", $response[0]); - foreach ($headers as $header) { - call_user_func([$this->model, 'parseHeaders'], $this->model->getResource(), $header); - } - - // Return body - return $response[1] ?? ''; - } - - /** - * Check that HTTP client parses cookies. - * - * @param string $response - * @dataProvider cookiesDataProvider - */ - public function testCookies($response) - { - self::$curlExectClosure = function () use ($response) { - $this->handleResponse($response); - }; - $this->model->get('http://127.0.0.1/test'); - $cookies = $this->model->getCookies(); - $this->assertIsArray($cookies); - $this->assertEquals([ - 'Normal' => 'OK', - 'Uppercase' => 'OK', - 'Lowercase' => 'OK', - ], $cookies); - } - - /** - * @return array - */ - public function cookiesDataProvider() - { - return [ - [file_get_contents(__DIR__ . '/_files/curl_response_cookies.txt')], - ]; - } -} diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/Mock/CurlMock.php b/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/Mock/CurlMock.php deleted file mode 100644 index 03d786a7ec73c..0000000000000 --- a/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/Mock/CurlMock.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Framework\HTTP\Test\Unit\ClientMock\Mock; - -use Magento\Framework\HTTP\Client\Curl; - -/** - * Extended Curl class with modifications for testing - */ -class CurlMock extends Curl -{ - // @codingStandardsIgnoreStart - /** - * Unfortunately, it is necessary for the tests to set this function public. - * - * @param resource $ch curl handle, not needed - * @param string $data - * @return int - * @throws \Exception - */ - public function parseHeaders($ch, $data) - { - return parent::parseHeaders($ch, $data); - } - // @codingStandardsIgnoreEnd - - /** - * Return Curl resource, only used for testing. - * - * @return resource - */ - public function getResource() - { - return $this->_ch; - } -} diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/_files/curl_exec_mock.php b/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/_files/curl_exec_mock.php deleted file mode 100644 index 019f4889530d8..0000000000000 --- a/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/_files/curl_exec_mock.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Framework\HTTP\Client; - -use Magento\Framework\HTTP\Test\Unit\ClientMock\CurlMockTest; - -/** - * Override global PHP function - * - * @SuppressWarnings("unused") - * @param mixed $resource - * @return string - */ -function curl_exec($resource) -{ - return call_user_func(CurlMockTest::$curlExectClosure); -} diff --git a/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/_files/curl_response_cookies.txt b/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/_files/curl_response_cookies.txt deleted file mode 100644 index d68d286bb4de8..0000000000000 --- a/lib/internal/Magento/Framework/HTTP/Test/Unit/ClientMock/_files/curl_response_cookies.txt +++ /dev/null @@ -1,14 +0,0 @@ -HTTP/1.1 200 OK -Server: Apache -X-Frame-Options: SAMEORIGIN -Strict-Transport-Security: max-age=14400 -Strict-Transport-Security: max-age=14400 -Content-Type: text/html; charset=UTF-8 -Date: Mon, 22 Apr 2013 09:52:36 GMT -Content-Length: 8 -Connection: keep-alive -Set-Cookie: Normal=OK -SET-COOKIE: Uppercase=OK -set-cookie: Lowercase=OK - -VERIFIED From b3bab929a90f4c7a178fa1a61625a1866397ba97 Mon Sep 17 00:00:00 2001 From: Oleh Usik <o.usik@atwix.com> Date: Wed, 2 Sep 2020 13:07:29 +0300 Subject: [PATCH 039/132] Set Action Group as deprecation --- .../AdminNavigateToPageGridActionGroup.xml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminNavigateToPageGridActionGroup.xml diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminNavigateToPageGridActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminNavigateToPageGridActionGroup.xml new file mode 100644 index 0000000000000..93077d0d36128 --- /dev/null +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminNavigateToPageGridActionGroup.xml @@ -0,0 +1,20 @@ +<?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="AdminNavigateToPageGridActionGroup"> + <annotations> + <description>DEPRECATED. Use AdminOpenCMSPagesGridActionGroup instead. Navigates to CMS page grid.</description> + </annotations> + + + <amOnPage url="{{CmsPagesPage.url}}" stepKey="amOnPagePagesGrid"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + </actionGroup> +</actionGroups> From c09a26144f24548271e908efb4232baec079b92a Mon Sep 17 00:00:00 2001 From: Shankar Konar <konar.shankar2013@gmail.com> Date: Thu, 3 Sep 2020 11:39:31 +0530 Subject: [PATCH 040/132] Cover changes with Integration test --- .../Cms/Model/Wysiwyg/Images/StorageTest.php | 54 +++++++++++++------ 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Cms/Model/Wysiwyg/Images/StorageTest.php b/dev/tests/integration/testsuite/Magento/Cms/Model/Wysiwyg/Images/StorageTest.php index a68a546c20bc6..7baf52780e03c 100644 --- a/dev/tests/integration/testsuite/Magento/Cms/Model/Wysiwyg/Images/StorageTest.php +++ b/dev/tests/integration/testsuite/Magento/Cms/Model/Wysiwyg/Images/StorageTest.php @@ -7,6 +7,10 @@ namespace Magento\Cms\Model\Wysiwyg\Images; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Filesystem; +use Magento\Framework\Filesystem\Driver\File; +use Magento\Framework\Filesystem\DriverInterface; +use Magento\TestFramework\Helper\Bootstrap; /** * Test methods of class Storage @@ -29,22 +33,27 @@ class StorageTest extends \PHPUnit\Framework\TestCase private $objectManager; /** - * @var \Magento\Framework\Filesystem + * @var Filesystem */ private $filesystem; /** - * @var \Magento\Cms\Model\Wysiwyg\Images\Storage + * @var Storage */ private $storage; + /** + * @var DriverInterface + */ + private $driver; + /** * @inheritdoc */ // phpcs:disable public static function setUpBeforeClass(): void { - self::$_baseDir = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + self::$_baseDir = Bootstrap::getObjectManager()->get( \Magento\Cms\Helper\Wysiwyg\Images::class )->getCurrentPath() . 'MagentoCmsModelWysiwygImagesStorageTest'; if (!file_exists(self::$_baseDir)) { @@ -60,8 +69,8 @@ public static function setUpBeforeClass(): void // phpcs:ignore public static function tearDownAfterClass(): void { - \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Framework\Filesystem\Driver\File::class + Bootstrap::getObjectManager()->create( + File::class )->deleteDirectory( self::$_baseDir ); @@ -72,9 +81,10 @@ public static function tearDownAfterClass(): void */ protected function setUp(): void { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->filesystem = $this->objectManager->get(\Magento\Framework\Filesystem::class); - $this->storage = $this->objectManager->create(\Magento\Cms\Model\Wysiwyg\Images\Storage::class); + $this->objectManager = Bootstrap::getObjectManager(); + $this->filesystem = $this->objectManager->get(Filesystem::class); + $this->storage = $this->objectManager->create(Storage::class); + $this->driver = Bootstrap::getObjectManager()->get(DriverInterface::class); } /** @@ -83,17 +93,29 @@ protected function setUp(): void */ public function testGetFilesCollection(): void { - \Magento\TestFramework\Helper\Bootstrap::getInstance() + Bootstrap::getInstance() ->loadArea(\Magento\Backend\App\Area\FrontNameResolver::AREA_CODE); + $fileName = 'magento_image.jpg'; + $imagePath = realpath(__DIR__ . '/../../../../Catalog/_files/' . $fileName); + $mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); + $modifiableFilePath = $mediaDirectory->getAbsolutePath($fileName); + $this->driver->copy( + $imagePath, + $modifiableFilePath + ); $collection = $this->storage->getFilesCollection(self::$_baseDir, 'media'); $this->assertInstanceOf(\Magento\Cms\Model\Wysiwyg\Images\Storage\Collection::class, $collection); foreach ($collection as $item) { $this->assertInstanceOf(\Magento\Framework\DataObject::class, $item); - $this->assertStringEndsWith('/1.swf', $item->getUrl()); + $this->assertStringEndsWith('/' . $fileName, $item->getUrl()); $this->assertStringMatchesFormat( - 'http://%s/static/%s/adminhtml/%s/%s/Magento_Cms/images/placeholder_thumbnail.jpg', + 'http://%s/static/%s/adminhtml/%s/%s/Magento_Cms/images/magento_image.jpg', $item->getThumbUrl() ); + $this->assertEquals( + 'jpg', + $item->getMimeType() + ); return; } } @@ -121,7 +143,7 @@ public function testDeleteDirectory(): void $this->storage->createDirectory($dir, $path); $this->assertFileExists($fullPath); $this->storage->deleteDirectory($fullPath); - $this->assertFileNotExists($fullPath); + $this->assertFileDoesNotExist($fullPath); } /** @@ -142,7 +164,7 @@ public function testDeleteDirectoryWithExcludedDirPath(): void public function testUploadFile(): void { $fileName = 'magento_small_image.jpg'; - $tmpDirectory = $this->filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::SYS_TMP); + $tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::SYS_TMP); $filePath = $tmpDirectory->getAbsolutePath($fileName); // phpcs:disable $fixtureDir = realpath(__DIR__ . '/../../../../Catalog/_files'); @@ -172,7 +194,7 @@ public function testUploadFileWithExcludedDirPath(): void ); $fileName = 'magento_small_image.jpg'; - $tmpDirectory = $this->filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::SYS_TMP); + $tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::SYS_TMP); $filePath = $tmpDirectory->getAbsolutePath($fileName); // phpcs:disable $fixtureDir = realpath(__DIR__ . '/../../../../Catalog/_files'); @@ -204,7 +226,7 @@ public function testUploadFileWithWrongExtension(string $fileName, string $fileT $this->expectException(\Magento\Framework\Exception\LocalizedException::class); $this->expectExceptionMessage('File validation failed.'); - $tmpDirectory = $this->filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::SYS_TMP); + $tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::SYS_TMP); $filePath = $tmpDirectory->getAbsolutePath($fileName); // phpcs:disable $fixtureDir = realpath(__DIR__ . '/../../../_files'); @@ -251,7 +273,7 @@ public function testUploadFileWithWrongFile(): void $this->expectExceptionMessage('File validation failed.'); $fileName = 'file.gif'; - $tmpDirectory = $this->filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::SYS_TMP); + $tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::SYS_TMP); $filePath = $tmpDirectory->getAbsolutePath($fileName); // phpcs:disable $file = fopen($filePath, "wb"); From 1e6f09c35ef73e2481f6491271c9787b94afa8fa Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Fri, 4 Sep 2020 11:59:08 +0300 Subject: [PATCH 041/132] MC-36088: Non-relevant shipping method available for checkout --- .../Magento/Checkout/Model/ShippingInformationManagement.php | 5 ++++- app/code/Magento/Checkout/i18n/en_US.csv | 1 + .../web/template/shipping-address/shipping-method-item.html | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php index cbbbd9a9b4d01..f397a8ddc9cf1 100644 --- a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php +++ b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php @@ -209,8 +209,11 @@ public function saveAddressInformation( if (!$quote->getIsVirtual() && !$shippingAddress->getShippingRateByCode($shippingAddress->getShippingMethod()) ) { - throw new NoSuchEntityException( + $errorMessage = $methodCode ? __('Carrier with such method not found: %1, %2', $carrierCode, $methodCode) + : __('The shipping method is missing. Select the shipping method and try again.'); + throw new NoSuchEntityException( + $errorMessage ); } diff --git a/app/code/Magento/Checkout/i18n/en_US.csv b/app/code/Magento/Checkout/i18n/en_US.csv index 85ee4e1f03f0e..ca118f21f2441 100644 --- a/app/code/Magento/Checkout/i18n/en_US.csv +++ b/app/code/Magento/Checkout/i18n/en_US.csv @@ -185,3 +185,4 @@ Payment,Payment "Close","Close" "Show Cross-sell Items in the Shopping Cart","Show Cross-sell Items in the Shopping Cart" "You added %1 to your <a href=""%2"">shopping cart</a>.","You added %1 to your <a href=""%2"">shopping cart</a>." +"The shipping method is missing. Select the shipping method and try again.","The shipping method is missing. Select the shipping method and try again." diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/shipping-method-item.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/shipping-method-item.html index 11e419054582f..fd6be02657e3e 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/shipping-method-item.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/shipping-method-item.html @@ -15,9 +15,11 @@ attr="'aria-labelledby': 'label_method_' + method.method_code + '_' + method.carrier_code + ' ' + 'label_carrier_' + method.method_code + '_' + method.carrier_code, 'checked': element.rates().length == 1 || element.isSelected" /> </td> + <!-- ko ifnot: (method.error_message) --> <td class="col col-price"> <each args="element.getRegion('price')" render="" /> </td> + <!-- /ko --> <td class="col col-method" attr="'id': 'label_method_' + method.method_code + '_' + method.carrier_code" text="method.method_title" /> From 60c01638fe0f00d92184308eba1599cd58a74f6f Mon Sep 17 00:00:00 2001 From: Shankar Konar <konar.shankar2013@gmail.com> Date: Fri, 4 Sep 2020 15:44:15 +0530 Subject: [PATCH 042/132] Fixed Integration test --- .../Magento/Cms/Model/Wysiwyg/Images/StorageTest.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Cms/Model/Wysiwyg/Images/StorageTest.php b/dev/tests/integration/testsuite/Magento/Cms/Model/Wysiwyg/Images/StorageTest.php index 7baf52780e03c..448221503d7c9 100644 --- a/dev/tests/integration/testsuite/Magento/Cms/Model/Wysiwyg/Images/StorageTest.php +++ b/dev/tests/integration/testsuite/Magento/Cms/Model/Wysiwyg/Images/StorageTest.php @@ -98,22 +98,24 @@ public function testGetFilesCollection(): void $fileName = 'magento_image.jpg'; $imagePath = realpath(__DIR__ . '/../../../../Catalog/_files/' . $fileName); $mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); - $modifiableFilePath = $mediaDirectory->getAbsolutePath($fileName); + $modifiableFilePath = $mediaDirectory->getAbsolutePath('MagentoCmsModelWysiwygImagesStorageTest/' . $fileName); $this->driver->copy( $imagePath, $modifiableFilePath ); - $collection = $this->storage->getFilesCollection(self::$_baseDir, 'media'); + $this->storage->resizeFile($modifiableFilePath); + $collection = $this->storage->getFilesCollection(self::$_baseDir, 'image'); $this->assertInstanceOf(\Magento\Cms\Model\Wysiwyg\Images\Storage\Collection::class, $collection); foreach ($collection as $item) { $this->assertInstanceOf(\Magento\Framework\DataObject::class, $item); $this->assertStringEndsWith('/' . $fileName, $item->getUrl()); - $this->assertStringMatchesFormat( - 'http://%s/static/%s/adminhtml/%s/%s/Magento_Cms/images/magento_image.jpg', + $this->assertMatchesRegularExpression( + '/.thumbsMagentoCmsModelWysiwygImagesStorageTest/', + 'http://%s/pub/%s/.thumbsMagentoCmsModelWysiwygImagesStorageTest/magento_image.jpg', $item->getThumbUrl() ); $this->assertEquals( - 'jpg', + 'image/jpeg', $item->getMimeType() ); return; From 459fc2331762bdb7f5c9d84980d6980f712d5c99 Mon Sep 17 00:00:00 2001 From: "vadim.malesh" <engcom-vendorworker-charlie@adobe.com> Date: Fri, 4 Sep 2020 17:39:38 +0300 Subject: [PATCH 043/132] add testCaseId, change severity --- .../Test/Mftf/Test/AdminConfigSaveEmptySettingsTest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Integration/Test/Mftf/Test/AdminConfigSaveEmptySettingsTest.xml b/app/code/Magento/Integration/Test/Mftf/Test/AdminConfigSaveEmptySettingsTest.xml index ad1b27e7a0843..89a0fb4c1f026 100644 --- a/app/code/Magento/Integration/Test/Mftf/Test/AdminConfigSaveEmptySettingsTest.xml +++ b/app/code/Magento/Integration/Test/Mftf/Test/AdminConfigSaveEmptySettingsTest.xml @@ -13,7 +13,8 @@ <stories value="Save settings 'Access Token Expiration'."/> <title value="Save settings 'Access Token Expiration' with empty values."/> <description value="Save settings 'Customer Token Lifetime' and 'Admin Token Lifetime' with empty values without validations."/> - <severity value="MINOR"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-37382"/> <group value="configuration"/> </annotations> <before> From 36e4f44d0664f6184c15104fcfa40260886313c8 Mon Sep 17 00:00:00 2001 From: Roman Lytvynenko <lytvynen@adobe.com> Date: Fri, 4 Sep 2020 12:23:37 -0500 Subject: [PATCH 044/132] MC-37306: Sitemap generated by cron have wrong image URL (cache path) --- app/code/Magento/Sitemap/Model/Observer.php | 34 ++++++++++++++++----- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Sitemap/Model/Observer.php b/app/code/Magento/Sitemap/Model/Observer.php index ce74d738c4bc3..65e8597f3269b 100644 --- a/app/code/Magento/Sitemap/Model/Observer.php +++ b/app/code/Magento/Sitemap/Model/Observer.php @@ -5,10 +5,14 @@ */ namespace Magento\Sitemap\Model; +use Exception; use Magento\Sitemap\Model\EmailNotification as SitemapEmail; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Sitemap\Model\ResourceModel\Sitemap\Collection; use Magento\Sitemap\Model\ResourceModel\Sitemap\CollectionFactory; +use Magento\Store\Model\App\Emulation; use Magento\Store\Model\ScopeInterface; +use Magento\Framework\App\Area; /** * Sitemap module observer @@ -47,12 +51,12 @@ class Observer /** * Core store config * - * @var \Magento\Framework\App\Config\ScopeConfigInterface + * @var ScopeConfigInterface */ private $scopeConfig; /** - * @var \Magento\Sitemap\Model\ResourceModel\Sitemap\CollectionFactory + * @var CollectionFactory */ private $collectionFactory; @@ -61,27 +65,37 @@ class Observer */ private $emailNotification; + /** + * @var Emulation + */ + private $appEmulation; + /** * Observer constructor. * @param ScopeConfigInterface $scopeConfig * @param CollectionFactory $collectionFactory * @param EmailNotification $emailNotification + * @param Emulation $appEmulation */ public function __construct( ScopeConfigInterface $scopeConfig, CollectionFactory $collectionFactory, - SitemapEmail $emailNotification + SitemapEmail $emailNotification, + Emulation $appEmulation + ) { $this->scopeConfig = $scopeConfig; $this->collectionFactory = $collectionFactory; $this->emailNotification = $emailNotification; + $this->appEmulation = $appEmulation; + } /** * Generate sitemaps * * @return void - * @throws \Exception + * @throws Exception * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function scheduledGenerateSitemaps() @@ -101,12 +115,18 @@ public function scheduledGenerateSitemaps() } $collection = $this->collectionFactory->create(); - /* @var $collection \Magento\Sitemap\Model\ResourceModel\Sitemap\Collection */ + /* @var $collection Collection */ foreach ($collection as $sitemap) { - /* @var $sitemap \Magento\Sitemap\Model\Sitemap */ + /* @var $sitemap Sitemap */ try { + $this->appEmulation->startEnvironmentEmulation( + $sitemap->getStoreId(), + Area::AREA_FRONTEND, + true + ); $sitemap->generateXml(); - } catch (\Exception $e) { + $this->appEmulation->stopEnvironmentEmulation(); + } catch (Exception $e) { $errors[] = $e->getMessage(); } } From 99c59a2a703b3d1b68de29632bcc3528911dc13f Mon Sep 17 00:00:00 2001 From: Roman Lytvynenko <lytvynen@adobe.com> Date: Fri, 4 Sep 2020 15:10:22 -0500 Subject: [PATCH 045/132] MC-37306: Sitemap generated by cron have wrong image URL (cache path) --- app/code/Magento/Sitemap/Model/Observer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sitemap/Model/Observer.php b/app/code/Magento/Sitemap/Model/Observer.php index a87cb864532d9..4333c71c7497f 100644 --- a/app/code/Magento/Sitemap/Model/Observer.php +++ b/app/code/Magento/Sitemap/Model/Observer.php @@ -123,9 +123,10 @@ public function scheduledGenerateSitemaps() true ); $sitemap->generateXml(); - $this->appEmulation->stopEnvironmentEmulation(); } catch (\Exception $e) { $errors[] = $e->getMessage(); + } finally { + $this->appEmulation->stopEnvironmentEmulation(); } } if ($errors && $recipient) { From 6df880ab101645ded73a9bed0904f057987e3fb2 Mon Sep 17 00:00:00 2001 From: Oleh Usik <o.usik@atwix.com> Date: Sun, 6 Sep 2020 18:14:50 +0300 Subject: [PATCH 046/132] use right deprication tag --- .../ActionGroup/AdminNavigateToPageGridActionGroup.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminNavigateToPageGridActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminNavigateToPageGridActionGroup.xml index 93077d0d36128..6128db33a2afe 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminNavigateToPageGridActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminNavigateToPageGridActionGroup.xml @@ -8,13 +8,12 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminNavigateToPageGridActionGroup"> + <actionGroup name="AdminNavigateToPageGridActionGroup" deprecated="Use AdminOpenCMSPagesGridActionGroup instead."> <annotations> - <description>DEPRECATED. Use AdminOpenCMSPagesGridActionGroup instead. Navigates to CMS page grid.</description> + <description>Navigates to CMS page grid.</description> </annotations> - <amOnPage url="{{CmsPagesPage.url}}" stepKey="amOnPagePagesGrid"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> + <waitForPageLoad stepKey="waitForPageLoad"/> </actionGroup> </actionGroups> From 21f1eb357ce85f236f9af06ba3e429643ad28e3c Mon Sep 17 00:00:00 2001 From: Shankar Konar <konar.shankar2013@gmail.com> Date: Mon, 7 Sep 2020 10:38:09 +0530 Subject: [PATCH 047/132] Improved integration test --- .../Cms/Model/Wysiwyg/Images/StorageTest.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Cms/Model/Wysiwyg/Images/StorageTest.php b/dev/tests/integration/testsuite/Magento/Cms/Model/Wysiwyg/Images/StorageTest.php index 448221503d7c9..cb96ca2a14cac 100644 --- a/dev/tests/integration/testsuite/Magento/Cms/Model/Wysiwyg/Images/StorageTest.php +++ b/dev/tests/integration/testsuite/Magento/Cms/Model/Wysiwyg/Images/StorageTest.php @@ -6,7 +6,9 @@ */ namespace Magento\Cms\Model\Wysiwyg\Images; +use Magento\Cms\Model\Wysiwyg\Images\Storage\Collection; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\DataObject; use Magento\Framework\Filesystem; use Magento\Framework\Filesystem\Driver\File; use Magento\Framework\Filesystem\DriverInterface; @@ -105,18 +107,19 @@ public function testGetFilesCollection(): void ); $this->storage->resizeFile($modifiableFilePath); $collection = $this->storage->getFilesCollection(self::$_baseDir, 'image'); - $this->assertInstanceOf(\Magento\Cms\Model\Wysiwyg\Images\Storage\Collection::class, $collection); + $this->assertInstanceOf(Collection::class, $collection); foreach ($collection as $item) { - $this->assertInstanceOf(\Magento\Framework\DataObject::class, $item); + $this->assertInstanceOf(DataObject::class, $item); $this->assertStringEndsWith('/' . $fileName, $item->getUrl()); - $this->assertMatchesRegularExpression( - '/.thumbsMagentoCmsModelWysiwygImagesStorageTest/', - 'http://%s/pub/%s/.thumbsMagentoCmsModelWysiwygImagesStorageTest/magento_image.jpg', - $item->getThumbUrl() + $this->assertEquals( + '/pub/media/.thumbsMagentoCmsModelWysiwygImagesStorageTest/magento_image.jpg', + parse_url($item->getThumbUrl(), PHP_URL_PATH), + "Check if Thumbnail URL is equal to the generated URL" ); $this->assertEquals( 'image/jpeg', - $item->getMimeType() + $item->getMimeType(), + "Check if Mime Type is equal to the image in the file system" ); return; } From f898245488e4f199caae7e23f5b05433d0ff346e Mon Sep 17 00:00:00 2001 From: "vadim.malesh" <engcom-vendorworker-charlie@adobe.com> Date: Mon, 7 Sep 2020 12:26:53 +0300 Subject: [PATCH 048/132] fix unable to place order via paypal, test coverage --- .../Magento/Paypal/Model/Express/Checkout.php | 3 - .../Quote/Address/CollectTotalsObserver.php | 68 +++++---- .../Paypal/Model/Express/CheckoutTest.php | 38 ++++- .../Address/CollectTotalsObserverTest.php | 134 ++++++++++++------ 4 files changed, 158 insertions(+), 85 deletions(-) diff --git a/app/code/Magento/Paypal/Model/Express/Checkout.php b/app/code/Magento/Paypal/Model/Express/Checkout.php index 2b829086ac62e..389f20c757ae1 100644 --- a/app/code/Magento/Paypal/Model/Express/Checkout.php +++ b/app/code/Magento/Paypal/Model/Express/Checkout.php @@ -1159,9 +1159,6 @@ protected function prepareGuestQuote() ->setCustomerEmail($quote->getBillingAddress()->getEmail()) ->setCustomerIsGuest(true) ->setCustomerGroupId(\Magento\Customer\Model\Group::NOT_LOGGED_IN_ID); - if ($quote->getCustomer()->getEmail() === null) { - $quote->getCustomer()->setEmail($quote->getBillingAddress()->getEmail()); - } return $this; } } diff --git a/app/code/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserver.php b/app/code/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserver.php index a1228903e2323..c777887089b7e 100644 --- a/app/code/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserver.php +++ b/app/code/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserver.php @@ -5,7 +5,16 @@ */ namespace Magento\Quote\Observer\Frontend\Quote\Address; +use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\Customer\Api\Data\CustomerInterfaceFactory; +use Magento\Customer\Api\GroupManagementInterface; +use Magento\Customer\Helper\Address; +use Magento\Customer\Model\Session; +use Magento\Customer\Model\Vat; +use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; +use Magento\Quote\Api\Data\ShippingAssignmentInterface; +use Magento\Quote\Model\Quote; /** * Handle customer VAT number on collect_totals_before event of quote address. @@ -15,22 +24,22 @@ class CollectTotalsObserver implements ObserverInterface { /** - * @var \Magento\Customer\Api\AddressRepositoryInterface + * @var AddressRepositoryInterface */ private $addressRepository; /** - * @var \Magento\Customer\Model\Session + * @var Session */ private $customerSession; /** - * @var \Magento\Customer\Helper\Address + * @var Address */ protected $customerAddressHelper; /** - * @var \Magento\Customer\Model\Vat + * @var Vat */ protected $customerVat; @@ -40,36 +49,36 @@ class CollectTotalsObserver implements ObserverInterface protected $vatValidator; /** - * @var \Magento\Customer\Api\Data\CustomerInterfaceFactory + * @var CustomerInterfaceFactory */ protected $customerDataFactory; /** * Group Management * - * @var \Magento\Customer\Api\GroupManagementInterface + * @var GroupManagementInterface */ protected $groupManagement; /** * Initialize dependencies. * - * @param \Magento\Customer\Helper\Address $customerAddressHelper - * @param \Magento\Customer\Model\Vat $customerVat + * @param Address $customerAddressHelper + * @param Vat $customerVat * @param VatValidator $vatValidator - * @param \Magento\Customer\Api\Data\CustomerInterfaceFactory $customerDataFactory - * @param \Magento\Customer\Api\GroupManagementInterface $groupManagement - * @param \Magento\Customer\Api\AddressRepositoryInterface $addressRepository - * @param \Magento\Customer\Model\Session $customerSession + * @param CustomerInterfaceFactory $customerDataFactory + * @param GroupManagementInterface $groupManagement + * @param AddressRepositoryInterface $addressRepository + * @param Session $customerSession */ public function __construct( - \Magento\Customer\Helper\Address $customerAddressHelper, - \Magento\Customer\Model\Vat $customerVat, + Address $customerAddressHelper, + Vat $customerVat, VatValidator $vatValidator, - \Magento\Customer\Api\Data\CustomerInterfaceFactory $customerDataFactory, - \Magento\Customer\Api\GroupManagementInterface $groupManagement, - \Magento\Customer\Api\AddressRepositoryInterface $addressRepository, - \Magento\Customer\Model\Session $customerSession + CustomerInterfaceFactory $customerDataFactory, + GroupManagementInterface $groupManagement, + AddressRepositoryInterface $addressRepository, + Session $customerSession ) { $this->customerVat = $customerVat; $this->customerAddressHelper = $customerAddressHelper; @@ -83,25 +92,23 @@ public function __construct( /** * Handle customer VAT number if needed on collect_totals_before event of quote address * - * @param \Magento\Framework\Event\Observer $observer + * @param Observer $observer * @return void * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - public function execute(\Magento\Framework\Event\Observer $observer) + public function execute(Observer $observer) { - /** @var \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment */ + /** @var ShippingAssignmentInterface $shippingAssignment */ $shippingAssignment = $observer->getShippingAssignment(); - /** @var \Magento\Quote\Model\Quote $quote */ + /** @var Quote $quote */ $quote = $observer->getQuote(); - /** @var \Magento\Quote\Model\Quote\Address $address */ + /** @var Quote\Address $address */ $address = $shippingAssignment->getShipping()->getAddress(); $customer = $quote->getCustomer(); $storeId = $customer->getStoreId(); - if ($customer->getDisableAutoGroupChange() - || false == $this->vatValidator->isEnabled($address, $storeId) - ) { + if ($customer->getDisableAutoGroupChange() || !$this->vatValidator->isEnabled($address, $storeId)) { return; } $customerCountryCode = $address->getCountryId(); @@ -118,10 +125,10 @@ public function execute(\Magento\Framework\Event\Observer $observer) } $groupId = null; - if (empty($customerVatNumber) || false == $this->customerVat->isCountryInEU($customerCountryCode)) { - $groupId = $customer->getId() ? $this->groupManagement->getDefaultGroup( - $storeId - )->getId() : $this->groupManagement->getNotLoggedInGroup()->getId(); + if (empty($customerVatNumber) || !$this->customerVat->isCountryInEU($customerCountryCode)) { + $groupId = $customer->getId() + ? $this->groupManagement->getDefaultGroup($storeId)->getId() + : $this->groupManagement->getNotLoggedInGroup()->getId(); } else { // Magento always has to emulate group even if customer uses default billing/shipping address $groupId = $this->customerVat->getCustomerGroupIdBasedOnVatNumber( @@ -136,6 +143,7 @@ public function execute(\Magento\Framework\Event\Observer $observer) $quote->setCustomerGroupId($groupId); $this->customerSession->setCustomerGroupId($groupId); $customer->setGroupId($groupId); + $customer->setEmail($customer->getEmail() ?: $quote->getCustomerEmail()); $quote->setCustomer($customer); } } diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Model/Express/CheckoutTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Model/Express/CheckoutTest.php index c1ac7cf1ef723..13fcd53d78186 100644 --- a/dev/tests/integration/testsuite/Magento/Paypal/Model/Express/CheckoutTest.php +++ b/dev/tests/integration/testsuite/Magento/Paypal/Model/Express/CheckoutTest.php @@ -17,11 +17,13 @@ use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\ResourceModel\Quote\Collection; use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class CheckoutTest extends \PHPUnit\Framework\TestCase +class CheckoutTest extends TestCase { /** * @var ObjectManagerInterface @@ -29,22 +31,22 @@ class CheckoutTest extends \PHPUnit\Framework\TestCase private $objectManager; /** - * @var Info|\PHPUnit\Framework\MockObject\MockObject + * @var Info|MockObject */ private $paypalInfo; /** - * @var Config|\PHPUnit\Framework\MockObject\MockObject + * @var Config|MockObject */ private $paypalConfig; /** - * @var Factory|\PHPUnit\Framework\MockObject\MockObject + * @var Factory|MockObject */ private $apiTypeFactory; /** - * @var Nvp|\PHPUnit\Framework\MockObject\MockObject + * @var Nvp|MockObject */ private $api; @@ -215,6 +217,28 @@ public function testPlaceGuestQuote() $this->assertNotEmpty($order->getShippingAddress()); } + /** + * Place the order as guest when `Automatic Assignment to Customer Group` is enabled. + * + * @magentoDataFixture Magento/Paypal/_files/quote_express.php + * @magentoConfigFixture current_store customer/create_account/auto_group_assign 1 + * + * @return void + */ + public function testPlaceGuestQuoteAutomaticAssignmentEnabled(): void + { + $quote = $this->getFixtureQuote(); + $quote->setCheckoutMethod(Onepage::METHOD_GUEST); + $quote->getShippingAddress()->setSameAsBilling(0); + $quote->setReservedOrderId(null); + + $checkout = $this->getCheckout($quote); + $checkout->place('token'); + + $order = $checkout->getOrder(); + $this->assertNotEmpty($order->getRealOrderId()); + } + /** * @param Quote $quote * @return Checkout @@ -721,11 +745,11 @@ private function getFixtureQuote(): Quote /** * Adds countryFactory to a mock. * - * @param \PHPUnit\Framework\MockObject\MockObject $api + * @param MockObject $api * @return void * @throws \ReflectionException */ - private function addCountryFactory(\PHPUnit\Framework\MockObject\MockObject $api): void + private function addCountryFactory(MockObject $api): void { $reflection = new \ReflectionClass($api); $property = $reflection->getProperty('_countryFactory'); diff --git a/dev/tests/integration/testsuite/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserverTest.php b/dev/tests/integration/testsuite/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserverTest.php index f16986a3f2422..cb0c4b9ecdd2c 100644 --- a/dev/tests/integration/testsuite/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserverTest.php +++ b/dev/tests/integration/testsuite/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserverTest.php @@ -5,28 +5,43 @@ */ namespace Magento\Quote\Observer\Frontend\Quote\Address; +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Customer\Model\Customer; +use Magento\Customer\Model\CustomerRegistry; +use Magento\Customer\Model\Group; +use Magento\Framework\Event\Observer; +use Magento\Framework\ObjectManagerInterface; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\Quote\Address\Total; +use Magento\Quote\Model\Shipping; +use Magento\Quote\Model\ShippingAssignment; use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; -class CollectTotalsObserverTest extends \PHPUnit\Framework\TestCase +/** + * Test for \Magento\Quote\Observer\Frontend\Quote\Address\CollectTotalsObserver. + */ +class CollectTotalsObserverTest extends TestCase { + private const STUB_CUSTOMER_EMAIL = 'customer@example.com'; + /** - * @var \Magento\Quote\Observer\Frontend\Quote\Address\CollectTotalsObserver + * @var CollectTotalsObserver */ - protected $model; + private $model; /** - * Object Manager - * - * @var \Magento\Framework\ObjectManagerInterface + * @var ObjectManagerInterface */ private $objectManager; + /** + * @inheridoc + */ protected function setUp(): void { $this->objectManager = Bootstrap::getObjectManager(); - $this->model = $this->objectManager->create( - \Magento\Quote\Observer\Frontend\Quote\Address\CollectTotalsObserver::class - ); + $this->model = $this->objectManager->create(CollectTotalsObserver::class); } /** @@ -37,37 +52,37 @@ protected function setUp(): void * * @covers \Magento\Quote\Observer\Frontend\Quote\Address\CollectTotalsObserver::execute */ - public function testChangeQuoteCustomerGroupIdForCustomerWithDisabledAutomaticGroupChange() + public function testChangeQuoteCustomerGroupIdForCustomerWithDisabledAutomaticGroupChange(): void { - /** @var \Magento\Framework\ObjectManagerInterface $objectManager */ - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + /** @var ObjectManagerInterface $objectManager */ + $objectManager = Bootstrap::getObjectManager(); - /** @var $customer \Magento\Customer\Model\Customer */ - $customer = $objectManager->create(\Magento\Customer\Model\Customer::class); + /** @var $customer Customer */ + $customer = $objectManager->create(Customer::class); $customer->load(1); $customer->setDisableAutoGroupChange(1); $customer->setGroupId(2); $customer->save(); - /** @var \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository */ - $customerRepository = $objectManager->create(\Magento\Customer\Api\CustomerRepositoryInterface::class); + /** @var CustomerRepositoryInterface $customerRepository */ + $customerRepository = $objectManager->create(CustomerRepositoryInterface::class); $customerData = $customerRepository->getById($customer->getId()); - /** @var $quote \Magento\Quote\Model\Quote */ - $quote = $objectManager->create(\Magento\Quote\Model\Quote::class); + /** @var $quote Quote */ + $quote = $objectManager->create(Quote::class); $quote->load('test01', 'reserved_order_id'); $quote->setCustomer($customerData); $quoteAddress = $quote->getBillingAddress(); - $shippingAssignment = $this->objectManager->create(\Magento\Quote\Model\ShippingAssignment::class); - $shipping = $this->objectManager->create(\Magento\Quote\Model\Shipping::class); + $shippingAssignment = $this->objectManager->create(ShippingAssignment::class); + $shipping = $this->objectManager->create(Shipping::class); $shipping->setAddress($quoteAddress); $shippingAssignment->setShipping($shipping); - /** @var \Magento\Quote\Model\Quote\Address\Total $total */ - $total = $this->objectManager->create(\Magento\Quote\Model\Quote\Address\Total::class); + /** @var Total $total */ + $total = $this->objectManager->create(Total::class); $eventObserver = $objectManager->create( - \Magento\Framework\Event\Observer::class, + Observer::class, ['data' => [ 'quote' => $quote, 'shipping_assignment' => $shippingAssignment, @@ -88,51 +103,80 @@ public function testChangeQuoteCustomerGroupIdForCustomerWithDisabledAutomaticGr * * @covers \Magento\Quote\Observer\Frontend\Quote\Address\CollectTotalsObserver::execute */ - public function testChangeQuoteCustomerGroupIdForCustomerWithEnabledAutomaticGroupChange() + public function testChangeQuoteCustomerGroupIdForCustomerWithEnabledAutomaticGroupChange(): void { - /** @var \Magento\Framework\ObjectManagerInterface $objectManager */ - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + /** @var ObjectManagerInterface $objectManager */ + $objectManager = Bootstrap::getObjectManager(); - /** @var $customer \Magento\Customer\Model\Customer */ - $customer = $objectManager->create(\Magento\Customer\Model\Customer::class); + /** @var $customer Customer */ + $customer = $objectManager->create(Customer::class); $customer->load(1); $customer->setDisableAutoGroupChange(0); $customer->setGroupId(2); $customer->save(); - /** @var \Magento\Customer\Model\CustomerRegistry $customerRegistry */ - $customerRegistry = $objectManager->get(\Magento\Customer\Model\CustomerRegistry::class); + /** @var CustomerRegistry $customerRegistry */ + $customerRegistry = $objectManager->get(CustomerRegistry::class); $customerRegistry->remove($customer->getId()); - /** @var \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository */ - $customerRepository = $objectManager->create(\Magento\Customer\Api\CustomerRepositoryInterface::class); + /** @var CustomerRepositoryInterface $customerRepository */ + $customerRepository = $objectManager->create(CustomerRepositoryInterface::class); $customerData = $customerRepository->getById($customer->getId()); - /** @var $quote \Magento\Quote\Model\Quote */ - $quote = $objectManager->create(\Magento\Quote\Model\Quote::class); + /** @var $quote Quote */ + $quote = $objectManager->create(Quote::class); $quote->load('test01', 'reserved_order_id'); $quote->setCustomer($customerData); $quoteAddress = $quote->getBillingAddress(); - $shippingAssignment = $this->objectManager->create(\Magento\Quote\Model\ShippingAssignment::class); - $shipping = $this->objectManager->create(\Magento\Quote\Model\Shipping::class); + $shippingAssignment = $this->objectManager->create(ShippingAssignment::class); + $shipping = $this->objectManager->create(Shipping::class); $shipping->setAddress($quoteAddress); $shippingAssignment->setShipping($shipping); - /** @var \Magento\Quote\Model\Quote\Address\Total $total */ - $total = $this->objectManager->create(\Magento\Quote\Model\Quote\Address\Total::class); + /** @var Total $total */ + $total = $this->objectManager->create(Total::class); $eventObserver = $objectManager->create( - \Magento\Framework\Event\Observer::class, - ['data' => [ - 'quote' => $quote, - 'shipping_assignment' => $shippingAssignment, - 'total' => $total - ] - ] + Observer::class, + ['data' => ['quote' => $quote, 'shipping_assignment' => $shippingAssignment, 'total' => $total]] ); $this->model->execute($eventObserver); $this->assertEquals(1, $quote->getCustomer()->getGroupId()); } + + /** + * Dispatch event with guest quote and check that email will not be override to null when auto group assign enabled + * + * @magentoConfigFixture current_store customer/create_account/auto_group_assign 1 + * + * @return void + */ + public function testQuoteCustomerEmailNotChanged(): void + { + // prepare quote for guest + $quote = $this->objectManager->create(Quote::class); + $quote->setCustomerId(null) + ->setCustomerEmail(self::STUB_CUSTOMER_EMAIL) + ->setCustomerIsGuest(true) + ->setCustomerGroupId(Group::NOT_LOGGED_IN_ID); + + $quoteAddress = $quote->getBillingAddress(); + + $shippingAssignment = $this->objectManager->create(ShippingAssignment::class); + $shipping = $this->objectManager->create(Shipping::class); + $shipping->setAddress($quoteAddress); + $shippingAssignment->setShipping($shipping); + /** @var Total $total */ + $total = $this->objectManager->create(Total::class); + + $eventObserver = $this->objectManager->create( + Observer::class, + ['data' => ['quote' => $quote, 'shipping_assignment' => $shippingAssignment, 'total' => $total]] + ); + $this->model->execute($eventObserver); + + $this->assertEquals(self::STUB_CUSTOMER_EMAIL, $quote->getCustomerEmail()); + } } From 085c3317a0bf50ec3e605177568c2d1d253dbdd5 Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Mon, 7 Sep 2020 13:22:46 +0300 Subject: [PATCH 049/132] MC-36088: Non-relevant shipping method available for checkout --- .../Checkout/Test/Mftf/Data/ConfigData.xml | 7 +++ .../CheckoutShippingMethodsSection.xml | 1 + ...tForShowShippingMethodNoApplicableTest.xml | 63 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutForShowShippingMethodNoApplicableTest.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Data/ConfigData.xml b/app/code/Magento/Checkout/Test/Mftf/Data/ConfigData.xml index 9ab8a64c9ab88..216f01a95e890 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Data/ConfigData.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Data/ConfigData.xml @@ -81,6 +81,13 @@ <data key="label">All Allowed Countries</data> <data key="value">0</data> </entity> + <entity name="EnableFlatRateShowMethodNoApplicableConfigData"> + <data key="path">carriers/flatrate/showmethod</data> + <data key="scope">carriers</data> + <data key="scope_id">1</data> + <data key="label">Show Method if Not Applicable</data> + <data key="value">1</data> + </entity> <entity name="DisableFlatRateConfigData"> <data key="path">carriers/flatrate/active</data> <data key="scope">carriers</data> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml index 2f49e4f422a6e..233cc539e08a6 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingMethodsSection.xml @@ -20,5 +20,6 @@ <element name="shippingMethodLoader" type="button" selector="//div[contains(@class, 'checkout-shipping-method')]/following-sibling::div[contains(@class, 'loading-mask')]"/> <element name="freeShippingShippingMethod" type="input" selector="#s_method_freeshipping_freeshipping" timeout="30"/> <element name="noQuotesMsg" type="text" selector="#checkout-step-shipping_method div"/> + <element name="price" type="text" selector="//*[@id='checkout-shipping-method-load']//td[@class='col col-price']"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutForShowShippingMethodNoApplicableTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutForShowShippingMethodNoApplicableTest.xml new file mode 100644 index 0000000000000..22bc1260e5f33 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutForShowShippingMethodNoApplicableTest.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontCheckoutForShowShippingMethodNoApplicableTest"> + <annotations> + <stories value="Checkout for not applicable shipping method"/> + <title value="Storefront checkout for not applicable shipping method test"/> + <description value="Checkout flow if shipping rates are not applicable"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-37420"/> + <group value="checkout"/> + </annotations> + <before> + <!-- Create simple product --> + <createData entity="SimpleProduct2" stepKey="createProduct"/> + <!-- Enable flat rate shipping to specific country - Afghanistan --> + <magentoCLI command="config:set {{EnableFlatRateConfigData.path}} {{EnableFlatRateConfigData.value}}" stepKey="enableFlatRate"/> + <magentoCLI command="config:set {{EnableFlatRateToSpecificCountriesConfigData.path}} {{EnableFlatRateToSpecificCountriesConfigData.value}}" stepKey="allowFlatRateSpecificCountries"/> + <magentoCLI command="config:set {{EnableFlatRateToAfghanistanConfigData.path}} {{EnableFlatRateToAfghanistanConfigData.value}}" stepKey="enableFlatRateToAfghanistan"/> + <!-- Enable Show Method if Not Applicable--> + <magentoCLI command="config:set {{EnableFlatRateShowMethodNoApplicableConfigData.path}} {{EnableFlatRateShowMethodNoApplicableConfigData.value}}" stepKey="enableShowMethodNoApplicable"/> + <!-- Create Customer with filled Shipping & Billing Address --> + <createData entity="CustomerEntityOne" stepKey="createCustomer"/> + </before> + <after> + <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logoutFromStorefront"/> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + <magentoCLI command="config:set {{EnableFlatRateToAllAllowedCountriesConfigData.path}} {{EnableFlatRateToAllAllowedCountriesConfigData.value}}" stepKey="allowFlatRateToAllCountries"/> + <magentoCLI command="config:set {{EnableFlatRateShowMethodNoApplicableConfigData.path}} 0" stepKey="disableShowMethodNoApplicable"/> + <!-- Delete product --> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + </after> + <!-- Login with created Customer --> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginAsCustomer"> + <argument name="Customer" value="$$createCustomer$$"/> + </actionGroup> + <!-- Add product to cart --> + <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="openProductPage"> + <argument name="productUrlKey" value="$$createProduct.custom_attributes[url_key]$$"/> + </actionGroup> + <actionGroup ref="StorefrontAddProductToCartActionGroup" stepKey="addProductToCart"> + <argument name="product" value="$$createProduct$$"/> + <argument name="productCount" value="1"/> + </actionGroup> + <!-- Go to checkout page --> + <actionGroup ref="OpenStoreFrontCheckoutShippingPageActionGroup" stepKey="openCheckoutShippingPage"/> + <!-- Assert shipping price for US > California --> + <dontSeeElement selector="{{CheckoutShippingMethodsSection.price}}" stepKey="dontSeePrice"/> + <!-- Assert Next button is available --> + <seeElement selector="{{CheckoutShippingMethodsSection.next}}" stepKey="seeNextButton"/> + <click selector="{{CheckoutShippingMethodsSection.next}}" stepKey="clickNextButton"/> + <!-- Assert order cannot be placed and error message will shown. --> + <waitForPageLoad stepKey="waitForError"/> + <see stepKey="seeShippingMethodError" userInput="The shipping method is missing. Select the shipping method and try again."/> + </test> +</tests> From cffda9118a948ba47fceadf42eec8cb03078020a Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Mon, 7 Sep 2020 13:29:52 +0300 Subject: [PATCH 050/132] MC-36962: Create automated test for "Remove product added to shopping cart" --- ...ntCheckIsCartUpdatedAfterProductDelete.xml | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Test/StoreFrontCheckIsCartUpdatedAfterProductDelete.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StoreFrontCheckIsCartUpdatedAfterProductDelete.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StoreFrontCheckIsCartUpdatedAfterProductDelete.xml new file mode 100644 index 0000000000000..794f7566e62f6 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StoreFrontCheckIsCartUpdatedAfterProductDelete.xml @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StoreFrontCheckIsCartUpdatedAfterProductDelete"> + <annotations> + <stories value="Checkout"/> + <title value="Remove product added to shopping cart"/> + <description value="The product has to be deleted from shopping cart if it deleted in admin panel"/> + <testCaseId value="MC-36299"/> + <severity value="CRITICAL"/> + <group value="Shopping Cart"/> + </annotations> + <before> + <createData entity="Simple_US_Customer" stepKey="createCustomer"/> + <createData entity="SimpleProduct2" stepKey="createFirstProduct"> + <field key="price">10.00</field> + </createData> + <createData entity="SimpleProduct2" stepKey="createSecondProduct"> + <field key="price">20.00</field> + </createData> + </before> + <after> + <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logoutCustomer"/> + <deleteData createDataKey="createSecondProduct" stepKey="deleteSecondProduct"/> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + </after> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefront"> + <argument name="Customer" value="$createCustomer$"/> + </actionGroup> + <actionGroup ref="AddSimpleProductToCartActionGroup" stepKey="addFirstProductToCart"> + <argument name="product" value="$createFirstProduct$"/> + </actionGroup> + <actionGroup ref="AddSimpleProductToCartActionGroup" stepKey="addSecondProductToCart"> + <argument name="product" value="$createSecondProduct$"/> + </actionGroup> + <actionGroup ref="ClickViewAndEditCartFromMiniCartActionGroup" stepKey="selectViewAndEditCart"/> + <actionGroup ref="AssertStorefrontShoppingCartSummaryItemsActionGroup" stepKey="assertCartTotals"> + <argument name="subtotal" value="$30.00"/> + <argument name="total" value="$40.00"/> + </actionGroup> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <actionGroup ref="DeleteProductBySkuActionGroup" stepKey="deleteCreatedProduct"> + <argument name="sku" value="$createFirstProduct.sku$"/> + </actionGroup> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCheckoutPage"/> + <actionGroup ref="AssertStorefrontCheckoutCartItemsActionGroup" stepKey="assertCartAfterProductDeleted"> + <argument name="productName" value="$createSecondProduct.name$"/> + <argument name="productSku" value="$createSecondProduct.sku$"/> + <argument name="productPrice" value="$createSecondProduct.price$"/> + <argument name="subtotal" value="$createSecondProduct.price$" /> + <argument name="qty" value="1"/> + </actionGroup> + </test> +</tests> From a47c588134719f6e84f7dd3517c1f9cc0f849165 Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Mon, 7 Sep 2020 17:03:53 +0300 Subject: [PATCH 051/132] MC-36962: Create automated test for "Remove product added to shopping cart" --- ...CheckIsCartUpdatedAfterProductDeleteTest.xml} | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) rename app/code/Magento/Checkout/Test/Mftf/Test/{StoreFrontCheckIsCartUpdatedAfterProductDelete.xml => StorefrontCheckIsCartUpdatedAfterProductDeleteTest.xml} (85%) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StoreFrontCheckIsCartUpdatedAfterProductDelete.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckIsCartUpdatedAfterProductDeleteTest.xml similarity index 85% rename from app/code/Magento/Checkout/Test/Mftf/Test/StoreFrontCheckIsCartUpdatedAfterProductDelete.xml rename to app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckIsCartUpdatedAfterProductDeleteTest.xml index 794f7566e62f6..f4d1329e199e1 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StoreFrontCheckIsCartUpdatedAfterProductDelete.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckIsCartUpdatedAfterProductDeleteTest.xml @@ -7,14 +7,17 @@ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="StoreFrontCheckIsCartUpdatedAfterProductDelete"> + <test name="StorefrontCheckIsCartUpdatedAfterProductDeleteTest"> <annotations> - <stories value="Checkout"/> + <features value="Checkout"/> + <stories value="Delete Products from Shopping Cart"/> <title value="Remove product added to shopping cart"/> <description value="The product has to be deleted from shopping cart if it deleted in admin panel"/> <testCaseId value="MC-36299"/> + <useCaseId value="MAGETWO-83169"/> <severity value="CRITICAL"/> - <group value="Shopping Cart"/> + <group value="checkout"/> + <group value="catalog"/> </annotations> <before> <createData entity="Simple_US_Customer" stepKey="createCustomer"/> @@ -29,7 +32,7 @@ <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logoutCustomer"/> <deleteData createDataKey="createSecondProduct" stepKey="deleteSecondProduct"/> <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> - <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> </after> <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefront"> <argument name="Customer" value="$createCustomer$"/> @@ -46,10 +49,10 @@ <argument name="total" value="$40.00"/> </actionGroup> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> - <actionGroup ref="DeleteProductBySkuActionGroup" stepKey="deleteCreatedProduct"> + <actionGroup ref="DeleteProductBySkuActionGroup" stepKey="deleteFirstProduct"> <argument name="sku" value="$createFirstProduct.sku$"/> </actionGroup> - <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCheckoutPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToShoppingCartPage"/> <actionGroup ref="AssertStorefrontCheckoutCartItemsActionGroup" stepKey="assertCartAfterProductDeleted"> <argument name="productName" value="$createSecondProduct.name$"/> <argument name="productSku" value="$createSecondProduct.sku$"/> @@ -57,5 +60,6 @@ <argument name="subtotal" value="$createSecondProduct.price$" /> <argument name="qty" value="1"/> </actionGroup> + <dontSee selector="{{CheckoutCartProductSection.productName}}" userInput="$createFirstProduct.name$" stepKey="seeProductNameInCheckoutSummary"/> </test> </tests> From b8ce61b1572259f447fad11bc776735e777f3bc3 Mon Sep 17 00:00:00 2001 From: Oleh Usik <o.usik@atwix.com> Date: Mon, 7 Sep 2020 17:06:20 +0300 Subject: [PATCH 052/132] add AdminOpenCatalogProductPageActionGroup --- .../Mftf/Test/AdminAddBundleItemsTest.xml | 3 +-- .../Test/AdminAttributeSetSelectionTest.xml | 6 ++---- .../AdminBasicBundleProductAttributesTest.xml | 3 +-- .../Test/AdminDeleteABundleProductTest.xml | 4 +--- .../Test/BundleProductFixedPricingTest.xml | 3 +-- .../Test/NewBundleProductSelectionTest.xml | 3 +-- ...AdminOpenCatalogProductPageActionGroup.xml | 19 +++++++++++++++++++ .../GoToProductCatalogPageActionGroup.xml | 2 +- ...CreateSimpleProductSwitchToVirtualTest.xml | 4 ++-- ...nCreateNewAttributeFromProductPageTest.xml | 2 +- .../AdminMoveProductBetweenCategoriesTest.xml | 6 ++---- ...roductTypeSwitchingToSimpleProductTest.xml | 2 +- ...TypeSwitchingToDownloadableProductTest.xml | 2 +- .../Mftf/Test/AdminSortingByWebsitesTest.xml | 2 +- .../Mftf/Test/AdminVerifyProductOrderTest.xml | 2 +- ...oadableProductSwitchToConfigurableTest.xml | 4 ++-- ...oductTypeSwitchingToVirtualProductTest.xml | 2 +- ...TypeSwitchingToConfigurableProductTest.xml | 2 +- ...TypeSwitchingToConfigurableProductTest.xml | 2 +- .../ProductsQtyReturnAfterOrderCancelTest.xml | 4 ++-- ...TypeSwitchingToDownloadableProductTest.xml | 2 +- 21 files changed, 44 insertions(+), 35 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminOpenCatalogProductPageActionGroup.xml diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddBundleItemsTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddBundleItemsTest.xml index a79bd333499af..26119c5267d86 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddBundleItemsTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddBundleItemsTest.xml @@ -86,8 +86,7 @@ <!--Add another bundle option with 2 items--> <!--Go to bundle product creation page--> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="GoToCatalogProductPage"/> - <waitForPageLoad stepKey="WaitForPageToLoad"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToCatalogProductPage"/> <conditionalClick selector="{{AdminProductFiltersSection.filtersClear}}" dependentSelector="{{AdminProductFiltersSection.filtersClear}}" visible="true" stepKey="ClickOnButtonToRemoveFiltersIfPresent"/> <waitForPageLoad stepKey="WaitForClear"/> <actionGroup ref="FilterProductGridByNameActionGroup" stepKey="filterBundleProductOptionsDownToName"> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAttributeSetSelectionTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAttributeSetSelectionTest.xml index 33bfa455e2bdf..ca8a35ee7a363 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAttributeSetSelectionTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAttributeSetSelectionTest.xml @@ -54,8 +54,7 @@ <!--Testing that price appears correctly in admin catalog--> <!--Set filter to product name--> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="GoToCatalogProductPage"/> - <waitForPageLoad stepKey="WaitForPageToLoad"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToCatalogProductPage"/> <actionGroup ref="FilterProductGridByNameActionGroup" stepKey="filterBundleProductOptionsDownToName"> <argument name="product" value="BundleProduct"/> </actionGroup> @@ -75,8 +74,7 @@ <!--Testing that price appears correctly in admin catalog--> <!--Set filter to product name--> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="GoToCatalogProductPage2"/> - <waitForPageLoad stepKey="WaitForPageToLoad2"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToCatalogProductPage2"/> <actionGroup ref="FilterProductGridByNameActionGroup" stepKey="filterBundleProductOptionsDownToName2"> <argument name="product" value="BundleProduct"/> </actionGroup> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml index 41b372cf150a0..79d85c6ced957 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml @@ -96,8 +96,7 @@ </actionGroup> <!--Filter catalog--> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="goToCatalogProductPage"/> - <waitForPageLoad stepKey="WaitForPageToLoad"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToCatalogProductPage"/> <actionGroup ref="FilterProductGridByNameActionGroup" stepKey="filterBundleProductOptionsDownToName"> <argument name="product" value="BundleProduct"/> </actionGroup> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteABundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteABundleProductTest.xml index 66295e148b40d..83db83949f059 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteABundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteABundleProductTest.xml @@ -58,9 +58,7 @@ <actionGroup ref="AdminProductFormSaveActionGroup" stepKey="clickSaveButton"/> <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="messageYouSavedTheProductIsShown"/> - <!--Go to catalog deletion page--> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="goToCatalogPage"/> - <waitForPageLoad stepKey="Loading"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToCatalogPage"/> <!--Apply Name Filter--> <actionGroup ref="FilterProductGridByNameActionGroup" stepKey="filterBundleProductOptionsDownToName"> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/BundleProductFixedPricingTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/BundleProductFixedPricingTest.xml index b91f995b70ba7..d9ab2962964b2 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/BundleProductFixedPricingTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/BundleProductFixedPricingTest.xml @@ -76,8 +76,7 @@ <!--Testing that price appears correctly in admin catalog--> <!--Set filter to product name--> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="GoToCatalogProductPage"/> - <waitForPageLoad stepKey="WaitForPageToLoad"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToCatalogProductPage"/> <conditionalClick selector="{{AdminProductFiltersSection.filtersClear}}" dependentSelector="{{AdminProductFiltersSection.filtersClear}}" visible="true" stepKey="ClickOnButtonToRemoveFiltersIfPresent"/> <waitForPageLoad stepKey="WaitForClear"/> <actionGroup ref="FilterProductGridByNameActionGroup" stepKey="filterBundleProductOptionsDownToName"> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/NewBundleProductSelectionTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/NewBundleProductSelectionTest.xml index e722caaf090c5..f4b81e9ba9577 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/NewBundleProductSelectionTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/NewBundleProductSelectionTest.xml @@ -24,8 +24,7 @@ <after> <actionGroup ref="AdminLogoutActionGroup" stepKey="amOnLogoutPage"/> </after> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="GoToCatalogProductPage"/> - <waitForPageLoad stepKey="WaitForPageToLoad"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToCatalogProductPage"/> <!--Selecting new bundle product--> <actionGroup ref="GoToCreateProductPageActionGroup" stepKey="goToCreateBundleProduct"> <argument name="product" value="BundleProduct"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminOpenCatalogProductPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminOpenCatalogProductPageActionGroup.xml new file mode 100644 index 0000000000000..bb2191e190c29 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminOpenCatalogProductPageActionGroup.xml @@ -0,0 +1,19 @@ +<?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="AdminOpenCatalogProductPageActionGroup"> + <annotations> + <description>Open catalog product page.</description> + </annotations> + + <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="openCatalogProductPage"/> + <waitForPageLoad stepKey="waitForPageToLoad"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/GoToProductCatalogPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/GoToProductCatalogPageActionGroup.xml index 08bf948c2223b..7e64dd520844d 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/GoToProductCatalogPageActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/GoToProductCatalogPageActionGroup.xml @@ -8,7 +8,7 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="GoToProductCatalogPageActionGroup"> + <actionGroup name="GoToProductCatalogPageActionGroup" deprecated="Use AdminOpenCatalogProductPageActionGroup instead."> <annotations> <description>Goes to the Admin Products grid page.</description> </annotations> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateAndSwitchProductType/AdminCreateSimpleProductSwitchToVirtualTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateAndSwitchProductType/AdminCreateSimpleProductSwitchToVirtualTest.xml index 3c7900f37d36f..6e607ca012ba0 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateAndSwitchProductType/AdminCreateSimpleProductSwitchToVirtualTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateAndSwitchProductType/AdminCreateSimpleProductSwitchToVirtualTest.xml @@ -22,7 +22,7 @@ <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> </before> <after> - <actionGroup ref="GoToProductCatalogPageActionGroup" stepKey="goToProductCatalogPage"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToProductCatalogPage"/> <actionGroup ref="DeleteProductUsingProductGridActionGroup" stepKey="deleteSimpleProduct"> <argument name="product" value="_defaultProduct"/> </actionGroup> @@ -49,7 +49,7 @@ <actionGroup ref="SaveProductFormActionGroup" stepKey="saveProductForm"/> <!-- Check that product was added with implicit type change --> <comment stepKey="beforeVerify" userInput="Verify Product Type Assigned Correctly"/> - <actionGroup ref="GoToProductCatalogPageActionGroup" stepKey="goToProductCatalogPage"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToProductCatalogPage"/> <actionGroup ref="ResetProductGridToDefaultViewActionGroup" stepKey="resetSearch"/> <actionGroup ref="FilterProductGridByNameActionGroup" stepKey="searchForProduct"> <argument name="product" value="_defaultProduct"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateNewAttributeFromProductPageTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateNewAttributeFromProductPageTest.xml index e99643deed11d..52cac23574b53 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateNewAttributeFromProductPageTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateNewAttributeFromProductPageTest.xml @@ -26,7 +26,7 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> - <actionGroup ref="GoToProductCatalogPageActionGroup" stepKey="goToProductCatalogPage"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToProductCatalogPage"/> <actionGroup ref="GoToCreateProductPageActionGroup" stepKey="goToCreateProduct"> <argument name="product" value="SimpleProduct"/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveProductBetweenCategoriesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveProductBetweenCategoriesTest.xml index 059a3a321b16a..6e50c500036e3 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveProductBetweenCategoriesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveProductBetweenCategoriesTest.xml @@ -89,8 +89,7 @@ <see selector="{{AdminIndexManagementSection.successMessage}}" userInput="You saved the configuration." stepKey="seeMessage"/> <!-- Navigate to the Catalog > Products --> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="onCatalogProductPage"/> - <waitForPageLoad stepKey="waitForProductPage"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="onCatalogProductPage"/> <!-- Click on <product1>: Product page opens--> <actionGroup ref="FilterProductGridByNameActionGroup" stepKey="filterProduct"> @@ -160,8 +159,7 @@ <actionGroup ref="AdminLoginActionGroup" stepKey="LoginAdmin"/> <!-- Navigate to the Catalog > Products: Navigate to the Catalog>Products --> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="amOnProductPage"/> - <waitForPageLoad stepKey="waitForProductsPage"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="amOnProductPage"/> <!-- Click on <product1> --> <actionGroup ref="FilterAndSelectProductActionGroup" stepKey="openSimpleProduct"> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminDownloadableProductTypeSwitchingToSimpleProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminDownloadableProductTypeSwitchingToSimpleProductTest.xml index 6d7de64b47434..6cbf03a02f3b0 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminDownloadableProductTypeSwitchingToSimpleProductTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminDownloadableProductTypeSwitchingToSimpleProductTest.xml @@ -29,7 +29,7 @@ <actionGroup ref="SaveProductFormActionGroup" stepKey="saveProductForm"/> <!--Assert simple product on Admin product page grid--> <comment userInput="Assert simple product in Admin product page grid" stepKey="commentAssertProductOnAdmin"/> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="goToCatalogSimpleProductPage"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToCatalogSimpleProductPage"/> <actionGroup ref="FilterProductGridBySku2ActionGroup" stepKey="filterSimpleProductGridBySku"> <argument name="sku" value="$$createProduct.sku$$"/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminVirtualProductTypeSwitchingToDownloadableProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminVirtualProductTypeSwitchingToDownloadableProductTest.xml index de99933c78933..2311369db48f6 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminVirtualProductTypeSwitchingToDownloadableProductTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminVirtualProductTypeSwitchingToDownloadableProductTest.xml @@ -49,7 +49,7 @@ <actionGroup ref="SaveProductFormActionGroup" stepKey="saveDownloadableProductForm"/> <!--Assert downloadable product on Admin product page grid--> <comment userInput="Assert configurable product in Admin product page grid" stepKey="commentAssertDownloadableProductOnAdmin"/> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="goToCatalogProductPage"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToCatalogProductPage"/> <actionGroup ref="FilterProductGridBySku2ActionGroup" stepKey="filterProductGridBySku"> <argument name="sku" value="$$createProduct.sku$$"/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSortingByWebsitesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSortingByWebsitesTest.xml index f5fb33afd4617..73aeed3af4fb0 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSortingByWebsitesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSortingByWebsitesTest.xml @@ -42,7 +42,7 @@ <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteTestWebsite"> <argument name="websiteName" value="{{customWebsite.name}}"/> </actionGroup> - <actionGroup ref="GoToProductCatalogPageActionGroup" stepKey="goToProductCatalogPage"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToProductCatalogPage"/> <actionGroup ref="ResetProductGridToDefaultViewActionGroup" stepKey="resetProductGridColumnsInitial"/> <actionGroup ref="ResetWebUrlOptionsActionGroup" stepKey="resetUrlOption"/> <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminVerifyProductOrderTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminVerifyProductOrderTest.xml index 9146ee4d4d579..914e72d51e92a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminVerifyProductOrderTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminVerifyProductOrderTest.xml @@ -25,7 +25,7 @@ <after> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> - <actionGroup ref="GoToProductCatalogPageActionGroup" stepKey="goToProductCatalogPage"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToProductCatalogPage"/> <actionGroup ref="VerifyProductTypeOrder" stepKey="verifyProductTypeOrder"/> </test> </tests> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateAndSwitchProductType/AdminCreateDownloadableProductSwitchToConfigurableTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateAndSwitchProductType/AdminCreateDownloadableProductSwitchToConfigurableTest.xml index dc3608ec827df..17c7426dc547f 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateAndSwitchProductType/AdminCreateDownloadableProductSwitchToConfigurableTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateAndSwitchProductType/AdminCreateDownloadableProductSwitchToConfigurableTest.xml @@ -27,7 +27,7 @@ </createData> </before> <after> - <actionGroup ref="GoToProductCatalogPageActionGroup" stepKey="goToProductCatalogPage"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToProductCatalogPage"/> <actionGroup ref="DeleteProductUsingProductGridActionGroup" stepKey="deleteConfigurableProduct"> <argument name="product" value="_defaultProduct"/> </actionGroup> @@ -62,7 +62,7 @@ <actionGroup ref="SaveConfiguredProductActionGroup" stepKey="saveProductForm"/> <!-- Check that product was added with implicit type change --> <comment stepKey="beforeVerify" userInput="Verify Product Type Assigned Correctly"/> - <actionGroup ref="GoToProductCatalogPageActionGroup" stepKey="goToProductCatalogPage"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToProductCatalogPage"/> <actionGroup ref="ResetProductGridToDefaultViewActionGroup" stepKey="resetSearch"/> <actionGroup ref="FilterProductGridByNameActionGroup" stepKey="searchForProduct"> <argument name="product" value="_defaultProduct"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminConfigurableProductTypeSwitchingToVirtualProductTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminConfigurableProductTypeSwitchingToVirtualProductTest.xml index dd176455a03ba..f287aca332b48 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminConfigurableProductTypeSwitchingToVirtualProductTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminConfigurableProductTypeSwitchingToVirtualProductTest.xml @@ -36,7 +36,7 @@ <actionGroup ref="SaveProductFormActionGroup" stepKey="saveVirtualProductForm"/> <!--Assert virtual product on Admin product page grid--> <comment userInput="Assert virtual product on Admin product page grid" stepKey="commentAssertVirtualProductOnAdmin"/> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="goToCatalogProductPageForVirtual"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToCatalogProductPageForVirtual"/> <actionGroup ref="FilterProductGridBySku2ActionGroup" stepKey="filterProductGridBySkuForVirtual"> <argument name="sku" value="$createProduct.sku$"/> </actionGroup> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminSimpleProductTypeSwitchingToConfigurableProductTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminSimpleProductTypeSwitchingToConfigurableProductTest.xml index 14979f93ca423..f3b79765f746d 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminSimpleProductTypeSwitchingToConfigurableProductTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminSimpleProductTypeSwitchingToConfigurableProductTest.xml @@ -61,7 +61,7 @@ <actionGroup ref="SaveConfiguredProductActionGroup" stepKey="saveConfigProductForm"/> <!--Assert configurable product on Admin product page grid--> <comment userInput="Assert configurable product in Admin product page grid" stepKey="commentAssertConfigProductOnAdmin"/> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="goToCatalogProductPage"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToCatalogProductPage"/> <actionGroup ref="FilterProductGridBySku2ActionGroup" stepKey="filterProductGridBySku"> <argument name="sku" value="$createProduct.sku$"/> </actionGroup> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminVirtualProductTypeSwitchingToConfigurableProductTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminVirtualProductTypeSwitchingToConfigurableProductTest.xml index e986ea38f0fe1..bb5baf33d95fb 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminVirtualProductTypeSwitchingToConfigurableProductTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminVirtualProductTypeSwitchingToConfigurableProductTest.xml @@ -60,7 +60,7 @@ <actionGroup ref="SaveConfiguredProductActionGroup" stepKey="saveNewConfigurableProductForm"/> <!--Assert configurable product on Admin product page grid--> <comment userInput="Assert configurable product in Admin product page grid" stepKey="commentAssertConfigurableProductOnAdmin"/> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="goToCatalogProductPageForConfigurable"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToCatalogProductPageForConfigurable"/> <actionGroup ref="FilterProductGridBySku2ActionGroup" stepKey="filterProductGridBySkuForConfigurable"> <argument name="sku" value="$$createProduct.sku$$"/> </actionGroup> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml index 898e277cff55c..2c00f6e6528a9 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml @@ -35,7 +35,7 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="amOnLogoutPage"/> </after> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="GoToCatalogProductPage1"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToCatalogProductPage1"/> <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial"/> <actionGroup ref="OpenEditProductOnBackendActionGroup" stepKey="openEditProduct"> @@ -87,7 +87,7 @@ <see selector="{{AdminOrderItemsOrderedSection.itemQty('1')}}" userInput="Canceled 3" stepKey="seeCanceledQuantity"/> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="GoToCatalogProductPage"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToCatalogProductPage"/> <actionGroup ref="FilterProductGridBySku2ActionGroup" stepKey="filterProductGridBySku"> <argument name="sku" value="$$createConfigProduct.sku$$"/> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminSimpleProductTypeSwitchingToDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminSimpleProductTypeSwitchingToDownloadableProductTest.xml index 0f03a6a47c795..0237eca61b784 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminSimpleProductTypeSwitchingToDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminProductTypeSwitchingOnEditingTest/AdminSimpleProductTypeSwitchingToDownloadableProductTest.xml @@ -49,7 +49,7 @@ <actionGroup ref="SaveProductFormActionGroup" stepKey="saveDownloadableProductForm"/> <!--Assert downloadable product on Admin product page grid--> <comment userInput="Assert configurable product in Admin product page grid" stepKey="commentAssertDownloadableProductOnAdmin"/> - <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="goToCatalogProductPage"/> + <actionGroup ref="AdminOpenCatalogProductPageActionGroup" stepKey="goToCatalogProductPage"/> <actionGroup ref="FilterProductGridBySku2ActionGroup" stepKey="filterProductGridBySku"> <argument name="sku" value="$$createProduct.sku$$"/> </actionGroup> From 1900ffcddcd8e9d3817de7fea29496d69997d531 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <51681487+engcom-Foxtrot@users.noreply.github.com> Date: Mon, 7 Sep 2020 17:13:41 +0300 Subject: [PATCH 053/132] magento/magento2#25147: Totals Information Management - setting quote shipping method when address method is null. --- .../Model/TotalsInformationManagementTest.php | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 app/code/Magento/Checkout/Test/Unit/Model/TotalsInformationManagementTest.php diff --git a/app/code/Magento/Checkout/Test/Unit/Model/TotalsInformationManagementTest.php b/app/code/Magento/Checkout/Test/Unit/Model/TotalsInformationManagementTest.php new file mode 100644 index 0000000000000..c20e7599cfad4 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Unit/Model/TotalsInformationManagementTest.php @@ -0,0 +1,132 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Checkout\Test\Unit\Model; + +use Magento\Checkout\Api\Data\TotalsInformationInterface; +use Magento\Checkout\Model\TotalsInformationManagement; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Quote\Api\CartRepositoryInterface; +use Magento\Quote\Api\CartTotalRepositoryInterface; +use Magento\Quote\Model\Quote\Address; + +class TotalsInformationManagementTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var CartRepositoryInterface|\PHPUnit\Framework\MockObject\MockObject + */ + private $cartRepositoryMock; + + /** + * @var CartTotalRepositoryInterface|\PHPUnit\Framework\MockObject\MockObject + */ + private $cartTotalRepositoryMock; + + /** + * @var TotalsInformationManagement + */ + private $totalsInformationManagement; + + protected function setUp() + { + $this->objectManager = new ObjectManager($this); + $this->cartRepositoryMock = $this->createMock( + CartRepositoryInterface::class + ); + $this->cartTotalRepositoryMock = $this->createMock( + CartTotalRepositoryInterface::class + ); + + $this->totalsInformationManagement = $this->objectManager->getObject( + TotalsInformationManagement::class, + [ + 'cartRepository' => $this->cartRepositoryMock, + 'cartTotalRepository' => $this->cartTotalRepositoryMock, + ] + ); + } + + /** + * Test for \Magento\Checkout\Model\TotalsInformationManagement::calculate. + * + * @param string|null $carrierCode + * @param string|null $carrierMethod + * @param int $methodSetCount + * @dataProvider dataProviderCalculate + */ + public function testCalculate(?string $carrierCode, ?string $carrierMethod, int $methodSetCount) + { + $cartId = 1; + $cartMock = $this->createMock( + \Magento\Quote\Model\Quote::class + ); + $cartMock->expects($this->once())->method('getItemsCount')->willReturn(1); + $cartMock->expects($this->once())->method('getIsVirtual')->willReturn(false); + $this->cartRepositoryMock->expects($this->once())->method('get')->with($cartId)->willReturn($cartMock); + $this->cartTotalRepositoryMock->expects($this->once())->method('get')->with($cartId); + + $addressInformationMock = $this->createMock( + TotalsInformationInterface::class + ); + $addressMock = $this->createPartialMock( + Address::class, + [ + 'setShippingMethod', + 'setCollectShippingRates' + ] + ); + + $addressInformationMock->expects($this->once())->method('getAddress')->willReturn($addressMock); + $addressInformationMock->expects($this->any())->method('getShippingCarrierCode')->willReturn($carrierCode); + $addressInformationMock->expects($this->any())->method('getShippingMethodCode')->willReturn($carrierMethod); + $cartMock->expects($this->once())->method('setShippingAddress')->with($addressMock); + $cartMock->expects($this->exactly($methodSetCount))->method('getShippingAddress')->willReturn($addressMock); + $addressMock->expects($this->exactly($methodSetCount)) + ->method('setCollectShippingRates')->with(true)->willReturn($addressMock); + $addressMock->expects($this->exactly($methodSetCount)) + ->method('setShippingMethod')->with($carrierCode . '_' . $carrierMethod); + $cartMock->expects($this->once())->method('collectTotals'); + + $this->totalsInformationManagement->calculate($cartId, $addressInformationMock); + } + + /** + * Data provider for testCalculate. + * + * @return array + */ + public function dataProviderCalculate(): array + { + return [ + [ + null, + null, + 0 + ], + [ + null, + 'carrier_method', + 0 + ], + [ + 'carrier_code', + null, + 0 + ], + [ + 'carrier_code', + 'carrier_method', + 1 + ] + ]; + } +} From ae01dae651524c7a1f4cbe82bc9516d643a8dd8f Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Mon, 7 Sep 2020 18:14:35 +0300 Subject: [PATCH 054/132] MC-36962: Create automated test for "Remove product added to shopping cart" --- .../Test/StorefrontCheckIsCartUpdatedAfterProductDeleteTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckIsCartUpdatedAfterProductDeleteTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckIsCartUpdatedAfterProductDeleteTest.xml index f4d1329e199e1..8be86b19867e3 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckIsCartUpdatedAfterProductDeleteTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckIsCartUpdatedAfterProductDeleteTest.xml @@ -60,6 +60,6 @@ <argument name="subtotal" value="$createSecondProduct.price$" /> <argument name="qty" value="1"/> </actionGroup> - <dontSee selector="{{CheckoutCartProductSection.productName}}" userInput="$createFirstProduct.name$" stepKey="seeProductNameInCheckoutSummary"/> + <dontSee selector="{{CheckoutCartProductSection.productName}}" userInput="$createFirstProduct.name$" stepKey="checkFirstProductIsAbsentInCart"/> </test> </tests> From eb6e3e4f578a468630a889232423d2d792ff2460 Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Tue, 8 Sep 2020 10:22:18 +0300 Subject: [PATCH 055/132] MC-36962: Create automated test for "Remove product added to shopping cart" --- .../Test/StorefrontCheckIsCartUpdatedAfterProductDeleteTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckIsCartUpdatedAfterProductDeleteTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckIsCartUpdatedAfterProductDeleteTest.xml index 8be86b19867e3..fd6a1035a326a 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckIsCartUpdatedAfterProductDeleteTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckIsCartUpdatedAfterProductDeleteTest.xml @@ -60,6 +60,6 @@ <argument name="subtotal" value="$createSecondProduct.price$" /> <argument name="qty" value="1"/> </actionGroup> - <dontSee selector="{{CheckoutCartProductSection.productName}}" userInput="$createFirstProduct.name$" stepKey="checkFirstProductIsAbsentInCart"/> + <dontSee selector="{{CheckoutCartProductSection.productName}}" userInput="$createFirstProduct.name$" stepKey="checkFirstProductIsAbsentInCart"/> </test> </tests> From 832bb01549a2f3a7cb1fc96459c8930ce05634cb Mon Sep 17 00:00:00 2001 From: Oleh Usik <o.usik@atwix.com> Date: Tue, 8 Sep 2020 10:28:02 +0300 Subject: [PATCH 056/132] Changed description --- .../Mftf/ActionGroup/AdminOpenCatalogProductPageActionGroup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminOpenCatalogProductPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminOpenCatalogProductPageActionGroup.xml index bb2191e190c29..0e606b00d5913 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminOpenCatalogProductPageActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminOpenCatalogProductPageActionGroup.xml @@ -10,7 +10,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="AdminOpenCatalogProductPageActionGroup"> <annotations> - <description>Open catalog product page.</description> + <description>Open page with product grid.</description> </annotations> <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="openCatalogProductPage"/> From 80e375fe169a87fe144dff4a24f64cda83d8a944 Mon Sep 17 00:00:00 2001 From: Roman Lytvynenko <lytvynen@adobe.com> Date: Tue, 8 Sep 2020 08:04:52 -0500 Subject: [PATCH 057/132] MC-37306: Sitemap generated by cron have wrong image URL (cache path) --- .../Sitemap/Test/Unit/Model/ObserverTest.php | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php b/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php index 23ebe4f85f79e..e4407448ae15a 100644 --- a/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php +++ b/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php @@ -142,4 +142,36 @@ public function testScheduledGenerateSitemapsSendsExceptionEmail() $this->observer->scheduledGenerateSitemaps(); } + + /** + * Test if cron scheduled XML sitemap generation will start and stop the store environment emulation + * + * @throws \Exception + */ + public function testCronGenerateSitemapEnvironmentEmulation() + { + $storeId = 1; + + $this->scopeConfigMock->expects($this->once())->method('isSetFlag')->willReturn(true); + + $this->collectionFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->sitemapCollectionMock); + + $this->sitemapCollectionMock->expects($this->any()) + ->method('getIterator') + ->willReturn(new \ArrayIterator([$this->sitemapMock])); + + $this->sitemapMock->expects($this->at(0)) + ->method('getStoreId') + ->willReturn($storeId); + + $this->appEmulationMock->expects($this->once()) + ->method('startEnvironmentEmulation'); + + $this->appEmulationMock->expects($this->once()) + ->method('stopEnvironmentEmulation'); + + $this->observer->scheduledGenerateSitemaps(); + } } From 7f8db98f9b8ab85e510dd19ea4fe538397216877 Mon Sep 17 00:00:00 2001 From: SmVladyslav <vlatame.tsg@gmail.com> Date: Tue, 8 Sep 2020 17:56:39 +0300 Subject: [PATCH 058/132] MC-37393: Mass action is not deleted Default Billing and Shipping Address on admin Customer Page --- .../view/adminhtml/web/js/form/components/insert-listing.js | 4 +++- .../Magento/Customer/view/base/ui_component/customer_form.xml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/view/adminhtml/web/js/form/components/insert-listing.js b/app/code/Magento/Customer/view/adminhtml/web/js/form/components/insert-listing.js index 912d4b32130ec..aa8c199e4f261 100644 --- a/app/code/Magento/Customer/view/adminhtml/web/js/form/components/insert-listing.js +++ b/app/code/Magento/Customer/view/adminhtml/web/js/form/components/insert-listing.js @@ -62,7 +62,9 @@ define([ * @param {Object} data - customer address */ deleteMassaction: function (data) { - var ids = _.map(data, function (val) { + var ids = data.selected || this.selections().selected(); + + ids = _.map(ids, function (val) { return parseFloat(val); }); diff --git a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml index 78bbd612f5b70..065d87792665f 100644 --- a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml +++ b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml @@ -511,7 +511,7 @@ <imports>true</imports> </dataLinks> <externalProvider>customer_address_listing.customer_address_listing_data_source</externalProvider> - <selectionsProvider>customer_address_listing.customer_address_listing.customer_address_listing_columns.ids</selectionsProvider> + <selectionsProvider>customer_address_listing.customer_address_listing.customer_address_columns.ids</selectionsProvider> <autoRender>true</autoRender> <dataScope>customer_address_listing</dataScope> <ns>customer_address_listing</ns> From 8b338672bd7dcb62f41c85548616446a996b6779 Mon Sep 17 00:00:00 2001 From: SmVladyslav <vlatame.tsg@gmail.com> Date: Wed, 9 Sep 2020 10:07:35 +0300 Subject: [PATCH 059/132] MC-37393: Mass action is not deleted Default Billing and Shipping Address on admin Customer Page --- .../form/components/insert-listing.test.js | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 dev/tests/js/jasmine/tests/app/code/Magento/Customer/adminhtml/js/view/form/components/insert-listing.test.js diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Customer/adminhtml/js/view/form/components/insert-listing.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Customer/adminhtml/js/view/form/components/insert-listing.test.js new file mode 100644 index 0000000000000..cd8e7a83c0427 --- /dev/null +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Customer/adminhtml/js/view/form/components/insert-listing.test.js @@ -0,0 +1,66 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/* eslint-disable max-nested-callbacks */ +define(['Magento_Customer/js/form/components/insert-listing'], function (Constr) { + 'use strict'; + + describe('Magento_Customer/js/form/components/insert-listing', function () { + var obj, + ids = ['1', '2'], + data = { + action: 'delete', + data: { + selected: ids + } + }; + + beforeEach(function () { + obj = new Constr({}); + }); + + describe('Check delete massaction process', function () { + it('Check call to deleteMassaction method', function () { + obj.deleteMassaction = { + call: jasmine.createSpy() + }; + obj.onMassAction(data); + + expect(obj.deleteMassaction.call).toHaveBeenCalledWith(obj, { + selected: ids + }); + }); + + it('Check ids are retrieved from selections provider if they are NOT in data', function () { + var selectionsProvider = { + selected: jasmine.createSpy().and.returnValue(ids) + }; + + obj.selections = function () { // jscs:ignore jsDoc + return selectionsProvider; + }; + obj._delete = jasmine.createSpy(); + obj.onMassAction({ + action: 'delete', + data: {} + }); + + expect(selectionsProvider.selected).toHaveBeenCalled(); + expect(obj._delete).toHaveBeenCalledWith([1, 2]); + }); + + it('Check removal of default addresses', function () { + obj.source = { + get: jasmine.createSpy().and.returnValues(2, 3), + set: jasmine.createSpy() + }; + obj.onMassAction(data); + + expect(obj.source.get.calls.count()).toEqual(2); + expect(obj.source.set.calls.count()).toEqual(1); + }); + }); + }); +}); From b0e0517f8a570d9b98312f472ed147ab3b7331f3 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <51681487+engcom-Foxtrot@users.noreply.github.com> Date: Wed, 9 Sep 2020 10:56:07 +0300 Subject: [PATCH 060/132] magento/magento2#25147: Totals Information Management - setting quote shipping method when address method is null - unit test update. --- .../Model/TotalsInformationManagementTest.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Unit/Model/TotalsInformationManagementTest.php b/app/code/Magento/Checkout/Test/Unit/Model/TotalsInformationManagementTest.php index c20e7599cfad4..61049b4893476 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/TotalsInformationManagementTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/TotalsInformationManagementTest.php @@ -36,7 +36,7 @@ class TotalsInformationManagementTest extends \PHPUnit\Framework\TestCase */ private $totalsInformationManagement; - protected function setUp() + protected function setUp(): void { $this->objectManager = new ObjectManager($this); $this->cartRepositoryMock = $this->createMock( @@ -77,13 +77,15 @@ public function testCalculate(?string $carrierCode, ?string $carrierMethod, int $addressInformationMock = $this->createMock( TotalsInformationInterface::class ); - $addressMock = $this->createPartialMock( - Address::class, - [ - 'setShippingMethod', - 'setCollectShippingRates' - ] - ); + $addressMock = $this->getMockBuilder(Address::class) + ->addMethods( + [ + 'setShippingMethod', + 'setCollectShippingRates', + ] + ) + ->disableOriginalConstructor() + ->getMock(); $addressInformationMock->expects($this->once())->method('getAddress')->willReturn($addressMock); $addressInformationMock->expects($this->any())->method('getShippingCarrierCode')->willReturn($carrierCode); From e307834d818a440812c91a29940b550d803cdf70 Mon Sep 17 00:00:00 2001 From: mastiuhin-olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Wed, 9 Sep 2020 11:30:45 +0300 Subject: [PATCH 061/132] MC-34344: AdminLoginAfterJSMinificationTest does not properly enable minification --- .../Backend/Test/Mftf/Test/AdminLoginAfterJSMinificationTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Backend/Test/Mftf/Test/AdminLoginAfterJSMinificationTest.xml b/app/code/Magento/Backend/Test/Mftf/Test/AdminLoginAfterJSMinificationTest.xml index fb58b59b0ccaa..8e684868a1539 100644 --- a/app/code/Magento/Backend/Test/Mftf/Test/AdminLoginAfterJSMinificationTest.xml +++ b/app/code/Magento/Backend/Test/Mftf/Test/AdminLoginAfterJSMinificationTest.xml @@ -24,6 +24,7 @@ <actionGroup ref="CliCacheCleanActionGroup" stepKey="cleanCache"> <argument name="tags" value="config"/> </actionGroup> + <magentoCLI command="setup:static-content:deploy -f" stepKey="deployStaticContent"/> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> </before> <after> From b0179a9ee14501a65e7cbddac0bd6ce257f22d64 Mon Sep 17 00:00:00 2001 From: SmVladyslav <vlatame.tsg@gmail.com> Date: Wed, 9 Sep 2020 12:00:20 +0300 Subject: [PATCH 062/132] MC-37393: Mass action is not deleted Default Billing and Shipping Address on admin Customer Page --- .../form/components/insert-listing.test.js | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Customer/adminhtml/js/view/form/components/insert-listing.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Customer/adminhtml/js/view/form/components/insert-listing.test.js index cd8e7a83c0427..63ce265ac9001 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Customer/adminhtml/js/view/form/components/insert-listing.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Customer/adminhtml/js/view/form/components/insert-listing.test.js @@ -4,6 +4,7 @@ */ /* eslint-disable max-nested-callbacks */ +/*jscs:disable jsDoc*/ define(['Magento_Customer/js/form/components/insert-listing'], function (Constr) { 'use strict'; @@ -15,10 +16,18 @@ define(['Magento_Customer/js/form/components/insert-listing'], function (Constr) data: { selected: ids } + }, + selectionsProvider = { + selected: jasmine.createSpy().and.returnValue(ids) }; beforeEach(function () { - obj = new Constr({}); + obj = new Constr({ + name: 'content_name', + selections: function () { + return selectionsProvider; + } + }); }); describe('Check delete massaction process', function () { @@ -34,13 +43,6 @@ define(['Magento_Customer/js/form/components/insert-listing'], function (Constr) }); it('Check ids are retrieved from selections provider if they are NOT in data', function () { - var selectionsProvider = { - selected: jasmine.createSpy().and.returnValue(ids) - }; - - obj.selections = function () { // jscs:ignore jsDoc - return selectionsProvider; - }; obj._delete = jasmine.createSpy(); obj.onMassAction({ action: 'delete', @@ -48,6 +50,7 @@ define(['Magento_Customer/js/form/components/insert-listing'], function (Constr) }); expect(selectionsProvider.selected).toHaveBeenCalled(); + selectionsProvider.selected.calls.reset(); expect(obj._delete).toHaveBeenCalledWith([1, 2]); }); @@ -58,6 +61,7 @@ define(['Magento_Customer/js/form/components/insert-listing'], function (Constr) }; obj.onMassAction(data); + expect(selectionsProvider.selected).not.toHaveBeenCalled(); expect(obj.source.get.calls.count()).toEqual(2); expect(obj.source.set.calls.count()).toEqual(1); }); From 1f6e82fede343e6e239aaedc854ea6d63317272c Mon Sep 17 00:00:00 2001 From: "taras.gamanov" <engcom-vendorworker-hotel@adobe.com> Date: Wed, 9 Sep 2020 13:44:06 +0300 Subject: [PATCH 063/132] Fix for multiselect with search on grid. --- .../Test/AdminGridSearchSelectAllTest.xml | 57 +++++++++++++++++++ .../base/web/js/grid/columns/multiselect.js | 10 +++- 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Ui/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml diff --git a/app/code/Magento/Ui/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml b/app/code/Magento/Ui/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml new file mode 100644 index 0000000000000..8498ad7646ef0 --- /dev/null +++ b/app/code/Magento/Ui/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminGridSearchSelectAllTest"> + <annotations> + <stories value="Selection should be removed during search."/> + <title value="Selection should be removed during search."/> + <description value="Empty selected before and after search, like it works for filter"/> + <testCaseId value=""/> + <severity value="CRITICAL"/> + <group value="uI"/> + </annotations> + <before> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <!--Create three customers--> + <createData entity="Simple_US_Customer" stepKey="firstCustomer"/> + <createData entity="Simple_US_Customer" stepKey="secondCustomer"/> + <createData entity="Simple_US_Customer" stepKey="thirdCustomer"/> + </before> + <after> + <!--Remove two created customers, third already deleted--> + <deleteData createDataKey="firstCustomer" stepKey="deleteFirstCustomer"/> + <deleteData createDataKey="secondCustomer" stepKey="deleteSecondCustomer"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + </after> + <amOnPage url="{{AdminCustomerPage.url}}" stepKey="openCustomerPage"/> + <!-- search Admin Data Grid By Keyword --> + <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clickClearFilters"/> + <fillField selector="{{AdminDataGridHeaderSection.search}}" userInput="$$secondCustomer.email$$" stepKey="fillKeywordSearchFieldWithSecondCustomerEmail"/> + <click selector="{{AdminDataGridHeaderSection.submitSearch}}" stepKey="clickKeywordSearch"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <!-- Check select all action --> + <actionGroup ref="AdminSelectAllCustomers" stepKey="selectAllCustomers"/> + <seeCheckboxIsChecked selector="{{AdminCustomerGridMainActionsSection.customerCheckbox($$secondCustomer.email$$)}}" stepKey="checkSecondCustomerIsCheckedAfterSelectAll"/> + <!-- Clear searching By Keyword--> + <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clickClearFiltersAfterSearch"/> + <waitForPageLoad stepKey="waitForPageLoadAfterSearchRemoved"/> + <!-- Check if selection has bee removed --> + <dontSeeCheckboxIsChecked selector="{{AdminCustomerGridMainActionsSection.customerCheckbox($$secondCustomer.email$$)}}" stepKey="checkSecondCustomerCheckboxIsUnchecked"/> + <!-- Check delete action --> + <click selector="{{AdminCustomerGridMainActionsSection.customerCheckbox(($$thirdCustomer.email$$)}}" stepKey="selectThirdCustomer"/> + <seeCheckboxIsChecked selector="{{AdminCustomerGridMainActionsSection.customerCheckbox($$thirdCustomer.email$$)}}" stepKey="checkThirdCustomerIsChecked"/> + <!-- Use delete action for selected --> + <click selector="{{AdminCustomerGridMainActionsSection.actions}}" stepKey="clickActions"/> + <click selector="{{AdminCustomerGridMainActionsSection.delete}}" stepKey="clickDelete"/> + <waitForAjaxLoad stepKey="waitForLoadConfirmation"/> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmDelete"/> + <!-- Check if only one record record has been deleted --> + <see selector="{{AdminMessagesSection.success}}" userInput="A total of 1 record(s) were deleted" stepKey="seeSuccess"/> + </test> +</tests> diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js index ba0f4d25c25a4..4edd71bdc4906 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js @@ -52,6 +52,7 @@ define([ listens: { '${ $.provider }:params.filters': 'onFilter', + '${ $.provider }:params.search': 'onSearch', selected: 'onSelectedChange', rows: 'onRowsChange' }, @@ -235,7 +236,7 @@ define([ * @returns {Multiselect} Chainable. */ togglePage: function () { - return this.isPageSelected() ? this.deselectPage() : this.selectPage(); + return this.isPageSelected() && !this.excluded().length ? this.deselectPage() : this.selectPage(); }, /** @@ -496,6 +497,13 @@ define([ if (!this.preserveSelectionsOnFilter) { this.deselectAll(); } + }, + + /** + * Is invoked when search is applied or removed + */ + onSearch: function () { + this.onFilter(); } }); }); From 2e8a9aa02157a50300a21167b4dfcffc728be935 Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Wed, 9 Sep 2020 14:34:23 +0300 Subject: [PATCH 064/132] MC-36088: Non-relevant shipping method available for checkout --- app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js index fe8d7782e5eae..ff652e1e6e7a9 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js @@ -282,7 +282,7 @@ define([ option = _.isObject(this.countryOptions) && this.countryOptions[quote.shippingAddress().countryId], messageContainer = registry.get('checkout.errors').messageContainer; - if (!quote.shippingMethod()) { + if (!quote.shippingMethod() || !quote.shippingMethod()['method_code']) { this.errorValidationMessage( $t('The shipping method is missing. Select the shipping method and try again.') ); From 72db9daac8bbd68754dcdfdd8e6aad2ec7bacc06 Mon Sep 17 00:00:00 2001 From: Roman Lytvynenko <lytvynen@adobe.com> Date: Wed, 9 Sep 2020 08:08:31 -0500 Subject: [PATCH 065/132] MC-37306: Sitemap generated by cron have wrong image URL (cache path) --- app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php b/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php index e4407448ae15a..70520862faee1 100644 --- a/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php +++ b/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php @@ -166,6 +166,9 @@ public function testCronGenerateSitemapEnvironmentEmulation() ->method('getStoreId') ->willReturn($storeId); + $this->sitemapMock->expects($this->once()) + ->method('generateXml'); + $this->appEmulationMock->expects($this->once()) ->method('startEnvironmentEmulation'); From 3dd3bb94a174c8bd4f87f9ee6b617009b38d2ca4 Mon Sep 17 00:00:00 2001 From: Oleh Usik <o.usik@atwix.com> Date: Wed, 9 Sep 2020 17:13:09 +0300 Subject: [PATCH 066/132] Add AdminClickInvoiceButtonIntoOrderActionGroup --- .../Test/AdminDashboardWithChartsTest.xml | 3 +-- ...tedProductToConfigurableOutOfStockTest.xml | 3 +-- .../ProductsQtyReturnAfterOrderCancelTest.xml | 3 +-- .../CancelOrdersInOrderSalesReportTest.xml | 3 +-- ...ClickInvoiceButtonIntoOrderActionGroup.xml | 20 +++++++++++++++++++ .../GoToInvoiceIntoOrderActionGroup.xml | 2 +- ...tCreateInvoiceFromOrderPageActionGroup.xml | 2 +- .../Test/Mftf/Test/AdminCreateInvoiceTest.xml | 3 +-- .../CreateInvoiceAndCheckInvoiceOrderTest.xml | 2 +- ...iceWithCashOnDeliveryPaymentMethodTest.xml | 2 +- ...eWithShipmentAndCheckInvoicedOrderTest.xml | 2 +- ...ateInvoiceWithZeroSubtotalCheckoutTest.xml | 2 +- ...editMemoTotalAfterShippingDiscountTest.xml | 3 +-- 13 files changed, 32 insertions(+), 18 deletions(-) create mode 100644 app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminClickInvoiceButtonIntoOrderActionGroup.xml diff --git a/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsTest.xml b/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsTest.xml index 439b6ac063618..968a11600ef48 100644 --- a/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsTest.xml +++ b/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsTest.xml @@ -84,8 +84,7 @@ <comment userInput="Create invoice" stepKey="createInvoice"/> <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceButton"/> - <waitForPageLoad stepKey="waitForInvoicePageToLoad"/> + <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoiceButton"/> <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seeNewInvoiceInPageTitle" after="clickInvoiceButton"/> <see selector="{{AdminInvoiceTotalSection.total('Subtotal')}}" userInput="$150.00" stepKey="seeCorrectGrandTotal"/> <actionGroup ref="AdminInvoiceClickSubmitActionGroup" stepKey="clickSubmitInvoice"/> diff --git a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml index f1c01919d52f1..1f5a1df7b1186 100644 --- a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml +++ b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml @@ -125,8 +125,7 @@ <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask4"/> <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoice"/> - <waitForPageLoad stepKey="waitForNewInvoicePageToLoad"/> + <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoice"/> <actionGroup ref="AdminInvoiceClickSubmitActionGroup" stepKey="clickSubmitInvoice"/> <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The invoice has been created." stepKey="seeSuccessMessage"/> <click selector="{{AdminOrderDetailsMainActionsSection.ship}}" stepKey="clickShip"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml index 898e277cff55c..b96c5b446fd44 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml @@ -70,8 +70,7 @@ </actionGroup> <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceButton"/> - <waitForPageLoad stepKey="waitForNewInvoicePageLoad"/> + <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoiceButton"/> <fillField selector="{{AdminInvoiceItemsSection.qtyToInvoiceColumn}}" userInput="1" stepKey="ChangeQtyToInvoice"/> <click selector="{{AdminInvoiceItemsSection.updateQty}}" stepKey="updateQuantity"/> <waitForPageLoad stepKey="waitPageToBeLoaded"/> diff --git a/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml b/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml index 3e79eb044b5cb..0307e21667cc4 100644 --- a/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml +++ b/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml @@ -47,8 +47,7 @@ <argument name="customer" value="$$createCustomer$$"/> </actionGroup> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceAction"/> - <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seePageNameNewInvoicePage"/> + <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoiceAction"/> <actionGroup ref="AdminInvoiceClickSubmitActionGroup" stepKey="clickSubmitInvoice"/> <click selector="{{AdminOrderDetailsMainActionsSection.ship}}" stepKey="clickShipAction"/> <seeInCurrentUrl url="{{AdminShipmentNewPage.url}}" stepKey="seeOrderShipmentUrl"/> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminClickInvoiceButtonIntoOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminClickInvoiceButtonIntoOrderActionGroup.xml new file mode 100644 index 0000000000000..d4a1c2c19b1e6 --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminClickInvoiceButtonIntoOrderActionGroup.xml @@ -0,0 +1,20 @@ +<?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="AdminClickInvoiceButtonIntoOrderActionGroup"> + <annotations> + <description>Click 'Invoice' button on the order view page.</description> + </annotations> + + <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceAction"/> + <waitForPageLoad stepKey="waitForProductPage"/> + <seeInCurrentUrl url="{{AdminInvoiceNewPage.url}}" stepKey="seeOrderInvoiceUrl"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/GoToInvoiceIntoOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/GoToInvoiceIntoOrderActionGroup.xml index 15c7f3e9a7022..84623339fe3c9 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/GoToInvoiceIntoOrderActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/GoToInvoiceIntoOrderActionGroup.xml @@ -8,7 +8,7 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="GoToInvoiceIntoOrderActionGroup"> + <actionGroup name="GoToInvoiceIntoOrderActionGroup" deprecated="Use AdminClickInvoiceButtonIntoOrderActionGroup instead."> <annotations> <description>Clicks on 'Invoice' on the Admin Orders view page. Validates that the URL and Page Title are correct.</description> </annotations> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/StartCreateInvoiceFromOrderPageActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/StartCreateInvoiceFromOrderPageActionGroup.xml index 25906e895726d..fb220a0949cb9 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/StartCreateInvoiceFromOrderPageActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/StartCreateInvoiceFromOrderPageActionGroup.xml @@ -8,7 +8,7 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="StartCreateInvoiceFromOrderPageActionGroup"> + <actionGroup name="StartCreateInvoiceFromOrderPageActionGroup" deprecated="Use AdminClickInvoiceButtonIntoOrderActionGroup instead."> <annotations> <description>Clicks on 'Invoice' on the Admin Orders view page. Validates that the URL and Page Title are correct.</description> </annotations> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml index 30f8386b3bb91..54aa456ae8e64 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml @@ -68,8 +68,7 @@ <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask4"/> <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoice"/> - <waitForPageLoad stepKey="waitForNewInvoicePageToLoad"/> + <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoice"/> <actionGroup ref="AdminInvoiceClickSubmitActionGroup" stepKey="clickSubmitInvoice"/> <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The invoice has been created." stepKey="seeSuccessMessage"/> <click selector="{{AdminOrderDetailsOrderViewSection.invoices}}" stepKey="clickInvoices"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceAndCheckInvoiceOrderTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceAndCheckInvoiceOrderTest.xml index d0c1b51008684..c1a69eb075f12 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceAndCheckInvoiceOrderTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceAndCheckInvoiceOrderTest.xml @@ -84,7 +84,7 @@ <click selector="{{AdminDataGridTableSection.firstRow}}" stepKey="clickCreatedOrderInGrid"/> <!-- Go to invoice tab and fill data --> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceAction"/> + <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoiceAction"/> <fillField selector="{{AdminOrderInvoiceViewSection.invoiceQty}}" userInput="1" stepKey="fillInvoiceQuantity"/> <click selector="{{AdminOrderInvoiceViewSection.updateInvoiceBtn}}" stepKey="clickUpdateQtyInvoiceBtn"/> <fillField selector="{{AdminInvoiceTotalSection.invoiceComment}}" userInput="comment" stepKey="writeComment"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithCashOnDeliveryPaymentMethodTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithCashOnDeliveryPaymentMethodTest.xml index e5cfd5dc4afa0..9da2a8a4583dc 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithCashOnDeliveryPaymentMethodTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithCashOnDeliveryPaymentMethodTest.xml @@ -84,7 +84,7 @@ <click selector="{{AdminDataGridTableSection.firstRow}}" stepKey="clickCreatedOrderInGrid"/> <!-- Go to invoice tab and fill data --> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceAction"/> + <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoiceAction"/> <fillField selector="{{AdminOrderInvoiceViewSection.invoiceQty}}" userInput="1" stepKey="fillInvoiceQuantity"/> <click selector="{{AdminOrderInvoiceViewSection.updateInvoiceBtn}}" stepKey="clickUpdateQtyInvoiceBtn"/> <fillField selector="{{AdminInvoiceTotalSection.invoiceComment}}" userInput="comment" stepKey="writeComment"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithShipmentAndCheckInvoicedOrderTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithShipmentAndCheckInvoicedOrderTest.xml index 12b956be22cfb..cf29df126d387 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithShipmentAndCheckInvoicedOrderTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithShipmentAndCheckInvoicedOrderTest.xml @@ -78,7 +78,7 @@ <click selector="{{AdminDataGridTableSection.firstRow}}" stepKey="clickCreatedOrderInGrid"/> <!-- Go to invoice tab and fill data --> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceAction"/> + <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoiceAction"/> <click selector="{{AdminInvoicePaymentShippingSection.CreateShipment}}" stepKey="createShipment"/> <fillField selector="{{AdminInvoiceTotalSection.invoiceComment}}" userInput="comment" stepKey="writeComment"/> <actionGroup ref="AdminInvoiceClickSubmitActionGroup" stepKey="clickSubmitInvoice"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithZeroSubtotalCheckoutTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithZeroSubtotalCheckoutTest.xml index 780bffd359ba7..879c093a1da16 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithZeroSubtotalCheckoutTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithZeroSubtotalCheckoutTest.xml @@ -93,7 +93,7 @@ <click selector="{{AdminDataGridTableSection.firstRow}}" stepKey="clickCreatedOrderInGrid"/> <!-- Go to invoice tab and fill data --> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceAction"/> + <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoiceAction"/> <fillField selector="{{AdminInvoiceTotalSection.invoiceComment}}" userInput="comment" stepKey="writeComment"/> <actionGroup ref="AdminInvoiceClickSubmitActionGroup" stepKey="clickSubmitInvoice"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml index e41e3acbae380..cffcd7390ddc4 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml @@ -102,8 +102,7 @@ <!-- Create invoice --> <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceButton"/> - <waitForPageLoad stepKey="waitForNewInvoicePageToLoad"/> + <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoiceButton"/> <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seeNewInvoiceInPageTitle" after="clickInvoiceButton"/> <!-- Verify Invoice Totals including subTotal Shipping Discount and GrandTotal --> From 3ae37b3660f460e169f8e7f406a2cee3c8ac0728 Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Wed, 9 Sep 2020 17:32:00 +0300 Subject: [PATCH 067/132] MC-36088: Non-relevant shipping method available for checkout --- .../Magento/Checkout/view/frontend/web/js/view/shipping.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js index ff652e1e6e7a9..35d7a60e7b81a 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js @@ -282,7 +282,7 @@ define([ option = _.isObject(this.countryOptions) && this.countryOptions[quote.shippingAddress().countryId], messageContainer = registry.get('checkout.errors').messageContainer; - if (!quote.shippingMethod() || !quote.shippingMethod()['method_code']) { + if (!quote.shippingMethod()) { this.errorValidationMessage( $t('The shipping method is missing. Select the shipping method and try again.') ); @@ -304,6 +304,11 @@ define([ !quote.shippingMethod()['method_code'] || !quote.shippingMethod()['carrier_code'] ) { + if (!quote.shippingMethod()['method_code']) { + this.errorValidationMessage( + $t('The shipping method is missing. Select the shipping method and try again.') + ); + } this.focusInvalid(); return false; From 18ffc03901ee695cd7e2c1b4258de885a124f932 Mon Sep 17 00:00:00 2001 From: Oleh Usik <o.usik@atwix.com> Date: Wed, 9 Sep 2020 18:32:25 +0300 Subject: [PATCH 068/132] revert some changes --- .../Backend/Test/Mftf/Test/AdminDashboardWithChartsTest.xml | 3 ++- .../Test/AssociatedProductToConfigurableOutOfStockTest.xml | 3 ++- .../Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml | 3 ++- .../Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml | 3 ++- .../Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsTest.xml b/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsTest.xml index 968a11600ef48..439b6ac063618 100644 --- a/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsTest.xml +++ b/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsTest.xml @@ -84,7 +84,8 @@ <comment userInput="Create invoice" stepKey="createInvoice"/> <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> - <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoiceButton"/> + <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceButton"/> + <waitForPageLoad stepKey="waitForInvoicePageToLoad"/> <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seeNewInvoiceInPageTitle" after="clickInvoiceButton"/> <see selector="{{AdminInvoiceTotalSection.total('Subtotal')}}" userInput="$150.00" stepKey="seeCorrectGrandTotal"/> <actionGroup ref="AdminInvoiceClickSubmitActionGroup" stepKey="clickSubmitInvoice"/> diff --git a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml index 1f5a1df7b1186..f1c01919d52f1 100644 --- a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml +++ b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml @@ -125,7 +125,8 @@ <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask4"/> <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> - <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoice"/> + <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoice"/> + <waitForPageLoad stepKey="waitForNewInvoicePageToLoad"/> <actionGroup ref="AdminInvoiceClickSubmitActionGroup" stepKey="clickSubmitInvoice"/> <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The invoice has been created." stepKey="seeSuccessMessage"/> <click selector="{{AdminOrderDetailsMainActionsSection.ship}}" stepKey="clickShip"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml index b96c5b446fd44..898e277cff55c 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml @@ -70,7 +70,8 @@ </actionGroup> <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> - <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoiceButton"/> + <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceButton"/> + <waitForPageLoad stepKey="waitForNewInvoicePageLoad"/> <fillField selector="{{AdminInvoiceItemsSection.qtyToInvoiceColumn}}" userInput="1" stepKey="ChangeQtyToInvoice"/> <click selector="{{AdminInvoiceItemsSection.updateQty}}" stepKey="updateQuantity"/> <waitForPageLoad stepKey="waitPageToBeLoaded"/> diff --git a/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml b/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml index 0307e21667cc4..3e79eb044b5cb 100644 --- a/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml +++ b/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml @@ -47,7 +47,8 @@ <argument name="customer" value="$$createCustomer$$"/> </actionGroup> - <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoiceAction"/> + <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceAction"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seePageNameNewInvoicePage"/> <actionGroup ref="AdminInvoiceClickSubmitActionGroup" stepKey="clickSubmitInvoice"/> <click selector="{{AdminOrderDetailsMainActionsSection.ship}}" stepKey="clickShipAction"/> <seeInCurrentUrl url="{{AdminShipmentNewPage.url}}" stepKey="seeOrderShipmentUrl"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml index cffcd7390ddc4..e41e3acbae380 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml @@ -102,7 +102,8 @@ <!-- Create invoice --> <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> - <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoiceButton"/> + <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceButton"/> + <waitForPageLoad stepKey="waitForNewInvoicePageToLoad"/> <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seeNewInvoiceInPageTitle" after="clickInvoiceButton"/> <!-- Verify Invoice Totals including subTotal Shipping Discount and GrandTotal --> From 5ced4ba9bf80956c8fb3f6f067dc138bbc00582f Mon Sep 17 00:00:00 2001 From: Oleh Usik <o.usik@atwix.com> Date: Wed, 9 Sep 2020 19:08:27 +0300 Subject: [PATCH 069/132] revert some files --- .../Test/Mftf/ActionGroup/GoToInvoiceIntoOrderActionGroup.xml | 2 +- .../ActionGroup/StartCreateInvoiceFromOrderPageActionGroup.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/GoToInvoiceIntoOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/GoToInvoiceIntoOrderActionGroup.xml index 84623339fe3c9..15c7f3e9a7022 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/GoToInvoiceIntoOrderActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/GoToInvoiceIntoOrderActionGroup.xml @@ -8,7 +8,7 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="GoToInvoiceIntoOrderActionGroup" deprecated="Use AdminClickInvoiceButtonIntoOrderActionGroup instead."> + <actionGroup name="GoToInvoiceIntoOrderActionGroup"> <annotations> <description>Clicks on 'Invoice' on the Admin Orders view page. Validates that the URL and Page Title are correct.</description> </annotations> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/StartCreateInvoiceFromOrderPageActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/StartCreateInvoiceFromOrderPageActionGroup.xml index fb220a0949cb9..25906e895726d 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/StartCreateInvoiceFromOrderPageActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/StartCreateInvoiceFromOrderPageActionGroup.xml @@ -8,7 +8,7 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="StartCreateInvoiceFromOrderPageActionGroup" deprecated="Use AdminClickInvoiceButtonIntoOrderActionGroup instead."> + <actionGroup name="StartCreateInvoiceFromOrderPageActionGroup"> <annotations> <description>Clicks on 'Invoice' on the Admin Orders view page. Validates that the URL and Page Title are correct.</description> </annotations> From e837bdc66501762a46418e2fdfea3746295f690f Mon Sep 17 00:00:00 2001 From: "taras.gamanov" <engcom-vendorworker-hotel@adobe.com> Date: Wed, 9 Sep 2020 21:00:28 +0300 Subject: [PATCH 070/132] Fix for select all on page on grid. --- .../AdminCustomerGridMainActionsSection.xml | 1 + .../AdminGridSelectAllActionGroup.xml | 20 +++++++ .../Test/AdminGridSearchSelectAllTest.xml | 5 +- .../Test/AdminGridSelectAllOnPageTest.xml | 55 +++++++++++++++++++ .../base/js/grid/columns/multiselect.test.js | 13 +++++ 5 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminGridSelectAllActionGroup.xml create mode 100644 app/code/Magento/Ui/Test/Mftf/Test/AdminGridSelectAllOnPageTest.xml diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerGridMainActionsSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerGridMainActionsSection.xml index d644b581088bc..8277cdd64928a 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerGridMainActionsSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerGridMainActionsSection.xml @@ -11,6 +11,7 @@ <section name="AdminCustomerGridMainActionsSection"> <element name="addNewCustomer" type="button" selector="#add" timeout="30"/> <element name="multicheck" type="checkbox" selector="#container>div>div.admin__data-grid-wrap>table>thead>tr>th.data-grid-multicheck-cell>div>label"/> + <element name="multicheckTick" type="checkbox" selector="#container>div>div.admin__data-grid-wrap>table>thead>tr>th.data-grid-multicheck-cell>div>input"/> <element name="delete" type="button" selector="//*[contains(@class, 'admin__data-grid-header')]//span[contains(@class,'action-menu-item') and text()='Delete']"/> <element name="actions" type="text" selector=".action-select"/> <element name="customerCheckbox" type="button" selector="//*[contains(text(),'{{arg}}')]/parent::td/preceding-sibling::td/label[@class='data-grid-checkbox-cell-inner']//input" parameterized="true"/> diff --git a/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminGridSelectAllActionGroup.xml b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminGridSelectAllActionGroup.xml new file mode 100644 index 0000000000000..bbfb7e46d89ec --- /dev/null +++ b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminGridSelectAllActionGroup.xml @@ -0,0 +1,20 @@ +<?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="AdminGridSelectAllActionGroup"> + <annotations> + <description>Click on select all option on the grid</description> + </annotations> + + <waitForElementVisible selector="{{AdminGridSelectRows.multicheckDropdown}}" stepKey="waitForElement"/> + <click selector="{{AdminGridSelectRows.multicheckDropdown}}" stepKey="openMulticheckDropdown"/> + <click selector="{{AdminGridSelectRows.multicheckOption('Select All')}}" stepKey="clickSelectAllCustomers"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Ui/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml b/app/code/Magento/Ui/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml index 8498ad7646ef0..53687607f6a5b 100644 --- a/app/code/Magento/Ui/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml +++ b/app/code/Magento/Ui/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml @@ -35,9 +35,8 @@ <fillField selector="{{AdminDataGridHeaderSection.search}}" userInput="$$secondCustomer.email$$" stepKey="fillKeywordSearchFieldWithSecondCustomerEmail"/> <click selector="{{AdminDataGridHeaderSection.submitSearch}}" stepKey="clickKeywordSearch"/> <waitForPageLoad stepKey="waitForPageLoad"/> - <!-- Check select all action --> - <actionGroup ref="AdminSelectAllCustomers" stepKey="selectAllCustomers"/> - <seeCheckboxIsChecked selector="{{AdminCustomerGridMainActionsSection.customerCheckbox($$secondCustomer.email$$)}}" stepKey="checkSecondCustomerIsCheckedAfterSelectAll"/> + <!-- Select all from dropdown --> + <actionGroup ref="AdminGridSelectAllActionGroup" stepKey="selectAllCustomers"/> <!-- Clear searching By Keyword--> <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clickClearFiltersAfterSearch"/> <waitForPageLoad stepKey="waitForPageLoadAfterSearchRemoved"/> diff --git a/app/code/Magento/Ui/Test/Mftf/Test/AdminGridSelectAllOnPageTest.xml b/app/code/Magento/Ui/Test/Mftf/Test/AdminGridSelectAllOnPageTest.xml new file mode 100644 index 0000000000000..e74466d4e27af --- /dev/null +++ b/app/code/Magento/Ui/Test/Mftf/Test/AdminGridSelectAllOnPageTest.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminGridSelectAllOnPageTest"> + <annotations> + <stories value="Toggle select page."/> + <title value="Toggle select page."/> + <description value="Empty selected before and after search, like it works for filter"/> + <testCaseId value=""/> + <severity value="CRITICAL"/> + <group value="uI"/> + </annotations> + <before> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <!--Create three customers--> + <createData entity="Simple_US_Customer" stepKey="firstCustomer"/> + <createData entity="Simple_US_Customer" stepKey="secondCustomer"/> + <createData entity="Simple_US_Customer" stepKey="thirdCustomer"/> + </before> + <after> + <!--Remove created customers --> + <deleteData createDataKey="firstCustomer" stepKey="deleteFirstCustomer"/> + <deleteData createDataKey="secondCustomer" stepKey="deleteSecondCustomer"/> + <deleteData createDataKey="thirdCustomer" stepKey="deleteThirdCustomer"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + </after> + <amOnPage url="{{AdminCustomerPage.url}}" stepKey="openCustomerPage"/> + <!-- Select all from dropdown --> + <actionGroup ref="AdminGridSelectAllActionGroup" stepKey="selectAllCustomers"/> + <!-- Deselect third customer --> + <click selector="{{AdminCustomerGridMainActionsSection.customerCheckbox(($$thirdCustomer.email$$)}}" stepKey="selectThirdCustomer"/> + <dontSeeCheckboxIsChecked selector="{{AdminCustomerGridMainActionsSection.customerCheckbox($$thirdCustomer.email$$)}}" stepKey="checkThirdCustomerCheckboxIsUnchecked"/> + <!-- Click select all on page checkbox --> + <actionGroup ref="AdminSelectAllCustomers" stepKey="selectAllCustomersOnPage"/> + <seeElement selector="{{AdminCustomerGridMainActionsSection.multicheckTick}}" stepKey="waitForElement"/> + <seeCheckboxIsChecked selector="{{AdminCustomerGridMainActionsSection.multicheckTick}}" stepKey="checkAllSelectedCheckBoxIsChecked"/> + <!-- Check all created records selected --> + <seeCheckboxIsChecked selector="{{AdminCustomerGridMainActionsSection.customerCheckbox($$firstCustomer.email$$)}}" stepKey="checkFirstCustomerIsCheckedAfterSelectPage"/> + <seeCheckboxIsChecked selector="{{AdminCustomerGridMainActionsSection.customerCheckbox($$secondCustomer.email$$)}}" stepKey="checkSecondCustomerIsCheckedAfterSelectPage"/> + <seeCheckboxIsChecked selector="{{AdminCustomerGridMainActionsSection.customerCheckbox($$thirdCustomer.email$$)}}" stepKey="checkThirdCustomerIsCheckedAfterSelectPage"/> + <!-- Click deselect all on page checkbox --> + <actionGroup ref="AdminSelectAllCustomers" stepKey="deselectAllCustomersCheckbox"/> + <dontSeeCheckboxIsChecked selector="{{AdminCustomerGridMainActionsSection.multicheckTick}}" stepKey="checkAllSelectedCheckBoxUnchecked"/> + <!-- Check all created records unselected --> + <dontSeeCheckboxIsChecked selector="{{AdminCustomerGridMainActionsSection.customerCheckbox($$firstCustomer.email$$)}}" stepKey="checkFirstCustomerIsUncheckedAfterSelectPage"/> + <dontSeeCheckboxIsChecked selector="{{AdminCustomerGridMainActionsSection.customerCheckbox($$secondCustomer.email$$)}}" stepKey="checkSecondCustomerIsUncheckedAfterSelectPage"/> + <dontSeeCheckboxIsChecked selector="{{AdminCustomerGridMainActionsSection.customerCheckbox($$thirdCustomer.email$$)}}" stepKey="checkThirdCustomerIsUncheckedAfterSelectPage"/> + </test> +</tests> diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/multiselect.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/multiselect.test.js index de3387e31af88..5975f21e08070 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/multiselect.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/multiselect.test.js @@ -135,6 +135,19 @@ define([ expect(multiSelect.selected().toString()).toEqual('3,4,1,2'); }); + it('Select all rows all over the Grid and deselects all records', function () { + multiSelect.rows([{ + id: 1 + }, { + id: 2 + }]); + + multiSelect.selectAll(); + multiSelect.deselectAll(); + multiSelect.indetermine(2); + expect(multiSelect.togglePage().selected()).toEqual([1, 2]); + }); + it('Select all rows all over the Grid without all rows on current page but with specific rows on another page', function () { multiSelect.rows([{ From 2b918dac3a4504e7ebbc61ff51c8d537606992eb Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Thu, 10 Sep 2020 08:48:26 +0300 Subject: [PATCH 071/132] MC-36088: Non-relevant shipping method available for checkout --- app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js index 35d7a60e7b81a..659c8f7a60d68 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js @@ -304,7 +304,7 @@ define([ !quote.shippingMethod()['method_code'] || !quote.shippingMethod()['carrier_code'] ) { - if (!quote.shippingMethod()['method_code']) { + if (!quote.shippingMethod()['method_code']) {//eslint-disable-line max-depth this.errorValidationMessage( $t('The shipping method is missing. Select the shipping method and try again.') ); From 0cf0e09cf5453c7fb4f8502722b1a0447c00b9db Mon Sep 17 00:00:00 2001 From: Shankar Konar <konar.shankar2013@gmail.com> Date: Thu, 10 Sep 2020 12:16:34 +0530 Subject: [PATCH 072/132] Fixed file validation error --- lib/internal/Magento/Framework/File/Mime.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/internal/Magento/Framework/File/Mime.php b/lib/internal/Magento/Framework/File/Mime.php index 148f43d47cfd4..e0b22e4c944d9 100644 --- a/lib/internal/Magento/Framework/File/Mime.php +++ b/lib/internal/Magento/Framework/File/Mime.php @@ -108,6 +108,9 @@ public function getMimeType($file) if (function_exists('mime_content_type')) { $result = $this->getNativeMimeType($file); + } else { + $imageInfo = getimagesize($file); + $result = $imageInfo['mime']; } if (null === $result && isset($this->mimeTypes[$extension])) { From 591e04e80f0727840ac9ec8035caa055e148a930 Mon Sep 17 00:00:00 2001 From: "taras.gamanov" <engcom-vendorworker-hotel@adobe.com> Date: Thu, 10 Sep 2020 10:29:45 +0300 Subject: [PATCH 073/132] Reformat for static test. --- .../Magento/Ui/view/base/web/js/grid/columns/multiselect.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js index 4edd71bdc4906..828bbccee0478 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js @@ -503,7 +503,7 @@ define([ * Is invoked when search is applied or removed */ onSearch: function () { - this.onFilter(); + this.onFilter(); } }); }); From e4fb9d153ef4ea1c411de5ac7954a4849e57a7f0 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <51681487+engcom-Foxtrot@users.noreply.github.com> Date: Thu, 10 Sep 2020 10:48:49 +0300 Subject: [PATCH 074/132] magento/magento2#25147: Totals Information Management - setting quote shipping method when address method is null - static tests fix. --- .../Magento/Checkout/Model/TotalsInformationManagement.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/Model/TotalsInformationManagement.php b/app/code/Magento/Checkout/Model/TotalsInformationManagement.php index a27a11ca22b78..7328f8845545c 100644 --- a/app/code/Magento/Checkout/Model/TotalsInformationManagement.php +++ b/app/code/Magento/Checkout/Model/TotalsInformationManagement.php @@ -6,7 +6,7 @@ namespace Magento\Checkout\Model; /** - * Class TotalsInformationManagement + * Class for management of totals information. */ class TotalsInformationManagement implements \Magento\Checkout\Api\TotalsInformationManagementInterface { @@ -38,7 +38,7 @@ public function __construct( } /** - * {@inheritDoc} + * @inheritDoc */ public function calculate( $cartId, @@ -64,6 +64,8 @@ public function calculate( } /** + * Check if quote have items. + * * @param \Magento\Quote\Model\Quote $quote * @throws \Magento\Framework\Exception\LocalizedException * @return void From f019712ea87afd04e7f6ec521f40f28c0894a8a5 Mon Sep 17 00:00:00 2001 From: "taras.gamanov" <engcom-vendorworker-hotel@adobe.com> Date: Thu, 10 Sep 2020 15:39:56 +0300 Subject: [PATCH 075/132] Moved MFTF to the customer module. --- .../Test/Mftf/Test/AdminGridSearchSelectAllTest.xml | 0 .../Test/Mftf/Test/AdminGridSelectAllOnPageTest.xml | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename app/code/Magento/{Ui => Customer}/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml (100%) rename app/code/Magento/{Ui => Customer}/Test/Mftf/Test/AdminGridSelectAllOnPageTest.xml (100%) diff --git a/app/code/Magento/Ui/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml similarity index 100% rename from app/code/Magento/Ui/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml rename to app/code/Magento/Customer/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml diff --git a/app/code/Magento/Ui/Test/Mftf/Test/AdminGridSelectAllOnPageTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminGridSelectAllOnPageTest.xml similarity index 100% rename from app/code/Magento/Ui/Test/Mftf/Test/AdminGridSelectAllOnPageTest.xml rename to app/code/Magento/Customer/Test/Mftf/Test/AdminGridSelectAllOnPageTest.xml From a7cd4a5ce4a3e321c6e954bc6cfeb2c0a93b4f2f Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Thu, 10 Sep 2020 16:17:39 +0300 Subject: [PATCH 076/132] MC-37089: Create automated test for "[Security] Customer's Order Data are not available for Guests" --- .../Sales/Controller/Guest/ViewTest.php | 52 ++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Guest/ViewTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Guest/ViewTest.php index 5a912c2960ab6..d9255ba212700 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Guest/ViewTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Guest/ViewTest.php @@ -7,22 +7,70 @@ namespace Magento\Sales\Controller\Guest; +use Magento\Framework\Stdlib\CookieManagerInterface; +use Magento\Sales\Api\Data\OrderInterfaceFactory; +use Magento\Sales\Api\OrderRepositoryInterface; use Magento\TestFramework\Request; use Magento\TestFramework\TestCase\AbstractController; /** - * Test for \Magento\Sales\Controller\Guest\View class. + * Test for orders and returns controller. + * + * @see \Magento\Sales\Controller\Guest\View */ class ViewTest extends AbstractController { + /** @var CookieManagerInterface */ + private $cookieManager; + + /** @var OrderInterfaceFactory */ + private $orderFactory; + + /** @var OrderRepositoryInterface */ + private $orderRepository; + + /** + * @inheritdoc + */ + protected function setUp(): void + { + parent::setUp(); + + $this->cookieManager = $this->_objectManager->get(CookieManagerInterface::class); + $this->orderFactory = $this->_objectManager->get(OrderInterfaceFactory::class); + $this->orderRepository = $this->_objectManager->get(OrderRepositoryInterface::class); + } + /** * Check that controller applied GET requests. + * + * @return void */ - public function testExecuteWithGetRequest() + public function testExecuteWithGetRequest(): void { $this->getRequest()->setMethod(Request::METHOD_GET); $this->dispatch('sales/guest/view/'); $this->assertRedirect($this->stringContains('sales/guest/form')); } + + /** + * @magentoDataFixture Magento/Sales/_files/order.php + * + * @return void + */ + public function testExecuteWithWrongCookie(): void + { + $order = $this->orderFactory->create()->loadByIncrementId('100000001'); + $order->setProtectCode('0e6640'); + $this->orderRepository->save($order); + $cookieValue = base64_encode('0' . ':' . $order->getIncrementId()); + $this->cookieManager->setPublicCookie(\Magento\Sales\Helper\Guest::COOKIE_NAME, $cookieValue); + $this->getRequest()->setMethod(Request::METHOD_GET); + $this->dispatch('sales/guest/view/'); + $this->assertRedirect($this->stringContains('sales/guest/form/')); + $this->assertSessionMessages( + $this->containsEqual((string)__('You entered incorrect data. Please try again.')) + ); + } } From 965bb729d7e447cca71aa8c1b473249a250d1d31 Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Thu, 10 Sep 2020 16:38:00 +0300 Subject: [PATCH 077/132] MC-36088: Non-relevant shipping method available for checkout --- .../Checkout/view/frontend/web/js/view/shipping.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js index 659c8f7a60d68..646e6156ec646 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js @@ -299,16 +299,17 @@ define([ this.source.set('params.invalid', false); this.triggerShippingDataValidateEvent(); + if (!quote.shippingMethod()['method_code']) { + this.errorValidationMessage( + $t('The shipping method is missing. Select the shipping method and try again.') + ); + } + if (emailValidationResult && this.source.get('params.invalid') || !quote.shippingMethod()['method_code'] || !quote.shippingMethod()['carrier_code'] ) { - if (!quote.shippingMethod()['method_code']) {//eslint-disable-line max-depth - this.errorValidationMessage( - $t('The shipping method is missing. Select the shipping method and try again.') - ); - } this.focusInvalid(); return false; From 22da500519287b49c984ed615b66d0edd6f55bb0 Mon Sep 17 00:00:00 2001 From: Viktor Kopin <viktor.kopin@transoftgroup.com> Date: Thu, 10 Sep 2020 17:13:18 +0300 Subject: [PATCH 078/132] adobe-stock-integration#1806: fix inserted rendition image size from media gallery on preview --- .../Wysiwyg/Images/GetInsertImageContent.php | 71 ++++++++++++++++++- .../Controller/Adminhtml/Image/OnInsert.php | 64 +++++++++++++++++ .../etc/adminhtml/routes.xml | 15 ++++ .../Ui/Component/Listing/Columns/Url.php | 2 +- .../grid/columns/image/insertImageAction.js | 8 +-- 5 files changed, 153 insertions(+), 7 deletions(-) create mode 100644 app/code/Magento/MediaGalleryRenditions/Controller/Adminhtml/Image/OnInsert.php create mode 100644 app/code/Magento/MediaGalleryRenditions/etc/adminhtml/routes.xml diff --git a/app/code/Magento/Cms/Model/Wysiwyg/Images/GetInsertImageContent.php b/app/code/Magento/Cms/Model/Wysiwyg/Images/GetInsertImageContent.php index 305d73fff4dc7..cb76c0ff463ba 100644 --- a/app/code/Magento/Cms/Model/Wysiwyg/Images/GetInsertImageContent.php +++ b/app/code/Magento/Cms/Model/Wysiwyg/Images/GetInsertImageContent.php @@ -10,6 +10,11 @@ use Magento\Catalog\Helper\Data as CatalogHelper; use Magento\Cms\Helper\Wysiwyg\Images as ImagesHelper; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\File\Mime; +use Magento\Framework\Filesystem; +use Magento\Framework\Filesystem\Directory\ReadInterface; +use Magento\Framework\Filesystem\File\WriteInterface; class GetInsertImageContent { @@ -23,14 +28,37 @@ class GetInsertImageContent */ private $catalogHelper; + /** + * @var Filesystem + */ + private $filesystem; + + /** + * @var Mime + */ + private $mime; + + /** + * @var WriteInterface + */ + private $pubDirectory; + /** * @param ImagesHelper $imagesHelper * @param CatalogHelper $catalogHelper + * @param Filesystem $fileSystem + * @param Mime $mime */ - public function __construct(ImagesHelper $imagesHelper, CatalogHelper $catalogHelper) - { + public function __construct( + ImagesHelper $imagesHelper, + CatalogHelper $catalogHelper, + Filesystem $fileSystem, + Mime $mime + ) { $this->imagesHelper = $imagesHelper; $this->catalogHelper = $catalogHelper; + $this->filesystem = $fileSystem; + $this->mime = $mime; } /** @@ -60,4 +88,43 @@ public function execute( return $this->imagesHelper->getImageHtmlDeclaration($filename, $renderAsTag); } + + /** + * Retrieve size of requested file + * + * @param string $path + * @return int + */ + public function getImageSize(string $path): int + { + $directory = $this->getPubDirectory(); + + return $directory->isExist($path) ? $directory->stat($path)['size'] : 0; + } + + /** + * Retrieve MIME type of requested file + * + * @param string $path + * @return string + */ + public function getMimeType(string $path) + { + $absoluteFilePath = $this->getPubDirectory()->getAbsolutePath($path); + + return $this->mime->getMimeType($absoluteFilePath); + } + + /** + * Retrieve pub directory read interface instance + * + * @return ReadInterface + */ + private function getPubDirectory() + { + if ($this->pubDirectory === null) { + $this->pubDirectory = $this->filesystem->getDirectoryRead(DirectoryList::PUB); + } + return $this->pubDirectory; + } } diff --git a/app/code/Magento/MediaGalleryRenditions/Controller/Adminhtml/Image/OnInsert.php b/app/code/Magento/MediaGalleryRenditions/Controller/Adminhtml/Image/OnInsert.php new file mode 100644 index 0000000000000..464a7951fb378 --- /dev/null +++ b/app/code/Magento/MediaGalleryRenditions/Controller/Adminhtml/Image/OnInsert.php @@ -0,0 +1,64 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\MediaGalleryRenditions\Controller\Adminhtml\Image; + +use Magento\Backend\App\Action; +use Magento\Backend\App\Action\Context; +use Magento\Cms\Model\Wysiwyg\Images\GetInsertImageContent; +use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\Controller\Result\JsonFactory; +use Magento\Framework\Controller\ResultInterface; + +/** + * Class OnInsert + */ +class OnInsert extends Action implements HttpPostActionInterface +{ + /** + * @var JsonFactory + */ + protected $resultJsonFactory; + + /** + * @var GetInsertImageContent + */ + private $getInsertImageContent; + + /** + * @param Context $context + * @param JsonFactory $resultJsonFactory + * @param GetInsertImageContent|null $getInsertImageContent + */ + public function __construct( + Context $context, + JsonFactory $resultJsonFactory, + GetInsertImageContent $getInsertImageContent + ) { + parent::__construct($context); + $this->resultJsonFactory = $resultJsonFactory; + $this->getInsertImageContent = $getInsertImageContent; + } + + /** + * Return a content (just a link or an html block) for inserting image to the content + * + * @return ResultInterface + */ + public function execute() + { + $data = $this->getRequest()->getParams(); + $path = $this->getInsertImageContent->execute( + $data['filename'], + $data['force_static_path'], + $data['as_is'], + isset($data['store']) ? (int)$data['store'] : null + ); + $size = $this->getInsertImageContent->getImageSize($path); + $type = $this->getInsertImageContent->getMimeType($path); + return $this->resultJsonFactory->create()->setData(['path' => $path, 'size' => $size, 'type' => $type]); + } +} diff --git a/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/routes.xml b/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/routes.xml new file mode 100644 index 0000000000000..79a584a8687b9 --- /dev/null +++ b/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/routes.xml @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> + <router id="admin"> + <route id="media_gallery_renditions" frontName="media_gallery_renditions"> + <module name="Magento_MediaGalleryRenditions" before="Magento_Backend" /> + </route> + </router> +</config> diff --git a/app/code/Magento/MediaGalleryUi/Ui/Component/Listing/Columns/Url.php b/app/code/Magento/MediaGalleryUi/Ui/Component/Listing/Columns/Url.php index 481f8ab861f0f..195e355196305 100644 --- a/app/code/Magento/MediaGalleryUi/Ui/Component/Listing/Columns/Url.php +++ b/app/code/Magento/MediaGalleryUi/Ui/Component/Listing/Columns/Url.php @@ -98,7 +98,7 @@ public function prepare(): void array_replace_recursive( (array)$this->getData('config'), [ - 'onInsertUrl' => $this->urlInterface->getUrl('cms/wysiwyg_images/oninsert'), + 'onInsertUrl' => $this->urlInterface->getUrl('media_gallery_renditions/image/oninsert'), 'storeId' => $this->storeManager->getStore()->getId() ] ) diff --git a/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/grid/columns/image/insertImageAction.js b/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/grid/columns/image/insertImageAction.js index f72a05b6d2709..57e1f3cebd881 100644 --- a/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/grid/columns/image/insertImageAction.js +++ b/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/grid/columns/image/insertImageAction.js @@ -47,13 +47,13 @@ define([ showLoader: true }).done($.proxy(function (data) { if (targetElement.is('textarea')) { - this.insertAtCursor(targetElement.get(0), data); + this.insertAtCursor(targetElement.get(0), data.path); targetElement.focus(); $(targetElement).change(); } else { - targetElement.val(data) - .data('size', record.size) - .data('mime-type', record['content_type']) + targetElement.val(data.path) + .data('size', data.size) + .data('mime-type', data.type) .trigger('change'); } }, this)); From b5edc504c2e64c13a0bc45d6da7fd50c1d4e5e22 Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Fri, 11 Sep 2020 12:19:02 +0300 Subject: [PATCH 079/132] MC-37089: Create automated test for "[Security] Customer's Order Data are not available for Guests" --- .../testsuite/Magento/Sales/Controller/Guest/ViewTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Guest/ViewTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Guest/ViewTest.php index d9255ba212700..d5f252ffdad53 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Guest/ViewTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Guest/ViewTest.php @@ -10,6 +10,7 @@ use Magento\Framework\Stdlib\CookieManagerInterface; use Magento\Sales\Api\Data\OrderInterfaceFactory; use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Helper\Guest; use Magento\TestFramework\Request; use Magento\TestFramework\TestCase\AbstractController; @@ -65,7 +66,7 @@ public function testExecuteWithWrongCookie(): void $order->setProtectCode('0e6640'); $this->orderRepository->save($order); $cookieValue = base64_encode('0' . ':' . $order->getIncrementId()); - $this->cookieManager->setPublicCookie(\Magento\Sales\Helper\Guest::COOKIE_NAME, $cookieValue); + $this->cookieManager->setPublicCookie(Guest::COOKIE_NAME, $cookieValue); $this->getRequest()->setMethod(Request::METHOD_GET); $this->dispatch('sales/guest/view/'); $this->assertRedirect($this->stringContains('sales/guest/form/')); From b5180c00976cafeee03a1ba55833c9ae871c6194 Mon Sep 17 00:00:00 2001 From: Viktor Kopin <viktor.kopin@transoftgroup.com> Date: Fri, 11 Sep 2020 14:59:25 +0300 Subject: [PATCH 080/132] adobe-stock-integration#1806: refactoring and cover by mftf test --- .../Section/AdminCategoryContentSection.xml | 1 + .../Wysiwyg/Images/GetInsertImageContent.php | 66 +-------- .../Controller/Adminhtml/Image/OnInsert.php | 64 --------- ...diaGalleryInsertLargeImageFileSizeTest.xml | 65 +++++++++ .../etc/adminhtml/routes.xml | 15 -- .../Controller/Adminhtml/Image/OnInsert.php | 130 ++++++++++++++++++ ...inAssertImageUploadFileSizeActionGroup.xml | 25 ++++ .../AdminEnhancedMediaGalleryImageData.xml | 9 ++ .../Ui/Component/Listing/Columns/Url.php | 2 +- 9 files changed, 233 insertions(+), 144 deletions(-) delete mode 100644 app/code/Magento/MediaGalleryRenditions/Controller/Adminhtml/Image/OnInsert.php create mode 100644 app/code/Magento/MediaGalleryRenditions/Test/Mftf/Test/AdminMediaGalleryInsertLargeImageFileSizeTest.xml delete mode 100644 app/code/Magento/MediaGalleryRenditions/etc/adminhtml/routes.xml create mode 100644 app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php create mode 100644 app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminAssertImageUploadFileSizeActionGroup.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryContentSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryContentSection.xml index 1cb095974d0fd..034150ef45460 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryContentSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryContentSection.xml @@ -14,6 +14,7 @@ <element name="selectFromGalleryButton" type="button" selector="//*[@class='file-uploader-area']/label[text()='Select from Gallery']"/> <element name="uploadImageFile" type="input" selector=".file-uploader-area>input"/> <element name="imageFileName" type="text" selector=".file-uploader-filename"/> + <element name="imageFileMeta" type="text" selector=".file-uploader-meta"/> <element name="removeImageButton" type="button" selector=".file-uploader-summary .action-remove"/> <element name="AddCMSBlock" type="select" selector="//*[@name='landing_page']"/> <element name="description" type="input" selector="//*[@name='description']"/> diff --git a/app/code/Magento/Cms/Model/Wysiwyg/Images/GetInsertImageContent.php b/app/code/Magento/Cms/Model/Wysiwyg/Images/GetInsertImageContent.php index cb76c0ff463ba..bfadd904eb283 100644 --- a/app/code/Magento/Cms/Model/Wysiwyg/Images/GetInsertImageContent.php +++ b/app/code/Magento/Cms/Model/Wysiwyg/Images/GetInsertImageContent.php @@ -28,37 +28,14 @@ class GetInsertImageContent */ private $catalogHelper; - /** - * @var Filesystem - */ - private $filesystem; - - /** - * @var Mime - */ - private $mime; - - /** - * @var WriteInterface - */ - private $pubDirectory; - /** * @param ImagesHelper $imagesHelper * @param CatalogHelper $catalogHelper - * @param Filesystem $fileSystem - * @param Mime $mime */ - public function __construct( - ImagesHelper $imagesHelper, - CatalogHelper $catalogHelper, - Filesystem $fileSystem, - Mime $mime - ) { + public function __construct(ImagesHelper $imagesHelper, CatalogHelper $catalogHelper) + { $this->imagesHelper = $imagesHelper; $this->catalogHelper = $catalogHelper; - $this->filesystem = $fileSystem; - $this->mime = $mime; } /** @@ -88,43 +65,4 @@ public function execute( return $this->imagesHelper->getImageHtmlDeclaration($filename, $renderAsTag); } - - /** - * Retrieve size of requested file - * - * @param string $path - * @return int - */ - public function getImageSize(string $path): int - { - $directory = $this->getPubDirectory(); - - return $directory->isExist($path) ? $directory->stat($path)['size'] : 0; - } - - /** - * Retrieve MIME type of requested file - * - * @param string $path - * @return string - */ - public function getMimeType(string $path) - { - $absoluteFilePath = $this->getPubDirectory()->getAbsolutePath($path); - - return $this->mime->getMimeType($absoluteFilePath); - } - - /** - * Retrieve pub directory read interface instance - * - * @return ReadInterface - */ - private function getPubDirectory() - { - if ($this->pubDirectory === null) { - $this->pubDirectory = $this->filesystem->getDirectoryRead(DirectoryList::PUB); - } - return $this->pubDirectory; - } } diff --git a/app/code/Magento/MediaGalleryRenditions/Controller/Adminhtml/Image/OnInsert.php b/app/code/Magento/MediaGalleryRenditions/Controller/Adminhtml/Image/OnInsert.php deleted file mode 100644 index 464a7951fb378..0000000000000 --- a/app/code/Magento/MediaGalleryRenditions/Controller/Adminhtml/Image/OnInsert.php +++ /dev/null @@ -1,64 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\MediaGalleryRenditions\Controller\Adminhtml\Image; - -use Magento\Backend\App\Action; -use Magento\Backend\App\Action\Context; -use Magento\Cms\Model\Wysiwyg\Images\GetInsertImageContent; -use Magento\Framework\App\Action\HttpPostActionInterface; -use Magento\Framework\Controller\Result\JsonFactory; -use Magento\Framework\Controller\ResultInterface; - -/** - * Class OnInsert - */ -class OnInsert extends Action implements HttpPostActionInterface -{ - /** - * @var JsonFactory - */ - protected $resultJsonFactory; - - /** - * @var GetInsertImageContent - */ - private $getInsertImageContent; - - /** - * @param Context $context - * @param JsonFactory $resultJsonFactory - * @param GetInsertImageContent|null $getInsertImageContent - */ - public function __construct( - Context $context, - JsonFactory $resultJsonFactory, - GetInsertImageContent $getInsertImageContent - ) { - parent::__construct($context); - $this->resultJsonFactory = $resultJsonFactory; - $this->getInsertImageContent = $getInsertImageContent; - } - - /** - * Return a content (just a link or an html block) for inserting image to the content - * - * @return ResultInterface - */ - public function execute() - { - $data = $this->getRequest()->getParams(); - $path = $this->getInsertImageContent->execute( - $data['filename'], - $data['force_static_path'], - $data['as_is'], - isset($data['store']) ? (int)$data['store'] : null - ); - $size = $this->getInsertImageContent->getImageSize($path); - $type = $this->getInsertImageContent->getMimeType($path); - return $this->resultJsonFactory->create()->setData(['path' => $path, 'size' => $size, 'type' => $type]); - } -} diff --git a/app/code/Magento/MediaGalleryRenditions/Test/Mftf/Test/AdminMediaGalleryInsertLargeImageFileSizeTest.xml b/app/code/Magento/MediaGalleryRenditions/Test/Mftf/Test/AdminMediaGalleryInsertLargeImageFileSizeTest.xml new file mode 100644 index 0000000000000..d9e965b490666 --- /dev/null +++ b/app/code/Magento/MediaGalleryRenditions/Test/Mftf/Test/AdminMediaGalleryInsertLargeImageFileSizeTest.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminMediaGalleryInsertLargeImageFileSizeTest"> + <annotations> + <features value="AdminMediaGalleryInsertLargeImageFileSizeTest"/> + <useCaseId value="https://github.com/magento/adobe-stock-integration/issues/1806"/> + <title value="Admin user should see correct image file size after rendition"/> + <testCaseId value="https://studio.cucumber.io/projects/131313/test-plan/folders/1507933/scenarios/5200023"/> + <description value="Admin user should see correct image file size after rendition"/> + <severity value="MAJOR"/> + <group value="media_gallery_ui"/> + </annotations> + <before> + <createData entity="SimpleSubCategory" stepKey="category"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + </before> + <after> + <!-- Delete uploaded image --> + <actionGroup ref="AdminOpenCategoryGridPageActionGroup" stepKey="openCategoryPageFoDelete"/> + <actionGroup ref="AdminEditCategoryInGridPageActionGroup" stepKey="editCategoryItemForDelete"> + <argument name="categoryName" value="$category.name$"/> + </actionGroup> + <actionGroup ref="AdminOpenMediaGalleryFromCategoryImageUploaderActionGroup" stepKey="openMediaGalleryForDelete"/> + <actionGroup ref="AdminEnhancedMediaGalleryEnableMassActionModeActionGroup" stepKey="enableMassActionToDeleteImages"/> + <actionGroup ref="AdminEnhancedMediaGallerySelectImageForMassActionActionGroup" stepKey="selectSecondImageToDelete"> + <argument name="imageName" value="{{LargeImage.title}}"/> + </actionGroup> + <actionGroup ref="AdminEnhancedMediaGalleryClickDeleteImagesButtonActionGroup" stepKey="clickDeleteSelectedButton"/> + <actionGroup ref="AdminEnhancedMediaGalleryConfirmDeleteImagesActionGroup" stepKey="deleteImages"/> + + <!-- Delete category --> + <deleteData createDataKey="category" stepKey="deleteCategory"/> + </after> + + <!-- Open category page --> + <actionGroup ref="AdminOpenCategoryGridPageActionGroup" stepKey="openCategoryPage"/> + <actionGroup ref="AdminEditCategoryInGridPageActionGroup" stepKey="editCategoryItem"> + <argument name="categoryName" value="$category.name$"/> + </actionGroup> + <actionGroup ref="AdminSaveCategoryFormActionGroup" stepKey="saveCategoryForm"/> + + <!-- Add image to category from gallery --> + <actionGroup ref="AdminOpenMediaGalleryFromCategoryImageUploaderActionGroup" stepKey="openMediaGallery"/> + <actionGroup ref="AdminEnhancedMediaGalleryUploadImageActionGroup" stepKey="addCategoryImage"> + <argument name="image" value="LargeImage"/> + </actionGroup> + <actionGroup ref="AdminMediaGalleryClickImageInGridActionGroup" stepKey="selectImage"> + <argument name="imageName" value="{{LargeImage.title}}"/> + </actionGroup> + <actionGroup ref="AdminMediaGalleryClickAddSelectedActionGroup" stepKey="addSelected"/> + + <!-- Assert added image size --> + <actionGroup ref="AdminAssertImageUploadFileSizeThanActionGroup" stepKey="assertSize"> + <argument name="fileSize" value="26 KB"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/routes.xml b/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/routes.xml deleted file mode 100644 index 79a584a8687b9..0000000000000 --- a/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/routes.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> - <router id="admin"> - <route id="media_gallery_renditions" frontName="media_gallery_renditions"> - <module name="Magento_MediaGalleryRenditions" before="Magento_Backend" /> - </route> - </router> -</config> diff --git a/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php b/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php new file mode 100644 index 0000000000000..0f812fe8940c6 --- /dev/null +++ b/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php @@ -0,0 +1,130 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\MediaGalleryUi\Controller\Adminhtml\Image; + +use Magento\Backend\App\Action; +use Magento\Backend\App\Action\Context; +use Magento\Cms\Model\Wysiwyg\Images\GetInsertImageContent; +use Magento\Framework\App\Action\HttpPostActionInterface; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Controller\Result\JsonFactory; +use Magento\Framework\Controller\ResultInterface; +use Magento\Framework\File\Mime; +use Magento\Framework\Filesystem; +use Magento\Framework\Filesystem\Directory\ReadInterface; +use Magento\Framework\Filesystem\File\WriteInterface; + +/** + * Class OnInsert + */ +class OnInsert extends Action implements HttpPostActionInterface +{ + /** + * @var JsonFactory + */ + private $resultJsonFactory; + + /** + * @var GetInsertImageContent + */ + private $getInsertImageContent; + + /** + * @var Filesystem + */ + private $filesystem; + + /** + * @var Mime + */ + private $mime; + + /** + * @var WriteInterface + */ + private $pubDirectory; + + /** + * @param Context $context + * @param JsonFactory $resultJsonFactory + * @param GetInsertImageContent|null $getInsertImageContent + * @param Filesystem $fileSystem + * @param Mime $mime + */ + public function __construct( + Context $context, + JsonFactory $resultJsonFactory, + GetInsertImageContent $getInsertImageContent, + Filesystem $fileSystem, + Mime $mime + ) { + parent::__construct($context); + $this->resultJsonFactory = $resultJsonFactory; + $this->getInsertImageContent = $getInsertImageContent; + $this->filesystem = $fileSystem; + $this->mime = $mime; + } + + /** + * Return a content (just a link or an html block) for inserting image to the content + * + * @return ResultInterface + */ + public function execute() + { + $data = $this->getRequest()->getParams(); + $path = $this->getInsertImageContent->execute( + $data['filename'], + $data['force_static_path'], + $data['as_is'], + isset($data['store']) ? (int)$data['store'] : null + ); + + $size = $data['force_static_path'] ? $this->getImageSize($path) : 0; + $type = $data['force_static_path'] ? $this->getMimeType($path) : ''; + return $this->resultJsonFactory->create()->setData(['path' => $path, 'size' => $size, 'type' => $type]); + } + + /** + * Retrieve size of requested file + * + * @param string $path + * @return int + */ + private function getImageSize(string $path): int + { + $directory = $this->getPubDirectory(); + + return $directory->isExist($path) ? $directory->stat($path)['size'] : 0; + } + + /** + * Retrieve MIME type of requested file + * + * @param string $path + * @return string + */ + private function getMimeType(string $path) + { + $absoluteFilePath = $this->getPubDirectory()->getAbsolutePath($path); + + return $this->mime->getMimeType($absoluteFilePath); + } + + /** + * Retrieve pub directory read interface instance + * + * @return ReadInterface + */ + private function getPubDirectory() + { + if ($this->pubDirectory === null) { + $this->pubDirectory = $this->filesystem->getDirectoryRead(DirectoryList::PUB); + } + return $this->pubDirectory; + } +} diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminAssertImageUploadFileSizeActionGroup.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminAssertImageUploadFileSizeActionGroup.xml new file mode 100644 index 0000000000000..8d8ff1f34e293 --- /dev/null +++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminAssertImageUploadFileSizeActionGroup.xml @@ -0,0 +1,25 @@ +<?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="AdminAssertImageUploadFileSizeThanActionGroup"> + <annotations> + <description>Validates that the provided image has correct file size in category content section.</description> + </annotations> + <arguments> + <argument name="fileSize" type="string"/> + </arguments> + + <grabTextFrom selector="{{AdminCategoryContentSection.imageFileMeta}}" stepKey="imageSize"/> + <assertStringContainsString stepKey="assertFileSize"> + <expectedResult type="string">{{fileSize}}</expectedResult> + <actualResult type="variable">imageSize</actualResult> + </assertStringContainsString> + + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/Data/AdminEnhancedMediaGalleryImageData.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/Data/AdminEnhancedMediaGalleryImageData.xml index dbc298798ee8e..26e0ac180e7fe 100644 --- a/app/code/Magento/MediaGalleryUi/Test/Mftf/Data/AdminEnhancedMediaGalleryImageData.xml +++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/Data/AdminEnhancedMediaGalleryImageData.xml @@ -40,4 +40,13 @@ <data key="extension">jpg</data> <data key="keywords">magento, mediagallerymetadata</data> </entity> + <entity name="LargeImage" type="image"> + <data key="title">magento</data> + <data key="description">Description of the large magento image</data> + <data key="file">magento.jpg</data> + <data key="value">magento.jpg</data> + <data key="fileName">magento</data> + <data key="extension">jpg</data> + <data key="keywords">magento, mediagallerymetadata</data> + </entity> </entities> diff --git a/app/code/Magento/MediaGalleryUi/Ui/Component/Listing/Columns/Url.php b/app/code/Magento/MediaGalleryUi/Ui/Component/Listing/Columns/Url.php index 195e355196305..be39e1539690f 100644 --- a/app/code/Magento/MediaGalleryUi/Ui/Component/Listing/Columns/Url.php +++ b/app/code/Magento/MediaGalleryUi/Ui/Component/Listing/Columns/Url.php @@ -98,7 +98,7 @@ public function prepare(): void array_replace_recursive( (array)$this->getData('config'), [ - 'onInsertUrl' => $this->urlInterface->getUrl('media_gallery_renditions/image/oninsert'), + 'onInsertUrl' => $this->urlInterface->getUrl('media_gallery/image/oninsert'), 'storeId' => $this->storeManager->getStore()->getId() ] ) From d121a9f4b844ea0b0db9f4e9722c3a3807d194d9 Mon Sep 17 00:00:00 2001 From: Serhii Balko <serhii.balko@transoftgroup.com> Date: Fri, 11 Sep 2020 15:14:15 +0300 Subject: [PATCH 081/132] MC-36836: Datepicker issue on Admin GRID --- .../Framework/Stdlib/DateTime/Timezone.php | 88 ++++++++++++++----- .../Test/Unit/DateTime/TimezoneTest.php | 27 +++++- 2 files changed, 90 insertions(+), 25 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 42ffeae2aa883..cdf175767d6aa 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -30,6 +30,11 @@ class Timezone implements TimezoneInterface \IntlDateFormatter::SHORT, ]; + /** + * @var array + */ + private $dateFormatterCache = []; + /** * @var string */ @@ -174,16 +179,9 @@ public function date($date = null, $locale = null, $useTimezone = true, $include case ($date instanceof \DateTimeImmutable): return new \DateTime($date->format('Y-m-d H:i:s'), $date->getTimezone()); case (!is_numeric($date)): - $timeType = $includeTime ? \IntlDateFormatter::SHORT : \IntlDateFormatter::NONE; - $formatter = new \IntlDateFormatter( - $locale, - \IntlDateFormatter::MEDIUM, - $timeType, - new \DateTimeZone($timezone) - ); - $date = $this->appendTimeIfNeeded($date, $includeTime, $timezone, $locale); - $date = $formatter->parse($date) ?: (new \DateTime($date))->getTimestamp(); + $date = $this->parseLocaleDate($date, $locale, $timezone, $includeTime) + ?: (new \DateTime($date))->getTimestamp(); break; } @@ -343,33 +341,77 @@ public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s') private function appendTimeIfNeeded($date, $includeTime, $timezone, $locale) { if ($includeTime && !preg_match('/\d{1}:\d{2}/', $date)) { - - $formatterWithoutHour = new \IntlDateFormatter( - $locale, - \IntlDateFormatter::MEDIUM, - \IntlDateFormatter::NONE, - new \DateTimeZone($timezone) - ); - $convertedDate = $formatterWithoutHour->parse($date); - + $convertedDate = $this->parseLocaleDate($date, $locale, $timezone, false); if (!$convertedDate) { throw new LocalizedException( new Phrase( 'Could not append time to DateTime' ) ); - } - $formatterWithHour = new \IntlDateFormatter( + $formatterWithHour = $this->getDateFormatter( $locale, + $timezone, \IntlDateFormatter::MEDIUM, - \IntlDateFormatter::SHORT, - new \DateTimeZone($timezone) + \IntlDateFormatter::SHORT ); - $date = $formatterWithHour->format($convertedDate); } return $date; } + + /** + * Parse date by locale format through IntlDateFormatter + * + * @param string $date + * @param string $locale + * @param string $timeZone + * @param bool $includeTime + * @return int|null Timestamp of date + */ + private function parseLocaleDate(string $date, string $locale, string $timeZone, bool $includeTime): ?int + { + $allowedStyles = [\IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT]; + $timeStyle = $includeTime ? \IntlDateFormatter::SHORT : \IntlDateFormatter::NONE; + + /** + * Try to parse date with different styles + */ + foreach ($allowedStyles as $style) { + $formatter = $this->getDateFormatter($locale, $timeZone, $style, $timeStyle); + $timeStamp = $formatter->parse($date); + if ($timeStamp) { + return $timeStamp; + } + } + + return null; + } + + /** + * Get date formatter for locale + * + * @param string $locale + * @param string $timeZone + * @param int $style + * @param int $timeStyle + * @return \IntlDateFormatter + */ + private function getDateFormatter(string $locale, string $timeZone, int $style, int $timeStyle): \IntlDateFormatter + { + $cacheKey = "{$locale}_{$timeZone}_{$style}_{$timeStyle}"; + if (isset($this->dateFormatterCache[$cacheKey])) { + return $this->dateFormatterCache[$cacheKey]; + } + + $this->dateFormatterCache[$cacheKey] = new \IntlDateFormatter( + $locale, + $style, + $timeStyle, + new \DateTimeZone($timeZone) + ); + + return $this->dateFormatterCache[$cacheKey]; + } } diff --git a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php index 09f85567e4c0d..2e8110316ec29 100644 --- a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php +++ b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php @@ -101,7 +101,12 @@ public function testDateIncludeTime($date, $locale, $includeTime, $expectedTimes /** @var \DateTime $dateTime */ $dateTime = $timezone->date($date, $locale, true, $includeTime); - $this->assertEquals($expectedTimestamp, $dateTime->getTimestamp()); + if (is_numeric($expectedTimestamp)) { + $this->assertEquals($expectedTimestamp, $dateTime->getTimestamp()); + } else { + $format = $includeTime ? DateTime::DATETIME_PHP_FORMAT : DateTime::DATE_PHP_FORMAT; + $this->assertEquals($expectedTimestamp, date($format, $dateTime->getTimestamp())); + } } /** @@ -151,7 +156,25 @@ public function dateIncludeTimeDataProvider(): array 'el_GR', // locale false, // include time 1635570000 // expected timestamp - ] + ], + 'Parse Saudi Arabia date without time' => [ + '31‏/8‏/2020 02020', + 'ar_SA', + false, + '2020-08-31' + ], + 'Parse date in short style with long year 1999' => [ + '9/11/1999', + 'en_US', + false, + '1999-09-11' + ], + 'Parse date in short style with long year 2099' => [ + '9/2/2099', + 'en_US', + false, + '2099-09-02' + ], ]; } From faf6dface4d7ac453c181fdad50a51e70e8e673c Mon Sep 17 00:00:00 2001 From: Janusz Janczy <janusz.janczy@snow.dog> Date: Mon, 7 Sep 2020 21:38:57 -0300 Subject: [PATCH 082/132] Fix gallery rendering on page load so current breakpoint configuration isn't replaced on page load by any other configuration --- .../tests/lib/mage/gallery/gallery.test.js | 45 +++++++++++++++++++ lib/web/mage/gallery/gallery.js | 34 +++++++++----- 2 files changed, 67 insertions(+), 12 deletions(-) diff --git a/dev/tests/js/jasmine/tests/lib/mage/gallery/gallery.test.js b/dev/tests/js/jasmine/tests/lib/mage/gallery/gallery.test.js index 7700c3d64a1b7..4cb48148e70c3 100644 --- a/dev/tests/js/jasmine/tests/lib/mage/gallery/gallery.test.js +++ b/dev/tests/js/jasmine/tests/lib/mage/gallery/gallery.test.js @@ -98,8 +98,53 @@ define([ expect(gallery.settings.fotoramaApi).toBeDefined(); expect(gallery.settings.data).toBeDefined(); expect(gallery.settings.api).toBeDefined(); + expect(gallery.settings.activeBreakpoint).toEqual({}); $.fn.data = originSpy; }); + + it('Verify gallery navigation is set properly as dots if specified in options', function () { + // added + options.breakpoints = { + mobile: { + conditions: { + 'max-width': '767px' + }, + options: { + options: { + nav: 'dots' + } + } + }, + desktop: { + conditions: { + 'min-width': '1024px' + }, + options: { + options: { + nav: 'thumbs' + } + } + } + }; + + originSpy = $.fn.data; + jqueryDataMock = { + setOptions: jasmine.createSpy().and.returnValue(true), + updateOptions: jasmine.createSpy().and.returnValue(true), + }; + spyOn($.fn, 'data').and.callFake(function () { + return jqueryDataMock; + }); + + gallery = new Gallery(options, element); + + options.breakpoints.mobile.options.options.arrows = false; + expect(JSON.stringify(gallery.settings.activeBreakpoint)) + .toEqual(JSON.stringify(options.breakpoints.mobile.options)); + + $.fn.data = originSpy; + }); + }); }); diff --git a/lib/web/mage/gallery/gallery.js b/lib/web/mage/gallery/gallery.js index 02ba72f64127b..70273cffbd9d1 100644 --- a/lib/web/mage/gallery/gallery.js +++ b/lib/web/mage/gallery/gallery.js @@ -318,13 +318,17 @@ define([ settings = this.settings, config = this.config, startConfig = this.startConfig, + isInitialized = {}, isTouchEnabled = this.isTouchEnabled; if (_.isObject(settings.breakpoints)) { pairs = _.pairs(settings.breakpoints); _.each(pairs, function (pair) { + var mediaQuery = pair[0]; + + isInitialized[mediaQuery] = false; mediaCheck({ - media: pair[0], + media: mediaQuery, /** * Is triggered when breakpoint enties. @@ -339,29 +343,35 @@ define([ } if (isTouchEnabled) { - settings.breakpoints[pair[0]].options.arrows = false; + settings.breakpoints[mediaQuery].options.arrows = false; - if (settings.breakpoints[pair[0]].options.fullscreen) { - settings.breakpoints[pair[0]].options.fullscreen.arrows = false; + if (settings.breakpoints[mediaQuery].options.fullscreen) { + settings.breakpoints[mediaQuery].options.fullscreen.arrows = false; } } - settings.api.updateOptions(settings.breakpoints[pair[0]].options, true); - $.extend(true, config, settings.breakpoints[pair[0]]); - settings.activeBreakpoint = settings.breakpoints[pair[0]]; + settings.api.updateOptions(settings.breakpoints[mediaQuery].options, true); + $.extend(true, config, settings.breakpoints[mediaQuery]); + settings.activeBreakpoint = settings.breakpoints[mediaQuery]; + + isInitialized[mediaQuery] = true; }, /** * Is triggered when breakpoint exits. */ exit: function () { - $.extend(true, config, _.clone(startConfig)); - settings.api.updateOptions(settings.defaultConfig.options, true); + if (isInitialized[mediaQuery]) { + $.extend(true, config, _.clone(startConfig)); + settings.api.updateOptions(settings.defaultConfig.options, true); - if (settings.isFullscreen) { - settings.api.updateOptions(settings.fullscreenConfig, true); + if (settings.isFullscreen) { + settings.api.updateOptions(settings.fullscreenConfig, true); + } + settings.activeBreakpoint = {}; + } else { + isInitialized[mediaQuery] = true; } - settings.activeBreakpoint = {}; } }); }); From de91c2ba7a3449858e9f464c720e3a3870797c7a Mon Sep 17 00:00:00 2001 From: "Leandro F. L" <lfluvisotto@gmail.com> Date: Fri, 11 Sep 2020 23:19:51 -0300 Subject: [PATCH 083/132] Modal content with good message format for newlines --- app/code/Magento/User/i18n/en_US.csv | 4 ++-- .../User/view/adminhtml/templates/role/users_grid_js.phtml | 6 +++--- .../User/view/adminhtml/templates/user/roles_grid_js.phtml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/User/i18n/en_US.csv b/app/code/Magento/User/i18n/en_US.csv index 064b6428387fe..cd550015401d0 100644 --- a/app/code/Magento/User/i18n/en_US.csv +++ b/app/code/Magento/User/i18n/en_US.csv @@ -106,8 +106,8 @@ username,username Custom,Custom All,All Resources,Resources -"Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?","Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?" -"Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?","Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?" +"Warning!<br>This action will remove this user from already assigned role.<br>Are you sure?","Warning!<br>This action will remove this user from already assigned role.<br>Are you sure?" +"Warning!<br>This action will remove those users from already assigned roles.<br>Are you sure?","Warning!<br>This action will remove those users from already assigned roles.<br>Are you sure?" "Password Reset Confirmation for %name","Password Reset Confirmation for %name" "%name,","%name," "There was recently a request to change the password for your account.","There was recently a request to change the password for your account." diff --git a/app/code/Magento/User/view/adminhtml/templates/role/users_grid_js.phtml b/app/code/Magento/User/view/adminhtml/templates/role/users_grid_js.phtml index 2042479832898..b0107a53593d3 100644 --- a/app/code/Magento/User/view/adminhtml/templates/role/users_grid_js.phtml +++ b/app/code/Magento/User/view/adminhtml/templates/role/users_grid_js.phtml @@ -51,8 +51,8 @@ if (is_object($myBlock) && $myBlock->getJsObjectName()): if (checked) { confirm({ - content: "{$myBlock->escapeJs(__('Warning!\r\nThis action will remove this user from already ' . - 'assigned role\r\nAre you sure?'))}", + content: "{$myBlock->escapeJs(__('Warning!<br>This action will remove this user from already ' . + 'assigned role.<br>Are you sure?'))}", actions: { confirm: function () { checkbox[0].checked = false; @@ -102,7 +102,7 @@ if (is_object($myBlock) && $myBlock->getJsObjectName()): allCheckbox.checked = true; confirm({ content: "{$myBlock->escapeJs( - __('Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?') + __('Warning!<br>This action will remove those users from already assigned roles.<br>Are you sure?') )}", actions: { confirm: function () { diff --git a/app/code/Magento/User/view/adminhtml/templates/user/roles_grid_js.phtml b/app/code/Magento/User/view/adminhtml/templates/user/roles_grid_js.phtml index 71a866f945693..7455c26334c02 100644 --- a/app/code/Magento/User/view/adminhtml/templates/user/roles_grid_js.phtml +++ b/app/code/Magento/User/view/adminhtml/templates/user/roles_grid_js.phtml @@ -45,7 +45,7 @@ if (is_object($myBlock) && $myBlock->getJsObjectName()): var checked = isInput ? checkbox[0].checked : !checkbox[0].checked; if (checked && warning && radioBoxes.size() > 0) { if ( !confirm("{$myBlock->escapeJs( - __('Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?') + __('Warning!<br>This action will remove this user from already assigned role.<br>Are you sure?') )}") ) { checkbox[0].checked = false; for(i in radioBoxes) { From 4fb010264fb7256e1cae8bfd4efa91090246dad6 Mon Sep 17 00:00:00 2001 From: Oleh Usik <o.usik@atwix.com> Date: Sun, 13 Sep 2020 20:08:36 +0300 Subject: [PATCH 084/132] apply recommendations --- .../Backend/Test/Mftf/Test/AdminDashboardWithChartsTest.xml | 3 +-- .../Test/AssociatedProductToConfigurableOutOfStockTest.xml | 3 +-- .../Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml | 3 +-- .../Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml | 2 +- ...oup.xml => AdminClickInvoiceButtonOrderViewActionGroup.xml} | 3 +-- .../Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml | 2 +- .../Test/Mftf/Test/CreateInvoiceAndCheckInvoiceOrderTest.xml | 2 +- .../Test/CreateInvoiceWithCashOnDeliveryPaymentMethodTest.xml | 2 +- .../CreateInvoiceWithShipmentAndCheckInvoicedOrderTest.xml | 2 +- .../Mftf/Test/CreateInvoiceWithZeroSubtotalCheckoutTest.xml | 2 +- .../Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml | 3 +-- 11 files changed, 11 insertions(+), 16 deletions(-) rename app/code/Magento/Sales/Test/Mftf/ActionGroup/{AdminClickInvoiceButtonIntoOrderActionGroup.xml => AdminClickInvoiceButtonOrderViewActionGroup.xml} (80%) diff --git a/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsTest.xml b/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsTest.xml index 439b6ac063618..fdc8eb9d3b759 100644 --- a/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsTest.xml +++ b/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsTest.xml @@ -84,8 +84,7 @@ <comment userInput="Create invoice" stepKey="createInvoice"/> <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceButton"/> - <waitForPageLoad stepKey="waitForInvoicePageToLoad"/> + <actionGroup ref="AdminClickInvoiceButtonOrderViewActionGroup" stepKey="clickInvoiceButton"/> <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seeNewInvoiceInPageTitle" after="clickInvoiceButton"/> <see selector="{{AdminInvoiceTotalSection.total('Subtotal')}}" userInput="$150.00" stepKey="seeCorrectGrandTotal"/> <actionGroup ref="AdminInvoiceClickSubmitActionGroup" stepKey="clickSubmitInvoice"/> diff --git a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml index f1c01919d52f1..09465dc314c50 100644 --- a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml +++ b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml @@ -125,8 +125,7 @@ <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask4"/> <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoice"/> - <waitForPageLoad stepKey="waitForNewInvoicePageToLoad"/> + <actionGroup ref="AdminClickInvoiceButtonOrderViewActionGroup" stepKey="clickInvoice"/> <actionGroup ref="AdminInvoiceClickSubmitActionGroup" stepKey="clickSubmitInvoice"/> <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The invoice has been created." stepKey="seeSuccessMessage"/> <click selector="{{AdminOrderDetailsMainActionsSection.ship}}" stepKey="clickShip"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml index 898e277cff55c..7f80603f66ddb 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml @@ -70,8 +70,7 @@ </actionGroup> <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceButton"/> - <waitForPageLoad stepKey="waitForNewInvoicePageLoad"/> + <actionGroup ref="AdminClickInvoiceButtonOrderViewActionGroup" stepKey="clickInvoiceButton"/> <fillField selector="{{AdminInvoiceItemsSection.qtyToInvoiceColumn}}" userInput="1" stepKey="ChangeQtyToInvoice"/> <click selector="{{AdminInvoiceItemsSection.updateQty}}" stepKey="updateQuantity"/> <waitForPageLoad stepKey="waitPageToBeLoaded"/> diff --git a/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml b/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml index 3e79eb044b5cb..6e9e8e800e076 100644 --- a/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml +++ b/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml @@ -47,7 +47,7 @@ <argument name="customer" value="$$createCustomer$$"/> </actionGroup> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceAction"/> + <actionGroup ref="AdminClickInvoiceButtonOrderViewActionGroup" stepKey="clickInvoiceAction"/> <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seePageNameNewInvoicePage"/> <actionGroup ref="AdminInvoiceClickSubmitActionGroup" stepKey="clickSubmitInvoice"/> <click selector="{{AdminOrderDetailsMainActionsSection.ship}}" stepKey="clickShipAction"/> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminClickInvoiceButtonIntoOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminClickInvoiceButtonOrderViewActionGroup.xml similarity index 80% rename from app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminClickInvoiceButtonIntoOrderActionGroup.xml rename to app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminClickInvoiceButtonOrderViewActionGroup.xml index d4a1c2c19b1e6..4617437595c9c 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminClickInvoiceButtonIntoOrderActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminClickInvoiceButtonOrderViewActionGroup.xml @@ -8,13 +8,12 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminClickInvoiceButtonIntoOrderActionGroup"> + <actionGroup name="AdminClickInvoiceButtonOrderViewActionGroup"> <annotations> <description>Click 'Invoice' button on the order view page.</description> </annotations> <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceAction"/> <waitForPageLoad stepKey="waitForProductPage"/> - <seeInCurrentUrl url="{{AdminInvoiceNewPage.url}}" stepKey="seeOrderInvoiceUrl"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml index 54aa456ae8e64..91a8f95880fbc 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml @@ -68,7 +68,7 @@ <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask4"/> <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> - <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoice"/> + <actionGroup ref="AdminClickInvoiceButtonOrderViewActionGroup" stepKey="clickInvoice"/> <actionGroup ref="AdminInvoiceClickSubmitActionGroup" stepKey="clickSubmitInvoice"/> <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The invoice has been created." stepKey="seeSuccessMessage"/> <click selector="{{AdminOrderDetailsOrderViewSection.invoices}}" stepKey="clickInvoices"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceAndCheckInvoiceOrderTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceAndCheckInvoiceOrderTest.xml index c1a69eb075f12..1143391bc70d7 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceAndCheckInvoiceOrderTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceAndCheckInvoiceOrderTest.xml @@ -84,7 +84,7 @@ <click selector="{{AdminDataGridTableSection.firstRow}}" stepKey="clickCreatedOrderInGrid"/> <!-- Go to invoice tab and fill data --> - <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoiceAction"/> + <actionGroup ref="AdminClickInvoiceButtonOrderViewActionGroup" stepKey="clickInvoiceAction"/> <fillField selector="{{AdminOrderInvoiceViewSection.invoiceQty}}" userInput="1" stepKey="fillInvoiceQuantity"/> <click selector="{{AdminOrderInvoiceViewSection.updateInvoiceBtn}}" stepKey="clickUpdateQtyInvoiceBtn"/> <fillField selector="{{AdminInvoiceTotalSection.invoiceComment}}" userInput="comment" stepKey="writeComment"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithCashOnDeliveryPaymentMethodTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithCashOnDeliveryPaymentMethodTest.xml index 9da2a8a4583dc..f245a1326628e 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithCashOnDeliveryPaymentMethodTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithCashOnDeliveryPaymentMethodTest.xml @@ -84,7 +84,7 @@ <click selector="{{AdminDataGridTableSection.firstRow}}" stepKey="clickCreatedOrderInGrid"/> <!-- Go to invoice tab and fill data --> - <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoiceAction"/> + <actionGroup ref="AdminClickInvoiceButtonOrderViewActionGroup" stepKey="clickInvoiceAction"/> <fillField selector="{{AdminOrderInvoiceViewSection.invoiceQty}}" userInput="1" stepKey="fillInvoiceQuantity"/> <click selector="{{AdminOrderInvoiceViewSection.updateInvoiceBtn}}" stepKey="clickUpdateQtyInvoiceBtn"/> <fillField selector="{{AdminInvoiceTotalSection.invoiceComment}}" userInput="comment" stepKey="writeComment"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithShipmentAndCheckInvoicedOrderTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithShipmentAndCheckInvoicedOrderTest.xml index cf29df126d387..a751745fedd9d 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithShipmentAndCheckInvoicedOrderTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithShipmentAndCheckInvoicedOrderTest.xml @@ -78,7 +78,7 @@ <click selector="{{AdminDataGridTableSection.firstRow}}" stepKey="clickCreatedOrderInGrid"/> <!-- Go to invoice tab and fill data --> - <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoiceAction"/> + <actionGroup ref="AdminClickInvoiceButtonOrderViewActionGroup" stepKey="clickInvoiceAction"/> <click selector="{{AdminInvoicePaymentShippingSection.CreateShipment}}" stepKey="createShipment"/> <fillField selector="{{AdminInvoiceTotalSection.invoiceComment}}" userInput="comment" stepKey="writeComment"/> <actionGroup ref="AdminInvoiceClickSubmitActionGroup" stepKey="clickSubmitInvoice"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithZeroSubtotalCheckoutTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithZeroSubtotalCheckoutTest.xml index 879c093a1da16..44102def21d7f 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithZeroSubtotalCheckoutTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreateInvoiceWithZeroSubtotalCheckoutTest.xml @@ -93,7 +93,7 @@ <click selector="{{AdminDataGridTableSection.firstRow}}" stepKey="clickCreatedOrderInGrid"/> <!-- Go to invoice tab and fill data --> - <actionGroup ref="AdminClickInvoiceButtonIntoOrderActionGroup" stepKey="clickInvoiceAction"/> + <actionGroup ref="AdminClickInvoiceButtonOrderViewActionGroup" stepKey="clickInvoiceAction"/> <fillField selector="{{AdminInvoiceTotalSection.invoiceComment}}" userInput="comment" stepKey="writeComment"/> <actionGroup ref="AdminInvoiceClickSubmitActionGroup" stepKey="clickSubmitInvoice"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml index e41e3acbae380..20dcb262b5831 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml @@ -102,8 +102,7 @@ <!-- Create invoice --> <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> - <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceButton"/> - <waitForPageLoad stepKey="waitForNewInvoicePageToLoad"/> + <actionGroup ref="AdminClickInvoiceButtonOrderViewActionGroup" stepKey="clickInvoiceButton"/> <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seeNewInvoiceInPageTitle" after="clickInvoiceButton"/> <!-- Verify Invoice Totals including subTotal Shipping Discount and GrandTotal --> From 09bd902440a57c2253f8f44abbbe1da8e98901fc Mon Sep 17 00:00:00 2001 From: Shankar Konar <konar.shankar2013@gmail.com> Date: Mon, 14 Sep 2020 10:32:43 +0530 Subject: [PATCH 085/132] Changes covered with Unit test --- .../Framework/File/Test/Unit/MimeTest.php | 1 + .../Framework/File/Test/Unit/_files/magento | Bin 0 -> 55303 bytes 2 files changed, 1 insertion(+) create mode 100644 lib/internal/Magento/Framework/File/Test/Unit/_files/magento diff --git a/lib/internal/Magento/Framework/File/Test/Unit/MimeTest.php b/lib/internal/Magento/Framework/File/Test/Unit/MimeTest.php index 3c571452d7a3e..7a54a7966b500 100644 --- a/lib/internal/Magento/Framework/File/Test/Unit/MimeTest.php +++ b/lib/internal/Magento/Framework/File/Test/Unit/MimeTest.php @@ -58,6 +58,7 @@ public function getMimeTypeDataProvider(): array 'weird extension' => [__DIR__ . '/_files/file.weird', 'application/octet-stream'], 'weird uppercase extension' => [__DIR__ . '/_files/UPPERCASE.WEIRD', 'application/octet-stream'], 'generic mime type' => [__DIR__ . '/_files/blank.html', 'text/html'], + 'tmp file mime type' => [__DIR__ . '/_files/magento', 'image/jpeg'], ]; } } diff --git a/lib/internal/Magento/Framework/File/Test/Unit/_files/magento b/lib/internal/Magento/Framework/File/Test/Unit/_files/magento new file mode 100644 index 0000000000000000000000000000000000000000..c377daf8fb0b390d89aa4f6f111715fc9118ca1b GIT binary patch literal 55303 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 Hh5vs5{BvNq literal 0 HcmV?d00001 From 9a6bd96ac0a0d71a1a8a597cbbd031fc3c420bc8 Mon Sep 17 00:00:00 2001 From: Viktor Kopin <viktor.kopin@transoftgroup.com> Date: Mon, 14 Sep 2020 10:53:09 +0300 Subject: [PATCH 086/132] magento/adobe-stock-integration#1806: fix static, refactoring --- .../Wysiwyg/Images/GetInsertImageContent.php | 5 - ...diaGalleryInsertLargeImageFileSizeTest.xml | 10 +- .../Controller/Adminhtml/Image/OnInsert.php | 90 ++--------- .../Model/GetInsertImageData.php | 140 ++++++++++++++++++ .../AdminEnhancedMediaGalleryImageData.xml | 9 -- app/code/Magento/MediaGalleryUi/etc/di.xml | 1 + .../grid/columns/image/insertImageAction.js | 4 +- .../Api/GetInsertImageDataInterface.php | 65 ++++++++ 8 files changed, 228 insertions(+), 96 deletions(-) create mode 100644 app/code/Magento/MediaGalleryUi/Model/GetInsertImageData.php create mode 100644 app/code/Magento/MediaGalleryUiApi/Api/GetInsertImageDataInterface.php diff --git a/app/code/Magento/Cms/Model/Wysiwyg/Images/GetInsertImageContent.php b/app/code/Magento/Cms/Model/Wysiwyg/Images/GetInsertImageContent.php index bfadd904eb283..305d73fff4dc7 100644 --- a/app/code/Magento/Cms/Model/Wysiwyg/Images/GetInsertImageContent.php +++ b/app/code/Magento/Cms/Model/Wysiwyg/Images/GetInsertImageContent.php @@ -10,11 +10,6 @@ use Magento\Catalog\Helper\Data as CatalogHelper; use Magento\Cms\Helper\Wysiwyg\Images as ImagesHelper; -use Magento\Framework\App\Filesystem\DirectoryList; -use Magento\Framework\File\Mime; -use Magento\Framework\Filesystem; -use Magento\Framework\Filesystem\Directory\ReadInterface; -use Magento\Framework\Filesystem\File\WriteInterface; class GetInsertImageContent { diff --git a/app/code/Magento/MediaGalleryRenditions/Test/Mftf/Test/AdminMediaGalleryInsertLargeImageFileSizeTest.xml b/app/code/Magento/MediaGalleryRenditions/Test/Mftf/Test/AdminMediaGalleryInsertLargeImageFileSizeTest.xml index d9e965b490666..27e1690d97e5a 100644 --- a/app/code/Magento/MediaGalleryRenditions/Test/Mftf/Test/AdminMediaGalleryInsertLargeImageFileSizeTest.xml +++ b/app/code/Magento/MediaGalleryRenditions/Test/Mftf/Test/AdminMediaGalleryInsertLargeImageFileSizeTest.xml @@ -14,8 +14,9 @@ <useCaseId value="https://github.com/magento/adobe-stock-integration/issues/1806"/> <title value="Admin user should see correct image file size after rendition"/> <testCaseId value="https://studio.cucumber.io/projects/131313/test-plan/folders/1507933/scenarios/5200023"/> + <stories value="User inserts image rendition to the content"/> <description value="Admin user should see correct image file size after rendition"/> - <severity value="MAJOR"/> + <severity value="AVERAGE"/> <group value="media_gallery_ui"/> </annotations> <before> @@ -31,7 +32,7 @@ <actionGroup ref="AdminOpenMediaGalleryFromCategoryImageUploaderActionGroup" stepKey="openMediaGalleryForDelete"/> <actionGroup ref="AdminEnhancedMediaGalleryEnableMassActionModeActionGroup" stepKey="enableMassActionToDeleteImages"/> <actionGroup ref="AdminEnhancedMediaGallerySelectImageForMassActionActionGroup" stepKey="selectSecondImageToDelete"> - <argument name="imageName" value="{{LargeImage.title}}"/> + <argument name="imageName" value="{{ImageUpload.fileName}}"/> </actionGroup> <actionGroup ref="AdminEnhancedMediaGalleryClickDeleteImagesButtonActionGroup" stepKey="clickDeleteSelectedButton"/> <actionGroup ref="AdminEnhancedMediaGalleryConfirmDeleteImagesActionGroup" stepKey="deleteImages"/> @@ -45,15 +46,14 @@ <actionGroup ref="AdminEditCategoryInGridPageActionGroup" stepKey="editCategoryItem"> <argument name="categoryName" value="$category.name$"/> </actionGroup> - <actionGroup ref="AdminSaveCategoryFormActionGroup" stepKey="saveCategoryForm"/> <!-- Add image to category from gallery --> <actionGroup ref="AdminOpenMediaGalleryFromCategoryImageUploaderActionGroup" stepKey="openMediaGallery"/> <actionGroup ref="AdminEnhancedMediaGalleryUploadImageActionGroup" stepKey="addCategoryImage"> - <argument name="image" value="LargeImage"/> + <argument name="image" value="ImageUpload"/> </actionGroup> <actionGroup ref="AdminMediaGalleryClickImageInGridActionGroup" stepKey="selectImage"> - <argument name="imageName" value="{{LargeImage.title}}"/> + <argument name="imageName" value="{{ImageUpload.fileName}}"/> </actionGroup> <actionGroup ref="AdminMediaGalleryClickAddSelectedActionGroup" stepKey="addSelected"/> diff --git a/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php b/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php index 0f812fe8940c6..9c8aeb9fa873a 100644 --- a/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php +++ b/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php @@ -8,65 +8,44 @@ use Magento\Backend\App\Action; use Magento\Backend\App\Action\Context; -use Magento\Cms\Model\Wysiwyg\Images\GetInsertImageContent; use Magento\Framework\App\Action\HttpPostActionInterface; -use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Controller\Result\JsonFactory; use Magento\Framework\Controller\ResultInterface; -use Magento\Framework\File\Mime; -use Magento\Framework\Filesystem; -use Magento\Framework\Filesystem\Directory\ReadInterface; -use Magento\Framework\Filesystem\File\WriteInterface; +use Magento\MediaGalleryUiApi\Api\GetInsertImageDataInterface; /** - * Class OnInsert + * OnInsert action returns on insert image details */ class OnInsert extends Action implements HttpPostActionInterface { /** - * @var JsonFactory - */ - private $resultJsonFactory; - - /** - * @var GetInsertImageContent - */ - private $getInsertImageContent; - - /** - * @var Filesystem + * @see _isAllowed() */ - private $filesystem; + public const ADMIN_RESOURCE = 'Magento_MediaGalleryUiApi::insert_assets'; /** - * @var Mime + * @var JsonFactory */ - private $mime; + private $resultJsonFactory; /** - * @var WriteInterface + * @var GetInsertImageDataInterface */ - private $pubDirectory; + private $getInsertImageData; /** * @param Context $context * @param JsonFactory $resultJsonFactory - * @param GetInsertImageContent|null $getInsertImageContent - * @param Filesystem $fileSystem - * @param Mime $mime + * @param GetInsertImageDataInterface|null $getInsertImageContent */ public function __construct( Context $context, JsonFactory $resultJsonFactory, - GetInsertImageContent $getInsertImageContent, - Filesystem $fileSystem, - Mime $mime + GetInsertImageDataInterface $getInsertImageData ) { parent::__construct($context); $this->resultJsonFactory = $resultJsonFactory; - $this->getInsertImageContent = $getInsertImageContent; - $this->filesystem = $fileSystem; - $this->mime = $mime; + $this->getInsertImageData = $getInsertImageData; } /** @@ -77,54 +56,15 @@ public function __construct( public function execute() { $data = $this->getRequest()->getParams(); - $path = $this->getInsertImageContent->execute( + $content = $this->getInsertImageData->getImageContent( $data['filename'], $data['force_static_path'], $data['as_is'], isset($data['store']) ? (int)$data['store'] : null ); - $size = $data['force_static_path'] ? $this->getImageSize($path) : 0; - $type = $data['force_static_path'] ? $this->getMimeType($path) : ''; - return $this->resultJsonFactory->create()->setData(['path' => $path, 'size' => $size, 'type' => $type]); - } - - /** - * Retrieve size of requested file - * - * @param string $path - * @return int - */ - private function getImageSize(string $path): int - { - $directory = $this->getPubDirectory(); - - return $directory->isExist($path) ? $directory->stat($path)['size'] : 0; - } - - /** - * Retrieve MIME type of requested file - * - * @param string $path - * @return string - */ - private function getMimeType(string $path) - { - $absoluteFilePath = $this->getPubDirectory()->getAbsolutePath($path); - - return $this->mime->getMimeType($absoluteFilePath); - } - - /** - * Retrieve pub directory read interface instance - * - * @return ReadInterface - */ - private function getPubDirectory() - { - if ($this->pubDirectory === null) { - $this->pubDirectory = $this->filesystem->getDirectoryRead(DirectoryList::PUB); - } - return $this->pubDirectory; + $size = $data['force_static_path'] ? $this->getInsertImageData->getFileSize($content) : 0; + $type = $data['force_static_path'] ? $this->getInsertImageData->getMimeType($content) : ''; + return $this->resultJsonFactory->create()->setData(['content' => $content, 'size' => $size, 'type' => $type]); } } diff --git a/app/code/Magento/MediaGalleryUi/Model/GetInsertImageData.php b/app/code/Magento/MediaGalleryUi/Model/GetInsertImageData.php new file mode 100644 index 0000000000000..b226c1d40ab72 --- /dev/null +++ b/app/code/Magento/MediaGalleryUi/Model/GetInsertImageData.php @@ -0,0 +1,140 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\MediaGalleryUi\Model; + +use Magento\Cms\Model\Wysiwyg\Images\GetInsertImageContent; +use Magento\Framework\Api\ExtensionAttributesInterface; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\File\Mime; +use Magento\Framework\Filesystem; +use Magento\Framework\Filesystem\Directory\ReadInterface; +use Magento\MediaGalleryUiApi\Api\GetInsertImageDataInterface; + +/** + * Class responsible to provide insert image details + */ +class GetInsertImageData implements GetInsertImageDataInterface +{ + private $extensionAttributes; + + /** + * @var GetInsertImageContent + */ + private $getInsertImageContent; + + /** + * @var Filesystem + */ + private $filesystem; + + /** + * @var Mime + */ + private $mime; + + /** + * @var ReadInterface + */ + private $pubDirectory; + + /** + * GetInsertImageData constructor. + * + * @param GetInsertImageContent $getInsertImageContent + * @param Filesystem $fileSystem + * @param Mime $mime + */ + public function __construct( + GetInsertImageContent $getInsertImageContent, + Filesystem $fileSystem, + Mime $mime + ) { + $this->getInsertImageContent = $getInsertImageContent; + $this->filesystem = $fileSystem; + $this->mime = $mime; + } + + /** + * Retrieves a content (just a link or an html block) for inserting image to the content + * + * @param string $encodedFilename + * @param bool $forceStaticPath + * @param bool $renderAsTag + * @param int|null $storeId + * @return null|string + */ + public function getImageContent( + string $encodedFilename, + bool $forceStaticPath, + bool $renderAsTag, + ?int $storeId = null + ): string { + return $this->getInsertImageContent->execute($encodedFilename, $forceStaticPath, $renderAsTag, $storeId); + } + + /** + * Retrieve size of requested file + * + * @param string $path + * @return int + */ + public function getFileSize(string $path): int + { + $directory = $this->getPubDirectory(); + + return $directory->isExist($path) ? $directory->stat($path)['size'] : 0; + } + + /** + * Retrieve MIME type of requested file + * + * @param string $path + * @return string + */ + public function getMimeType(string $path): string + { + $absoluteFilePath = $this->getPubDirectory()->getAbsolutePath($path); + + return $this->getPubDirectory()->isExist($path) ? $this->mime->getMimeType($absoluteFilePath) : ''; + } + + /** + * Retrieve pub directory read interface instance + * + * @return ReadInterface + */ + private function getPubDirectory(): ReadInterface + { + if ($this->pubDirectory === null) { + $this->pubDirectory = $this->filesystem->getDirectoryRead(DirectoryList::PUB); + } + return $this->pubDirectory; + } + + /** + * Get extension attributes + * + * @return ExtensionAttributesInterface|null + */ + public function getExtensionAttributes(): ?ExtensionAttributesInterface + { + return $this->extensionAttributes; + } + + /** + * Set extension attributes + * + * @param ExtensionAttributesInterface|null $extensionAttributes + * @return void + */ + public function setExtensionAttributes(?ExtensionAttributesInterface $extensionAttributes): void + { + $this->extensionAttributes = $extensionAttributes; + } +} diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/Data/AdminEnhancedMediaGalleryImageData.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/Data/AdminEnhancedMediaGalleryImageData.xml index 26e0ac180e7fe..dbc298798ee8e 100644 --- a/app/code/Magento/MediaGalleryUi/Test/Mftf/Data/AdminEnhancedMediaGalleryImageData.xml +++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/Data/AdminEnhancedMediaGalleryImageData.xml @@ -40,13 +40,4 @@ <data key="extension">jpg</data> <data key="keywords">magento, mediagallerymetadata</data> </entity> - <entity name="LargeImage" type="image"> - <data key="title">magento</data> - <data key="description">Description of the large magento image</data> - <data key="file">magento.jpg</data> - <data key="value">magento.jpg</data> - <data key="fileName">magento</data> - <data key="extension">jpg</data> - <data key="keywords">magento, mediagallerymetadata</data> - </entity> </entities> diff --git a/app/code/Magento/MediaGalleryUi/etc/di.xml b/app/code/Magento/MediaGalleryUi/etc/di.xml index 6ed3a98bbf03a..5f80406ec75ab 100644 --- a/app/code/Magento/MediaGalleryUi/etc/di.xml +++ b/app/code/Magento/MediaGalleryUi/etc/di.xml @@ -7,6 +7,7 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\MediaGalleryUiApi\Api\ConfigInterface" type="Magento\MediaGalleryUi\Model\Config"/> + <preference for="Magento\MediaGalleryUiApi\Api\GetInsertImageDataInterface" type="Magento\MediaGalleryUi\Model\GetInsertImageData"/> <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory"> <arguments> <argument name="collections" xsi:type="array"> diff --git a/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/grid/columns/image/insertImageAction.js b/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/grid/columns/image/insertImageAction.js index 57e1f3cebd881..322b29c92ca5b 100644 --- a/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/grid/columns/image/insertImageAction.js +++ b/app/code/Magento/MediaGalleryUi/view/adminhtml/web/js/grid/columns/image/insertImageAction.js @@ -47,11 +47,11 @@ define([ showLoader: true }).done($.proxy(function (data) { if (targetElement.is('textarea')) { - this.insertAtCursor(targetElement.get(0), data.path); + this.insertAtCursor(targetElement.get(0), data.content); targetElement.focus(); $(targetElement).change(); } else { - targetElement.val(data.path) + targetElement.val(data.content) .data('size', data.size) .data('mime-type', data.type) .trigger('change'); diff --git a/app/code/Magento/MediaGalleryUiApi/Api/GetInsertImageDataInterface.php b/app/code/Magento/MediaGalleryUiApi/Api/GetInsertImageDataInterface.php new file mode 100644 index 0000000000000..0be264bcb7189 --- /dev/null +++ b/app/code/Magento/MediaGalleryUiApi/Api/GetInsertImageDataInterface.php @@ -0,0 +1,65 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\MediaGalleryUiApi\Api; + +use Magento\Framework\Api\ExtensibleDataInterface; +use Magento\Framework\Api\ExtensionAttributesInterface; + +/** + * Class responsible to provide insert image details + */ +interface GetInsertImageDataInterface extends ExtensibleDataInterface +{ + /** + * Retrieves a content (just a link or an html block) for inserting image to the content + * + * @param string $encodedFilename + * @param bool $forceStaticPath + * @param bool $renderAsTag + * @param int|null $storeId + * @return null|string + */ + public function getImageContent( + string $encodedFilename, + bool $forceStaticPath, + bool $renderAsTag, + ?int $storeId = null + ): string; + + /** + * Retrieve size of requested file + * + * @param string $path + * @return int + */ + public function getFileSize(string $path): int; + + /** + * Retrieve MIME type of requested file + * + * @param string $path + * @return string + */ + public function getMimeType(string $path): string; + + /** + * Get extension attributes + * + * @return ExtensionAttributesInterface|null + */ + public function getExtensionAttributes(): ?ExtensionAttributesInterface; + + /** + * Set extension attributes + * + * @param ExtensionAttributesInterface|null $extensionAttributes + * @return void + */ + public function setExtensionAttributes(?ExtensionAttributesInterface $extensionAttributes): void; +} From 6572d43d3067e548f686ad0db85c81b064b47604 Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Mon, 14 Sep 2020 11:32:42 +0300 Subject: [PATCH 087/132] MC-36971: Create automated test for "Calculation of invoiced child items in "sales_order_item" table for order with configurable product after partial invoice" --- .../Adminhtml/Order/Invoice/SaveTest.php | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Invoice/SaveTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Invoice/SaveTest.php index 13003e40dc0a3..dc903107d5ce3 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Invoice/SaveTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Invoice/SaveTest.php @@ -9,7 +9,9 @@ use Magento\Framework\Escaper; use Magento\Sales\Api\Data\InvoiceInterface; +use Magento\Sales\Api\Data\OrderItemInterface; use Magento\Sales\Model\Order; +use Magento\Sales\Model\ResourceModel\Order\Item; use PHPUnit\Framework\Constraint\StringContains; /** @@ -28,6 +30,9 @@ class SaveTest extends AbstractInvoiceControllerTest /** @var Escaper */ private $escaper; + /** @var Item */ + private $orderItemResource; + /** * @inheritdoc */ @@ -36,6 +41,7 @@ protected function setUp(): void parent::setUp(); $this->escaper = $this->_objectManager->get(Escaper::class); + $this->orderItemResource = $this->_objectManager->get(Item::class); } /** @@ -173,6 +179,39 @@ public function testInvoiceWithoutQty(): void $this->assertErrorResponse($this->escaper->escapeHtml($expectedMessage)); } + /** + * @magentoDataFixture Magento/Sales/_files/order_configurable_product.php + * + * @return void + */ + public function testPartialInvoiceWitConfigurableProduct(): void + { + $order = $this->getOrder('100000001'); + $post = $this->hydratePost([$order->getItemsCollection()->getFirstItem()->getId() => '1']); + $this->prepareRequest($post, ['order_id' => $order->getEntityId()]); + $this->dispatch('backend/sales/order_invoice/save'); + $this->assertSessionMessages($this->containsEqual((string)__('The invoice has been created.'))); + $orderItems = $this->getOrderItemsQtyInvoiced((int)$order->getEntityId()); + $this->assertCount(2, $orderItems); + $this->assertEquals($orderItems[0]['qty_invoiced'], $orderItems[1]['qty_invoiced']); + } + + /** + * Get order items qty invoiced + * + * @param int $orderId + * @return array + */ + private function getOrderItemsQtyInvoiced(int $orderId): array + { + $connection = $this->orderItemResource->getConnection(); + $select = $connection->select() + ->from($this->orderItemResource->getMainTable(), OrderItemInterface::QTY_INVOICED) + ->where(OrderItemInterface::ORDER_ID . ' = ?', $orderId); + + return $connection->fetchAll($select); + } + /** * @inheritdoc */ From 9d0252a47858a2c268181a2e77606a5a6bcdc6cb Mon Sep 17 00:00:00 2001 From: Viktor Kopin <viktor.kopin@transoftgroup.com> Date: Mon, 14 Sep 2020 11:47:12 +0300 Subject: [PATCH 088/132] magento/adobe-stock-integration#1806: fix static --- .../Controller/Adminhtml/Image/OnInsert.php | 2 +- .../MediaGalleryUi/Model/GetInsertImageData.php | 13 ++++++++----- .../Api/GetInsertImageDataInterface.php | 11 ++++++----- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php b/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php index 9c8aeb9fa873a..848fb7cd39119 100644 --- a/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php +++ b/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php @@ -36,7 +36,7 @@ class OnInsert extends Action implements HttpPostActionInterface /** * @param Context $context * @param JsonFactory $resultJsonFactory - * @param GetInsertImageDataInterface|null $getInsertImageContent + * @param GetInsertImageDataInterface|null $getInsertImageData */ public function __construct( Context $context, diff --git a/app/code/Magento/MediaGalleryUi/Model/GetInsertImageData.php b/app/code/Magento/MediaGalleryUi/Model/GetInsertImageData.php index b226c1d40ab72..03481f6a98a93 100644 --- a/app/code/Magento/MediaGalleryUi/Model/GetInsertImageData.php +++ b/app/code/Magento/MediaGalleryUi/Model/GetInsertImageData.php @@ -9,11 +9,11 @@ namespace Magento\MediaGalleryUi\Model; use Magento\Cms\Model\Wysiwyg\Images\GetInsertImageContent; -use Magento\Framework\Api\ExtensionAttributesInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\File\Mime; use Magento\Framework\Filesystem; use Magento\Framework\Filesystem\Directory\ReadInterface; +use Magento\MediaGalleryUiApi\Api\GetInsertImageDataExtensionInterface; use Magento\MediaGalleryUiApi\Api\GetInsertImageDataInterface; /** @@ -21,6 +21,9 @@ */ class GetInsertImageData implements GetInsertImageDataInterface { + /** + * @var GetInsertImageDataExtensionInterface + */ private $extensionAttributes; /** @@ -120,9 +123,9 @@ private function getPubDirectory(): ReadInterface /** * Get extension attributes * - * @return ExtensionAttributesInterface|null + * @return GetInsertImageDataExtensionInterface|null */ - public function getExtensionAttributes(): ?ExtensionAttributesInterface + public function getExtensionAttributes(): ?GetInsertImageDataExtensionInterface { return $this->extensionAttributes; } @@ -130,10 +133,10 @@ public function getExtensionAttributes(): ?ExtensionAttributesInterface /** * Set extension attributes * - * @param ExtensionAttributesInterface|null $extensionAttributes + * @param GetInsertImageDataExtensionInterface|null $extensionAttributes * @return void */ - public function setExtensionAttributes(?ExtensionAttributesInterface $extensionAttributes): void + public function setExtensionAttributes(?GetInsertImageDataExtensionInterface $extensionAttributes): void { $this->extensionAttributes = $extensionAttributes; } diff --git a/app/code/Magento/MediaGalleryUiApi/Api/GetInsertImageDataInterface.php b/app/code/Magento/MediaGalleryUiApi/Api/GetInsertImageDataInterface.php index 0be264bcb7189..470abf0770a21 100644 --- a/app/code/Magento/MediaGalleryUiApi/Api/GetInsertImageDataInterface.php +++ b/app/code/Magento/MediaGalleryUiApi/Api/GetInsertImageDataInterface.php @@ -9,7 +9,6 @@ namespace Magento\MediaGalleryUiApi\Api; use Magento\Framework\Api\ExtensibleDataInterface; -use Magento\Framework\Api\ExtensionAttributesInterface; /** * Class responsible to provide insert image details @@ -51,15 +50,17 @@ public function getMimeType(string $path): string; /** * Get extension attributes * - * @return ExtensionAttributesInterface|null + * @return \Magento\MediaGalleryUiApi\Api\GetInsertImageDataExtensionInterface|null */ - public function getExtensionAttributes(): ?ExtensionAttributesInterface; + public function getExtensionAttributes(): ?\Magento\MediaGalleryUiApi\Api\GetInsertImageDataExtensionInterface; /** * Set extension attributes * - * @param ExtensionAttributesInterface|null $extensionAttributes + * @param \Magento\MediaGalleryUiApi\Api\GetInsertImageDataExtensionInterface|null $extensionAttributes * @return void */ - public function setExtensionAttributes(?ExtensionAttributesInterface $extensionAttributes): void; + public function setExtensionAttributes( + ?\Magento\MediaGalleryUiApi\Api\GetInsertImageDataExtensionInterface $extensionAttributes + ): void; } From 6b680631b74287afc3ead77863501282411fbad4 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Mon, 14 Sep 2020 14:05:13 +0300 Subject: [PATCH 089/132] MC-25238: Unstable Test "StorefrontCheckoutWithDifferentShippingAndBillingAddressAndRegisterCustomerAfterCheckoutTest" --- ...tFillEstimateShippingAndTaxActionGroup.xml | 17 ++++ ...ressAndCreateCustomerAfterCheckoutTest.xml | 99 +++++++++++++++++++ ...ssAndRegisterCustomerAfterCheckoutTest.xml | 7 +- .../AdminDeleteCustomerInGridActionGroup.xml | 27 +++++ 4 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Checkout/Test/Mftf/ActionGroup/CartFillEstimateShippingAndTaxActionGroup.xml create mode 100644 app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndCreateCustomerAfterCheckoutTest.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerInGridActionGroup.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CartFillEstimateShippingAndTaxActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CartFillEstimateShippingAndTaxActionGroup.xml new file mode 100644 index 0000000000000..14609ce1a8bf0 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CartFillEstimateShippingAndTaxActionGroup.xml @@ -0,0 +1,17 @@ +<?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="CartFillEstimateShippingAndTaxActionGroup" extends="CheckoutFillEstimateShippingAndTaxActionGroup"> + <arguments> + <argument name="address" defaultValue="US_Address_TX" type="entity"/> + </arguments> + <waitForElementVisible selector="{{CheckoutCartSummarySection.estimateShippingAndTax}}" after="openShippingDetails" stepKey="waitForSummarySectionLoad"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndCreateCustomerAfterCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndCreateCustomerAfterCheckoutTest.xml new file mode 100644 index 0000000000000..9f3eb0c9e3118 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndCreateCustomerAfterCheckoutTest.xml @@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontCheckoutWithDifferentShippingAndBillingAddressAndCreateCustomerAfterCheckoutTest"> + <annotations> + <stories value="Checkout"/> + <title value="Verify UK customer checkout with different billing and shipping address and register customer after checkout"/> + <description value="Checkout as UK customer with different shipping/billing address and register checkout method"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-14712"/> + <group value="mtf_migrated"/> + </annotations> + + <before> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginToAdminPanel"/> + <createData entity="SimpleProduct2" stepKey="simpleProduct"> + <field key="price">50.00</field> + </createData> + </before> + <after> + <!-- Sign out Customer from storefront --> + <actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="openHomePage"/> + <actionGroup ref="StorefrontSignOutActionGroup" stepKey="customerLogout"/> + <deleteData createDataKey="simpleProduct" stepKey="deleteProduct"/> + <actionGroup ref="AdminDeleteCustomerInGridActionGroup" stepKey="deleteCustomer"> + <argument name="customerEmail" value="UKCustomer.email"/> + </actionGroup> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + </after> + + <!--Open Product page in StoreFront and assert product and price range --> + <actionGroup ref="AssertProductNameAndSkuInStorefrontProductPageByCustomAttributeUrlKeyActionGroup" stepKey="openProductPageAndVerifyProduct"> + <argument name="product" value="$$simpleProduct$$"/> + </actionGroup> + + <!--Add product to the cart --> + <actionGroup ref="StorefrontAddProductToCartWithQtyActionGroup" stepKey="addSimpleProductToCart"> + <argument name="productQty" value="1"/> + </actionGroup> + + <!--Open View and edit --> + <actionGroup ref="ClickViewAndEditCartFromMiniCartActionGroup" stepKey="openCartFromMiniCart"/> + + <!-- Fill the Estimate Shipping and Tax section --> + <actionGroup ref="CartFillEstimateShippingAndTaxActionGroup" stepKey="fillEstimateShippingAndTaxFields"/> + <click selector="{{CheckoutCartSummarySection.proceedToCheckout}}" stepKey="goToCheckout"/> + <waitForPageLoad stepKey="waitForPageToLoad"/> + + <!-- Fill the guest form --> + <actionGroup ref="FillGuestCheckoutShippingAddressFormActionGroup" stepKey="fillGuestShippingAddress"> + <argument name="customer" value="UKCustomer"/> + <argument name="customerAddress" value="updateCustomerUKAddress"/> + </actionGroup> + <actionGroup ref="StorefrontCheckoutClickNextButtonActionGroup" stepKey="goToBillingStep"/> + <waitForElementVisible selector="{{CheckoutPaymentSection.billingAddressNotSameCheckbox}}" stepKey="waitForSameBillingAndShippingAddressCheckboxVisible"/> + <uncheckOption selector="{{CheckoutPaymentSection.billingAddressNotSameCheckbox}}" stepKey="uncheckSameBillingAndShippingAddress"/> + <conditionalClick selector="{{CheckoutShippingSection.editAddressButton}}" dependentSelector="{{CheckoutShippingSection.editAddressButton}}" visible="true" stepKey="clickEditBillingAddressButton"/> + <waitForLoadingMaskToDisappear stepKey="waitForBillingAddressFormLoad"/> + + <!-- Fill Billing Address --> + <actionGroup ref="StorefrontFillBillingAddressActionGroup" stepKey="fillBillingAddressForm"/> + <click selector="{{CheckoutPaymentSection.update}}" stepKey="clickOnUpdateBillingAddressButton"/> + + <!--Place order --> + <actionGroup ref="ClickPlaceOrderActionGroup" stepKey="clickOnPlaceOrder"/> + <seeElement selector="{{StorefrontMinicartSection.emptyMiniCart}}" stepKey="assertEmptyCart" /> + <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumberWithoutLink}}" stepKey="orderId"/> + + <!-- Register customer after checkout --> + <actionGroup ref="StorefrontRegisterCustomerAfterCheckoutActionGroup" stepKey="registerCustomer"/> + + <!-- Open Order Index Page --> + <actionGroup ref="AdminOrdersPageOpenActionGroup" stepKey="goToOrdersGrid"/> + + <!-- Filter Order using orderId and assert order--> + <actionGroup ref="FilterOrderGridByIdActionGroup" stepKey="filterOrderGridById"> + <argument name="orderId" value="$orderId"/> + </actionGroup> + + <click selector="{{AdminOrdersGridSection.viewLink('$orderId')}}" stepKey="openOrderPage"/> + <waitForPageLoad stepKey="waitForOrderPageToLoad"/> + + <!-- Assert Grand Total --> + <see selector="{{AdminOrderTotalSection.grandTotal}}" userInput="$55.00" stepKey="seeGrandTotal"/> + <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Pending" stepKey="seeOrderStatus"/> + + <!-- Ship the order and assert the status --> + <actionGroup ref="AdminShipThePendingOrderActionGroup" stepKey="shipTheOrder"/> + + <!-- Assert order buttons --> + <actionGroup ref="AdminAssertOrderAvailableButtonsActionGroup" stepKey="assertOrderButtons"/> + </test> +</tests> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndRegisterCustomerAfterCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndRegisterCustomerAfterCheckoutTest.xml index cf10db2352df8..118205e912b5e 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndRegisterCustomerAfterCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndRegisterCustomerAfterCheckoutTest.xml @@ -7,14 +7,17 @@ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="StorefrontCheckoutWithDifferentShippingAndBillingAddressAndRegisterCustomerAfterCheckoutTest"> + <test name="StorefrontCheckoutWithDifferentShippingAndBillingAddressAndRegisterCustomerAfterCheckoutTest" deprecated="Use StorefrontCheckoutWithDifferentShippingAndBillingAddressAndCreateCustomerAfterCheckoutTest instead"> <annotations> <stories value="Checkout"/> - <title value="Verify UK customer checkout with different billing and shipping address and register customer after checkout"/> + <title value="DEPRECATED. Verify UK customer checkout with different billing and shipping address and register customer after checkout"/> <description value="Checkout as UK customer with different shipping/billing address and register checkout method"/> <severity value="CRITICAL"/> <testCaseId value="MC-14712"/> <group value="mtf_migrated"/> + <skip> + <issueId value="DEPRECATED">Use StorefrontCheckoutWithDifferentShippingAndBillingAddressAndCreateCustomerAfterCheckoutTest instead</issueId> + </skip> </annotations> <before> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerInGridActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerInGridActionGroup.xml new file mode 100644 index 0000000000000..deb6b992a50db --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerInGridActionGroup.xml @@ -0,0 +1,27 @@ +<?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="AdminDeleteCustomerInGridActionGroup" extends="AdminDeleteCustomerActionGroup"> + <arguments> + <argument name="customerEmail"/> + </arguments> + + <remove keyForRemoval="openFilters"/> + <remove keyForRemoval="fillEmail"/> + <remove keyForRemoval="clickApplyFilters"/> + <remove keyForRemoval="chooseCustomer"/> + <click selector="{{AdminDataGridHeaderSection.filters}}" after="waitForFiltersClear" stepKey="openFiltersSection"/> + <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="AdminDataGridHeaderSection.clearFilters" visible="true" after="openFiltersSection" stepKey="clearFiltersIfTheyAreSet"/> + <fillField userInput="{{customerEmail}}" selector="{{AdminCustomerFiltersSection.emailInput}}" after="clearFiltersIfTheyAreSet" stepKey="fillEmailFilterField"/> + <click selector="{{AdminCustomerFiltersSection.apply}}" after="fillEmailFilterField" stepKey="applyEmailFilter"/> + <waitForElementVisible selector="{{AdminCustomerGridMainActionsSection.customerCheckbox(customerEmail)}}" after="applyEmailFilter" stepKey="waitForAppliedFilterLoad"/> + <click selector="{{AdminCustomerGridMainActionsSection.customerCheckbox(customerEmail)}}" after="waitForAppliedFilterLoad" stepKey="chooseCustomer"/> + </actionGroup> +</actionGroups> From 145922d2c34b2afdcecabbedf1320050d1353a7d Mon Sep 17 00:00:00 2001 From: mastiuhin-olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Mon, 14 Sep 2020 14:17:07 +0300 Subject: [PATCH 090/132] MC-34344: AdminLoginAfterJSMinificationTest does not properly enable minification --- .../Test/Mftf/Test/AdminLoginAfterJSMinificationTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Test/Mftf/Test/AdminLoginAfterJSMinificationTest.xml b/app/code/Magento/Backend/Test/Mftf/Test/AdminLoginAfterJSMinificationTest.xml index 8e684868a1539..af0a5751a7488 100644 --- a/app/code/Magento/Backend/Test/Mftf/Test/AdminLoginAfterJSMinificationTest.xml +++ b/app/code/Magento/Backend/Test/Mftf/Test/AdminLoginAfterJSMinificationTest.xml @@ -31,8 +31,8 @@ <magentoCLI command="config:set {{MinifyJavaScriptFilesDisableConfigData.path}} {{MinifyJavaScriptFilesDisableConfigData.value}}" stepKey="disableJsMinification"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> - <see userInput="Dashboard" selector="{{AdminHeaderSection.pageTitle}}" stepKey="seeDashboardTitle"/> <waitForPageLoad stepKey="waitForPageLoadOnDashboard"/> + <see userInput="Dashboard" selector="{{AdminHeaderSection.pageTitle}}" stepKey="seeDashboardTitle"/> <actionGroup ref="AssertAdminSuccessLoginActionGroup" stepKey="loggedInSuccessfully"/> <actionGroup ref="AssertAdminPageIsNot404ActionGroup" stepKey="dontSee404Page"/> </test> From d117405b0bd3533ed85da241e32b1c51c24ecff9 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Mon, 14 Sep 2020 14:45:43 +0300 Subject: [PATCH 091/132] MC-36831: Unexpected "Image" section appears when creating product scheduled update --- .../view/adminhtml/templates/helper/gallery.phtml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ProductVideo/view/adminhtml/templates/helper/gallery.phtml b/app/code/Magento/ProductVideo/view/adminhtml/templates/helper/gallery.phtml index b729eadf122c5..b75b59eeacce2 100644 --- a/app/code/Magento/ProductVideo/view/adminhtml/templates/helper/gallery.phtml +++ b/app/code/Magento/ProductVideo/view/adminhtml/templates/helper/gallery.phtml @@ -268,7 +268,8 @@ $elementToggleCode = $element->getToggleCode() ? $element->getToggleCode(): </fieldset> </div> </script> - <div id="new_video_<?= /* @noEscape */ $block->getNewVideoBlockName() ?>"> + <?php $videoBlockId = "new_video_" . $block->getHtmlId() . rand(); ?> + <div id="<?= /* @noEscape */ $videoBlockId ?>"> <?= $block->getFormHtml() ?> <div id="video-player-preview-location" class="video-player-sidebar"> <div class="video-player-container"></div> @@ -288,7 +289,7 @@ $elementToggleCode = $element->getToggleCode() ? $element->getToggleCode(): </div> <?= /* @noEscape */ $secureRenderer->renderStyleAsTag( 'display:none', - 'div#new_video_' . /* @noEscape */ $block->getNewVideoBlockName() + 'div#' . $videoBlockId ) ?> <?= $block->getChildHtml('new-video') ?> From 4d360719963db55bafa2e2fea885c2667d5873e7 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Mon, 14 Sep 2020 15:49:14 +0300 Subject: [PATCH 092/132] MC-25249: Unstable Test "AdminUpdateCategoryWithProductsTest" --- ...CategoryWithProductsDefaultSortingTest.xml | 72 +++++++++++++++++++ .../AdminUpdateCategoryWithProductsTest.xml | 7 +- 2 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithProductsDefaultSortingTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithProductsDefaultSortingTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithProductsDefaultSortingTest.xml new file mode 100644 index 0000000000000..e8998203296ed --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithProductsDefaultSortingTest.xml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminUpdateCategoryWithProductsDefaultSortingTest"> + <annotations> + <features value="Catalog"/> + <stories value="Update categories"/> + <title value="Update category, sort products by default sorting"/> + <description value="Login as admin, update category and sort products"/> + <testCaseId value="MC-25667"/> + <severity value="CRITICAL"/> + <group value="catalog"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <createData entity="defaultSimpleProduct" stepKey="simpleProduct" /> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginToAdminPanel"/> + </before> + <after> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="simpleProduct" stepKey="deleteSimpleProduct"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> + </after> + + <!--Open Category Page--> + <actionGroup ref="GoToAdminCategoryPageByIdActionGroup" stepKey="goToAdminCategoryPage"> + <argument name="id" value="$createCategory.id$"/> + </actionGroup> + + <!--Update Product Display Setting--> + <waitForElementVisible selector="{{AdminCategoryDisplaySettingsSection.settingsHeader}}" stepKey="waitForDisplaySettingsSection"/> + <conditionalClick selector="{{AdminCategoryDisplaySettingsSection.settingsHeader}}" dependentSelector="{{AdminCategoryDisplaySettingsSection.displayMode}}" visible="false" stepKey="openDisplaySettingsSection"/> + <click selector="{{CategoryDisplaySettingsSection.productListCheckBox}}" stepKey="enableTheAvailableProductList"/> + <selectOption selector="{{CategoryDisplaySettingsSection.productList}}" parameterArray="['Product Name', 'Price']" stepKey="selectPrice"/> + <waitForElementVisible selector="{{CategoryDisplaySettingsSection.defaultProductLisCheckBox}}" stepKey="waitForDefaultProductList"/> + <click selector="{{CategoryDisplaySettingsSection.defaultProductLisCheckBox}}" stepKey="enableTheDefaultProductList"/> + <selectOption selector="{{CategoryDisplaySettingsSection.defaultProductList}}" userInput="name" stepKey="selectProductName"/> + + <!--Add Products in Category--> + <actionGroup ref="AdminCategoryAssignProductActionGroup" stepKey="assignSimpleProductToCategory"> + <argument name="productSku" value="$simpleProduct.sku$"/> + </actionGroup> + <actionGroup ref="AdminSaveCategoryFormActionGroup" stepKey="saveCategory"/> + + <!--Verify Category Title--> + <see selector="{{AdminCategoryContentSection.categoryPageTitle}}" userInput="{{_defaultCategory.name}}" stepKey="seeCategoryNamePageTitle" /> + + <!--Verify Category in store front page--> + <actionGroup ref="StorefrontGoToCategoryPageActionGroup" stepKey="openStorefrontCategoryPage"> + <argument name="categoryName" value="$createCategory.name$"/> + </actionGroup> + + <!--Verify Product in Category--> + <actionGroup ref="AssertStorefrontProductIsPresentOnCategoryPageActionGroup" stepKey="assertSimpleProductOnCategoryPage"> + <argument name="productName" value="$simpleProduct.name$"/> + </actionGroup> + + <!--Verify product name and sku on Store Front--> + <actionGroup ref="AssertProductNameAndSkuInStorefrontProductPageByCustomAttributeUrlKeyActionGroup" stepKey="assertProductOnStorefrontProductPage"> + <argument name="product" value="$simpleProduct$"/> + </actionGroup> + </test> +</tests> + diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithProductsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithProductsTest.xml index b0829d96db4fd..f82294ece6478 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithProductsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithProductsTest.xml @@ -7,15 +7,18 @@ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminUpdateCategoryWithProductsTest"> + <test name="AdminUpdateCategoryWithProductsTest" deprecated="Use AdminUpdateCategoryWithProductsDefaultSortingTest instead"> <annotations> <stories value="Update categories"/> - <title value="Update category, sort products by default sorting"/> + <title value="DEPRECATED. Update category, sort products by default sorting"/> <description value="Login as admin, update category and sort products"/> <testCaseId value="MC-6059"/> <severity value="BLOCKER"/> <group value="Catalog"/> <group value="mtf_migrated"/> + <skip> + <issueId value="DEPRECATED">Use AdminUpdateCategoryWithProductsDefaultSortingTest instead</issueId> + </skip> </annotations> <before> <actionGroup ref="AdminLoginActionGroup" stepKey="loginToAdminPanel"/> From 996bdaf1bbacb29b9c4ada30fd0775b71944554e Mon Sep 17 00:00:00 2001 From: Oleh Usik <o.usik@atwix.com> Date: Mon, 14 Sep 2020 16:17:57 +0300 Subject: [PATCH 093/132] Create StorefrontClickRefundTabCustomerOrderViewActionGroup --- ...kRefundTabCustomerOrderViewActionGroup.xml | 19 +++++++++++++++++++ ...reateCreditMemoBankTransferPaymentTest.xml | 6 ++---- ...AdminCreateCreditMemoPartialRefundTest.xml | 6 ++---- ...CreateCreditMemoWithCashOnDeliveryTest.xml | 6 ++---- ...nCreateCreditMemoWithPurchaseOrderTest.xml | 6 ++---- 5 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 app/code/Magento/Sales/Test/Mftf/ActionGroup/StorefrontClickRefundTabCustomerOrderViewActionGroup.xml diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/StorefrontClickRefundTabCustomerOrderViewActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/StorefrontClickRefundTabCustomerOrderViewActionGroup.xml new file mode 100644 index 0000000000000..fda22395f359c --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/StorefrontClickRefundTabCustomerOrderViewActionGroup.xml @@ -0,0 +1,19 @@ +<?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="StorefrontClickRefundTabCustomerOrderViewActionGroup"> + <annotations> + <description>Click "Refund" tab for customer order view.</description> + </annotations> + + <click selector="{{StorefrontCustomerOrderSection.tabRefund}}" stepKey="clickRefundTab"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoBankTransferPaymentTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoBankTransferPaymentTest.xml index c4656e394d349..6ed8510db777c 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoBankTransferPaymentTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoBankTransferPaymentTest.xml @@ -129,13 +129,11 @@ </actionGroup> <!-- Assert refunded Grand Total on frontend --> - <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="onAccountPage"/> - <waitForPageLoad stepKey="waitForPage"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="onAccountPage"/> <scrollTo selector="{{StorefrontCustomerResentOrdersSection.blockResentOrders}}" stepKey="scrollToResent"/> <click selector="{{StorefrontCustomerResentOrdersSection.viewOrder({$grabOrderId})}}" stepKey="clickOnOrder"/> <waitForPageLoad stepKey="waitForViewOrder"/> - <click selector="{{StorefrontCustomerOrderSection.tabRefund}}" stepKey="clickRefund"/> - <waitForPageLoad stepKey="waitRefundsLoad"/> + <actionGroup ref="StorefrontClickRefundTabCustomerOrderViewActionGroup" stepKey="clickRefund"/> <scrollTo selector="{{StorefrontCustomerOrderSection.grandTotalRefund}}" stepKey="scrollToGrandTotal"/> <see selector="{{StorefrontCustomerOrderSection.grandTotalRefund}}" userInput="555.00" stepKey="seeGrandTotal"/> </test> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoPartialRefundTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoPartialRefundTest.xml index eb3d4ad991915..68301187d3d31 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoPartialRefundTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoPartialRefundTest.xml @@ -123,13 +123,11 @@ </actionGroup> <!-- Assert refunded Grand Total on frontend --> - <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="onAccountPage"/> - <waitForPageLoad stepKey="waitForPage"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="onAccountPage"/> <scrollTo selector="{{StorefrontCustomerResentOrdersSection.blockResentOrders}}" stepKey="scrollToResent"/> <click selector="{{StorefrontCustomerResentOrdersSection.viewOrder({$grabOrderId})}}" stepKey="clickOnOrder"/> <waitForPageLoad stepKey="waitForViewOrder"/> - <click selector="{{StorefrontCustomerOrderSection.tabRefund}}" stepKey="clickRefund"/> - <waitForPageLoad stepKey="waitRefundsLoad"/> + <actionGroup ref="StorefrontClickRefundTabCustomerOrderViewActionGroup" stepKey="clickRefund"/> <scrollTo selector="{{StorefrontCustomerOrderSection.grandTotalRefund}}" stepKey="scrollToGrandTotal"/> <see selector="{{StorefrontCustomerOrderSection.grandTotalRefund}}" userInput="110.00" stepKey="seeGrandTotal"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithCashOnDeliveryTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithCashOnDeliveryTest.xml index 4383820ba6bee..a1027a9987b1f 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithCashOnDeliveryTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithCashOnDeliveryTest.xml @@ -116,13 +116,11 @@ </actionGroup> <!-- Assert refunded Grand Total on frontend --> - <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="onAccountPage"/> - <waitForPageLoad stepKey="waitForPage"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="onAccountPage"/> <scrollTo selector="{{StorefrontCustomerResentOrdersSection.blockResentOrders}}" stepKey="scrollToResent"/> <click selector="{{StorefrontCustomerResentOrdersSection.viewOrder({$grabOrderId})}}" stepKey="clickOnOrder"/> <waitForPageLoad stepKey="waitForViewOrder"/> - <click selector="{{StorefrontCustomerOrderSection.tabRefund}}" stepKey="clickRefund"/> - <waitForPageLoad stepKey="waitRefundsLoad"/> + <actionGroup ref="StorefrontClickRefundTabCustomerOrderViewActionGroup" stepKey="clickRefund"/> <scrollTo selector="{{StorefrontCustomerOrderSection.grandTotalRefund}}" stepKey="scrollToGrandTotal"/> <see selector="{{StorefrontCustomerOrderSection.grandTotalRefund}}" userInput="555.00" stepKey="seeGrandTotal"/> </test> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithPurchaseOrderTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithPurchaseOrderTest.xml index 56399401b205e..141fa2a9e5d06 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithPurchaseOrderTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithPurchaseOrderTest.xml @@ -115,13 +115,11 @@ </actionGroup> <!-- Assert refunded Grand Total on frontend --> - <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="onAccountPage"/> - <waitForPageLoad stepKey="waitForPage"/> + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="onAccountPage"/> <scrollTo selector="{{StorefrontCustomerResentOrdersSection.blockResentOrders}}" stepKey="scrollToResent"/> <click selector="{{StorefrontCustomerResentOrdersSection.viewOrder({$grabOrderId})}}" stepKey="clickOnOrder"/> <waitForPageLoad stepKey="waitForViewOrder"/> - <click selector="{{StorefrontCustomerOrderSection.tabRefund}}" stepKey="clickRefund"/> - <waitForPageLoad stepKey="waitRefundsLoad"/> + <actionGroup ref="StorefrontClickRefundTabCustomerOrderViewActionGroup" stepKey="clickRefund"/> <scrollTo selector="{{StorefrontCustomerOrderSection.grandTotalRefund}}" stepKey="scrollToGrandTotal"/> <see selector="{{StorefrontCustomerOrderSection.grandTotalRefund}}" userInput="555.00" stepKey="seeGrandTotal"/> </test> From 1db2872bb5999085f4e72474c8f9339fa468fb7d Mon Sep 17 00:00:00 2001 From: Viktor Kopin <viktor.kopin@transoftgroup.com> Date: Mon, 14 Sep 2020 16:21:35 +0300 Subject: [PATCH 094/132] magento/adobe-stock-integration#1806: fix static --- .../Controller/Adminhtml/Image/OnInsert.php | 16 ++- .../MediaGalleryUi/Model/InsertImageData.php | 103 ++++++++++++++++++ .../GetInsertImageData.php | 78 ++++++------- app/code/Magento/MediaGalleryUi/etc/di.xml | 3 +- .../Api/Data/InsertImageDataInterface.php | 55 ++++++++++ .../Api/GetInsertImageDataInterface.php | 43 +------- 6 files changed, 210 insertions(+), 88 deletions(-) create mode 100644 app/code/Magento/MediaGalleryUi/Model/InsertImageData.php rename app/code/Magento/MediaGalleryUi/Model/{ => InsertImageData}/GetInsertImageData.php (66%) create mode 100644 app/code/Magento/MediaGalleryUiApi/Api/Data/InsertImageDataInterface.php diff --git a/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php b/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php index 848fb7cd39119..249ea686b1b6b 100644 --- a/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php +++ b/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php @@ -4,6 +4,8 @@ * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\MediaGalleryUi\Controller\Adminhtml\Image; use Magento\Backend\App\Action; @@ -56,15 +58,17 @@ public function __construct( public function execute() { $data = $this->getRequest()->getParams(); - $content = $this->getInsertImageData->getImageContent( + $insertImageData = $this->getInsertImageData->execute( $data['filename'], - $data['force_static_path'], - $data['as_is'], + (bool)$data['force_static_path'], + (bool)$data['as_is'], isset($data['store']) ? (int)$data['store'] : null ); - $size = $data['force_static_path'] ? $this->getInsertImageData->getFileSize($content) : 0; - $type = $data['force_static_path'] ? $this->getInsertImageData->getMimeType($content) : ''; - return $this->resultJsonFactory->create()->setData(['content' => $content, 'size' => $size, 'type' => $type]); + return $this->resultJsonFactory->create()->setData([ + 'content' => $insertImageData->getContent(), + 'size' => $insertImageData->getSize(), + 'type' => $insertImageData->getType(), + ]); } } diff --git a/app/code/Magento/MediaGalleryUi/Model/InsertImageData.php b/app/code/Magento/MediaGalleryUi/Model/InsertImageData.php new file mode 100644 index 0000000000000..fdf5c229a7c63 --- /dev/null +++ b/app/code/Magento/MediaGalleryUi/Model/InsertImageData.php @@ -0,0 +1,103 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\MediaGalleryUi\Model; + +use Magento\MediaGalleryUiApi\Api\Data\InsertImageDataInterface; +use Magento\MediaGalleryUiApi\Api\InsertImageDataExtensionInterface; + +/** + * Class responsible to provide insert image details + */ +class InsertImageData implements InsertImageDataInterface +{ + /** + * @var InsertImageDataExtensionInterface + */ + private $extensionAttributes; + + /** + * @var string + */ + private $content; + + /** + * @var int + */ + private $size; + + /** + * @var string + */ + private $type; + + /** + * InsertImageData constructor. + * + * @param string $content + * @param int $size + * @param string $type + */ + public function __construct(string $content, int $size, string $type) + { + $this->content = $content; + $this->size = $size; + $this->type = $type; + } + + /** + * Returns a content (just a link or an html block) for inserting image to the content + * + * @return string + */ + public function getContent(): string + { + return $this->content; + } + + /** + * Returns size of requested file + * + * @return int + */ + public function getSize(): int + { + return $this->size; + } + + /** + * Returns MIME type of requested file + * + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * Get extension attributes + * + * @return ?\Magento\MediaGalleryUiApi\Api\InsertImageDataExtensionInterface;|null + */ + public function getExtensionAttributes(): ?InsertImageDataExtensionInterface + { + return $this->extensionAttributes; + } + + /** + * Set extension attributes + * + * @param ?\Magento\MediaGalleryUiApi\Api\InsertImageDataExtensionInterface;|null $extensionAttributes + * @return void + */ + public function setExtensionAttributes(?InsertImageDataExtensionInterface $extensionAttributes): void + { + $this->extensionAttributes = $extensionAttributes; + } +} diff --git a/app/code/Magento/MediaGalleryUi/Model/GetInsertImageData.php b/app/code/Magento/MediaGalleryUi/Model/InsertImageData/GetInsertImageData.php similarity index 66% rename from app/code/Magento/MediaGalleryUi/Model/GetInsertImageData.php rename to app/code/Magento/MediaGalleryUi/Model/InsertImageData/GetInsertImageData.php index 03481f6a98a93..ffd004464abe9 100644 --- a/app/code/Magento/MediaGalleryUi/Model/GetInsertImageData.php +++ b/app/code/Magento/MediaGalleryUi/Model/InsertImageData/GetInsertImageData.php @@ -6,25 +6,28 @@ declare(strict_types=1); -namespace Magento\MediaGalleryUi\Model; +namespace Magento\MediaGalleryUi\Model\InsertImageData; use Magento\Cms\Model\Wysiwyg\Images\GetInsertImageContent; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\File\Mime; use Magento\Framework\Filesystem; use Magento\Framework\Filesystem\Directory\ReadInterface; -use Magento\MediaGalleryUiApi\Api\GetInsertImageDataExtensionInterface; +use Magento\MediaGalleryUi\Model\InsertImageDataFactory; +use Magento\MediaGalleryUiApi\Api\Data\InsertImageDataInterface; use Magento\MediaGalleryUiApi\Api\GetInsertImageDataInterface; -/** - * Class responsible to provide insert image details - */ class GetInsertImageData implements GetInsertImageDataInterface { /** - * @var GetInsertImageDataExtensionInterface + * @var ReadInterface + */ + private $pubDirectory; + + /** + * @var Filesystem */ - private $extensionAttributes; + private $filesystem; /** * @var GetInsertImageContent @@ -32,53 +35,63 @@ class GetInsertImageData implements GetInsertImageDataInterface private $getInsertImageContent; /** - * @var Filesystem + * @var InsertImageDataFactory */ - private $filesystem; + private $insertImageDataFactory; /** * @var Mime */ private $mime; - /** - * @var ReadInterface - */ - private $pubDirectory; - /** * GetInsertImageData constructor. * * @param GetInsertImageContent $getInsertImageContent * @param Filesystem $fileSystem * @param Mime $mime + * @param InsertImageDataFactory $insertImageDataFactory */ public function __construct( GetInsertImageContent $getInsertImageContent, Filesystem $fileSystem, - Mime $mime + Mime $mime, + InsertImageDataFactory $insertImageDataFactory ) { $this->getInsertImageContent = $getInsertImageContent; $this->filesystem = $fileSystem; $this->mime = $mime; + $this->insertImageDataFactory = $insertImageDataFactory; } /** - * Retrieves a content (just a link or an html block) for inserting image to the content + * Returns image data object * * @param string $encodedFilename * @param bool $forceStaticPath * @param bool $renderAsTag * @param int|null $storeId - * @return null|string + * @return InsertImageDataInterface */ - public function getImageContent( + public function execute( string $encodedFilename, bool $forceStaticPath, bool $renderAsTag, ?int $storeId = null - ): string { - return $this->getInsertImageContent->execute($encodedFilename, $forceStaticPath, $renderAsTag, $storeId); + ): InsertImageDataInterface { + $content = $this->getInsertImageContent->execute( + $encodedFilename, + $forceStaticPath, + $renderAsTag, + $storeId + ); + $size = $forceStaticPath ? $this->getSize($content) : 0; + $type = $forceStaticPath ? $this->getType($content) : ''; + return $this->insertImageDataFactory->create([ + 'content' => $content, + 'size' => $size, + 'type' => $type + ]); } /** @@ -87,7 +100,7 @@ public function getImageContent( * @param string $path * @return int */ - public function getFileSize(string $path): int + private function getSize(string $path): int { $directory = $this->getPubDirectory(); @@ -100,7 +113,7 @@ public function getFileSize(string $path): int * @param string $path * @return string */ - public function getMimeType(string $path): string + public function getType(string $path): string { $absoluteFilePath = $this->getPubDirectory()->getAbsolutePath($path); @@ -119,25 +132,4 @@ private function getPubDirectory(): ReadInterface } return $this->pubDirectory; } - - /** - * Get extension attributes - * - * @return GetInsertImageDataExtensionInterface|null - */ - public function getExtensionAttributes(): ?GetInsertImageDataExtensionInterface - { - return $this->extensionAttributes; - } - - /** - * Set extension attributes - * - * @param GetInsertImageDataExtensionInterface|null $extensionAttributes - * @return void - */ - public function setExtensionAttributes(?GetInsertImageDataExtensionInterface $extensionAttributes): void - { - $this->extensionAttributes = $extensionAttributes; - } } diff --git a/app/code/Magento/MediaGalleryUi/etc/di.xml b/app/code/Magento/MediaGalleryUi/etc/di.xml index 5f80406ec75ab..65f539ff858c9 100644 --- a/app/code/Magento/MediaGalleryUi/etc/di.xml +++ b/app/code/Magento/MediaGalleryUi/etc/di.xml @@ -7,7 +7,8 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\MediaGalleryUiApi\Api\ConfigInterface" type="Magento\MediaGalleryUi\Model\Config"/> - <preference for="Magento\MediaGalleryUiApi\Api\GetInsertImageDataInterface" type="Magento\MediaGalleryUi\Model\GetInsertImageData"/> + <preference for="Magento\MediaGalleryUiApi\Api\GetInsertImageDataInterface" type="\Magento\MediaGalleryUi\Model\InsertImageData\GetInsertImageData"/> + <preference for="Magento\MediaGalleryUiApi\Api\Data\InsertImageDataInterface" type="\Magento\MediaGalleryUi\Model\InsertImageData"/> <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory"> <arguments> <argument name="collections" xsi:type="array"> diff --git a/app/code/Magento/MediaGalleryUiApi/Api/Data/InsertImageDataInterface.php b/app/code/Magento/MediaGalleryUiApi/Api/Data/InsertImageDataInterface.php new file mode 100644 index 0000000000000..5f6d2b15778e1 --- /dev/null +++ b/app/code/Magento/MediaGalleryUiApi/Api/Data/InsertImageDataInterface.php @@ -0,0 +1,55 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\MediaGalleryUiApi\Api\Data; + +use Magento\Framework\Api\ExtensibleDataInterface; + +/** + * Class responsible to provide insert image details + */ +interface InsertImageDataInterface extends ExtensibleDataInterface +{ + /** + * Returns a content (just a link or an html block) for inserting image to the content + * + * @return null|string + */ + public function getContent(): ?string; + + /** + * Returns size of requested file + * + * @return int + */ + public function getSize(): int; + + /** + * Returns MIME type of requested file + * + * @return string + */ + public function getType(): string; + + /** + * Get extension attributes + * + * @return \Magento\MediaGalleryUiApi\Api\InsertImageDataExtensionInterface|null + */ + public function getExtensionAttributes(): ?\Magento\MediaGalleryUiApi\Api\InsertImageDataExtensionInterface; + + /** + * Set extension attributes + * + * @param \Magento\MediaGalleryUiApi\Api\InsertImageDataExtensionInterface|null $extensionAttributes + * @return void + */ + public function setExtensionAttributes( + ?\Magento\MediaGalleryUiApi\Api\InsertImageDataExtensionInterface $extensionAttributes + ): void; +} diff --git a/app/code/Magento/MediaGalleryUiApi/Api/GetInsertImageDataInterface.php b/app/code/Magento/MediaGalleryUiApi/Api/GetInsertImageDataInterface.php index 470abf0770a21..7b88a0fabad7c 100644 --- a/app/code/Magento/MediaGalleryUiApi/Api/GetInsertImageDataInterface.php +++ b/app/code/Magento/MediaGalleryUiApi/Api/GetInsertImageDataInterface.php @@ -8,12 +8,12 @@ namespace Magento\MediaGalleryUiApi\Api; -use Magento\Framework\Api\ExtensibleDataInterface; +use Magento\MediaGalleryUiApi\Api\Data\InsertImageDataInterface; /** * Class responsible to provide insert image details */ -interface GetInsertImageDataInterface extends ExtensibleDataInterface +interface GetInsertImageDataInterface { /** * Retrieves a content (just a link or an html block) for inserting image to the content @@ -22,45 +22,12 @@ interface GetInsertImageDataInterface extends ExtensibleDataInterface * @param bool $forceStaticPath * @param bool $renderAsTag * @param int|null $storeId - * @return null|string + * @return InsertImageDataInterface */ - public function getImageContent( + public function execute( string $encodedFilename, bool $forceStaticPath, bool $renderAsTag, ?int $storeId = null - ): string; - - /** - * Retrieve size of requested file - * - * @param string $path - * @return int - */ - public function getFileSize(string $path): int; - - /** - * Retrieve MIME type of requested file - * - * @param string $path - * @return string - */ - public function getMimeType(string $path): string; - - /** - * Get extension attributes - * - * @return \Magento\MediaGalleryUiApi\Api\GetInsertImageDataExtensionInterface|null - */ - public function getExtensionAttributes(): ?\Magento\MediaGalleryUiApi\Api\GetInsertImageDataExtensionInterface; - - /** - * Set extension attributes - * - * @param \Magento\MediaGalleryUiApi\Api\GetInsertImageDataExtensionInterface|null $extensionAttributes - * @return void - */ - public function setExtensionAttributes( - ?\Magento\MediaGalleryUiApi\Api\GetInsertImageDataExtensionInterface $extensionAttributes - ): void; + ): InsertImageDataInterface; } From 1340ce26380bcd03ff6273b3309354c02d0d649b Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Mon, 14 Sep 2020 17:14:43 +0300 Subject: [PATCH 095/132] MC-36971: Create automated test for "Calculation of invoiced child items in "sales_order_item" table for order with configurable product after partial invoice" --- .../Sales/Controller/Adminhtml/Order/Invoice/SaveTest.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Invoice/SaveTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Invoice/SaveTest.php index dc903107d5ce3..d00b4c784110c 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Invoice/SaveTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Invoice/SaveTest.php @@ -189,11 +189,12 @@ public function testPartialInvoiceWitConfigurableProduct(): void $order = $this->getOrder('100000001'); $post = $this->hydratePost([$order->getItemsCollection()->getFirstItem()->getId() => '1']); $this->prepareRequest($post, ['order_id' => $order->getEntityId()]); - $this->dispatch('backend/sales/order_invoice/save'); + $this->dispatch($this->uri); $this->assertSessionMessages($this->containsEqual((string)__('The invoice has been created.'))); $orderItems = $this->getOrderItemsQtyInvoiced((int)$order->getEntityId()); $this->assertCount(2, $orderItems); - $this->assertEquals($orderItems[0]['qty_invoiced'], $orderItems[1]['qty_invoiced']); + $this->assertEquals(1, (int)$orderItems[0]); + $this->assertEquals($orderItems[0], $orderItems[1]); } /** @@ -209,7 +210,7 @@ private function getOrderItemsQtyInvoiced(int $orderId): array ->from($this->orderItemResource->getMainTable(), OrderItemInterface::QTY_INVOICED) ->where(OrderItemInterface::ORDER_ID . ' = ?', $orderId); - return $connection->fetchAll($select); + return $connection->fetchCol($select); } /** From 79ddf9a70463ba4e5b21f0eb0415443062998c82 Mon Sep 17 00:00:00 2001 From: joweecaquicla <joie@abovethefray.io> Date: Tue, 15 Sep 2020 00:48:34 +0800 Subject: [PATCH 096/132] magento/adobe-stock-integration#1827: Improve AdminMediaGalleryUploadCategoryImageTest - modified AdminMediaGalleryUploadCategoryImageTest --- .../Test/Mftf/Section/AdminMediaGalleryFolderSection.xml | 2 ++ .../Mftf/Test/AdminMediaGalleryUploadCategoryImageTest.xml | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/Section/AdminMediaGalleryFolderSection.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/Section/AdminMediaGalleryFolderSection.xml index 4c9e6bf362194..2e6919f692042 100644 --- a/app/code/Magento/MediaGalleryUi/Test/Mftf/Section/AdminMediaGalleryFolderSection.xml +++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/Section/AdminMediaGalleryFolderSection.xml @@ -18,5 +18,7 @@ <element name="folderNameField" type="button" selector="[name=folder_name]"/> <element name="folderConfirmCreateButton" type="button" selector="//button/span[contains(text(),'Confirm')]"/> <element name="folderNameValidationMessage" type="block" selector="label.mage-error"/> + <element name="folderArrow" type="button" selector="#{{id}} > .jstree-icon" parameterized="true"/> + <element name="checkIfFolderArrowExpand" type="button" selector="//li[@id='{{id}}' and contains(@class,'jstree-closed')]" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminMediaGalleryUploadCategoryImageTest.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminMediaGalleryUploadCategoryImageTest.xml index 684db1d4a2627..f4b96683a620e 100644 --- a/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminMediaGalleryUploadCategoryImageTest.xml +++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminMediaGalleryUploadCategoryImageTest.xml @@ -37,9 +37,8 @@ <actionGroup ref="AdminSaveCategoryFormActionGroup" stepKey="saveCategoryForm"/> <actionGroup ref="AdminOpenMediaGalleryFromCategoryImageUploaderActionGroup" stepKey="openMediaGalleryFromImageUploader"/> <actionGroup ref="ClearFiltersAdminDataGridActionGroup" stepKey="clearFilter"/> - <actionGroup ref="AdminMediaGalleryFolderSelectActionGroup" stepKey="selectCatalogFolder"> - <argument name="name" value="catalog"/> - </actionGroup> + <conditionalClick selector="{{AdminMediaGalleryFolderSection.folderArrow(catalog)}}" + dependentSelector="{{AdminMediaGalleryFolderSection.checkIfFolderArrowExpand(catalog)}}" stepKey="clickArrowIfClosed" visible="true"/> <actionGroup ref="AdminMediaGalleryFolderSelectActionGroup" stepKey="selectCategoryFolder"> <argument name="name" value="category"/> </actionGroup> From 45a224f0e9ede127ac94a3388f15a077f48dd568 Mon Sep 17 00:00:00 2001 From: joweecaquicla <joie@abovethefray.io> Date: Tue, 15 Sep 2020 01:17:15 +0800 Subject: [PATCH 097/132] magento/adobe-stock-integration#1832: Rename renditions stores config fieldset and add comments - modified config fieldset and added comments --- .../Magento/MediaGalleryRenditions/etc/adminhtml/system.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/system.xml b/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/system.xml index 64f338d53a283..eab106013b38c 100644 --- a/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/system.xml +++ b/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/system.xml @@ -9,7 +9,9 @@ <system> <section id="system"> <group id="media_gallery_renditions" translate="label" type="text" sortOrder="1010" showInDefault="1" showInWebsite="0" showInStore="0"> - <label>Media Gallery Renditions</label> + <label>Media Gallery Image Size</label> + <comment>Resize images to improve performance and decrease the file size. When you use an image from Media Gallery on the storefront, the smaller image is generated and placed instead of the original. + Changing these settings will update all generated images.</comment> <field id="width" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0"> <label>Max Width</label> <validate>validate-zero-or-greater validate-digits</validate> From dd347f553580182102e8e28fa7027c6fbdecb4b3 Mon Sep 17 00:00:00 2001 From: joweecaquicla <joie@abovethefray.io> Date: Tue, 15 Sep 2020 02:16:53 +0800 Subject: [PATCH 098/132] magento/adobe-stock-integration#1832: Rename renditions stores config fieldset and add comments - additional modifications --- .../Magento/MediaGalleryRenditions/etc/adminhtml/system.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/system.xml b/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/system.xml index eab106013b38c..c6ac58ffe2b13 100644 --- a/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/system.xml +++ b/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/system.xml @@ -13,12 +13,14 @@ <comment>Resize images to improve performance and decrease the file size. When you use an image from Media Gallery on the storefront, the smaller image is generated and placed instead of the original. Changing these settings will update all generated images.</comment> <field id="width" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0"> - <label>Max Width</label> + <label>Maximum Width</label> <validate>validate-zero-or-greater validate-digits</validate> + <comment>Enter the maximum width of an image in pixels.</comment> </field> <field id="height" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="0"> - <label>Max Height</label> + <label>Maximum Height</label> <validate>validate-zero-or-greater validate-digits</validate> + <comment>Enter the maximum height of an image in pixels.</comment> </field> </group> </section> From ee983370e90c4a2f5aa1d5977f6c2fa1e7093152 Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Mon, 14 Sep 2020 21:46:26 +0300 Subject: [PATCH 099/132] magento/adobe-stock-integration#1832: Updated fieldset name --- .../Magento/MediaGalleryRenditions/etc/adminhtml/system.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/system.xml b/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/system.xml index c6ac58ffe2b13..b60a858da5f26 100644 --- a/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/system.xml +++ b/app/code/Magento/MediaGalleryRenditions/etc/adminhtml/system.xml @@ -9,7 +9,7 @@ <system> <section id="system"> <group id="media_gallery_renditions" translate="label" type="text" sortOrder="1010" showInDefault="1" showInWebsite="0" showInStore="0"> - <label>Media Gallery Image Size</label> + <label>Media Gallery Image Optimization</label> <comment>Resize images to improve performance and decrease the file size. When you use an image from Media Gallery on the storefront, the smaller image is generated and placed instead of the original. Changing these settings will update all generated images.</comment> <field id="width" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0"> From 837dd9d228eaad4ee06f00f0383c03e6d2aebd6f Mon Sep 17 00:00:00 2001 From: Viktor Kopin <viktor.kopin@transoftgroup.com> Date: Tue, 15 Sep 2020 10:02:23 +0300 Subject: [PATCH 100/132] magento/adobe-stock-integration#1806: remove unnecessary interface, after review fixes --- .../Controller/Adminhtml/Image/OnInsert.php | 8 ++--- .../MediaGalleryUi/Model/InsertImageData.php | 9 +++-- .../InsertImageData/GetInsertImageData.php | 9 +++-- .../Model}/InsertImageDataInterface.php | 10 +++--- app/code/Magento/MediaGalleryUi/etc/di.xml | 1 - .../Api/GetInsertImageDataInterface.php | 33 ------------------- 6 files changed, 17 insertions(+), 53 deletions(-) rename app/code/Magento/{MediaGalleryUiApi/Api/Data => MediaGalleryUi/Model}/InsertImageDataInterface.php (72%) delete mode 100644 app/code/Magento/MediaGalleryUiApi/Api/GetInsertImageDataInterface.php diff --git a/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php b/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php index 249ea686b1b6b..b92724f64148e 100644 --- a/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php +++ b/app/code/Magento/MediaGalleryUi/Controller/Adminhtml/Image/OnInsert.php @@ -13,7 +13,7 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Controller\Result\JsonFactory; use Magento\Framework\Controller\ResultInterface; -use Magento\MediaGalleryUiApi\Api\GetInsertImageDataInterface; +use Magento\MediaGalleryUi\Model\InsertImageData\GetInsertImageData; /** * OnInsert action returns on insert image details @@ -31,19 +31,19 @@ class OnInsert extends Action implements HttpPostActionInterface private $resultJsonFactory; /** - * @var GetInsertImageDataInterface + * @var GetInsertImageData */ private $getInsertImageData; /** * @param Context $context * @param JsonFactory $resultJsonFactory - * @param GetInsertImageDataInterface|null $getInsertImageData + * @param GetInsertImageData $getInsertImageData */ public function __construct( Context $context, JsonFactory $resultJsonFactory, - GetInsertImageDataInterface $getInsertImageData + GetInsertImageData $getInsertImageData ) { parent::__construct($context); $this->resultJsonFactory = $resultJsonFactory; diff --git a/app/code/Magento/MediaGalleryUi/Model/InsertImageData.php b/app/code/Magento/MediaGalleryUi/Model/InsertImageData.php index fdf5c229a7c63..f70ed8e308c99 100644 --- a/app/code/Magento/MediaGalleryUi/Model/InsertImageData.php +++ b/app/code/Magento/MediaGalleryUi/Model/InsertImageData.php @@ -8,8 +8,7 @@ namespace Magento\MediaGalleryUi\Model; -use Magento\MediaGalleryUiApi\Api\Data\InsertImageDataInterface; -use Magento\MediaGalleryUiApi\Api\InsertImageDataExtensionInterface; +use Magento\MediaGalleryUi\Model\InsertImageDataExtensionInterface; /** * Class responsible to provide insert image details @@ -83,7 +82,7 @@ public function getType(): string /** * Get extension attributes * - * @return ?\Magento\MediaGalleryUiApi\Api\InsertImageDataExtensionInterface;|null + * @return \Magento\MediaGalleryUi\Model\InsertImageDataExtensionInterface|null */ public function getExtensionAttributes(): ?InsertImageDataExtensionInterface { @@ -93,10 +92,10 @@ public function getExtensionAttributes(): ?InsertImageDataExtensionInterface /** * Set extension attributes * - * @param ?\Magento\MediaGalleryUiApi\Api\InsertImageDataExtensionInterface;|null $extensionAttributes + * @param \Magento\MediaGalleryUi\Model\InsertImageDataExtensionInterface $extensionAttributes * @return void */ - public function setExtensionAttributes(?InsertImageDataExtensionInterface $extensionAttributes): void + public function setExtensionAttributes(InsertImageDataExtensionInterface $extensionAttributes): void { $this->extensionAttributes = $extensionAttributes; } diff --git a/app/code/Magento/MediaGalleryUi/Model/InsertImageData/GetInsertImageData.php b/app/code/Magento/MediaGalleryUi/Model/InsertImageData/GetInsertImageData.php index ffd004464abe9..486be92d6e0eb 100644 --- a/app/code/Magento/MediaGalleryUi/Model/InsertImageData/GetInsertImageData.php +++ b/app/code/Magento/MediaGalleryUi/Model/InsertImageData/GetInsertImageData.php @@ -14,10 +14,9 @@ use Magento\Framework\Filesystem; use Magento\Framework\Filesystem\Directory\ReadInterface; use Magento\MediaGalleryUi\Model\InsertImageDataFactory; -use Magento\MediaGalleryUiApi\Api\Data\InsertImageDataInterface; -use Magento\MediaGalleryUiApi\Api\GetInsertImageDataInterface; +use Magento\MediaGalleryUi\Model\InsertImageDataInterface; -class GetInsertImageData implements GetInsertImageDataInterface +class GetInsertImageData { /** * @var ReadInterface @@ -115,9 +114,9 @@ private function getSize(string $path): int */ public function getType(string $path): string { - $absoluteFilePath = $this->getPubDirectory()->getAbsolutePath($path); + $fileExist = $this->getPubDirectory()->isExist($path); - return $this->getPubDirectory()->isExist($path) ? $this->mime->getMimeType($absoluteFilePath) : ''; + return $fileExist ? $this->mime->getMimeType($this->getPubDirectory()->getAbsolutePath($path)) : ''; } /** diff --git a/app/code/Magento/MediaGalleryUiApi/Api/Data/InsertImageDataInterface.php b/app/code/Magento/MediaGalleryUi/Model/InsertImageDataInterface.php similarity index 72% rename from app/code/Magento/MediaGalleryUiApi/Api/Data/InsertImageDataInterface.php rename to app/code/Magento/MediaGalleryUi/Model/InsertImageDataInterface.php index 5f6d2b15778e1..063d76292d625 100644 --- a/app/code/Magento/MediaGalleryUiApi/Api/Data/InsertImageDataInterface.php +++ b/app/code/Magento/MediaGalleryUi/Model/InsertImageDataInterface.php @@ -6,7 +6,7 @@ declare(strict_types=1); -namespace Magento\MediaGalleryUiApi\Api\Data; +namespace Magento\MediaGalleryUi\Model; use Magento\Framework\Api\ExtensibleDataInterface; @@ -39,17 +39,17 @@ public function getType(): string; /** * Get extension attributes * - * @return \Magento\MediaGalleryUiApi\Api\InsertImageDataExtensionInterface|null + * @return \Magento\MediaGalleryUi\Model\InsertImageDataExtensionInterface|null */ - public function getExtensionAttributes(): ?\Magento\MediaGalleryUiApi\Api\InsertImageDataExtensionInterface; + public function getExtensionAttributes(): ?\Magento\MediaGalleryUi\Model\InsertImageDataExtensionInterface; /** * Set extension attributes * - * @param \Magento\MediaGalleryUiApi\Api\InsertImageDataExtensionInterface|null $extensionAttributes + * @param \Magento\MediaGalleryUi\Model\InsertImageDataExtensionInterface $extensionAttributes * @return void */ public function setExtensionAttributes( - ?\Magento\MediaGalleryUiApi\Api\InsertImageDataExtensionInterface $extensionAttributes + \Magento\MediaGalleryUi\Model\InsertImageDataExtensionInterface $extensionAttributes ): void; } diff --git a/app/code/Magento/MediaGalleryUi/etc/di.xml b/app/code/Magento/MediaGalleryUi/etc/di.xml index 65f539ff858c9..964ac92399738 100644 --- a/app/code/Magento/MediaGalleryUi/etc/di.xml +++ b/app/code/Magento/MediaGalleryUi/etc/di.xml @@ -7,7 +7,6 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\MediaGalleryUiApi\Api\ConfigInterface" type="Magento\MediaGalleryUi\Model\Config"/> - <preference for="Magento\MediaGalleryUiApi\Api\GetInsertImageDataInterface" type="\Magento\MediaGalleryUi\Model\InsertImageData\GetInsertImageData"/> <preference for="Magento\MediaGalleryUiApi\Api\Data\InsertImageDataInterface" type="\Magento\MediaGalleryUi\Model\InsertImageData"/> <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory"> <arguments> diff --git a/app/code/Magento/MediaGalleryUiApi/Api/GetInsertImageDataInterface.php b/app/code/Magento/MediaGalleryUiApi/Api/GetInsertImageDataInterface.php deleted file mode 100644 index 7b88a0fabad7c..0000000000000 --- a/app/code/Magento/MediaGalleryUiApi/Api/GetInsertImageDataInterface.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\MediaGalleryUiApi\Api; - -use Magento\MediaGalleryUiApi\Api\Data\InsertImageDataInterface; - -/** - * Class responsible to provide insert image details - */ -interface GetInsertImageDataInterface -{ - /** - * Retrieves a content (just a link or an html block) for inserting image to the content - * - * @param string $encodedFilename - * @param bool $forceStaticPath - * @param bool $renderAsTag - * @param int|null $storeId - * @return InsertImageDataInterface - */ - public function execute( - string $encodedFilename, - bool $forceStaticPath, - bool $renderAsTag, - ?int $storeId = null - ): InsertImageDataInterface; -} From a46a395a1a6e3f40f90fb040874f518083ba9627 Mon Sep 17 00:00:00 2001 From: Vadim Malesh <51680850+engcom-Charlie@users.noreply.github.com> Date: Tue, 15 Sep 2020 10:11:28 +0300 Subject: [PATCH 101/132] fix static --- dev/tests/js/jasmine/tests/lib/mage/gallery/gallery.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/js/jasmine/tests/lib/mage/gallery/gallery.test.js b/dev/tests/js/jasmine/tests/lib/mage/gallery/gallery.test.js index 4cb48148e70c3..5db506b00a883 100644 --- a/dev/tests/js/jasmine/tests/lib/mage/gallery/gallery.test.js +++ b/dev/tests/js/jasmine/tests/lib/mage/gallery/gallery.test.js @@ -131,7 +131,7 @@ define([ originSpy = $.fn.data; jqueryDataMock = { setOptions: jasmine.createSpy().and.returnValue(true), - updateOptions: jasmine.createSpy().and.returnValue(true), + updateOptions: jasmine.createSpy().and.returnValue(true) }; spyOn($.fn, 'data').and.callFake(function () { return jqueryDataMock; From a48a6b1a8ea691ce082d3544b15019c917a963d0 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Tue, 15 Sep 2020 10:33:49 +0300 Subject: [PATCH 102/132] MC-25238: Unstable Test "StorefrontCheckoutWithDifferentShippingAndBillingAddressAndRegisterCustomerAfterCheckoutTest" --- ...tFillEstimateShippingAndTaxActionGroup.xml | 17 --------- ...tFillEstimateShippingAndTaxActionGroup.xml | 3 +- ...ressAndCreateCustomerAfterCheckoutTest.xml | 38 +++++++++---------- .../AdminDeleteCustomerInGridActionGroup.xml | 27 ------------- 4 files changed, 19 insertions(+), 66 deletions(-) delete mode 100644 app/code/Magento/Checkout/Test/Mftf/ActionGroup/CartFillEstimateShippingAndTaxActionGroup.xml delete mode 100644 app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerInGridActionGroup.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CartFillEstimateShippingAndTaxActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CartFillEstimateShippingAndTaxActionGroup.xml deleted file mode 100644 index 14609ce1a8bf0..0000000000000 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CartFillEstimateShippingAndTaxActionGroup.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?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="CartFillEstimateShippingAndTaxActionGroup" extends="CheckoutFillEstimateShippingAndTaxActionGroup"> - <arguments> - <argument name="address" defaultValue="US_Address_TX" type="entity"/> - </arguments> - <waitForElementVisible selector="{{CheckoutCartSummarySection.estimateShippingAndTax}}" after="openShippingDetails" stepKey="waitForSummarySectionLoad"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutFillEstimateShippingAndTaxActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutFillEstimateShippingAndTaxActionGroup.xml index f564e14989e75..d6180d64ea82f 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutFillEstimateShippingAndTaxActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutFillEstimateShippingAndTaxActionGroup.xml @@ -13,10 +13,11 @@ <argument name="address" defaultValue="US_Address_TX" type="entity"/> </arguments> <conditionalClick selector="{{CheckoutCartSummarySection.estimateShippingAndTax}}" dependentSelector="{{CheckoutCartSummarySection.estimateShippingAndTaxSummary}}" visible="false" stepKey="openShippingDetails"/> + <waitForElementVisible selector="{{CheckoutCartSummarySection.estimateShippingAndTax}}" stepKey="waitForSummarySectionLoad"/> <selectOption selector="{{CheckoutCartSummarySection.country}}" userInput="{{address.country_id}}" stepKey="selectCountry"/> <selectOption selector="{{CheckoutCartSummarySection.stateProvince}}" userInput="{{address.state}}" stepKey="selectState"/> <waitForElementVisible selector="{{CheckoutCartSummarySection.postcode}}" stepKey="waitForPostCodeVisible"/> <fillField selector="{{CheckoutCartSummarySection.postcode}}" userInput="{{address.postcode}}" stepKey="selectPostCode"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDiappear"/> </actionGroup> -</actionGroups> \ No newline at end of file +</actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndCreateCustomerAfterCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndCreateCustomerAfterCheckoutTest.xml index 9f3eb0c9e3118..ef1f30e2d9c36 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndCreateCustomerAfterCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndCreateCustomerAfterCheckoutTest.xml @@ -13,8 +13,9 @@ <title value="Verify UK customer checkout with different billing and shipping address and register customer after checkout"/> <description value="Checkout as UK customer with different shipping/billing address and register checkout method"/> <severity value="CRITICAL"/> - <testCaseId value="MC-14712"/> + <testCaseId value="MC-28288"/> <group value="mtf_migrated"/> + <group value="checkout"/> </annotations> <before> @@ -25,30 +26,30 @@ </before> <after> <!-- Sign out Customer from storefront --> - <actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="openHomePage"/> - <actionGroup ref="StorefrontSignOutActionGroup" stepKey="customerLogout"/> + <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logoutCustomer"/> <deleteData createDataKey="simpleProduct" stepKey="deleteProduct"/> - <actionGroup ref="AdminDeleteCustomerInGridActionGroup" stepKey="deleteCustomer"> + <actionGroup ref="AdminDeleteCustomerActionGroup" stepKey="deleteCustomer"> <argument name="customerEmail" value="UKCustomer.email"/> </actionGroup> - <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + <actionGroup ref="ClearFiltersAdminDataGridActionGroup" stepKey="clearCustomersGridFilter"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> </after> <!--Open Product page in StoreFront and assert product and price range --> <actionGroup ref="AssertProductNameAndSkuInStorefrontProductPageByCustomAttributeUrlKeyActionGroup" stepKey="openProductPageAndVerifyProduct"> - <argument name="product" value="$$simpleProduct$$"/> + <argument name="product" value="$simpleProduct$"/> </actionGroup> <!--Add product to the cart --> - <actionGroup ref="StorefrontAddProductToCartWithQtyActionGroup" stepKey="addSimpleProductToCart"> - <argument name="productQty" value="1"/> + <actionGroup ref="AddSimpleProductToCartActionGroup" stepKey="addProductToCart"> + <argument name="product" value="$simpleProduct$"/> </actionGroup> <!--Open View and edit --> <actionGroup ref="ClickViewAndEditCartFromMiniCartActionGroup" stepKey="openCartFromMiniCart"/> <!-- Fill the Estimate Shipping and Tax section --> - <actionGroup ref="CartFillEstimateShippingAndTaxActionGroup" stepKey="fillEstimateShippingAndTaxFields"/> + <actionGroup ref="CheckoutFillEstimateShippingAndTaxActionGroup" stepKey="fillEstimateShippingAndTaxFields"/> <click selector="{{CheckoutCartSummarySection.proceedToCheckout}}" stepKey="goToCheckout"/> <waitForPageLoad stepKey="waitForPageToLoad"/> @@ -57,11 +58,11 @@ <argument name="customer" value="UKCustomer"/> <argument name="customerAddress" value="updateCustomerUKAddress"/> </actionGroup> - <actionGroup ref="StorefrontCheckoutClickNextButtonActionGroup" stepKey="goToBillingStep"/> + <actionGroup ref="CheckoutSelectFlatRateShippingMethodActionGroup" stepKey="selectFlatRateShipping"/> + <actionGroup ref="StorefrontCheckoutClickNextOnShippingStepActionGroup" stepKey="goToBillingStep"/> <waitForElementVisible selector="{{CheckoutPaymentSection.billingAddressNotSameCheckbox}}" stepKey="waitForSameBillingAndShippingAddressCheckboxVisible"/> <uncheckOption selector="{{CheckoutPaymentSection.billingAddressNotSameCheckbox}}" stepKey="uncheckSameBillingAndShippingAddress"/> <conditionalClick selector="{{CheckoutShippingSection.editAddressButton}}" dependentSelector="{{CheckoutShippingSection.editAddressButton}}" visible="true" stepKey="clickEditBillingAddressButton"/> - <waitForLoadingMaskToDisappear stepKey="waitForBillingAddressFormLoad"/> <!-- Fill Billing Address --> <actionGroup ref="StorefrontFillBillingAddressActionGroup" stepKey="fillBillingAddressForm"/> @@ -75,23 +76,18 @@ <!-- Register customer after checkout --> <actionGroup ref="StorefrontRegisterCustomerAfterCheckoutActionGroup" stepKey="registerCustomer"/> - <!-- Open Order Index Page --> - <actionGroup ref="AdminOrdersPageOpenActionGroup" stepKey="goToOrdersGrid"/> - - <!-- Filter Order using orderId and assert order--> - <actionGroup ref="FilterOrderGridByIdActionGroup" stepKey="filterOrderGridById"> - <argument name="orderId" value="$orderId"/> + <!-- Open Order Page in admin --> + <actionGroup ref="OpenOrderByIdActionGroup" stepKey="openOrder"> + <argument name="orderId" value="{$orderId}"/> </actionGroup> - <click selector="{{AdminOrdersGridSection.viewLink('$orderId')}}" stepKey="openOrderPage"/> - <waitForPageLoad stepKey="waitForOrderPageToLoad"/> - <!-- Assert Grand Total --> <see selector="{{AdminOrderTotalSection.grandTotal}}" userInput="$55.00" stepKey="seeGrandTotal"/> <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Pending" stepKey="seeOrderStatus"/> <!-- Ship the order and assert the status --> - <actionGroup ref="AdminShipThePendingOrderActionGroup" stepKey="shipTheOrder"/> + <actionGroup ref="GoToShipmentIntoOrderActionGroup" stepKey="goToShipment"/> + <actionGroup ref="SubmitShipmentIntoOrderActionGroup" stepKey="submitShipment"/> <!-- Assert order buttons --> <actionGroup ref="AdminAssertOrderAvailableButtonsActionGroup" stepKey="assertOrderButtons"/> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerInGridActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerInGridActionGroup.xml deleted file mode 100644 index deb6b992a50db..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminDeleteCustomerInGridActionGroup.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?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="AdminDeleteCustomerInGridActionGroup" extends="AdminDeleteCustomerActionGroup"> - <arguments> - <argument name="customerEmail"/> - </arguments> - - <remove keyForRemoval="openFilters"/> - <remove keyForRemoval="fillEmail"/> - <remove keyForRemoval="clickApplyFilters"/> - <remove keyForRemoval="chooseCustomer"/> - <click selector="{{AdminDataGridHeaderSection.filters}}" after="waitForFiltersClear" stepKey="openFiltersSection"/> - <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="AdminDataGridHeaderSection.clearFilters" visible="true" after="openFiltersSection" stepKey="clearFiltersIfTheyAreSet"/> - <fillField userInput="{{customerEmail}}" selector="{{AdminCustomerFiltersSection.emailInput}}" after="clearFiltersIfTheyAreSet" stepKey="fillEmailFilterField"/> - <click selector="{{AdminCustomerFiltersSection.apply}}" after="fillEmailFilterField" stepKey="applyEmailFilter"/> - <waitForElementVisible selector="{{AdminCustomerGridMainActionsSection.customerCheckbox(customerEmail)}}" after="applyEmailFilter" stepKey="waitForAppliedFilterLoad"/> - <click selector="{{AdminCustomerGridMainActionsSection.customerCheckbox(customerEmail)}}" after="waitForAppliedFilterLoad" stepKey="chooseCustomer"/> - </actionGroup> -</actionGroups> From cb2fc97a1d54c4eb0307a4aa76710fc8baa62f36 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Tue, 15 Sep 2020 11:23:14 +0300 Subject: [PATCH 103/132] MC-25249: Unstable Test "AdminUpdateCategoryWithProductsTest" --- .../AdminUpdateCategoryWithProductsDefaultSortingTest.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithProductsDefaultSortingTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithProductsDefaultSortingTest.xml index e8998203296ed..051495b257012 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithProductsDefaultSortingTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithProductsDefaultSortingTest.xml @@ -38,6 +38,7 @@ <!--Update Product Display Setting--> <waitForElementVisible selector="{{AdminCategoryDisplaySettingsSection.settingsHeader}}" stepKey="waitForDisplaySettingsSection"/> <conditionalClick selector="{{AdminCategoryDisplaySettingsSection.settingsHeader}}" dependentSelector="{{AdminCategoryDisplaySettingsSection.displayMode}}" visible="false" stepKey="openDisplaySettingsSection"/> + <waitForElementVisible selector="{{CategoryDisplaySettingsSection.productListCheckBox}}" stepKey="waitForAvailableProductListCheckbox"/> <click selector="{{CategoryDisplaySettingsSection.productListCheckBox}}" stepKey="enableTheAvailableProductList"/> <selectOption selector="{{CategoryDisplaySettingsSection.productList}}" parameterArray="['Product Name', 'Price']" stepKey="selectPrice"/> <waitForElementVisible selector="{{CategoryDisplaySettingsSection.defaultProductLisCheckBox}}" stepKey="waitForDefaultProductList"/> @@ -54,9 +55,7 @@ <see selector="{{AdminCategoryContentSection.categoryPageTitle}}" userInput="{{_defaultCategory.name}}" stepKey="seeCategoryNamePageTitle" /> <!--Verify Category in store front page--> - <actionGroup ref="StorefrontGoToCategoryPageActionGroup" stepKey="openStorefrontCategoryPage"> - <argument name="categoryName" value="$createCategory.name$"/> - </actionGroup> + <amOnPage url="{{StorefrontCategoryPage.url($createCategory.custom_attributes[url_key]$)}}" stepKey="openStorefrontCategoryPage"/> <!--Verify Product in Category--> <actionGroup ref="AssertStorefrontProductIsPresentOnCategoryPageActionGroup" stepKey="assertSimpleProductOnCategoryPage"> From 70df4f05f74ecbb87355ac7c60fce6407436406b Mon Sep 17 00:00:00 2001 From: Vadim Malesh <51680850+engcom-Charlie@users.noreply.github.com> Date: Tue, 15 Sep 2020 13:17:58 +0300 Subject: [PATCH 104/132] add testCaseId --- .../Customer/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml index 53687607f6a5b..64e9f6d10bdb3 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminGridSearchSelectAllTest.xml @@ -12,7 +12,7 @@ <stories value="Selection should be removed during search."/> <title value="Selection should be removed during search."/> <description value="Empty selected before and after search, like it works for filter"/> - <testCaseId value=""/> + <testCaseId value="MC-37659"/> <severity value="CRITICAL"/> <group value="uI"/> </annotations> From a85a63b7fb59ae7cf92c3c1a2dc65afe49fcba3d Mon Sep 17 00:00:00 2001 From: Vadim Malesh <51680850+engcom-Charlie@users.noreply.github.com> Date: Tue, 15 Sep 2020 13:18:49 +0300 Subject: [PATCH 105/132] add testCaseId to AdminGridSelectAllOnPageTest --- .../Customer/Test/Mftf/Test/AdminGridSelectAllOnPageTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminGridSelectAllOnPageTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminGridSelectAllOnPageTest.xml index e74466d4e27af..bfc49fd476dd0 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/AdminGridSelectAllOnPageTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminGridSelectAllOnPageTest.xml @@ -12,7 +12,7 @@ <stories value="Toggle select page."/> <title value="Toggle select page."/> <description value="Empty selected before and after search, like it works for filter"/> - <testCaseId value=""/> + <testCaseId value="MC-37660"/> <severity value="CRITICAL"/> <group value="uI"/> </annotations> From 31e376a509d1acd6d852fb5f17ed54ca6d98cc15 Mon Sep 17 00:00:00 2001 From: Mykhailo Matiola <mykhailo.matiola@transoftgroup.com> Date: Tue, 15 Sep 2020 13:49:28 +0300 Subject: [PATCH 106/132] MC-37103: Create automated test for "Create order from customer page, free" --- .../AssertAdminFreePaymentActionGroup.xml | 17 +++++++++++++++++ .../Section/AdminOrderFormPaymentSection.xml | 1 + 2 files changed, 18 insertions(+) create mode 100644 app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml new file mode 100644 index 0000000000000..271ad76a7e8bc --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml @@ -0,0 +1,17 @@ +<?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="AssertAdminFreePaymentActionGroup"> + <annotations> + <description>Checks the free payment on the Admin Create Order page.</description> + </annotations> + <click selector="{{AdminOrderFormPaymentSection.linkPaymentOptions}}" stepKey="clickPaymentMethods"/> + <see selector="{{AdminOrderFormPaymentSection.freePaymentLabel}}" userInput="No Payment Information Required" stepKey="checkFreeShipping"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml index a478d79d8553f..ab612d4849ad2 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml @@ -28,5 +28,6 @@ <element name="cashOnDeliveryOption" type="radio" selector="#p_method_cashondelivery" timeout="30"/> <element name="purchaseOrderOption" type="radio" selector="#p_method_purchaseorder" timeout="30"/> <element name="purchaseOrderNumber" type="input" selector="#po_number"/> + <element name="freePaymentLabel" type="text" selector="#order-billing_method_form label[for='p_method_free']"/> </section> </sections> From 1535626df1c487201ded3eeab88d5e9e2f8e4161 Mon Sep 17 00:00:00 2001 From: Viktor Kopin <viktor.kopin@transoftgroup.com> Date: Tue, 15 Sep 2020 14:17:05 +0300 Subject: [PATCH 107/132] magento/adobe-stock-integration#1806: fix mftf test --- ...diaGalleryInsertLargeImageFileSizeTest.xml | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/app/code/Magento/MediaGalleryRenditions/Test/Mftf/Test/AdminMediaGalleryInsertLargeImageFileSizeTest.xml b/app/code/Magento/MediaGalleryRenditions/Test/Mftf/Test/AdminMediaGalleryInsertLargeImageFileSizeTest.xml index 27e1690d97e5a..0140b8fd90bc0 100644 --- a/app/code/Magento/MediaGalleryRenditions/Test/Mftf/Test/AdminMediaGalleryInsertLargeImageFileSizeTest.xml +++ b/app/code/Magento/MediaGalleryRenditions/Test/Mftf/Test/AdminMediaGalleryInsertLargeImageFileSizeTest.xml @@ -22,21 +22,18 @@ <before> <createData entity="SimpleSubCategory" stepKey="category"/> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <!-- Prepare configuration --> + <magentoCLI command="config:set system/media_gallery_renditions/width 50" stepKey="prepareWidth"/> + <magentoCLI command="config:set system/media_gallery_renditions/height 50" stepKey="prepareHeight"/> </before> <after> + <!-- Restore configuration --> + <magentoCLI command="config:set system/media_gallery_renditions/width 1000" stepKey="restoreWidth"/> + <magentoCLI command="config:set system/media_gallery_renditions/height 1000" stepKey="restoreHeight"/> <!-- Delete uploaded image --> - <actionGroup ref="AdminOpenCategoryGridPageActionGroup" stepKey="openCategoryPageFoDelete"/> - <actionGroup ref="AdminEditCategoryInGridPageActionGroup" stepKey="editCategoryItemForDelete"> - <argument name="categoryName" value="$category.name$"/> - </actionGroup> - <actionGroup ref="AdminOpenMediaGalleryFromCategoryImageUploaderActionGroup" stepKey="openMediaGalleryForDelete"/> - <actionGroup ref="AdminEnhancedMediaGalleryEnableMassActionModeActionGroup" stepKey="enableMassActionToDeleteImages"/> - <actionGroup ref="AdminEnhancedMediaGallerySelectImageForMassActionActionGroup" stepKey="selectSecondImageToDelete"> - <argument name="imageName" value="{{ImageUpload.fileName}}"/> - </actionGroup> - <actionGroup ref="AdminEnhancedMediaGalleryClickDeleteImagesButtonActionGroup" stepKey="clickDeleteSelectedButton"/> - <actionGroup ref="AdminEnhancedMediaGalleryConfirmDeleteImagesActionGroup" stepKey="deleteImages"/> - + <actionGroup ref="AdminOpenMediaGalleryFromCategoryImageUploaderActionGroup" stepKey="openMediaGalleryFromWysiwyg"/> + <actionGroup ref="AdminEnhancedMediaGalleryImageDeleteActionGroup" stepKey="removeSavedPreview"/> + <actionGroup ref="AdminAdobeStockMediaGalleryClearFiltersActionGroup" stepKey="clearFilters"/> <!-- Delete category --> <deleteData createDataKey="category" stepKey="deleteCategory"/> </after> @@ -49,17 +46,18 @@ <!-- Add image to category from gallery --> <actionGroup ref="AdminOpenMediaGalleryFromCategoryImageUploaderActionGroup" stepKey="openMediaGallery"/> - <actionGroup ref="AdminEnhancedMediaGalleryUploadImageActionGroup" stepKey="addCategoryImage"> - <argument name="image" value="ImageUpload"/> - </actionGroup> - <actionGroup ref="AdminMediaGalleryClickImageInGridActionGroup" stepKey="selectImage"> - <argument name="imageName" value="{{ImageUpload.fileName}}"/> + <actionGroup ref="AdminAdobeStockOpenFromEnhancedMediaGalleryActionGroup" stepKey="openAdobeStockPanel"/> + <actionGroup ref="AdminSearchImagesOnModalActionGroup" stepKey="searchForUnlicensedImage"> + <argument name="query" value="{{AdobeStockUnlicensedImage.id}}"/> </actionGroup> - <actionGroup ref="AdminMediaGalleryClickAddSelectedActionGroup" stepKey="addSelected"/> + <actionGroup ref="AdminAdobeStockExpandImagePreviewActionGroup" stepKey="expandImagePreview"/> + <actionGroup ref="AdminAdobeStockSavePreviewActionGroup" stepKey="saveImagePreview"/> + <actionGroup ref="AdminSaveAdobeStockImagePreviewActionGroup" stepKey="confirmSaveImagePreview"/> + <actionGroup ref="AdminMediaGalleryClickAddSelectedActionGroup" stepKey="addSelectedSavedPreview"/> <!-- Assert added image size --> <actionGroup ref="AdminAssertImageUploadFileSizeThanActionGroup" stepKey="assertSize"> - <argument name="fileSize" value="26 KB"/> + <argument name="fileSize" value="1 KB"/> </actionGroup> </test> </tests> From 7a121ac85d296ca4e5e59914fcc13575cb1dc812 Mon Sep 17 00:00:00 2001 From: Mykhailo Matiola <mykhailo.matiola@transoftgroup.com> Date: Tue, 15 Sep 2020 15:03:42 +0300 Subject: [PATCH 108/132] MC-37103: Create automated test for "Create order from customer page, free" --- .../Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml index 271ad76a7e8bc..7160f98f008cb 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml @@ -12,6 +12,7 @@ <description>Checks the free payment on the Admin Create Order page.</description> </annotations> <click selector="{{AdminOrderFormPaymentSection.linkPaymentOptions}}" stepKey="clickPaymentMethods"/> + <waitForAjaxLoad stepKey="waitForPaymentBlockLoad"/> <see selector="{{AdminOrderFormPaymentSection.freePaymentLabel}}" userInput="No Payment Information Required" stepKey="checkFreeShipping"/> </actionGroup> </actionGroups> From 751b8585c8457b66016b7860555951f8c5c42688 Mon Sep 17 00:00:00 2001 From: joweecaquicla <joie@abovethefray.io> Date: Tue, 15 Sep 2020 21:42:12 +0800 Subject: [PATCH 109/132] magento/adobe-stock-integration#1827: Improve AdminMediaGalleryUploadCategoryImageTest - applied request changes --- ...dminMediaGalleryExpandFolderActionGroup.xml | 18 ++++++++++++++++++ ...dminMediaGalleryUploadCategoryImageTest.xml | 5 +++-- 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminMediaGalleryExpandFolderActionGroup.xml diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminMediaGalleryExpandFolderActionGroup.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminMediaGalleryExpandFolderActionGroup.xml new file mode 100644 index 0000000000000..f10aed54c8447 --- /dev/null +++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminMediaGalleryExpandFolderActionGroup.xml @@ -0,0 +1,18 @@ +<?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="AdminMediaGalleryExpandFolderActionGroup"> + <arguments> + <argument name="fieldId" type="string"/> + </arguments> + <conditionalClick selector="{{AdminMediaGalleryFolderSection.folderArrow(fieldId)}}" + dependentSelector="{{AdminMediaGalleryFolderSection.checkIfFolderArrowExpand(fieldId)}}" stepKey="clickArrowIfClosed" visible="true"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminMediaGalleryUploadCategoryImageTest.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminMediaGalleryUploadCategoryImageTest.xml index f4b96683a620e..fa43e4e17d406 100644 --- a/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminMediaGalleryUploadCategoryImageTest.xml +++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/Test/AdminMediaGalleryUploadCategoryImageTest.xml @@ -37,8 +37,9 @@ <actionGroup ref="AdminSaveCategoryFormActionGroup" stepKey="saveCategoryForm"/> <actionGroup ref="AdminOpenMediaGalleryFromCategoryImageUploaderActionGroup" stepKey="openMediaGalleryFromImageUploader"/> <actionGroup ref="ClearFiltersAdminDataGridActionGroup" stepKey="clearFilter"/> - <conditionalClick selector="{{AdminMediaGalleryFolderSection.folderArrow(catalog)}}" - dependentSelector="{{AdminMediaGalleryFolderSection.checkIfFolderArrowExpand(catalog)}}" stepKey="clickArrowIfClosed" visible="true"/> + <actionGroup ref="AdminMediaGalleryExpandFolderActionGroup" stepKey="expandCatalogFolder"> + <argument name="fieldId" value="catalog"/> + </actionGroup> <actionGroup ref="AdminMediaGalleryFolderSelectActionGroup" stepKey="selectCategoryFolder"> <argument name="name" value="category"/> </actionGroup> From cbc38f64f28829ec4a0b9b86b0c9959ab0ddcdfd Mon Sep 17 00:00:00 2001 From: Viktor Kopin <viktor.kopin@transoftgroup.com> Date: Tue, 15 Sep 2020 16:43:17 +0300 Subject: [PATCH 110/132] magento/adobe-stock-integration#1806: revert mftf changes, add wait loading mask --- ...diaGalleryInsertLargeImageFileSizeTest.xml | 37 ++++++++++--------- ...ediaGalleryClickAddSelectedActionGroup.xml | 1 + 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/MediaGalleryRenditions/Test/Mftf/Test/AdminMediaGalleryInsertLargeImageFileSizeTest.xml b/app/code/Magento/MediaGalleryRenditions/Test/Mftf/Test/AdminMediaGalleryInsertLargeImageFileSizeTest.xml index 0140b8fd90bc0..d859f4852aaaf 100644 --- a/app/code/Magento/MediaGalleryRenditions/Test/Mftf/Test/AdminMediaGalleryInsertLargeImageFileSizeTest.xml +++ b/app/code/Magento/MediaGalleryRenditions/Test/Mftf/Test/AdminMediaGalleryInsertLargeImageFileSizeTest.xml @@ -22,18 +22,21 @@ <before> <createData entity="SimpleSubCategory" stepKey="category"/> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> - <!-- Prepare configuration --> - <magentoCLI command="config:set system/media_gallery_renditions/width 50" stepKey="prepareWidth"/> - <magentoCLI command="config:set system/media_gallery_renditions/height 50" stepKey="prepareHeight"/> </before> <after> - <!-- Restore configuration --> - <magentoCLI command="config:set system/media_gallery_renditions/width 1000" stepKey="restoreWidth"/> - <magentoCLI command="config:set system/media_gallery_renditions/height 1000" stepKey="restoreHeight"/> <!-- Delete uploaded image --> - <actionGroup ref="AdminOpenMediaGalleryFromCategoryImageUploaderActionGroup" stepKey="openMediaGalleryFromWysiwyg"/> - <actionGroup ref="AdminEnhancedMediaGalleryImageDeleteActionGroup" stepKey="removeSavedPreview"/> - <actionGroup ref="AdminAdobeStockMediaGalleryClearFiltersActionGroup" stepKey="clearFilters"/> + <actionGroup ref="AdminOpenCategoryGridPageActionGroup" stepKey="openCategoryPageFoDelete"/> + <actionGroup ref="AdminEditCategoryInGridPageActionGroup" stepKey="editCategoryItemForDelete"> + <argument name="categoryName" value="$category.name$"/> + </actionGroup> + <actionGroup ref="AdminOpenMediaGalleryFromCategoryImageUploaderActionGroup" stepKey="openMediaGalleryForDelete"/> + <actionGroup ref="AdminEnhancedMediaGalleryEnableMassActionModeActionGroup" stepKey="enableMassActionToDeleteImages"/> + <actionGroup ref="AdminEnhancedMediaGallerySelectImageForMassActionActionGroup" stepKey="selectSecondImageToDelete"> + <argument name="imageName" value="{{ImageUpload.fileName}}"/> + </actionGroup> + <actionGroup ref="AdminEnhancedMediaGalleryClickDeleteImagesButtonActionGroup" stepKey="clickDeleteSelectedButton"/> + <actionGroup ref="AdminEnhancedMediaGalleryConfirmDeleteImagesActionGroup" stepKey="deleteImages"/> + <!-- Delete category --> <deleteData createDataKey="category" stepKey="deleteCategory"/> </after> @@ -46,18 +49,18 @@ <!-- Add image to category from gallery --> <actionGroup ref="AdminOpenMediaGalleryFromCategoryImageUploaderActionGroup" stepKey="openMediaGallery"/> - <actionGroup ref="AdminAdobeStockOpenFromEnhancedMediaGalleryActionGroup" stepKey="openAdobeStockPanel"/> - <actionGroup ref="AdminSearchImagesOnModalActionGroup" stepKey="searchForUnlicensedImage"> - <argument name="query" value="{{AdobeStockUnlicensedImage.id}}"/> + <actionGroup ref="AdminEnhancedMediaGalleryUploadImageActionGroup" stepKey="addCategoryImage"> + <argument name="image" value="ImageUpload"/> + </actionGroup> + <actionGroup ref="AdminMediaGalleryClickImageInGridActionGroup" stepKey="selectImage"> + <argument name="imageName" value="{{ImageUpload.fileName}}"/> </actionGroup> - <actionGroup ref="AdminAdobeStockExpandImagePreviewActionGroup" stepKey="expandImagePreview"/> - <actionGroup ref="AdminAdobeStockSavePreviewActionGroup" stepKey="saveImagePreview"/> - <actionGroup ref="AdminSaveAdobeStockImagePreviewActionGroup" stepKey="confirmSaveImagePreview"/> - <actionGroup ref="AdminMediaGalleryClickAddSelectedActionGroup" stepKey="addSelectedSavedPreview"/> + <actionGroup ref="AdminMediaGalleryClickAddSelectedActionGroup" stepKey="addSelected"/> + <!-- Assert added image size --> <actionGroup ref="AdminAssertImageUploadFileSizeThanActionGroup" stepKey="assertSize"> - <argument name="fileSize" value="1 KB"/> + <argument name="fileSize" value="26 KB"/> </actionGroup> </test> </tests> diff --git a/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminMediaGalleryClickAddSelectedActionGroup.xml b/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminMediaGalleryClickAddSelectedActionGroup.xml index 28dcc1c553a5a..45ab4dc4538e0 100644 --- a/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminMediaGalleryClickAddSelectedActionGroup.xml +++ b/app/code/Magento/MediaGalleryUi/Test/Mftf/ActionGroup/AdminMediaGalleryClickAddSelectedActionGroup.xml @@ -12,5 +12,6 @@ <waitForElementVisible selector="{{AdminMediaGalleryHeaderButtonsSection.addSelected}}" stepKey="waitForAddSelectedButton"/> <click selector="{{AdminMediaGalleryHeaderButtonsSection.addSelected}}" stepKey="ClickAddSelected"/> <wait time="5" stepKey="waitForImageToBeAdded"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappear"/> </actionGroup> </actionGroups> From 0cafa206549c4cfe9aff495f2566b3213273a196 Mon Sep 17 00:00:00 2001 From: Viktor Kopin <viktor.kopin@transoftgroup.com> Date: Tue, 15 Sep 2020 23:41:01 +0300 Subject: [PATCH 111/132] magento/adobe-stock-integration#1806: fix relative path --- .../InsertImageData/GetInsertImageData.php | 45 ++++++++++++++----- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/MediaGalleryUi/Model/InsertImageData/GetInsertImageData.php b/app/code/Magento/MediaGalleryUi/Model/InsertImageData/GetInsertImageData.php index 486be92d6e0eb..e4e0a1bdc3313 100644 --- a/app/code/Magento/MediaGalleryUi/Model/InsertImageData/GetInsertImageData.php +++ b/app/code/Magento/MediaGalleryUi/Model/InsertImageData/GetInsertImageData.php @@ -8,6 +8,7 @@ namespace Magento\MediaGalleryUi\Model\InsertImageData; +use Magento\Cms\Helper\Wysiwyg\Images; use Magento\Cms\Model\Wysiwyg\Images\GetInsertImageContent; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\File\Mime; @@ -21,7 +22,7 @@ class GetInsertImageData /** * @var ReadInterface */ - private $pubDirectory; + private $mediaDirectory; /** * @var Filesystem @@ -43,6 +44,11 @@ class GetInsertImageData */ private $mime; + /** + * @var Images + */ + private $imagesHelper; + /** * GetInsertImageData constructor. * @@ -50,17 +56,20 @@ class GetInsertImageData * @param Filesystem $fileSystem * @param Mime $mime * @param InsertImageDataFactory $insertImageDataFactory + * @param Images $imagesHelper */ public function __construct( GetInsertImageContent $getInsertImageContent, Filesystem $fileSystem, Mime $mime, - InsertImageDataFactory $insertImageDataFactory + InsertImageDataFactory $insertImageDataFactory, + Images $imagesHelper ) { $this->getInsertImageContent = $getInsertImageContent; $this->filesystem = $fileSystem; $this->mime = $mime; $this->insertImageDataFactory = $insertImageDataFactory; + $this->imagesHelper = $imagesHelper; } /** @@ -84,8 +93,9 @@ public function execute( $renderAsTag, $storeId ); - $size = $forceStaticPath ? $this->getSize($content) : 0; - $type = $forceStaticPath ? $this->getType($content) : ''; + $relativePath = $this->getImageRelativePath($content); + $size = $forceStaticPath ? $this->getSize($relativePath) : 0; + $type = $forceStaticPath ? $this->getType($relativePath) : ''; return $this->insertImageDataFactory->create([ 'content' => $content, 'size' => $size, @@ -101,7 +111,7 @@ public function execute( */ private function getSize(string $path): int { - $directory = $this->getPubDirectory(); + $directory = $this->getMediaDirectory(); return $directory->isExist($path) ? $directory->stat($path)['size'] : 0; } @@ -114,9 +124,9 @@ private function getSize(string $path): int */ public function getType(string $path): string { - $fileExist = $this->getPubDirectory()->isExist($path); + $fileExist = $this->getMediaDirectory()->isExist($path); - return $fileExist ? $this->mime->getMimeType($this->getPubDirectory()->getAbsolutePath($path)) : ''; + return $fileExist ? $this->mime->getMimeType($this->getMediaDirectory()->getAbsolutePath($path)) : ''; } /** @@ -124,11 +134,24 @@ public function getType(string $path): string * * @return ReadInterface */ - private function getPubDirectory(): ReadInterface + private function getMediaDirectory(): ReadInterface { - if ($this->pubDirectory === null) { - $this->pubDirectory = $this->filesystem->getDirectoryRead(DirectoryList::PUB); + if ($this->mediaDirectory === null) { + $this->mediaDirectory = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA); } - return $this->pubDirectory; + + return $this->mediaDirectory; + } + + /** + * Retrieves image relative path + * + * @param string $content + * @return string + */ + private function getImageRelativePath(string $content): string + { + $mediaPath = parse_url($this->imagesHelper->getCurrentUrl(), PHP_URL_PATH); + return substr($content, strlen($mediaPath)); } } From 202dd910f0a1f1739c25a98fb194e1b5934a84a8 Mon Sep 17 00:00:00 2001 From: Serhii Balko <serhii.balko@transoftgroup.com> Date: Wed, 16 Sep 2020 09:36:32 +0300 Subject: [PATCH 112/132] MC-36836: Stabilize integration tests --- .../ConfigurableProduct/_files/configurable_products.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_products.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_products.php index 61c2bf7b5fa72..f6e6261c75662 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_products.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_products.php @@ -44,7 +44,6 @@ $product = $objectManager->create(Product::class); $productId = array_shift($productIds); $product->setTypeId(Type::TYPE_SIMPLE) - ->setId($productId) ->setAttributeSetId($attributeSetId) ->setWebsiteIds([1]) ->setName('Configurable Option' . $option->getLabel()) @@ -84,7 +83,6 @@ $product->setExtensionAttributes($extensionConfigurableAttributes); $product->setTypeId(Configurable::TYPE_CODE) - ->setId(1) ->setAttributeSetId($attributeSetId) ->setWebsiteIds([1]) ->setName('Configurable Product') @@ -110,7 +108,6 @@ $product = $objectManager->create(Product::class); $productId = array_shift($productIds); $product->setTypeId(Type::TYPE_SIMPLE) - ->setId($productId) ->setAttributeSetId($attributeSetId) ->setWebsiteIds([1]) ->setName('Configurable Option' . $option->getLabel()) @@ -155,7 +152,6 @@ $product->setExtensionAttributes($extensionConfigurableAttributes); $product->setTypeId(Configurable::TYPE_CODE) - ->setId(11) ->setAttributeSetId($attributeSetId) ->setWebsiteIds([1]) ->setName('Configurable Product 12345') From 35642f7b3af5eadf3c05d47ee19412f547233ee4 Mon Sep 17 00:00:00 2001 From: Viktor Kopin <viktor.kopin@transoftgroup.com> Date: Wed, 16 Sep 2020 09:56:46 +0300 Subject: [PATCH 113/132] magento/adobe-stock-integration#1806: fix static tests --- .../MediaGalleryUi/Model/InsertImageData/GetInsertImageData.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/MediaGalleryUi/Model/InsertImageData/GetInsertImageData.php b/app/code/Magento/MediaGalleryUi/Model/InsertImageData/GetInsertImageData.php index e4e0a1bdc3313..6f1d399784139 100644 --- a/app/code/Magento/MediaGalleryUi/Model/InsertImageData/GetInsertImageData.php +++ b/app/code/Magento/MediaGalleryUi/Model/InsertImageData/GetInsertImageData.php @@ -151,6 +151,7 @@ private function getMediaDirectory(): ReadInterface */ private function getImageRelativePath(string $content): string { + // phpcs:ignore Magento2.Functions.DiscouragedFunction $mediaPath = parse_url($this->imagesHelper->getCurrentUrl(), PHP_URL_PATH); return substr($content, strlen($mediaPath)); } From a69f6c63aa84f83f6ae552ec5599ccb4c123630d Mon Sep 17 00:00:00 2001 From: Mykhailo Matiola <mykhailo.matiola@transoftgroup.com> Date: Wed, 16 Sep 2020 11:01:26 +0300 Subject: [PATCH 114/132] MC-37103: Create automated test for "Create order from customer page, free" --- .../Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml index 7160f98f008cb..f4caaa73aa58f 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml @@ -13,6 +13,6 @@ </annotations> <click selector="{{AdminOrderFormPaymentSection.linkPaymentOptions}}" stepKey="clickPaymentMethods"/> <waitForAjaxLoad stepKey="waitForPaymentBlockLoad"/> - <see selector="{{AdminOrderFormPaymentSection.freePaymentLabel}}" userInput="No Payment Information Required" stepKey="checkFreeShipping"/> + <see selector="{{AdminOrderFormPaymentSection.freePaymentLabel}}" userInput="No Payment Information Required" stepKey="checkFreePaymentLabel"/> </actionGroup> </actionGroups> From 92654aa7621bf420386c20421b49f05f9538d0be Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@transoftgroup.com> Date: Wed, 16 Sep 2020 11:25:09 +0300 Subject: [PATCH 115/132] MC-25238: Unstable Test "StorefrontCheckoutWithDifferentShippingAndBillingAddressAndRegisterCustomerAfterCheckoutTest" --- .../CheckoutFillEstimateShippingAndTaxActionGroup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutFillEstimateShippingAndTaxActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutFillEstimateShippingAndTaxActionGroup.xml index d6180d64ea82f..49b950fd51fdc 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutFillEstimateShippingAndTaxActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutFillEstimateShippingAndTaxActionGroup.xml @@ -13,7 +13,7 @@ <argument name="address" defaultValue="US_Address_TX" type="entity"/> </arguments> <conditionalClick selector="{{CheckoutCartSummarySection.estimateShippingAndTax}}" dependentSelector="{{CheckoutCartSummarySection.estimateShippingAndTaxSummary}}" visible="false" stepKey="openShippingDetails"/> - <waitForElementVisible selector="{{CheckoutCartSummarySection.estimateShippingAndTax}}" stepKey="waitForSummarySectionLoad"/> + <waitForElementVisible selector="{{CheckoutCartSummarySection.country}}" stepKey="waitForSummarySectionLoad"/> <selectOption selector="{{CheckoutCartSummarySection.country}}" userInput="{{address.country_id}}" stepKey="selectCountry"/> <selectOption selector="{{CheckoutCartSummarySection.stateProvince}}" userInput="{{address.state}}" stepKey="selectState"/> <waitForElementVisible selector="{{CheckoutCartSummarySection.postcode}}" stepKey="waitForPostCodeVisible"/> From 31811672508dcffb5d4c5aa324b6f61ecf2c510d Mon Sep 17 00:00:00 2001 From: Serhii Balko <serhii.balko@transoftgroup.com> Date: Wed, 16 Sep 2020 11:43:13 +0300 Subject: [PATCH 116/132] MC-36836: Stabilize integration tests --- .../Multishipping/Fixtures/quote_with_configurable_product.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Multishipping/Fixtures/quote_with_configurable_product.php b/dev/tests/integration/testsuite/Magento/Multishipping/Fixtures/quote_with_configurable_product.php index 31b0ac84266e7..3b70659f80a42 100644 --- a/dev/tests/integration/testsuite/Magento/Multishipping/Fixtures/quote_with_configurable_product.php +++ b/dev/tests/integration/testsuite/Magento/Multishipping/Fixtures/quote_with_configurable_product.php @@ -24,7 +24,7 @@ $objectManager = Bootstrap::getObjectManager(); /** @var ProductRepositoryInterface $productRepository */ $productRepository = $objectManager->create(ProductRepositoryInterface::class); -$product = $productRepository->getById(10); +$product = $productRepository->get('simple_10'); $product->setStockData(['use_config_manage_stock' => 1, 'qty' => 4, 'is_qty_decimal' => 0, 'is_in_stock' => 1]); $productRepository->save($product); From 0993a482bfd84afb0c5c30fdfc607f24f7eb1b15 Mon Sep 17 00:00:00 2001 From: Mykhailo Matiola <mykhailo.matiola@transoftgroup.com> Date: Wed, 16 Sep 2020 13:21:22 +0300 Subject: [PATCH 117/132] MC-37103: Create automated test for "Create order from customer page, free" --- ...inFreePaymentMethodExistsOnCreateOrderPageActionGroup.xml} | 4 ++-- .../Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename app/code/Magento/Sales/Test/Mftf/ActionGroup/{AssertAdminFreePaymentActionGroup.xml => AssertAdminFreePaymentMethodExistsOnCreateOrderPageActionGroup.xml} (77%) diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentMethodExistsOnCreateOrderPageActionGroup.xml similarity index 77% rename from app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml rename to app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentMethodExistsOnCreateOrderPageActionGroup.xml index f4caaa73aa58f..75146e891a02a 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminFreePaymentMethodExistsOnCreateOrderPageActionGroup.xml @@ -7,12 +7,12 @@ --> <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AssertAdminFreePaymentActionGroup"> + <actionGroup name="AssertAdminFreePaymentMethodExistsOnCreateOrderPageActionGroup"> <annotations> <description>Checks the free payment on the Admin Create Order page.</description> </annotations> <click selector="{{AdminOrderFormPaymentSection.linkPaymentOptions}}" stepKey="clickPaymentMethods"/> - <waitForAjaxLoad stepKey="waitForPaymentBlockLoad"/> + <waitForElementVisible selector="{{AdminOrderFormPaymentSection.freePaymentLabel}}" stepKey="waitForPaymentLabelVisible"/> <see selector="{{AdminOrderFormPaymentSection.freePaymentLabel}}" userInput="No Payment Information Required" stepKey="checkFreePaymentLabel"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml index ab612d4849ad2..72fe45465c67b 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml @@ -15,7 +15,7 @@ <element name="flatRateOption" type="radio" selector="#s_method_flatrate_flatrate" timeout="30"/> <element name="shippingError" type="text" selector="#order[has_shipping]-error"/> <element name="freeShippingOption" type="radio" selector="#s_method_freeshipping_freeshipping" timeout="30"/> - <element name="linkPaymentOptions" type="button" selector="#order-billing_method_summary>a"/> + <element name="linkPaymentOptions" type="button" selector="#order-billing_method_summary>a" timeout="30"/> <element name="blockPayment" type="text" selector="#order-billing_method"/> <element name="checkMoneyOption" type="radio" selector="#p_method_checkmo" timeout="30"/> <element name="checkBankTransfer" type="radio" selector="#p_method_banktransfer" timeout="30"/> From a7eadf4af474acafaf740d8b9a6b8011b9ba8f38 Mon Sep 17 00:00:00 2001 From: Serhii Balko <serhii.balko@transoftgroup.com> Date: Wed, 16 Sep 2020 13:59:25 +0300 Subject: [PATCH 118/132] MC-36836: Stabilize integration tests --- .../_files/quote_with_configurable_product_last_variation.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/quote_with_configurable_product_last_variation.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/quote_with_configurable_product_last_variation.php index 072c0cd8f9118..1f0dee32ce4a2 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/quote_with_configurable_product_last_variation.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/quote_with_configurable_product_last_variation.php @@ -14,11 +14,11 @@ $quote = $objectManager->create(\Magento\Quote\Model\Quote::class); /** @var ProductRepositoryInterface $productRepository */ $productRepository = $objectManager->create(ProductRepositoryInterface::class); -$product = $productRepository->getById(10); +$product = $productRepository->get('simple_10'); $product->setStockData(['use_config_manage_stock' => 1, 'qty' => 1, 'is_qty_decimal' => 0, 'is_in_stock' => 1]); $productRepository->save($product); -$product = $productRepository->getById(20); +$product = $productRepository->get('simple_20'); $product->setStockData(['use_config_manage_stock' => 1, 'qty' => 0, 'is_qty_decimal' => 0, 'is_in_stock' => 0]); $productRepository->save($product); From 964826c89f1364ec98c2ef40d015ff4506a521ed Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Wed, 16 Sep 2020 12:39:46 +0300 Subject: [PATCH 119/132] MC-23649: Flaky MFTF Test: MC-11016: Delete Bundle Dynamic Product --- ...minDeleteBundleDynamicPriceProductTest.xml | 70 +++++++++++++++++++ .../AdminDeleteBundleDynamicProductTest.xml | 6 +- 2 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml new file mode 100644 index 0000000000000..5e1eadf8be286 --- /dev/null +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminDeleteBundleDynamicPriceProductTest"> + <annotations> + <features value="Bundle"/> + <stories value="Delete products"/> + <title value="Delete Bundle Dynamic Product"/> + <description value="Admin should be able to delete a bundle dynamic product"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-26056"/> + <group value="mtf_migrated"/> + <group value="bundle"/> + </annotations> + <before> + <!-- Create category and simple product --> + <createData entity="SimpleSubCategory" stepKey="createCategory"/> + <createData entity="SimpleProduct2" stepKey="createSimpleProduct"/> + + <!-- Create bundle product --> + <createData entity="ApiBundleProductPriceViewRange" stepKey="createDynamicBundleProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="DropDownBundleOption" stepKey="bundleOption"> + <requiredEntity createDataKey="createDynamicBundleProduct"/> + </createData> + <createData entity="ApiBundleLink" stepKey="createNewBundleLink"> + <requiredEntity createDataKey="createDynamicBundleProduct"/> + <requiredEntity createDataKey="bundleOption"/> + <requiredEntity createDataKey="createSimpleProduct"/> + </createData> + + <magentoCron groups="index" stepKey="runCronIndex"/> + <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> + <argument name="tags" value=""/> + </actionGroup> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + </before> + <after> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + </after> + <actionGroup ref="DeleteProductUsingProductGridActionGroup" stepKey="deleteBundleProductFilteredBySkuAndName"> + <argument name="product" value="$createDynamicBundleProduct$"/> + </actionGroup> + <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="A total of 1 record(s) have been deleted." stepKey="deleteMessage"/> + <!-- Verify product on Product Page --> + <amOnPage url="{{StorefrontProductPage.url($createDynamicBundleProduct.custom_attributes[url_key]$)}}" stepKey="openBundleProductPage"/> + <see selector="{{StorefrontProductInfoMainSection.productName}}" userInput="Whoops, our bad..." stepKey="seeWhoopsMessage"/> + <!-- Search for the product by sku --> + <actionGroup ref="StoreFrontQuickSearchActionGroup" stepKey="searchBySku"> + <argument name="query" value="$createDynamicBundleProduct.sku$"/> + </actionGroup> + <!-- Should not see bundle product --> + <dontSee userInput="$createDynamicBundleProduct.sku$" selector="{{StorefrontCatalogSearchMainSection.searchResults}}" stepKey="dontSeeProduct"/> + <comment userInput="redundant action" stepKey="seeCantFindProductMessage"/> + <amOnPage url="{{StorefrontCategoryPage.url($createCategory.custom_attributes[url_key]$)}}" stepKey="openCategoryPage"/> + <!-- Should not see any products in category --> + <dontSee userInput="$createDynamicBundleProduct.name$" selector="{{StorefrontCategoryMainSection.productsList}}" stepKey="dontSeeProductInCategory"/> + <see selector="{{StorefrontCategoryMainSection.emptyProductMessage}}" userInput="We can't find products matching the selection." stepKey="seeEmptyProductMessage"/> + </test> +</tests> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicProductTest.xml index a2f26e235fc23..ed0c811b88a10 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicProductTest.xml @@ -11,13 +11,13 @@ <annotations> <features value="Bundle"/> <stories value="Delete products"/> - <title value="Delete Bundle Dynamic Product"/> - <description value="Admin should be able to delete a bundle dynamic product"/> + <title value="Deprecated. Delete Bundle Dynamic Product"/> + <description value="Deprecated. Admin should be able to delete a bundle dynamic product"/> <severity value="CRITICAL"/> <testCaseId value="MC-11016"/> <group value="mtf_migrated"/> <skip> - <issueId value="MC-16393"/> + <issueId value="DEPRECATED">Use AdminDeleteBundleDynamicPriceProductTest instead</issueId> </skip> </annotations> <before> From d0d2265b072c3c28a293301c4366aff10932a3f7 Mon Sep 17 00:00:00 2001 From: Viktor Kopin <viktor.kopin@transoftgroup.com> Date: Wed, 16 Sep 2020 17:11:54 +0300 Subject: [PATCH 120/132] magento/adobe-stock-integration#1806: add action group --- ...AdminRenditionsSetImageSizeActionGroup.xml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 app/code/Magento/MediaGalleryRenditions/Test/Mftf/ActionGroup/AdminRenditionsSetImageSizeActionGroup.xml diff --git a/app/code/Magento/MediaGalleryRenditions/Test/Mftf/ActionGroup/AdminRenditionsSetImageSizeActionGroup.xml b/app/code/Magento/MediaGalleryRenditions/Test/Mftf/ActionGroup/AdminRenditionsSetImageSizeActionGroup.xml new file mode 100644 index 0000000000000..e55b4eba6aa9b --- /dev/null +++ b/app/code/Magento/MediaGalleryRenditions/Test/Mftf/ActionGroup/AdminRenditionsSetImageSizeActionGroup.xml @@ -0,0 +1,20 @@ +<?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="AdminRenditionsSetImageSizeActionGroup"> + <arguments> + <argument name="width" defaultValue="1000" type="string"/> + <argument name="height" defaultValue="1000" type="string"/> + </arguments> + <magentoCLI command="config:set system/media_gallery_renditions/width {{width}}" stepKey="setWidth"/> + <magentoCLI command="config:set system/media_gallery_renditions/height {{height}}" stepKey="setHeight"/> + <magentoCLI command="cache:flush config" stepKey="cleanCache"/> + </actionGroup> +</actionGroups> From 885150d4bc8d31fcbb4db1bf9732d43466598e76 Mon Sep 17 00:00:00 2001 From: Viktor Kopin <viktor.kopin@transoftgroup.com> Date: Wed, 16 Sep 2020 17:27:39 +0300 Subject: [PATCH 121/132] magento/adobe-stock-integration#1806: remove cache flush --- .../Mftf/ActionGroup/AdminRenditionsSetImageSizeActionGroup.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/MediaGalleryRenditions/Test/Mftf/ActionGroup/AdminRenditionsSetImageSizeActionGroup.xml b/app/code/Magento/MediaGalleryRenditions/Test/Mftf/ActionGroup/AdminRenditionsSetImageSizeActionGroup.xml index e55b4eba6aa9b..b841d064aab7e 100644 --- a/app/code/Magento/MediaGalleryRenditions/Test/Mftf/ActionGroup/AdminRenditionsSetImageSizeActionGroup.xml +++ b/app/code/Magento/MediaGalleryRenditions/Test/Mftf/ActionGroup/AdminRenditionsSetImageSizeActionGroup.xml @@ -15,6 +15,5 @@ </arguments> <magentoCLI command="config:set system/media_gallery_renditions/width {{width}}" stepKey="setWidth"/> <magentoCLI command="config:set system/media_gallery_renditions/height {{height}}" stepKey="setHeight"/> - <magentoCLI command="cache:flush config" stepKey="cleanCache"/> </actionGroup> </actionGroups> From 5af6dbc2699dde3d0830f09bb6d6549f0ddd95a9 Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Wed, 16 Sep 2020 18:44:13 +0300 Subject: [PATCH 122/132] magento/adobe-stock-integration#1729: Reduced html content of image details templates --- .../adminhtml/templates/image_details.phtml | 27 +++----------- .../templates/image_details_standalone.phtml | 31 ++++------------ .../templates/image_edit_details.phtml | 35 +++++-------------- .../image_edit_details_standalone.phtml | 35 +++++-------------- .../adminhtml/web/template/image/actions.html | 19 ++++++---- 5 files changed, 39 insertions(+), 108 deletions(-) diff --git a/app/code/Magento/MediaGalleryUi/view/adminhtml/templates/image_details.phtml b/app/code/Magento/MediaGalleryUi/view/adminhtml/templates/image_details.phtml index 5df5c1a6c4cbd..783ff5a9c05bd 100644 --- a/app/code/Magento/MediaGalleryUi/view/adminhtml/templates/image_details.phtml +++ b/app/code/Magento/MediaGalleryUi/view/adminhtml/templates/image_details.phtml @@ -22,15 +22,8 @@ use Magento\Framework\Escaper; title: '<?= $escaper->escapeHtmlAttr(__('Image Details')); ?>' } }"> - <div class="page-main-actions"> - <div class="page-actions"> - <div class="page-actions-inner"> - <div class="page-action-buttons" id="media-gallery-image-actions" - data-bind="scope: 'mediaGalleryImageActions'"> - <!-- ko template: getTemplate() --><!-- /ko --> - </div> - </div> - </div> + <div class="page-main-actions" data-bind="scope: 'mediaGalleryImageActions'"> + <!-- ko template: getTemplate() --><!-- /ko --> </div> <div id="media-gallery-image-details-messages" data-bind="scope: 'mediaGalleryImageDetailsMessages'"> <!-- ko template: getTemplate() --><!-- /ko --> @@ -51,22 +44,10 @@ use Magento\Framework\Escaper; "modalSelector": ".media-gallery-image-details-modal", "modalWindowSelector": ".media-gallery-image-details", "mediaGridMessages": "media_gallery_listing.media_gallery_listing.messages" - } - } - } - }, - "#media-gallery-image-details-messages": { - "Magento_Ui/js/core/app": { - "components": { + }, "mediaGalleryImageDetailsMessages": { "component": "Magento_MediaGalleryUi/js/grid/messages" - } - } - } - }, - "#media-gallery-image-actions": { - "Magento_Ui/js/core/app": { - "components": { + }, "mediaGalleryImageActions": { "component": "Magento_MediaGalleryUi/js/image/image-actions", "modalSelector": ".media-gallery-image-details-modal", diff --git a/app/code/Magento/MediaGalleryUi/view/adminhtml/templates/image_details_standalone.phtml b/app/code/Magento/MediaGalleryUi/view/adminhtml/templates/image_details_standalone.phtml index fdae0a549606c..a4a096939eea4 100644 --- a/app/code/Magento/MediaGalleryUi/view/adminhtml/templates/image_details_standalone.phtml +++ b/app/code/Magento/MediaGalleryUi/view/adminhtml/templates/image_details_standalone.phtml @@ -18,15 +18,8 @@ title: '<?= $escaper->escapeHtmlAttr(__('Image Details')); ?>' } }"> - <div class="page-main-actions"> - <div class="page-actions"> - <div class="page-actions-inner"> - <div class="page-action-buttons" id="media-gallery-image-actions" - data-bind="scope: 'mediaGalleryImageActions'"> - <!-- ko template: getTemplate() --><!-- /ko --> - </div> - </div> - </div> + <div class="page-main-actions" data-bind="scope: 'mediaGalleryImageActions'"> + <!-- ko template: getTemplate() --><!-- /ko --> </div> <div id="media-gallery-image-details-messages" data-bind="scope: 'mediaGalleryImageDetailsMessages'"> <!-- ko template: getTemplate() --><!-- /ko --> @@ -47,22 +40,7 @@ "modalSelector": ".media-gallery-image-details-modal", "modalWindowSelector": ".media-gallery-image-details", "mediaGridMessages": "standalone_media_gallery_listing.standalone_media_gallery_listing.messages" - } - } - } - }, - "#media-gallery-image-details-messages": { - "Magento_Ui/js/core/app": { - "components": { - "mediaGalleryImageDetailsMessages": { - "component": "Magento_MediaGalleryUi/js/grid/messages" - } - } - } - }, - "#media-gallery-image-actions": { - "Magento_Ui/js/core/app": { - "components": { + }, "mediaGalleryImageActions": { "component": "Magento_MediaGalleryUi/js/image/image-actions", "modalSelector": ".media-gallery-image-details-modal", @@ -70,6 +48,9 @@ "mediaGalleryImageDetailsName": "mediaGalleryImageDetails", "imageModelName" : "standalone_media_gallery_listing.standalone_media_gallery_listing.media_gallery_columns.thumbnail_url", "actionsList": <?= /* @noEscape */ $block->getActionsJson() ?> + }, + "mediaGalleryImageDetailsMessages": { + "component": "Magento_MediaGalleryUi/js/grid/messages" } } } diff --git a/app/code/Magento/MediaGalleryUi/view/adminhtml/templates/image_edit_details.phtml b/app/code/Magento/MediaGalleryUi/view/adminhtml/templates/image_edit_details.phtml index c2b7e66cc89bd..bda0dccb9ae4b 100644 --- a/app/code/Magento/MediaGalleryUi/view/adminhtml/templates/image_edit_details.phtml +++ b/app/code/Magento/MediaGalleryUi/view/adminhtml/templates/image_edit_details.phtml @@ -20,15 +20,8 @@ use Magento\Backend\Block\Template; title: '<?= $escaper->escapeHtmlAttr(__('Edit Image')); ?>' } }"> - <div class="page-main-actions"> - <div class="page-actions"> - <div class="page-actions-inner"> - <div class="page-action-buttons" id="media-gallery-edit-image-actions" - data-bind="scope: 'mediaGalleryImageEditActions'"> - <!-- ko template: getTemplate() --><!-- /ko --> - </div> - </div> - </div> + <div class="page-main-actions" data-bind="scope: 'mediaGalleryImageEditActions'"> + <!-- ko template: getTemplate() --><!-- /ko --> </div> <div id="media-gallery-image-edit-details-messages" data-bind="scope: 'mediaGalleryEditDetailsMessages'"> <!-- ko template: getTemplate() --><!-- /ko --> @@ -50,25 +43,10 @@ use Magento\Backend\Block\Template; "imageEditDetailsUrl": "<?= $escaper->escapeJs($block->getData('imageEditDetailsUrl')); ?>", "saveDetailsUrl": "<?= $escaper->escapeJs($block->getData('saveDetailsUrl')); ?>", "mediaGridMessages": "standalone_media_gallery_listing.standalone_media_gallery_listing.messages" - } - } - }, - "Magento_MediaGalleryUi/js/validation/validate-image-title": {}, - "Magento_MediaGalleryUi/js/validation/validate-image-description": {}, - "Magento_MediaGalleryUi/js/validation/validate-image-keyword": {} - }, - "#media-gallery-image-edit-details-messages": { - "Magento_Ui/js/core/app": { - "components": { + }, "mediaGalleryEditDetailsMessages": { "component": "Magento_MediaGalleryUi/js/grid/messages" - } - } - } - }, - "#media-gallery-edit-image-actions": { - "Magento_Ui/js/core/app": { - "components": { + }, "mediaGalleryImageEditActions": { "component": "Magento_MediaGalleryUi/js/image/image-actions", "modalSelector": ".media-gallery-edit-image-details-modal", @@ -91,7 +69,10 @@ use Magento\Backend\Block\Template; ] } } - } + }, + "Magento_MediaGalleryUi/js/validation/validate-image-title": {}, + "Magento_MediaGalleryUi/js/validation/validate-image-description": {}, + "Magento_MediaGalleryUi/js/validation/validate-image-keyword": {} } } </script> diff --git a/app/code/Magento/MediaGalleryUi/view/adminhtml/templates/image_edit_details_standalone.phtml b/app/code/Magento/MediaGalleryUi/view/adminhtml/templates/image_edit_details_standalone.phtml index ec48ed8bb9053..9a8f01b1c2939 100644 --- a/app/code/Magento/MediaGalleryUi/view/adminhtml/templates/image_edit_details_standalone.phtml +++ b/app/code/Magento/MediaGalleryUi/view/adminhtml/templates/image_edit_details_standalone.phtml @@ -20,15 +20,8 @@ use Magento\Backend\Block\Template; title: '<?= $escaper->escapeHtmlAttr(__('Edit Image')); ?>' } }"> - <div class="page-main-actions"> - <div class="page-actions"> - <div class="page-actions-inner"> - <div class="page-action-buttons" id="media-gallery-edit-image-actions" - data-bind="scope: 'mediaGalleryImageEditActions'"> - <!-- ko template: getTemplate() --><!-- /ko --> - </div> - </div> - </div> + <div class="page-main-actions" data-bind="scope: 'mediaGalleryImageEditActions'"> + <!-- ko template: getTemplate() --><!-- /ko --> </div> <div id="media-gallery-image-edit-details-messages" data-bind="scope: 'mediaGalleryEditDetailsMessages'"> <!-- ko template: getTemplate() --><!-- /ko --> @@ -50,25 +43,10 @@ use Magento\Backend\Block\Template; "imageEditDetailsUrl": "<?= $escaper->escapeJs($block->getData('imageEditDetailsUrl')); ?>", "saveDetailsUrl": "<?= $escaper->escapeJs($block->getData('saveDetailsUrl')); ?>", "mediaGridMessages": "standalone_media_gallery_listing.standalone_media_gallery_listing.messages" - } - } - }, - "Magento_MediaGalleryUi/js/validation/validate-image-title": {}, - "Magento_MediaGalleryUi/js/validation/validate-image-description": {}, - "Magento_MediaGalleryUi/js/validation/validate-image-keyword": {} - }, - "#media-gallery-image-edit-details-messages": { - "Magento_Ui/js/core/app": { - "components": { + }, "mediaGalleryEditDetailsMessages": { "component": "Magento_MediaGalleryUi/js/grid/messages" - } - } - } - }, - "#media-gallery-edit-image-actions": { - "Magento_Ui/js/core/app": { - "components": { + }, "mediaGalleryImageEditActions": { "component": "Magento_MediaGalleryUi/js/image/image-actions", "modalSelector": ".media-gallery-edit-image-details-modal", @@ -91,7 +69,10 @@ use Magento\Backend\Block\Template; ] } } - } + }, + "Magento_MediaGalleryUi/js/validation/validate-image-title": {}, + "Magento_MediaGalleryUi/js/validation/validate-image-description": {}, + "Magento_MediaGalleryUi/js/validation/validate-image-keyword": {} } } </script> diff --git a/app/code/Magento/MediaGalleryUi/view/adminhtml/web/template/image/actions.html b/app/code/Magento/MediaGalleryUi/view/adminhtml/web/template/image/actions.html index 8ecaf0bd2a019..3a80116c9225e 100644 --- a/app/code/Magento/MediaGalleryUi/view/adminhtml/web/template/image/actions.html +++ b/app/code/Magento/MediaGalleryUi/view/adminhtml/web/template/image/actions.html @@ -4,9 +4,16 @@ * See COPYING.txt for license details. */ --> -<each args="{ data: actionsList, as: 'action' }"> - <button type="button" click="$parent[action.handler].bind($parent)" - attr="{class: action.classes, id: 'image-details-action-' + action.name, title: $t(action.title)}"> - <span translate="action.title"></span> - </button> -</each> +<div class="page-actions"> + <div class="page-actions-inner"> + <div class="page-action-buttons"> + <each args="{ data: actionsList, as: 'action' }"> + <button type="button" click="$parent[action.handler].bind($parent)" + attr="{class: action.classes, id: 'image-details-action-' + action.name, title: $t(action.title)}"> + <span translate="action.title"></span> + </button> + </each> + </div> + </div> +</div> + From 41f22a37e391f8e35943662df7ea5c0ce3413598 Mon Sep 17 00:00:00 2001 From: Oleh Usik <o.usik@atwix.com> Date: Thu, 17 Sep 2020 00:00:18 +0300 Subject: [PATCH 123/132] deprecated GoToAttributeGridPageActionGroup --- .../ActionGroup/AdminOpenAttributeSetGridPageActionGroup.xml | 4 ++++ .../Mftf/ActionGroup/GoToAttributeGridPageActionGroup.xml | 2 +- .../Test/StorefrontQuickSearchConfigurableChildrenTest.xml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminOpenAttributeSetGridPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminOpenAttributeSetGridPageActionGroup.xml index c6f0c3332b1d5..38193fe547e52 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminOpenAttributeSetGridPageActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminOpenAttributeSetGridPageActionGroup.xml @@ -8,6 +8,10 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="AdminOpenAttributeSetGridPageActionGroup"> + <annotations> + <description>Open the Attribute Sets grid page.</description> + </annotations> + <amOnPage url="{{AdminProductAttributeSetGridPage.url}}" stepKey="goToAttributeSetPage"/> <waitForPageLoad stepKey="waitForAttributeSetPageLoad"/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/GoToAttributeGridPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/GoToAttributeGridPageActionGroup.xml index 2b5fe9d76875c..6e44c33d81ba4 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/GoToAttributeGridPageActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/GoToAttributeGridPageActionGroup.xml @@ -8,7 +8,7 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="GoToAttributeGridPageActionGroup"> + <actionGroup name="GoToAttributeGridPageActionGroup" deprecated="Use AdminOpenAttributeSetGridPageActionGroup instead."> <annotations> <description>Goes to the Attribute Sets grid page.</description> </annotations> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontQuickSearchConfigurableChildrenTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontQuickSearchConfigurableChildrenTest.xml index 66d695cbb2025..67e8bc6bf183c 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontQuickSearchConfigurableChildrenTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontQuickSearchConfigurableChildrenTest.xml @@ -32,7 +32,7 @@ <!-- Assign attribute to set --> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> - <actionGroup ref="GoToAttributeGridPageActionGroup" stepKey="goToAttributeSetPage"/> + <actionGroup ref="AdminOpenAttributeSetGridPageActionGroup" stepKey="goToAttributeSetPage"/> <actionGroup ref="GoToAttributeSetByNameActionGroup" stepKey="openAttributeSetByName"> <argument name="name" value="$createAttributeSet.attribute_set_name$"/> </actionGroup> From 73e5ef0407e6878b3d71dc37d0c3470a68f345c1 Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Thu, 17 Sep 2020 11:43:19 +0300 Subject: [PATCH 124/132] MC-25079: [Functional Test Failed]:Magento\FunctionalTestingFramework.functional.ApplyCatalogPriceRuleByProductAttributeTest --- ...onditionWithSelectAttributeActionGroup.xml | 20 ++ ...CatalogPriceRuleByProductAttributeTest.xml | 198 ++++++++++++++++++ ...CatalogPriceRuleByProductAttributeTest.xml | 2 +- 3 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/AdminFillCatalogRuleConditionWithSelectAttributeActionGroup.xml create mode 100644 app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogPriceRuleByProductAttributeTest.xml diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/AdminFillCatalogRuleConditionWithSelectAttributeActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/AdminFillCatalogRuleConditionWithSelectAttributeActionGroup.xml new file mode 100644 index 0000000000000..147dd126ebdf5 --- /dev/null +++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/AdminFillCatalogRuleConditionWithSelectAttributeActionGroup.xml @@ -0,0 +1,20 @@ +<?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="AdminFillCatalogRuleConditionWithSelectAttributeActionGroup" extends="AdminFillCatalogRuleConditionActionGroup"> + <annotations> + <description>EXTENDS: AdminFillCatalogRuleConditionActionGroup. Clicks on the Conditions tab. Fills in the provided condition with attribute type select.</description> + </annotations> + <remove keyForRemoval="fillConditionValue"/> + <selectOption selector="{{AdminNewCatalogPriceRuleConditions.activeValueInput}}" userInput="{{conditionValue}}" after="waitForValueInput" stepKey="selectConditionValue"/> + <remove keyForRemoval="clickApply"/> + <remove keyForRemoval="waitForApplyButtonInvisibility"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogPriceRuleByProductAttributeTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogPriceRuleByProductAttributeTest.xml new file mode 100644 index 0000000000000..e51b4042851aa --- /dev/null +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogPriceRuleByProductAttributeTest.xml @@ -0,0 +1,198 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminApplyCatalogPriceRuleByProductAttributeTest"> + <annotations> + <features value="CatalogRule"/> + <stories value="Catalog price rule"/> + <title value="Admin should be able to apply the catalog price rule by product attribute"/> + <description value="Admin should be able to apply the catalog price rule by product attribute"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-25351"/> + <group value="catalog_rule"/> + </annotations> + <before> + <createData entity="productDropDownAttribute" stepKey="createDropdownAttribute"/> + <!--Create attribute options--> + <createData entity="ProductAttributeOption7" stepKey="createProductAttributeOptionGreen"> + <requiredEntity createDataKey="createDropdownAttribute"/> + </createData> + <createData entity="ProductAttributeOption8" stepKey="createProductAttributeOptionRed"> + <requiredEntity createDataKey="createDropdownAttribute"/> + </createData> + <!--Add attribute to default attribute set--> + <createData entity="AddToDefaultSet" stepKey="addAttributeToDefaultSet"> + <requiredEntity createDataKey="createDropdownAttribute"/> + </createData> + + <createData entity="ApiCategory" stepKey="createCategory"/> + <createData entity="ApiSimpleProduct" stepKey="createFirstProduct"> + <field key="price">40.00</field> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="ApiSimpleProduct" stepKey="createSecondProduct"> + <field key="price">40.00</field> + <requiredEntity createDataKey="createCategory"/> + </createData> + + <!-- 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="productAttributeWithTwoOptionsNotVisible" stepKey="createConfigProductAttribute"/> + <createData entity="productAttributeOption1" stepKey="createFirstConfigProductAttributeOption"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="createSecondConfigProductAttributeOption"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getFirstConfigAttributeOption"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getSecondConfigAttributeOption"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + + <!-- Create the 2 children that will be a part of the configurable product --> + <createData entity="ApiSimpleOne" stepKey="createConfigFirstChildProduct"> + <field key="price">60.00</field> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getFirstConfigAttributeOption"/> + </createData> + <createData entity="ApiSimpleTwo" stepKey="createConfigSecondChildProduct"> + <field key="price">60.00</field> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getSecondConfigAttributeOption"/> + </createData> + + <!-- Assign the two products to the configurable product --> + <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getFirstConfigAttributeOption"/> + <requiredEntity createDataKey="getSecondConfigAttributeOption"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createFirstConfigProductAddChild"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigFirstChildProduct"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createSecondConfigProductAddChild"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigSecondChildProduct"/> + </createData> + + <actionGroup ref="AdminLoginActionGroup" stepKey="loginToAdmin"/> + <!-- Update first simple product --> + <actionGroup ref="AdminProductPageOpenByIdActionGroup" stepKey="openFirstSimpleProductForEdit"> + <argument name="productId" value="$createFirstProduct.id$"/> + </actionGroup> + <selectOption selector="{{AdminProductFormSection.customSelectField($createDropdownAttribute.attribute[attribute_code]$)}}" + userInput="$createProductAttributeOptionGreen.option[store_labels][0][label]$" stepKey="setAttributeValueForFirstSimple"/> + <actionGroup ref="SaveProductFormActionGroup" stepKey="saveFirstSimpleProduct"/> + <!-- Update second simple product --> + <actionGroup ref="AdminProductPageOpenByIdActionGroup" stepKey="openSecondSimpleProductForEdit"> + <argument name="productId" value="$createSecondProduct.id$"/> + </actionGroup> + <selectOption selector="{{AdminProductFormSection.customSelectField($createDropdownAttribute.attribute[attribute_code]$)}}" + userInput="$createProductAttributeOptionRed.option[store_labels][0][label]$" stepKey="setAttributeValueForSecondSimple"/> + <actionGroup ref="SaveProductFormActionGroup" stepKey="saveSecondSimpleProduct"/> + <!-- Update first child of configurable product --> + <actionGroup ref="AdminProductPageOpenByIdActionGroup" stepKey="openFirstChildProductForEdit"> + <argument name="productId" value="$createConfigFirstChildProduct.id$"/> + </actionGroup> + <selectOption selector="{{AdminProductFormSection.customSelectField($createDropdownAttribute.attribute[attribute_code]$)}}" + userInput="$createProductAttributeOptionGreen.option[store_labels][0][label]$" stepKey="setAttributeValueForFirstChildProduct"/> + <actionGroup ref="SaveProductFormActionGroup" stepKey="saveFirstChildProduct"/> + <!-- Update second child of configurable product --> + <actionGroup ref="AdminProductPageOpenByIdActionGroup" stepKey="openSecondChildProductForEdit"> + <argument name="productId" value="$createConfigSecondChildProduct.id$"/> + </actionGroup> + <selectOption selector="{{AdminProductFormSection.customSelectField($createDropdownAttribute.attribute[attribute_code]$)}}" + userInput="$createProductAttributeOptionGreen.option[store_labels][0][label]$" stepKey="setAttributeValueForSecondChildProduct"/> + <actionGroup ref="SaveProductFormActionGroup" stepKey="saveSecondChildProduct"/> + <actionGroup ref="AdminCatalogPriceRuleDeleteAllActionGroup" stepKey="deleteAllCatalogPriceRule"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> + </before> + <after> + <!-- Delete created data --> + <deleteData createDataKey="createDropdownAttribute" stepKey="deleteDropdownAttribute"/> + <deleteData createDataKey="createFirstProduct" stepKey="deleteFirstProduct"/> + <deleteData createDataKey="createSecondProduct" stepKey="deleteSecondProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> + <deleteData createDataKey="createConfigFirstChildProduct" stepKey="deleteConfigFirstChildProduct"/> + <deleteData createDataKey="createConfigSecondChildProduct" stepKey="deleteConfigSecondChildProduct"/> + <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + <actionGroup ref="AdminCatalogPriceRuleDeleteAllActionGroup" stepKey="deleteAllCatalogPriceRule"/> + <actionGroup ref="ClearFiltersAdminDataGridActionGroup" stepKey="resetCatalogRulesGridFilter"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> + <!-- Reindex invalidated indices after product attribute has been created/deleted --> + <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> + </after> + <!-- Create Catalog Price Rule --> + <actionGroup ref="AdminOpenNewCatalogPriceRuleFormPageActionGroup" stepKey="startCreatingFirstPriceRule"/> + <actionGroup ref="AdminCatalogPriceRuleFillMainInfoActionGroup" stepKey="fillMainInfoForFirstPriceRule"> + <argument name="groups" value="'NOT LOGGED IN'"/> + </actionGroup> + <actionGroup ref="AdminFillCatalogRuleConditionWithSelectAttributeActionGroup" stepKey="createCatalogPriceRule"> + <argument name="condition" value="$createDropdownAttribute.default_frontend_label$"/> + <argument name="conditionValue" value="$createProductAttributeOptionGreen.option[store_labels][0][label]$"/> + </actionGroup> + <actionGroup ref="AdminCatalogPriceRuleFillActionsActionGroup" stepKey="fillActionsForCatalogPriceRule"> + <argument name="discountAmount" value="{{SimpleCatalogPriceRule.discount_amount}}"/> + </actionGroup> + <actionGroup ref="AdminCatalogPriceRuleSaveAndApplyActionGroup" stepKey="saveAndApplyCatalogPriceRule"/> + <!-- Run cron --> + <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex"> + <argument name="indices" value="catalogrule_rule"/> + </actionGroup> + <!-- Open first simple product page on storefront --> + <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="openFirstSimpleProductPage"> + <argument name="productUrlKey" value="$createFirstProduct.custom_attributes[url_key]$"/> + </actionGroup> + <!-- Verify price for simple product with attribute option green=$20 --> + <actionGroup ref="AssertStorefrontProductPricesActionGroup" stepKey="assertFirstSimpleProductPrices"> + <argument name="productPrice" value="$createFirstProduct.price$"/> + <argument name="productFinalPrice" value="$20.00"/> + </actionGroup> + + <!-- Open the configurable product page on storefront --> + <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="openConfigurableProductPage"> + <argument name="productUrlKey" value="$createConfigProduct.custom_attributes[url_key]$"/> + </actionGroup> + <!-- Verify price for configurable product with attribute option green=$30 --> + <selectOption selector="{{AdminCustomerActivitiesConfigureSection.addAttribute}}" userInput="option1" stepKey="selectFirstOptionOfConfigProduct"/> + <actionGroup ref="AssertStorefrontProductPricesActionGroup" stepKey="assertConfigProductWithFirstOptionPrices"> + <argument name="productPrice" value="$createConfigFirstChildProduct.price$"/> + <argument name="productFinalPrice" value="$30.00"/> + </actionGroup> + <!-- Verify price for configurable product with attribute option green=$54 --> + <selectOption selector="{{AdminCustomerActivitiesConfigureSection.addAttribute}}" userInput="option2" stepKey="selectSecondOptionOfConfigProduct"/> + <actionGroup ref="AssertStorefrontProductPricesActionGroup" stepKey="assertConfigProductWithSecondOptionPrices"> + <argument name="productPrice" value="$createConfigSecondChildProduct.price$"/> + <argument name="productFinalPrice" value="$30.00"/> + </actionGroup> + + <!-- Open the second simple product page on storefront --> + <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="openSecondSimpleProductPage"> + <argument name="productUrlKey" value="$createSecondProduct.custom_attributes[url_key]$"/> + </actionGroup> + <!-- Verify Price for second simple product with specialColor red=$40 --> + <actionGroup ref="AssertStorefrontProductPricesActionGroup" stepKey="assertSecondSimpleProductPrices"> + <argument name="productPrice" value="$createSecondProduct.price$"/> + <argument name="productFinalPrice" value="$createSecondProduct.price$"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml index 6817dd4dafc5f..09fa7c353a2cd 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml @@ -17,7 +17,7 @@ <testCaseId value="MC-148"/> <group value="CatalogRule"/> <skip> - <issueId value="MC-22577"/> + <issueId value="DEPRECATED">Use AdminApplyCatalogPriceRuleByProductAttributeTest instead.</issueId> </skip> </annotations> <before> From a066291619d510a3faeefbc59d59521b202212e3 Mon Sep 17 00:00:00 2001 From: SmVladyslav <vlatame.tsg@gmail.com> Date: Thu, 17 Sep 2020 14:03:03 +0300 Subject: [PATCH 125/132] MC-37594: Unexpected "Dashboard" page loading in the Admin panel --- .../templates/widget/tabshoriz.phtml | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Backend/view/adminhtml/templates/widget/tabshoriz.phtml b/app/code/Magento/Backend/view/adminhtml/templates/widget/tabshoriz.phtml index c51b357091bda..0e4634bf2016a 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/widget/tabshoriz.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/widget/tabshoriz.phtml @@ -4,45 +4,53 @@ * See COPYING.txt for license details. */ -/** @var \Magento\Framework\View\Helper\SecureHtmlRenderer $secureRenderer */ +use Magento\Framework\Escaper; +use Magento\Framework\View\Helper\SecureHtmlRenderer; + +/** @var SecureHtmlRenderer $secureRenderer */ +/** @var Escaper $escaper */ +$blockId = $block->getId(); ?> <!-- <?php if ($block->getTitle()): ?> - <h3><?= $block->escapeHtml($block->getTitle()) ?></h3> + <h3><?= $escaper->escapeHtml($block->getTitle()) ?></h3> <?php endif ?> --> <?php if (!empty($tabs)): ?> -<div id="<?= $block->escapeHtmlAttr($block->getId()) ?>"> +<div id="<?= $escaper->escapeHtmlAttr($blockId) ?>" class="hidden"> <ul class="tabs-horiz"> <?php foreach ($tabs as $_tab): ?> + <?php $tabId = $block->getTabId($_tab) ?> <?php $_tabClass = 'tab-item-link ' . $block->getTabClass($_tab) . ' ' . (preg_match('/\s?ajax\s?/', $_tab->getClass()) ? 'notloaded' : '') ?> <?php $_tabType = (!preg_match('/\s?ajax\s?/', $_tabClass) && $block->getTabUrl($_tab) != '#') ? 'link' : '' ?> <?php $_tabHref = $block->getTabUrl($_tab) == '#' ? - '#' . $block->getTabId($_tab) . '_content' : + '#' . $tabId . '_content' : $block->getTabUrl($_tab) ?> <li> - <a href="<?= $block->escapeUrl($_tabHref) ?>" - id="<?= $block->escapeHtmlAttr($block->getTabId($_tab)) ?>" - title="<?= $block->escapeHtmlAttr($block->getTabTitle($_tab)) ?>" - class="<?= $block->escapeHtmlAttr($_tabClass) ?>" - data-tab-type="<?= $block->escapeHtmlAttr($_tabType) ?>"> + <a href="<?= $escaper->escapeUrl($_tabHref) ?>" + id="<?= $escaper->escapeHtmlAttr($tabId) ?>" + title="<?= $escaper->escapeHtmlAttr($block->getTabTitle($_tab)) ?>" + class="<?= $escaper->escapeHtmlAttr($_tabClass) ?>" + data-tab-type="<?= $escaper->escapeHtmlAttr($_tabType) ?>"> <span> <span class="changed" - title="<?= $block->escapeHtmlAttr(__('The information in this tab has been changed.')) ?>"></span> + title="<?= $escaper->escapeHtmlAttr(__( + 'The information in this tab has been changed.' + )) ?>"></span> <span class="error" - title="<?= $block->escapeHtmlAttr(__( + title="<?= $escaper->escapeHtmlAttr(__( 'This tab contains invalid data. Please resolve this before saving.' )) ?>"></span> <span class="loader" - title="<?= $block->escapeHtmlAttr(__('Loading...')) ?>"></span> - <?= $block->escapeHtml($block->getTabLabel($_tab)) ?> + title="<?= $escaper->escapeHtmlAttr(__('Loading...')) ?>"></span> + <?= $escaper->escapeHtml($block->getTabLabel($_tab)) ?> </span> </a> - <div id="<?= $block->escapeHtmlAttr($block->getTabId($_tab)) ?>_content"> + <div id="<?= $escaper->escapeHtmlAttr($tabId) ?>_content"> <?= /* @noEscape */ $block->getTabContent($_tab) ?> </div> <?= /* @noEscape */ $secureRenderer->renderStyleAsTag( 'display:none', - '#' . $block->escapeJs($block->getTabId($_tab)) . '_content' + '#' . $escaper->escapeJs($tabId) . '_content' ); ?> </li> <?php endforeach; ?> @@ -51,11 +59,12 @@ <?php $scriptString = <<<script require(["jquery","mage/backend/tabs"], function($){ $(function() { - $('#{$block->getId()}').tabs({ - active: '{$block->getActiveTabId()}', - destination: '#{$block->getDestElementId()}', + $('#{$escaper->escapeJs($blockId)}').tabs({ + active: '{$escaper->escapeJs($block->getActiveTabId())}', + destination: '#{$escaper->escapeJs($block->getDestElementId())}', shadowTabs: {$block->getAllShadowTabs()} }); + $('#{$escaper->escapeJs($blockId)}').removeClass('hidden'); }); }); script; From 79adffe5e315747fde870cfdfb3a5131f1faf5bd Mon Sep 17 00:00:00 2001 From: Yurii Sapiha <yurasapiga93@gmail.com> Date: Thu, 17 Sep 2020 15:29:07 +0300 Subject: [PATCH 126/132] MC-25079: [Functional Test Failed]:Magento\FunctionalTestingFramework.functional.ApplyCatalogPriceRuleByProductAttributeTest --- ...FillCatalogRuleConditionWithSelectAttributeActionGroup.xml | 3 +-- .../Test/AdminApplyCatalogPriceRuleByProductAttributeTest.xml | 4 ++-- .../Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/AdminFillCatalogRuleConditionWithSelectAttributeActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/AdminFillCatalogRuleConditionWithSelectAttributeActionGroup.xml index 147dd126ebdf5..08e3e58632101 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/AdminFillCatalogRuleConditionWithSelectAttributeActionGroup.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/AdminFillCatalogRuleConditionWithSelectAttributeActionGroup.xml @@ -12,8 +12,7 @@ <annotations> <description>EXTENDS: AdminFillCatalogRuleConditionActionGroup. Clicks on the Conditions tab. Fills in the provided condition with attribute type select.</description> </annotations> - <remove keyForRemoval="fillConditionValue"/> - <selectOption selector="{{AdminNewCatalogPriceRuleConditions.activeValueInput}}" userInput="{{conditionValue}}" after="waitForValueInput" stepKey="selectConditionValue"/> + <selectOption selector="{{AdminNewCatalogPriceRuleConditions.activeValueInput}}" userInput="{{conditionValue}}" stepKey="fillConditionValue"/> <remove keyForRemoval="clickApply"/> <remove keyForRemoval="waitForApplyButtonInvisibility"/> </actionGroup> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogPriceRuleByProductAttributeTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogPriceRuleByProductAttributeTest.xml index e51b4042851aa..547ef356f099d 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogPriceRuleByProductAttributeTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogPriceRuleByProductAttributeTest.xml @@ -16,7 +16,7 @@ <description value="Admin should be able to apply the catalog price rule by product attribute"/> <severity value="CRITICAL"/> <testCaseId value="MC-25351"/> - <group value="catalog_rule"/> + <group value="catalogRule"/> </annotations> <before> <createData entity="productDropDownAttribute" stepKey="createDropdownAttribute"/> @@ -178,7 +178,7 @@ <argument name="productPrice" value="$createConfigFirstChildProduct.price$"/> <argument name="productFinalPrice" value="$30.00"/> </actionGroup> - <!-- Verify price for configurable product with attribute option green=$54 --> + <!-- Verify price for configurable product with attribute option green=$30 --> <selectOption selector="{{AdminCustomerActivitiesConfigureSection.addAttribute}}" userInput="option2" stepKey="selectSecondOptionOfConfigProduct"/> <actionGroup ref="AssertStorefrontProductPricesActionGroup" stepKey="assertConfigProductWithSecondOptionPrices"> <argument name="productPrice" value="$createConfigSecondChildProduct.price$"/> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml index 09fa7c353a2cd..6de7bba59c340 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml @@ -8,10 +8,10 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="ApplyCatalogPriceRuleByProductAttributeTest"> + <test name="ApplyCatalogPriceRuleByProductAttributeTest" deprecated="Use AdminApplyCatalogPriceRuleByProductAttributeTest"> <annotations> <stories value="Catalog price rule"/> - <title value="Admin should be able to apply the catalog price rule by product attribute"/> + <title value="DEPRECATED. Admin should be able to apply the catalog price rule by product attribute"/> <description value="Admin should be able to apply the catalog price rule by product attribute"/> <severity value="CRITICAL"/> <testCaseId value="MC-148"/> From 1d3760dd638835154174eb01431f0f2b0d27ce37 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Thu, 17 Sep 2020 15:58:09 +0300 Subject: [PATCH 127/132] MC-37714: [MFTF] AddSimpleProductToOrderFromShoppingCartTest fails because of bad design --- .../Test/AddSimpleProductToOrderFromShoppingCartTest.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AddSimpleProductToOrderFromShoppingCartTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AddSimpleProductToOrderFromShoppingCartTest.xml index 701b7ebe4a958..24e6c5eddf7db 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AddSimpleProductToOrderFromShoppingCartTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AddSimpleProductToOrderFromShoppingCartTest.xml @@ -19,23 +19,22 @@ <group value="sales"/> <group value="mtf_migrated"/> </annotations> + <before> <!-- Create customer --> <createData entity="Simple_US_Customer" stepKey="createCustomer"/> - <!-- Create product --> <createData entity="SimpleProduct2" stepKey="createProduct"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> </before> + <after> <!-- Admin log out --> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> - <!-- Customer log out --> <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="customerLogout"/> - <!-- Delete customer --> <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> - <!-- Delete product --> <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> </after> From 2fec0980de53c2d2c7cc0e07caa27d20c3e2919e Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Thu, 17 Sep 2020 16:15:13 +0300 Subject: [PATCH 128/132] MC-23649: Flaky MFTF Test: MC-11016: Delete Bundle Dynamic Product --- .../Test/AdminDeleteBundleDynamicPriceProductTest.xml | 10 ++++------ .../Mftf/Test/AdminDeleteBundleDynamicProductTest.xml | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml index 5e1eadf8be286..994dd116564c7 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml @@ -36,9 +36,8 @@ <requiredEntity createDataKey="createSimpleProduct"/> </createData> - <magentoCron groups="index" stepKey="runCronIndex"/> - <actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache"> - <argument name="tags" value=""/> + <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindexInvalidatedIndices"> + <argument name="indices" value="cataloginventory_stock"/> </actionGroup> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> </before> @@ -48,8 +47,8 @@ <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> - <actionGroup ref="DeleteProductUsingProductGridActionGroup" stepKey="deleteBundleProductFilteredBySkuAndName"> - <argument name="product" value="$createDynamicBundleProduct$"/> + <actionGroup ref="DeleteProductBySkuActionGroup" stepKey="deleteBundleProductBySku"> + <argument name="sku" value="$createDynamicBundleProduct.sku$"/> </actionGroup> <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="A total of 1 record(s) have been deleted." stepKey="deleteMessage"/> <!-- Verify product on Product Page --> @@ -61,7 +60,6 @@ </actionGroup> <!-- Should not see bundle product --> <dontSee userInput="$createDynamicBundleProduct.sku$" selector="{{StorefrontCatalogSearchMainSection.searchResults}}" stepKey="dontSeeProduct"/> - <comment userInput="redundant action" stepKey="seeCantFindProductMessage"/> <amOnPage url="{{StorefrontCategoryPage.url($createCategory.custom_attributes[url_key]$)}}" stepKey="openCategoryPage"/> <!-- Should not see any products in category --> <dontSee userInput="$createDynamicBundleProduct.name$" selector="{{StorefrontCategoryMainSection.productsList}}" stepKey="dontSeeProductInCategory"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicProductTest.xml index ed0c811b88a10..7973860e4d5c5 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicProductTest.xml @@ -7,7 +7,7 @@ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminDeleteBundleDynamicProductTest"> + <test name="AdminDeleteBundleDynamicProductTest" deprecated="Use AdminDeleteBundleDynamicPriceProductTest instead"> <annotations> <features value="Bundle"/> <stories value="Delete products"/> From 575123c6c62cc4244ccf010f28c7e35922118691 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Thu, 17 Sep 2020 16:31:28 +0300 Subject: [PATCH 129/132] MC-23649: Flaky MFTF Test: MC-11016: Delete Bundle Dynamic Product --- .../Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml index 994dd116564c7..a902e5c9d103d 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml @@ -35,7 +35,7 @@ <requiredEntity createDataKey="bundleOption"/> <requiredEntity createDataKey="createSimpleProduct"/> </createData> - + <!-- TODO: Remove this action when MC-37719 will be fixed --> <actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindexInvalidatedIndices"> <argument name="indices" value="cataloginventory_stock"/> </actionGroup> From 1324176bbeab4328b752ed683b6e5e70546d69f7 Mon Sep 17 00:00:00 2001 From: SmVladyslav <vlatame.tsg@gmail.com> Date: Thu, 17 Sep 2020 17:53:46 +0300 Subject: [PATCH 130/132] MC-37377: Incorrect count of selected records in customer address grid --- .../view/adminhtml/web/js/form/components/insert-listing.js | 6 +++++- .../js/view/form/components/insert-listing.test.js | 6 ++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Customer/view/adminhtml/web/js/form/components/insert-listing.js b/app/code/Magento/Customer/view/adminhtml/web/js/form/components/insert-listing.js index aa8c199e4f261..1578677414b78 100644 --- a/app/code/Magento/Customer/view/adminhtml/web/js/form/components/insert-listing.js +++ b/app/code/Magento/Customer/view/adminhtml/web/js/form/components/insert-listing.js @@ -72,7 +72,7 @@ define([ }, /** - * Delete customer address by ids + * Delete customer address and selections by provided ids. * * @param {Array} ids */ @@ -87,6 +87,10 @@ define([ if (ids.indexOf(defaultBillingId) !== -1) { this.source.set('data.default_billing_address', []); } + + _.each(ids, function (id) { + this.selections().deselect(id.toString(), false); + }, this); } }); }); diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Customer/adminhtml/js/view/form/components/insert-listing.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Customer/adminhtml/js/view/form/components/insert-listing.test.js index 63ce265ac9001..e07b1fbc69453 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Customer/adminhtml/js/view/form/components/insert-listing.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Customer/adminhtml/js/view/form/components/insert-listing.test.js @@ -18,7 +18,8 @@ define(['Magento_Customer/js/form/components/insert-listing'], function (Constr) } }, selectionsProvider = { - selected: jasmine.createSpy().and.returnValue(ids) + selected: jasmine.createSpy().and.returnValue(ids), + deselect: jasmine.createSpy() }; beforeEach(function () { @@ -54,7 +55,7 @@ define(['Magento_Customer/js/form/components/insert-listing'], function (Constr) expect(obj._delete).toHaveBeenCalledWith([1, 2]); }); - it('Check removal of default addresses', function () { + it('Check removal of default addresses and selections by provided ids', function () { obj.source = { get: jasmine.createSpy().and.returnValues(2, 3), set: jasmine.createSpy() @@ -64,6 +65,7 @@ define(['Magento_Customer/js/form/components/insert-listing'], function (Constr) expect(selectionsProvider.selected).not.toHaveBeenCalled(); expect(obj.source.get.calls.count()).toEqual(2); expect(obj.source.set.calls.count()).toEqual(1); + expect(selectionsProvider.deselect.calls.count()).toEqual(2); }); }); }); From 74ed9f98a7d89de92b7de98cdaddf456dfe0bd45 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Fri, 18 Sep 2020 10:48:36 +0300 Subject: [PATCH 131/132] MC-23649: Flaky MFTF Test: MC-11016: Delete Bundle Dynamic Product --- .../Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml index a902e5c9d103d..8b50fffec091f 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicPriceProductTest.xml @@ -50,7 +50,6 @@ <actionGroup ref="DeleteProductBySkuActionGroup" stepKey="deleteBundleProductBySku"> <argument name="sku" value="$createDynamicBundleProduct.sku$"/> </actionGroup> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="A total of 1 record(s) have been deleted." stepKey="deleteMessage"/> <!-- Verify product on Product Page --> <amOnPage url="{{StorefrontProductPage.url($createDynamicBundleProduct.custom_attributes[url_key]$)}}" stepKey="openBundleProductPage"/> <see selector="{{StorefrontProductInfoMainSection.productName}}" userInput="Whoops, our bad..." stepKey="seeWhoopsMessage"/> From d002fde7e6679f7a087bba2e9a977a97ba1c826a Mon Sep 17 00:00:00 2001 From: SmVladyslav <vlatame.tsg@gmail.com> Date: Fri, 18 Sep 2020 12:49:26 +0300 Subject: [PATCH 132/132] MC-37594: Unexpected "Dashboard" page loading in the Admin panel --- .../view/adminhtml/templates/widget/tabshoriz.phtml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Backend/view/adminhtml/templates/widget/tabshoriz.phtml b/app/code/Magento/Backend/view/adminhtml/templates/widget/tabshoriz.phtml index 0e4634bf2016a..9a3c941fdc9ed 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/widget/tabshoriz.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/widget/tabshoriz.phtml @@ -7,15 +7,14 @@ use Magento\Framework\Escaper; use Magento\Framework\View\Helper\SecureHtmlRenderer; -/** @var SecureHtmlRenderer $secureRenderer */ -/** @var Escaper $escaper */ -$blockId = $block->getId(); +/** + * @var SecureHtmlRenderer $secureRenderer + * @var Escaper $escaper + */ ?> -<!-- <?php if ($block->getTitle()): ?> - <h3><?= $escaper->escapeHtml($block->getTitle()) ?></h3> -<?php endif ?> --> <?php if (!empty($tabs)): ?> -<div id="<?= $escaper->escapeHtmlAttr($blockId) ?>" class="hidden"> + <?php $blockId = $block->getId() ?> +<div id="<?= $escaper->escapeHtmlAttr($blockId) ?>" class="hidden"> <ul class="tabs-horiz"> <?php foreach ($tabs as $_tab): ?> <?php $tabId = $block->getTabId($_tab) ?>