diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Noroute/Index.php b/app/code/Magento/Backend/Controller/Adminhtml/Noroute/Index.php
index 64038d17f14c64cee9a0cd01ef3bf2cfdccc05da..87153c381c1f7d053a40d67ec784f62d02375084 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Noroute/Index.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Noroute/Index.php
@@ -41,7 +41,7 @@ class Index extends \Magento\Backend\App\Action
     {
         /** @var \Magento\Backend\Model\View\Result\Page $resultPage */
         $resultPage = $this->resultPageFactory->create();
-        $resultPage->setStatusHeader(404, '1.1', 'Forbidden');
+        $resultPage->setStatusHeader(404, '1.1', 'Not Found');
         $resultPage->setHeader('Status', '404 File not found');
         $resultPage->addHandle('adminhtml_noroute');
         return $resultPage;
diff --git a/app/code/Magento/Backend/etc/adminhtml/di.xml b/app/code/Magento/Backend/etc/adminhtml/di.xml
index 5154c4eb56c915546545675ad6562d8684daf136..97a39139411c0bd4b48dc3e5285170f73e40e322 100644
--- a/app/code/Magento/Backend/etc/adminhtml/di.xml
+++ b/app/code/Magento/Backend/etc/adminhtml/di.xml
@@ -147,4 +147,9 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\View\Layout\Generator\Block">
+        <arguments>
+            <argument name="defaultClass" xsi:type="string">Magento\Backend\Block\Template</argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/Bundle/Model/OptionRepository.php b/app/code/Magento/Bundle/Model/OptionRepository.php
index 43e46ef7f1c893fd931c6af3f43cf0dc9a1caf41..9940344b5b61cc6bdfb2bbeac88edd2977bd91c0 100644
--- a/app/code/Magento/Bundle/Model/OptionRepository.php
+++ b/app/code/Magento/Bundle/Model/OptionRepository.php
@@ -208,7 +208,7 @@ class OptionRepository implements \Magento\Bundle\Api\ProductOptionRepositoryInt
             }
         } else {
             if (!$existingOption->getOptionId()) {
-                throw new NoSuchEntityException('Requested option doesn\'t exist');
+                throw new NoSuchEntityException(__('Requested option doesn\'t exist'));
             }
 
             $option->setData(array_merge($existingOption->getData(), $option->getData()));
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js
index 82033590b1135033f378b36f1649c6d8f6b4d27c..79050ca087740f26ce907fce33d8b7e775e36b55 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js
@@ -206,7 +206,7 @@ define([
                     regionInput.removeClass('required-entry');
                 }
 
-                regionList.removeClass('required-entry').hide();
+                regionList.removeClass('required-entry').prop('disabled', 'disabled').hide();
                 regionInput.show();
                 label.attr('for', regionInput.attr('id'));
             }
diff --git a/app/code/Magento/Review/Block/Product/ReviewRenderer.php b/app/code/Magento/Review/Block/Product/ReviewRenderer.php
index f60b33bffb8cb5a57cfbc36b7ae509c31cdcbda7..8aa10d2437cbbf21b157b4ac3b2ec68303c982f5 100644
--- a/app/code/Magento/Review/Block/Product/ReviewRenderer.php
+++ b/app/code/Magento/Review/Block/Product/ReviewRenderer.php
@@ -57,6 +57,10 @@ class ReviewRenderer extends \Magento\Framework\View\Element\Template implements
         $templateType = self::DEFAULT_VIEW,
         $displayIfNoReviews = false
     ) {
+        if (!$product->getRatingSummary()) {
+            $this->_reviewFactory->create()->getEntitySummary($product, $this->_storeManager->getStore()->getId());
+        }
+
         if (!$product->getRatingSummary() && !$displayIfNoReviews) {
             return '';
         }
@@ -68,9 +72,6 @@ class ReviewRenderer extends \Magento\Framework\View\Element\Template implements
 
         $this->setDisplayIfEmpty($displayIfNoReviews);
 
-        if (!$product->getRatingSummary()) {
-            $this->_reviewFactory->create()->getEntitySummary($product, $this->_storeManager->getStore()->getId());
-        }
         $this->setProduct($product);
 
         return $this->toHtml();
diff --git a/app/code/Magento/Search/view/frontend/web/form-mini.js b/app/code/Magento/Search/view/frontend/web/form-mini.js
index 7b2c7003074cbd176770c6258a6d23d5eba91a10..e8598f46eb5be7a1b70f8637623eddf46eb9578f 100644
--- a/app/code/Magento/Search/view/frontend/web/form-mini.js
+++ b/app/code/Magento/Search/view/frontend/web/form-mini.js
@@ -286,46 +286,50 @@ define([
                 $.getJSON(this.options.url, {
                     q: value
                 }, $.proxy(function (data) {
-                    $.each(data, function (index, element) {
-                        var html;
-
-                        element.index = index;
-                        html = template({
-                            data: element
+                    if (data.length) {
+                        $.each(data, function (index, element) {
+                            var html;
+
+                            element.index = index;
+                            html = template({
+                                data: element
+                            });
+                            dropdown.append(html);
                         });
-                        dropdown.append(html);
-                    });
-                    this.responseList.indexList = this.autoComplete.html(dropdown)
-                        .css(clonePosition)
-                        .show()
-                        .find(this.options.responseFieldElements + ':visible');
-
-                    this._resetResponseList(false);
-                    this.element.removeAttr('aria-activedescendant');
-
-                    if (this.responseList.indexList.length) {
-                        this._updateAriaHasPopup(true);
-                    } else {
-                        this._updateAriaHasPopup(false);
-                    }
 
-                    this.responseList.indexList
-                        .on('click', function (e) {
-                            this.responseList.selected = $(e.currentTarget);
-                            this.searchForm.trigger('submit');
-                        }.bind(this))
-                        .on('mouseenter mouseleave', function (e) {
-                            this.responseList.indexList.removeClass(this.options.selectClass);
-                            $(e.target).addClass(this.options.selectClass);
-                            this.responseList.selected = $(e.target);
-                            this.element.attr('aria-activedescendant', $(e.target).attr('id'));
-                        }.bind(this))
-                        .on('mouseout', function (e) {
-                            if (!this._getLastElement() && this._getLastElement().hasClass(this.options.selectClass)) {
-                                $(e.target).removeClass(this.options.selectClass);
-                                this._resetResponseList(false);
-                            }
-                        }.bind(this));
+                        this.responseList.indexList = this.autoComplete.html(dropdown)
+                            .css(clonePosition)
+                            .show()
+                            .find(this.options.responseFieldElements + ':visible');
+
+                        this._resetResponseList(false);
+                        this.element.removeAttr('aria-activedescendant');
+
+                        if (this.responseList.indexList.length) {
+                            this._updateAriaHasPopup(true);
+                        } else {
+                            this._updateAriaHasPopup(false);
+                        }
+
+                        this.responseList.indexList
+                            .on('click', function (e) {
+                                this.responseList.selected = $(e.currentTarget);
+                                this.searchForm.trigger('submit');
+                            }.bind(this))
+                            .on('mouseenter mouseleave', function (e) {
+                                this.responseList.indexList.removeClass(this.options.selectClass);
+                                $(e.target).addClass(this.options.selectClass);
+                                this.responseList.selected = $(e.target);
+                                this.element.attr('aria-activedescendant', $(e.target).attr('id'));
+                            }.bind(this))
+                            .on('mouseout', function (e) {
+                                if (!this._getLastElement() &&
+                                    this._getLastElement().hasClass(this.options.selectClass)) {
+                                    $(e.target).removeClass(this.options.selectClass);
+                                    this._resetResponseList(false);
+                                }
+                            }.bind(this));
+                    }
                 }, this));
             } else {
                 this._resetResponseList(true);
diff --git a/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php b/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php
index 7a1bbf986de6149068f8d1cdf9c92f0b3d3c2bc9..a0c687bde1b478334e7cee68c378528fc62499bf 100644
--- a/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php
+++ b/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php
@@ -7,13 +7,56 @@ namespace Magento\Ui\Controller\Adminhtml\Index;
 
 use Magento\Ui\Controller\Adminhtml\AbstractAction;
 use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Backend\App\Action\Context;
+use Magento\Framework\View\Element\UiComponentFactory;
+use Psr\Log\LoggerInterface;
+use Magento\Framework\Escaper;
+use Magento\Framework\Controller\Result\JsonFactory;
 
 class Render extends AbstractAction
 {
+    /**
+     * @var JsonFactory
+     */
+    private $resultJsonFactory;
+
+    /**
+     * @var Escaper
+     */
+    private $escaper;
+
+    /**
+     * @var LoggerInterface
+     */
+    private $logger;
+
+    /**
+     * @param Context $context
+     * @param UiComponentFactory $factory
+     * @param JsonFactory|null $resultJsonFactory
+     * @param Escaper|null $escaper
+     * @param LoggerInterface|null $logger
+     */
+    public function __construct(
+        Context $context,
+        UiComponentFactory $factory,
+        JsonFactory $resultJsonFactory = null,
+        Escaper $escaper = null,
+        LoggerInterface $logger = null
+    ) {
+        parent::__construct($context, $factory);
+        $this->resultJsonFactory = $resultJsonFactory ?: \Magento\Framework\App\ObjectManager::getInstance()
+            ->get(\Magento\Framework\Controller\Result\JsonFactory::class);
+        $this->escaper = $escaper ?: \Magento\Framework\App\ObjectManager::getInstance()
+            ->get(\Magento\Framework\Escaper::class);
+        $this->logger = $logger ?: \Magento\Framework\App\ObjectManager::getInstance()
+            ->get(\Psr\Log\LoggerInterface::class);
+    }
+
     /**
      * Action for AJAX request
      *
-     * @return void
+     * @return void|\Magento\Framework\Controller\ResultInterface
      */
     public function execute()
     {
@@ -22,10 +65,40 @@ class Render extends AbstractAction
             return;
         }
 
-        $component = $this->factory->create($this->_request->getParam('namespace'));
-        if ($this->validateAclResource($component->getContext()->getDataProvider()->getConfigData())) {
-            $this->prepareComponent($component);
-            $this->_response->appendBody((string) $component->render());
+        try {
+            $component = $this->factory->create($this->_request->getParam('namespace'));
+            if ($this->validateAclResource($component->getContext()->getDataProvider()->getConfigData())) {
+                $this->prepareComponent($component);
+                $this->_response->appendBody((string) $component->render());
+            }
+        } catch (\Magento\Framework\Exception\LocalizedException $e) {
+            $this->logger->critical($e);
+            $result = [
+                'error' => $this->escaper->escapeHtml($e->getMessage()),
+                'errorcode' => $this->escaper->escapeHtml($e->getCode())
+            ];
+            /** @var \Magento\Framework\Controller\Result\Json $resultJson */
+            $resultJson = $this->resultJsonFactory->create();
+            $resultJson->setStatusHeader(
+                \Zend\Http\Response::STATUS_CODE_400,
+                \Zend\Http\AbstractMessage::VERSION_11,
+                'Bad Request'
+            );
+            return $resultJson->setData($result);
+        } catch (\Exception $e) {
+            $this->logger->critical($e);
+            $result = [
+                'error' => _('UI component could not be rendered because of system exception'),
+                'errorcode' => $this->escaper->escapeHtml($e->getCode())
+            ];
+            /** @var \Magento\Framework\Controller\Result\Json $resultJson */
+            $resultJson = $this->resultJsonFactory->create();
+            $resultJson->setStatusHeader(
+                \Zend\Http\Response::STATUS_CODE_400,
+                \Zend\Http\AbstractMessage::VERSION_11,
+                'Bad Request'
+            );
+            return $resultJson->setData($result);
         }
     }
 
diff --git a/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/RenderTest.php b/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/RenderTest.php
index 5ab08a8a64a199231246c59252dca72cf9b57186..7d5de26be6d2ef856ecd922aadf7e2c4fe9ee1f5 100644
--- a/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/RenderTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/RenderTest.php
@@ -5,7 +5,8 @@
  */
 namespace Magento\Ui\Test\Unit\Controller\Adminhtml\Index;
 
-use \Magento\Ui\Controller\Adminhtml\Index\Render;
+use Magento\Ui\Controller\Adminhtml\Index\Render;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -17,6 +18,11 @@ class RenderTest extends \PHPUnit\Framework\TestCase
      */
     private $render;
 
+    /**
+     * @var ObjectManagerHelper
+     */
+    private $objectManagerHelper;
+
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
@@ -73,6 +79,16 @@ class RenderTest extends \PHPUnit\Framework\TestCase
      */
     private $uiComponentMock;
 
+    /**
+     * @var \Magento\Framework\Controller\Result\JsonFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $resultJsonFactoryMock;
+
+    /**
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $loggerMock;
+
     protected function setUp()
     {
         $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class)
@@ -114,6 +130,14 @@ class RenderTest extends \PHPUnit\Framework\TestCase
             ['render']
         );
 
+        $this->resultJsonFactoryMock = $this->getMockBuilder(
+            \Magento\Framework\Controller\Result\JsonFactory::class
+        )
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->loggerMock = $this->getMockForAbstractClass(\Psr\Log\LoggerInterface::class);
+
         $this->contextMock->expects($this->any())
             ->method('getRequest')
             ->willReturn($this->requestMock);
@@ -136,7 +160,70 @@ class RenderTest extends \PHPUnit\Framework\TestCase
             ->method('getDataProvider')
             ->willReturn($this->dataProviderMock);
 
-        $this->render = new Render($this->contextMock, $this->uiFactoryMock);
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+
+        $this->render = $this->objectManagerHelper->getObject(
+            \Magento\Ui\Controller\Adminhtml\Index\Render::class,
+            [
+                'context' => $this->contextMock,
+                'factory' => $this->uiFactoryMock,
+                'resultJsonFactory' => $this->resultJsonFactoryMock,
+                'logger' => $this->loggerMock
+            ]
+        );
+    }
+
+    public function testExecuteAjaxRequestException()
+    {
+        $name = 'test-name';
+        $renderedData = '<html>data</html>';
+
+        $this->requestMock->expects($this->any())
+            ->method('getParam')
+            ->with('namespace')
+            ->willReturn($name);
+        $this->requestMock->expects($this->any())
+            ->method('getParams')
+            ->willReturn([]);
+        $this->responseMock->expects($this->once())
+            ->method('appendBody')
+            ->willThrowException(new \Exception('exception'));
+
+        $jsonResultMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Json::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['setData'])
+            ->getMock();
+
+        $this->resultJsonFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($jsonResultMock);
+
+        $jsonResultMock->expects($this->once())
+            ->method('setData')
+            ->willReturnSelf();
+
+        $this->loggerMock->expects($this->once())
+            ->method('critical')
+            ->willReturnSelf();
+
+        $this->dataProviderMock->expects($this->once())
+            ->method('getConfigData')
+            ->willReturn([]);
+
+        $this->uiComponentMock->expects($this->once())
+            ->method('render')
+            ->willReturn($renderedData);
+        $this->uiComponentMock->expects($this->once())
+            ->method('getChildComponents')
+            ->willReturn([]);
+        $this->uiComponentMock->expects($this->once())
+            ->method('getContext')
+            ->willReturn($this->uiComponentContextMock);
+        $this->uiFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($this->uiComponentMock);
+
+        $this->render->executeAjaxRequest();
     }
 
     public function testExecuteAjaxRequest()
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js
index 22ba19657168d753355eab375f8e85f3b1e7825a..ecc4ec1902d87a7c334e218fdf629707b9747a8d 100644
--- a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js
+++ b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js
@@ -10,8 +10,10 @@ define([
     'underscore',
     'mageUtils',
     'uiLayout',
-    'uiCollection'
-], function (_, utils, layout, Collection) {
+    'uiCollection',
+    'mage/translate',
+    'jquery'
+], function (_, utils, layout, Collection, $t, $) {
     'use strict';
 
     /**
@@ -48,6 +50,7 @@ define([
             stickyTmpl: 'ui/grid/sticky/filters',
             _processed: [],
             columnsProvider: 'ns = ${ $.ns }, componentType = columns',
+            bookmarksProvider: 'ns = ${ $.ns }, componentType = bookmark',
             applied: {
                 placeholder: true
             },
@@ -102,7 +105,9 @@ define([
                 applied: '${ $.provider }:params.filters'
             },
             imports: {
-                'onColumnsUpdate': '${ $.columnsProvider }:elems'
+                onColumnsUpdate: '${ $.columnsProvider }:elems',
+                onBackendError: '${ $.provider }:lastError',
+                bookmarksActiveIndex: '${ $.bookmarksProvider }:activeIndex'
             },
             modules: {
                 columns: '${ $.columnsProvider }',
@@ -371,6 +376,37 @@ define([
          */
         onColumnsUpdate: function (columns) {
             columns.forEach(this.addFilter, this);
+        },
+
+        /**
+         * Provider ajax error listener.
+         *
+         * @param {bool} isError - Selected index of the filter.
+         */
+        onBackendError: function (isError) {
+            var defaultMessage = 'Something went wrong with processing the default view and we have restored the ' +
+                    'filter to its original state.',
+                customMessage  = 'Something went wrong with processing current custom view and filters have been ' +
+                    'reset to its original state. Please edit filters then click apply.';
+
+            if (isError) {
+                this.clear();
+
+                $('body').notification('clear')
+                    .notification('add', {
+                        error: true,
+                        message: $.mage.__(this.bookmarksActiveIndex !== 'default' ? customMessage : defaultMessage),
+
+                        /**
+                         * @param {String} message
+                         */
+                        insertMethod: function (message) {
+                            var $wrapper = $('<div/>').html(message);
+
+                            $('.page-main-actions').after($wrapper);
+                        }
+                    });
+            }
         }
     });
 });
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/provider.js b/app/code/Magento/Ui/view/base/web/js/grid/provider.js
index 14a64216ef597988575f72330be0f382562b206a..25bf25e6f65c02477bf9ba38a3bf4db9cc40d966 100644
--- a/app/code/Magento/Ui/view/base/web/js/grid/provider.js
+++ b/app/code/Magento/Ui/view/base/web/js/grid/provider.js
@@ -21,6 +21,7 @@ define([
     return Element.extend({
         defaults: {
             firstLoad: true,
+            lastError: false,
             storageConfig: {
                 component: 'Magento_Ui/js/grid/data-storage',
                 provider: '${ $.storageConfig.name }',
@@ -120,7 +121,7 @@ define([
 
             request
                 .done(this.onReload)
-                .fail(this.onError);
+                .fail(this.onError.bind(this));
 
             return request;
         },
@@ -144,6 +145,10 @@ define([
                 return;
             }
 
+            this.set('lastError', true);
+
+            this.firstLoad = false;
+
             alert({
                 content: $t('Something went wrong.')
             });
@@ -157,6 +162,8 @@ define([
         onReload: function (data) {
             this.firstLoad = false;
 
+            this.set('lastError', false);
+
             this.setData(data)
                 .trigger('reloaded');
         },
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js
index e673431cd43ab3b21f47bba707f2a34261673898..76b00f56e780c52ef0640a2556c19dc1aad413f9 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js
@@ -244,7 +244,7 @@ define([
         ],
         'stripped-min-length': [
             function (value, param) {
-                return value.length >= param;
+                return _.isUndefined(value) || value.length === 0 || utils.stripHtml(value).length >= param;
             },
             $.mage.__('Please enter at least {0} characters')
         ],
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/StoreGrid.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/StoreGrid.php
index ae3857d8e4f6dce09fb3db380c6bc3299cb15a7a..87a3ed048dbb9af62ba28191cd29a33012d48dde 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/StoreGrid.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Store/StoreGrid.php
@@ -99,6 +99,18 @@ class StoreGrid extends Grid
         $this->_rootElement->find(sprintf($this->storeName, $websiteName), Locator::SELECTOR_XPATH)->click();
     }
 
+    /**
+     * Search and open appropriate Website by name.
+     *
+     * @param string $websiteName
+     * @return void
+     */
+    public function searchAndOpenWebsiteByName($websiteName)
+    {
+        $this->search(['website_title' => $websiteName]);
+        $this->_rootElement->find(sprintf($this->storeName, $websiteName), Locator::SELECTOR_XPATH)->click();
+    }
+
     /**
      * Search and open appropriate Store View.
      *
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Grid.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Grid.php
index 67ef167e3fcddcb1515eb749782d0bbfc47fb419..29efb2b4fa03712b3427ed955d508d71fbeea5ba 100755
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Grid.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Grid.php
@@ -60,6 +60,10 @@ class Grid extends DataGrid
             'selector' => '[name="attribute_set_id"]',
             'input' => 'select',
         ],
+        'store_id' => [
+            'selector' => '[name="store_id"]',
+            'input' => 'select',
+        ],
     ];
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductGridIsRendered.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductGridIsRendered.php
new file mode 100644
index 0000000000000000000000000000000000000000..1d5c1e33c94d668fcd4cd2c2c07a2146e1adb0db
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductGridIsRendered.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+/**
+ * Assert that product grid is rendered correctly.
+ */
+class AssertProductGridIsRendered extends \Magento\Mtf\Constraint\AbstractConstraint
+{
+    /**
+     * Assert that product grid is rendered correctly.
+     *
+     * @param \Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex $catalogProductIndex
+     * @return void
+     */
+    public function processAssert(
+        \Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex $catalogProductIndex
+    ) {
+        $productId = $catalogProductIndex->open()->getProductGrid()->getFirstItemId();
+        \PHPUnit_Framework_Assert::assertNotNull(
+            $productId,
+            'Product grid is not rendered correctly.'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Product grid is rendered correctly.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertResetFilterMessage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertResetFilterMessage.php
new file mode 100644
index 0000000000000000000000000000000000000000..5816744e7a3b23500001bb282673d2901a142f44
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertResetFilterMessage.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+/**
+ * Assert that filters have been reset successfully.
+ */
+class AssertResetFilterMessage extends \Magento\Mtf\Constraint\AbstractConstraint
+{
+    /**
+     * Assert message that filters have been reset.
+     *
+     * @param \Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex $catalogProductIndex
+     * @return void
+     */
+    public function processAssert(
+        \Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex $catalogProductIndex
+    ) {
+        \PHPUnit_Framework_Assert::assertContains(
+            'restored the filter to its original state',
+            $catalogProductIndex->getMessagesBlock()->getErrorMessage()
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Filters have been reset successfully.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/GridFilteringDeletedEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/GridFilteringDeletedEntityTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e49d4e3a9ccd4f80b42c0a86aee0b3041b11e12e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/GridFilteringDeletedEntityTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Ui\Test\TestCase\GridFilteringDeletedEntityTest" summary="Grid filtering by deleted entity" ticketId="MAGETWO-71940">
+        <variation name="GridFilteringDeletedEntityTestVariation1">
+            <data name="tag" xsi:type="string">severity:S2</data>
+            <data name="steps" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="0" xsi:type="string">Magento\Store\Test\TestStep\DeleteWebsitesEntityStep</item>
+                </item>
+            </data>
+            <data name="fixtureName" xsi:type="string">catalogProductSimple</data>
+            <data name="fixtureDataSet" xsi:type="string">product_with_additional_website</data>
+            <data name="filters" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="name" xsi:type="string">:name</item>
+                </item>
+            </data>
+            <data name="pageClass" xsi:type="string">Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex</data>
+            <data name="gridRetriever" xsi:type="string">getProductGrid</data>
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductGridIsRendered"/>
+            <constraint name="Magento\Catalog\Test\Constraint\AssertResetFilterMessage"/>
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml
index d9c73fe52277c2a46c443a7aa3252361e9ddb55f..a524139d3f3ad602eceb155a642322e1b7c8be92 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml
@@ -1147,5 +1147,42 @@
                 <item name="value" xsi:type="string">170</item>
             </field>
         </dataset>
+
+        <dataset name="with_only_two_options">
+            <field name="name" xsi:type="string">Configurable product with two options %isolation%</field>
+            <field name="sku" xsi:type="string">sku_test_configurable_product_with_two_options_%isolation%</field>
+            <field name="price" xsi:type="array">
+                <item name="value" xsi:type="string">40</item>
+                <item name="dataset" xsi:type="string">price_40</item>
+            </field>
+            <field name="product_has_weight" xsi:type="string">This item has weight</field>
+            <field name="weight" xsi:type="string">30</field>
+            <field name="status" xsi:type="string">Yes</field>
+            <field name="visibility" xsi:type="string">Catalog, Search</field>
+            <field name="tax_class_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">taxable_goods</item>
+            </field>
+            <field name="url_key" xsi:type="string">configurable-product-with-two-options-%isolation%</field>
+            <field name="configurable_attributes_data" xsi:type="array">
+                <item name="dataset" xsi:type="string">two_options</item>
+            </field>
+            <field name="quantity_and_stock_status" xsi:type="array">
+                <item name="is_in_stock" xsi:type="string">In Stock</item>
+            </field>
+            <field name="website_ids" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="dataset" xsi:type="string">default</item>
+                </item>
+            </field>
+            <field name="attribute_set_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">default</item>
+            </field>
+            <field name="checkout_data" xsi:type="array">
+                <item name="dataset" xsi:type="string">configurable_default_with_two_options</item>
+            </field>
+            <field name="category_ids" xsi:type="array">
+                <item name="dataset" xsi:type="string">default_subcategory</item>
+            </field>
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/CheckoutData.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/CheckoutData.xml
index 003c129c9f9694c47bd0b06bad04873317603a76..136696ff81047d51e58bf50c0808680704f47b1c 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/CheckoutData.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/CheckoutData.xml
@@ -466,5 +466,26 @@
                 <item name="subtotal" xsi:type="string">15</item>
             </field>
         </dataset>
+
+        <dataset name="configurable_default_with_two_options">
+            <field name="options" xsi:type="array">
+                <item name="configurable_options" xsi:type="array">
+                    <item name="0" xsi:type="array">
+                        <item name="title" xsi:type="string">attribute_key_0</item>
+                        <item name="value" xsi:type="string">option_key_0</item>
+                    </item>
+                    <item name="1" xsi:type="array">
+                        <item name="title" xsi:type="string">attribute_key_0</item>
+                        <item name="value" xsi:type="string">option_key_1</item>
+                    </item>
+                </item>
+            </field>
+            <field name="qty" xsi:type="string">3</field>
+            <field name="cartItem" xsi:type="array">
+                <item name="price" xsi:type="string">40</item>
+                <item name="qty" xsi:type="string">3</item>
+                <item name="subtotal" xsi:type="string">120</item>
+            </field>
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Sold/Grid.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Sold/Grid.php
index f74fe80f69eb3b009a3995d32c9b716739a524e0..a9233a1574e07adc6d6f1e4d7112097b58947a35 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Sold/Grid.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Product/Sold/Grid.php
@@ -34,6 +34,13 @@ class Grid extends \Magento\Backend\Test\Block\Widget\Grid
      */
     protected $product = './/*[contains(.,"%s")]/*[contains(@class,"col-qty")]';
 
+    /**
+     * Product sku from grid locator
+     *
+     * @var string
+     */
+    protected $productSku = './/*[contains(.,"%s")]/*[contains(@class,"col-sku")]';
+
     /**
      * Filter locator
      *
@@ -102,4 +109,21 @@ class Grid extends \Magento\Backend\Test\Block\Widget\Grid
         }
         return $views;
     }
+
+    /**
+     * Get product sku from Ordered Products Report grid
+     *
+     * @param OrderInjectable $order
+     * @return array
+     */
+    public function getOrdersResultsforConfigurableProducts(OrderInjectable $order)
+    {
+        $products = $order->getEntityId()['products'];
+        $skus = [];
+        foreach ($products as $key => $productSku) {
+            $skus[$key] = $this->_rootElement
+                ->find(sprintf($this->productSku, $productSku->getName()), Locator::SELECTOR_XPATH)->getText();
+        }
+        return $skus;
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertOrderedProductReportForConfigurableProduct.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertOrderedProductReportForConfigurableProduct.php
new file mode 100644
index 0000000000000000000000000000000000000000..1d7f7020893540319e3e84b8a72da663db1988a8
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertOrderedProductReportForConfigurableProduct.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Reports\Test\Constraint;
+
+use Magento\ConfigurableProduct\Test\Fixture\ConfigurableProduct;
+use Magento\Reports\Test\Page\Adminhtml\OrderedProductsReport;
+use Magento\Sales\Test\Fixture\OrderInjectable;
+use Magento\Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Assert product name, sku and qty in Ordered Products report
+ *
+ */
+class AssertOrderedProductReportForConfigurableProduct extends AbstractConstraint
+{
+    /**
+     * Assert product name, sku and qty in Ordered Products report
+     *
+     * @param OrderedProductsReport $orderedProducts
+     * @param OrderInjectable $order
+     * @return void
+     */
+    public function processAssert(OrderedProductsReport $orderedProducts, OrderInjectable $order)
+    {
+        $products = $order->getEntityId()['products'];
+        $simpleChildSku = $orderedProducts->getGridBlock()->getOrdersResultsforConfigurableProducts($order);
+        $filters = [];
+        foreach ($products as $product) {
+            /** @var ConfigurableProduct $product */
+            if ($product->hasData('configurable_attributes_data')) {
+                $matrix = isset($product->getConfigurableAttributesData()['matrix']) ?
+                    $product->getConfigurableAttributesData()['matrix'] : [];
+                foreach ($matrix as $variation) {
+                    $filters[] = $variation['sku'];
+                }
+            }
+        }
+        \PHPUnit_Framework_Assert::assertContains(
+            $simpleChildSku[0],
+            $filters,
+            'Ordered simple product sku is not present in the Reports grid'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Child  product sku is present on the Ordered Products report grid';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php
index 570cbb5ba8f16b908f7d6baeae45c74e95e12886..b43eb335d36c53836b4c10ae83ec225ff7bdfae3 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php
@@ -28,7 +28,6 @@ class OrderedProductsReportEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'no';
-    const STABLE = 'no';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.xml
index a6b325e19d29c826b5f833e2f95a271705a5a5f6..15947020c1bbea22c347af5e7908e0e77a65992c 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.xml
@@ -28,5 +28,13 @@
             <data name="customersReport/report_period" xsi:type="string">Day</data>
             <constraint name="Magento\Reports\Test\Constraint\AssertOrderedProductResult" />
         </variation>
+        <variation name="OrderedProductsReportEntityTestVariation4" summary="Ordered Product Report for Configurable Product" ticketId="MAGETWO-75456">
+            <data name="order/dataset" xsi:type="string">configurable_product</data>
+            <data name="customersReport/report_from" xsi:type="string">m/d/Y -1 day</data>
+            <data name="customersReport/report_to" xsi:type="string">m/d/Y</data>
+            <data name="customersReport/report_period" xsi:type="string">Day</data>
+            <constraint name="Magento\Reports\Test\Constraint\AssertOrderedProductResult" />
+            <constraint name="Magento\Reports\Test\Constraint\AssertOrderedProductReportForConfigurableProduct" />
+        </variation>
     </testCase>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Repository/OrderInjectable.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/Repository/OrderInjectable.xml
index aff22086394d20c2c8ae305eacca73a792a9b531..e6c61c189d195937b17193c63b7ef7262842a040 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/Repository/OrderInjectable.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Repository/OrderInjectable.xml
@@ -326,5 +326,29 @@
             <field name="base_currency_code" xsi:type="string">0</field>
             <field name="order_currency_code" xsi:type="string">USD</field>
         </dataset>
+
+        <dataset name="configurable_product">
+            <field name="entity_id" xsi:type="array">
+                <item name="products" xsi:type="string">configurableProduct::with_only_two_options</item>
+            </field>
+            <field name="customer_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">default</item>
+            </field>
+            <field name="billing_address_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">US_address</item>
+            </field>
+            <field name="store_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">default_store_view</item>
+            </field>
+            <field name="payment_auth_expiration" xsi:type="array">
+                <item name="method" xsi:type="string">checkmo</item>
+            </field>
+            <field name="shipping_method" xsi:type="string">flatrate_flatrate</field>
+            <field name="payment_authorization_amount" xsi:type="array">
+                <item name="method" xsi:type="string">free</item>
+            </field>
+            <field name="base_currency_code" xsi:type="string">0</field>
+            <field name="order_currency_code" xsi:type="string">USD</field>
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestStep/DeleteWebsitesEntityStep.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestStep/DeleteWebsitesEntityStep.php
new file mode 100644
index 0000000000000000000000000000000000000000..c18f5629d2e02a65df0103726dcd807c718d66d7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestStep/DeleteWebsitesEntityStep.php
@@ -0,0 +1,122 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Store\Test\TestStep;
+
+use Magento\Backend\Test\Page\Adminhtml\EditWebsite;
+use Magento\Backend\Test\Page\Adminhtml\DeleteWebsite;
+use Magento\Backend\Test\Page\Adminhtml\StoreIndex;
+use Magento\Backup\Test\Page\Adminhtml\BackupIndex;
+use Magento\Store\Test\Fixture\Store;
+use Magento\Mtf\TestStep\TestStepInterface;
+use Magento\Mtf\Fixture\FixtureFactory;
+use Magento\Mtf\Fixture\FixtureInterface;
+
+/**
+ * Test Step for DeleteStoreEntity
+ */
+class DeleteWebsitesEntityStep implements TestStepInterface
+{
+    /* tags */
+    const MVP = 'yes';
+    const SEVERITY = 'S2';
+    /* end tags */
+
+    /**
+     * Page BackupIndex
+     *
+     * @var BackupIndex
+     */
+    private $backupIndex;
+
+    /**
+     * Page StoreIndex
+     *
+     * @var StoreIndex
+     */
+    private $storeIndex;
+
+    /**
+     * Page EditWebsite
+     *
+     * @var EditWebsite
+     */
+    private $editWebsite;
+
+    /**
+     * Page StoreDelete
+     *
+     * @var DeleteWebsite
+     */
+    private $deleteWebsite;
+
+    /**
+     * Fixture factory.
+     *
+     * @var FixtureFactory
+     */
+    private $fixtureFactory;
+
+    /**
+     * Fixture factory.
+     *
+     * @var FixtureInterface
+     */
+    private $item;
+
+    /**
+     * @var string
+     */
+    private $createBackup;
+
+    /**
+     * Prepare pages for test
+     *
+     * @param BackupIndex $backupIndex
+     * @param StoreIndex $storeIndex
+     * @param EditWebsite $editWebsite
+     * @param DeleteWebsite $deleteWebsite
+     * @param FixtureFactory $fixtureFactory
+     * @param FixtureInterface $item
+     * @param string $createBackup
+     */
+    public function __construct(
+        BackupIndex $backupIndex,
+        StoreIndex $storeIndex,
+        EditWebsite $editWebsite,
+        DeleteWebsite $deleteWebsite,
+        FixtureFactory $fixtureFactory,
+        FixtureInterface $item,
+        $createBackup = 'No'
+    ) {
+        $this->storeIndex = $storeIndex;
+        $this->editWebsite = $editWebsite;
+        $this->backupIndex = $backupIndex;
+        $this->deleteWebsite = $deleteWebsite;
+        $this->item = $item;
+        $this->createBackup = $createBackup;
+        $this->fixtureFactory = $fixtureFactory;
+    }
+
+    /**
+     * Delete specific Store View.
+     *
+     * @return void
+     */
+    public function run()
+    {
+        $this->backupIndex->open()->getBackupGrid()->massaction([], 'Delete', true, 'Select All');
+        $this->storeIndex->open();
+        $websiteNames = $this->item->getWebsiteIds();
+        if (is_array($websiteNames) && count($websiteNames) > 0) {
+            $websiteName = end($websiteNames);
+            $this->storeIndex->getStoreGrid()->searchAndOpenWebsiteByName($websiteName);
+            $this->editWebsite->getFormPageActions()->delete();
+            $this->deleteWebsite->getDeleteWebsiteForm()->fillForm(['create_backup' => $this->createBackup]);
+            $this->deleteWebsite->getFormPageActions()->delete();
+        }
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringDeletedEntityTest.php b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringDeletedEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6c5d91fda0d9cce1a30ee6f435086454881691cc
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringDeletedEntityTest.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Ui\Test\TestCase;
+
+use Magento\Mtf\Fixture\FixtureFactory;
+use Magento\Mtf\Fixture\FixtureInterface;
+use Magento\Mtf\Page\PageFactory;
+use Magento\Mtf\TestCase\Injectable;
+use Magento\Ui\Test\Block\Adminhtml\DataGrid;
+
+/**
+ * Precondition:
+ * 1. Create items
+ *
+ * Steps:
+ * 1. Navigate to backend.
+ * 2. Go to grid page
+ * 3. Filter grid using provided columns
+ * 5. Perform Asserts
+ *
+ * @group Ui
+ * @ZephyrId MAGETWO-71940
+ */
+class GridFilteringDeletedEntityTest extends Injectable
+{
+    /* tags */
+    const SEVERITY = 'S2';
+    const STABLE = 'no';
+    const MVP = 'no';
+    /* end tags */
+
+    /**
+     * Order index page.
+     *
+     * @var PageFactory
+     */
+    protected $pageFactory;
+
+    /**
+     * Fixture factory.
+     *
+     * @var FixtureFactory
+     */
+    protected $fixtureFactory;
+
+    /**
+     * Injection data.
+     *
+     * @param PageFactory $pageFactory
+     * @param FixtureFactory $fixtureFactory
+     * @return void
+     */
+    public function __inject(PageFactory $pageFactory, FixtureFactory $fixtureFactory)
+    {
+        $this->pageFactory = $pageFactory;
+        $this->fixtureFactory = $fixtureFactory;
+    }
+
+    /**
+     * @param string $pageClass
+     * @param string $gridRetriever
+     * @param string[] $filters
+     * @param string $fixtureName
+     * @param string[] $steps
+     * @param array $fixtureDataSet
+     * @return void
+     */
+    public function test(
+        $pageClass,
+        $gridRetriever,
+        array $filters,
+        $fixtureName,
+        array $steps = [],
+        $fixtureDataSet = null
+    ) {
+        $item = $this->createItems($fixtureName, $fixtureDataSet);
+        $page = $this->pageFactory->create($pageClass);
+
+        $page->open();
+        /** @var DataGrid $gridBlock */
+        $gridBlock = $page->$gridRetriever();
+        $gridBlock->resetFilter();
+
+        foreach ($filters as $itemFilters) {
+            $filterArray = [];
+            foreach ($itemFilters as $itemFiltersName => $itemFilterValue) {
+                if (substr($itemFilterValue, 0, 1) === ':') {
+                    $value = $item->getData(substr($itemFilterValue, 1));
+                } else {
+                    $value = $itemFilterValue;
+                }
+                $filterArray[$itemFiltersName] = $value;
+            }
+
+            $storesArray = $item->getDataFieldConfig('website_ids')['source']->getStores();
+            $store = end($storesArray);
+            $filterArray['store_id']  = $store->getName();
+            $gridBlock->search($filterArray);
+        }
+
+        if (!empty($steps)) {
+            foreach ($steps as $step) {
+                $this->processSteps($item, $step);
+            }
+        }
+    }
+
+    /**
+     * @param string $fixtureName
+     * @param string $fixtureDataSet
+     * @return FixtureInterface
+     */
+    private function createItems($fixtureName, $fixtureDataSet)
+    {
+        $item = $this->fixtureFactory->createByCode($fixtureName, ['dataset' => $fixtureDataSet]);
+        $item->persist();
+        return $item;
+    }
+
+    /**
+     * @param FixtureInterface $item
+     * @param array $steps
+     * @return void
+     */
+    private function processSteps(FixtureInterface $item, $steps)
+    {
+        foreach ($steps as $step) {
+            $processStep = $this->objectManager->create($step, ['item' => $item]);
+            $processStep->run();
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Review/Block/Product/ReviewRendererTest.php b/dev/tests/integration/testsuite/Magento/Review/Block/Product/ReviewRendererTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..749d6c74917b733acfae32926bf80e9192e3d969
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Review/Block/Product/ReviewRendererTest.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Review\Block\Product;
+
+class ReviewRendererTest extends \PHPUnit\Framework\TestCase
+{
+    /**
+     * Test verifies ReviewRenderer::getReviewsSummaryHtml call with $displayIfNoReviews = false
+     * The reviews summary will be shown as expected only if there is at least one review available
+     *
+     * @magentoDataFixture Magento/Review/_files/different_reviews.php
+     * @magentoAppArea frontend
+     */
+    public function testGetReviewSummaryHtml()
+    {
+        $productSku = 'simple';
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
+        $productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
+        $product = $productRepository->get($productSku);
+        /** @var  ReviewRenderer $reviewRenderer */
+        $reviewRenderer = $objectManager->create(ReviewRenderer::class);
+        $actualResult = $reviewRenderer->getReviewsSummaryHtml($product);
+        $this->assertEquals(2, $reviewRenderer->getReviewsCount());
+        $this->assertContains('<span itemprop="reviewCount">2</span>', $actualResult);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Review/_files/different_reviews.php b/dev/tests/integration/testsuite/Magento/Review/_files/different_reviews.php
index 627434111fe79969d6730d10cb1acf2602f569dc..b7de6c99130e49c34a3df4156a15f4503d485105 100644
--- a/dev/tests/integration/testsuite/Magento/Review/_files/different_reviews.php
+++ b/dev/tests/integration/testsuite/Magento/Review/_files/different_reviews.php
@@ -71,3 +71,4 @@ $review->setEntityId(
         )->getStore()->getId()
     ]
 )->save();
+$review->aggregate();
diff --git a/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Repository.php b/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Repository.php
index ecdc51044430aeb49dfed36da3fd85c9baf7af03..b1cdb53288216f73935336e87b45a6569c866055 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Repository.php
+++ b/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Repository.php
@@ -226,13 +226,15 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
         /** @var ParameterReflection $parameterReflection */
         $parameterReflection = $methodReflection->getParameters()[0];
         $body = "if (!\$id) {\n"
-            . "    throw new \\" . InputException::class . "('ID required');\n"
+            . "    throw new \\" . InputException::class . "(new \\Magento\\Framework\\Phrase('ID required'));\n"
             . "}\n"
             . "if (!isset(\$this->registry[\$id])) {\n"
             . "    \$entity = \$this->" . $this->_getSourcePersistorPropertyName()
             . "->loadEntity(\$id);\n"
             . "    if (!\$entity->getId()) {\n"
-            . "        throw new \\" . NoSuchEntityException::class . "('Requested entity doesn\\'t exist');\n"
+            . "        throw new \\" . NoSuchEntityException::class . "(\n"
+            . "            new \\Magento\\Framework\\Phrase('Requested entity doesn\\'t exist')\n"
+            . "        );\n"
             . "    }\n"
             . "    \$this->registry[\$id] = \$entity;\n"
             . "}\n"
diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt
index 1aeaec427d0d38c756599de1b2eb96612fdb9e2c..222d5c7ffc6d167b61e421485ea4a0761b320316 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt
+++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt
@@ -71,12 +71,14 @@ class SampleRepository implements SampleRepositoryInterface
     public function get($id)
     {
         if (!$id) {
-            throw new \Magento\Framework\Exception\InputException('ID required');
+            throw new \Magento\Framework\Exception\InputException(new \Magento\Framework\Phrase('ID required'));
         }
         if (!isset($this->registry[$id])) {
             $entity = $this->sampleInterfacePersistor->loadEntity($id);
             if (!$entity->getId()) {
-                throw new \Magento\Framework\Exception\NoSuchEntityException('Requested entity doesn\'t exist');
+                throw new \Magento\Framework\Exception\NoSuchEntityException(
+                    new \Magento\Framework\Phrase('Requested entity doesn\'t exist')
+                );
             }
             $this->registry[$id] = $entity;
         }
diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/TSampleRepository.txt b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/TSampleRepository.txt
index 53ec1801995ad7ec9f3944827ad44ec39ebbc344..e4067e70670a49e5691f3b672810bcc117961ff6 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/TSampleRepository.txt
+++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/TSampleRepository.txt
@@ -71,12 +71,14 @@ class TSampleRepository implements TSampleRepositoryInterface
     public function get(int $id) : \Magento\Framework\ObjectManager\Code\Generator\TSampleInterface
     {
         if (!$id) {
-            throw new \Magento\Framework\Exception\InputException('ID required');
+            throw new \Magento\Framework\Exception\InputException(new \Magento\Framework\Phrase('ID required'));
         }
         if (!isset($this->registry[$id])) {
             $entity = $this->tSampleInterfacePersistor->loadEntity($id);
             if (!$entity->getId()) {
-                throw new \Magento\Framework\Exception\NoSuchEntityException('Requested entity doesn\'t exist');
+                throw new \Magento\Framework\Exception\NoSuchEntityException(
+                    new \Magento\Framework\Phrase('Requested entity doesn\'t exist')
+                );
             }
             $this->registry[$id] = $entity;
         }
diff --git a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php
index d38c6b37fdd40a8b57c731f53f66a7dc56ec0926..e995b2c20a6ab5f4fd483a9b200c1a0b151dee4f 100755
--- a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php
+++ b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php
@@ -7,6 +7,7 @@ namespace Magento\Framework\View\Layout\Generator;
 
 use Magento\Framework\App\State;
 use Magento\Framework\ObjectManager\Config\Reader\Dom;
+use Magento\Framework\View\Element\Template;
 use Magento\Framework\View\Layout;
 
 /**
@@ -60,6 +61,13 @@ class Block implements Layout\GeneratorInterface
      */
     protected $exceptionHandlerBlockFactory;
 
+    /**
+     * Default block class name. Will be used if no class name is specified in block configuration
+     *
+     * @var string
+     */
+    private $defaultClass;
+
     /**
      * @param \Magento\Framework\View\Element\BlockFactory $blockFactory
      * @param \Magento\Framework\Data\Argument\InterpreterInterface $argumentInterpreter
@@ -69,6 +77,7 @@ class Block implements Layout\GeneratorInterface
      * @param \Magento\Framework\App\ScopeResolverInterface $scopeResolver
      * @param \Magento\Framework\View\Element\ExceptionHandlerBlockFactory $exceptionHandlerBlockFactory
      * @param State $appState
+     * @param string $defaultClass
      */
     public function __construct(
         \Magento\Framework\View\Element\BlockFactory $blockFactory,
@@ -78,7 +87,8 @@ class Block implements Layout\GeneratorInterface
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Framework\App\ScopeResolverInterface $scopeResolver,
         \Magento\Framework\View\Element\ExceptionHandlerBlockFactory $exceptionHandlerBlockFactory,
-        State $appState
+        State $appState,
+        $defaultClass = Template::class
     ) {
         $this->blockFactory = $blockFactory;
         $this->argumentInterpreter = $argumentInterpreter;
@@ -88,6 +98,7 @@ class Block implements Layout\GeneratorInterface
         $this->scopeResolver = $scopeResolver;
         $this->exceptionHandlerBlockFactory = $exceptionHandlerBlockFactory;
         $this->appState = $appState;
+        $this->defaultClass = $defaultClass;
     }
 
     /**
@@ -210,7 +221,8 @@ class Block implements Layout\GeneratorInterface
         }
 
         // create block
-        $className = $attributes['class'];
+        $className = isset($attributes['class']) && !empty($attributes['class']) ?
+            $attributes['class'] : $this->defaultClass ;
         $block = $this->createBlock($className, $elementName, [
             'data' => $this->evaluateArguments($data['arguments'])
         ]);
diff --git a/setup/src/Magento/Setup/Console/Command/UpgradeCommand.php b/setup/src/Magento/Setup/Console/Command/UpgradeCommand.php
index a3d2ca3d8c408cdc5155fda77191b29d4dab89f5..e2d032da9b1966e37daf0b52b3151a351cf81804 100644
--- a/setup/src/Magento/Setup/Console/Command/UpgradeCommand.php
+++ b/setup/src/Magento/Setup/Console/Command/UpgradeCommand.php
@@ -6,6 +6,7 @@
 namespace Magento\Setup\Console\Command;
 
 use Magento\Deploy\Console\Command\App\ConfigImportCommand;
+use Magento\Framework\App\State as AppState;
 use Magento\Framework\App\DeploymentConfig;
 use Magento\Framework\App\ObjectManager;
 use Magento\Framework\Setup\ConsoleLogger;
@@ -37,16 +38,25 @@ class UpgradeCommand extends AbstractSetupCommand
      */
     private $deploymentConfig;
 
+    /**
+     * @var AppState
+     */
+    private $appState;
+
     /**
      * Constructor
      *
      * @param InstallerFactory $installerFactory
      * @param DeploymentConfig $deploymentConfig
      */
-    public function __construct(InstallerFactory $installerFactory, DeploymentConfig $deploymentConfig = null)
-    {
+    public function __construct(
+        InstallerFactory $installerFactory,
+        DeploymentConfig $deploymentConfig = null,
+        AppState $appState = null
+    ) {
         $this->installerFactory = $installerFactory;
         $this->deploymentConfig = $deploymentConfig ?: ObjectManager::getInstance()->get(DeploymentConfig::class);
+        $this->appState = $appState ?: ObjectManager::getInstance()->get(AppState::class);
         parent::__construct();
     }
 
@@ -90,7 +100,7 @@ class UpgradeCommand extends AbstractSetupCommand
                 $importConfigCommand->run($arrayInput, $output);
             }
 
-            if (!$keepGenerated) {
+            if (!$keepGenerated && $this->appState->getMode() === AppState::MODE_PRODUCTION) {
                 $output->writeln(
                     '<info>Please re-run Magento compile command. Use the command "setup:di:compile"</info>'
                 );
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/UpgradeCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/UpgradeCommandTest.php
index 59816ab77153b18c15bce682be94661035c7da9a..fb81c6677274ec0e026cfc69fd48f52dca3eaa87 100644
--- a/setup/src/Magento/Setup/Test/Unit/Console/Command/UpgradeCommandTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/UpgradeCommandTest.php
@@ -6,6 +6,7 @@
 namespace Magento\Setup\Test\Unit\Console\Command;
 
 use Magento\Framework\App\DeploymentConfig;
+use Magento\Framework\App\State as AppState;
 use Magento\Framework\Console\Cli;
 use Magento\Setup\Console\Command\UpgradeCommand;
 use Magento\Setup\Model\Installer;
@@ -29,11 +30,15 @@ class UpgradeCommandTest extends \PHPUnit\Framework\TestCase
      */
     private $installerMock;
 
+    /**
+     * @var AppState|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $appStateMock;
+
     /**
      * @var UpgradeCommand
      */
     private $upgradeCommand;
-
     /**
      * @var CommandTester
      */
@@ -56,16 +61,24 @@ class UpgradeCommandTest extends \PHPUnit\Framework\TestCase
         $this->installerFactoryMock->expects($this->once())
             ->method('create')
             ->willReturn($this->installerMock);
+        $this->appStateMock = $this->getMockBuilder(AppState::class)
+            ->disableOriginalConstructor()
+            ->getMock();
 
-        $this->upgradeCommand = new UpgradeCommand($this->installerFactoryMock, $this->deploymentConfigMock);
+        $this->upgradeCommand = new UpgradeCommand(
+            $this->installerFactoryMock,
+            $this->deploymentConfigMock,
+            $this->appStateMock
+        );
         $this->commandTester = new CommandTester($this->upgradeCommand);
     }
 
     /**
      * @dataProvider executeDataProvider
      */
-    public function testExecute($options, $expectedString = '')
+    public function testExecute($options, $deployMode, $expectedString = '')
     {
+        $this->appStateMock->method('getMode')->willReturn($deployMode);
         $this->installerMock->expects($this->at(0))
             ->method('updateModulesSequence');
         $this->installerMock->expects($this->at(1))
@@ -85,11 +98,23 @@ class UpgradeCommandTest extends \PHPUnit\Framework\TestCase
         return [
             [
                 'options' => [],
+                'deployMode' => \Magento\Framework\App\State::MODE_PRODUCTION,
                 'expectedString' => 'Please re-run Magento compile command. Use the command "setup:di:compile"'
                     . PHP_EOL
             ],
             [
                 'options' => ['--keep-generated' => true],
+                'deployMode' => \Magento\Framework\App\State::MODE_PRODUCTION,
+                'expectedString' => ''
+            ],
+            [
+                'options' => [],
+                'deployMode' => \Magento\Framework\App\State::MODE_DEVELOPER,
+                'expectedString' => ''
+            ],
+            [
+                'options' => [],
+                'deployMode' => \Magento\Framework\App\State::MODE_DEFAULT,
                 'expectedString' => ''
             ],
         ];