diff --git a/.htaccess.sample b/.htaccess.sample index 8e6e702ced716..3c412725f2134 100644 --- a/.htaccess.sample +++ b/.htaccess.sample @@ -111,7 +111,8 @@ ############################################ ## enable rewrites - Options +FollowSymLinks + # The following line has better security but add some performance overhead - see https://httpd.apache.org/docs/2.4/en/misc/perf-tuning.html + Options -FollowSymLinks +SymLinksIfOwnerMatch RewriteEngine on ############################################ diff --git a/README.md b/README.md index 9b1aa1b7b3e28..eca00d852940a 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,13 @@ Welcome to Magento 2 installation! We're glad you chose to install Magento 2, a cutting edge, feature-rich eCommerce solution that gets results. ## Magento system requirements -[Magento system requirements](http://devdocs.magento.com/magento-system-requirements.html) +[Magento system requirements](http://devdocs.magento.com/guides/v2.2/install-gde/system-requirements2.html) ## Install Magento To install Magento, see either: * [Magento DevBox](https://magento.com/tech-resources/download), the easiest way to get started with Magento. -* [Installation guide](http://devdocs.magento.com/guides/v2.0/install-gde/bk-install-guide.html) +* [Installation guide](http://devdocs.magento.com/guides/v2.2/install-gde/bk-install-guide.html)

Contributing to the Magento 2 code base

Contributions can take the form of new components or features, changes to existing features, tests, documentation (such as developer guides, user guides, examples, or specifications), bug fixes, optimizations, or just good suggestions. @@ -22,8 +22,8 @@ To learn about issues, click [here][2]. To open an issue, click [here][3]. To suggest documentation improvements, click [here][4]. -[1]: -[2]: +[1]: +[2]: [3]: [4]: diff --git a/app/bootstrap.php b/app/bootstrap.php index 6701a9f4dd51e..aba8668f4a158 100644 --- a/app/bootstrap.php +++ b/app/bootstrap.php @@ -14,12 +14,12 @@ if (!defined('PHP_VERSION_ID') || !(PHP_VERSION_ID === 70002 || PHP_VERSION_ID === 70004 || PHP_VERSION_ID >= 70006)) { if (PHP_SAPI == 'cli') { echo 'Magento supports 7.0.2, 7.0.4, and 7.0.6 or later. ' . - 'Please read http://devdocs.magento.com/guides/v1.0/install-gde/system-requirements.html'; + 'Please read http://devdocs.magento.com/guides/v2.2/install-gde/system-requirements.html'; } else { echo <<

Magento supports PHP 7.0.2, 7.0.4, and 7.0.6 or later. Please read - + Magento System Requirements. HTML; diff --git a/app/code/Magento/AdminNotification/Model/Feed.php b/app/code/Magento/AdminNotification/Model/Feed.php index 1766425fb19b1..d3b0b8501c864 100644 --- a/app/code/Magento/AdminNotification/Model/Feed.php +++ b/app/code/Magento/AdminNotification/Model/Feed.php @@ -214,9 +214,6 @@ public function getFeedData() ); $curl->write(\Zend_Http_Client::GET, $this->getFeedUrl(), '1.0'); $data = $curl->read(); - if ($data === false) { - return false; - } $data = preg_split('/^\r?$/m', $data, 2); $data = trim($data[1]); $curl->close(); diff --git a/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing.php b/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing.php index 23829d3725119..0e8acb37104e6 100644 --- a/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing.php +++ b/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing.php @@ -394,7 +394,7 @@ protected function saveAndReplaceAdvancedPrices() ? $rowData[self::COL_TIER_PRICE] : 0, 'percentage_value' => $rowData[self::COL_TIER_PRICE_TYPE] === self::TIER_PRICE_TYPE_PERCENT ? $rowData[self::COL_TIER_PRICE] : null, - 'website_id' => $this->getWebsiteId($rowData[self::COL_TIER_PRICE_WEBSITE]) + 'website_id' => $this->getWebSiteId($rowData[self::COL_TIER_PRICE_WEBSITE]) ]; } } diff --git a/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php b/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php index 5111b4932d7a8..9a380ff75da24 100644 --- a/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php +++ b/app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Import/AdvancedPricing/Validator/WebsiteTest.php @@ -27,7 +27,7 @@ class WebsiteTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $this->webSiteModel = $this->getMockBuilder(\Magento\Store\Model\WebSite::class) + $this->webSiteModel = $this->getMockBuilder(\Magento\Store\Model\Website::class) ->setMethods(['getBaseCurrency']) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/Backend/Block/System/Store/Edit/AbstractForm.php b/app/code/Magento/Backend/Block/System/Store/Edit/AbstractForm.php index f19799d2e4939..034887c67d1ee 100644 --- a/app/code/Magento/Backend/Block/System/Store/Edit/AbstractForm.php +++ b/app/code/Magento/Backend/Block/System/Store/Edit/AbstractForm.php @@ -37,7 +37,7 @@ protected function _prepareForm() ['data' => ['id' => 'edit_form', 'action' => $this->getData('action'), 'method' => 'post']] ); - $this->_prepareStoreFieldSet($form); + $this->_prepareStoreFieldset($form); $form->addField( 'store_type', diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Noroute/Index.php b/app/code/Magento/Backend/Controller/Adminhtml/Noroute/Index.php index e8251b5be6030..ce59d2fd48e5a 100644 --- a/app/code/Magento/Backend/Controller/Adminhtml/Noroute/Index.php +++ b/app/code/Magento/Backend/Controller/Adminhtml/Noroute/Index.php @@ -34,7 +34,7 @@ public function execute() { /** @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/Controller/Adminhtml/System/Account/Save.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Account/Save.php index c9bce1cbf3888..421885a0c32a3 100644 --- a/app/code/Magento/Backend/Controller/Adminhtml/System/Account/Save.php +++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Account/Save.php @@ -54,9 +54,9 @@ public function execute() $user = $this->_objectManager->create(\Magento\User\Model\User::class)->load($userId); $user->setId($userId) - ->setUsername($this->getRequest()->getParam('username', false)) - ->setFirstname($this->getRequest()->getParam('firstname', false)) - ->setLastname($this->getRequest()->getParam('lastname', false)) + ->setUserName($this->getRequest()->getParam('username', false)) + ->setFirstName($this->getRequest()->getParam('firstname', false)) + ->setLastName($this->getRequest()->getParam('lastname', false)) ->setEmail(strtolower($this->getRequest()->getParam('email', false))); if ($this->_objectManager->get(\Magento\Framework\Validator\Locale::class)->isValid($interfaceLocale)) { diff --git a/app/code/Magento/Backend/Test/Unit/Block/Widget/Grid/ColumnSetTest.php b/app/code/Magento/Backend/Test/Unit/Block/Widget/Grid/ColumnSetTest.php index be171a8ed40bf..df242a4cf6129 100644 --- a/app/code/Magento/Backend/Test/Unit/Block/Widget/Grid/ColumnSetTest.php +++ b/app/code/Magento/Backend/Test/Unit/Block/Widget/Grid/ColumnSetTest.php @@ -117,7 +117,7 @@ public function testSetFilterTypePropagatesFilterTypeToColumns() public function testGetRowUrlIfUrlPathNotSet() { - $this->assertEquals('#', $this->_block->getRowUrl(new \StdClass())); + $this->assertEquals('#', $this->_block->getRowUrl(new \stdClass())); } public function testGetRowUrl() diff --git a/app/code/Magento/Backend/Test/Unit/Block/Widget/Grid/ColumnTest.php b/app/code/Magento/Backend/Test/Unit/Block/Widget/Grid/ColumnTest.php index da13af87b71ea..c5c56fd75fbe7 100644 --- a/app/code/Magento/Backend/Test/Unit/Block/Widget/Grid/ColumnTest.php +++ b/app/code/Magento/Backend/Test/Unit/Block/Widget/Grid/ColumnTest.php @@ -351,7 +351,7 @@ public function testSetGetGrid() $this->_block->setFilter('StdClass'); - $grid = new \StdClass(); + $grid = new \stdClass(); $this->_block->setGrid($grid); $this->assertEquals($grid, $this->_block->getGrid()); } diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml index 92df39bd65ee4..04bfe76bce9e7 100644 --- a/app/code/Magento/Backend/etc/adminhtml/system.xml +++ b/app/code/Magento/Backend/etc/adminhtml/system.xml @@ -231,7 +231,7 @@ Magento\Directory\Model\Config\Source\Country - + Magento\Directory\Model\Config\Source\Country diff --git a/app/code/Magento/Backend/view/adminhtml/templates/page/header.phtml b/app/code/Magento/Backend/view/adminhtml/templates/page/header.phtml index 40b7173f47417..8feccc9cf1b8f 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/page/header.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/page/header.phtml @@ -29,7 +29,7 @@ data-mage-init='{"dropdown":{}}' data-toggle="dropdown"> - +

    @@ -39,7 +39,7 @@ href="getUrl('adminhtml/system_account/index') ?>" getUiId('user', 'account', 'settings') ?> title="escapeHtml(__('Account Setting')) ?>"> - (escapeHtml($block->getUser()->getUsername()) ?>) + (escapeHtml($block->getUser()->getUserName()) ?>) diff --git a/app/code/Magento/Backend/view/adminhtml/templates/system/search.phtml b/app/code/Magento/Backend/view/adminhtml/templates/system/search.phtml index a528133b2bc3a..b50183ced29b4 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/system/search.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/system/search.phtml @@ -28,16 +28,16 @@ diff --git a/app/code/Magento/Tinymce3/view/base/web/tinymce3Adapter.js b/app/code/Magento/Tinymce3/view/base/web/tinymce3Adapter.js index 08bbb95888d8d..fd5e9628fecdb 100644 --- a/app/code/Magento/Tinymce3/view/base/web/tinymce3Adapter.js +++ b/app/code/Magento/Tinymce3/view/base/web/tinymce3Adapter.js @@ -132,6 +132,10 @@ define([ ed.onInit.add(self.onEditorInit.bind(self)); + ed.onInit.add(function (editor) { + varienGlobalEvents.fireEvent('wysiwygEditorInitialized', editor); + }); + ed.onSubmit.add(function (edi, e) { varienGlobalEvents.fireEvent('tinymceSubmit', e); }); @@ -244,6 +248,13 @@ define([ return tinyMCE3.get(id); }, + /** + * @return {String|null} + */ + getId: function () { + return this.id || (this.activeEditor() ? this.activeEditor().id : null) || tinyMceEditors.values()[0].id; + }, + /** * @return {Object} */ @@ -261,6 +272,35 @@ define([ this.activeEditor().execCommand('mceInsertContent', typeof ui !== 'undefined' ? ui : false, content); }, + /** + * Set the status of the toolbar to disabled or enabled (true for enabled, false for disabled) + * @param {Boolean} enabled + */ + setToolbarStatus: function (enabled) { + _.each(this.activeEditor().controlManager.controls, function (property, index, controls) { + controls[property.id].setDisabled(!enabled); + }); + }, + + /** + * Set the status of the editor and toolbar + * + * @param {Boolean} enabled + */ + setEnabledStatus: function (enabled) { + if (this.activeEditor()) { + this.activeEditor().getBody().setAttribute('contenteditable', enabled); + this.activeEditor().readonly = !enabled; + this.setToolbarStatus(enabled); + } + + if (enabled) { + this.getTextArea().removeProp('disabled'); + } else { + this.getTextArea().prop('disabled', 'disabled'); + } + }, + /** * Set caret location in WYSIWYG editor. * @@ -279,7 +319,7 @@ define([ storeId = this.config['store_id'] !== null ? this.config['store_id'] : 0, frameDialog = jQuery(o.win.frameElement).parents('[role="dialog"]'), wUrl = this.config['files_browser_window_url'] + - 'target_element_id/' + this.id + '/' + + 'target_element_id/' + this.getId() + '/' + 'store/' + storeId + '/'; this.mediaBrowserOpener = o.win; @@ -331,14 +371,14 @@ define([ * @return {jQuery|*|HTMLElement} */ getToggleButton: function () { - return $('toggle' + this.id); + return $('toggle' + this.getId()); }, /** * Get plugins button. */ getPluginButtons: function () { - return $$('#buttons' + this.id + ' > button.plugin'); + return jQuery('#buttons' + this.getId() + ' > button.plugin'); }, /** @@ -350,11 +390,9 @@ define([ this.setup(mode); - tinyMCE3.execCommand('mceAddControl', false, this.id); + tinyMCE3.execCommand('mceAddControl', false, this.getId()); - this.getPluginButtons().each(function (e) { - e.hide(); - }); + this.getPluginButtons().hide(); return this; }, @@ -365,11 +403,9 @@ define([ turnOff: function () { this.closePopups(); - tinyMCE3.execCommand('mceRemoveControl', false, this.id); + tinyMCE3.execCommand('mceRemoveControl', false, this.getId()); - this.getPluginButtons().each(function (e) { - e.show(); - }); + this.getPluginButtons().show(); return this; }, @@ -380,8 +416,8 @@ define([ closePopups: function () { if (typeof closeEditorPopup == 'function') { // close all popups to avoid problems with updating parent content area - closeEditorPopup('widget_window' + this.id); - closeEditorPopup('browser_window' + this.id); + closeEditorPopup('widget_window' + this.getId()); + closeEditorPopup('browser_window' + this.getId()); } }, @@ -389,7 +425,7 @@ define([ * @return {Boolean} */ toggle: function () { - if (!tinyMCE3.get(this.id)) { + if (!tinyMCE3.get(this.getId())) { this.turnOn(); return true; @@ -415,8 +451,8 @@ define([ * On form validation. */ onFormValidation: function () { - if (tinyMCE3.get(this.id)) { - $(this.id).value = tinyMCE3.get(this.id).getContent(); + if (tinyMCE3.get(this.getId())) { + $(this.getId()).value = tinyMCE3.get(this.getId()).getContent(); } }, @@ -444,25 +480,28 @@ define([ * @param {String} directive */ makeDirectiveUrl: function (directive) { - return this.config['directives_url'].replace('directive', 'directive/___directive/' + directive); + return this.config['directives_url'].replace(/directive.*/, 'directive/___directive/' + directive); }, /** + * Convert {{directive}} style attributes syntax to absolute URLs * @param {Object} content * @return {*} */ encodeDirectives: function (content) { // collect all HTML tags with attributes that contain directives - return content.gsub(/<([a-z0-9\-\_]+.+?)([a-z0-9\-\_]+=".*?\{\{.+?\}\}.*?".*?)>/i, function (match) { - var attributesString = match[2]; + return content.gsub(/<([a-z0-9\-\_]+[^>]+?)([a-z0-9\-\_]+=".*?\{\{.+?\}\}.*?".*?)>/i, function (match) { + var attributesString = match[2], + decodedDirectiveString; // process tag attributes string attributesString = attributesString.gsub(/([a-z0-9\-\_]+)="(.*?)(\{\{.+?\}\})(.*?)"/i, function (m) { - return m[1] + '="' + m[2] + this.makeDirectiveUrl(Base64.mageEncode(m[3])) + m[4] + '"'; + decodedDirectiveString = encodeURIComponent(Base64.mageEncode(m[3].replace(/"/g, '"'))); + + return m[1] + '="' + m[2] + this.makeDirectiveUrl(decodedDirectiveString) + m[4] + '"'; }.bind(this)); return '<' + match[1] + attributesString + '>'; - }.bind(this)); }, @@ -493,16 +532,17 @@ define([ }, /** + * Convert absolute URLs to {{directive}} style attributes syntax * @param {Object} content * @return {*} */ decodeDirectives: function (content) { // escape special chars in directives url to use it in regular expression var url = this.makeDirectiveUrl('%directive%').replace(/([$^.?*!+:=()\[\]{}|\\])/g, '\\$1'), - reg = new RegExp(url.replace('%directive%', '([a-zA-Z0-9,_-]+)')); + reg = new RegExp(url.replace('%directive%', '([a-zA-Z0-9%,_-]+)\/?')); return content.gsub(reg, function (match) { //eslint-disable-line no-extra-bind - return Base64.mageDecode(match[1]); + return Base64.mageDecode(decodeURIComponent(match[1])).replace(/"/g, '"'); }); }, @@ -548,7 +588,7 @@ define([ * Update text area. */ updateTextArea: function () { - var editor = tinyMCE3.get(this.id), + var editor = tinyMCE3.get(this.getId()), content; if (!editor) { @@ -558,7 +598,14 @@ define([ content = editor.getContent(); content = this.decodeContent(content); - jQuery('#' + this.id).val(content).trigger('change'); + this.getTextArea().val(content).trigger('change'); + }, + + /** + * @return {Object} jQuery textarea element + */ + getTextArea: function () { + return jQuery('#' + this.getId()); }, /** diff --git a/app/code/Magento/Ui/Config/Converter/HtmlContent.php b/app/code/Magento/Ui/Config/Converter/HtmlContent.php index f77b4a5285d5a..db874a302bd50 100644 --- a/app/code/Magento/Ui/Config/Converter/HtmlContent.php +++ b/app/code/Magento/Ui/Config/Converter/HtmlContent.php @@ -23,7 +23,7 @@ public function convert(\DOMNode $node, array $data) if ($node->nodeType == XML_ELEMENT_NODE) { $xml = '' . "\n" . '' . "\n" - . $node->ownerDocument->saveXml($node) . "\n" + . $node->ownerDocument->saveXML($node) . "\n" . ''; $items['layout']['xsi:type'] = 'string'; $items['layout']['name'] = 'layout'; diff --git a/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php b/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php index 18fd5eea2f5f2..4df9198c0b95d 100644 --- a/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php +++ b/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php @@ -79,7 +79,10 @@ private function validateAclResource($dataProviderConfigData) { if (isset($dataProviderConfigData['aclResource'])) { if (!$this->_authorization->isAllowed($dataProviderConfigData['aclResource'])) { - $this->_redirect('admin/denied'); + if (!$this->_request->isAjax()) { + $this->_redirect('admin/denied'); + } + return false; } } 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 b1ef1dd9b5249..d41c90bfa760a 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 @@ -208,6 +208,13 @@ public function testExecuteAjaxRequestWithoutPermissions(array $dataProviderConf $this->requestMock->expects($this->any()) ->method('getParams') ->willReturn([]); + if ($isAllowed === false) { + $this->requestMock->expects($this->once()) + ->method('isAjax') + ->willReturn(true); + } + $this->responseMock->expects($this->never()) + ->method('setRedirect'); $this->responseMock->expects($this->any()) ->method('appendBody') ->with($renderedData); diff --git a/app/code/Magento/Ui/view/base/ui_component/templates/container/default.xhtml b/app/code/Magento/Ui/view/base/ui_component/templates/container/default.xhtml index dd4a2038a53c4..5bbf252c8a787 100644 --- a/app/code/Magento/Ui/view/base/ui_component/templates/container/default.xhtml +++ b/app/code/Magento/Ui/view/base/ui_component/templates/container/default.xhtml @@ -5,7 +5,7 @@ * See COPYING.txt for license details. */ --> -
    +
    diff --git a/app/code/Magento/Ui/view/base/ui_component/templates/export/button.xhtml b/app/code/Magento/Ui/view/base/ui_component/templates/export/button.xhtml index 6dc91cf6b3d5b..977ea8374dfa8 100644 --- a/app/code/Magento/Ui/view/base/ui_component/templates/export/button.xhtml +++ b/app/code/Magento/Ui/view/base/ui_component/templates/export/button.xhtml @@ -5,7 +5,7 @@ * See COPYING.txt for license details. */ --> -
    +
    diff --git a/app/code/Magento/Ui/view/base/ui_component/templates/form/collapsible.xhtml b/app/code/Magento/Ui/view/base/ui_component/templates/form/collapsible.xhtml index baab52111aebe..aedf18961a719 100644 --- a/app/code/Magento/Ui/view/base/ui_component/templates/form/collapsible.xhtml +++ b/app/code/Magento/Ui/view/base/ui_component/templates/form/collapsible.xhtml @@ -5,7 +5,7 @@ * See COPYING.txt for license details. */ --> -
    +
    diff --git a/app/code/Magento/Ui/view/base/ui_component/templates/form/default.xhtml b/app/code/Magento/Ui/view/base/ui_component/templates/form/default.xhtml index 5e0d699ed3edc..9d7715db905ab 100644 --- a/app/code/Magento/Ui/view/base/ui_component/templates/form/default.xhtml +++ b/app/code/Magento/Ui/view/base/ui_component/templates/form/default.xhtml @@ -5,7 +5,7 @@ * See COPYING.txt for license details. */ --> -
    +
    diff --git a/app/code/Magento/Ui/view/base/ui_component/templates/listing/default.xhtml b/app/code/Magento/Ui/view/base/ui_component/templates/listing/default.xhtml index 88a8e42e2966b..661c7c0c23dfb 100644 --- a/app/code/Magento/Ui/view/base/ui_component/templates/listing/default.xhtml +++ b/app/code/Magento/Ui/view/base/ui_component/templates/listing/default.xhtml @@ -9,7 +9,7 @@ class="admin__data-grid-outer-wrap" data-bind="scope: '{{getName()}}.{{getName()}}'" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../Ui/etc/ui_template.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_template.xsd">
    diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js index 6bbcb4416d33a..b6979121a1891 100755 --- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js @@ -118,8 +118,8 @@ define([ this._super(); - scope = this.dataScope; - name = scope.split('.').slice(1); + scope = this.dataScope.split('.'); + name = scope.length > 1 ? scope.slice(1) : scope; valueUpdate = this.showFallbackReset ? 'afterkeydown' : this.valueUpdate; diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js b/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js index bc57374476735..29ffb488981d9 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/wysiwyg.js @@ -7,12 +7,14 @@ * @api */ define([ + 'wysiwygAdapter', 'Magento_Ui/js/lib/view/utils/async', 'underscore', 'ko', './abstract', + 'mage/adminhtml/events', 'Magento_Variable/variables' -], function ($, _, ko, Abstract) { +], function (wysiwyg, $, _, ko, Abstract, varienGlobalEvents) { 'use strict'; return Abstract.extend({ @@ -45,8 +47,7 @@ define([ component: this, selector: 'button' }, function (element) { - this.$wysiwygEditorButton = this.$wysiwygEditorButton ? - this.$wysiwygEditorButton.add($(element)) : $(element); + this.$wysiwygEditorButton = $(element); }.bind(this)); return this; @@ -89,21 +90,30 @@ define([ /** * Set disabled property to wysiwyg component * - * @param {Boolean} status + * @param {Boolean} disabled */ - setDisabled: function (status) { - this.$wysiwygEditorButton.attr('disabled', status); + setDisabled: function (disabled) { + if (this.$wysiwygEditorButton && disabled) { + this.$wysiwygEditorButton.prop('disabled', 'disabled'); + } else if (this.$wysiwygEditorButton) { + this.$wysiwygEditorButton.removeProp('disabled'); + } /* eslint-disable no-undef */ - if (wysiwygAdapter && wysiwygAdapter.activeEditor()) { - _.each(wysiwygAdapter.activeEditor().controlManager.controls, function (property, index, controls) { - controls[property.id].setDisabled(status); + if (typeof wysiwyg !== 'undefined' && wysiwyg.activeEditor()) { + + _.each(wysiwyg.activeEditor().controlManager.controls, function (property, index, controls) { + controls[property.id].setDisabled(disabled); }); - wysiwygAdapter.activeEditor().getBody().setAttribute('contenteditable', !status); + if (wysiwyg && disabled) { + wysiwyg.setEnabledStatus(false); + wysiwyg.getPluginButtons().prop('disabled', 'disabled'); + } else if (wysiwyg) { + wysiwyg.setEnabledStatus(true); + wysiwyg.getPluginButtons().removeProp('disabled'); + } } - - /* eslint-enable no-undef*/ } }); }); 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 c7fb51f813ba0..01a1575541408 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).text().length >= param; + return _.isUndefined(value) || value.length === 0 || utils.stripHtml(value).length >= param; }, $.mage.__('Please enter at least {0} characters') ], @@ -360,7 +360,7 @@ define([ ], 'pattern': [ function (value, param) { - return param.test(value); + return new RegExp(param).test(value); }, $.mage.__('Invalid format.') ], diff --git a/app/code/Magento/User/Model/ResourceModel/User.php b/app/code/Magento/User/Model/ResourceModel/User.php index 880dec93fc91b..b3e4936266a3f 100644 --- a/app/code/Magento/User/Model/ResourceModel/User.php +++ b/app/code/Magento/User/Model/ResourceModel/User.php @@ -222,7 +222,7 @@ protected function _createUserRole($parentId, ModelUser $user) 'role_type' => RoleUser::ROLE_TYPE, 'user_id' => $user->getId(), 'user_type' => UserContextInterface::USER_TYPE_ADMIN, - 'role_name' => $user->getFirstname(), + 'role_name' => $user->getFirstName(), ] ); diff --git a/app/code/Magento/User/Model/User.php b/app/code/Magento/User/Model/User.php index b1b655dddd0a3..2a7d43008f2ad 100644 --- a/app/code/Magento/User/Model/User.php +++ b/app/code/Magento/User/Model/User.php @@ -467,7 +467,7 @@ protected function createChangesDescriptionString() $changes[] = __('password'); } - if ($this->getUsername() != $this->getOrigData('username') && $this->getOrigData('username')) { + if ($this->getUserName() != $this->getOrigData('username') && $this->getOrigData('username')) { $changes[] = __('username'); } @@ -515,7 +515,7 @@ protected function sendUserNotificationEmail($changes, $email = null) */ public function getName($separator = ' ') { - return $this->getFirstname() . $separator . $this->getLastname(); + return $this->getFirstName() . $separator . $this->getLastName(); } /** @@ -547,7 +547,7 @@ public function authenticate($username, $password) ['username' => $username, 'user' => $this] ); $this->loadByUsername($username); - $sensitive = $config ? $username == $this->getUsername() : true; + $sensitive = $config ? $username == $this->getUserName() : true; if ($sensitive && $this->getId()) { $result = $this->verifyIdentity($password); } diff --git a/app/code/Magento/User/Test/Unit/Model/UserTest.php b/app/code/Magento/User/Test/Unit/Model/UserTest.php index 847b6b34d3501..1d63d1aed3e1a 100644 --- a/app/code/Magento/User/Test/Unit/Model/UserTest.php +++ b/app/code/Magento/User/Test/Unit/Model/UserTest.php @@ -183,11 +183,11 @@ public function testSendNotificationEmailsIfRequired() $this->model->setPassword($password); $this->model->setOrigData('password', $origPassword); - $this->model->setUsername($username); + $this->model->setUserName($username); $this->model->setOrigData('username', $origUsername); - $this->model->setFirstname($firstName); - $this->model->setLastname($lastName); + $this->model->setFirstName($firstName); + $this->model->setLastName($lastName); $this->configMock->expects($this->exactly(4)) ->method('getValue') @@ -255,8 +255,8 @@ public function testSendPasswordResetConfirmationEmail() $lastName = 'Bar'; $this->model->setEmail($email); - $this->model->setFirstname($firstName); - $this->model->setLastname($lastName); + $this->model->setFirstName($firstName); + $this->model->setLastName($lastName); $this->configMock->expects($this->at(0)) ->method('getValue') diff --git a/app/code/Magento/Variable/Block/System/Variable/Edit.php b/app/code/Magento/Variable/Block/System/Variable/Edit.php index be68814ea27e2..ea119b88fa795 100644 --- a/app/code/Magento/Variable/Block/System/Variable/Edit.php +++ b/app/code/Magento/Variable/Block/System/Variable/Edit.php @@ -90,11 +90,7 @@ protected function _preparelayout() */ public function getFormHtml() { - $formHtml = parent::getFormHtml(); - if (!$this->_storeManager->isSingleStoreMode() && $this->getVariable()->getId()) { - $formHtml = $formHtml; - } - return $formHtml; + return parent::getFormHtml(); } /** diff --git a/app/code/Magento/Webapi/Model/Soap/Fault.php b/app/code/Magento/Webapi/Model/Soap/Fault.php index ee9c194e7c55a..b8ddf4e47d451 100644 --- a/app/code/Magento/Webapi/Model/Soap/Fault.php +++ b/app/code/Magento/Webapi/Model/Soap/Fault.php @@ -355,7 +355,7 @@ protected function _getWrappedErrorsXml($wrappedErrors) $errorsXml = ''; foreach ($wrappedErrors as $error) { - $errorsXml .= $this->_generateErrorNodeXml($error); + $errorsXml .= $this->_generateErrorNodeXML($error); } if (!empty($errorsXml)) { $wrappedErrorsNode = self::NODE_DETAIL_WRAPPED_ERRORS; diff --git a/app/code/Magento/Widget/Model/Config/Converter.php b/app/code/Magento/Widget/Model/Config/Converter.php index 010c46da56950..40718a5a5db9c 100644 --- a/app/code/Magento/Widget/Model/Config/Converter.php +++ b/app/code/Magento/Widget/Model/Config/Converter.php @@ -222,7 +222,7 @@ protected function _convertDepends($source) { $depends = []; foreach ($source->childNodes as $childNode) { - if ($childNode->nodeName == '#text') { + if ($childNode->nodeName === '#text') { continue; } if ($childNode->nodeName !== 'parameter') { @@ -231,12 +231,23 @@ protected function _convertDepends($source) ); } $parameterAttributes = $childNode->attributes; - $depends[$parameterAttributes->getNamedItem( - 'name' - )->nodeValue] = [ - 'value' => $parameterAttributes->getNamedItem('value')->nodeValue, - ]; + $dependencyName = $parameterAttributes->getNamedItem('name')->nodeValue; + $dependencyValue = $parameterAttributes->getNamedItem('value')->nodeValue; + + if (!isset($depends[$dependencyName])) { + $depends[$dependencyName] = [ + 'value' => $dependencyValue, + ]; + + continue; + } else if (!isset($depends[$dependencyName]['values'])) { + $depends[$dependencyName]['values'] = [$depends[$dependencyName]['value']]; + unset($depends[$dependencyName]['value']); + } + + $depends[$dependencyName]['values'][] = $dependencyValue; } + return $depends; } diff --git a/app/code/Magento/Widget/Model/Template/Filter.php b/app/code/Magento/Widget/Model/Template/Filter.php index 7cd8276ffef3d..7c3e8e467e038 100644 --- a/app/code/Magento/Widget/Model/Template/Filter.php +++ b/app/code/Magento/Widget/Model/Template/Filter.php @@ -136,7 +136,7 @@ public function widgetDirective($construction) */ public function mediaDirective($construction) { - $params = $this->getParameters($construction[2]); + $params = $this->getParameters(html_entity_decode($construction[2], ENT_QUOTES)); return $this->_storeManager->getStore() ->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . $params['url']; } diff --git a/app/code/Magento/Widget/Model/Widget/Instance.php b/app/code/Magento/Widget/Model/Widget/Instance.php index 07a995e3f7734..f21609cb1ef5c 100644 --- a/app/code/Magento/Widget/Model/Widget/Instance.php +++ b/app/code/Magento/Widget/Model/Widget/Instance.php @@ -34,7 +34,12 @@ class Instance extends \Magento\Framework\Model\AbstractModel const PRODUCT_LAYOUT_HANDLE = 'catalog_product_view'; - const SINGLE_PRODUCT_LAYOUT_HANLDE = 'catalog_product_view_id_{{ID}}'; + /** + * @deprecated see self::SINGLE_PRODUCT_LAYOUT_HANDLE + */ + const SINGLE_PRODUCT_LAYOUT_HANLDE = self::SINGLE_PRODUCT_LAYOUT_HANDLE; + + const SINGLE_PRODUCT_LAYOUT_HANDLE = 'catalog_product_view_id_{{ID}}'; const PRODUCT_TYPE_LAYOUT_HANDLE = 'catalog_product_view_type_{{TYPE}}'; @@ -188,12 +193,12 @@ protected function _construct() $this->_specificEntitiesLayoutHandles = [ 'anchor_categories' => self::SINGLE_CATEGORY_LAYOUT_HANDLE, 'notanchor_categories' => self::SINGLE_CATEGORY_LAYOUT_HANDLE, - 'all_products' => self::SINGLE_PRODUCT_LAYOUT_HANLDE, + 'all_products' => self::SINGLE_PRODUCT_LAYOUT_HANDLE, ]; foreach (array_keys($this->_productType->getTypes()) as $typeId) { $layoutHandle = str_replace('{{TYPE}}', $typeId, self::PRODUCT_TYPE_LAYOUT_HANDLE); $this->_layoutHandles[$typeId . '_products'] = $layoutHandle; - $this->_specificEntitiesLayoutHandles[$typeId . '_products'] = self::SINGLE_PRODUCT_LAYOUT_HANLDE; + $this->_specificEntitiesLayoutHandles[$typeId . '_products'] = self::SINGLE_PRODUCT_LAYOUT_HANDLE; } } diff --git a/app/code/Magento/Widget/Test/Unit/Model/Config/FileResolverTest.php b/app/code/Magento/Widget/Test/Unit/Model/Config/FileResolverTest.php index 65e45b73d88eb..301869a50a713 100644 --- a/app/code/Magento/Widget/Test/Unit/Model/Config/FileResolverTest.php +++ b/app/code/Magento/Widget/Test/Unit/Model/Config/FileResolverTest.php @@ -41,7 +41,7 @@ protected function setUp() public function testGetGlobal() { - $expected = new \StdClass(); + $expected = new \stdClass(); $this->moduleReader ->expects($this->once()) ->method('getConfigurationFiles') @@ -52,7 +52,7 @@ public function testGetGlobal() public function testGetDesign() { - $expected = new \StdClass(); + $expected = new \stdClass(); $this->componentDirSearch->expects($this->once()) ->method('collectFiles') ->with(ComponentRegistrar::THEME, 'etc/file') @@ -63,7 +63,7 @@ public function testGetDesign() public function testGetDefault() { - $expected = new \StdClass(); + $expected = new \stdClass(); $this->factory->expects($this->once())->method('create')->with([])->willReturn($expected); $this->assertSame($expected, $this->object->get('file', 'unknown')); } diff --git a/app/code/Magento/Widget/Test/Unit/Model/Template/FilterTest.php b/app/code/Magento/Widget/Test/Unit/Model/Template/FilterTest.php index a7fccf0bc14ca..db2f468da663c 100644 --- a/app/code/Magento/Widget/Test/Unit/Model/Template/FilterTest.php +++ b/app/code/Magento/Widget/Test/Unit/Model/Template/FilterTest.php @@ -270,4 +270,22 @@ public function testMediaDirective() $result = $this->filter->mediaDirective($construction); $this->assertEquals($baseUrl . $image, $result); } + + public function testMediaDirectiveWithEncodedQuotes() + { + $image = 'wysiwyg/VB.png'; + $construction = ['{{media url="' . $image . '"}}', 'media', ' url="' . $image . '"']; + $baseUrl = 'http://localhost/pub/media/'; + + $this->storeMock->expects($this->once()) + ->method('getBaseUrl') + ->with(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) + ->willReturn($baseUrl); + $this->storeManagerMock->expects($this->once()) + ->method('getStore') + ->willReturn($this->storeMock); + + $result = $this->filter->mediaDirective($construction); + $this->assertEquals($baseUrl . $image, $result); + } } diff --git a/app/code/Magento/Widget/etc/widget.xsd b/app/code/Magento/Widget/etc/widget.xsd index caaeec8ac4b84..70c9ec8e3514f 100644 --- a/app/code/Magento/Widget/etc/widget.xsd +++ b/app/code/Magento/Widget/etc/widget.xsd @@ -212,8 +212,8 @@ List of parameters this parameter depends on. - + - + diff --git a/app/code/Magento/Widget/etc/widget_file.xsd b/app/code/Magento/Widget/etc/widget_file.xsd index 6ebf7a201212e..afdd506f3ba24 100644 --- a/app/code/Magento/Widget/etc/widget_file.xsd +++ b/app/code/Magento/Widget/etc/widget_file.xsd @@ -212,8 +212,8 @@ List of parameters this parameter depends on. - + - + diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions-bar/_store-switcher.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions-bar/_store-switcher.less index 2ae0f3d2430bb..80bebb22a9043 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions-bar/_store-switcher.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions-bar/_store-switcher.less @@ -42,6 +42,14 @@ max-height: 250px; overflow-y: auto; padding-top: .25em; + &::-webkit-scrollbar { + -webkit-appearance: none; + width: 7px; + } + &::-webkit-scrollbar-thumb { + border-radius: 4px; + background-color: rgba(0, 0, 0, .5); + } li { border: 0; diff --git a/app/design/adminhtml/Magento/backend/Magento_ConfigurableProduct/web/css/source/module/components/_currency-addon.less b/app/design/adminhtml/Magento/backend/Magento_ConfigurableProduct/web/css/source/module/components/_currency-addon.less index 0c33b8d3b8a02..1e5d03d6f25c2 100644 --- a/app/design/adminhtml/Magento/backend/Magento_ConfigurableProduct/web/css/source/module/components/_currency-addon.less +++ b/app/design/adminhtml/Magento/backend/Magento_ConfigurableProduct/web/css/source/module/components/_currency-addon.less @@ -10,7 +10,8 @@ @currency-addon-symbol__border-color: @field-control__border-color; @currency-addon-symbol__color: @color-gray52; @currency-addon-symbol__height: @field-control__height; -@currency-addon-symbol__width: 1.6rem; +@currency-addon-symbol__width: 2.6rem; + // // Common diff --git a/app/design/adminhtml/Magento/backend/Magento_Marketplace/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_Marketplace/web/css/source/_module.less index 6afe96c7f9ef8..d4f918567e579 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Marketplace/web/css/source/_module.less +++ b/app/design/adminhtml/Magento/backend/Magento_Marketplace/web/css/source/_module.less @@ -61,7 +61,7 @@ } .partners-footer { - .magento-connect-logo { + .magento-marketplace-logo { float: right; margin-bottom: 1px; } diff --git a/app/design/frontend/Magento/blank/etc/view.xml b/app/design/frontend/Magento/blank/etc/view.xml index c0c40250158c0..8264e3111de88 100644 --- a/app/design/frontend/Magento/blank/etc/view.xml +++ b/app/design/frontend/Magento/blank/etc/view.xml @@ -12,9 +12,9 @@ 140 140 - - 152 - 188 + + 240 + 300 110 diff --git a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_toolbar.less b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_toolbar.less index 5c51938b23422..580abf264cadc 100644 --- a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_toolbar.less +++ b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_toolbar.less @@ -44,7 +44,6 @@ line-height: @toolbar-mode-icon-font-size + 2; margin: 0; padding: 7px 0; - position: absolute; text-align: left; top: 0; vertical-align: middle; diff --git a/app/design/frontend/Magento/luma/Magento_Newsletter/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Newsletter/web/css/source/_module.less index 94d7c7e4e5bff..9ccd6c190ec0e 100644 --- a/app/design/frontend/Magento/luma/Magento_Newsletter/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Newsletter/web/css/source/_module.less @@ -67,6 +67,7 @@ border-bottom-left-radius: 0; border-top-left-radius: 0; margin-left: -1px; + white-space: nowrap; } } } diff --git a/app/design/frontend/Magento/luma/etc/view.xml b/app/design/frontend/Magento/luma/etc/view.xml index f688c232b93c9..349224a34022c 100644 --- a/app/design/frontend/Magento/luma/etc/view.xml +++ b/app/design/frontend/Magento/luma/etc/view.xml @@ -12,9 +12,9 @@ 140 140 - - 200 - 248 + + 240 + 300 165 diff --git a/dev/tests/acceptance/tests/_suite/sampleSuite.xml b/dev/tests/acceptance/tests/_suite/sampleSuite.xml index d42f6d00132b9..372dc19b13663 100644 --- a/dev/tests/acceptance/tests/_suite/sampleSuite.xml +++ b/dev/tests/acceptance/tests/_suite/sampleSuite.xml @@ -6,13 +6,33 @@ */ --> + + + + + + + + + + + + + + + + + + + + - - + + @@ -20,7 +40,7 @@ - + @@ -35,9 +55,9 @@ - - - + + + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/Test/AdminConfigurationBlankIndustryCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/Test/AdminConfigurationBlankIndustryCest.xml index 359b6a54a52f7..6f2f7b5782342 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/Test/AdminConfigurationBlankIndustryCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/Test/AdminConfigurationBlankIndustryCest.xml @@ -16,6 +16,7 @@ + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/Test/AdminConfigurationTimeToSendDataCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/Test/AdminConfigurationTimeToSendDataCest.xml index 30fb9d3ce1db8..bde91098fcf1a 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/Test/AdminConfigurationTimeToSendDataCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Analytics/Test/AdminConfigurationTimeToSendDataCest.xml @@ -17,6 +17,8 @@ + + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/SortByIdDescendingActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/SortByIdDescendingActionGroup.xml new file mode 100644 index 0000000000000..5c130df74b66c --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Backend/ActionGroup/SortByIdDescendingActionGroup.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontProductActionSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontProductActionSection.xml new file mode 100644 index 0000000000000..976bd2adac217 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontProductActionSection.xml @@ -0,0 +1,13 @@ + + + +
    + +
    +
    diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontProductInfoMainSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontProductInfoMainSection.xml index 00074afebf7f4..1f0c0721b6452 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontProductInfoMainSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontProductInfoMainSection.xml @@ -9,6 +9,7 @@
    + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageToWYSIWYGCatalogCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageToWYSIWYGCatalogCest.xml index db132158d0255..62adf4573999b 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageToWYSIWYGCatalogCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageToWYSIWYGCatalogCest.xml @@ -14,9 +14,9 @@ - - - + + + <description value="Admin should be able to add image to WYSIWYG Editor on Catalog Page"/> <severity value="CRITICAL"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageToWYSIWYGProductCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageToWYSIWYGProductCest.xml index 3868909a24b4b..aaa3f95d8775b 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageToWYSIWYGProductCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminAddImageToWYSIWYGProductCest.xml @@ -9,14 +9,13 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AddImageToWYSIWYGProductEditor"> <annotations> - <features value="Add Image to WYSIWYG on Product Page"/> - <stories value="Default WYSIWYG toolbar configuration with Magento Media Gallery-MAGETWO-42041"/> - <group value="addImageProduct"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-42041-Default WYSIWYG toolbar configuration with Magento Media Gallery"/> + <group value="Catalog"/> <title value="Admin should be able to add image to WYSIWYG Editor on Product Page"/> <description value="Admin should be able to add image to WYSIWYG Editor on Product Page"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-84375"/> - <group value="skip"/> </annotations> <before> <actionGroup ref="LoginActionGroup" stepKey="login"/> @@ -29,6 +28,7 @@ <fillField userInput="{{_defaultProduct.price}}" selector="{{AdminProductFormSection.productPrice}}" stepKey="fillPrice"/> <fillField userInput="{{_defaultProduct.sku}}" selector="{{AdminProductFormSection.productSku}}" stepKey="fillSKU"/> <fillField userInput="{{_defaultProduct.quantity}}" selector="{{AdminProductFormSection.productQuantity}}" stepKey="fillQuantity"/> + <scrollTo selector="{{AdminProductFormSection.productQuantity}}" stepKey="scrollToQty" /> <click selector="{{AdminProductFormSection.contentTab}}" stepKey="clickContentTab" /> <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.TinyMCE4}}" stepKey="waitForDescription" /> <click selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertImageIcon}}" stepKey="clickInsertImageIcon1" /> @@ -69,7 +69,7 @@ <fillField selector="{{ProductDescriptionWYSIWYGToolbarSection.Height}}" userInput="{{ImageUpload.height}}" stepKey="fillImageHeight1" /> <click selector="{{ProductDescriptionWYSIWYGToolbarSection.OkBtn}}" stepKey="clickOkBtn1" /> <waitForPageLoad stepKey="waitForPageLoad3"/> - + <scrollTo selector="{{ProductDescriptionWYSIWYGToolbarSection.TinyMCE4}}" stepKey="scrollToTinyMCE4" /> <click selector="{{ProductShortDescriptionWYSIWYGToolbarSection.InsertImageIcon}}" stepKey="clickInsertImageIcon2" /> <waitForPageLoad stepKey="waitForPageLoad4" /> <click selector="{{ProductShortDescriptionWYSIWYGToolbarSection.Browse}}" stepKey="clickBrowse2" /> @@ -99,6 +99,7 @@ <click selector="{{ProductShortDescriptionWYSIWYGToolbarSection.OkBtn}}" stepKey="clickOkBtn2" /> <waitForPageLoad stepKey="waitForPageLoad6"/> <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoading13" /> <amOnPage url="{{_defaultProduct.name}}.html" stepKey="navigateToProductPage"/> <waitForPageLoad stepKey="waitForPageLoad2"/> <seeElement selector="{{StorefrontProductInfoMainSection.mediaDescription}}" stepKey="assertMediaDescription"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminEditTextEditorProductAttributeCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminEditTextEditorProductAttributeCest.xml index 9b91f5a923f60..add104ad8a50b 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminEditTextEditorProductAttributeCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/AdminEditTextEditorProductAttributeCest.xml @@ -9,9 +9,9 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="EditTextEditorProductAttributeCest"> <annotations> - <features value="TinyMCEv4"/> - <stories value="Input type configuration for custom Product Attributes-MAGETWO-51484"/> - <group value="editProductAttribute"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-51484-Input type configuration for custom Product Attributes"/> + <group value="Catalog"/> <title value="Admin see TinyMCEv4.6 is native WYSIWYG on Product Page"/> <description value="Admin should be able to switch between 2 version of Tinymce in the admin back-end."/> <severity value="CRITICAL"/> @@ -46,6 +46,7 @@ <dontSeeElement selector="{{ProductAttributeWYSIWYGSection.TinyMCE4($$myProductAttributeCreation.attribute_code$$)}}" stepKey="dontSeeTinyMCE4" /> <fillField selector="{{ProductAttributeWYSIWYGSection.TextArea($$myProductAttributeCreation.attribute_code$$)}}" userInput="Text Area" stepKey="fillContentTextarea" /> <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoading1"/> <!-- Go to storefront product page, assert product content --> <amOnPage url="{{_defaultProduct.name}}.html" stepKey="navigateToProductPage"/> <waitForPageLoad stepKey="waitForPageLoad5"/> @@ -64,10 +65,12 @@ <waitForPageLoad stepKey="waitForPageLoad8"/> <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="amOnProductGrid" /> <waitForPageLoad stepKey="waitForPageLoad9"/> + <actionGroup ref="SortByIdDescendingActionGroup" stepKey="sortByIdDescending" /> <click selector="{{AdminProductGridActionSection.productName(_defaultProduct.name)}}" stepKey="navigateToEditProduct" /> <waitForPageLoad stepKey="waitForPageLoad10" /> <seeElement selector="{{ProductAttributeWYSIWYGSection.TinyMCE4($$myProductAttributeCreation.attribute_code$$)}}" stepKey="waitForPageLoad11"/> <after> + <deleteData createDataKey="myProductAttributeCreation" stepKey="deletePreReqProductAttribute" /> <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> <actionGroup ref="logout" stepKey="logout"/> </after> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyDefaultWYSIWYGToolbarOnProducCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyDefaultWYSIWYGToolbarOnProductCest.xml similarity index 94% rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyDefaultWYSIWYGToolbarOnProducCest.xml rename to dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyDefaultWYSIWYGToolbarOnProductCest.xml index bf8c55ae76357..07af48562d3b9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyDefaultWYSIWYGToolbarOnProducCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyDefaultWYSIWYGToolbarOnProductCest.xml @@ -10,9 +10,9 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="Verifydefaultcontrolsonproductdescription"> <annotations> - <features value="Default WYSIWYG toolbar configuration in Magento"/> - <stories value="Default toolbar configuration in Magento-MAGETWO-70412"/> - <group value="WYSIWYG"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-70412-Default toolbar configuration in Magento"/> + <group value="Catalog"/> <title value="You should be able to see default toolbar display on Description content area"/> <description value="You should be able to see default toolbar display on Description content area"/> <severity value="CRITICAL"/> @@ -25,6 +25,7 @@ </before> <amOnPage url="{{AdminProductEditPage(simple)}}" stepKey="navigateToProduct"/> <waitForPageLoad stepKey="wait"/> + <scrollTo selector="{{AdminProductFormSection.productQuantity}}" stepKey="scrollToQty" /> <click selector="{{AdminProductFormSection.contentTab}}" stepKey="clickContentTab" /> <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.TinyMCE4}}" stepKey="waitforTinyMCE4Visible1"/> <seeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.TinyMCE4}}" stepKey="TinyMCE4Description" /> @@ -63,6 +64,7 @@ </before> <amOnPage url="{{AdminProductEditPage(simple)}}" stepKey="navigateToProduct"/> <waitForPageLoad stepKey="wait"/> + <scrollTo selector="{{AdminProductFormSection.productQuantity}}" stepKey="scrollToQty" /> <click selector="{{AdminProductFormSection.contentTab}}" stepKey="clickContentTab" /> <waitForElementVisible selector="{{ProductShortDescriptionWYSIWYGToolbarSection.TinyMCE4}}" stepKey="waitforTinyMCE4Visible2"/> <seeElement selector="{{ProductShortDescriptionWYSIWYGToolbarSection.TinyMCE4}}" stepKey="TinyMCE4ShortDescription" /> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCatalogCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCatalogCest.xml index be281d02c29d3..4aa6be2c41595 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCatalogCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCatalogCest.xml @@ -10,9 +10,9 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="DefaultTinyMCEv4onCatalogPage"> <annotations> - <features value="TinyMCEv4"/> - <stories value="Apply new WYSIWYG on Categories Page-MAGETWO-72137"/> - <group value="WYSIWYG"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-72137-Apply new WYSIWYG on Categories Page"/> + <group value="Catalog"/> <title value="Admin see TinyMCEv4.6 is native WYSIWYG on Catalog Page"/> <description value="Admin see TinyMCEv4.6 is native WYSIWYG on Catalog Page"/> <severity value="CRITICAL"/> @@ -31,30 +31,18 @@ <click selector="{{AdminProductFormSection.contentTab}}" stepKey="clickContentTab"/> <waitForElementVisible selector="{{CatalogWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE4" /> <seeElement selector="{{CatalogWYSIWYGSection.ShowHideBtn}}" stepKey="seeShowHideBtn" /> - <seeElement selector="{{CatalogWYSIWYGSection.TinyMCE4}}" stepKey="TinyMCE4" /> - <seeElement selector="{{CatalogWYSIWYGSection.Style}}" stepKey="assertInfo2"/> - <seeElement selector="{{CatalogWYSIWYGSection.Bold}}" stepKey="assertInfo3"/> - <seeElement selector="{{CatalogWYSIWYGSection.Italic}}" stepKey="assertInfo4"/> - <seeElement selector="{{CatalogWYSIWYGSection.Underline}}" stepKey="assertInfo5"/> - <seeElement selector="{{CatalogWYSIWYGSection.AlignLeft}}" stepKey="assertInfo6"/> - <seeElement selector="{{CatalogWYSIWYGSection.AlignCenter}}" stepKey="assertInfo7"/> - <seeElement selector="{{CatalogWYSIWYGSection.AlignRight}}" stepKey="assertInfo8"/> - <seeElement selector="{{CatalogWYSIWYGSection.Numlist}}" stepKey="assertInfo9"/> - <seeElement selector="{{CatalogWYSIWYGSection.Bullet}}" stepKey="assertInfo10"/> - <seeElement selector="{{CatalogWYSIWYGSection.InsertLink}}" stepKey="assertInfo11"/> - <seeElement selector="{{CatalogWYSIWYGSection.InsertImage}}" stepKey="assertInf12"/> - <seeElement selector="{{CatalogWYSIWYGSection.InsertTable}}" stepKey="assertInfo13"/> - <seeElement selector="{{CatalogWYSIWYGSection.SpecialCharacter}}" stepKey="assertInfo14"/> + <actionGroup ref="VerifyTinyMCEActionGroup" stepKey="verifyTinyMCE4"/> <executeJS function="tinyMCE.get('category_form_description').setContent('Hello World!');" stepKey="executeJSFillContent"/> <click selector="{{CatalogWYSIWYGSection.ShowHideBtn}}" stepKey="clickShowHideBtn" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.InsertImageBtn}}" stepKey="waitForInsertImage" /> - <seeElement selector="{{CmsWYSIWYGSection.InsertImageBtn}}" stepKey="insertImage"/> - <dontSee selector="{{CmsWYSIWYGSection.InsertWidgetBtn}}" stepKey="insertWidget" /> - <dontSee selector="{{CmsWYSIWYGSection.InsertVariableBtn}}" stepKey="insertVariable" /> + <waitForElementVisible selector="{{TinyMCESection.InsertImageBtn}}" stepKey="waitForInsertImage" /> + <seeElement selector="{{TinyMCESection.InsertImageBtn}}" stepKey="insertImage"/> + <dontSee selector="{{TinyMCESection.InsertWidgetBtn}}" stepKey="insertWidget" /> + <dontSee selector="{{TinyMCESection.InsertVariableBtn}}" stepKey="insertVariable" /> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCatalog"/> <!-- Go to storefront product page, assert product content --> <amOnPage url="/{{SimpleSubCategory.name_lwr}}.html" stepKey="goToCategoryFrontPage"/> <waitForPageLoad stepKey="waitForPageLoad2"/> + <waitForElementVisible selector="{{StorefrontCategoryMainSection.CatalogDescription}}" stepKey="waitForDesVisible" /> <see userInput="Hello World!" selector="{{StorefrontCategoryMainSection.CatalogDescription}}" stepKey="assertCatalogDescription"/> <after> <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnProductCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnProductCest.xml index 0a2fb2ee041dc..a8641640432f2 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnProductCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnProductCest.xml @@ -9,9 +9,9 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="DefaultTinyMCEv4onProductPage"> <annotations> - <features value="TinyMCEv4"/> - <stories value="TinyMCE v4.6 as a native WYSIWYG editor extension-MAGETWO-72114"/> - <group value="WYSIWYG"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-72114-TinyMCE v4.6 as a native WYSIWYG editor"/> + <group value="Catalog"/> <title value="Admin see TinyMCEv4.6 is native WYSIWYG on Product Page"/> <description value="Admin should be able to switch between 2 version of Tinymce in the admin back-end."/> <severity value="CRITICAL"/> @@ -28,6 +28,7 @@ <fillField userInput="{{_defaultProduct.price}}" selector="{{AdminProductFormSection.productPrice}}" stepKey="fillPrice"/> <fillField userInput="{{_defaultProduct.sku}}" selector="{{AdminProductFormSection.productSku}}" stepKey="fillSKU"/> <fillField userInput="{{_defaultProduct.quantity}}" selector="{{AdminProductFormSection.productQuantity}}" stepKey="fillQuantity"/> + <scrollTo selector="{{AdminProductFormSection.productQuantity}}" stepKey="scrollToQty" /> <click selector="{{AdminProductFormSection.contentTab}}" stepKey="clickContentTab" /> <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.TinyMCE4}}" stepKey="waitForDescription" /> <seeElement selector="{{ProductDescriptionWYSIWYGToolbarSection.TinyMCE4}}" stepKey="TinyMCE4Description" /> @@ -38,17 +39,19 @@ <click selector="{{ProductDescriptionWYSIWYGToolbarSection.showHideBtn}}" stepKey="clickShowHideBtn1" /> <waitForElementVisible selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertImageBtn}}" stepKey="waitForInsertImage1" /> <see selector="{{ProductDescriptionWYSIWYGToolbarSection.InsertImageBtn}}" userInput="Insert Image..." stepKey="seeInsertImage1"/> - <dontSee selector="{{CmsWYSIWYGSection.InsertWidgetBtn}}" stepKey="insertWidget1" /> - <dontSee selector="{{CmsWYSIWYGSection.InsertVariableBtn}}" stepKey="insertVariable1" /> + <dontSee selector="{{TinyMCESection.InsertWidgetBtn}}" stepKey="insertWidget1" /> + <dontSee selector="{{TinyMCESection.InsertVariableBtn}}" stepKey="insertVariable1" /> + <scrollTo selector="{{ProductDescriptionWYSIWYGToolbarSection.showHideBtn}}" stepKey="scrollToDesShowHideBtn" /> <click selector="{{ProductShortDescriptionWYSIWYGToolbarSection.showHideBtn}}" stepKey="clickShowHideBtn2" /> <waitForElementVisible selector="{{ProductShortDescriptionWYSIWYGToolbarSection.InsertImageBtn}}" stepKey="waitForInsertImage2" /> <see selector="{{ProductShortDescriptionWYSIWYGToolbarSection.InsertImageBtn}}" userInput="Insert Image..." stepKey="seeInsertImage2"/> - <dontSee selector="{{CmsWYSIWYGSection.InsertWidgetBtn}}" stepKey="insertWidget2" /> - <dontSee selector="{{CmsWYSIWYGSection.InsertVariableBtn}}" stepKey="insertVariable2" /> + <dontSee selector="{{TinyMCESection.InsertWidgetBtn}}" stepKey="insertWidget2" /> + <dontSee selector="{{TinyMCESection.InsertVariableBtn}}" stepKey="insertVariable2" /> <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct"/> <!-- Go to storefront product page, assert product content --> <amOnPage url="{{_defaultProduct.name}}.html" stepKey="navigateToProductPage"/> <waitForPageLoad stepKey="waitForPageLoad2"/> + <scrollTo selector="{{StorefrontProductInfoMainSection.stock}}" stepKey="scrollToStock"/> <see userInput="Hello World!" selector="{{StorefrontProductInfoMainSection.productDescription}}" stepKey="assertProductDescription"/> <see userInput="Hello World! Short Content" selector="{{StorefrontProductInfoMainSection.productShortDescription}}" stepKey="assertProductShortDescription"/> <after> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/Data/CatalogRuleData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/Data/CatalogRuleData.xml new file mode 100644 index 0000000000000..bf750bc3c9944 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/Data/CatalogRuleData.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="_defaultCatalogRule" type="catalogRule"> + <data key="name" unique="suffix">CatalogPriceRule</data> + <data key="description">Catalog Price Rule Description</data> + <data key="is_active">1</data> + <array key="customer_group_ids"> + <item>0</item> + </array> + <array key="website_ids"> + <item>1</item> + </array> + <data key="simple_action">by_percent</data> + <data key="discount_amount">10</data> + </entity> +</entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/Metadata/catalog-rule-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/Metadata/catalog-rule-meta.xml new file mode 100644 index 0000000000000..e404e4471ba45 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/CatalogRule/Metadata/catalog-rule-meta.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> + <operation name="createCatalogRule" dataType="catalogRule" + type="create" auth="adminFormKey" url="/catalog_rule/promo_catalog/save/" method="POST"> + <contentType>application/x-www-form-urlencoded</contentType> + <field key="name">string</field> + <field key="description">string</field> + <field key="is_active">string</field> + <array key="customer_group_ids"> + <value>integer</value> + </array> + <array key="website_ids"> + <value>integer</value> + </array> + <field key="simple_action">string</field> + <field key="discount_amount">string</field> + </operation> +</operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/VerifyTinyMCEActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/VerifyTinyMCEActionGroup.xml new file mode 100644 index 0000000000000..f3c2f31270f33 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/VerifyTinyMCEActionGroup.xml @@ -0,0 +1,31 @@ +<?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="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="VerifyTinyMCEActionGroup"> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE" /> + <seeElement selector="{{TinyMCESection.TinyMCE4}}" stepKey="seeTinyMCE4" /> + <seeElement selector="{{TinyMCESection.Style}}" stepKey="assertInfo2"/> + <seeElement selector="{{TinyMCESection.Bold}}" stepKey="assertInfo3"/> + <seeElement selector="{{TinyMCESection.Italic}}" stepKey="assertInfo4"/> + <seeElement selector="{{TinyMCESection.Underline}}" stepKey="assertInfo5"/> + <seeElement selector="{{TinyMCESection.AlignLeft}}" stepKey="assertInfo6"/> + <seeElement selector="{{TinyMCESection.AlignCenter}}" stepKey="assertInfo7"/> + <seeElement selector="{{TinyMCESection.AlignRight}}" stepKey="assertInfo8"/> + <seeElement selector="{{TinyMCESection.Numlist}}" stepKey="assertInfo9"/> + <seeElement selector="{{TinyMCESection.Bullet}}" stepKey="assertInfo10"/> + <seeElement selector="{{TinyMCESection.InsertLink}}" stepKey="assertInfo11"/> + <seeElement selector="{{TinyMCESection.InsertImageIcon}}" stepKey="assertInf12"/> + <seeElement selector="{{TinyMCESection.InsertTable}}" stepKey="assertInfo13"/> + <seeElement selector="{{TinyMCESection.SpecialCharacter}}" stepKey="assertInfo14"/> + </actionGroup> + <actionGroup name="VerifyMagentoEntityActionGroup"> + <seeElement selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="assertInfo15"/> + <seeElement selector="{{TinyMCESection.InsertVariableIcon}}" stepKey="assertInfo16"/> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Metadata/block-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Metadata/block-meta.xml index ec874f5513a96..2cbae2b71a6ef 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Metadata/block-meta.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Metadata/block-meta.xml @@ -16,4 +16,8 @@ <field key="active">true</field> </object> </operation> + + <operation name="DeleteBlock" dataType="block" type="delete" auth="adminOauth" url="/V1/cmsBlock/{id}" method="DELETE"> + <contentType>application/json</contentType> + </operation> </operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Metadata/cms-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Metadata/cms-meta.xml index b55cb44b086cc..21ad5bc8d8752 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Metadata/cms-meta.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Metadata/cms-meta.xml @@ -17,7 +17,7 @@ <field key="content">string</field> </object> </operation> - <operation name="DeleteCMS" dataType="cms_page" type="delete" auth="adminOauth" url="/V1/cmsPage/{pageId}" method="DELETE"> + <operation name="DeleteCMS" dataType="cms_page" type="delete" auth="adminOauth" url="/V1/cmsPage/{id}" method="DELETE"> <contentType>application/json</contentType> </operation> </operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Page/CmsNewBlockPage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Page/CmsNewBlockPage.xml index 20332ee4cf073..5cccbf2943114 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Page/CmsNewBlockPage.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Page/CmsNewBlockPage.xml @@ -8,7 +8,7 @@ <pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> - <page name="CmsNewBlock" url="admin/cms/block/new" area="admin" module="Magento_Cms"> + <page name="CmsNewBlock" area="admin" url="/cms/block/new" module="Magento_Cms"> <section name="CmsNewBlockBlockActionsSection"/> <section name="CmsNewBlockBlockBasicFieldsSection"/> </page> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/BlockNewPageContentSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/BlockNewPageContentSection.xml index 4ad7b436405ab..1c42d3817d246 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/BlockNewPageContentSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/BlockNewPageContentSection.xml @@ -9,45 +9,6 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="BlockWYSIWYGSection"> - <element name="TinyMCE4" type="text" selector=".mce-branding-powered-by" /> - <element name="TinyMCE3" type="text" selector="#cms_page_form_content_tbl"/> <element name="ShowHideBtn" type="button" selector="#togglecms_block_form_content"/> - <element name="InsertWidgetBtn" type="button" selector=".scalable.action-add-widget.plugin"/> - <element name="InsertWidgetIcon" type="button" selector="div[aria-label='Insert Widget']"/> - <element name="InsertVariableBtn" type="button" selector=".scalable.add-variable.plugin"/> - <element name="InsertVariableIcon" type="button" selector="div[aria-label='Insert Variable']"/> - <element name="InsertImageBtn" type="button" selector=".scalable.action-add-image.plugin"/> - <element name="InsertImageIcon" type="button" selector=".mce-i-image"/> - <element name="Browse" type="button" selector=".mce-i-browse"/> - <element name="BrowseUploadImage" type="file" selector=".fileupload" /> - <element name="image" type="text" selector="//small[text()='{{var1}}']" parameterized="true"/> - <element name="ImageSource" type="input" selector=".mce-combobox.mce-abs-layout-item.mce-last.mce-has-open" /> - <element name="ImageDescription" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-last" /> - <element name="Height" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-first" /> - <element name="UploadImage" type="file" selector=".fileupload" /> - <element name="OkBtn" type="button" selector="//span[text()='Ok']"/> - <element name="InsertFile" type="text" selector="#insert_files"/> - <element name="CreateFolder" type="button" selector="#new_folder" /> - <element name="DeleteSelectedBtn" type="text" selector="#delete_files"/> - <element name="CancelBtn" type="button" selector="#cancel" /> - <element name="Style" type="button" selector=".mce-txt" /> - <element name="Bold" type="button" selector=".mce-i-bold" /> - <element name="Italic" type="button" selector=".mce-i-italic" /> - <element name="Underline" type="button" selector=".mce-i-underline" /> - <element name="AlignLeft" type="button" selector=".mce-i-alignleft" /> - <element name="AlignCenter" type="button" selector=".mce-i-aligncenter" /> - <element name="AlignRight" type="button" selector=".mce-i-alignright" /> - <element name="Bullet" type="button" selector=".mce-i-bullist" /> - <element name="Numlist" type="button" selector=".mce-i-numlist" /> - <element name="InsertLink" type="button" selector=".mce-i-link" /> - <element name="InsertImage" type="button" selector=".mce-i-image" /> - <element name="InsertTable" type="button" selector=".mce-i-table" /> - <element name="SpecialCharacter" type="button" selector=".mce-i-charmap" /> - <element name="FolderName" type="button" selector="input[data-role='promptField']" /> - <element name="AcceptFolderName" type="button" selector=".action-primary.action-accept" /> - <element name="StorageRootArrow" type="button" selector="#root > .jstree-icon" /> - <element name="checkIfArrowExpand" type="button" selector="//li[@id='root' and contains(@class,'jstree-closed')]" /> - <element name="imageSelected" type="text" selector="//small[text()='{{var1}}']/parent::*[@class='filecnt selected']" parameterized="true"/> - <element name="confirmDelete" type="button" selector=".action-primary.action-accept" /> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/CmsNewBlockBlockBasicFieldsSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/CmsNewBlockBlockBasicFieldsSection.xml index c7446d798d7d4..78d9dad4eedd6 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/CmsNewBlockBlockBasicFieldsSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/CmsNewBlockBlockBasicFieldsSection.xml @@ -11,6 +11,6 @@ <section name="CmsNewBlockBlockBasicFieldsSection"> <element name="title" type="input" selector="input[name=title]"/> <element name="identifier" type="input" selector="input[name=identifier]"/> - <element name="wysiwyg_hr_element" type="input" selector="#cms_block_form_content_hr"/> + <element name="content_textarea" type="input" selector="#cms_block_form_content"/> </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/CmsNewPagePageContentSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/CmsNewPagePageContentSection.xml index 998286460affc..addc466c4b026 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/CmsNewPagePageContentSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/CmsNewPagePageContentSection.xml @@ -15,98 +15,9 @@ </section> <section name="CmsWYSIWYGSection"> <element name="CheckIfTabExpand" type="button" selector="//div[@data-state-collapsible='closed']//span[text()='Content']"/> - <element name="TinyMCE4" type="text" selector=".mce-branding-powered-by" /> - <element name="TinyMCE3" type="text" selector="#cms_page_form_content_tbl"/> <element name="ShowHideBtn" type="button" selector="#togglecms_page_form_content"/> <element name="InsertWidgetBtn" type="button" selector=".action-add-widget"/> - <element name="InsertWidgetIcon" type="button" selector="div[aria-label='Insert Widget']"/> <element name="InsertVariableBtn" type="button" selector=".scalable.add-variable.plugin"/> - <element name="InsertVariableIcon" type="button" selector="div[aria-label='Insert Variable']"/> <element name="InsertImageBtn" type="button" selector=".scalable.action-add-image.plugin"/> - <element name="InsertImageIcon" type="button" selector=".mce-i-image"/> - <element name="Browse" type="button" selector=".mce-i-browse"/> - <element name="BrowseUploadImage" type="file" selector=".fileupload" /> - <element name="image" type="text" selector="//small[text()='{{var1}}']" parameterized="true"/> - <element name="imageSelected" type="text" selector="//small[text()='{{var1}}']/parent::*[@class='filecnt selected']" parameterized="true"/> - <element name="ImageSource" type="input" selector=".mce-combobox.mce-abs-layout-item.mce-last.mce-has-open" /> - <element name="ImageDescription" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-last" /> - <element name="Height" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-first" /> - <element name="UploadImage" type="file" selector=".fileupload" /> - <element name="OkBtn" type="button" selector="//span[text()='Ok']"/> - <element name="InsertFile" type="text" selector="#insert_files"/> - <element name="CreateFolder" type="button" selector="#new_folder" /> - <element name="DeleteSelectedBtn" type="text" selector="#delete_files"/> - <element name="CancelBtn" type="button" selector="#cancel" /> - <element name="Style" type="button" selector=".mce-txt" /> - <element name="Bold" type="button" selector=".mce-i-bold" /> - <element name="Italic" type="button" selector=".mce-i-italic" /> - <element name="Underline" type="button" selector=".mce-i-underline" /> - <element name="AlignLeft" type="button" selector=".mce-i-alignleft" /> - <element name="AlignCenter" type="button" selector=".mce-i-aligncenter" /> - <element name="AlignRight" type="button" selector=".mce-i-alignright" /> - <element name="Bullet" type="button" selector=".mce-i-bullist" /> - <element name="Numlist" type="button" selector=".mce-i-numlist" /> - <element name="InsertLink" type="button" selector=".mce-i-link" /> - <element name="InsertImage" type="button" selector=".mce-i-image" /> - <element name="InsertTable" type="button" selector=".mce-i-table" /> - <element name="SpecialCharacter" type="button" selector=".mce-i-charmap" /> - <element name="FolderName" type="button" selector="input[data-role='promptField']" /> - <element name="AcceptFolderName" type="button" selector=".action-primary.action-accept" /> - <element name="StorageRootArrow" type="button" selector="#root > .jstree-icon" /> - <element name="checkIfArrowExpand" type="button" selector="//li[@id='root' and contains(@class,'jstree-closed')]" /> - <element name="confirmDelete" type="button" selector=".action-primary.action-accept" /> - </section> - <section name="VariableSection"> - <element name="InsertWidget" type="button" selector="#insert_variable"/> - <element name="InsertVariableBtnEnabled" type="button" selector="//button[@id='insert_variable' and not(contains(@class,'disabled'))]"/> - <element name="InsertVariableBtnDisabled" type="button" selector="//button[@id='insert_variable' and contains(@class,'disabled')]"/> - <element name="CancelBtnEnabled" type="button" selector="//button[@class='action-scalable cancel' and not(contains(@class,'disabled'))]"/> - <element name="Close" type="button" selector="#close"/> - <element name="SearchTxtbox" type="input" selector="input[placeholder='Search by keyword']"/> - <element name="ColName" type="text" selector="//table[@class='data-grid data-grid-draggable']/thead/tr/th/span[text()='{{var1}}']" parameterized="true"/> - <element name="Radio" type="input" selector="//input[@type='radio' and contains(@value, '{{var1}}')]" parameterized="true"/> - <element name="VariableRadio" type="input" selector="//div[text()='{{var1}}']/parent::td//preceding-sibling::td/input[@type='radio']" parameterized="true"/> - <element name="VariableInAscSort" type="input" selector="#variable"/> - <element name="VariableInDescSort" type="input" selector="#variable"/> - <element name="Type" type="input" selector="#value"/> - <element name="Code" type="input" selector="#code"/> - <element name="searchResult" type="text" selector="//table/tbody/tr//td/div[text()='{{var1}}']" parameterized="true" /> - <element name="VariableTitle" type="text" selector="//h1[contains(text(), 'Insert Variable')]"/> - </section> - <section name="WidgetSection"> - <element name="InsertWidgetTitle" type="text" selector="//h1[contains(text(),'Insert Widget')]"/> - <element name="SelectCategoryTitle" type="text" selector="//h1[contains(text(),'Select Category')]"/> - <element name="SelectProductTitle" type="text" selector="//h1[contains(text(),'Select Product')]"/> - <element name="SelectPageTitle" type="text" selector="//h1[contains(text(),'Select Page')]"/> - <element name="SelectBlockTitle" type="text" selector="//h1[contains(text(),'Select Block')]"/> - <element name="InsertWidget" type="button" selector="#insert_button"/> - <element name="InsertWidgetBtnDisabled" type="button" selector="//button[@id='insert_button' and contains(@class,'disabled')]"/> - <element name="InsertWidgetBtnEnabled" type="button" selector="//button[@id='insert_button' and not(contains(@class,'disabled'))]"/> - <element name="CancelBtnEnabled" type="button" selector="//button[@id='reset' and not(contains(@class,'disabled'))]"/> - <element name="Close" type="button" selector="#close"/> - <element name="WidgetType" type="button" selector="#select_widget_type"/> - <element name="WidgetTemplate" type="button" selector="select[name='parameters[template]']"/> - <element name="BtnChooser" type="button" selector=".btn-chooser"/> - <element name="CMSPage" type="text" selector="//td[contains(text(),'Home page')]"/> - <element name="BlockPage" type="text" selector="//td[contains(text(),'{{var1}}')]" parameterized="true"/> - <element name="PreCreateCategory" type="text" selector=" //span[contains(text(),'{{var1}}')]" parameterized="true"/> - <element name="PreCreateProduct" type="text" selector="//td[contains(text(),'{{var1}}')]" parameterized="true"/> - <element name="NoOfProductToDisplay" type="input" selector="input[data-ui-id='wysiwyg-widget-options-fieldset-element-text-parameters-products-count']"/> - <element name="AddParam" type="button" selector=".rule-param-add"/> - <element name="ConditionsDropdown" type="select" selector="#conditions__1__new_child"/> - <element name="RuleParam" type="button" selector="//a[text()='...']"/> - <element name="Chooser" type="button" selector="//img[@title='Open Chooser']"/> - <element name="PageSize" type="input" selector="input[name='parameters[page_size]']"/> - <element name="ProductAttribute" type="multiselect" selector="select[name='parameters[show_attributes][]']" /> - <element name="ButtonToShow" type="multiselect" selector="select[name='parameters[show_buttons][]']"/> - <!--Widget on Storefront--> - <element name="CategoryWidget" type="text" selector="//a[@href='http://magento2.vagrant42/{{var1}}.html?___store=default']" parameterized="true"/> - <element name="CMSPageWidget" type="text" selector="//a[@href='http://magento2.vagrant42/home']"/> - <!--Compare on Storefront--> - <element name="ProductName" type="text" selector=".product.name.product-item-name" /> - <element name="CompareBtn" type="button" selector=".action.tocompare"/> - <element name="ClearCompare" type="button" selector="#compare-clear-all"/> - <element name="AcceptClear" type="button" selector=".action-primary.action-accept" /> - </section> </sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/CmsPagesPageActionsSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/CmsPagesPageActionsSection.xml index c845bbc02d3c5..5e6ca7a193613 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/CmsPagesPageActionsSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/CmsPagesPageActionsSection.xml @@ -9,6 +9,11 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="CmsPagesPageActionsSection"> + <element name="FilterBtn" type="input" selector="//button[text()='Filters']"/> + <element name="URLKey" type="input" selector="//div[@class='admin__form-field-control']/input[@name='identifier']"/> + <element name="ApplyFiltersBtn" type="button" selector="//span[text()='Apply Filters']"/> + <element name="searchBox" type="input" selector="//div[@class='admin__data-grid-actions-wrap']//following-sibling::div//input[@id='fulltext']"/> + <element name="searchBtn" type="button" selector="//div[@class='admin__data-grid-actions-wrap']//following-sibling::div//input[@id='fulltext']/following-sibling::button"/> <element name="addNewPage" type="button" selector="#add" timeout="30"/> <element name="select" type="button" selector="//div[text()='{{var1}}']/parent::td//following-sibling::td[@class='data-grid-actions-cell']//button[text()='Select']" parameterized="true"/> <element name="edit" type="button" selector="//div[text()='{{var1}}']/parent::td//following-sibling::td[@class='data-grid-actions-cell']//a[text()='Edit']" parameterized="true"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/TinyMCESection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/TinyMCESection.xml new file mode 100644 index 0000000000000..dbedf129c3757 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Section/TinyMCESection.xml @@ -0,0 +1,109 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="TinyMCESection"> + <element name="checkIfContentTabOpen" type="button" selector="//span[text()='Content']/parent::strong/parent::*[@data-state-collapsible='closed']"/> + <element name="CheckIfTabExpand" type="button" selector="//div[@data-state-collapsible='closed']//span[text()='Content']"/> + <element name="TinyMCE4" type="text" selector=".mce-branding-powered-by" /> + <element name="TinyMCE3" type="text" selector="#cms_page_form_content_tbl"/> + <element name="InsertWidgetBtn" type="button" selector=".action-add-widget"/> + <element name="InsertWidgetIcon" type="button" selector="div[aria-label='Insert Widget']"/> + <element name="InsertVariableBtn" type="button" selector=".scalable.add-variable.plugin"/> + <element name="InsertVariableIcon" type="button" selector="div[aria-label='Insert Variable']"/> + <element name="InsertImageBtn" type="button" selector=".scalable.action-add-image.plugin"/> + <element name="InsertImageIcon" type="button" selector=".mce-i-image"/> + <element name="Style" type="button" selector=".mce-txt" /> + <element name="Bold" type="button" selector=".mce-i-bold" /> + <element name="Italic" type="button" selector=".mce-i-italic" /> + <element name="Underline" type="button" selector=".mce-i-underline" /> + <element name="AlignLeft" type="button" selector=".mce-i-alignleft" /> + <element name="AlignCenter" type="button" selector=".mce-i-aligncenter" /> + <element name="AlignRight" type="button" selector=".mce-i-alignright" /> + <element name="Bullet" type="button" selector=".mce-i-bullist" /> + <element name="Numlist" type="button" selector=".mce-i-numlist" /> + <element name="InsertLink" type="button" selector=".mce-i-link" /> + <element name="InsertImage" type="button" selector=".mce-i-image" /> + <element name="InsertTable" type="button" selector=".mce-i-table" /> + <element name="SpecialCharacter" type="button" selector=".mce-i-charmap" /> + </section> + <section name="MediaGallerySection"> + <element name="Browse" type="button" selector=".mce-i-browse"/> + <element name="BrowseUploadImage" type="file" selector=".fileupload" /> + <element name="image" type="text" selector="//small[text()='{{var1}}']" parameterized="true"/> + <element name="imageSelected" type="text" selector="//small[text()='{{var1}}']/parent::*[@class='filecnt selected']" parameterized="true"/> + <element name="ImageSource" type="input" selector=".mce-combobox.mce-abs-layout-item.mce-last.mce-has-open" /> + <element name="ImageDescription" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-last" /> + <element name="Height" type="input" selector=".mce-textbox.mce-abs-layout-item.mce-first" /> + <element name="UploadImage" type="file" selector=".fileupload" /> + <element name="OkBtn" type="button" selector="//span[text()='Ok']"/> + <element name="InsertFile" type="text" selector="#insert_files"/> + <element name="CreateFolder" type="button" selector="#new_folder" /> + <element name="DeleteSelectedBtn" type="text" selector="#delete_files"/> + <element name="CancelBtn" type="button" selector="#cancel" /> + <element name="FolderName" type="button" selector="input[data-role='promptField']" /> + <element name="AcceptFolderName" type="button" selector=".action-primary.action-accept" /> + <element name="StorageRootArrow" type="button" selector="#root > .jstree-icon" /> + <element name="checkIfArrowExpand" type="button" selector="//li[@id='root' and contains(@class,'jstree-closed')]" /> + <element name="confirmDelete" type="button" selector=".action-primary.action-accept" /> + </section> + <section name="VariableSection"> + <element name="InsertWidget" type="button" selector="#insert_variable"/> + <element name="InsertVariableBtnEnabled" type="button" selector="//button[@id='insert_variable' and not(contains(@class,'disabled'))]"/> + <element name="InsertVariableBtnDisabled" type="button" selector="//button[@id='insert_variable' and contains(@class,'disabled')]"/> + <element name="CancelBtnEnabled" type="button" selector="//button[@class='action-scalable cancel' and not(contains(@class,'disabled'))]"/> + <element name="Close" type="button" selector="#close"/> + <element name="SearchTxtbox" type="input" selector="input[placeholder='Search by keyword']"/> + <element name="ColName" type="text" selector="//table[@class='data-grid data-grid-draggable']/thead/tr/th/span[text()='{{var1}}']" parameterized="true"/> + <element name="Radio" type="input" selector="//input[@type='radio' and contains(@value, '{{var1}}')]" parameterized="true"/> + <element name="VariableRadio" type="input" selector="//div[text()='{{var1}}']/parent::td//preceding-sibling::td/input[@type='radio']" parameterized="true"/> + <element name="VariableInAscSort" type="input" selector="#variable"/> + <element name="VariableInDescSort" type="input" selector="#variable"/> + <element name="Type" type="input" selector="#value"/> + <element name="Code" type="input" selector="#code"/> + <element name="searchResult" type="text" selector="//table/tbody/tr//td/div[text()='{{var1}}']" parameterized="true" /> + <element name="VariableTitle" type="text" selector="//h1[contains(text(), 'Insert Variable')]"/> + </section> + <section name="WidgetSection"> + <element name="InsertWidgetTitle" type="text" selector="//h1[contains(text(),'Insert Widget')]"/> + <element name="SelectCategoryTitle" type="text" selector="//h1[contains(text(),'Select Category')]"/> + <element name="SelectProductTitle" type="text" selector="//h1[contains(text(),'Select Product')]"/> + <element name="SelectPageTitle" type="text" selector="//h1[contains(text(),'Select Page')]"/> + <element name="SelectBlockTitle" type="text" selector="//h1[contains(text(),'Select Block')]"/> + <element name="InsertWidget" type="button" selector="#insert_button"/> + <element name="InsertWidgetBtnDisabled" type="button" selector="//button[@id='insert_button' and contains(@class,'disabled')]"/> + <element name="InsertWidgetBtnEnabled" type="button" selector="//button[@id='insert_button' and not(contains(@class,'disabled'))]"/> + <element name="CancelBtnEnabled" type="button" selector="//button[@id='reset' and not(contains(@class,'disabled'))]"/> + <element name="Close" type="button" selector="#close"/> + <element name="WidgetType" type="button" selector="#select_widget_type"/> + <element name="WidgetTemplate" type="button" selector="select[name='parameters[template]']"/> + <element name="BtnChooser" type="button" selector=".btn-chooser"/> + <element name="CMSPage" type="text" selector="//td[contains(text(),'Home page')]"/> + <element name="BlockPage" type="text" selector="//td[contains(text(),'{{var1}}')]" parameterized="true"/> + <element name="PreCreateCategory" type="text" selector=" //span[contains(text(),'{{var1}}')]" parameterized="true"/> + <element name="PreCreateProduct" type="text" selector="//td[contains(text(),'{{var1}}')]" parameterized="true"/> + <element name="NoOfProductToDisplay" type="input" selector="input[data-ui-id='wysiwyg-widget-options-fieldset-element-text-parameters-products-count']"/> + <element name="AddParam" type="button" selector=".rule-param-add"/> + <element name="ConditionsDropdown" type="select" selector="#conditions__1__new_child"/> + <element name="RuleParam" type="button" selector="//a[text()='...']"/> + <element name="Chooser" type="button" selector="//img[@title='Open Chooser']"/> + <element name="PageSize" type="input" selector="input[name='parameters[page_size]']"/> + <element name="ProductAttribute" type="multiselect" selector="select[name='parameters[show_attributes][]']" /> + <element name="ButtonToShow" type="multiselect" selector="select[name='parameters[show_buttons][]']"/> + <!--Widget on Storefront--> + <element name="CategoryWidget" type="text" selector="//a[@href='http://magento2.vagrant42/{{var1}}.html?___store=default']" parameterized="true"/> + <element name="CMSPageWidget" type="text" selector="//a[@href='http://magento2.vagrant42/home']"/> + <!--Compare on Storefront--> + <element name="ProductName" type="text" selector=".product.name.product-item-name" /> + <element name="CompareBtn" type="button" selector=".action.tocompare"/> + <element name="ClearCompare" type="button" selector="#compare-clear-all"/> + <element name="AcceptClear" type="button" selector=".action-primary.action-accept" /> + + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddImageToWYSIWYGBlockCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddImageToWYSIWYGBlockCest.xml index c7683d847eda3..f01d4fdfa472d 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddImageToWYSIWYGBlockCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddImageToWYSIWYGBlockCest.xml @@ -9,14 +9,13 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AddImageToWYSIWYGEditorBlock"> <annotations> - <features value="Add Image to WYSIWYG Block"/> - <stories value="Default WYSIWYG toolbar configuration with Magento Media Gallery-MAGETWO-42041"/> - <group value="addImageBlock"/> - <title value="You should be able to add image to WYSIWYG EditorBlock"/> - <description value="You should be able to add image to WYSIWYG Editor Block"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-42041-Default WYSIWYG toolbar configuration with Magento Media Gallery"/> + <group value="Cms"/> + <title value="Admin should be able to add image to WYSIWYG content of Block"/> + <description value="Admin should be able to add image to WYSIWYG content of Block"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-84376"/> - <group value="skip" /> </annotations> <before> <createData entity="_defaultCmsPage" stepKey="createCMSPage" /> @@ -29,71 +28,77 @@ <fillField selector="{{BlockNewPageBasicFieldsSection.blockTitle}}" userInput="{{_defaultBlock.title}}" stepKey="fillFieldTitle1"/> <fillField selector="{{BlockNewPageBasicFieldsSection.identifier}}" userInput="{{_defaultBlock.identifier}}" stepKey="fillFieldIdentifier"/> <selectOption selector="{{BlockNewPageBasicFieldsSection.storeView}}" userInput="All Store View" stepKey="selectAllStoreView" /> - <waitForElementVisible selector="{{BlockWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE" /> - <click selector="{{BlockWYSIWYGSection.InsertImageIcon}}" stepKey="clickInsertImageIcon" /> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE" /> + <click selector="{{TinyMCESection.InsertImageIcon}}" stepKey="clickInsertImageIcon" /> <waitForPageLoad stepKey="waitForPageLoad2" /> - <click selector="{{BlockWYSIWYGSection.Browse}}" stepKey="clickBrowse" /> + <click selector="{{MediaGallerySection.Browse}}" stepKey="clickBrowse" /> <waitForPageLoad stepKey="waitForPageLoad3" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading1" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading2" /> - <waitForElement selector="{{BlockWYSIWYGSection.CancelBtn}}" stepKey="waitForContent" /> - <see selector="{{BlockWYSIWYGSection.CancelBtn}}" userInput="Cancel" stepKey="seeCancelBtn" /> - <see selector="{{BlockWYSIWYGSection.CreateFolder}}" userInput="Create Folder" stepKey="seeCreateFolderBtn" /> - <see selector="{{BlockWYSIWYGSection.InsertFile}}" userInput="Add Selected" stepKey="seeAddSelectedBtn" /> - <click selector="{{BlockWYSIWYGSection.CreateFolder}}" stepKey="createFolder"/> - <waitForElementVisible selector="{{BlockWYSIWYGSection.FolderName}}" stepKey="waitForPopUp" /> - <fillField selector="{{BlockWYSIWYGSection.FolderName}}" userInput="{{ImageFolder.name}}" stepKey="fillFolderName" /> - <waitForElement selector="{{BlockWYSIWYGSection.AcceptFolderName}}" stepKey="waitForAcceptBtn" /> + <waitForElement selector="{{MediaGallerySection.CancelBtn}}" stepKey="waitForContent" /> + <see selector="{{MediaGallerySection.CancelBtn}}" userInput="Cancel" stepKey="seeCancelBtn" /> + <see selector="{{MediaGallerySection.CreateFolder}}" userInput="Create Folder" stepKey="seeCreateFolderBtn" /> + <see selector="{{MediaGallerySection.InsertFile}}" userInput="Add Selected" stepKey="seeAddSelectedBtn" /> + <click selector="{{MediaGallerySection.CreateFolder}}" stepKey="createFolder"/> + <waitForElementVisible selector="{{MediaGallerySection.FolderName}}" stepKey="waitForPopUp" /> + <fillField selector="{{MediaGallerySection.FolderName}}" userInput="{{ImageFolder.name}}" stepKey="fillFolderName" /> + <waitForElement selector="{{MediaGallerySection.AcceptFolderName}}" stepKey="waitForAcceptBtn" /> <wait time="3" stepKey="wait"/> - <click selector="{{BlockWYSIWYGSection.AcceptFolderName}}" stepKey="acceptFolderName" /> + <click selector="{{MediaGallerySection.AcceptFolderName}}" stepKey="acceptFolderName" /> <waitForPageLoad stepKey="waitForPageLoad4" /> - <conditionalClick selector="{{BlockWYSIWYGSection.StorageRootArrow}}" dependentSelector="{{BlockWYSIWYGSection.checkIfArrowExpand}}" stepKey="clickArrowIfCloses" visible="true"/> + <conditionalClick selector="{{MediaGallerySection.StorageRootArrow}}" dependentSelector="{{MediaGallerySection.checkIfArrowExpand}}" stepKey="clickArrowIfCloses" visible="true"/> <waitForText userInput="{{ImageFolder.name}}" stepKey="waitForNewFolder" /> <click userInput="{{ImageFolder.name}}" stepKey="clickOnCreatedFolder" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading3" /> - <attachFile selector="{{BlockWYSIWYGSection.BrowseUploadImage}}" userInput="{{ImageUpload.file}}" stepKey="uploadImage1"/> + <attachFile selector="{{MediaGallerySection.BrowseUploadImage}}" userInput="{{ImageUpload.file}}" stepKey="uploadImage1"/> <waitForLoadingMaskToDisappear stepKey="waitForLoading4" /> - <waitForElementVisible selector="{{BlockWYSIWYGSection.image(ImageUpload.file)}}" stepKey="waitForUploadImage1" /> - <seeElement selector="{{BlockWYSIWYGSection.imageSelected(ImageUpload.file)}}" stepKey="seeImageSelected" /> - <see selector="{{BlockWYSIWYGSection.DeleteSelectedBtn}}" userInput="Delete Selected" stepKey="seeDeleteBtn"/> - <click selector="{{BlockWYSIWYGSection.DeleteSelectedBtn}}" stepKey="clickDeleteSelected" /> + <waitForElementVisible selector="{{MediaGallerySection.image(ImageUpload.file)}}" stepKey="waitForUploadImage1" /> + <seeElement selector="{{MediaGallerySection.imageSelected(ImageUpload.file)}}" stepKey="seeImageSelected" /> + <see selector="{{MediaGallerySection.DeleteSelectedBtn}}" userInput="Delete Selected" stepKey="seeDeleteBtn"/> + <click selector="{{MediaGallerySection.DeleteSelectedBtn}}" stepKey="clickDeleteSelected" /> <waitForText userInput="OK" stepKey="waitForConfirm" /> - <click selector="{{BlockWYSIWYGSection.confirmDelete}}" stepKey="confirmDelete" /> - <waitForElementNotVisible selector="{{BlockWYSIWYGSection.image(ImageUpload.file)}}" stepKey="waitForImageDeleted" /> - <dontSeeElement selector="{{BlockWYSIWYGSection.image(ImageUpload.file)}}" stepKey="dontSeeImage" /> - <attachFile selector="{{BlockWYSIWYGSection.BrowseUploadImage}}" userInput="{{ImageUpload.file}}" stepKey="uploadImage2"/> + <click selector="{{MediaGallerySection.confirmDelete}}" stepKey="confirmDelete" /> + <waitForElementNotVisible selector="{{MediaGallerySection.image(ImageUpload.file)}}" stepKey="waitForImageDeleted" /> + <dontSeeElement selector="{{MediaGallerySection.image(ImageUpload.file)}}" stepKey="dontSeeImage" /> + <attachFile selector="{{MediaGallerySection.BrowseUploadImage}}" userInput="{{ImageUpload.file}}" stepKey="uploadImage2"/> <waitForLoadingMaskToDisappear stepKey="waitForLoading5" /> - <waitForElementVisible selector="{{BlockWYSIWYGSection.image(ImageUpload.file)}}" stepKey="waitForUploadImage2" /> - <click selector="{{BlockWYSIWYGSection.InsertFile}}" stepKey="clickInsertBtn" /> + <waitForElementVisible selector="{{MediaGallerySection.image(ImageUpload.file)}}" stepKey="waitForUploadImage2" /> + <click selector="{{MediaGallerySection.InsertFile}}" stepKey="clickInsertBtn" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading6" /> - <waitForElementVisible selector="{{BlockWYSIWYGSection.OkBtn}}" stepKey="waitForOkBtn" /> - <fillField selector="{{BlockWYSIWYGSection.ImageDescription}}" userInput="{{ImageUpload.content}}" stepKey="fillImageDescription" /> - <fillField selector="{{BlockWYSIWYGSection.Height}}" userInput="{{ImageUpload.height}}" stepKey="fillImageHeight" /> - <click selector="{{BlockWYSIWYGSection.OkBtn}}" stepKey="clickOkBtn" /> + <waitForElementVisible selector="{{MediaGallerySection.OkBtn}}" stepKey="waitForOkBtn" /> + <fillField selector="{{MediaGallerySection.ImageDescription}}" userInput="{{ImageUpload.content}}" stepKey="fillImageDescription" /> + <fillField selector="{{MediaGallerySection.Height}}" userInput="{{ImageUpload.height}}" stepKey="fillImageHeight" /> + <click selector="{{MediaGallerySection.OkBtn}}" stepKey="clickOkBtn" /> <waitForPageLoad stepKey="waitForPageLoad5"/> <click selector="{{BlockNewPagePageActionsSection.saveBlock}}" stepKey="clickSaveBlock"/> <amOnPage url="{{CmsPagesPage.url}}" stepKey="amOnEditPage"/> <waitForPageLoad stepKey="waitForPageLoad6"/> + <click selector="{{CmsPagesPageActionsSection.FilterBtn}}" stepKey="clickFiltersBtn" /> + <fillField selector="{{CmsPagesPageActionsSection.URLKey}}" userInput="$$createCMSPage.identifier$$" stepKey="fillOutURLKey" /> + <click selector="{{CmsPagesPageActionsSection.ApplyFiltersBtn}}" stepKey="clickApplyBtn" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoading9" /> + <actionGroup ref="SortByIdDescendingActionGroup" stepKey="sortByIdDescending" /> <waitForElementVisible selector="{{CmsPagesPageActionsSection.select('$$createCMSPage.identifier$$')}}" stepKey="waitForCMSPageGrid" /> - <scrollTo selector="{{CmsPagesPageActionsSection.select('$$createCMSPage.identifier$$')}}" stepKey="scrollToCMSPage" /> <click selector="{{CmsPagesPageActionsSection.select('$$createCMSPage.identifier$$')}}" stepKey="clickSelect" /> <waitForElementVisible selector="{{CmsPagesPageActionsSection.edit('$$createCMSPage.identifier$$')}}" stepKey="waitForEditLink" /> <click selector="{{CmsPagesPageActionsSection.edit('$$createCMSPage.identifier$$')}}" stepKey="clickEdit" /> <waitForPageLoad stepKey="waitForPageLoad7" /> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> - <seeElement selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> - <click selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> + <seeElement selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> + <click selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> <waitForPageLoad stepKey="waitForPageLoad8" /> <selectOption selector="{{WidgetSection.WidgetType}}" userInput="CMS Static Block" stepKey="selectCMSStaticBlock" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading7" /> <selectOption selector="{{WidgetSection.WidgetTemplate}}" userInput="CMS Static Block Default Template" stepKey="selectTemplate" /> <click selector="{{WidgetSection.BtnChooser}}" stepKey="clickSelectPageBtn" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoading8" /> + <actionGroup ref="SortByIdDescendingActionGroup" stepKey="sortByIdDescending2" /> <waitForElementVisible selector="{{WidgetSection.BlockPage(_defaultBlock.identifier)}}" stepKey="waitForBlockTitle" /> <click selector="{{WidgetSection.BlockPage(_defaultBlock.identifier)}}" stepKey="selectPreCreateBlock" /> <wait time="3" stepKey="wait1" /> <click selector="{{WidgetSection.InsertWidget}}" stepKey="clickInsertWidgetBtn" /> - <waitForLoadingMaskToDisappear stepKey="waitForLoading8" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoading9" /> <waitForPageLoad stepKey="waitForPageLoad9" /> <click selector="{{CmsNewPagePageActionsSection.savePage}}" stepKey="clickSavePage"/> <waitForPageLoad stepKey="waitForPageLoad10"/> @@ -103,6 +108,7 @@ <!--see image on Storefront--> <seeElement selector="{{StorefrontBlockSection.mediaDescription}}" stepKey="assertMediaDescription"/> <after> + <deleteData createDataKey="createCMSPage" stepKey="deletePreReqCMSPage" /> <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> <actionGroup ref="logout" stepKey="logout"/> </after> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddImageToWYSIWYGCMSCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddImageToWYSIWYGCMSCest.xml index 0fee3bc8686ec..f490a221b311b 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddImageToWYSIWYGCMSCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddImageToWYSIWYGCMSCest.xml @@ -9,13 +9,13 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AddImageToWYSIWYGEditorCMS"> <annotations> - <features value="Add Image to WYSIWYG CMS"/> - <stories value="Default WYSIWYG toolbar configuration with Magento Media Gallery-MAGETWO-42041"/> - <group value="addImageCMS"/> - <title value="You should be able to add image to WYSIWYG Editor CMS"/> - <description value="You should be able to add image to WYSIWYG Editor CMS"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-42041-Default WYSIWYG toolbar configuration with Magento Media Gallery"/> + <group value="Cms"/> + <title value="Admin should be able to add image to WYSIWYG content of CMS Page"/> + <description value="Admin should be able to add image to WYSIWYG content of CMS Page"/> <severity value="CRITICAL"/> - <testCaseId value="MAGETWO-85825 "/> + <testCaseId value="MAGETWO-85825"/> </annotations> <before> <actionGroup ref="LoginActionGroup" stepKey="login"/> @@ -26,44 +26,44 @@ <waitForPageLoad stepKey="wait"/> <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle"/> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickExpandContent"/> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE4" /> - <click selector="{{CmsWYSIWYGSection.InsertImageIcon}}" stepKey="clickInsertImageIcon" /> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE4" /> + <click selector="{{TinyMCESection.InsertImageIcon}}" stepKey="clickInsertImageIcon" /> <waitForPageLoad stepKey="waitForPageLoad" /> - <click selector="{{CmsWYSIWYGSection.Browse}}" stepKey="clickBrowse" /> + <click selector="{{MediaGallerySection.Browse}}" stepKey="clickBrowse" /> <waitForPageLoad stepKey="waitForPageLoad1" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading1" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading2" /> - <see selector="{{CmsWYSIWYGSection.CancelBtn}}" userInput="Cancel" stepKey="seeCancelBtn" /> - <see selector="{{CmsWYSIWYGSection.CreateFolder}}" userInput="Create Folder" stepKey="seeCreateFolderBtn" /> - <see selector="{{CmsWYSIWYGSection.InsertFile}}" userInput="Add Selected" stepKey="seeAddSelectedBtn" /> - <click selector="{{CmsWYSIWYGSection.CreateFolder}}" stepKey="createFolder"/> - <waitForElementVisible selector="{{CmsWYSIWYGSection.FolderName}}" stepKey="waitForPopUp" /> - <fillField selector="{{CmsWYSIWYGSection.FolderName}}" userInput="{{ImageFolder.name}}" stepKey="fillFolderName" /> - <click selector="{{CmsWYSIWYGSection.AcceptFolderName}}" stepKey="acceptFolderName" /> + <see selector="{{MediaGallerySection.CancelBtn}}" userInput="Cancel" stepKey="seeCancelBtn" /> + <see selector="{{MediaGallerySection.CreateFolder}}" userInput="Create Folder" stepKey="seeCreateFolderBtn" /> + <see selector="{{MediaGallerySection.InsertFile}}" userInput="Add Selected" stepKey="seeAddSelectedBtn" /> + <click selector="{{MediaGallerySection.CreateFolder}}" stepKey="createFolder"/> + <waitForElementVisible selector="{{MediaGallerySection.FolderName}}" stepKey="waitForPopUp" /> + <fillField selector="{{MediaGallerySection.FolderName}}" userInput="{{ImageFolder.name}}" stepKey="fillFolderName" /> + <click selector="{{MediaGallerySection.AcceptFolderName}}" stepKey="acceptFolderName" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading3" /> - <conditionalClick selector="{{CmsWYSIWYGSection.StorageRootArrow}}" dependentSelector="{{CmsWYSIWYGSection.checkIfArrowExpand}}" stepKey="clickArrowIfCloses" visible="true"/> + <conditionalClick selector="{{MediaGallerySection.StorageRootArrow}}" dependentSelector="{{MediaGallerySection.checkIfArrowExpand}}" stepKey="clickArrowIfCloses" visible="true"/> <waitForText userInput="{{ImageFolder.name}}" stepKey="waitForNewFolder" /> <click userInput="{{ImageFolder.name}}" stepKey="clickOnCreatedFolder" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading5" /> - <attachFile selector="{{CmsWYSIWYGSection.BrowseUploadImage}}" userInput="{{ImageUpload.file}}" stepKey="uploadImage1"/> + <attachFile selector="{{MediaGallerySection.BrowseUploadImage}}" userInput="{{ImageUpload.file}}" stepKey="uploadImage1"/> <waitForLoadingMaskToDisappear stepKey="waitForLoading6" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.image(ImageUpload.file)}}" stepKey="waitForUploadImage1" /> - <seeElement selector="{{CmsWYSIWYGSection.imageSelected(ImageUpload.file)}}" stepKey="seeImageSelected" /> - <see selector="{{CmsWYSIWYGSection.DeleteSelectedBtn}}" userInput="Delete Selected" stepKey="seeDeleteBtn"/> - <click selector="{{CmsWYSIWYGSection.DeleteSelectedBtn}}" stepKey="clickDeleteSelected" /> + <waitForElementVisible selector="{{MediaGallerySection.image(ImageUpload.file)}}" stepKey="waitForUploadImage1" /> + <seeElement selector="{{MediaGallerySection.imageSelected(ImageUpload.file)}}" stepKey="seeImageSelected" /> + <see selector="{{MediaGallerySection.DeleteSelectedBtn}}" userInput="Delete Selected" stepKey="seeDeleteBtn"/> + <click selector="{{MediaGallerySection.DeleteSelectedBtn}}" stepKey="clickDeleteSelected" /> <waitForText userInput="OK" stepKey="waitForConfirm" /> - <click selector="{{CmsWYSIWYGSection.confirmDelete}}" stepKey="confirmDelete" /> - <waitForElementNotVisible selector="{{CmsWYSIWYGSection.image(ImageUpload.file)}}" stepKey="waitForImageDeleted" /> - <dontSeeElement selector="{{CmsWYSIWYGSection.image(ImageUpload.file)}}" stepKey="dontSeeImage" /> - <attachFile selector="{{CmsWYSIWYGSection.BrowseUploadImage}}" userInput="{{ImageUpload.file}}" stepKey="uploadImage2"/> + <click selector="{{MediaGallerySection.confirmDelete}}" stepKey="confirmDelete" /> + <waitForElementNotVisible selector="{{MediaGallerySection.image(ImageUpload.file)}}" stepKey="waitForImageDeleted" /> + <dontSeeElement selector="{{MediaGallerySection.image(ImageUpload.file)}}" stepKey="dontSeeImage" /> + <attachFile selector="{{MediaGallerySection.BrowseUploadImage}}" userInput="{{ImageUpload.file}}" stepKey="uploadImage2"/> <waitForLoadingMaskToDisappear stepKey="waitForLoading9" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.image(ImageUpload.file)}}" stepKey="waitForUploadImage2" /> - <click selector="{{CmsWYSIWYGSection.InsertFile}}" stepKey="clickInsertBtn" /> + <waitForElementVisible selector="{{MediaGallerySection.image(ImageUpload.file)}}" stepKey="waitForUploadImage2" /> + <click selector="{{MediaGallerySection.InsertFile}}" stepKey="clickInsertBtn" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading7" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.OkBtn}}" stepKey="waitForOkBtn" /> - <fillField selector="{{CmsWYSIWYGSection.ImageDescription}}" userInput="{{ImageUpload.content}}" stepKey="fillImageDescription" /> - <fillField selector="{{CmsWYSIWYGSection.Height}}" userInput="{{ImageUpload.height}}" stepKey="fillImageHeight" /> - <click selector="{{CmsWYSIWYGSection.OkBtn}}" stepKey="clickOkBtn" /> + <waitForElementVisible selector="{{MediaGallerySection.OkBtn}}" stepKey="waitForOkBtn" /> + <fillField selector="{{MediaGallerySection.ImageDescription}}" userInput="{{ImageUpload.content}}" stepKey="fillImageDescription" /> + <fillField selector="{{MediaGallerySection.Height}}" userInput="{{ImageUpload.height}}" stepKey="fillImageHeight" /> + <click selector="{{MediaGallerySection.OkBtn}}" stepKey="clickOkBtn" /> <waitForPageLoad stepKey="wait3"/> <click selector="{{CmsNewPagePageSeoSection.header}}" stepKey="clickExpandSearchEngineOptimisation"/> <fillField selector="{{CmsNewPagePageSeoSection.urlKey}}" userInput="{{_defaultCmsPage.identifier}}" stepKey="fillFieldUrlKey"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddVariableToWYSIWYGBlockCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddVariableToWYSIWYGBlockCest.xml index 77ac3ed328935..5f92a5766a65c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddVariableToWYSIWYGBlockCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddVariableToWYSIWYGBlockCest.xml @@ -9,13 +9,12 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AddVariableToBlock"> <annotations> - <features value="Add Variable to WYSIWYG Block"/> - <stories value="Add Variable to WYSIWYG MAGETWO-42158"/> - <group value="variableBLock"/> - <title value="You should be able to add variable to WYSIWYG Editor of Block"/> - <description value="You should be able to add variable to WYSIWYG Editor Block"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-42158-Variable with WYSIWYG"/> + <group value="Cms"/> + <title value="Admin should be able to add variable to WYSIWYG content of Block"/> + <description value="You should be able to add variable to WYSIWYG content Block"/> <testCaseId value="MAGETWO-84378"/> - <group value="skip"/> </annotations> <before> <createData entity="_defaultCmsPage" stepKey="createCMSPage" /> @@ -38,9 +37,9 @@ <fillField selector="{{BlockNewPageBasicFieldsSection.blockTitle}}" userInput="{{_defaultBlock.title}}" stepKey="fillFieldTitle1"/> <fillField selector="{{BlockNewPageBasicFieldsSection.identifier}}" userInput="{{_defaultBlock.identifier}}" stepKey="fillFieldIdentifier"/> <selectOption selector="{{BlockNewPageBasicFieldsSection.storeView}}" userInput="All Store View" stepKey="selectAllStoreView" /> - <waitForElementVisible selector="{{BlockWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE" /> - <seeElement selector="{{BlockWYSIWYGSection.InsertVariableIcon}}" stepKey="seeInsertVariableIcon" /> - <click selector="{{BlockWYSIWYGSection.InsertVariableIcon}}" stepKey="clickInsertVariableIcon1" /> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE" /> + <seeElement selector="{{TinyMCESection.InsertVariableIcon}}" stepKey="seeInsertVariableIcon" /> + <click selector="{{TinyMCESection.InsertVariableIcon}}" stepKey="clickInsertVariableIcon1" /> <waitForText userInput="Insert Variable" stepKey="waitForSlideOutOpen"/> <waitForLoadingMaskToDisappear stepKey="waitForPageLoad3"/> <!--see Insert Variable button disabled--> @@ -56,8 +55,9 @@ <click selector="{{VariableSection.Radio('city')}}" stepKey="selectDefaultVariable"/> <see selector="{{VariableSection.InsertVariableBtnEnabled}}" userInput="Insert Variable" stepKey="seeInsertVarialeEnabled" /> <click selector="{{VariableSection.InsertVariableBtnEnabled}}" stepKey="save1" /> - <waitForPageLoad stepKey="waitForPageLoad10" /> - <click selector="{{BlockWYSIWYGSection.InsertVariableIcon}}" stepKey="clickInsertVariableIcon2" /> + <scrollTo selector="{{BlockNewPageBasicFieldsSection.blockTitle}}" stepKey="scrollToBlockTitle" /> + <waitForElementNotVisible selector="{{VariableSection.VariableTitle}}" stepKey="waitForSlideoutCloses" /> + <click selector="{{TinyMCESection.InsertVariableIcon}}" stepKey="clickInsertVariableIcon2" /> <waitForPageLoad stepKey="waitForPageLoad4"/> <!--see custom variable--> <see userInput="{{customVariable.code}}" stepKey="seeCustomVariable"/> @@ -73,33 +73,41 @@ <click selector="{{VariableSection.InsertVariableBtnEnabled}}" stepKey="save2" /> <waitForElementNotVisible selector="{{VariableSection.VariableTitle}}" stepKey="waitForSlideOutClose" /> <click selector="{{BlockWYSIWYGSection.ShowHideBtn}}" stepKey="clickShow/HideBtn"/> - <waitForElementVisible selector="{{BlockWYSIWYGSection.InsertVariableBtn}}" stepKey="waitForInsertVariableBtn" /> - <seeElement selector="{{BlockWYSIWYGSection.InsertVariableBtn}}" stepKey="InsertVariableBtn" /> + <waitForElementVisible selector="{{TinyMCESection.InsertVariableBtn}}" stepKey="waitForInsertVariableBtn" /> + <seeElement selector="{{TinyMCESection.InsertVariableBtn}}" stepKey="InsertVariableBtn" /> <click selector="{{BlockNewPagePageActionsSection.saveBlock}}" stepKey="clickSaveBlock"/> <amOnPage url="{{CmsPagesPage.url}}" stepKey="amOnEditPage"/> <waitForPageLoad stepKey="waitForPageLoad7"/> + <click selector="{{CmsPagesPageActionsSection.FilterBtn}}" stepKey="clickFiltersBtn" /> + <fillField selector="{{CmsPagesPageActionsSection.URLKey}}" userInput="$$createCMSPage.identifier$$" stepKey="fillOutURLKey" /> + <click selector="{{CmsPagesPageActionsSection.ApplyFiltersBtn}}" stepKey="clickApplyBtn" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoading2" /> + <actionGroup ref="SortByIdDescendingActionGroup" stepKey="sortByIdDescending" /> <waitForElementVisible selector="{{CmsPagesPageActionsSection.select('$$createCMSPage.identifier$$')}}" stepKey="waitForCMSPageGrid" /> - <scrollTo selector="{{CmsPagesPageActionsSection.select('$$createCMSPage.identifier$$')}}" stepKey="scrollToCMSPage" /> <click selector="{{CmsPagesPageActionsSection.select('$$createCMSPage.identifier$$')}}" stepKey="clickSelect" /> <waitForElementVisible selector="{{CmsPagesPageActionsSection.edit('$$createCMSPage.identifier$$')}}" stepKey="waitForEditLink" /> <click selector="{{CmsPagesPageActionsSection.edit('$$createCMSPage.identifier$$')}}" stepKey="clickEdit" /> <waitForPageLoad stepKey="waitForPageLoad8" /> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> - <seeElement selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> - <click selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> + <seeElement selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> + <click selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> <waitForPageLoad stepKey="waitForPageLoad9" /> <selectOption selector="{{WidgetSection.WidgetType}}" userInput="CMS Static Block" stepKey="selectCMSStaticBlock" /> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappear" /> <selectOption selector="{{WidgetSection.WidgetTemplate}}" userInput="CMS Static Block Default Template" stepKey="selectTemplate" /> <click selector="{{WidgetSection.BtnChooser}}" stepKey="clickSelectPageBtn" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappearAfterClickingBtnChooser" /> + <actionGroup ref="SortByIdDescendingActionGroup" stepKey="sortByIdDescending2" /> <waitForElementVisible selector="{{WidgetSection.BlockPage(_defaultBlock.identifier)}}" stepKey="waitForBlockTitle" /> <click selector="{{WidgetSection.BlockPage(_defaultBlock.identifier)}}" stepKey="selectPreCreateBlock" /> <wait time="3" stepKey="wait1" /> <click selector="{{WidgetSection.InsertWidget}}" stepKey="clickInsertWidgetBtn" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading" /> <waitForPageLoad stepKey="waitForPageLoad10" /> + <waitForElementVisible selector="{{CmsNewPagePageActionsSection.savePage}}" stepKey="waitForSaveButtonVisible"/> <click selector="{{CmsNewPagePageActionsSection.savePage}}" stepKey="clickSavePage"/> + <waitForPageLoad stepKey="waitForPageLoadAfterSaveCmsPage" /> <see userInput="You saved the page." stepKey="seeSuccessMessage"/> <amOnPage url="$$createCMSPage.identifier$$" stepKey="amOnPageTestPage1"/> <waitForPageLoad stepKey="waitForPageLoad11" /> @@ -116,6 +124,7 @@ <!--see custom variable blank--> <dontSee userInput="{{customVariable.html}}" stepKey="dontSeeCustomVariableName" /> <after> + <deleteData createDataKey="createCMSPage" stepKey="deletePreReqCMSPage" /> <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> <actionGroup ref="logout" stepKey="logout"/> </after> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddVariableToWYSIWYGCMSCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddVariableToWYSIWYGCMSCest.xml index 6867fa376a632..23384f1c04a73 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddVariableToWYSIWYGCMSCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddVariableToWYSIWYGCMSCest.xml @@ -9,14 +9,13 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="InsertDefaultMagentoVariableIntoWYSIWYGOnPages"> <annotations> - <features value="Add Variable to WYSIWYG"/> - <stories value="Add Variable to WYSIWYG MAGETWO-42158"/> - <group value="addVariableToCMS"/> - <title value="Insert default Magento variable into content of WYSIWYG on Pages"/> - <description value="Insert default Magento variable into content of WYSIWYG on Pages"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-42158-Variable with WYSIWYG "/> + <group value="Cms"/> + <title value="Insert default Magento variable into content of WYSIWYG on CMS Pages"/> + <description value="Insert default Magento variable into content of WYSIWYG on CMS Pages"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-83504"/> - <group value="skip" /> </annotations> <before> <actionGroup ref="LoginActionGroup" stepKey="loginGetFromGeneralFile"/> @@ -37,10 +36,10 @@ <waitForPageLoad stepKey="waitForPageLoad2"/> <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle"/> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> <executeJS function="tinyMCE.activeEditor.setContent('Hello CMS Page!');" stepKey="executeJSFillContent"/> - <seeElement selector="{{CmsWYSIWYGSection.InsertVariableIcon}}" stepKey="seeInsertVariableIcon" /> - <click selector="{{CmsWYSIWYGSection.InsertVariableIcon}}" stepKey="clickInsertVariableIcon1" /> + <seeElement selector="{{TinyMCESection.InsertVariableIcon}}" stepKey="seeInsertVariableIcon" /> + <click selector="{{TinyMCESection.InsertVariableIcon}}" stepKey="clickInsertVariableIcon1" /> <waitForLoadingMaskToDisappear stepKey="waitForPageLoad3"/> <waitForText userInput="Insert Variable" stepKey="waitForSlideOutOpen"/> <!--see Insert Variable button disabled--> @@ -57,7 +56,7 @@ <see selector="{{VariableSection.InsertVariableBtnEnabled}}" userInput="Insert Variable" stepKey="seeInsertVarialeEnabled" /> <click selector="{{VariableSection.InsertVariableBtnEnabled}}" stepKey="save1" /> <waitForPageLoad stepKey="waitForPageLoad8" /> - <click selector="{{CmsWYSIWYGSection.InsertVariableIcon}}" stepKey="clickInsertVariableIcon2" /> + <click selector="{{TinyMCESection.InsertVariableIcon}}" stepKey="clickInsertVariableIcon2" /> <waitForPageLoad stepKey="waitForPageLoad4"/> <!--see custom variable--> <see userInput="{{customVariable.code}}" stepKey="seeCustomVariable"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGBlockCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGBlockCest.xml index 998649c7c78c3..e6963d5b9def4 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGBlockCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGBlockCest.xml @@ -9,11 +9,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AddWidgetToBlock"> <annotations> - <features value="Add Widget to WYSIWYG of Block"/> - <stories value="Apply new WYSIWYG in Block-MAGETWO-47309"/> - <group value="widgetBLock"/> - <title value="You should be able to add widget to WYSIWYG Editor of Block"/> - <description value="You should be able to add widget to WYSIWYG Editor Block"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-42156-Apply new WYSIWYG in Block"/> + <group value="Cms"/> + <title value="Admin should be able to add widget to WYSIWYG content of Block"/> + <description value="Admin should be able to add widget to WYSIWYG content Block"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-84654"/> <group value="skip" /> @@ -29,8 +29,8 @@ <fillField selector="{{BlockNewPageBasicFieldsSection.blockTitle}}" userInput="{{_defaultBlock.title}}" stepKey="fillFieldTitle"/> <fillField selector="{{BlockNewPageBasicFieldsSection.identifier}}" userInput="{{_defaultBlock.identifier}}" stepKey="fillFieldIdentifier"/> <selectOption selector="{{BlockNewPageBasicFieldsSection.storeView}}" userInput="All Store View" stepKey="selectAllStoreView" /> - <waitForElementVisible selector="{{BlockWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE" /> - <click selector="{{BlockWYSIWYGSection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon1" /> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE" /> + <click selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon1" /> <wait time="10" stepKey="waitForPageLoad2" /> <see userInput="Inserting a widget does not create a widget instance." stepKey="seeMessage" /> <selectOption selector="{{WidgetSection.WidgetType}}" userInput="CMS Page Link" stepKey="selectCMSPageLink" /> @@ -47,21 +47,27 @@ <click selector="{{BlockNewPagePageActionsSection.saveBlock}}" stepKey="clickSaveBlock"/> <amOnPage url="{{CmsPagesPage.url}}" stepKey="amOnEditPage"/> <waitForPageLoad stepKey="waitForPageLoad3"/> + <click selector="{{CmsPagesPageActionsSection.FilterBtn}}" stepKey="clickFiltersBtn" /> + <fillField selector="{{CmsPagesPageActionsSection.URLKey}}" userInput="$$createCMSPage.identifier$$" stepKey="fillOutURLKey" /> + <click selector="{{CmsPagesPageActionsSection.ApplyFiltersBtn}}" stepKey="clickApplyBtn" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoading3" /> + <actionGroup ref="SortByIdDescendingActionGroup" stepKey="sortByIdDescending" /> <waitForElementVisible selector="{{CmsPagesPageActionsSection.select('$$createCMSPage.identifier$$')}}" stepKey="waitForCMSPageGrid" /> - <scrollTo selector="{{CmsPagesPageActionsSection.select('$$createCMSPage.identifier$$')}}" stepKey="scrollToCMSPage" /> <click selector="{{CmsPagesPageActionsSection.select('$$createCMSPage.identifier$$')}}" stepKey="clickSelect" /> <waitForElementVisible selector="{{CmsPagesPageActionsSection.edit('$$createCMSPage.identifier$$')}}" stepKey="waitForEditLink" /> <click selector="{{CmsPagesPageActionsSection.edit('$$createCMSPage.identifier$$')}}" stepKey="clickEdit" /> <waitForPageLoad stepKey="waitForPageLoad4" /> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> - <seeElement selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> - <click selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon2" /> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> + <seeElement selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> + <click selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon2" /> <waitForPageLoad stepKey="waitForPageLoad5" /> <selectOption selector="{{WidgetSection.WidgetType}}" userInput="CMS Static Block" stepKey="selectCMSStaticBlock" /> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappear2" /> <selectOption selector="{{WidgetSection.WidgetTemplate}}" userInput="CMS Static Block Default Template" stepKey="selectTemplate2" /> <click selector="{{WidgetSection.BtnChooser}}" stepKey="clickSelectPageBtn2" /> + <waitForLoadingMaskToDisappear stepKey="waitForWidgetChooserLoadingMaskToDisappear"/> + <actionGroup ref="SortByIdDescendingActionGroup" stepKey="sortByIdDescending2" /> <waitForElementVisible selector="{{WidgetSection.BlockPage(_defaultBlock.identifier)}}" stepKey="waitForBlockTitle" /> <click selector="{{WidgetSection.BlockPage(_defaultBlock.identifier)}}" stepKey="selectPreCreateBlock" /> <wait time="3" stepKey="wait1" /> @@ -74,7 +80,7 @@ <waitForPageLoad stepKey="waitForPageLoad7" /> <see userInput="Home page" stepKey="seeHomePageCMSPage"/> <after> - <!--<deleteData createDataKey="createCMSPage" stepKey="deleteCMSPage" />--> + <deleteData createDataKey="createCMSPage" stepKey="deletePreReqCMSPage" /> <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> <actionGroup ref="logout" stepKey="logout"/> </after> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCMSPageLinkTypeCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCMSPageLinkTypeCest.xml index 9c88502e207e1..3e50ce671cd3c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCMSPageLinkTypeCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCMSPageLinkTypeCest.xml @@ -10,9 +10,9 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AddWidgetToWYSIWYGWithTypeOfCMSPageLink"> <annotations> - <features value="Add Widget to WYSIWYG"/> - <stories value="Widgets in WYSIWYG"/> - <group value="CMSPageLink"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-42156-Widgets in WYSIWYG"/> + <group value="Cms"/> <title value="Create CMS Page With Widget Type:CMS page link"/> <description value="Create CMS Page With Widget Type:CMS page link"/> <severity value="CRITICAL"/> @@ -28,10 +28,10 @@ <waitForPageLoad stepKey="wait1"/> <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle"/> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> <executeJS function="tinyMCE.activeEditor.setContent('Hello CMS Page!');" stepKey="executeJSFillContent"/> - <seeElement selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> - <click selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> + <seeElement selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> + <click selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> <waitForPageLoad stepKey="wait2"/> <see userInput="Inserting a widget does not create a widget instance." stepKey="seeMessage" /> <!--see Insert Widget button disabled--> @@ -46,6 +46,7 @@ <click selector="{{WidgetSection.BtnChooser}}" stepKey="clickSelectPageBtn" /> <!--<waitForLoadingMaskToDisappear stepKey="wait3"/>--> <waitForElementVisible selector="{{WidgetSection.CMSPage}}" stepKey="waitForPageVisible" /> + <scrollTo selector="{{WidgetSection.CMSPage}}" stepKey="scrollToCMSName" /> <click selector="{{WidgetSection.CMSPage}}" stepKey="selectPreCreateCMS" /> <waitForElementNotVisible selector="{{WidgetSection.SelectPageTitle}}" stepKey="waitForSlideOutCloses" /> <click selector="{{WidgetSection.InsertWidget}}" stepKey="clickInsertWidget" /> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCMSStaticBlockTypeCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCMSStaticBlockTypeCest.xml index 6b2cbdc24ae2c..c0dfe18d7bcf6 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCMSStaticBlockTypeCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCMSStaticBlockTypeCest.xml @@ -10,16 +10,16 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AddWidgetToWYSIWYGWithTypeOfCMSStaticBlock"> <annotations> - <features value="Add Widget to WYSIWYG"/> - <stories value="Widgets in WYSIWYG"/> - <group value="CMSStaticBlock"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-42156-Widgets in WYSIWYG"/> + <group value="Cms"/> <title value="Create CMS Page With Widget Type:CMS Static Block"/> - <description value="Create CMS Page With Widget Type:CMS Static Blocl"/> + <description value="Create CMS Page With Widget Type:CMS Static Block"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-83787"/> </annotations> <before> - <createData entity="_defaultBlock" stepKey="createPreBlock" /> + <createData entity="_defaultBlock" stepKey="createPreReqBlock" /> <actionGroup ref="LoginActionGroup" stepKey="login"/> <actionGroup ref="EnabledWYSIWYG" stepKey="enableWYSIWYG"/> <actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4" /> @@ -29,10 +29,10 @@ <waitForPageLoad stepKey="wait1"/> <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle"/> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> <executeJS function="tinyMCE.activeEditor.setContent('Hello CMS Page!');" stepKey="executeJSFillContent"/> - <seeElement selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> - <click selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> + <seeElement selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> + <click selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> <waitForPageLoad stepKey="waitForPageLoad" /> <see userInput="Inserting a widget does not create a widget instance." stepKey="seeMessage" /> <!--see Insert Widget button disabled--> @@ -47,8 +47,10 @@ <selectOption selector="{{WidgetSection.WidgetTemplate}}" userInput="CMS Static Block Default Template" stepKey="selectTemplate" /> <click selector="{{WidgetSection.BtnChooser}}" stepKey="clickSelectPageBtn" /> <waitForLoadingMaskToDisappear stepKey="wait3"/> - <waitForElementVisible selector="{{WidgetSection.BlockPage($$createPreBlock.identifier$$)}}" stepKey="waitForSlideoutOpens" /> - <click selector="{{WidgetSection.BlockPage($$createPreBlock.identifier$$)}}" stepKey="selectPreCreateBlock" /> + <actionGroup ref="SortByIdDescendingActionGroup" stepKey="sortByIdDescending" /> + <waitForElementVisible selector="{{WidgetSection.BlockPage($$createPreReqBlock.identifier$$)}}" stepKey="waitForSlideoutOpens" /> + <scrollTo selector="{{WidgetSection.BlockPage($$createPreReqBlock.identifier$$)}}" stepKey="scrollToBlockIdentifier" /> + <click selector="{{WidgetSection.BlockPage($$createPreReqBlock.identifier$$)}}" stepKey="selectPreCreateBlock" /> <waitForElementNotVisible selector="{{WidgetSection.SelectBlockTitle}}" stepKey="waitForSlideoutCloses" /> <click selector="{{WidgetSection.InsertWidget}}" stepKey="clickInsertWidget" /> <waitForLoadingMaskToDisappear stepKey="waitingForLoading" /> @@ -61,8 +63,9 @@ <waitForPageLoad stepKey="wait5" /> <!--see widget on Storefront--> <see userInput="Hello CMS Page!" stepKey="seeContent"/> - <see userInput="$$createPreBlock.content$$" stepKey="seeBlockLink"/> + <see userInput="$$createPreReqBlock.content$$" stepKey="seeBlockLink"/> <after> + <deleteData createDataKey="createPreReqBlock" stepKey="deletePreReqBlock" /> <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> <actionGroup ref="logout" stepKey="logout"/> </after> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogCategoryLinkTypeCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogCategoryLinkTypeCest.xml index 9e4a77ad1ef06..03b9499a2a962 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogCategoryLinkTypeCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogCategoryLinkTypeCest.xml @@ -9,11 +9,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AddWidgetToWYSIWYGWithTypeOfCatalogCategoryLink"> <annotations> - <features value="Add Widget to WYSIWYG"/> - <stories value="Widgets in WYSIWYG"/> - <group value="categoryLink"/> - <title value="Insert default Magento widget into content of WYSIWYG on CMS Pages"/> - <description value="Insert default Magento widget into content of WYSIWYG on CMS Pages"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-42156-Widgets in WYSIWYG"/> + <group value="Cms"/> + <title value="Create CMS Page With Widget Type: Catalog category link"/> + <description value="Create CMS Page With Widget Type: Catalog category link"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-83611"/> </annotations> @@ -22,16 +22,17 @@ <actionGroup ref="LoginActionGroup" stepKey="login"/> <actionGroup ref="EnabledWYSIWYG" stepKey="enableWYSIWYG"/> <actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4" /> + <actionGroup ref="ConfigAdminAccountSharingActionGroup" stepKey="allowAdminShareAccount"/> </before> <!--Main test--> <amOnPage url="{{CmsNewPagePage.url}}" stepKey="navigateToPage"/> <waitForPageLoad stepKey="wait1"/> <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle"/> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> <executeJS function="tinyMCE.activeEditor.setContent('Hello CMS Page!');" stepKey="executeJSFillContent"/> - <seeElement selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> - <click selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> + <seeElement selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> + <click selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> <waitForPageLoad stepKey="wait2"/> <see userInput="Inserting a widget does not create a widget instance." stepKey="seeMessage" /> <!--see Insert Widget button disabled--> @@ -60,6 +61,7 @@ <!--see widget on Storefront--> <see userInput="$$createPreReqCategory.name$$" stepKey="seeCategoryLink"/> <after> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCatalog" /> <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> <actionGroup ref="logout" stepKey="logout"/> </after> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogProductLinkTypeCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogProductLinkTypeCest.xml index da09d2512315d..622d29ebb196c 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogProductLinkTypeCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogProductLinkTypeCest.xml @@ -10,9 +10,9 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AddWidgetToWYSIWYGWithTypeOfCatalogProductLink"> <annotations> - <features value="Add Widget to WYSIWYG"/> - <stories value="Widgets in WYSIWYG"/> - <group value="productLink"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-42156-Widgets in WYSIWYG"/> + <group value="Cms"/> <title value="Create CMS Page With Widget Type: Catalog product link"/> <description value="Create CMS Page With Widget Type: Catalog product link"/> <severity value="CRITICAL"/> @@ -32,10 +32,10 @@ <waitForPageLoad stepKey="wait1"/> <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle"/> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> <executeJS function="tinyMCE.activeEditor.setContent('Hello CMS Page!');" stepKey="executeJSFillContent"/> - <seeElement selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> - <click selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> + <seeElement selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> + <click selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> <waitForPageLoad stepKey="wait2"/> <see userInput="Inserting a widget does not create a widget instance." stepKey="seeMessage" /> <waitForPageLoad stepKey="wait3"/> @@ -68,6 +68,8 @@ <see userInput="Hello CMS Page!" stepKey="seeContent"/> <see userInput="$$createPreReqProduct.name$$" stepKey="seeProductLink"/> <after> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCatalog" /> + <deleteData createDataKey="createPreReqProduct" stepKey="deletePreReqProduct" /> <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> <actionGroup ref="logout" stepKey="logout"/> </after> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogProductListTypeCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogProductListTypeCest.xml index 83ea2264371ca..e21a77b25e6e0 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogProductListTypeCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithCatalogProductListTypeCest.xml @@ -9,13 +9,13 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AddWidgetToWYSIWYGWithTypeOfCatalogProductList"> <annotations> - <features value="Add Widget to WYSIWYG"/> - <stories value="Widgets in WYSIWYG"/> - <group value="productList"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-42156-Widgets in WYSIWYG"/> + <group value="Cms"/> <title value="Create CMS Page With Widget Type: Catalog product list"/> <description value="Create CMS Page With Widget Type: Catalog product list"/> <severity value="CRITICAL"/> - <testCaseId value="MAGETWO-"/> + <testCaseId value="MAGETWO-67091"/> </annotations> <before> <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> @@ -34,10 +34,10 @@ <waitForPageLoad stepKey="wait1"/> <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle"/> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> <executeJS function="tinyMCE.activeEditor.setContent('Hello CMS Page!');" stepKey="executeJSFillContent"/> - <seeElement selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> - <click selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> + <seeElement selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> + <click selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> <waitForPageLoad stepKey="waitForPageLoad1" /> <see userInput="Inserting a widget does not create a widget instance." stepKey="seeMessage" /> <!--see Insert Widget button disabled--> @@ -73,6 +73,9 @@ <see userInput="$$createPreReqProduct1.name$$" stepKey="seeProductLink1"/> <see userInput="$$createPreReqProduct2.name$$" stepKey="seeProductLink2"/> <after> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCatalog" /> + <deleteData createDataKey="createPreReqProduct1" stepKey="deletePreReqProduct1" /> + <deleteData createDataKey="createPreReqProduct2" stepKey="deletePreReqProduct2" /> <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> <actionGroup ref="logout" stepKey="logout"/> </after> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithRecentlyComparedProductsTypeCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithRecentlyComparedProductsTypeCest.xml index 7dedac0e843be..66ae4a5d1cc53 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithRecentlyComparedProductsTypeCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithRecentlyComparedProductsTypeCest.xml @@ -7,12 +7,12 @@ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AddWidgetToWYSIWYGWithTypeOfRecentlyComparedProducts"> <annotations> - <features value="Add Widget to WYSIWYG"/> - <stories value="Widgets in WYSIWYG"/> - <group value="recentlyCompared"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-42156-Widgets in WYSIWYG"/> + <group value="Cms"/> <title value="Create CMS Page With Widget Type: Recently Compared Products"/> <description value="Create CMS Page With Widget Type: Recently Compared Products"/> <severity value="CRITICAL"/> @@ -33,10 +33,10 @@ <waitForPageLoad stepKey="wait1"/> <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle"/> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> <executeJS function="tinyMCE.activeEditor.setContent('Hello CMS Page!');" stepKey="executeJSFillContent"/> - <seeElement selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> - <click selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> + <seeElement selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> + <click selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> <waitForPageLoad stepKey="waitForPageLoad" /> <see userInput="Inserting a widget does not create a widget instance." stepKey="seeMessage" /> <waitForPageLoad stepKey="wait2"/> @@ -76,9 +76,11 @@ <!--see widget on Storefront--> <see userInput="Hello CMS Page!" stepKey="seeContent"/> <waitForPageLoad stepKey="wait6" /> - <waitForText userInput="$$createPreReqProduct.name$$" stepKey="waiForProductVisible" /> + <waitForText userInput="$$createPreReqProduct.name$$" stepKey="waitForProductVisible" /> <see userInput="$$createPreReqProduct.name$$" stepKey="seeProductName" /> <after> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCatalog" /> + <deleteData createDataKey="createPreReqProduct" stepKey="deletePreReqProduct" /> <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> <actionGroup ref="logout" stepKey="logout"/> </after> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithRecentlyViewedProductsTypeCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithRecentlyViewedProductsTypeCest.xml index eb96c3047bf15..143033c98e9f6 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithRecentlyViewedProductsTypeCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminAddWidgetToWYSIWYGWithRecentlyViewedProductsTypeCest.xml @@ -10,9 +10,9 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AddWidgetToWYSIWYGWithTypeOfRecentlyViewedProducts"> <annotations> - <features value="Add Widget to WYSIWYG"/> - <stories value="Widgets in WYSIWYG"/> - <group value="recentlyViewed"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-42156-Widgets in WYSIWYG"/> + <group value="Cms"/> <title value="Create CMS Page With Widget Type: Recently Viewed Products"/> <description value="Create CMS Page With Widget Type: Recently Viewed Products"/> <severity value="CRITICAL"/> @@ -32,10 +32,10 @@ <waitForPageLoad stepKey="wait1"/> <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle"/> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> <executeJS function="tinyMCE.activeEditor.setContent('Hello CMS Page!');" stepKey="executeJSFillContent"/> - <seeElement selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> - <click selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> + <seeElement selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="seeWidgetIcon" /> + <click selector="{{TinyMCESection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> <waitForPageLoad stepKey="waitForPageLoad" /> <see userInput="Inserting a widget does not create a widget instance." stepKey="seeMessage" /> <!--see Insert Widget button disabled--> @@ -68,6 +68,8 @@ <waitForText userInput="$$createPreReqProduct.name$$" stepKey="waitForProductVisible" /> <see userInput="$$createPreReqProduct.name$$" stepKey="seeProductName" /> <after> + <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCatalog" /> + <deleteData createDataKey="createPreReqProduct" stepKey="deletePreReqProduct" /> <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> <actionGroup ref="logout" stepKey="logout"/> </after> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsPageTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsPageTest.xml index 234cfb200b6c3..bbbb282c17678 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsPageTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminCreateCmsPageTest.xml @@ -33,6 +33,7 @@ <fillField selector="{{CmsNewPagePageContentSection.content}}" userInput="{{_defaultCmsPage.content}}" stepKey="fillFieldContent"/> <click selector="{{CmsNewPagePageSeoSection.header}}" stepKey="clickExpandSearchEngineOptimisation"/> <fillField selector="{{CmsNewPagePageSeoSection.urlKey}}" userInput="{{_defaultCmsPage.identifier}}" stepKey="fillFieldUrlKey"/> + <waitForElementVisible selector="{{CmsNewPagePageActionsSection.savePage}}" stepKey="waitForSaveButtonVisible"/> <click selector="{{CmsNewPagePageActionsSection.savePage}}" stepKey="clickSavePage"/> <see userInput="You saved the page." stepKey="seeSuccessMessage"/> <amOnPage url="{{_defaultCmsPage.identifier}}" stepKey="amOnPageTestPage"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminSwitchWYSIWYGOptionsCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminSwitchWYSIWYGOptionsCest.xml index 11cec94b91b54..56edb80d7f759 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminSwitchWYSIWYGOptionsCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/AdminSwitchWYSIWYGOptionsCest.xml @@ -10,14 +10,13 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AdminSwitchWYSIWYGOptionsCest"> <annotations> - <features value="TinyMCEv4"/> - <stories value="Admin are able to switch between TinyMCE versions MAGETWO-51829"/> - <group value="switcher"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-51829-Extensible list of WYSIWYG editors available in Magento"/> + <group value="Cms"/> <title value="Admin are able to switch between versions of TinyMCE."/> <description value="Admin are able to switch between versions of TinyMCE."/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-82936"/> - <group value="skip" /> </annotations> <before> <actionGroup ref="LoginActionGroup" stepKey="loginGetFromGeneralFile"/> @@ -35,8 +34,8 @@ <waitForPageLoad stepKey="wait1"/> <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle1"/> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab1" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> - <seeElement selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="seeTinyMCE4" /> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> + <seeElement selector="{{TinyMCESection.TinyMCE4}}" stepKey="seeTinyMCE4" /> <executeJS function="tinyMCE.activeEditor.setContent('Hello TinyMCE4!');" stepKey="executeJSFillContent1"/> <click selector="{{CmsWYSIWYGSection.ShowHideBtn}}" stepKey="clickShowHideBtn1" /> <scrollTo selector="{{CmsNewPagePageSeoSection.header}}" stepKey="scrollToSearchEngineTab1" /> @@ -49,7 +48,7 @@ <!--see widget on Storefront--> <see userInput="Hello TinyMCE4!" stepKey="seeContent1"/> <amOnPage url="{{ConfigurationStoresPage.url}}" stepKey="navigateToWYSIWYGConfigPage2"/> - <click selector="{{ContentManagementSection.WYSIWYGOptions}}" stepKey="expandWYSIWYGOptions2" /> + <conditionalClick stepKey="expandWYSIWYGOptions" selector="{{ContentManagementSection.WYSIWYGOptions}}" dependentSelector="{{ContentManagementSection.CheckIfTabExpand}}" visible="true" /> <waitForElementVisible selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="waitForCheckbox2" /> <uncheckOption selector="{{ContentManagementSection.SwitcherSystemValue}}" stepKey="uncheckUseSystemValue2"/> <waitForElementVisible selector="{{ContentManagementSection.Switcher}}" stepKey="waitForSwitcherDropdown2" /> @@ -60,8 +59,8 @@ <waitForPageLoad stepKey="wait2"/> <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle2"/> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab2" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE3}}" stepKey="waitForTinyMCE3"/> - <seeElement selector="{{CmsWYSIWYGSection.TinyMCE3}}" stepKey="seeTinyMCE3" /> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE3}}" stepKey="waitForTinyMCE3"/> + <seeElement selector="{{TinyMCESection.TinyMCE3}}" stepKey="seeTinyMCE3" /> <executeJS function="tinyMCE.activeEditor.setContent('Hello TinyMCE3!');" stepKey="executeJSFillContent2"/> <click selector="{{CmsWYSIWYGSection.ShowHideBtn}}" stepKey="clickShowHideBtn2" /> <scrollTo selector="{{CmsNewPagePageSeoSection.header}}" stepKey="scrollToSearchEngineTab2" /> @@ -73,6 +72,7 @@ <waitForPageLoad stepKey="wait4" /> <!--see widget on Storefront--> <see userInput="Hello TinyMCE3!" stepKey="seeContent2"/> + <actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4" /> <after> <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> <actionGroup ref="logout" stepKey="logout"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnBlockCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnBlockCest.xml index 15c0b8c8e6639..c6faf6bdce28f 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnBlockCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnBlockCest.xml @@ -10,17 +10,16 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="DefaultTinyMCEv4onBlockPage"> <annotations> - <features value="TinyMCEv4"/> - <stories value="Apply new WYSIWYG on Block Page-MAGETWO-42046"/> - <group value="blockWYSIWYG"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-42046-Apply new WYSIWYG on CMS Page and Block"/> + <group value="Cms"/> <title value="Admin see TinyMCEv4.6 is native WYSIWYG on Block"/> <description value="Admin see TinyMCEv4.6 is native WYSIWYG on Block"/> <severity value="CRITICAL"/> - <testCaseId value="MAGETWO-84184 "/> - <group value="skip" /> + <testCaseId value="MAGETWO-84184"/> </annotations> <before> - <createData entity="_defaultCmsPage" stepKey="createCMSPage" /> + <createData entity="_defaultCmsPage" stepKey="createPreReqCMSPage" /> <actionGroup ref="LoginActionGroup" stepKey="loginGetFromGeneralFile"/> <actionGroup ref="EnabledWYSIWYG" stepKey="enableWYSIWYG"/> <actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4" /> @@ -30,50 +29,45 @@ <fillField selector="{{BlockNewPageBasicFieldsSection.blockTitle}}" userInput="{{_defaultBlock.title}}" stepKey="fillFieldTitle"/> <fillField selector="{{BlockNewPageBasicFieldsSection.identifier}}" userInput="{{_defaultBlock.identifier}}" stepKey="fillFieldIdentifier"/> <selectOption selector="{{BlockNewPageBasicFieldsSection.storeView}}" userInput="All Store View" stepKey="selectAllStoreView" /> - <waitForElementVisible selector="{{BlockWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE" /> - <seeElement selector="{{BlockWYSIWYGSection.TinyMCE4}}" stepKey="seeTinyMCE4" /> - <seeElement selector="{{BlockWYSIWYGSection.Style}}" stepKey="assertInfo2"/> - <seeElement selector="{{BlockWYSIWYGSection.Bold}}" stepKey="assertInfo3"/> - <seeElement selector="{{BlockWYSIWYGSection.Italic}}" stepKey="assertInfo4"/> - <seeElement selector="{{BlockWYSIWYGSection.Underline}}" stepKey="assertInfo5"/> - <seeElement selector="{{BlockWYSIWYGSection.AlignLeft}}" stepKey="assertInfo6"/> - <seeElement selector="{{BlockWYSIWYGSection.AlignCenter}}" stepKey="assertInfo7"/> - <seeElement selector="{{BlockWYSIWYGSection.AlignRight}}" stepKey="assertInfo8"/> - <seeElement selector="{{BlockWYSIWYGSection.Numlist}}" stepKey="assertInfo9"/> - <seeElement selector="{{BlockWYSIWYGSection.Bullet}}" stepKey="assertInfo10"/> - <seeElement selector="{{BlockWYSIWYGSection.InsertLink}}" stepKey="assertInfo11"/> - <seeElement selector="{{BlockWYSIWYGSection.InsertImageIcon}}" stepKey="assertInf12"/> - <seeElement selector="{{BlockWYSIWYGSection.InsertTable}}" stepKey="assertInfo13"/> - <seeElement selector="{{BlockWYSIWYGSection.SpecialCharacter}}" stepKey="assertInfo14"/> - <seeElement selector="{{BlockWYSIWYGSection.InsertWidgetIcon}}" stepKey="assertInfo15"/> - <seeElement selector="{{BlockWYSIWYGSection.InsertVariableIcon}}" stepKey="assertInfo16"/> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE" /> + <actionGroup ref="VerifyTinyMCEActionGroup" stepKey="verifyTinyMCE4"/> + <actionGroup ref="VerifyMagentoEntityActionGroup" stepKey="verifyMagentoEntities"/> <executeJS function="tinyMCE.get('cms_block_form_content').setContent('Hello Block Page!');" stepKey="executeJSFillContent"/> <click selector="{{BlockWYSIWYGSection.ShowHideBtn}}" stepKey="clickShowHideBtn1" /> - <waitForElementVisible selector="{{BlockWYSIWYGSection.InsertWidgetBtn}}" stepKey="waitForInsertWidget" /> - <see selector="{{BlockWYSIWYGSection.InsertImageBtn}}" userInput="Insert Image..." stepKey="assertInf17"/> - <see selector="{{BlockWYSIWYGSection.InsertWidgetBtn}}" userInput="Insert Widget..." stepKey="assertInfo18"/> - <see selector="{{BlockWYSIWYGSection.InsertVariableBtn}}" userInput="Insert Variable..." stepKey="assertInfo19"/> + <waitForElementVisible selector="{{TinyMCESection.InsertWidgetBtn}}" stepKey="waitForInsertWidget" /> + <see selector="{{TinyMCESection.InsertImageBtn}}" userInput="Insert Image..." stepKey="assertInf17"/> + <see selector="{{TinyMCESection.InsertWidgetBtn}}" userInput="Insert Widget..." stepKey="assertInfo18"/> + <see selector="{{TinyMCESection.InsertVariableBtn}}" userInput="Insert Variable..." stepKey="assertInfo19"/> <click selector="{{BlockNewPagePageActionsSection.saveBlock}}" stepKey="clickSaveBlock"/> <amOnPage url="{{CmsPagesPage.url}}" stepKey="amOnEditPage"/> <waitForPageLoad stepKey="waitForPageLoad2"/> - <waitForElementVisible selector="{{CmsPagesPageActionsSection.select('$$createCMSPage.identifier$$')}}" stepKey="waitForCMSPageGrid" /> - <scrollTo selector="{{CmsPagesPageActionsSection.select('$$createCMSPage.identifier$$')}}" stepKey="scrollToCMSPage" /> - <click selector="{{CmsPagesPageActionsSection.select('$$createCMSPage.identifier$$')}}" stepKey="clickSelect" /> - <waitForElementVisible selector="{{CmsPagesPageActionsSection.edit('$$createCMSPage.identifier$$')}}" stepKey="waitForEditLink" /> - <click selector="{{CmsPagesPageActionsSection.edit('$$createCMSPage.identifier$$')}}" stepKey="clickEdit" /> + <click selector="{{CmsPagesPageActionsSection.FilterBtn}}" stepKey="clickFiltersBtn" /> + <fillField selector="{{CmsPagesPageActionsSection.URLKey}}" userInput="$$createPreReqCMSPage.identifier$$" stepKey="fillOutURLKey" /> + <click selector="{{CmsPagesPageActionsSection.ApplyFiltersBtn}}" stepKey="clickApplyBtn" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoading3" /> + <actionGroup ref="SortByIdDescendingActionGroup" stepKey="sortByIdDescending" /> + <waitForElementVisible selector="{{CmsPagesPageActionsSection.select('$$createPreReqCMSPage.identifier$$')}}" stepKey="waitForCMSPageGrid" /> + <scrollTo selector="{{CmsPagesPageActionsSection.select('$$createPreReqCMSPage.identifier$$')}}" stepKey="scrollToCMSPage" /> + <click selector="{{CmsPagesPageActionsSection.select('$$createPreReqCMSPage.identifier$$')}}" stepKey="clickSelect" /> + <waitForElementVisible selector="{{CmsPagesPageActionsSection.edit('$$createPreReqCMSPage.identifier$$')}}" stepKey="waitForEditLink" /> + <click selector="{{CmsPagesPageActionsSection.edit('$$createPreReqCMSPage.identifier$$')}}" stepKey="clickEdit" /> <waitForPageLoad stepKey="waitForPageLoad3" /> + <scrollTo selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" stepKey="scrollToPageTitle" /> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab" /> <waitForElementVisible selector="{{CmsWYSIWYGSection.ShowHideBtn}}" stepKey="waitforShowHideBtn" /> <click selector="{{CmsWYSIWYGSection.ShowHideBtn}}" stepKey="clickShowHideBtn2"/> - <waitForElementVisible selector="{{CmsWYSIWYGSection.InsertWidgetBtn}}" stepKey="waitForInsertInsertWidgetBtn" /> - <seeElement selector="{{CmsWYSIWYGSection.InsertWidgetBtn}}" stepKey="widgetBtn" /> - <click selector="{{CmsWYSIWYGSection.InsertWidgetBtn}}" stepKey="clickInsertWidgetBtn"/> + <waitForElementVisible selector="{{TinyMCESection.InsertWidgetBtn}}" stepKey="waitForInsertInsertWidgetBtn" /> + <seeElement selector="{{TinyMCESection.InsertWidgetBtn}}" stepKey="widgetBtn" /> + <click selector="{{TinyMCESection.InsertWidgetBtn}}" stepKey="clickInsertWidgetBtn"/> <waitForPageLoad stepKey="waitForPageLoad4"/> <selectOption selector="{{WidgetSection.WidgetType}}" userInput="CMS Static Block" stepKey="selectCMSStaticBlock" /> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappear" /> <selectOption selector="{{WidgetSection.WidgetTemplate}}" userInput="CMS Static Block Default Template" stepKey="selectTemplate" /> <click selector="{{WidgetSection.BtnChooser}}" stepKey="clickSelectPageBtn" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappearAfterClickingBtnChooser" /> + <actionGroup ref="SortByIdDescendingActionGroup" stepKey="sortByIdDescending2" /> <waitForElementVisible selector="{{WidgetSection.BlockPage(_defaultBlock.identifier)}}" stepKey="waitForBlockCode" /> + <scrollTo selector="{{WidgetSection.BlockPage(_defaultBlock.identifier)}}" stepKey="scrollToBlockIdentifier" /> <click selector="{{WidgetSection.BlockPage(_defaultBlock.identifier)}}" stepKey="selectPreCreateBlock" /> <wait time="3" stepKey="wait1" /> <click selector="{{WidgetSection.InsertWidget}}" stepKey="clickInsertWidget" /> @@ -81,11 +75,12 @@ <waitForPageLoad stepKey="waitForPageLoad5" /> <click selector="{{CmsNewPagePageActionsSection.savePage}}" stepKey="clickSavePage"/> <see userInput="You saved the page." stepKey="seeSuccessMessage"/> - <amOnPage url="$$createCMSPage.identifier$$" stepKey="amOnPageTestPage"/> + <amOnPage url="$$createPreReqCMSPage.identifier$$" stepKey="amOnPageTestPage"/> <waitForPageLoad stepKey="waitForPageLoad6" /> <!--see content of Block on Storefront--> <see userInput="Hello Block Page!" stepKey="seeContent"/> <after> + <deleteData createDataKey="createPreReqCMSPage" stepKey="deletePreReqCMSPage" /> <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> <actionGroup ref="logout" stepKey="logout"/> </after> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCMSPageCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCMSPageCest.xml index b3879563e6d68..7978faec189db 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCMSPageCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCMSPageCest.xml @@ -10,9 +10,9 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="DefaultTinyMCEv4onCMSPage"> <annotations> - <features value="TinyMCEv4"/> - <stories value="Apply new WYSIWYG on CMS Page-MAGETWO-42046"/> - <group value="cmsWYSIWYG"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-42046-Apply new WYSIWYG on CMS Page"/> + <group value="Cms"/> <title value="Admin see TinyMCEv4.6 is native WYSIWYG on CMS Page"/> <description value="Admin see TinyMCEv4.6 is native WYSIWYG on CMS Page"/> <severity value="CRITICAL"/> @@ -29,32 +29,19 @@ <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{_defaultCmsPage.title}}" stepKey="fillFieldTitle"/> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickExpandContent"/> <fillField selector="{{CmsNewPagePageContentSection.contentHeading}}" userInput="{{_defaultCmsPage.content_heading}}" stepKey="fillFieldContentHeading"/> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE" /> - <seeElement selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="seeTinyMCE4" /> - <seeElement selector="{{CmsWYSIWYGSection.Style}}" stepKey="assertInfo2"/> - <seeElement selector="{{CmsWYSIWYGSection.Bold}}" stepKey="assertInfo3"/> - <seeElement selector="{{CmsWYSIWYGSection.Italic}}" stepKey="assertInfo4"/> - <seeElement selector="{{CmsWYSIWYGSection.Underline}}" stepKey="assertInfo5"/> - <seeElement selector="{{CmsWYSIWYGSection.AlignLeft}}" stepKey="assertInfo6"/> - <seeElement selector="{{CmsWYSIWYGSection.AlignCenter}}" stepKey="assertInfo7"/> - <seeElement selector="{{CmsWYSIWYGSection.AlignRight}}" stepKey="assertInfo8"/> - <seeElement selector="{{CmsWYSIWYGSection.Numlist}}" stepKey="assertInfo9"/> - <seeElement selector="{{CmsWYSIWYGSection.Bullet}}" stepKey="assertInfo10"/> - <seeElement selector="{{CmsWYSIWYGSection.InsertLink}}" stepKey="assertInfo11"/> - <seeElement selector="{{CmsWYSIWYGSection.InsertImageIcon}}" stepKey="assertInf12"/> - <seeElement selector="{{CmsWYSIWYGSection.InsertTable}}" stepKey="assertInfo13"/> - <seeElement selector="{{CmsWYSIWYGSection.SpecialCharacter}}" stepKey="assertInfo14"/> - <seeElement selector="{{CmsWYSIWYGSection.InsertWidgetIcon}}" stepKey="assertInfo15"/> - <seeElement selector="{{CmsWYSIWYGSection.InsertVariableIcon}}" stepKey="assertInfo16"/> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE" /> + <actionGroup ref="VerifyTinyMCEActionGroup" stepKey="verifyTinyMCE4"/> + <actionGroup ref="VerifyMagentoEntityActionGroup" stepKey="verifyMagentoEntities"/> <executeJS function="tinyMCE.get('cms_page_form_content').setContent('Hello World!');" stepKey="executeJSFillContent"/> <click selector="{{CmsWYSIWYGSection.ShowHideBtn}}" stepKey="clickShowHideBtn" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.InsertWidgetBtn}}" stepKey="waitForInsertWidget" /> - <see selector="{{CmsWYSIWYGSection.InsertImageBtn}}" userInput="Insert Image..." stepKey="assertInf17"/> - <see selector="{{CmsWYSIWYGSection.InsertWidgetBtn}}" userInput="Insert Widget..." stepKey="assertInfo18"/> - <see selector="{{CmsWYSIWYGSection.InsertVariableBtn}}" userInput="Insert Variable..." stepKey="assertInfo19"/> + <waitForElementVisible selector="{{TinyMCESection.InsertWidgetBtn}}" stepKey="waitForInsertWidget" /> + <see selector="{{TinyMCESection.InsertImageBtn}}" userInput="Insert Image..." stepKey="assertInf17"/> + <see selector="{{TinyMCESection.InsertWidgetBtn}}" userInput="Insert Widget..." stepKey="assertInfo18"/> + <see selector="{{TinyMCESection.InsertVariableBtn}}" userInput="Insert Variable..." stepKey="assertInfo19"/> <click selector="{{CmsNewPagePageSeoSection.header}}" stepKey="clickExpandSearchEngineOptimisation"/> <fillField selector="{{CmsNewPagePageSeoSection.urlKey}}" userInput="{{_defaultCmsPage.identifier}}" stepKey="fillFieldUrlKey"/> <click selector="{{CmsNewPagePageActionsSection.savePage}}" stepKey="clickSavePage"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoading" /> <see userInput="You saved the page." stepKey="seeSuccessMessage"/> <amOnPage url="{{_defaultCmsPage.identifier}}" stepKey="amOnPageTestPage"/> <waitForPageLoad stepKey="waitForPageLoad2"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/ActionGroup/ConfigAdminAccountSharingActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/ActionGroup/ConfigAdminAccountSharingActionGroup.xml new file mode 100644 index 0000000000000..efd6574e7f4af --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/ActionGroup/ConfigAdminAccountSharingActionGroup.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> +<actionGroup name="ConfigAdminAccountSharingActionGroup"> + <amOnPage url="{{_ENV.MAGENTO_BACKEND_NAME}}/admin/system_config/edit/section/admin/" stepKey="navigateToConfigurationPage" /> + <waitForPageLoad stepKey="wait1"/> + <conditionalClick stepKey="expandSecurityTab" selector="{{AdminSection.SecurityTab}}" dependentSelector="{{AdminSection.CheckIfTabExpand}}" visible="true" /> + <waitForElementVisible selector="{{AdminSection.AdminAccountSharing}}" stepKey="waitForAdminAccountSharingDrpDown" /> + <uncheckOption selector="{{AdminSection.EnableSystemValue}}" stepKey="uncheckUseSystemValue"/> + <selectOption selector="{{AdminSection.AdminAccountSharing}}" userInput="Yes" stepKey="selectYes"/> + <click selector="{{AdminSection.SecurityTab}}" stepKey="clollapseSecurityTab" /> + <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig" /> +</actionGroup> +</actionGroups> + diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/ConfigWYSIWYGActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/ActionGroup/ConfigWYSIWYGActionGroup.xml similarity index 100% rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/ConfigWYSIWYGActionGroup.xml rename to dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/ActionGroup/ConfigWYSIWYGActionGroup.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/SwitcherActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/ActionGroup/SwitcherActionGroup.xml similarity index 100% rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/SwitcherActionGroup.xml rename to dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/ActionGroup/SwitcherActionGroup.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/Section/AdminSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/Section/AdminSection.xml new file mode 100644 index 0000000000000..294f08326f63b --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Config/Section/AdminSection.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="AdminSection"> + <element name="CheckIfTabExpand" type="button" selector="#admin_security-head:not(.open)"/> + <element name="SecurityTab" type="button" selector="#admin_security-head"/> + <element name="AdminAccountSharing" type="button" selector="#admin_security_admin_account_sharing"/> + <element name="EnableSystemValue" type="button" selector="#admin_security_admin_account_sharing_inherit"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/ActionGroup/LoginToStorefrontActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/ActionGroup/LoginToStorefrontActionGroup.xml new file mode 100644 index 0000000000000..ee455a4c03984 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Customer/ActionGroup/LoginToStorefrontActionGroup.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="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="LoginToStorefrontActionGroup"> + <arguments> + <argument name="Customer"/> + </arguments> + <amOnPage stepKey="amOnSignInPage" url="{{StorefrontCustomerSignInPage.url}}"/> + <fillField stepKey="fillEmail" userInput="{{Customer.email}}" selector="{{StorefrontCustomerSignInFormSection.emailField}}"/> + <fillField stepKey="fillPassword" userInput="{{Customer.password}}" selector="{{StorefrontCustomerSignInFormSection.passwordField}}"/> + <click stepKey="clickSignInAccountButton" selector="{{StorefrontCustomerSignInFormSection.signInAccountButton}}"/> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddImageToWYSIWYGNewsletterCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddImageToWYSIWYGNewsletterCest.xml index cdd62ac97de09..a8e08bccec8c4 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddImageToWYSIWYGNewsletterCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddImageToWYSIWYGNewsletterCest.xml @@ -9,11 +9,11 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AddImageToNewsletter"> <annotations> - <features value="Add Image to WYSIWYG of Newsletter"/> - <stories value="Apply new WYSIWYG in Newsletter-MAGETWO-47309"/> - <group value="newsletter"/> - <title value="You should be able to add image to WYSIWYG Editor of Newsletter"/> - <description value="You should be able to add image to WYSIWYG Editor Newsletter"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-47309-Apply new WYSIWYG in Newsletter"/> + <group value="Newsletter"/> + <title value="Admin should be able to add image to WYSIWYG content of Newsletter"/> + <description value="Admin should be able to add image to WYSIWYG content Newsletter"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-84377"/> </annotations> @@ -29,45 +29,45 @@ <fillField selector="{{BasicFieldNewsletterSection.senderName}}" userInput="{{_defaultNewsletter.senderName}}" stepKey="fillSenderName" /> <fillField selector="{{BasicFieldNewsletterSection.senderEmail}}" userInput="{{_defaultNewsletter.senderEmail}}" stepKey="fillSenderEmail" /> <waitForElementVisible selector="{{NewsletterWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE4"/> - <click selector="{{CmsWYSIWYGSection.InsertImageIcon}}" stepKey="clickInsertImageIcon" /> + <click selector="{{TinyMCESection.InsertImageIcon}}" stepKey="clickInsertImageIcon" /> <waitForPageLoad stepKey="waitForPageLoad" /> - <click selector="{{CmsWYSIWYGSection.Browse}}" stepKey="clickBrowse" /> - <waitForElement selector="{{CmsWYSIWYGSection.CancelBtn}}" stepKey="waitForCancelBtn" /> + <click selector="{{MediaGallerySection.Browse}}" stepKey="clickBrowse" /> + <waitForElement selector="{{MediaGallerySection.CancelBtn}}" stepKey="waitForCancelBtn" /> <waitForPageLoad stepKey="waitForPageLoad2" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading1" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading2" /> - <waitForElement selector="{{CmsWYSIWYGSection.StorageRootArrow}}" stepKey="waitForStorageFoot" /> - <see selector="{{CmsWYSIWYGSection.CancelBtn}}" userInput="Cancel" stepKey="seeCancelBtn" /> - <see selector="{{CmsWYSIWYGSection.CreateFolder}}" userInput="Create Folder" stepKey="seeCreateFolderBtn" /> - <see selector="{{CmsWYSIWYGSection.InsertFile}}" userInput="Add Selected" stepKey="seeAddSelectedBtn" /> - <click selector="{{CmsWYSIWYGSection.CreateFolder}}" stepKey="createFolder"/> - <waitForElementVisible selector="{{CmsWYSIWYGSection.FolderName}}" stepKey="waitForPopUp" /> - <fillField selector="{{CmsWYSIWYGSection.FolderName}}" userInput="{{ImageFolder.name}}" stepKey="fillFolderName" /> - <click selector="{{CmsWYSIWYGSection.AcceptFolderName}}" stepKey="acceptFolderName" /> + <waitForElement selector="{{MediaGallerySection.StorageRootArrow}}" stepKey="waitForStorageFoot" /> + <see selector="{{MediaGallerySection.CancelBtn}}" userInput="Cancel" stepKey="seeCancelBtn" /> + <see selector="{{MediaGallerySection.CreateFolder}}" userInput="Create Folder" stepKey="seeCreateFolderBtn" /> + <see selector="{{MediaGallerySection.InsertFile}}" userInput="Add Selected" stepKey="seeAddSelectedBtn" /> + <click selector="{{MediaGallerySection.CreateFolder}}" stepKey="createFolder"/> + <waitForElementVisible selector="{{MediaGallerySection.FolderName}}" stepKey="waitForPopUp" /> + <fillField selector="{{MediaGallerySection.FolderName}}" userInput="{{ImageFolder.name}}" stepKey="fillFolderName" /> + <click selector="{{MediaGallerySection.AcceptFolderName}}" stepKey="acceptFolderName" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading3" /> - <conditionalClick selector="{{CmsWYSIWYGSection.StorageRootArrow}}" dependentSelector="{{CmsWYSIWYGSection.checkIfArrowExpand}}" stepKey="clickArrowIfCloses" visible="true"/> + <conditionalClick selector="{{MediaGallerySection.StorageRootArrow}}" dependentSelector="{{MediaGallerySection.checkIfArrowExpand}}" stepKey="clickArrowIfCloses" visible="true"/> <waitForText userInput="{{ImageFolder.name}}" stepKey="waitForNewFolder" /> <click userInput="{{ImageFolder.name}}" stepKey="clickOnCreatedFolder" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading5" /> - <attachFile selector="{{CmsWYSIWYGSection.BrowseUploadImage}}" userInput="{{ImageUpload.file}}" stepKey="uploadImage1"/> + <attachFile selector="{{MediaGallerySection.BrowseUploadImage}}" userInput="{{ImageUpload.file}}" stepKey="uploadImage1"/> <waitForLoadingMaskToDisappear stepKey="waitForLoading6" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.image(ImageUpload.file)}}" stepKey="waitForUploadImage1" /> - <seeElement selector="{{CmsWYSIWYGSection.imageSelected(ImageUpload.file)}}" stepKey="seeImageSelected" /> - <see selector="{{CmsWYSIWYGSection.DeleteSelectedBtn}}" userInput="Delete Selected" stepKey="seeDeleteBtn"/> - <click selector="{{CmsWYSIWYGSection.DeleteSelectedBtn}}" stepKey="clickDeleteSelected" /> + <waitForElementVisible selector="{{MediaGallerySection.image(ImageUpload.file)}}" stepKey="waitForUploadImage1" /> + <seeElement selector="{{MediaGallerySection.imageSelected(ImageUpload.file)}}" stepKey="seeImageSelected" /> + <see selector="{{MediaGallerySection.DeleteSelectedBtn}}" userInput="Delete Selected" stepKey="seeDeleteBtn"/> + <click selector="{{MediaGallerySection.DeleteSelectedBtn}}" stepKey="clickDeleteSelected" /> <waitForText userInput="OK" stepKey="waitForConfirm" /> - <click selector="{{CmsWYSIWYGSection.confirmDelete}}" stepKey="confirmDelete" /> - <waitForElementNotVisible selector="{{CmsWYSIWYGSection.image(ImageUpload.file)}}" stepKey="waitForImageDeleted" /> - <dontSeeElement selector="{{CmsWYSIWYGSection.image(ImageUpload.file)}}" stepKey="dontSeeImage" /> - <attachFile selector="{{CmsWYSIWYGSection.BrowseUploadImage}}" userInput="{{ImageUpload.file}}" stepKey="uploadImage2"/> + <click selector="{{MediaGallerySection.confirmDelete}}" stepKey="confirmDelete" /> + <waitForElementNotVisible selector="{{MediaGallerySection.image(ImageUpload.file)}}" stepKey="waitForImageDeleted" /> + <dontSeeElement selector="{{MediaGallerySection.image(ImageUpload.file)}}" stepKey="dontSeeImage" /> + <attachFile selector="{{MediaGallerySection.BrowseUploadImage}}" userInput="{{ImageUpload.file}}" stepKey="uploadImage2"/> <waitForLoadingMaskToDisappear stepKey="waitForLoading9" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.image(ImageUpload.file)}}" stepKey="waitForUploadImage2" /> - <click selector="{{CmsWYSIWYGSection.InsertFile}}" stepKey="clickInsertBtn" /> + <waitForElementVisible selector="{{MediaGallerySection.image(ImageUpload.file)}}" stepKey="waitForUploadImage2" /> + <click selector="{{MediaGallerySection.InsertFile}}" stepKey="clickInsertBtn" /> <waitForLoadingMaskToDisappear stepKey="waitForLoading7" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.OkBtn}}" stepKey="waitForOkBtn" /> - <fillField selector="{{CmsWYSIWYGSection.ImageDescription}}" userInput="{{ImageUpload.content}}" stepKey="fillImageDescription" /> - <fillField selector="{{CmsWYSIWYGSection.Height}}" userInput="{{ImageUpload.height}}" stepKey="fillImageHeight" /> - <click selector="{{CmsWYSIWYGSection.OkBtn}}" stepKey="clickOkBtn" /> + <waitForElementVisible selector="{{MediaGallerySection.OkBtn}}" stepKey="waitForOkBtn" /> + <fillField selector="{{MediaGallerySection.ImageDescription}}" userInput="{{ImageUpload.content}}" stepKey="fillImageDescription" /> + <fillField selector="{{MediaGallerySection.Height}}" userInput="{{ImageUpload.height}}" stepKey="fillImageHeight" /> + <click selector="{{MediaGallerySection.OkBtn}}" stepKey="clickOkBtn" /> <waitForPageLoad stepKey="waitForPageLoad8"/> <!--Go to Storefront--> <click selector="{{BasicFieldNewsletterSection.save}}" stepKey="clickSaveTemplate"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddVariableToWYSIWYGNewsletterCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddVariableToWYSIWYGNewsletterCest.xml index 2c9c0066a6622..fa40177cc9fa3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddVariableToWYSIWYGNewsletterCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddVariableToWYSIWYGNewsletterCest.xml @@ -9,13 +9,12 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AddVariableToNewsletter"> <annotations> - <features value="Add Variable to WYSIWYG Newsletter"/> - <stories value="Add Variable to WYSIWYG MAGETWO-42158"/> - <group value="newsletter"/> - <title value="You should be able to add variable to WYSIWYG Editor of Newsletter"/> - <description value="You should be able to add variable to WYSIWYG Editor Newsletter"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-42158-Variables with WYSIWYG"/> + <group value="Newsletter"/> + <title value="Admin should be able to add variable to WYSIWYG Editor of Newsletter"/> + <description value="Admin should be able to add variable to WYSIWYG Editor Newsletter"/> <testCaseId value="MAGETWO-84379"/> - <group value="skip"/> </annotations> <before> <actionGroup ref="LoginActionGroup" stepKey="loginGetFromGeneralFile"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddWidgetToWYSIWYGNewsletterCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddWidgetToWYSIWYGNewsletterCest.xml index 105a543733442..85ba7e6fcc9c3 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddWidgetToWYSIWYGNewsletterCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/AdminAddWidgetToWYSIWYGNewsletterCest.xml @@ -9,9 +9,9 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="AddWidgetToNewsletter"> <annotations> - <features value="Add Widget to WYSIWYG of Newsletter"/> - <stories value="Apply new WYSIWYG in Newsletter-MAGETWO-47309"/> - <group value="newsletter"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-47309-Apply new WYSIWYG in Newsletter"/> + <group value="Newsletter"/> <title value="You should be able to add widget to WYSIWYG Editor of Newsletter"/> <description value="You should be able to add widget to WYSIWYG Editor Newsletter"/> <severity value="CRITICAL"/> @@ -28,7 +28,7 @@ <fillField selector="{{BasicFieldNewsletterSection.templateSubject}}" userInput="{{_defaultNewsletter.subject}}" stepKey="fillTemplateSubject" /> <fillField selector="{{BasicFieldNewsletterSection.senderName}}" userInput="{{_defaultNewsletter.senderName}}" stepKey="fillSenderName" /> <fillField selector="{{BasicFieldNewsletterSection.senderEmail}}" userInput="{{_defaultNewsletter.senderEmail}}" stepKey="fillSenderEmail" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE" /> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE" /> <click selector="{{NewsletterWYSIWYGSection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> <wait time="10" stepKey="waitForPageLoad" /> <see userInput="Inserting a widget does not create a widget instance." stepKey="seeMessage" /> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnNewsletterCest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnNewsletterCest.xml index 5c2a126a63d5c..f9571a6e7477e 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnNewsletterCest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Newsletter/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnNewsletterCest.xml @@ -9,9 +9,9 @@ xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> <test name="DefaultTinyMCEv4onNewsletter"> <annotations> - <features value="TinyMCEv4"/> - <stories value="Apply new WYSIWYG in Newsletter-MAGETWO-47309"/> - <group value="newsletter"/> + <features value="MAGETWO-36659-[CMS] WYSIWYG update"/> + <stories value="MAGETWO-47309-Apply new WYSIWYG in Newsletter"/> + <group value="Newsletter"/> <title value="Admin see TinyMCEv4.6 is native WYSIWYG on Newsletter"/> <description value="Admin see TinyMCEv4.6 is native WYSIWYG on Newsletter"/> <severity value="CRITICAL"/> @@ -28,26 +28,12 @@ <fillField selector="{{BasicFieldNewsletterSection.templateSubject}}" userInput="{{_defaultNewsletter.subject}}" stepKey="fillTemplateSubject" /> <fillField selector="{{BasicFieldNewsletterSection.senderName}}" userInput="{{_defaultNewsletter.senderName}}" stepKey="fillSenderName" /> <fillField selector="{{BasicFieldNewsletterSection.senderEmail}}" userInput="{{_defaultNewsletter.senderEmail}}" stepKey="fillSenderEmail" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.TinyMCE4}}" stepKey="waitForTinyMCE" /> - <seeElement selector="{{NewsletterWYSIWYGSection.TinyMCE4}}" stepKey="seeTinyMCE4" /> - <seeElement selector="{{NewsletterWYSIWYGSection.Style}}" stepKey="assertInfo2"/> - <seeElement selector="{{NewsletterWYSIWYGSection.Bold}}" stepKey="assertInfo3"/> - <seeElement selector="{{NewsletterWYSIWYGSection.Italic}}" stepKey="assertInfo4"/> - <seeElement selector="{{NewsletterWYSIWYGSection.Underline}}" stepKey="assertInfo5"/> - <seeElement selector="{{NewsletterWYSIWYGSection.AlignLeft}}" stepKey="assertInfo6"/> - <seeElement selector="{{NewsletterWYSIWYGSection.AlignCenter}}" stepKey="assertInfo7"/> - <seeElement selector="{{NewsletterWYSIWYGSection.AlignRight}}" stepKey="assertInfo8"/> - <seeElement selector="{{NewsletterWYSIWYGSection.Numlist}}" stepKey="assertInfo9"/> - <seeElement selector="{{NewsletterWYSIWYGSection.Bullet}}" stepKey="assertInfo10"/> - <seeElement selector="{{NewsletterWYSIWYGSection.InsertLink}}" stepKey="assertInfo11"/> - <seeElement selector="{{NewsletterWYSIWYGSection.InsertImageIcon}}" stepKey="assertInf12"/> - <seeElement selector="{{NewsletterWYSIWYGSection.InsertTable}}" stepKey="assertInfo13"/> - <seeElement selector="{{NewsletterWYSIWYGSection.SpecialCharacter}}" stepKey="assertInfo14"/> - <seeElement selector="{{NewsletterWYSIWYGSection.InsertWidgetIcon}}" stepKey="assertInfo15"/> - <seeElement selector="{{NewsletterWYSIWYGSection.InsertVariableIcon}}" stepKey="assertInfo16"/> + <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE" /> + <actionGroup ref="VerifyTinyMCEActionGroup" stepKey="verifyTinyMCE4"/> + <actionGroup ref="VerifyMagentoEntityActionGroup" stepKey="verifyMagentoEntities"/> <executeJS function="tinyMCE.get('text').setContent('Hello World From Newsletter Template!');" stepKey="executeJSFillContent"/> <click selector="{{NewsletterWYSIWYGSection.ShowHideBtn}}" stepKey="clickShowHideBtn2" /> - <waitForElementVisible selector="{{CmsWYSIWYGSection.InsertWidgetBtn}}" stepKey="waitForInsertWidget" /> + <waitForElementVisible selector="{{TinyMCESection.InsertWidgetBtn}}" stepKey="waitForInsertWidget" /> <see selector="{{NewsletterWYSIWYGSection.InsertImageBtn}}" userInput="Insert Image..." stepKey="assertInf17"/> <see selector="{{NewsletterWYSIWYGSection.InsertWidgetBtn}}" userInput="Insert Widget..." stepKey="assertInfo18"/> <see selector="{{NewsletterWYSIWYGSection.InsertVariableBtn}}" userInput="Insert Variable..." stepKey="assertInfo19"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/ActionGroup/ApplyCartRuleOnStorefrontActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/ActionGroup/ApplyCartRuleOnStorefrontActionGroup.xml new file mode 100644 index 0000000000000..06318f5080943 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/ActionGroup/ApplyCartRuleOnStorefrontActionGroup.xml @@ -0,0 +1,28 @@ +<?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="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="ApplyCartRuleOnStorefrontActionGroup"> + <arguments> + <argument name="Product" defaultValue="_defaultProduct"/> + <argument name="Coupon" defaultValue="SimpleSalesRuleCoupon"/> + </arguments> + <amOnPage url="{{Product.name}}.html" stepKey="navigateToProductPage"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addToCart" /> + <waitForText userInput="You added {{Product.name}} to your shopping cart." stepKey="waitForAddedBtn"/> + <amOnPage url="/checkout/cart/" stepKey="onPageShoppingCart"/> + <waitForPageLoad stepKey="waitForPageLoad2"/> + <click selector="{{DiscountSection.DiscountTab}}" stepKey="scrollToDiscountTab" /> + <fillField selector="{{DiscountSection.CouponInput}}" userInput="{{Coupon.code}}" stepKey="fillCouponCode" /> + <click selector="{{DiscountSection.ApplyCodeBtn}}" stepKey="applyCode"/> + <waitForPageLoad stepKey="waitForPageLoad3"/> + <waitForText userInput="You used coupon code" stepKey="waitForText"/> + <see userInput="You used coupon code" stepKey="assertText"/> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Data/SalesRuleCouponData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Data/SalesRuleCouponData.xml new file mode 100644 index 0000000000000..b2e9f3d61abff --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Data/SalesRuleCouponData.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="SimpleSalesRuleCoupon" type="SalesRuleCoupon"> + <var key="rule_id" entityKey="rule_id" entityType="SalesRule"/> + <data key="code" unique="suffix">Code</data> + <data key="is_primary">1</data> + </entity> +</entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Data/SalesRuleData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Data/SalesRuleData.xml new file mode 100644 index 0000000000000..f26ce7dea1ece --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Data/SalesRuleData.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="SimpleSalesRule" type="SalesRule"> + <data key="name" unique="suffix">SimpleSalesRule</data> + <data key="is_active">true</data> + <data key="coupon_type">SPECIFIC_COUPON</data> + <data key="uses_per_coupon">10</data> + <data key="uses_per_customer">10</data> + <data key="simple_action">by_percent</data> + <array key="customer_group_ids"> + <item>0</item> + </array> + <array key="website_ids"> + <item>1</item> + </array> + </entity> +</entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Metadata/sales_rule-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Metadata/sales_rule-meta.xml index cb4df44683b11..63795e3e6b2de 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Metadata/sales_rule-meta.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Metadata/sales_rule-meta.xml @@ -72,4 +72,7 @@ </object> </object> </operation> + <operation name="DeleteSalesRule" dataType="SalesRule" type="delete" auth="adminOauth" url="/V1/salesRules/{rule_id}" method="DELETE"> + <contentType>application/json</contentType> + </operation> </operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Metadata/sales_rule_coupon-meta.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Metadata/sales_rule_coupon-meta.xml new file mode 100644 index 0000000000000..4debb7b2e4a2a --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Metadata/sales_rule_coupon-meta.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd"> + <operation name="CreateSalesRuleCoupon" dataType="SalesRuleCoupon" type="create" auth="adminOauth" url="/V1/coupons" method="POST"> + <contentType>application/json</contentType> + <object key="coupon" dataType="SalesRuleCoupon"> + <field key="rule_id" required="true">integer</field> + <field key="code">string</field> + <field key="usage_limit">integer</field> + <field key="usage_per_customer">integer</field> + <field key="times_used">integer</field> + <field key="expiration_date">string</field> + <field key="is_primary">boolean</field> + <field key="created_at">string</field> + <field key="type">integer</field> + </object> + </operation> + <operation name="DeleteSalesRuleCoupon" dataType="SalesRuleCoupon" type="delete" auth="adminOauth" url="/V1/coupons/{coupon_id}" method="DELETE"> + <contentType>application/json</contentType> + </operation> +</operations> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Section/DiscountSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Section/DiscountSection.xml new file mode 100644 index 0000000000000..853e8f75a217b --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/SalesRule/Section/DiscountSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="DiscountSection"> + <element name="DiscountTab" type="button" selector="//strong[text()='Apply Discount Code']"/> + <element name="CouponInput" type="input" selector="#coupon_code"/> + <element name="ApplyCodeBtn" type="button" selector="//span[text()='Apply Discount']"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminCreateStoreViewActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminCreateStoreViewActionGroup.xml new file mode 100644 index 0000000000000..4cf0e64ed467e --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/ActionGroup/AdminCreateStoreViewActionGroup.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<!-- Test XML Example --> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminCreateStoreViewActionGroup"> + <arguments> + <argument name="StoreGroup" defaultValue="_defaultStoreGroup"/> + </arguments> + <amOnPage url="{{AdminSystemStoreViewPage.url}}" stepKey="navigateToNewStoreView"/> + <waitForPageLoad stepKey="waitForPageLoad1" /> + <!--Create Store View--> + <selectOption selector="{{AdminNewStoreSection.storeGrpDropdown}}" userInput="{{StoreGroup.name}}" stepKey="selectStore" /> + <fillField selector="{{AdminNewStoreSection.storeNameTextField}}" userInput="{{customStore.name}}" stepKey="enterStoreViewName" /> + <fillField selector="{{AdminNewStoreSection.storeCodeTextField}}" userInput="{{customStore.code}}" stepKey="enterStoreViewCode" /> + <selectOption selector="{{AdminNewStoreSection.statusDropdown}}" userInput="Enabled" stepKey="setStatus" /> + <click selector="{{AdminNewStoreViewActionsSection.saveButton}}" stepKey="clickSaveStoreView" /> + <waitForElementVisible selector=".action-primary.action-accept" stepKey="waitForModal" /> + <seeInSource html="'Warning message'" stepKey="seeWarning" /> + <click selector=".action-primary.action-accept" stepKey="dismissModal" /> + <waitForPageLoad stepKey="waitForPageLoad2"/> + <waitForElementVisible selector="{{AdminStoresGridSection.storeFilterTextField}}" stepKey="waitForPageReolad"/> + <see userInput="You saved the store view." stepKey="seeSavedMessage" /> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Data/StoreGroupData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Data/StoreGroupData.xml index f59d363ad2065..891d307808760 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Data/StoreGroupData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Data/StoreGroupData.xml @@ -6,6 +6,12 @@ */ --> <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="_defaultStoreGroup" type="group"> + <data key="name">Main Website Store</data> + <data key="code">main_website_store</data> + <data key="root_category_id">2</data> + <data key="website_id">1</data> + </entity> <entity name="customStoreGroup" type="group"> <data key="group_id">null</data> <data key="name" unique="suffix">store</data> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Page/AdminSystemStoreViewPage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Page/AdminSystemStoreViewPage.xml new file mode 100644 index 0000000000000..6c62481d473a9 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Page/AdminSystemStoreViewPage.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> + <page name="AdminSystemStoreViewPage" url="admin/system_store/newStore" module="Store" area="admin"> + <section name="AdminNewStoreViewMainActionsSection"/> + <section name="AdminNewStoreSection"/> + </page> +</pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Section/AdminNewStoreViewActionsSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Section/AdminNewStoreViewActionsSection.xml new file mode 100644 index 0000000000000..5c731682e427c --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Section/AdminNewStoreViewActionsSection.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="AdminNewStoreViewActionsSection"> + <element name="backButton" type="button" selector="#back"/> + <element name="resetButton" type="button" selector="#reset"/> + <element name="saveButton" type="button" selector="#save"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreGroupTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreGroupTest.xml index d8766dff9a0c3..58867227d08da 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreGroupTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreGroupTest.xml @@ -26,6 +26,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin1"/> <amOnPage stepKey="s9" url="{{AdminSystemStorePage.url}}"/> + <waitForPageLoad stepKey="waitForPageLoad" /> <click stepKey="s11" selector="{{AdminStoresGridSection.resetButton}}"/> <waitForPageLoad stepKey="s15" time="10"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreViewTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreViewTest.xml new file mode 100644 index 0000000000000..6fcaf45a0acbc --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Store/Test/AdminCreateStoreViewTest.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<!-- Test XML Example --> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="AdminCreateStoreViewTest"> + <annotations> + <title value="Create a store view in admin"/> + <description value="Create a store view in admin"/> + <group value="storeView"/> + </annotations> + <before> + <actionGroup ref="LoginActionGroup" stepKey="login"/> + </before> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView" /> + <!--Confirm new store view on Store Grid--> + <fillField selector="{{AdminStoresGridSection.storeFilterTextField}}" userInput="{{customStore.name}}" stepKey="fillStoreViewFilter"/> + <click selector="{{AdminStoresGridSection.searchButton}}" stepKey="clickSearch" /> + <waitForPageLoad stepKey="waitForPageLoad"/> + <see selector="{{AdminStoresGridSection.storeNameInFirstRow}}" userInput="{{customStore.name}}" stepKey="seeNewStoreView" /> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/ActionGroup/AdminCreateUserActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/ActionGroup/AdminCreateUserActionGroup.xml new file mode 100644 index 0000000000000..f3edad3a082bb --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/ActionGroup/AdminCreateUserActionGroup.xml @@ -0,0 +1,34 @@ +<?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="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminCreateUserActionGroup"> + <arguments> + <argument name="role"/> + <argument name="User" defaultValue="admin2"/> + </arguments> + <amOnPage url="{{AdminEditUserPage.url}}" stepKey="navigateToNewUser"/> + <waitForPageLoad stepKey="waitForPageLoad1" /> + <fillField selector="{{AdminEditUserSection.usernameTextField}}" userInput="{{admin2.username}}" stepKey="enterUserName" /> + <fillField selector="{{AdminEditUserSection.firstNameTextField}}" userInput="{{admin2.firstName}}" stepKey="enterFirstName" /> + <fillField selector="{{AdminEditUserSection.lastNameTextField}}" userInput="{{admin2.lastName}}" stepKey="enterLastName" /> + <fillField selector="{{AdminEditUserSection.emailTextField}}" userInput="{{admin2.username}}@magento.com" stepKey="enterEmail" /> + <fillField selector="{{AdminEditUserSection.passwordTextField}}" userInput="{{admin2.password}}" stepKey="enterPassword" /> + <fillField selector="{{AdminEditUserSection.pwConfirmationTextField}}" userInput="{{admin2.password}}" stepKey="confirmPassword" /> + <fillField selector="{{AdminEditUserSection.currentPasswordField}}" userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}" stepKey="enterCurrentPassword" /> + <scrollToTopOfPage stepKey="scrollToTopOfPage" /> + <click selector="{{AdminEditUserSection.userRoleTab}}" stepKey="clickUserRole" /> + <fillField selector="{{AdminEditUserRoleSection.roleNameFilterTextField}}" userInput="{{role.name}}" stepKey="filterRole" /> + <click selector="{{AdminEditUserRoleSection.searchButton}}" stepKey="clickSearch" /> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappear1"/> + <click selector="{{AdminEditUserRoleSection.searchResultFirstRow}}" stepKey="selectRole" /> + <click selector="{{AdminEditUserSection.saveButton}}" stepKey="clickSaveUser" /> + <waitForPageLoad stepKey="waitForPageLoad2" /> + <see userInput="You saved the user." stepKey="seeSuccessMessage" /> + </actionGroup> +</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Data/UserData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Data/UserData.xml index b75c2eeb0e263..d738e86a529c8 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Data/UserData.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Data/UserData.xml @@ -12,4 +12,10 @@ <data key="email">admin@magento.com</data> <data key="password">admin123</data> </entity> + <entity name="admin2" type="user"> + <data key="username" unique="suffix">admin</data> + <data key="firstName">John</data> + <data key="lastName">Smith</data> + <data key="password">admin123</data> + </entity> </entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Data/UserRoleData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Data/UserRoleData.xml new file mode 100644 index 0000000000000..26df4b7afec65 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Data/UserRoleData.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="adminRole" type="role"> + <data key="name" unique="suffix">adminRole</data> + <data key="scope">1</data> + <data key="access">1</data> + </entity> +</entities> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Page/AdminEditRolePage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Page/AdminEditRolePage.xml new file mode 100644 index 0000000000000..58dfad7f34263 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Page/AdminEditRolePage.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> + <page name="AdminEditRolePage" url="admin/user_role/editrole" module="Magento_User" area="admin"> + <section name="AdminEditRoleInfoSection"/> + </page> +</pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Page/AdminEditUserPage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Page/AdminEditUserPage.xml index 7b188086e8ebd..893b59503a891 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Page/AdminEditUserPage.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Page/AdminEditUserPage.xml @@ -8,5 +8,6 @@ <pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> <page name="AdminEditUserPage" url="admin/user/new" area="admin" module="Magento_User"> <section name="AdminEditUserSection"/> + <section name="AdminEditUserRoleSection"/> </page> </pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Page/AdminRolesPage.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Page/AdminRolesPage.xml new file mode 100644 index 0000000000000..c056261ccbc4e --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Page/AdminRolesPage.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> + <page name="AdminRolesPage" url="admin/user_role/" module="Magento_User" area="admin"> + <section name="AdminRoleGridSection"/> + </page> +</pages> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Section/AdminEditRoleInfoSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Section/AdminEditRoleInfoSection.xml new file mode 100644 index 0000000000000..3e5b4ac6ecc88 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Section/AdminEditRoleInfoSection.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="AdminEditRoleInfoSection"> + <element name="roleName" type="input" selector="#role_name"/> + <element name="password" type="input" selector="#current_password"/> + <element name="roleResourcesTab" type="button" selector="#role_info_tabs_account"/> + <element name="backButton" type="button" selector="button[title='Back']"/> + <element name="resetButton" type="button" selector="button[title='Reset']"/> + <element name="saveButton" type="button" selector="button[title='Save Role']"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Section/AdminEditUserRoleSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Section/AdminEditUserRoleSection.xml new file mode 100644 index 0000000000000..857c36f9d71de --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Section/AdminEditUserRoleSection.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="AdminEditUserRoleSection"> + <element name="usernameTextField" type="input" selector="#user_username"/> + <element name="roleNameFilterTextField" type="input" selector="#permissionsUserRolesGrid_filter_role_name"/> + <element name="searchButton" type="button" selector=".admin__data-grid-header button[title=Search]"/> + <element name="resetButton" type="button" selector="button[title='Reset Filter']"/> + <element name="roleNameInFirstRow" type="text" selector=".col-role_name"/> + <element name="searchResultFirstRow" type="text" selector=".data-grid>tbody>tr"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Section/AdminEditUserSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Section/AdminEditUserSection.xml index 606a49b5e3e04..0dbac0a9386c9 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Section/AdminEditUserSection.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Section/AdminEditUserSection.xml @@ -8,6 +8,11 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> <section name="AdminEditUserSection"> <element name="usernameTextField" type="input" selector="#user_username"/> + <element name="firstNameTextField" type="input" selector="#user_firstname"/> + <element name="lastNameTextField" type="input" selector="#user_lastname"/> + <element name="emailTextField" type="input" selector="#user_email"/> + <element name="passwordTextField" type="input" selector="#user_password"/> + <element name="pwConfirmationTextField" type="input" selector="#user_confirmation"/> <element name="currentPasswordField" type="input" selector="#user_current_password"/> <element name="userRoleTab" type="button" selector="#page_tabs_roles_section"/> <element name="roleNameFilterTextField" type="input" selector="#permissionsUserRolesGrid_filter_role_name"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Section/AdminRoleGridSection.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Section/AdminRoleGridSection.xml new file mode 100644 index 0000000000000..9b91f4e1dd2a9 --- /dev/null +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/User/Section/AdminRoleGridSection.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + <section name="AdminRoleGridSection"> + <element name="idFilterTextField" type="input" selector="#roleGrid_filter_role_id"/> + <element name="roleNameFilterTextField" type="input" selector="#roleGrid_filter_role_name"/> + <element name="searchButton" type="button" selector=".admin__data-grid-header button[title=Search]"/> + <element name="resetButton" type="button" selector="button[title='Reset Filter']"/> + <element name="roleNameInFirstRow" type="text" selector=".col-role_name"/> + <element name="searchResultFirstRow" type="text" selector=".data-grid>tbody>tr"/> + </section> +</sections> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/CreateCustomVariableActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Variable/ActionGroup/CreateCustomVariableActionGroup.xml similarity index 100% rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/ActionGroup/CreateCustomVariableActionGroup.xml rename to dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Variable/ActionGroup/CreateCustomVariableActionGroup.xml diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Data/VariableData.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Variable/Data/VariableData.xml similarity index 100% rename from dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Cms/Data/VariableData.xml rename to dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Variable/Data/VariableData.xml diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php index 7cea3c2f6ee30..6f43cfa5fff1e 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php @@ -9,6 +9,7 @@ use Magento\TestFramework\TestCase\HttpClient\CurlClient; use Magento\TestFramework\Helper\JsonSerializer; use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; /** * Curl client for GraphQL @@ -73,7 +74,12 @@ public function postQuery(string $query, array $variables = [], string $operatio if (isset($error['message'])) { $errorMessage .= $error['message'] . PHP_EOL; } + if (isset($error['trace'])) { + $traceString = $error['trace']; + TestCase::assertNotEmpty($traceString, "trace is empty"); + } } + throw new \Exception('GraphQL response contains errors: ' . $errorMessage); } throw new \Exception('GraphQL responded with an unknown error: ' . $responseBody); diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/WebApiApplication.php b/dev/tests/api-functional/framework/Magento/TestFramework/WebApiApplication.php index 03364acbb8663..992653a3a65d6 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/WebApiApplication.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/WebApiApplication.php @@ -26,8 +26,12 @@ public function run() /** * {@inheritdoc} */ - public function install() + public function install($cleanup) { + if ($cleanup) { + $this->cleanup(); + } + $installOptions = $this->getInstallConfig(); /* Install application */ diff --git a/dev/tests/api-functional/framework/bootstrap.php b/dev/tests/api-functional/framework/bootstrap.php index 7a7b061858ac7..942582392e89e 100644 --- a/dev/tests/api-functional/framework/bootstrap.php +++ b/dev/tests/api-functional/framework/bootstrap.php @@ -58,10 +58,8 @@ ); if (defined('TESTS_MAGENTO_INSTALLATION') && TESTS_MAGENTO_INSTALLATION === 'enabled') { - if (defined('TESTS_CLEANUP') && TESTS_CLEANUP === 'enabled') { - $application->cleanup(); - } - $application->install(); + $cleanup = (defined('TESTS_CLEANUP') && TESTS_CLEANUP === 'enabled'); + $application->install($cleanup); } $bootstrap = new \Magento\TestFramework\Bootstrap( diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ExceptionFormatterDefaultModeTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ExceptionFormatterDefaultModeTest.php new file mode 100644 index 0000000000000..135131c88f4a8 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ExceptionFormatterDefaultModeTest.php @@ -0,0 +1,145 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\GraphQl\Catalog; + +use Magento\TestFramework\TestCase\GraphQlAbstract; + +class ExceptionFormatterDefaultModeTest extends GraphQlAbstract +{ + public function testInvalidEntityTypeExceptionInDefaultMode() + { + if (!$this->cleanCache()) { + $this->fail('Cache could not be cleaned properly.'); + } + $query + = <<<QUERY + { + customAttributeMetadata(attributes:[ + { + attribute_code:"sku" + entity_type:"invalid" + } + ]) + { + items{ + attribute_code + attribute_type + entity_type + } + } + } +QUERY; + $this->expectException(\Exception::class); + + $this->expectExceptionMessage('GraphQL response contains errors: Attribute code' . ' ' . + 'sku of entity type invalid not configured to have a type.'); + + $this->graphQlQuery($query); + } + + public function testDuplicateEntityTypeException() + { + $query + = <<<QUERY + { + customAttributeMetadata(attributes:[ + { + entity_type:"catalog_category" + entity_type:"catalog_product" + } + ]) + { + items{ + attribute_code + attribute_type + entity_type + } + } + } +QUERY; + $this->expectException(\Exception::class); + $this->expectExceptionMessage('GraphQL response contains errors: There' . ' ' . + 'can be only one input field named "entity_type"'); + $this->graphQlQuery($query); + } + + public function testEmptyAttributeInputException() + { + $query + = <<<QUERY + { + customAttributeMetadata(attributes:[ + { + + } + ]) + { + items{ + attribute_code + attribute_type + entity_type + } + } + } +QUERY; + $this->expectException(\Exception::class); + $this->expectExceptionMessage('GraphQL response contains errors: Attribute' . ' ' . + 'input does not contain attribute_code/entity_type for the input Empty AttributeInput.'); + + $this->graphQlQuery($query); + } + public function testAttributeWithNoEntityTypeInputException() + { + $query + = <<<QUERY + { + customAttributeMetadata(attributes:[ + { + attribute_code:"sku" + } + ]) + { + items{ + attribute_code + attribute_type + entity_type + } + } + } +QUERY; + $this->expectException(\Exception::class); + $this->expectExceptionMessage('GraphQL response contains errors: Attribute input' . ' ' . + 'does not contain entity_type for the input attribute_code: sku.'); + + $this->graphQlQuery($query); + } + + public function testAttributeWithNoAttributeCodeInputException() + { + $query + = <<<QUERY + { + customAttributeMetadata(attributes:[ + { + entity_type:"catalog_category" + } + ]) + { + items{ + attribute_code + attribute_type + entity_type + } + } + } +QUERY; + $this->expectException(\Exception::class); + $this->expectExceptionMessage('GraphQL response contains errors: Attribute input' . ' ' . + 'does not contain attribute_code for the input entity_type: catalog_category.'); + + $this->graphQlQuery($query); + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php index 5413e9ec91a1d..43d3e71935405 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php @@ -624,6 +624,39 @@ public function testQueryPageOutOfBoundException() $this->graphQlQuery($query); } + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testQueryWithNoSearchOrFilterArgumentException() + { + $query + = <<<QUERY +{ + products(pageSize:1) + { + items{ + id + attribute_set_id + created_at + name + sku + type_id + updated_at + weight + category_ids + + } + } + +} +QUERY; + + $this->expectException(\Exception::class); + $this->expectExceptionMessage('GraphQL response contains errors: One' .' ' . + 'of \'search\' or \'filter\' input arguments needs to be specified in products request.'); + $this->graphQlQuery($query); + } + /** * Asserts the different fields of items returned after search query is executed * diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php index 41d1d0e8f22ac..44bc309f754cb 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php @@ -665,7 +665,7 @@ private function assertEavAttributes($product, $actualResponse) $expectedAttribute = $product->getCustomAttribute($attributeCode); $assertionMap[] = [ - 'response_field' => $this->eavAttributesToGrahQlSchemaFieldTranslator($attributeCode), + 'response_field' => $this->eavAttributesToGraphQlSchemaFieldTranslator($attributeCode), 'expected_value' => $expectedAttribute ? $expectedAttribute->getValue() : null ]; } @@ -677,7 +677,7 @@ private function assertEavAttributes($product, $actualResponse) * @param string $eavAttributeCode * @return string */ - private function eavAttributesToGrahQlSchemaFieldTranslator(string $eavAttributeCode) + private function eavAttributesToGraphQlSchemaFieldTranslator(string $eavAttributeCode) { switch ($eavAttributeCode) { case 'news_from_date': diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Eav/ExceptionFormatterTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Eav/ExceptionFormatterTest.php new file mode 100644 index 0000000000000..821ce909afcad --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Eav/ExceptionFormatterTest.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\GraphQl\Eav; + +use Magento\Framework\App\State; +use Magento\TestFramework\ObjectManager; +use Magento\TestFramework\TestCase\GraphQlAbstract; + +class ExceptionFormatterTest extends GraphQlAbstract +{ + /** @var string */ + private $mageMode; + + /** + * @var \Magento\TestFramework\ObjectManager + */ + private $objectManager; + + protected function setUp() + { + parent::setUp(); + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + + $this->mageMode = $this->objectManager->get(State::class)->getMode(); + } + + protected function tearDown() + { + $this->objectManager->get(State::class)->setMode($this->mageMode); + } + + /** + * @param string $mageMode + */ + private function setDeveloperMode($mageMode = State::MODE_DEVELOPER) + { + $this->objectManager->get(State::class)->setMode($mageMode); + echo 'mageMode:'. $mageMode; + } + + public function testInvalidEntityTypeExceptionInDeveloperMode($mageMode = State::MODE_DEVELOPER) + { + $this->setDeveloperMode(); + $this->objectManager->get(State::class)->setMode($mageMode); + + if (!$this->cleanCache()) { + $this->fail('Cache could not be cleaned properly.'); + } + $query + = <<<QUERY + { + customAttributeMetadata(attributes:[ + { + attribute_code:"sku" + entity_type:"invalid" + } + ]) + { + items{ + attribute_code + attribute_type + entity_type + } + } + } +QUERY; + $this->expectException(\Exception::class); + + $this->expectExceptionMessage('GraphQL response contains errors: Attribute' . ' ' . + 'code sku of entity type invalid not configured to have a type.'); + + $this->graphQlQuery($query); + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/TestModule/GraphQlQueryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/TestModule/GraphQlQueryTest.php index a7e9a4481d772..c4a3eb433c60e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/TestModule/GraphQlQueryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/TestModule/GraphQlQueryTest.php @@ -27,9 +27,9 @@ public function testQueryTestModuleReturnsResults() } QUERY; - $reponse = $this->graphQlQuery($query); - $this->assertArrayHasKey('testItem', $reponse); - $testItem = $reponse['testItem']; + $response = $this->graphQlQuery($query); + $this->assertArrayHasKey('testItem', $response); + $testItem = $response['testItem']; $this->assertArrayHasKey('item_id', $testItem); $this->assertArrayHasKey('name', $testItem); $this->assertEquals(1, $testItem['item_id']); @@ -51,9 +51,9 @@ public function testQueryTestModuleExtensionAttribute() } QUERY; - $reponse = $this->graphQlQuery($query); - $this->assertArrayHasKey('testItem', $reponse); - $testItem = $reponse['testItem']; + $response = $this->graphQlQuery($query); + $this->assertArrayHasKey('testItem', $response); + $testItem = $response['testItem']; $this->assertArrayHasKey('integer_list', $testItem); $this->assertEquals([3, 4, 5], $testItem['integer_list']); } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php index dfd235320fe9d..4c0825e7e3243 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php @@ -8,6 +8,8 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product; use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; +use Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator; +use Magento\CmsUrlRewrite\Model\CmsPageUrlRewriteGenerator; use Magento\Store\Model\StoreManagerInterface; use Magento\TestFramework\ObjectManager; use Magento\TestFramework\TestCase\GraphQlAbstract; @@ -160,6 +162,42 @@ public function testCategoryUrlResolver() $this->assertEquals(strtoupper($expectedType), $response['urlResolver']['type']); } + /** + * @magentoApiDataFixture Magento/Cms/_files/pages.php + */ + public function testCMSPageUrlResolver() + { + /** @var \Magento\Cms\Model\Page $page */ + $page = $this->objectManager->get(\Magento\Cms\Model\Page::class); + $page->load('page100'); + $cmsPageId = $page->getId(); + $requestPath = $page->getIdentifier(); + + /** @var \Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator $urlPathGenerator */ + $urlPathGenerator = $this->objectManager->get(\Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator::class); + + /** @param \Magento\Cms\Api\Data\PageInterface $page */ + $targetPath = $urlPathGenerator->getCanonicalUrlPath($page); + $expectedEntityType = CmsPageUrlRewriteGenerator::ENTITY_TYPE; + + $query + = <<<QUERY +{ + urlResolver(url:"{$requestPath}") + { + id + canonical_url + type + } + +} +QUERY; + $response = $this->graphQlQuery($query); + $this->assertEquals($cmsPageId, $response['urlResolver']['id']); + $this->assertEquals($targetPath, $response['urlResolver']['canonical_url']); + $this->assertEquals(strtoupper(str_replace('-', '_', $expectedEntityType)), $response['urlResolver']['type']); + } + /** * Tests the use case where the url_key of the existing product is changed * diff --git a/dev/tests/functional/lib/Magento/Mtf/Client/Element/SimplifiedselectElement.php b/dev/tests/functional/lib/Magento/Mtf/Client/Element/SimplifiedselectElement.php index c9f37e9c18945..3aa7010377fb4 100644 --- a/dev/tests/functional/lib/Magento/Mtf/Client/Element/SimplifiedselectElement.php +++ b/dev/tests/functional/lib/Magento/Mtf/Client/Element/SimplifiedselectElement.php @@ -21,7 +21,7 @@ class SimplifiedselectElement extends SelectElement protected $optionGroupValue = ".//*[@data-title='%s' or contains(normalize-space(.), %s)]"; /** - * Select value in ropdown which has option groups. + * Select value in dropdown which has option groups. * * @param string $value * @return void diff --git a/dev/tests/functional/lib/Magento/Mtf/Client/Element/SwitcherElement.php b/dev/tests/functional/lib/Magento/Mtf/Client/Element/SwitcherElement.php index 6dce3d12a1fbe..36a203bb057e1 100644 --- a/dev/tests/functional/lib/Magento/Mtf/Client/Element/SwitcherElement.php +++ b/dev/tests/functional/lib/Magento/Mtf/Client/Element/SwitcherElement.php @@ -22,7 +22,7 @@ class SwitcherElement extends SimpleElement protected $parentContainer = 'parent::div[@data-role="switcher"]'; /** - * XPath selector for label text on swticher element. + * XPath selector for label text on switcher element. * * @var string */ diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CancelPartiallyInvoicedOrderTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CancelPartiallyInvoicedOrderTest.php index 71d9b11d12eb1..00c53c5e837d2 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CancelPartiallyInvoicedOrderTest.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CancelPartiallyInvoicedOrderTest.php @@ -20,7 +20,7 @@ * 3. Open the created order. * 4. Create partial invoice * 4. Do cancel Order. - * 5. Perform all assetions. + * 5. Perform all assertions. * * @group Order_Management * @ZephyrId MAGETWO-67787 diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/Attributes/Search.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/Attributes/Search.php index d17b06456c831..7b5bcf8060e2d 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/Attributes/Search.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Section/Attributes/Search.php @@ -37,7 +37,7 @@ class Search extends SuggestElement protected $actionToggle = '.action-toggle'; /** - * Saerch result dropdown. + * Search result dropdown. * * @var string */ diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeIsHtmlAllowed.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeIsHtmlAllowed.php index f1999498b96df..47a4ab7be3313 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeIsHtmlAllowed.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductAttributeIsHtmlAllowed.php @@ -23,7 +23,7 @@ class AssertProductAttributeIsHtmlAllowed extends AbstractConstraint /** * Check whether html tags are using in attribute value. - * Checked tag structure <b><i>atttribute_default_value</p></i></b> + * Checked tag structure <b><i>attribute_default_value</p></i></b> * * @param InjectableFixture $product * @param CatalogProductAttribute $attribute diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/WebsiteIds.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/WebsiteIds.php index 2bd71dbf4f8a6..57fe2bb59154f 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/WebsiteIds.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/WebsiteIds.php @@ -37,7 +37,7 @@ class WebsiteIds extends DataSource private $fixtureFactory; /** - * Rought fixture field data. + * Rough fixture field data. * * @var array */ diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php index 001e815ce2d2b..c75112fee8605 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php @@ -345,7 +345,7 @@ protected function preparePrice() } /** - * Preparation wheather product 'Is Virtual'. + * Preparation whether product 'Is Virtual'. * * @return void */ diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ReSavingProductAfterInitialSaveTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ReSavingProductAfterInitialSaveTest.php index 5ca7f06effc24..ba9714672cfbb 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ReSavingProductAfterInitialSaveTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ReSavingProductAfterInitialSaveTest.php @@ -19,7 +19,7 @@ * * 1. Login to backend. * 2. Create a product with invalid from and To dates - * 3. Save the product which generates an error messsage + * 3. Save the product which generates an error message * 4. Modify the dates to valid values * 5. Save the product again * 6. Product is saved successfully diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Repository/CatalogRule.xml b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Repository/CatalogRule.xml index e8959da642eac..fabf09a8ce772 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Repository/CatalogRule.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Repository/CatalogRule.xml @@ -72,6 +72,21 @@ <field name="discount_amount" xsi:type="string">10</field> </dataset> + <dataset name="active_catalog_price_rule_with_category_conditions"> + <field name="name" xsi:type="string">rule_name%isolation%</field> + <field name="description" xsi:type="string">Rule Description</field> + <field name="is_active" xsi:type="string">Active</field> + <field name="website_ids" xsi:type="array"> + <item name="0" xsi:type="string">Main Website</item> + </field> + <field name="customer_group_ids" xsi:type="array"> + <item name="1" xsi:type="string">General</item> + </field> + <field name="rule" xsi:type="string">[Category|is|2]</field> + <field name="simple_action" xsi:type="string">Adjust final price to this percentage</field> + <field name="discount_amount" xsi:type="string">50</field> + </dataset> + <dataset name="catalog_price_rule_priority_0"> <field name="name" xsi:type="string">catalog_price_rule_priority_0</field> <field name="description" xsi:type="string">-50% of price, Priority = 0</field> diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertConfigurableWithDisabledOtpionCatalogSearchNoResult.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertConfigurableWithDisabledOptionCatalogSearchNoResult.php similarity index 97% rename from dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertConfigurableWithDisabledOtpionCatalogSearchNoResult.php rename to dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertConfigurableWithDisabledOptionCatalogSearchNoResult.php index 6bb947941909e..a7538508caa76 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertConfigurableWithDisabledOtpionCatalogSearchNoResult.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertConfigurableWithDisabledOptionCatalogSearchNoResult.php @@ -19,7 +19,7 @@ /** * Assert search has no results after disabling configurable children. */ -class AssertConfigurableWithDisabledOtpionCatalogSearchNoResult extends AbstractConstraint +class AssertConfigurableWithDisabledOptionCatalogSearchNoResult extends AbstractConstraint { /** * Assert search has no results and product list in absent after disabling configurable children. diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/Method.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/Method.php index 3a66629116de9..f5024d3eb7b26 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/Method.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Shipping/Method.php @@ -91,7 +91,7 @@ public function selectShippingMethod(array $method) * @param array $method * @return bool */ - public function isShippingMethodAvaiable(array $method) + public function isShippingMethodAvailable(array $method) { $this->waitForShippingRates(); $selector = sprintf($this->shippingMethod, $method['shipping_method'], $method['shipping_service']); diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertBillingAddressSameAsShippingCheckbox.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertBillingAddressSameAsShippingCheckbox.php index 3e889c058ee84..9a042ab13f048 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertBillingAddressSameAsShippingCheckbox.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Constraint/AssertBillingAddressSameAsShippingCheckbox.php @@ -37,7 +37,7 @@ public function processAssert(CheckoutOnepage $checkoutOnepage, $billingCheckbox } /** - * Returns a string representation of successfull assertion. + * Returns a string representation of successful assertion. * * @return string */ diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/RemoveProductsFromTheCartStep.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/RemoveProductsFromTheCartStep.php index b4ea9ba26b0c2..6e1042eed5d83 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/RemoveProductsFromTheCartStep.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/RemoveProductsFromTheCartStep.php @@ -30,7 +30,7 @@ class RemoveProductsFromTheCartStep implements TestStepInterface private $cartPage; /** - * Quantity of items that should be removed from shoping cart. + * Quantity of items that should be removed from shopping cart. * * @var int|null */ diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Edit/PageForm.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Edit/PageForm.xml index 2ed1bdc790806..28de286b1411a 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Edit/PageForm.xml +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Block/Adminhtml/Page/Edit/PageForm.xml @@ -68,7 +68,7 @@ </custom_design> <seo> <class>\Magento\Backend\Test\Block\Widget\Tab</class> - <selector>//div[div/strong/span[text()="Search Engine Optimisation"]]</selector> + <selector>//div[div/strong/span[text()="Search Engine Optimization"]]</selector> <strategy>xpath</strategy> <fields> <identifier /> diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php index 36b544dc8b2d8..3191d975826f0 100644 --- a/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php @@ -13,7 +13,7 @@ * Steps: * 1. Log in to Admin. * 2. Go to Stores>Configuration>Advanced>admin>Security. - * 3. * 7. Verify admin Acoount Sharing option availability. + * 3. * 7. Verify admin Account Sharing option availability. * * @group Config_(PS) * @ZephyrId MAGETWO-47822 diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductTierPriceOnProductPage.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductTierPriceOnProductPage.php index 3845cdfd2d89f..01ff832cd7db3 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductTierPriceOnProductPage.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductTierPriceOnProductPage.php @@ -10,7 +10,7 @@ use Magento\ConfigurableProduct\Test\Block\Product\View\ConfigurableOptions; /** - * Open created configurble product on frontend and choose variation with tier price + * Open created configurable product on frontend and choose variation with tier price */ class AssertProductTierPriceOnProductPage extends AssertProductPage { diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/Customer/WebsiteId.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/Customer/WebsiteId.php index 72d7fdc63bc72..3e5ab87e0ed39 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/Customer/WebsiteId.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/Customer/WebsiteId.php @@ -38,7 +38,7 @@ class WebsiteId extends DataSource private $fixtureFactory; /** - * Rought fixture field data. + * Rough fixture field data. * * @var array */ diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/AbstractApplyVatIdTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/AbstractApplyVatIdTest.php index 2eb82c04d1f81..2d2392f3328fe 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/AbstractApplyVatIdTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/AbstractApplyVatIdTest.php @@ -76,7 +76,7 @@ public function __prepare(FixtureFactory $fixtureFactory) } /** - * Prepare VAT ID confguration. + * Prepare VAT ID configuration. * * @param ConfigData $vatConfig * @param string $customerGroup diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.php b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.php index 03779bd0ec674..a8c81ea14ba46 100644 --- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.php @@ -51,7 +51,7 @@ class ReAuthorizeTokensIntegrationEntityTest extends Injectable * * @param FixtureFactory $fixtureFactory * @param IntegrationIndex $integrationIndex - * @retun void + * @return void */ public function __inject(IntegrationIndex $integrationIndex, FixtureFactory $fixtureFactory) { diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php index fa14fcdc34b96..20fe0c8f55ccb 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php @@ -23,7 +23,7 @@ * 2. Sales > Orders. * 3. Open the created order. * 4. Do cancel Order. - * 5. Perform all assetions. + * 5. Perform all assertions. * * @group Order_Management * @ZephyrId MAGETWO-28191 diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.php index 0a15196d65ae2..6f8c8cf1e53bb 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.php @@ -30,7 +30,7 @@ class CreateCustomOrderStatusEntityTest extends Injectable /* end tags */ /** - * Order staus page. + * Order status page. * * @var OrderStatusIndex */ diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleSuccessDeleteMessage.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleSuccessDeleteMessage.php index 472218205cb4f..381de91030a61 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleSuccessDeleteMessage.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Constraint/AssertCartPriceRuleSuccessDeleteMessage.php @@ -10,7 +10,7 @@ use Magento\Mtf\Constraint\AbstractConstraint; /** - * Assert sales rule delte message. + * Assert sales rule delete message. */ class AssertCartPriceRuleSuccessDeleteMessage extends AbstractConstraint { diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingIntegrationTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingIntegrationTest.php index 5f803d634fa2a..d1e9c9dee9ec2 100644 --- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingIntegrationTest.php +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenEditingIntegrationTest.php @@ -84,7 +84,7 @@ public function __inject( /** * Run Lock user when creating new integration test. * - * @param Integration $initintegration + * @param Integration $initIntegration * @param Integration $integration * @param int $attempts * @param User $customAdmin @@ -92,7 +92,7 @@ public function __inject( * @return void */ public function test( - Integration $initintegration, + Integration $initIntegration, Integration $integration, $attempts, User $customAdmin, @@ -106,7 +106,7 @@ public function test( ['configData' => $this->configData] )->run(); $customAdmin->persist(); - $initintegration->persist(); + $initIntegration->persist(); // login to backend with new user $this->adminAuthLogin->open(); @@ -114,7 +114,7 @@ public function test( $this->adminAuthLogin->getLoginBlock()->submit(); // Steps - $filter = ['name' => $initintegration->getName()]; + $filter = ['name' => $initIntegration->getName()]; $this->integrationIndexPage->open(); $this->integrationIndexPage->getIntegrationGrid()->searchAndOpen($filter); for ($i = 0; $i < $attempts; $i++) { diff --git a/dev/tests/functional/tests/app/Magento/Shipping/Test/Constraint/AssertCityBasedShippingRateChanged.php b/dev/tests/functional/tests/app/Magento/Shipping/Test/Constraint/AssertCityBasedShippingRateChanged.php index a449f79ef68f3..ea5de8d06be00 100644 --- a/dev/tests/functional/tests/app/Magento/Shipping/Test/Constraint/AssertCityBasedShippingRateChanged.php +++ b/dev/tests/functional/tests/app/Magento/Shipping/Test/Constraint/AssertCityBasedShippingRateChanged.php @@ -30,11 +30,11 @@ public function processAssert(CheckoutOnepage $checkoutOnepage, $shippingMethod, 'Shipping rate has not been changed.' ); } - $shippingAvaialability = $isShippingAvailable ? 'avaiable' : 'unavailable'; + $shippingAvailability = $isShippingAvailable ? 'available' : 'unavailable'; \PHPUnit_Framework_Assert::assertEquals( $isShippingAvailable, - $checkoutOnepage->getShippingMethodBlock()->isShippingMethodAvaiable($shippingMethod), - "Shipping rates for {$shippingMethod['shipping_service']} should be $shippingAvaialability." + $checkoutOnepage->getShippingMethodBlock()->isShippingMethodAvailable($shippingMethod), + "Shipping rates for {$shippingMethod['shipping_service']} should be $shippingAvailability." ); } diff --git a/dev/tests/functional/tests/app/Magento/Shipping/Test/TestStep/FillShippingAddressesStep.php b/dev/tests/functional/tests/app/Magento/Shipping/Test/TestStep/FillShippingAddressesStep.php index 681b2746a4c34..abc560075d576 100644 --- a/dev/tests/functional/tests/app/Magento/Shipping/Test/TestStep/FillShippingAddressesStep.php +++ b/dev/tests/functional/tests/app/Magento/Shipping/Test/TestStep/FillShippingAddressesStep.php @@ -13,7 +13,7 @@ use Magento\Shipping\Test\Constraint\AssertCityBasedShippingRateChanged; /** - * Fill shipping addresses and assert rates relouding. + * Fill shipping addresses and assert rates reloading. */ class FillShippingAddressesStep implements TestStepInterface { diff --git a/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Footer.php b/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Footer.php index 0bcf20b38801e..30842af0b020d 100644 --- a/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Footer.php +++ b/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Footer.php @@ -120,7 +120,7 @@ public function selectStoreGroup(Store $store) } /** - * Check if correspondent "Store" is present in "Store" swither or not. + * Check if correspondent "Store" is present in "Store" switcher or not. * * @param Store $store * @return bool diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php index 15145c36afe0d..235b0d096533f 100644 --- a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php +++ b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php @@ -332,7 +332,7 @@ public function selectMassAction($massActionSelection) } /** - * Peform action using the dropdown above the grid. + * Perform action using the dropdown above the grid. * * @param array|string $action [array -> key = value from first select; value => value from subselect] * @return void diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Modal.php b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Modal.php index a9c8e87f1dc97..5c27776c09620 100644 --- a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Modal.php +++ b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Modal.php @@ -150,7 +150,7 @@ public function setAlertText($text) } /** - * Wait until modal window will disapper. + * Wait until modal window will disappear. * * @return void */ diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php index 57a170b924fe7..a54907aa49ec7 100644 --- a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php +++ b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php @@ -19,7 +19,7 @@ * Steps: * 1. Navigate to backend. * 2. Go to grid page - * 3. Perfrom full text search + * 3. Perform full text search * 5. Perform Asserts * * @group Ui diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/UrlRewriteForm.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/UrlRewriteForm.php index 114709becde6f..988229d308250 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/UrlRewriteForm.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/UrlRewriteForm.php @@ -39,7 +39,7 @@ protected function prepareData(FixtureInterface $fixture) * * @param array $data * @param SimpleElement $context - * @retun void + * @return void */ protected function fillFields(array $data, SimpleElement $context) { diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetCmsPageLink.php b/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetCmsPageLink.php index 411c15732f2ee..636af4e8032db 100644 --- a/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetCmsPageLink.php +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Constraint/AssertWidgetCmsPageLink.php @@ -12,7 +12,7 @@ use Magento\Mtf\Constraint\AbstractConstraint; /** - * Check that created widget displayed on frontent on Home page and on Advanced Search and + * Check that created widget displayed on frontend on Home page and on Advanced Search and * after click on widget link on frontend system redirects you to cms page. */ class AssertWidgetCmsPageLink extends AbstractConstraint diff --git a/dev/tests/integration/etc/di/preferences/ce.php b/dev/tests/integration/etc/di/preferences/ce.php index 0e6f90d75f311..d5aaa7e730826 100644 --- a/dev/tests/integration/etc/di/preferences/ce.php +++ b/dev/tests/integration/etc/di/preferences/ce.php @@ -16,6 +16,8 @@ \Magento\Framework\App\Response\Http::class => \Magento\TestFramework\Response::class, \Magento\Framework\Interception\PluginListInterface::class => \Magento\TestFramework\Interception\PluginList::class, + \Magento\Framework\Interception\ObjectManager\ConfigInterface::class => + \Magento\TestFramework\ObjectManager\Config::class, \Magento\Framework\Interception\ObjectManager\Config\Developer::class => \Magento\TestFramework\ObjectManager\Config::class, \Magento\Framework\View\LayoutInterface::class => \Magento\TestFramework\View\Layout::class, diff --git a/dev/tests/integration/framework/Magento/TestFramework/Application.php b/dev/tests/integration/framework/Magento/TestFramework/Application.php index a5a16c547e089..12f067fad53a9 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Application.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Application.php @@ -441,10 +441,11 @@ public function cleanup() /** * Install an application * + * @param bool $cleanup * @return void * @throws \Magento\Framework\Exception\LocalizedException */ - public function install() + public function install($cleanup) { $dirs = \Magento\Framework\App\Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS; $this->_ensureDirExists($this->installDir); @@ -459,8 +460,9 @@ public function install() $installParams = $this->getInstallCliParams(); // performance optimization: restore DB from last good dump to make installation on top of it (much faster) + // do not restore from the database if the cleanup option is set to ensure we have a clean DB to test on $db = $this->getDbInstance(); - if ($db->isDbDumpExists()) { + if ($db->isDbDumpExists() && !$cleanup) { $db->restoreFromDbDump(); } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Db/AbstractDb.php b/dev/tests/integration/framework/Magento/TestFramework/Db/AbstractDb.php index 949d17ffb5f66..a15bdec6157a3 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Db/AbstractDb.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Db/AbstractDb.php @@ -84,7 +84,7 @@ abstract public function cleanup(); abstract protected function getSetupDbDumpFilename(); /** - * Is dump esxists + * Is dump exists * * @return bool */ diff --git a/dev/tests/integration/framework/Magento/TestFramework/Db/Mysql.php b/dev/tests/integration/framework/Magento/TestFramework/Db/Mysql.php index 69f7f2b2ed8db..6900f89a55f9d 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Db/Mysql.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Db/Mysql.php @@ -87,7 +87,7 @@ protected function getSetupDbDumpFilename() } /** - * Is dump esxists + * Is dump exists * * @return bool */ diff --git a/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractConfigFiles.php b/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractConfigFiles.php index 913c710370816..92ac7ddd468ab 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractConfigFiles.php +++ b/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractConfigFiles.php @@ -47,7 +47,7 @@ public function setUp() \Magento\Framework\App\Arguments\FileResolver\Primary::class )->disableOriginalConstructor()->getMock(); - /* Enable Validation regardles of MAGE_MODE */ + /* Enable Validation regardless of MAGE_MODE */ $validateStateMock = $this->getMockBuilder( \Magento\Framework\Config\ValidationStateInterface::class )->disableOriginalConstructor()->getMock(); diff --git a/dev/tests/integration/framework/bootstrap.php b/dev/tests/integration/framework/bootstrap.php index 13008938147b5..4e14c8113a708 100644 --- a/dev/tests/integration/framework/bootstrap.php +++ b/dev/tests/integration/framework/bootstrap.php @@ -74,7 +74,7 @@ $application->cleanup(); } if (!$application->isInstalled()) { - $application->install(); + $application->install($settings->getAsBoolean('TESTS_CLEANUP')); } $application->initialize([]); diff --git a/dev/tests/integration/testsuite/Magento/AdminNotification/_files/notifications.php b/dev/tests/integration/testsuite/Magento/AdminNotification/_files/notifications.php index 4bb05645ed105..6615c24320b21 100644 --- a/dev/tests/integration/testsuite/Magento/AdminNotification/_files/notifications.php +++ b/dev/tests/integration/testsuite/Magento/AdminNotification/_files/notifications.php @@ -4,34 +4,34 @@ * See COPYING.txt for license details. */ $om = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); -$mesasge = $om->create(\Magento\AdminNotification\Model\Inbox::class); -$mesasge->setSeverity( +$message = $om->create(\Magento\AdminNotification\Model\Inbox::class); +$message->setSeverity( \Magento\Framework\Notification\MessageInterface::SEVERITY_CRITICAL )->setTitle( 'Unread Critical 1' )->save(); -$mesasge = $om->create(\Magento\AdminNotification\Model\Inbox::class); -$mesasge->setSeverity(\Magento\Framework\Notification\MessageInterface::SEVERITY_MAJOR) +$message = $om->create(\Magento\AdminNotification\Model\Inbox::class); +$message->setSeverity(\Magento\Framework\Notification\MessageInterface::SEVERITY_MAJOR) ->setTitle('Unread Major 1') ->save(); -$mesasge = $om->create(\Magento\AdminNotification\Model\Inbox::class); -$mesasge->setSeverity( +$message = $om->create(\Magento\AdminNotification\Model\Inbox::class); +$message->setSeverity( \Magento\Framework\Notification\MessageInterface::SEVERITY_CRITICAL )->setTitle( 'Unread Critical 2' )->save(); -$mesasge = $om->create(\Magento\AdminNotification\Model\Inbox::class); -$mesasge->setSeverity( +$message = $om->create(\Magento\AdminNotification\Model\Inbox::class); +$message->setSeverity( \Magento\Framework\Notification\MessageInterface::SEVERITY_CRITICAL )->setTitle( 'Unread Critical 3' )->save(); -$mesasge = $om->create(\Magento\AdminNotification\Model\Inbox::class); -$mesasge->setSeverity( +$message = $om->create(\Magento\AdminNotification\Model\Inbox::class); +$message->setSeverity( \Magento\Framework\Notification\MessageInterface::SEVERITY_CRITICAL )->setTitle( 'Read Critical 1' @@ -39,13 +39,13 @@ 1 )->save(); -$mesasge = $om->create(\Magento\AdminNotification\Model\Inbox::class); -$mesasge->setSeverity(\Magento\Framework\Notification\MessageInterface::SEVERITY_MAJOR) +$message = $om->create(\Magento\AdminNotification\Model\Inbox::class); +$message->setSeverity(\Magento\Framework\Notification\MessageInterface::SEVERITY_MAJOR) ->setTitle('Unread Major 2') ->save(); -$mesasge = $om->create(\Magento\AdminNotification\Model\Inbox::class); -$mesasge->setSeverity( +$message = $om->create(\Magento\AdminNotification\Model\Inbox::class); +$message->setSeverity( \Magento\Framework\Notification\MessageInterface::SEVERITY_CRITICAL )->setTitle( 'Removed Critical 1' diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php index 5e9244367bb13..8eeba1230f8b1 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php @@ -128,6 +128,14 @@ public function testGetChildren() $this->assertEquals(array_diff([4, 13], explode(',', $this->_model->getChildren())), []); } + public function testGetChildrenSorted() + { + $this->_model->load(2); + $unsorted = explode(',', $this->_model->getChildren()); + sort($unsorted); + $this->assertEquals(array_diff($unsorted, explode(',', $this->_model->getChildren(true, true, true))), []); + } + public function testGetPathInStore() { $this->_model->load(5); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/ImageTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/ImageTest.php index eb32fb98ce8fe..37fee97161b2d 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/ImageTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/ImageTest.php @@ -21,8 +21,8 @@ public function testSetBaseFilePlaceholder() $model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( \Magento\Catalog\Model\Product\Image::class ); - /** @var \Magento\Catalog\Model\View\Asset\Placeholder $defualtPlaceholder */ - $defualtPlaceholder = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + /** @var \Magento\Catalog\Model\View\Asset\Placeholder $defaultPlaceholder */ + $defaultPlaceholder = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->create( \Magento\Catalog\Model\View\Asset\Placeholder::class, ['type' => 'image'] @@ -30,7 +30,7 @@ public function testSetBaseFilePlaceholder() $model->setDestinationSubdir('image'); $model->setBaseFile(''); - $this->assertEquals($defualtPlaceholder->getSourceFile(), $model->getBaseFile()); + $this->assertEquals($defaultPlaceholder->getSourceFile(), $model->getBaseFile()); return $model; } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/TypeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/TypeTest.php index 7fe5fbc6303ad..dadee3d9b6fac 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/TypeTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/TypeTest.php @@ -20,7 +20,7 @@ protected function setUp() } /** - * @param sring|null $typeId + * @param string|null $typeId * @param string $expectedClass * @dataProvider factoryDataProvider */ @@ -52,7 +52,7 @@ public function factoryDataProvider() } /** - * @param sring|null $typeId + * @param string|null $typeId * @dataProvider factoryReturnsSingletonDataProvider */ public function testFactoryReturnsSingleton($typeId) @@ -82,7 +82,7 @@ public function factoryReturnsSingletonDataProvider() } /** - * @param sring|null $typeId + * @param string|null $typeId * @param string $expectedClass * @dataProvider priceFactoryDataProvider */ diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php index da47201fe6e38..d6786b6869db2 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php @@ -124,4 +124,29 @@ public function testGetProductsWithTierPrice() $this->assertEquals(50, $tierPrices[2]->getExtensionAttributes()->getPercentageValue()); $this->assertEquals(5, $tierPrices[2]->getValue()); } + + /** + * Checks a case if table for join specified as an array. + * + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function testJoinTable() + { + $this->collection->joinTable( + ['alias' => 'url_rewrite'], + 'entity_id = entity_id', + ['request_path'], + '{{table}}.entity_type = \'product\'', + 'left' + ); + $sql = (string) $this->collection->getSelect(); + $productTable = $this->collection->getTable('catalog_product_entity'); + $urlRewriteTable = $this->collection->getTable('url_rewrite'); + + $expected = 'SELECT `e`.*, `alias`.`request_path` FROM `' . $productTable . '` AS `e`' + . ' LEFT JOIN `' . $urlRewriteTable . '` AS `alias` ON (alias.entity_id =e.entity_id)' + . ' AND (alias.entity_type = \'product\')'; + + self::assertContains($expected, str_replace(PHP_EOL, '', $sql)); + } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php new file mode 100644 index 0000000000000..7954e2c36227f --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Model\ResourceModel; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +class ProductTest extends TestCase +{ + /** + * @var Product + */ + private $model; + + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + + $this->model = $this->objectManager->get(Product::class); + } + + /** + * Checks a possibility to retrieve product raw attribute value. + * + * @magentoDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testGetAttributeRawValue() + { + $sku = 'simple'; + $attribute = 'name'; + + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + $product = $productRepository->get($sku); + + $actual = $this->model->getAttributeRawValue($product->getId(), $attribute, null); + self::assertEquals($product->getName(), $actual); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_decimal_qty.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_decimal_qty.php new file mode 100644 index 0000000000000..37ce93cc9c420 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_decimal_qty.php @@ -0,0 +1,192 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory; + +\Magento\TestFramework\Helper\Bootstrap::getInstance()->reinitialize(); + +/** @var \Magento\TestFramework\ObjectManager $objectManager */ +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var \Magento\Catalog\Api\CategoryLinkManagementInterface $categoryLinkManagement */ +$categoryLinkManagement = $objectManager->get(\Magento\Catalog\Api\CategoryLinkManagementInterface::class); + +$tierPrices = []; +/** @var \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory */ +$tierPriceFactory = $objectManager->get(\Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory::class); +/** @var $tpExtensionAttributes */ +$tpExtensionAttributesFactory = $objectManager->get(ProductTierPriceExtensionFactory::class); + +$adminWebsite = $objectManager->get(\Magento\Store\Api\WebsiteRepositoryInterface::class)->get('admin'); +$tierPriceExtensionAttributes1 = $tpExtensionAttributesFactory->create() + ->setWebsiteId($adminWebsite->getId()); + +$tierPrices[] = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => \Magento\Customer\Model\Group::CUST_GROUP_ALL, + 'qty' => 2, + 'value' => 8, + ], + ] +)->setExtensionAttributes($tierPriceExtensionAttributes1); + +$tierPrices[] = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => \Magento\Customer\Model\Group::CUST_GROUP_ALL, + 'qty' => 5, + 'value' => 5, + ], + ] +)->setExtensionAttributes($tierPriceExtensionAttributes1); + +$tierPrices[] = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, + 'qty' => 3, + 'value' => 5, + ], + ] +)->setExtensionAttributes($tierPriceExtensionAttributes1); + +$tierPriceExtensionAttributes2 = $tpExtensionAttributesFactory->create() + ->setWebsiteId($adminWebsite->getId()) + ->setPercentageValue(50); + +$tierPrices[] = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, + 'qty' => 10, + ], + ] +)->setExtensionAttributes($tierPriceExtensionAttributes2); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = $objectManager->create(\Magento\Catalog\Model\Product::class); +$product->isObjectNew(true); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setId(1) + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setName('Simple Product') + ->setSku('simple_with_decimal_qty') + ->setPrice(10) + ->setWeight(1) + ->setShortDescription("Short description") + ->setTaxClassId(0) + ->setTierPrices($tierPrices) + ->setDescription('Description with <b>html tag</b>') + ->setMetaTitle('meta title') + ->setMetaKeyword('meta keyword') + ->setMetaDescription('meta description') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setStockData( + [ + 'use_config_manage_stock' => 1, + 'qty' => 100, + 'is_qty_decimal' => 1, + 'is_in_stock' => 1, + ] + )->setCanSaveCustomOptions(true) + ->setHasOptions(true); + +$oldOptions = [ + [ + 'previous_group' => 'text', + 'title' => 'Test Field', + 'type' => 'field', + 'is_require' => 1, + 'sort_order' => 0, + 'price' => 1, + 'price_type' => 'fixed', + 'sku' => '1-text', + 'max_characters' => 100, + ], + [ + 'previous_group' => 'date', + 'title' => 'Test Date and Time', + 'type' => 'date_time', + 'is_require' => 1, + 'sort_order' => 0, + 'price' => 2, + 'price_type' => 'fixed', + 'sku' => '2-date', + ], + [ + 'previous_group' => 'select', + 'title' => 'Test Select', + 'type' => 'drop_down', + 'is_require' => 1, + 'sort_order' => 0, + 'values' => [ + [ + 'option_type_id' => null, + 'title' => 'Option 1', + 'price' => 3, + 'price_type' => 'fixed', + 'sku' => '3-1-select', + ], + [ + 'option_type_id' => null, + 'title' => 'Option 2', + 'price' => 3, + 'price_type' => 'fixed', + 'sku' => '3-2-select', + ], + ], + ], + [ + 'previous_group' => 'select', + 'title' => 'Test Radio', + 'type' => 'radio', + 'is_require' => 1, + 'sort_order' => 0, + 'values' => [ + [ + 'option_type_id' => null, + 'title' => 'Option 1', + 'price' => 3, + 'price_type' => 'fixed', + 'sku' => '4-1-radio', + ], + [ + 'option_type_id' => null, + 'title' => 'Option 2', + 'price' => 3, + 'price_type' => 'fixed', + 'sku' => '4-2-radio', + ], + ], + ], +]; + +$options = []; + +/** @var \Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory $customOptionFactory */ +$customOptionFactory = $objectManager->create(\Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory::class); + +foreach ($oldOptions as $option) { + /** @var \Magento\Catalog\Api\Data\ProductCustomOptionInterface $option */ + $option = $customOptionFactory->create(['data' => $option]); + $option->setProductSku($product->getSku()); + + $options[] = $option; +} + +$product->setOptions($options); + +/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepositoryFactory */ +$productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); +$productRepository->save($product); + +$categoryLinkManagement->assignProductToCategories( + $product->getSku(), + [2] +); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_decimal_qty_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_decimal_qty_rollback.php new file mode 100644 index 0000000000000..55bd53a2d5794 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_decimal_qty_rollback.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Framework\Exception\NoSuchEntityException; + +\Magento\TestFramework\Helper\Bootstrap::getInstance()->getInstance()->reinitialize(); + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ +$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); +try { + $product = $productRepository->get('simple_with_decimal_qty', false, null, true); + $productRepository->delete($product); +} catch (NoSuchEntityException $e) { +} +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_with_product_links_data.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_with_product_links_data.php index d9482c40338a3..2f1f0a0b14f54 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_with_product_links_data.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_with_product_links_data.php @@ -7,7 +7,7 @@ require dirname(dirname(__DIR__)) . '/Catalog/_files/category.php'; /** Create fixture store */ require dirname(dirname(__DIR__)) . '/Store/_files/second_store.php'; -/** Create product with mulselect attribute */ +/** Create product with multiselect attribute */ require dirname(dirname(__DIR__)) . '/Catalog/_files/products_with_multiselect_attribute.php'; $productModel = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Observer/AddStockItemsObserverTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Observer/AddStockItemsObserverTest.php new file mode 100644 index 0000000000000..71af5d102a8d7 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Observer/AddStockItemsObserverTest.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogInventory\Observer; + +use Magento\CatalogInventory\Api\Data\StockItemInterface; +use Magento\Quote\Model\Quote; +use Magento\Quote\Model\ResourceModel\Quote\Item\Collection; +use Magento\Quote\Model\ResourceModel\Quote\Item\CollectionFactory; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +class AddStockItemsObserverTest extends TestCase +{ + /** + * Test addStockItemsObserver add stock items to products as extension attributes in quote item collection. + * + * @magentoDataFixture Magento/Sales/_files/quote.php + */ + public function testAddStockItemsToProductCollection() + { + $quote = Bootstrap::getObjectManager()->create(Quote::class); + $quote->load('test01', 'reserved_order_id'); + /** @var CollectionFactory $collectionFactory */ + $collectionFactory = Bootstrap::getObjectManager()->create(CollectionFactory::class); + /** @var Collection $collection */ + $collection = $collectionFactory->create(); + $collection->setQuote($quote); + /** @var Quote\Item $quoteItem */ + foreach ($collection->getItems() as $quoteItem) { + self::assertNotEmpty($quoteItem->getProduct()->getExtensionAttributes()->getStockItem()); + self::assertInstanceOf( + StockItemInterface::class, + $quoteItem->getProduct()->getExtensionAttributes()->getStockItem() + ); + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category.php index 2dc1713a5bb0d..aa753a3509987 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category.php +++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/product_with_category.php @@ -79,4 +79,4 @@ /** @var CategoryLinkManagementInterface $linkManagement */ $linkManagement = $objectManager->get(CategoryLinkManagementInterface::class); -$linkManagement->assignProductToCategories($product->getSku(), [$category->getEntityId()]); +$linkManagement->assignProductToCategories($product->getSku(), [Category::TREE_ROOT_ID, $category->getEntityId()]); diff --git a/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php b/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php index 6892f7b3a8a88..3a64a134d5f95 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php @@ -68,7 +68,7 @@ public function testCreateCollection() . '`value`:[`' . implode(',', $multiselectAttributeOptionIds) . '`]^]^]'; $this->block->setData('conditions_encoded', $encodedConditions); - // Load products collection filtered using specified conditions and perform assesrions + // Load products collection filtered using specified conditions and perform assertions $productCollection = $this->block->createCollection(); $productCollection->load(); $this->assertEquals( diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php index 8aa8d4cc810b1..01a7ae6087e06 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php @@ -235,6 +235,26 @@ public function testGetUsedProducts() } } + /** + * Test getUsedProducts returns array with same indexes regardless collections was cache or not. + * + * @magentoAppIsolation enabled + * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php + */ + public function testGetUsedProductsCached() + { + /** @var \Magento\Framework\App\Cache\StateInterface $cacheState */ + $cacheState = Bootstrap::getObjectManager()->get(\Magento\Framework\App\Cache\StateInterface::class); + $cacheState->setEnabled(\Magento\Framework\App\Cache\Type\Collection::TYPE_IDENTIFIER, true); + + $products = $this->getUsedProducts(); + $productsCached = $this->getUsedProducts(); + self::assertEquals( + array_keys($products), + array_keys($productsCached) + ); + } + public function testGetUsedProductCollection() { $this->assertInstanceOf( @@ -570,4 +590,14 @@ protected function _prepareForCart() return $product; } + + /** + * @return ProductInterface[] + */ + protected function getUsedProducts() + { + $product = Bootstrap::getObjectManager()->create(Product::class); + $product->load(1); + return $this->model->getUsedProducts($product); + } } diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_with_category_and_weight.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_with_category_and_weight.php index 519841ddb61e4..b8449a829a227 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_with_category_and_weight.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_with_category_and_weight.php @@ -55,8 +55,8 @@ $eavAttributeValues = [ 'category_ids' => [2] ]; - foreach ($eavAttributeValues as $eavCategoryAttributeCode => $eavCategoryAtttributeValues) { - $product->setCustomAttribute($eavCategoryAttributeCode, $eavCategoryAtttributeValues); + foreach ($eavAttributeValues as $eavCategoryAttributeCode => $eavCategoryAttributeValues) { + $product->setCustomAttribute($eavCategoryAttributeCode, $eavCategoryAttributeValues); } $product = $productRepository->save($product); diff --git a/dev/tests/integration/testsuite/Magento/Contact/Controller/IndexTest.php b/dev/tests/integration/testsuite/Magento/Contact/Controller/IndexTest.php index b8dbfec59845b..2d76632cae0b7 100644 --- a/dev/tests/integration/testsuite/Magento/Contact/Controller/IndexTest.php +++ b/dev/tests/integration/testsuite/Magento/Contact/Controller/IndexTest.php @@ -24,7 +24,7 @@ public function testPostAction() $this->assertRedirect($this->stringContains('contact/index')); $this->assertSessionMessages( $this->contains( - "Thanks for contacting us with your comments and questions. We'll respond to you very soon." + "Thanks for contacting us with your comments and questions. We'll respond to you very soon." ), \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS ); diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php index 769120127329e..dca24e92f0040 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php @@ -347,6 +347,7 @@ public function testSaveActionExistingCustomerUnsubscribeNewsletter() 'email' => 'customer@example.com', 'firstname' => 'test firstname', 'lastname' => 'test lastname', + 'sendemail_store_id' => 1 ], 'subscription' => '0' ]; diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerMetadataTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerMetadataTest.php index d88c0934e3f69..eb62eb886fd5d 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerMetadataTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerMetadataTest.php @@ -159,7 +159,7 @@ public function testGetCustomAttributesMetadataWithCustomAttributes() ); // Verify the consistency of custom attribute metadata from two services - // after getAttrbiuteCode was called + // after getAttributeCode was called foreach ($customAttributesMetadata2 as $attribute) { $attribute->getAttributeCode(); } diff --git a/dev/tests/integration/testsuite/Magento/Framework/Code/Reader/SourceArgumentsReaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/Code/Reader/SourceArgumentsReaderTest.php index 2f7f040d82c24..d1b22e853ce1d 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Code/Reader/SourceArgumentsReaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Code/Reader/SourceArgumentsReaderTest.php @@ -41,8 +41,8 @@ public function getConstructorArgumentTypesDataProvider() '\Imported\Name\Space\One', '\Imported\Name\Space\AnotherTest\Extended', '\Imported\Name\Space\Test', - '\Imported\Name\Space\Object\Under\Test', - '\Imported\Name\Space\Object', + '\Imported\Name\Space\ClassName\Under\Test', + '\Imported\Name\Space\ClassName', '\Some\Testing\Name\Space\Test', 'array', '' diff --git a/dev/tests/integration/testsuite/Magento/Framework/Code/Reader/_files/SourceArgumentsReaderTest.php.sample b/dev/tests/integration/testsuite/Magento/Framework/Code/Reader/_files/SourceArgumentsReaderTest.php.sample index 8bf978150d003..47c059de2034b 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Code/Reader/_files/SourceArgumentsReaderTest.php.sample +++ b/dev/tests/integration/testsuite/Magento/Framework/Code/Reader/_files/SourceArgumentsReaderTest.php.sample @@ -6,7 +6,7 @@ namespace Some\Testing\Name\Space; use Imported\Name\Space\One as FirstImport; -use Imported\Name\Space\Object; +use Imported\Name\Space\ClassName; use Imported\Name\Space\Test as Testing, \Imported\Name\Space\AnotherTest ; class AnotherSimpleClass @@ -16,8 +16,8 @@ class AnotherSimpleClass FirstImport $itemTwo, AnotherTest\Extended $itemThree, Testing $itemFour, - Object\Under\Test $itemFive, - Object $itemSix, + ClassName\Under\Test $itemFive, + ClassName $itemSix, Test $itemSeven, array $itemEight = [], $itemNine = 'test' diff --git a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/composer.lock b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/composer.lock index a94f384ba701b..756542fbdb222 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/composer.lock +++ b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/composer.lock @@ -782,34 +782,6 @@ "dev/tests/functional/.gitignore", "dev/tests/functional/.gitignore" ], - [ - "dev/tests/js/JsTestDriver/run_js_tests.php", - "dev/tests/js/JsTestDriver/run_js_tests.php" - ], - [ - "dev/tests/js/JsTestDriver/jsTestDriverOrder.php", - "dev/tests/js/JsTestDriver/jsTestDriverOrder.php" - ], - [ - "dev/tests/js/JsTestDriver/jsTestDriver.php.dist", - "dev/tests/js/JsTestDriver/jsTestDriver.php.dist" - ], - [ - "dev/tests/js/JsTestDriver/framework", - "dev/tests/js/JsTestDriver/framework" - ], - [ - "dev/tests/js/JsTestDriver/testsuite/lib", - "dev/tests/js/JsTestDriver/testsuite/lib" - ], - [ - "dev/tests/js/JsTestDriver/testsuite/mage", - "dev/tests/js/JsTestDriver/testsuite/mage" - ], - [ - "dev/tests/js/JsTestDriver/.gitignore", - "dev/tests/js/JsTestDriver/.gitignore" - ], [ "dev/tests/js/jasmine", "dev/tests/js/jasmine" diff --git a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/composer.lock b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/composer.lock index f027a2397f97f..48fa6d0d0cd34 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/composer.lock +++ b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/composer.lock @@ -775,18 +775,6 @@ "dev/tests/functional/.gitignore", "dev/tests/functional/.gitignore" ], - [ - "dev/tests/js/run_js_tests.php", - "dev/tests/js/run_js_tests.php" - ], - [ - "dev/tests/js/jsTestDriverOrder.php", - "dev/tests/js/jsTestDriverOrder.php" - ], - [ - "dev/tests/js/jsTestDriver.php.dist", - "dev/tests/js/jsTestDriver.php.dist" - ], [ "dev/tests/js/spec", "dev/tests/js/spec" diff --git a/dev/tests/integration/testsuite/Magento/Framework/Data/Form/Element/FieldsetTest.php b/dev/tests/integration/testsuite/Magento/Framework/Data/Form/Element/FieldsetTest.php index 444e18927f9ee..9453b07f41fc8 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Data/Form/Element/FieldsetTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Data/Form/Element/FieldsetTest.php @@ -246,7 +246,7 @@ public function getSubFieldsetDataProvider() $fieldsetField = $textField; $fieldsetField[1] = 'fieldset'; $advancedFieldsetFld = $fieldsetField; - // set isAdvenced flag + // set isAdvanced flag $advancedFieldsetFld[4] = true; $result = [[[$fieldsetField, $textField, $advancedFieldsetFld], 1]]; return $result; diff --git a/dev/tests/integration/testsuite/Magento/Framework/Mview/View/ChangelogTest.php b/dev/tests/integration/testsuite/Magento/Framework/Mview/View/ChangelogTest.php index b26a1cda2476d..c047bd4fffd3d 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Mview/View/ChangelogTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Mview/View/ChangelogTest.php @@ -126,14 +126,14 @@ public function testGetList() $this->assertEquals(0, $this->model->getVersion()); //the same that a table is empty $changelogName = $this->resource->getTableName($this->model->getName()); - $testChengelogData = [ + $testChangelogData = [ ['version_id' => 1, 'entity_id' => 1], ['version_id' => 2, 'entity_id' => 1], ['version_id' => 3, 'entity_id' => 2], ['version_id' => 4, 'entity_id' => 3], ['version_id' => 5, 'entity_id' => 1], ]; - foreach ($testChengelogData as $data) { + foreach ($testChangelogData as $data) { $this->connection->insert($changelogName, $data); } $this->assertEquals(5, $this->model->getVersion()); diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php index 629089ae4d99e..573531cff960a 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php @@ -36,15 +36,18 @@ protected function setUp() $sessionManager->writeClose(); } $this->deploymentConfigMock = $this->createMock(\Magento\Framework\App\DeploymentConfig::class); - - $this->deploymentConfigMock->expects($this->at(0)) - ->method('get') - ->with(Config::PARAM_SESSION_SAVE_PATH) - ->will($this->returnValue(null)); - $this->deploymentConfigMock->expects($this->at(1)) + $this->deploymentConfigMock ->method('get') - ->with(Config::PARAM_SESSION_CACHE_LIMITER) - ->will($this->returnValue($this->_cacheLimiter)); + ->willReturnCallback(function ($configPath) { + switch ($configPath) { + case Config::PARAM_SESSION_SAVE_METHOD: + return 'files'; + case Config::PARAM_SESSION_CACHE_LIMITER: + return $this->_cacheLimiter; + default: + return null; + } + }); $this->_model = $this->_objectManager->create( \Magento\Framework\Session\Config::class, @@ -83,15 +86,6 @@ public function testDefaultConfiguration() $this->assertEquals($this->_model->getSavePath(), $this->_model->getOption('save_path')); } - /** - * Unable to add integration tests for testGetLifetimePathNonDefault - * - * Error: Cannot modify header information - headers already sent - */ - public function testGetLifetimePathNonDefault() - { - } - public function testSetOptionsInvalidValue() { $preValue = $this->_model->getOptions(); @@ -280,16 +274,27 @@ public function testConstructorSavePath($existing, $given, $expected) $this->markTestSkipped('Cannot set session.save_path with ini_set'); } - $this->deploymentConfigMock->expects($this->at(0)) + $deploymentConfigMock = $this->createMock(\Magento\Framework\App\DeploymentConfig::class); + $deploymentConfigMock ->method('get') - ->with(Config::PARAM_SESSION_SAVE_PATH) - ->will($this->returnValue($given)); - - $this->_model = $this->_objectManager->create( + ->willReturnCallback(function ($configPath) use ($given) { + switch ($configPath) { + case Config::PARAM_SESSION_SAVE_METHOD: + return 'files'; + case Config::PARAM_SESSION_CACHE_LIMITER: + return $this->_cacheLimiter; + case Config::PARAM_SESSION_SAVE_PATH: + return $given; + default: + return null; + } + }); + + $model = $this->_objectManager->create( \Magento\Framework\Session\Config::class, - ['deploymentConfig' => $this->deploymentConfigMock] + ['deploymentConfig' => $deploymentConfigMock] ); - $this->assertEquals($expected, $this->_model->getOption('save_path')); + $this->assertEquals($expected, $model->getOption('save_path')); if ($sessionSavePath != ini_get('session.save_path')) { ini_set('session.save_path', $sessionSavePath); diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php index f30663a199a67..552a23a0c1fd5 100644 --- a/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php +++ b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php @@ -18,10 +18,11 @@ class ValidateTest extends \Magento\TestFramework\TestCase\AbstractBackendContro * @dataProvider validationDataProvider * @param string $fileName * @param string $message + * @param string $delimiter * @backupGlobals enabled * @magentoDbIsolation enabled */ - public function testValidationReturn($fileName, $message) + public function testValidationReturn($fileName, $message, $delimiter) { $validationStrategy = ProcessingErrorAggregatorInterface::VALIDATION_STRATEGY_STOP_ON_ERROR; @@ -36,7 +37,7 @@ public function testValidationReturn($fileName, $message) $this->getRequest()->setPostValue('behavior', 'append'); $this->getRequest()->setPostValue(Import::FIELD_NAME_VALIDATION_STRATEGY, $validationStrategy); $this->getRequest()->setPostValue(Import::FIELD_NAME_ALLOWED_ERROR_COUNT, 0); - $this->getRequest()->setPostValue('_import_field_separator', ','); + $this->getRequest()->setPostValue('_import_field_separator', $delimiter); /** @var \Magento\TestFramework\App\Filesystem $filesystem */ $filesystem = $this->_objectManager->get(\Magento\Framework\Filesystem::class); @@ -83,12 +84,24 @@ public function validationDataProvider() return [ [ 'file_name' => 'catalog_product.csv', - 'message' => 'File is valid' + 'message' => 'File is valid', + 'delimiter' => ',', ], [ 'file_name' => 'test.txt', - 'message' => '\'txt\' file extension is not supported' - ] + 'message' => '\'txt\' file extension is not supported', + 'delimiter' => ',', + ], + [ + 'file_name' => 'incorrect_catalog_product_comma.csv', + 'message' => 'Download full report', + 'delimiter' => ',', + ], + [ + 'file_name' => 'incorrect_catalog_product_semicolon.csv', + 'message' => 'Download full report', + 'delimiter' => ';', + ], ]; } } diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/_files/incorrect_catalog_product_comma.csv b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/_files/incorrect_catalog_product_comma.csv new file mode 100644 index 0000000000000..67114a40b2244 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/_files/incorrect_catalog_product_comma.csv @@ -0,0 +1,2 @@ +sku,store_view_code,attribute_set_code,product_type,categories,product_websites,name,description,short_description,weight,product_online,tax_class_name,visibility,price,special_price,special_price_from_date,special_price_to_date,url_key,meta_title,meta_keywords,meta_description,base_image,base_image_label,small_image,small_image_label,thumbnail_image,thumbnail_image_label,swatch_image,swatch_image_label,created_at,updated_at,new_from_date,new_to_date,display_product_options_in,map_price,msrp_price,map_enabled,gift_message_available,custom_design,custom_design_from,custom_design_to,custom_layout_update,page_layout,product_options_container,msrp_display_actual_price_type,country_of_manufacture,additional_attributes,qty,out_of_stock_qty,use_config_min_qty,is_qty_decimal,allow_backorders,use_config_backorders,min_cart_qty,use_config_min_sale_qty,max_cart_qty,use_config_max_sale_qty,is_in_stock,notify_on_stock_below,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,website_id,related_skus,related_position,crosssell_skus,crosssell_position,upsell_skus,upsell_position,additional_images,additional_image_labels,hide_from_product_page,custom_options,bundle_price_type,bundle_sku_type,bundle_price_view,bundle_weight_type,bundle_values,bundle_shipment_type,configurable_variations,configurable_variation_labels,associated_skus +Simple,,Default,simple,"Default Category/New",base,Simple,,,,1,"Taxable Goods","Catalo g, Search",100.0000,,,,simple,Simple,Simple,"Simple ",,,,,,,,,"10/25/17, 8:21 AM","10/25/17, 8:21 AM",,,"Block after Info Column",,,,"Use config",,,,,,,,,,100.0000,0.0000,1,0,0,1,1.0000,1,10000.0000,1,1,1.0000,1,1,1,1,1.0000,1,0,0,0,,,,,,,,,,,,,,,,,,, diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/_files/incorrect_catalog_product_semicolon.csv b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/_files/incorrect_catalog_product_semicolon.csv new file mode 100644 index 0000000000000..d0a0b8639cf78 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/_files/incorrect_catalog_product_semicolon.csv @@ -0,0 +1,2 @@ +sku;store_view_code;attribute_set_code;product_type;categories;product_websites;name;description;short_description;weight;product_online;tax_class_name;visibility;price;special_price;special_price_from_date;special_price_to_date;url_key;meta_title;meta_keywords;meta_description;base_image;base_image_label;small_image;small_image_label;thumbnail_image;thumbnail_image_label;swatch_image;swatch_image_label;created_at;updated_at;new_from_date;new_to_date;display_product_options_in;map_price;msrp_price;map_enabled;gift_message_available;custom_design;custom_design_from;custom_design_to;custom_layout_update;page_layout;product_options_container;msrp_display_actual_price_type;country_of_manufacture;additional_attributes;qty;out_of_stock_qty;use_config_min_qty;is_qty_decimal;allow_backorders;use_config_backorders;min_cart_qty;use_config_min_sale_qty;max_cart_qty;use_config_max_sale_qty;is_in_stock;notify_on_stock_below;use_config_notify_stock_qty;manage_stock;use_config_manage_stock;use_config_qty_increments;qty_increments;use_config_enable_qty_inc;enable_qty_increments;is_decimal_divided;website_id;related_skus;related_position;crosssell_skus;crosssell_position;upsell_skus;upsell_position;additional_images;additional_image_labels;hide_from_product_page;custom_options;bundle_price_type;bundle_sku_type;bundle_price_view;bundle_weight_type;bundle_values;bundle_shipment_type;configurable_variations;configurable_variation_labels;associated_skus +Simple;;Default;simple;"Default Category/New";base;Simple;;;;1;"Taxable Goods";"Catalo g, Search";100.0000;;;;simple;Simple;Simple;"Simple ";;;;;;;;;"10/25/17, 8,21 AM";"10/25/17, 8,21 AM";;;"Block after Info Column";;;;"Use config";;;;;;;;;;100.0000;0.0000;1;0;0;1;1.0000;1;10000.0000;1;1;1.0000;1;1;1;1;1.0000;1;0;0;0;;;;;;;;;;;;;;;;;;; diff --git a/dev/tests/integration/testsuite/Magento/Integration/Model/ResourceModel/Oauth/TokenTest.php b/dev/tests/integration/testsuite/Magento/Integration/Model/ResourceModel/Oauth/TokenTest.php index ef93099556dd9..57fac92aaabd7 100644 --- a/dev/tests/integration/testsuite/Magento/Integration/Model/ResourceModel/Oauth/TokenTest.php +++ b/dev/tests/integration/testsuite/Magento/Integration/Model/ResourceModel/Oauth/TokenTest.php @@ -252,7 +252,7 @@ public function deleteExpiredTokensDataProvider() } /** - * Make that only exired tokens were cleaned up + * Make that only expired tokens were cleaned up * * @param array $expectedRemovedTokenNumbers * @param array $expectedPreservedTokenNumbers diff --git a/dev/tests/integration/testsuite/Magento/Newsletter/_files/subscribers.php b/dev/tests/integration/testsuite/Magento/Newsletter/_files/subscribers.php index 152d65681c54f..84e72979cc4c5 100644 --- a/dev/tests/integration/testsuite/Magento/Newsletter/_files/subscribers.php +++ b/dev/tests/integration/testsuite/Magento/Newsletter/_files/subscribers.php @@ -28,7 +28,7 @@ $subscriber = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->create(\Magento\Newsletter\Model\Subscriber::class); -$subscriber->setStoreId($otherStore) +$subscriber->setStoreId($currentStore) // Intentionally setting ID to 0 instead of 2 to test fallback mechanism in Subscriber model ->setCustomerId(0) ->setSubscriberEmail('customer_two@example.com') diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Controller/ExpressTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Controller/ExpressTest.php index 157999224d7b8..3d30f8366598a 100644 --- a/dev/tests/integration/testsuite/Magento/Paypal/Controller/ExpressTest.php +++ b/dev/tests/integration/testsuite/Magento/Paypal/Controller/ExpressTest.php @@ -140,11 +140,12 @@ public function testStartActionCustomerToQuote() /** * Test return action with configurable product. - * - * @magentoDataFixture Magento/Paypal/_files/quote_express_configurable.php */ public function testReturnAction() { + // Skipped due to MAGETWO-87333 + //@magentoDataFixture Magento/Paypal/_files/quote_express_configurable.php + $this->markTestSkipped('MAGETWO-87333'); $quote = $this->_objectManager->create(Quote::class); $quote->load('test_cart_with_configurable', 'reserved_order_id'); diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php index 2da602c52242d..1a22ea947f85a 100644 --- a/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php +++ b/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php @@ -123,7 +123,7 @@ public function testProcessIpnRequestPartialRefund() /** * Refund rest of order amount by Paypal Express IPN message service. * - * @magentoDataFixture Magento/Paypal/_files/order_express_with_invoice_and_creditmemo.php + * @magentoDataFixture Magento/Paypal/_files/order_express_with_invoice_and_shipping.php * @magentoConfigFixture current_store payment/paypal_express/active 1 * @magentoConfigFixture current_store paypal/general/merchant_country US */ @@ -147,7 +147,7 @@ public function testProcessIpnRequestRestRefund() $creditmemoItems = $order->getCreditmemosCollection()->getItems(); $this->assertEquals(Order::STATE_CLOSED, $order->getState()) ; - $this->assertEquals(2, count($creditmemoItems)); + $this->assertEquals(1, count($creditmemoItems)); $this->assertEquals(10, $order->getSubtotalRefunded()); $this->assertEquals(10, $order->getBaseSubtotalRefunded()); $this->assertEquals(20, $order->getShippingRefunded()); diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php index 258b14bf6e0d3..ecd8b62b122d4 100644 --- a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php +++ b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php @@ -393,7 +393,7 @@ protected function _getCustomerDataArray() \Magento\Customer\Model\Data\Customer::DOB => '2014-02-03 00:00:00', \Magento\Customer\Model\Data\Customer::EMAIL => 'qa@example.com', \Magento\Customer\Model\Data\Customer::FIRSTNAME => 'Joe', - \Magento\Customer\Model\Data\Customer::GENDER => 'Male', + \Magento\Customer\Model\Data\Customer::GENDER => 0, \Magento\Customer\Model\Data\Customer::GROUP_ID => \Magento\Customer\Model\GroupManagement::NOT_LOGGED_IN_ID, \Magento\Customer\Model\Data\Customer::ID => 1, diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php index 5f3dbdabc640a..e071dde26a263 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php @@ -5,6 +5,10 @@ */ namespace Magento\Sales\Controller\Adminhtml\Order; +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Backend\Model\Session\Quote; +use Magento\Quote\Api\CartRepositoryInterface; + /** * @magentoAppArea adminhtml * @magentoDbIsolation enabled @@ -158,7 +162,7 @@ public function testIndexAction() */ public function testGetAclResource($actionName, $reordered, $expectedResult) { - $this->_objectManager->get(\Magento\Backend\Model\Session\Quote::class)->setReordered($reordered); + $this->_objectManager->get(Quote::class)->setReordered($reordered); $orderController = $this->_objectManager->get( \Magento\Sales\Controller\Adminhtml\Order\Stub\OrderCreateStub::class ); @@ -229,4 +233,57 @@ public function testDeniedSaveAction() $this->dispatch('backend/sales/order_create/save'); $this->assertEquals('403', $this->getResponse()->getHttpResponseCode()); } + + /** + * Checks a case when shipping is the same as billing and billing address details was changed by request. + * Both billing and shipping addresses should be updated. + * + * @magentoAppArea adminhtml + * @magentoDataFixture Magento/Sales/_files/quote_with_customer.php + */ + public function testSyncBetweenQuoteAddresses() + { + /** @var CustomerRepositoryInterface $customerRepository */ + $customerRepository = $this->_objectManager->get(CustomerRepositoryInterface::class); + $customer = $customerRepository->get('customer@example.com'); + + /** @var CartRepositoryInterface $quoteRepository */ + $quoteRepository = $this->_objectManager->get(CartRepositoryInterface::class); + $quote = $quoteRepository->getActiveForCustomer($customer->getId()); + + $session = $this->_objectManager->get(Quote::class); + $session->setQuoteId($quote->getId()); + + $data = [ + 'firstname' => 'John', + 'lastname' => 'Doe', + 'street' => ['Soborna 23'], + 'city' => 'Kyiv', + 'country_id' => 'UA', + 'region' => 'Kyivska', + 'region_id' => 1 + ]; + $this->getRequest()->setPostValue( + [ + 'order' => ['billing_address' => $data], + 'reset_shipping' => 1, + 'customer_id' => $customer->getId(), + 'store_id' => 1, + 'json' => true + ] + ); + + $this->dispatch('backend/sales/order_create/loadBlock/block/shipping_address'); + self::assertEquals(200, $this->getResponse()->getHttpResponseCode()); + + $updatedQuote = $quoteRepository->get($quote->getId()); + + $billingAddress = $updatedQuote->getBillingAddress(); + self::assertEquals($data['region_id'], $billingAddress->getRegionId()); + self::assertEquals($data['country_id'], $billingAddress->getCountryId()); + + $shippingAddress = $updatedQuote->getShippingAddress(); + self::assertEquals($data['city'], $shippingAddress->getCity()); + self::assertEquals($data['street'], $shippingAddress->getStreet()); + } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php index 946d15b6a81d7..ee7ddc1ba1aba 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php @@ -394,7 +394,7 @@ public function testCreateOrderNewCustomerDifferentAddresses() } /** - * @magentoDataFixture Magento/Catalog/_files/product_simple.php + * @magentoDataFixture Magento/Catalog/_files/product_simple_with_decimal_qty.php * @magentoDbIsolation enabled * @magentoAppIsolation enabled */ @@ -425,6 +425,10 @@ public function testCreateOrderNewCustomer() $paymentMethod ); $order = $this->_model->createOrder(); + //Check, order considering decimal qty in product. + foreach ($order->getItems() as $orderItem) { + self::assertTrue($orderItem->getIsQtyDecimal()); + } $this->_verifyCreatedOrder($order, $shippingMethod); } diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/StatusTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/StatusTest.php new file mode 100644 index 0000000000000..e4b64e77d6e05 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/StatusTest.php @@ -0,0 +1,49 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Sales\Model\Order; + +/** + * Class ShipmentTest + * @package Magento\Sales\Model\Order + */ +class StatusTest extends \PHPUnit\Framework\TestCase +{ + public function theCorrectLabelIsUsedDependingOnTheAreaProvider() + { + return [ + 'backend label' => [ + 'adminhtml', + 'Example', + ], + 'store view label' => [ + 'frontend', + 'Store view example', + ], + ]; + } + + /** + * In the backend the regular label must be showed. + * + * @param $area + * @param $result + * + * @magentoDataFixture Magento/Sales/_files/order_status.php + * @dataProvider theCorrectLabelIsUsedDependingOnTheAreaProvider + */ + public function testTheCorrectLabelIsUsedDependingOnTheArea($area, $result) + { + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $objectManager->get(\Magento\Framework\App\State::class)->setAreaCode($area); + + /** @var \Magento\Sales\Model\Order $order */ + $order = $objectManager->create(\Magento\Sales\Model\Order::class); + $order->loadByIncrementId('100000001'); + + $this->assertEquals($result, $order->getStatusLabel()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_status.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_status.php new file mode 100644 index 0000000000000..e65dd6b682396 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_status.php @@ -0,0 +1,25 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +require __DIR__ . '/order.php'; + +$orderStatus = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Sales\Model\Order\Status::class +); + +$data = [ + 'status' => 'example', + 'label' => 'Example', + 'store_labels' => [ + 1 => 'Store view example', + ] +]; + +$orderStatus->setData($data)->setStatus('example'); +$orderStatus->save(); + +$order->setStatus('example'); +$order->save(); diff --git a/dev/tests/integration/testsuite/Magento/Search/Model/SearchEngine/ConfigTest.php b/dev/tests/integration/testsuite/Magento/Search/Model/SearchEngine/ConfigTest.php index 49d73e71672d4..74926abb52d41 100644 --- a/dev/tests/integration/testsuite/Magento/Search/Model/SearchEngine/ConfigTest.php +++ b/dev/tests/integration/testsuite/Magento/Search/Model/SearchEngine/ConfigTest.php @@ -17,7 +17,7 @@ protected function setUp() $xmlPath = __DIR__ . '/../../_files/search_engine.xml'; $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - // Clear out the clache + // Clear out the cache $cacheManager = $objectManager->create(\Magento\Framework\App\Cache\Manager::class); /** @var \Magento\Framework\App\Cache\Manager $cacheManager */ $cacheManager->clean($cacheManager->getAvailableTypes()); diff --git a/dev/tests/integration/testsuite/Magento/Setup/Model/_files/testSkeleton/composer.lock b/dev/tests/integration/testsuite/Magento/Setup/Model/_files/testSkeleton/composer.lock index f027a2397f97f..48fa6d0d0cd34 100644 --- a/dev/tests/integration/testsuite/Magento/Setup/Model/_files/testSkeleton/composer.lock +++ b/dev/tests/integration/testsuite/Magento/Setup/Model/_files/testSkeleton/composer.lock @@ -775,18 +775,6 @@ "dev/tests/functional/.gitignore", "dev/tests/functional/.gitignore" ], - [ - "dev/tests/js/run_js_tests.php", - "dev/tests/js/run_js_tests.php" - ], - [ - "dev/tests/js/jsTestDriverOrder.php", - "dev/tests/js/jsTestDriverOrder.php" - ], - [ - "dev/tests/js/jsTestDriver.php.dist", - "dev/tests/js/jsTestDriver.php.dist" - ], [ "dev/tests/js/spec", "dev/tests/js/spec" diff --git a/dev/tests/integration/testsuite/Magento/Shipping/Helper/DataTest.php b/dev/tests/integration/testsuite/Magento/Shipping/Helper/DataTest.php index eaac89cc6851b..99a28812a12d5 100644 --- a/dev/tests/integration/testsuite/Magento/Shipping/Helper/DataTest.php +++ b/dev/tests/integration/testsuite/Magento/Shipping/Helper/DataTest.php @@ -5,16 +5,18 @@ */ namespace Magento\Shipping\Helper; +use Magento\Store\Model\StoreManagerInterface; + class DataTest extends \PHPUnit\Framework\TestCase { /** * @var \Magento\Shipping\Helper\Data */ - protected $_helper = null; + private $helper; protected function setUp() { - $this->_helper = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + $this->helper = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( \Magento\Shipping\Helper\Data::class ); } @@ -31,33 +33,77 @@ public function testGetTrackingPopupUrlBySalesModel($modelName, $getIdMethod, $e { $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); $constructArgs = []; - if (\Magento\Sales\Model\Order\Shipment::class == $modelName) { - $orderRepository = $this->_getMockOrderRepository($code); + if (\Magento\Sales\Model\Order\Shipment::class === $modelName) { + $orderRepository = $this->getMockOrderRepository($code); + $constructArgs['orderRepository'] = $orderRepository; + } elseif (\Magento\Sales\Model\Order\Shipment\Track::class === $modelName) { + $shipmentRepository = $this->getMockShipmentRepository($code); + $constructArgs['shipmentRepository'] = $shipmentRepository; + } + + $model = $objectManager->create($modelName, $constructArgs); + $model->{$getIdMethod}($entityId); + + if (\Magento\Sales\Model\Order::class === $modelName) { + $model->setProtectCode($code); + } + if (\Magento\Sales\Model\Order\Shipment\Track::class === $modelName) { + $model->setParentId(1); + } + + $actual = $this->helper->getTrackingPopupUrlBySalesModel($model); + $this->assertEquals($expected, $actual); + } + + /** + * From the admin panel with custom URL we should have generated frontend URL + * + * @param string $modelName + * @param string $getIdMethod + * @param int $entityId + * @param string $code + * @param string $expected + * @magentoAppArea adminhtml + * @magentoConfigFixture admin_store web/unsecure/base_link_url http://admin.localhost/ + * @dataProvider getTrackingPopupUrlBySalesModelDataProvider + */ + public function testGetTrackingPopupUrlBySalesModelFromAdmin($modelName, $getIdMethod, $entityId, $code, $expected) + { + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + + /** @var StoreManagerInterface $storeManager */ + $storeManager = $objectManager->create(StoreManagerInterface::class); + $storeManager->reinitStores(); + + $constructArgs = []; + if (\Magento\Sales\Model\Order\Shipment::class === $modelName) { + $orderRepository = $this->getMockOrderRepository($code); $constructArgs['orderRepository'] = $orderRepository; - } elseif (\Magento\Sales\Model\Order\Shipment\Track::class == $modelName) { - $shipmentRepository = $this->_getMockShipmentRepository($code); + } elseif (\Magento\Sales\Model\Order\Shipment\Track::class === $modelName) { + $shipmentRepository = $this->getMockShipmentRepository($code); $constructArgs['shipmentRepository'] = $shipmentRepository; } $model = $objectManager->create($modelName, $constructArgs); $model->{$getIdMethod}($entityId); - if (\Magento\Sales\Model\Order::class == $modelName) { + if (\Magento\Sales\Model\Order::class === $modelName) { $model->setProtectCode($code); } - if (\Magento\Sales\Model\Order\Shipment\Track::class == $modelName) { + if (\Magento\Sales\Model\Order\Shipment\Track::class === $modelName) { $model->setParentId(1); } - $actual = $this->_helper->getTrackingPopupUrlBySalesModel($model); + //Frontend URL should be used there + $actual = $this->helper->getTrackingPopupUrlBySalesModel($model); $this->assertEquals($expected, $actual); } /** * @param $code - * @return \Magento\Sales\Api\OrderRepositoryInterface + * @return \Magento\Sales\Api\OrderRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected function _getMockOrderRepository($code) + private function getMockOrderRepository($code) { $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); $order = $objectManager->create(\Magento\Sales\Model\Order::class); @@ -71,10 +117,10 @@ protected function _getMockOrderRepository($code) * @param $code * @return \Magento\Sales\Model\Order\ShipmentRepository|\PHPUnit_Framework_MockObject_MockObject */ - protected function _getMockShipmentRepository($code) + private function getMockShipmentRepository($code) { $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $orderRepository = $this->_getMockOrderRepository($code); + $orderRepository = $this->getMockOrderRepository($code); $shipmentArgs = ['orderRepository' => $orderRepository]; $shipment = $objectManager->create(\Magento\Sales\Model\Order\Shipment::class, $shipmentArgs); diff --git a/dev/tests/integration/testsuite/Magento/Theme/Model/Design/ConfigTest.php b/dev/tests/integration/testsuite/Magento/Theme/Model/Design/ConfigTest.php new file mode 100644 index 0000000000000..0ff43a5fd41ca --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Theme/Model/Design/ConfigTest.php @@ -0,0 +1,40 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Theme\Model\Design; + +/** + * Test for \Magento\Theme\Model\Design\Config\Storage. + */ +class ConfigTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\Theme\Model\Design\Config\Storage + */ + private $storage; + + protected function setUp() + { + $this->storage = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Theme\Model\Design\Config\Storage::class + ); + } + + /** + * Test design/header/welcome if it is saved in db as empty(null) it should be shown on backend as empty. + * + * @magentoDataFixture Magento/Theme/_files/config_data.php + */ + public function testLoad() + { + $data = $this->storage->load('stores', 1); + foreach ($data->getExtensionAttributes()->getDesignConfigData() as $configData) { + if ($configData->getPath() == 'design/header/welcome') { + $this->assertSame('', $configData->getValue()); + } + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/Theme/_files/config_data.php b/dev/tests/integration/testsuite/Magento/Theme/_files/config_data.php new file mode 100644 index 0000000000000..b8cbebc1f67c1 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Theme/_files/config_data.php @@ -0,0 +1,19 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Config\Model\Config\Factory; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); + +/** @var Factory $configFactory */ +$configFactory = $objectManager->create(Factory::class); +/** @var \Magento\Config\Model\Config $config */ +$config = $configFactory->create(); +$config->setScope('stores'); +$config->setStore('default'); +$config->setDataByPath('design/header/welcome', null); +$config->save(); diff --git a/dev/tests/integration/testsuite/Magento/Theme/_files/config_data_rollback.php b/dev/tests/integration/testsuite/Magento/Theme/_files/config_data_rollback.php new file mode 100644 index 0000000000000..ac02e98b49373 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Theme/_files/config_data_rollback.php @@ -0,0 +1,13 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +/** @var \Magento\Framework\App\ResourceConnection $resource */ +$resource = $objectManager->get(\Magento\Framework\App\ResourceConnection::class); +$connection = $resource->getConnection(); +$tableName = $resource->getTableName('core_config_data'); + +$connection->query("DELETE FROM $tableName WHERE path = 'design/header/welcome';"); diff --git a/dev/tests/integration/testsuite/Magento/Widget/Model/Template/FilterTest.php b/dev/tests/integration/testsuite/Magento/Widget/Model/Template/FilterTest.php index 095193ca0e764..fc3b0399d0497 100644 --- a/dev/tests/integration/testsuite/Magento/Widget/Model/Template/FilterTest.php +++ b/dev/tests/integration/testsuite/Magento/Widget/Model/Template/FilterTest.php @@ -20,4 +20,18 @@ public function testMediaDirective() $result = $filter->mediaDirective($construction); $this->assertEquals($baseUrl . $image, $result); } + + public function testMediaDirectiveWithEncodedQuotes() + { + $image = 'wysiwyg/VB.png'; + $construction = ['{{media url="' . $image . '"}}', 'media', ' url="' . $image . '"']; + $baseUrl = 'http://localhost/pub/media/'; + + /** @var \Magento\Widget\Model\Template\Filter $filter */ + $filter = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Widget\Model\Template\Filter::class + ); + $result = $filter->mediaDirective($construction); + $this->assertEquals($baseUrl . $image, $result); + } } diff --git a/dev/tests/js/JsTestDriver/.gitignore b/dev/tests/js/JsTestDriver/.gitignore deleted file mode 100644 index e94f6f277fc54..0000000000000 --- a/dev/tests/js/JsTestDriver/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -test-output/ -jsTestDriver.php -jsTestDriver.conf \ No newline at end of file diff --git a/dev/tests/js/JsTestDriver/framework/qunit/qunit-1.14.0.css b/dev/tests/js/JsTestDriver/framework/qunit/qunit-1.14.0.css deleted file mode 100644 index 93026e3ba3f6d..0000000000000 --- a/dev/tests/js/JsTestDriver/framework/qunit/qunit-1.14.0.css +++ /dev/null @@ -1,237 +0,0 @@ -/*! - * QUnit 1.14.0 - * http://qunitjs.com/ - * - * Copyright 2013 jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-01-31T16:40Z - */ - -/** Font Family and Sizes */ - -#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { - font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; -} - -#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } -#qunit-tests { font-size: smaller; } - - -/** Resets */ - -#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { - margin: 0; - padding: 0; -} - - -/** Header */ - -#qunit-header { - padding: 0.5em 0 0.5em 1em; - - color: #8699A4; - background-color: #0D3349; - - font-size: 1.5em; - line-height: 1em; - font-weight: 400; - - border-radius: 5px 5px 0 0; -} - -#qunit-header a { - text-decoration: none; - color: #C2CCD1; -} - -#qunit-header a:hover, -#qunit-header a:focus { - color: #FFF; -} - -#qunit-testrunner-toolbar label { - display: inline-block; - padding: 0 0.5em 0 0.1em; -} - -#qunit-banner { - height: 5px; -} - -#qunit-testrunner-toolbar { - padding: 0.5em 0 0.5em 2em; - color: #5E740B; - background-color: #EEE; - overflow: hidden; -} - -#qunit-userAgent { - padding: 0.5em 0 0.5em 2.5em; - background-color: #2B81AF; - color: #FFF; - text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; -} - -#qunit-modulefilter-container { - float: right; -} - -/** Tests: Pass/Fail */ - -#qunit-tests { - list-style-position: inside; -} - -#qunit-tests li { - padding: 0.4em 0.5em 0.4em 2.5em; - border-bottom: 1px solid #FFF; - list-style-position: inside; -} - -#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { - display: none; -} - -#qunit-tests li strong { - cursor: pointer; -} - -#qunit-tests li a { - padding: 0.5em; - color: #C2CCD1; - text-decoration: none; -} -#qunit-tests li a:hover, -#qunit-tests li a:focus { - color: #000; -} - -#qunit-tests li .runtime { - float: right; - font-size: smaller; -} - -.qunit-assert-list { - margin-top: 0.5em; - padding: 0.5em; - - background-color: #FFF; - - border-radius: 5px; -} - -.qunit-collapsed { - display: none; -} - -#qunit-tests table { - border-collapse: collapse; - margin-top: 0.2em; -} - -#qunit-tests th { - text-align: right; - vertical-align: top; - padding: 0 0.5em 0 0; -} - -#qunit-tests td { - vertical-align: top; -} - -#qunit-tests pre { - margin: 0; - white-space: pre-wrap; - word-wrap: break-word; -} - -#qunit-tests del { - background-color: #E0F2BE; - color: #374E0C; - text-decoration: none; -} - -#qunit-tests ins { - background-color: #FFCACA; - color: #500; - text-decoration: none; -} - -/*** Test Counts */ - -#qunit-tests b.counts { color: #000; } -#qunit-tests b.passed { color: #5E740B; } -#qunit-tests b.failed { color: #710909; } - -#qunit-tests li li { - padding: 5px; - background-color: #FFF; - border-bottom: none; - list-style-position: inside; -} - -/*** Passing Styles */ - -#qunit-tests li li.pass { - color: #3C510C; - background-color: #FFF; - border-left: 10px solid #C6E746; -} - -#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } -#qunit-tests .pass .test-name { color: #366097; } - -#qunit-tests .pass .test-actual, -#qunit-tests .pass .test-expected { color: #999; } - -#qunit-banner.qunit-pass { background-color: #C6E746; } - -/*** Failing Styles */ - -#qunit-tests li li.fail { - color: #710909; - background-color: #FFF; - border-left: 10px solid #EE5757; - white-space: pre; -} - -#qunit-tests > li:last-child { - border-radius: 0 0 5px 5px; -} - -#qunit-tests .fail { color: #000; background-color: #EE5757; } -#qunit-tests .fail .test-name, -#qunit-tests .fail .module-name { color: #000; } - -#qunit-tests .fail .test-actual { color: #EE5757; } -#qunit-tests .fail .test-expected { color: #008000; } - -#qunit-banner.qunit-fail { background-color: #EE5757; } - - -/** Result */ - -#qunit-testresult { - padding: 0.5em 0.5em 0.5em 2.5em; - - color: #2B81AF; - background-color: #D2E0E6; - - border-bottom: 1px solid #FFF; -} -#qunit-testresult .module-name { - font-weight: 700; -} - -/** Fixture */ - -#qunit-fixture { - position: absolute; - top: -10000px; - left: -10000px; - width: 1000px; - height: 1000px; -} diff --git a/dev/tests/js/JsTestDriver/framework/qunit/qunit-1.14.0.js b/dev/tests/js/JsTestDriver/framework/qunit/qunit-1.14.0.js deleted file mode 100644 index 0e279fde17024..0000000000000 --- a/dev/tests/js/JsTestDriver/framework/qunit/qunit-1.14.0.js +++ /dev/null @@ -1,2288 +0,0 @@ -/*! - * QUnit 1.14.0 - * http://qunitjs.com/ - * - * Copyright 2013 jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-01-31T16:40Z - */ - -(function( window ) { - -var QUnit, - assert, - config, - onErrorFnPrev, - testId = 0, - fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""), - toString = Object.prototype.toString, - hasOwn = Object.prototype.hasOwnProperty, - // Keep a local reference to Date (GH-283) - Date = window.Date, - setTimeout = window.setTimeout, - clearTimeout = window.clearTimeout, - defined = { - document: typeof window.document !== "undefined", - setTimeout: typeof window.setTimeout !== "undefined", - sessionStorage: (function() { - var x = "qunit-test-string"; - try { - sessionStorage.setItem( x, x ); - sessionStorage.removeItem( x ); - return true; - } catch( e ) { - return false; - } - }()) - }, - /** - * Provides a normalized error string, correcting an issue - * with IE 7 (and prior) where Error.prototype.toString is - * not properly implemented - * - * Based on http://es5.github.com/#x15.11.4.4 - * - * @param {String|Error} error - * @return {String} error message - */ - errorString = function( error ) { - var name, message, - errorString = error.toString(); - if ( errorString.substring( 0, 7 ) === "[object" ) { - name = error.name ? error.name.toString() : "Error"; - message = error.message ? error.message.toString() : ""; - if ( name && message ) { - return name + ": " + message; - } else if ( name ) { - return name; - } else if ( message ) { - return message; - } else { - return "Error"; - } - } else { - return errorString; - } - }, - /** - * Makes a clone of an object using only Array or Object as base, - * and copies over the own enumerable properties. - * - * @param {Object} obj - * @return {Object} New object with only the own properties (recursively). - */ - objectValues = function( obj ) { - // Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392. - /*jshint newcap: false */ - var key, val, - vals = QUnit.is( "array", obj ) ? [] : {}; - for ( key in obj ) { - if ( hasOwn.call( obj, key ) ) { - val = obj[key]; - vals[key] = val === Object(val) ? objectValues(val) : val; - } - } - return vals; - }; - - -// Root QUnit object. -// `QUnit` initialized at top of scope -QUnit = { - - // call on start of module test to prepend name to all tests - module: function( name, testEnvironment ) { - config.currentModule = name; - config.currentModuleTestEnvironment = testEnvironment; - config.modules[name] = true; - }, - - asyncTest: function( testName, expected, callback ) { - if ( arguments.length === 2 ) { - callback = expected; - expected = null; - } - - QUnit.test( testName, expected, callback, true ); - }, - - test: function( testName, expected, callback, async ) { - var test, - nameHtml = "<span class='test-name'>" + escapeText( testName ) + "</span>"; - - if ( arguments.length === 2 ) { - callback = expected; - expected = null; - } - - if ( config.currentModule ) { - nameHtml = "<span class='module-name'>" + escapeText( config.currentModule ) + "</span>: " + nameHtml; - } - - test = new Test({ - nameHtml: nameHtml, - testName: testName, - expected: expected, - async: async, - callback: callback, - module: config.currentModule, - moduleTestEnvironment: config.currentModuleTestEnvironment, - stack: sourceFromStacktrace( 2 ) - }); - - if ( !validTest( test ) ) { - return; - } - - test.queue(); - }, - - // Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through. - expect: function( asserts ) { - if (arguments.length === 1) { - config.current.expected = asserts; - } else { - return config.current.expected; - } - }, - - start: function( count ) { - // QUnit hasn't been initialized yet. - // Note: RequireJS (et al) may delay onLoad - if ( config.semaphore === undefined ) { - QUnit.begin(function() { - // This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first - setTimeout(function() { - QUnit.start( count ); - }); - }); - return; - } - - config.semaphore -= count || 1; - // don't start until equal number of stop-calls - if ( config.semaphore > 0 ) { - return; - } - // ignore if start is called more often then stop - if ( config.semaphore < 0 ) { - config.semaphore = 0; - QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) ); - return; - } - // A slight delay, to avoid any current callbacks - if ( defined.setTimeout ) { - setTimeout(function() { - if ( config.semaphore > 0 ) { - return; - } - if ( config.timeout ) { - clearTimeout( config.timeout ); - } - - config.blocking = false; - process( true ); - }, 13); - } else { - config.blocking = false; - process( true ); - } - }, - - stop: function( count ) { - config.semaphore += count || 1; - config.blocking = true; - - if ( config.testTimeout && defined.setTimeout ) { - clearTimeout( config.timeout ); - config.timeout = setTimeout(function() { - QUnit.ok( false, "Test timed out" ); - config.semaphore = 1; - QUnit.start(); - }, config.testTimeout ); - } - } -}; - -// We use the prototype to distinguish between properties that should -// be exposed as globals (and in exports) and those that shouldn't -(function() { - function F() {} - F.prototype = QUnit; - QUnit = new F(); - // Make F QUnit's constructor so that we can add to the prototype later - QUnit.constructor = F; -}()); - -/** - * Config object: Maintain internal state - * Later exposed as QUnit.config - * `config` initialized at top of scope - */ -config = { - // The queue of tests to run - queue: [], - - // block until document ready - blocking: true, - - // when enabled, show only failing tests - // gets persisted through sessionStorage and can be changed in UI via checkbox - hidepassed: false, - - // by default, run previously failed tests first - // very useful in combination with "Hide passed tests" checked - reorder: true, - - // by default, modify document.title when suite is done - altertitle: true, - - // by default, scroll to top of the page when suite is done - scrolltop: true, - - // when enabled, all tests must call expect() - requireExpects: false, - - // add checkboxes that are persisted in the query-string - // when enabled, the id is set to `true` as a `QUnit.config` property - urlConfig: [ - { - id: "noglobals", - label: "Check for Globals", - tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings." - }, - { - id: "notrycatch", - label: "No try-catch", - tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings." - } - ], - - // Set of all modules. - modules: {}, - - // logging callback queues - begin: [], - done: [], - log: [], - testStart: [], - testDone: [], - moduleStart: [], - moduleDone: [] -}; - -// Initialize more QUnit.config and QUnit.urlParams -(function() { - var i, current, - location = window.location || { search: "", protocol: "file:" }, - params = location.search.slice( 1 ).split( "&" ), - length = params.length, - urlParams = {}; - - if ( params[ 0 ] ) { - for ( i = 0; i < length; i++ ) { - current = params[ i ].split( "=" ); - current[ 0 ] = decodeURIComponent( current[ 0 ] ); - - // allow just a key to turn on a flag, e.g., test.html?noglobals - current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; - if ( urlParams[ current[ 0 ] ] ) { - urlParams[ current[ 0 ] ] = [].concat( urlParams[ current[ 0 ] ], current[ 1 ] ); - } else { - urlParams[ current[ 0 ] ] = current[ 1 ]; - } - } - } - - QUnit.urlParams = urlParams; - - // String search anywhere in moduleName+testName - config.filter = urlParams.filter; - - // Exact match of the module name - config.module = urlParams.module; - - config.testNumber = []; - if ( urlParams.testNumber ) { - - // Ensure that urlParams.testNumber is an array - urlParams.testNumber = [].concat( urlParams.testNumber ); - for ( i = 0; i < urlParams.testNumber.length; i++ ) { - current = urlParams.testNumber[ i ]; - config.testNumber.push( parseInt( current, 10 ) ); - } - } - - // Figure out if we're running the tests from a server or not - QUnit.isLocal = location.protocol === "file:"; -}()); - -extend( QUnit, { - - config: config, - - // Initialize the configuration options - init: function() { - extend( config, { - stats: { all: 0, bad: 0 }, - moduleStats: { all: 0, bad: 0 }, - started: +new Date(), - updateRate: 1000, - blocking: false, - autostart: true, - autorun: false, - filter: "", - queue: [], - semaphore: 1 - }); - - var tests, banner, result, - qunit = id( "qunit" ); - - if ( qunit ) { - qunit.innerHTML = - "<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" + - "<h2 id='qunit-banner'></h2>" + - "<div id='qunit-testrunner-toolbar'></div>" + - "<h2 id='qunit-userAgent'></h2>" + - "<ol id='qunit-tests'></ol>"; - } - - tests = id( "qunit-tests" ); - banner = id( "qunit-banner" ); - result = id( "qunit-testresult" ); - - if ( tests ) { - tests.innerHTML = ""; - } - - if ( banner ) { - banner.className = ""; - } - - if ( result ) { - result.parentNode.removeChild( result ); - } - - if ( tests ) { - result = document.createElement( "p" ); - result.id = "qunit-testresult"; - result.className = "result"; - tests.parentNode.insertBefore( result, tests ); - result.innerHTML = "Running...<br/> "; - } - }, - - // Resets the test setup. Useful for tests that modify the DOM. - /* - DEPRECATED: Use multiple tests instead of resetting inside a test. - Use testStart or testDone for custom cleanup. - This method will throw an error in 2.0, and will be removed in 2.1 - */ - reset: function() { - var fixture = id( "qunit-fixture" ); - if ( fixture ) { - fixture.innerHTML = config.fixture; - } - }, - - // Safe object type checking - is: function( type, obj ) { - return QUnit.objectType( obj ) === type; - }, - - objectType: function( obj ) { - if ( typeof obj === "undefined" ) { - return "undefined"; - } - - // Consider: typeof null === object - if ( obj === null ) { - return "null"; - } - - var match = toString.call( obj ).match(/^\[object\s(.*)\]$/), - type = match && match[1] || ""; - - switch ( type ) { - case "Number": - if ( isNaN(obj) ) { - return "nan"; - } - return "number"; - case "String": - case "Boolean": - case "Array": - case "Date": - case "RegExp": - case "Function": - return type.toLowerCase(); - } - if ( typeof obj === "object" ) { - return "object"; - } - return undefined; - }, - - push: function( result, actual, expected, message ) { - if ( !config.current ) { - throw new Error( "assertion outside test context, was " + sourceFromStacktrace() ); - } - - var output, source, - details = { - module: config.current.module, - name: config.current.testName, - result: result, - message: message, - actual: actual, - expected: expected - }; - - message = escapeText( message ) || ( result ? "okay" : "failed" ); - message = "<span class='test-message'>" + message + "</span>"; - output = message; - - if ( !result ) { - expected = escapeText( QUnit.jsDump.parse(expected) ); - actual = escapeText( QUnit.jsDump.parse(actual) ); - output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>"; - - if ( actual !== expected ) { - output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>"; - output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>"; - } - - source = sourceFromStacktrace(); - - if ( source ) { - details.source = source; - output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>"; - } - - output += "</table>"; - } - - runLoggingCallbacks( "log", QUnit, details ); - - config.current.assertions.push({ - result: !!result, - message: output - }); - }, - - pushFailure: function( message, source, actual ) { - if ( !config.current ) { - throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) ); - } - - var output, - details = { - module: config.current.module, - name: config.current.testName, - result: false, - message: message - }; - - message = escapeText( message ) || "error"; - message = "<span class='test-message'>" + message + "</span>"; - output = message; - - output += "<table>"; - - if ( actual ) { - output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText( actual ) + "</pre></td></tr>"; - } - - if ( source ) { - details.source = source; - output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>"; - } - - output += "</table>"; - - runLoggingCallbacks( "log", QUnit, details ); - - config.current.assertions.push({ - result: false, - message: output - }); - }, - - url: function( params ) { - params = extend( extend( {}, QUnit.urlParams ), params ); - var key, - querystring = "?"; - - for ( key in params ) { - if ( hasOwn.call( params, key ) ) { - querystring += encodeURIComponent( key ) + "=" + - encodeURIComponent( params[ key ] ) + "&"; - } - } - return window.location.protocol + "//" + window.location.host + - window.location.pathname + querystring.slice( 0, -1 ); - }, - - extend: extend, - id: id, - addEvent: addEvent, - addClass: addClass, - hasClass: hasClass, - removeClass: removeClass - // load, equiv, jsDump, diff: Attached later -}); - -/** - * @deprecated: Created for backwards compatibility with test runner that set the hook function - * into QUnit.{hook}, instead of invoking it and passing the hook function. - * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here. - * Doing this allows us to tell if the following methods have been overwritten on the actual - * QUnit object. - */ -extend( QUnit.constructor.prototype, { - - // Logging callbacks; all receive a single argument with the listed properties - // run test/logs.html for any related changes - begin: registerLoggingCallback( "begin" ), - - // done: { failed, passed, total, runtime } - done: registerLoggingCallback( "done" ), - - // log: { result, actual, expected, message } - log: registerLoggingCallback( "log" ), - - // testStart: { name } - testStart: registerLoggingCallback( "testStart" ), - - // testDone: { name, failed, passed, total, runtime } - testDone: registerLoggingCallback( "testDone" ), - - // moduleStart: { name } - moduleStart: registerLoggingCallback( "moduleStart" ), - - // moduleDone: { name, failed, passed, total } - moduleDone: registerLoggingCallback( "moduleDone" ) -}); - -if ( !defined.document || document.readyState === "complete" ) { - config.autorun = true; -} - -QUnit.load = function() { - runLoggingCallbacks( "begin", QUnit, {} ); - - // Initialize the config, saving the execution queue - var banner, filter, i, j, label, len, main, ol, toolbar, val, selection, - urlConfigContainer, moduleFilter, userAgent, - numModules = 0, - moduleNames = [], - moduleFilterHtml = "", - urlConfigHtml = "", - oldconfig = extend( {}, config ); - - QUnit.init(); - extend(config, oldconfig); - - config.blocking = false; - - len = config.urlConfig.length; - - for ( i = 0; i < len; i++ ) { - val = config.urlConfig[i]; - if ( typeof val === "string" ) { - val = { - id: val, - label: val - }; - } - config[ val.id ] = QUnit.urlParams[ val.id ]; - if ( !val.value || typeof val.value === "string" ) { - urlConfigHtml += "<input id='qunit-urlconfig-" + escapeText( val.id ) + - "' name='" + escapeText( val.id ) + - "' type='checkbox'" + - ( val.value ? " value='" + escapeText( val.value ) + "'" : "" ) + - ( config[ val.id ] ? " checked='checked'" : "" ) + - " title='" + escapeText( val.tooltip ) + - "'><label for='qunit-urlconfig-" + escapeText( val.id ) + - "' title='" + escapeText( val.tooltip ) + "'>" + val.label + "</label>"; - } else { - urlConfigHtml += "<label for='qunit-urlconfig-" + escapeText( val.id ) + - "' title='" + escapeText( val.tooltip ) + - "'>" + val.label + - ": </label><select id='qunit-urlconfig-" + escapeText( val.id ) + - "' name='" + escapeText( val.id ) + - "' title='" + escapeText( val.tooltip ) + - "'><option></option>"; - selection = false; - if ( QUnit.is( "array", val.value ) ) { - for ( j = 0; j < val.value.length; j++ ) { - urlConfigHtml += "<option value='" + escapeText( val.value[j] ) + "'" + - ( config[ val.id ] === val.value[j] ? - (selection = true) && " selected='selected'" : - "" ) + - ">" + escapeText( val.value[j] ) + "</option>"; - } - } else { - for ( j in val.value ) { - if ( hasOwn.call( val.value, j ) ) { - urlConfigHtml += "<option value='" + escapeText( j ) + "'" + - ( config[ val.id ] === j ? - (selection = true) && " selected='selected'" : - "" ) + - ">" + escapeText( val.value[j] ) + "</option>"; - } - } - } - if ( config[ val.id ] && !selection ) { - urlConfigHtml += "<option value='" + escapeText( config[ val.id ] ) + - "' selected='selected' disabled='disabled'>" + - escapeText( config[ val.id ] ) + - "</option>"; - } - urlConfigHtml += "</select>"; - } - } - for ( i in config.modules ) { - if ( config.modules.hasOwnProperty( i ) ) { - moduleNames.push(i); - } - } - numModules = moduleNames.length; - moduleNames.sort( function( a, b ) { - return a.localeCompare( b ); - }); - moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " + - ( config.module === undefined ? "selected='selected'" : "" ) + - ">< All Modules ></option>"; - - - for ( i = 0; i < numModules; i++) { - moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(moduleNames[i]) ) + "' " + - ( config.module === moduleNames[i] ? "selected='selected'" : "" ) + - ">" + escapeText(moduleNames[i]) + "</option>"; - } - moduleFilterHtml += "</select>"; - - // `userAgent` initialized at top of scope - userAgent = id( "qunit-userAgent" ); - if ( userAgent ) { - userAgent.innerHTML = navigator.userAgent; - } - - // `banner` initialized at top of scope - banner = id( "qunit-header" ); - if ( banner ) { - banner.innerHTML = "<a href='" + QUnit.url({ filter: undefined, module: undefined, testNumber: undefined }) + "'>" + banner.innerHTML + "</a> "; - } - - // `toolbar` initialized at top of scope - toolbar = id( "qunit-testrunner-toolbar" ); - if ( toolbar ) { - // `filter` initialized at top of scope - filter = document.createElement( "input" ); - filter.type = "checkbox"; - filter.id = "qunit-filter-pass"; - - addEvent( filter, "click", function() { - var tmp, - ol = id( "qunit-tests" ); - - if ( filter.checked ) { - ol.className = ol.className + " hidepass"; - } else { - tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " "; - ol.className = tmp.replace( / hidepass /, " " ); - } - if ( defined.sessionStorage ) { - if (filter.checked) { - sessionStorage.setItem( "qunit-filter-passed-tests", "true" ); - } else { - sessionStorage.removeItem( "qunit-filter-passed-tests" ); - } - } - }); - - if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) { - filter.checked = true; - // `ol` initialized at top of scope - ol = id( "qunit-tests" ); - ol.className = ol.className + " hidepass"; - } - toolbar.appendChild( filter ); - - // `label` initialized at top of scope - label = document.createElement( "label" ); - label.setAttribute( "for", "qunit-filter-pass" ); - label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." ); - label.innerHTML = "Hide passed tests"; - toolbar.appendChild( label ); - - urlConfigContainer = document.createElement("span"); - urlConfigContainer.innerHTML = urlConfigHtml; - // For oldIE support: - // * Add handlers to the individual elements instead of the container - // * Use "click" instead of "change" for checkboxes - // * Fallback from event.target to event.srcElement - addEvents( urlConfigContainer.getElementsByTagName("input"), "click", function( event ) { - var params = {}, - target = event.target || event.srcElement; - params[ target.name ] = target.checked ? - target.defaultValue || true : - undefined; - window.location = QUnit.url( params ); - }); - addEvents( urlConfigContainer.getElementsByTagName("select"), "change", function( event ) { - var params = {}, - target = event.target || event.srcElement; - params[ target.name ] = target.options[ target.selectedIndex ].value || undefined; - window.location = QUnit.url( params ); - }); - toolbar.appendChild( urlConfigContainer ); - - if (numModules > 1) { - moduleFilter = document.createElement( "span" ); - moduleFilter.setAttribute( "id", "qunit-modulefilter-container" ); - moduleFilter.innerHTML = moduleFilterHtml; - addEvent( moduleFilter.lastChild, "change", function() { - var selectBox = moduleFilter.getElementsByTagName("select")[0], - selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value); - - window.location = QUnit.url({ - module: ( selectedModule === "" ) ? undefined : selectedModule, - // Remove any existing filters - filter: undefined, - testNumber: undefined - }); - }); - toolbar.appendChild(moduleFilter); - } - } - - // `main` initialized at top of scope - main = id( "qunit-fixture" ); - if ( main ) { - config.fixture = main.innerHTML; - } - - if ( config.autostart ) { - QUnit.start(); - } -}; - -if ( defined.document ) { - addEvent( window, "load", QUnit.load ); -} - -// `onErrorFnPrev` initialized at top of scope -// Preserve other handlers -onErrorFnPrev = window.onerror; - -// Cover uncaught exceptions -// Returning true will suppress the default browser handler, -// returning false will let it run. -window.onerror = function ( error, filePath, linerNr ) { - var ret = false; - if ( onErrorFnPrev ) { - ret = onErrorFnPrev( error, filePath, linerNr ); - } - - // Treat return value as window.onerror itself does, - // Only do our handling if not suppressed. - if ( ret !== true ) { - if ( QUnit.config.current ) { - if ( QUnit.config.current.ignoreGlobalErrors ) { - return true; - } - QUnit.pushFailure( error, filePath + ":" + linerNr ); - } else { - QUnit.test( "global failure", extend( function() { - QUnit.pushFailure( error, filePath + ":" + linerNr ); - }, { validTest: validTest } ) ); - } - return false; - } - - return ret; -}; - -function done() { - config.autorun = true; - - // Log the last module results - if ( config.previousModule ) { - runLoggingCallbacks( "moduleDone", QUnit, { - name: config.previousModule, - failed: config.moduleStats.bad, - passed: config.moduleStats.all - config.moduleStats.bad, - total: config.moduleStats.all - }); - } - delete config.previousModule; - - var i, key, - banner = id( "qunit-banner" ), - tests = id( "qunit-tests" ), - runtime = +new Date() - config.started, - passed = config.stats.all - config.stats.bad, - html = [ - "Tests completed in ", - runtime, - " milliseconds.<br/>", - "<span class='passed'>", - passed, - "</span> assertions of <span class='total'>", - config.stats.all, - "</span> passed, <span class='failed'>", - config.stats.bad, - "</span> failed." - ].join( "" ); - - if ( banner ) { - banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" ); - } - - if ( tests ) { - id( "qunit-testresult" ).innerHTML = html; - } - - if ( config.altertitle && defined.document && document.title ) { - // show ✖ for good, ✔ for bad suite result in title - // use escape sequences in case file gets loaded with non-utf-8-charset - document.title = [ - ( config.stats.bad ? "\u2716" : "\u2714" ), - document.title.replace( /^[\u2714\u2716] /i, "" ) - ].join( " " ); - } - - // clear own sessionStorage items if all tests passed - if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) { - // `key` & `i` initialized at top of scope - for ( i = 0; i < sessionStorage.length; i++ ) { - key = sessionStorage.key( i++ ); - if ( key.indexOf( "qunit-test-" ) === 0 ) { - sessionStorage.removeItem( key ); - } - } - } - - // scroll back to top to show results - if ( config.scrolltop && window.scrollTo ) { - window.scrollTo(0, 0); - } - - runLoggingCallbacks( "done", QUnit, { - failed: config.stats.bad, - passed: passed, - total: config.stats.all, - runtime: runtime - }); -} - -/** @return Boolean: true if this test should be ran */ -function validTest( test ) { - var include, - filter = config.filter && config.filter.toLowerCase(), - module = config.module && config.module.toLowerCase(), - fullName = ( test.module + ": " + test.testName ).toLowerCase(); - - // Internally-generated tests are always valid - if ( test.callback && test.callback.validTest === validTest ) { - delete test.callback.validTest; - return true; - } - - if ( config.testNumber.length > 0 ) { - if ( inArray( test.testNumber, config.testNumber ) < 0 ) { - return false; - } - } - - if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) { - return false; - } - - if ( !filter ) { - return true; - } - - include = filter.charAt( 0 ) !== "!"; - if ( !include ) { - filter = filter.slice( 1 ); - } - - // If the filter matches, we need to honour include - if ( fullName.indexOf( filter ) !== -1 ) { - return include; - } - - // Otherwise, do the opposite - return !include; -} - -// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions) -// Later Safari and IE10 are supposed to support error.stack as well -// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack -function extractStacktrace( e, offset ) { - offset = offset === undefined ? 3 : offset; - - var stack, include, i; - - if ( e.stacktrace ) { - // Opera - return e.stacktrace.split( "\n" )[ offset + 3 ]; - } else if ( e.stack ) { - // Firefox, Chrome - stack = e.stack.split( "\n" ); - if (/^error$/i.test( stack[0] ) ) { - stack.shift(); - } - if ( fileName ) { - include = []; - for ( i = offset; i < stack.length; i++ ) { - if ( stack[ i ].indexOf( fileName ) !== -1 ) { - break; - } - include.push( stack[ i ] ); - } - if ( include.length ) { - return include.join( "\n" ); - } - } - return stack[ offset ]; - } else if ( e.sourceURL ) { - // Safari, PhantomJS - // hopefully one day Safari provides actual stacktraces - // exclude useless self-reference for generated Error objects - if ( /qunit.js$/.test( e.sourceURL ) ) { - return; - } - // for actual exceptions, this is useful - return e.sourceURL + ":" + e.line; - } -} -function sourceFromStacktrace( offset ) { - try { - throw new Error(); - } catch ( e ) { - return extractStacktrace( e, offset ); - } -} - -/** - * Escape text for attribute or text content. - */ -function escapeText( s ) { - if ( !s ) { - return ""; - } - s = s + ""; - // Both single quotes and double quotes (for attributes) - return s.replace( /['"<>&]/g, function( s ) { - switch( s ) { - case "'": - return "'"; - case "\"": - return """; - case "<": - return "<"; - case ">": - return ">"; - case "&": - return "&"; - } - }); -} - -function synchronize( callback, last ) { - config.queue.push( callback ); - - if ( config.autorun && !config.blocking ) { - process( last ); - } -} - -function process( last ) { - function next() { - process( last ); - } - var start = new Date().getTime(); - config.depth = config.depth ? config.depth + 1 : 1; - - while ( config.queue.length && !config.blocking ) { - if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) { - config.queue.shift()(); - } else { - setTimeout( next, 13 ); - break; - } - } - config.depth--; - if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) { - done(); - } -} - -function saveGlobal() { - config.pollution = []; - - if ( config.noglobals ) { - for ( var key in window ) { - if ( hasOwn.call( window, key ) ) { - // in Opera sometimes DOM element ids show up here, ignore them - if ( /^qunit-test-output/.test( key ) ) { - continue; - } - config.pollution.push( key ); - } - } - } -} - -function checkPollution() { - var newGlobals, - deletedGlobals, - old = config.pollution; - - saveGlobal(); - - newGlobals = diff( config.pollution, old ); - if ( newGlobals.length > 0 ) { - QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") ); - } - - deletedGlobals = diff( old, config.pollution ); - if ( deletedGlobals.length > 0 ) { - QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") ); - } -} - -// returns a new Array with the elements that are in a but not in b -function diff( a, b ) { - var i, j, - result = a.slice(); - - for ( i = 0; i < result.length; i++ ) { - for ( j = 0; j < b.length; j++ ) { - if ( result[i] === b[j] ) { - result.splice( i, 1 ); - i--; - break; - } - } - } - return result; -} - -function extend( a, b ) { - for ( var prop in b ) { - if ( hasOwn.call( b, prop ) ) { - // Avoid "Member not found" error in IE8 caused by messing with window.constructor - if ( !( prop === "constructor" && a === window ) ) { - if ( b[ prop ] === undefined ) { - delete a[ prop ]; - } else { - a[ prop ] = b[ prop ]; - } - } - } - } - - return a; -} - -/** - * @param {HTMLElement} elem - * @param {string} type - * @param {Function} fn - */ -function addEvent( elem, type, fn ) { - if ( elem.addEventListener ) { - - // Standards-based browsers - elem.addEventListener( type, fn, false ); - } else if ( elem.attachEvent ) { - - // support: IE <9 - elem.attachEvent( "on" + type, fn ); - } else { - - // Caller must ensure support for event listeners is present - throw new Error( "addEvent() was called in a context without event listener support" ); - } -} - -/** - * @param {Array|NodeList} elems - * @param {string} type - * @param {Function} fn - */ -function addEvents( elems, type, fn ) { - var i = elems.length; - while ( i-- ) { - addEvent( elems[i], type, fn ); - } -} - -function hasClass( elem, name ) { - return (" " + elem.className + " ").indexOf(" " + name + " ") > -1; -} - -function addClass( elem, name ) { - if ( !hasClass( elem, name ) ) { - elem.className += (elem.className ? " " : "") + name; - } -} - -function removeClass( elem, name ) { - var set = " " + elem.className + " "; - // Class name may appear multiple times - while ( set.indexOf(" " + name + " ") > -1 ) { - set = set.replace(" " + name + " " , " "); - } - // If possible, trim it for prettiness, but not necessarily - elem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\s+|\s+$/g, ""); -} - -function id( name ) { - return defined.document && document.getElementById && document.getElementById( name ); -} - -function registerLoggingCallback( key ) { - return function( callback ) { - config[key].push( callback ); - }; -} - -// Supports deprecated method of completely overwriting logging callbacks -function runLoggingCallbacks( key, scope, args ) { - var i, callbacks; - if ( QUnit.hasOwnProperty( key ) ) { - QUnit[ key ].call(scope, args ); - } else { - callbacks = config[ key ]; - for ( i = 0; i < callbacks.length; i++ ) { - callbacks[ i ].call( scope, args ); - } - } -} - -// from jquery.js -function inArray( elem, array ) { - if ( array.indexOf ) { - return array.indexOf( elem ); - } - - for ( var i = 0, length = array.length; i < length; i++ ) { - if ( array[ i ] === elem ) { - return i; - } - } - - return -1; -} - -function Test( settings ) { - extend( this, settings ); - this.assertions = []; - this.testNumber = ++Test.count; -} - -Test.count = 0; - -Test.prototype = { - init: function() { - var a, b, li, - tests = id( "qunit-tests" ); - - if ( tests ) { - b = document.createElement( "strong" ); - b.innerHTML = this.nameHtml; - - // `a` initialized at top of scope - a = document.createElement( "a" ); - a.innerHTML = "Rerun"; - a.href = QUnit.url({ testNumber: this.testNumber }); - - li = document.createElement( "li" ); - li.appendChild( b ); - li.appendChild( a ); - li.className = "running"; - li.id = this.id = "qunit-test-output" + testId++; - - tests.appendChild( li ); - } - }, - setup: function() { - if ( - // Emit moduleStart when we're switching from one module to another - this.module !== config.previousModule || - // They could be equal (both undefined) but if the previousModule property doesn't - // yet exist it means this is the first test in a suite that isn't wrapped in a - // module, in which case we'll just emit a moduleStart event for 'undefined'. - // Without this, reporters can get testStart before moduleStart which is a problem. - !hasOwn.call( config, "previousModule" ) - ) { - if ( hasOwn.call( config, "previousModule" ) ) { - runLoggingCallbacks( "moduleDone", QUnit, { - name: config.previousModule, - failed: config.moduleStats.bad, - passed: config.moduleStats.all - config.moduleStats.bad, - total: config.moduleStats.all - }); - } - config.previousModule = this.module; - config.moduleStats = { all: 0, bad: 0 }; - runLoggingCallbacks( "moduleStart", QUnit, { - name: this.module - }); - } - - config.current = this; - - this.testEnvironment = extend({ - setup: function() {}, - teardown: function() {} - }, this.moduleTestEnvironment ); - - this.started = +new Date(); - runLoggingCallbacks( "testStart", QUnit, { - name: this.testName, - module: this.module - }); - - /*jshint camelcase:false */ - - - /** - * Expose the current test environment. - * - * @deprecated since 1.12.0: Use QUnit.config.current.testEnvironment instead. - */ - QUnit.current_testEnvironment = this.testEnvironment; - - /*jshint camelcase:true */ - - if ( !config.pollution ) { - saveGlobal(); - } - if ( config.notrycatch ) { - this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert ); - return; - } - try { - this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert ); - } catch( e ) { - QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); - } - }, - run: function() { - config.current = this; - - var running = id( "qunit-testresult" ); - - if ( running ) { - running.innerHTML = "Running: <br/>" + this.nameHtml; - } - - if ( this.async ) { - QUnit.stop(); - } - - this.callbackStarted = +new Date(); - - if ( config.notrycatch ) { - this.callback.call( this.testEnvironment, QUnit.assert ); - this.callbackRuntime = +new Date() - this.callbackStarted; - return; - } - - try { - this.callback.call( this.testEnvironment, QUnit.assert ); - this.callbackRuntime = +new Date() - this.callbackStarted; - } catch( e ) { - this.callbackRuntime = +new Date() - this.callbackStarted; - - QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) ); - // else next test will carry the responsibility - saveGlobal(); - - // Restart the tests if they're blocking - if ( config.blocking ) { - QUnit.start(); - } - } - }, - teardown: function() { - config.current = this; - if ( config.notrycatch ) { - if ( typeof this.callbackRuntime === "undefined" ) { - this.callbackRuntime = +new Date() - this.callbackStarted; - } - this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert ); - return; - } else { - try { - this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert ); - } catch( e ) { - QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); - } - } - checkPollution(); - }, - finish: function() { - config.current = this; - if ( config.requireExpects && this.expected === null ) { - QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack ); - } else if ( this.expected !== null && this.expected !== this.assertions.length ) { - QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack ); - } else if ( this.expected === null && !this.assertions.length ) { - QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack ); - } - - var i, assertion, a, b, time, li, ol, - test = this, - good = 0, - bad = 0, - tests = id( "qunit-tests" ); - - this.runtime = +new Date() - this.started; - config.stats.all += this.assertions.length; - config.moduleStats.all += this.assertions.length; - - if ( tests ) { - ol = document.createElement( "ol" ); - ol.className = "qunit-assert-list"; - - for ( i = 0; i < this.assertions.length; i++ ) { - assertion = this.assertions[i]; - - li = document.createElement( "li" ); - li.className = assertion.result ? "pass" : "fail"; - li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" ); - ol.appendChild( li ); - - if ( assertion.result ) { - good++; - } else { - bad++; - config.stats.bad++; - config.moduleStats.bad++; - } - } - - // store result when possible - if ( QUnit.config.reorder && defined.sessionStorage ) { - if ( bad ) { - sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad ); - } else { - sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName ); - } - } - - if ( bad === 0 ) { - addClass( ol, "qunit-collapsed" ); - } - - // `b` initialized at top of scope - b = document.createElement( "strong" ); - b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>"; - - addEvent(b, "click", function() { - var next = b.parentNode.lastChild, - collapsed = hasClass( next, "qunit-collapsed" ); - ( collapsed ? removeClass : addClass )( next, "qunit-collapsed" ); - }); - - addEvent(b, "dblclick", function( e ) { - var target = e && e.target ? e.target : window.event.srcElement; - if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) { - target = target.parentNode; - } - if ( window.location && target.nodeName.toLowerCase() === "strong" ) { - window.location = QUnit.url({ testNumber: test.testNumber }); - } - }); - - // `time` initialized at top of scope - time = document.createElement( "span" ); - time.className = "runtime"; - time.innerHTML = this.runtime + " ms"; - - // `li` initialized at top of scope - li = id( this.id ); - li.className = bad ? "fail" : "pass"; - li.removeChild( li.firstChild ); - a = li.firstChild; - li.appendChild( b ); - li.appendChild( a ); - li.appendChild( time ); - li.appendChild( ol ); - - } else { - for ( i = 0; i < this.assertions.length; i++ ) { - if ( !this.assertions[i].result ) { - bad++; - config.stats.bad++; - config.moduleStats.bad++; - } - } - } - - runLoggingCallbacks( "testDone", QUnit, { - name: this.testName, - module: this.module, - failed: bad, - passed: this.assertions.length - bad, - total: this.assertions.length, - runtime: this.runtime, - // DEPRECATED: this property will be removed in 2.0.0, use runtime instead - duration: this.runtime - }); - - QUnit.reset(); - - config.current = undefined; - }, - - queue: function() { - var bad, - test = this; - - synchronize(function() { - test.init(); - }); - function run() { - // each of these can by async - synchronize(function() { - test.setup(); - }); - synchronize(function() { - test.run(); - }); - synchronize(function() { - test.teardown(); - }); - synchronize(function() { - test.finish(); - }); - } - - // `bad` initialized at top of scope - // defer when previous test run passed, if storage is available - bad = QUnit.config.reorder && defined.sessionStorage && - +sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName ); - - if ( bad ) { - run(); - } else { - synchronize( run, true ); - } - } -}; - -// `assert` initialized at top of scope -// Assert helpers -// All of these must either call QUnit.push() or manually do: -// - runLoggingCallbacks( "log", .. ); -// - config.current.assertions.push({ .. }); -assert = QUnit.assert = { - /** - * Asserts rough true-ish result. - * @name ok - * @function - * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); - */ - ok: function( result, msg ) { - if ( !config.current ) { - throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) ); - } - result = !!result; - msg = msg || ( result ? "okay" : "failed" ); - - var source, - details = { - module: config.current.module, - name: config.current.testName, - result: result, - message: msg - }; - - msg = "<span class='test-message'>" + escapeText( msg ) + "</span>"; - - if ( !result ) { - source = sourceFromStacktrace( 2 ); - if ( source ) { - details.source = source; - msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + - escapeText( source ) + - "</pre></td></tr></table>"; - } - } - runLoggingCallbacks( "log", QUnit, details ); - config.current.assertions.push({ - result: result, - message: msg - }); - }, - - /** - * Assert that the first two arguments are equal, with an optional message. - * Prints out both actual and expected values. - * @name equal - * @function - * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" ); - */ - equal: function( actual, expected, message ) { - /*jshint eqeqeq:false */ - QUnit.push( expected == actual, actual, expected, message ); - }, - - /** - * @name notEqual - * @function - */ - notEqual: function( actual, expected, message ) { - /*jshint eqeqeq:false */ - QUnit.push( expected != actual, actual, expected, message ); - }, - - /** - * @name propEqual - * @function - */ - propEqual: function( actual, expected, message ) { - actual = objectValues(actual); - expected = objectValues(expected); - QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name notPropEqual - * @function - */ - notPropEqual: function( actual, expected, message ) { - actual = objectValues(actual); - expected = objectValues(expected); - QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name deepEqual - * @function - */ - deepEqual: function( actual, expected, message ) { - QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name notDeepEqual - * @function - */ - notDeepEqual: function( actual, expected, message ) { - QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name strictEqual - * @function - */ - strictEqual: function( actual, expected, message ) { - QUnit.push( expected === actual, actual, expected, message ); - }, - - /** - * @name notStrictEqual - * @function - */ - notStrictEqual: function( actual, expected, message ) { - QUnit.push( expected !== actual, actual, expected, message ); - }, - - "throws": function( block, expected, message ) { - var actual, - expectedOutput = expected, - ok = false; - - // 'expected' is optional - if ( !message && typeof expected === "string" ) { - message = expected; - expected = null; - } - - config.current.ignoreGlobalErrors = true; - try { - block.call( config.current.testEnvironment ); - } catch (e) { - actual = e; - } - config.current.ignoreGlobalErrors = false; - - if ( actual ) { - - // we don't want to validate thrown error - if ( !expected ) { - ok = true; - expectedOutput = null; - - // expected is an Error object - } else if ( expected instanceof Error ) { - ok = actual instanceof Error && - actual.name === expected.name && - actual.message === expected.message; - - // expected is a regexp - } else if ( QUnit.objectType( expected ) === "regexp" ) { - ok = expected.test( errorString( actual ) ); - - // expected is a string - } else if ( QUnit.objectType( expected ) === "string" ) { - ok = expected === errorString( actual ); - - // expected is a constructor - } else if ( actual instanceof expected ) { - ok = true; - - // expected is a validation function which returns true is validation passed - } else if ( expected.call( {}, actual ) === true ) { - expectedOutput = null; - ok = true; - } - - QUnit.push( ok, actual, expectedOutput, message ); - } else { - QUnit.pushFailure( message, null, "No exception was thrown." ); - } - } -}; - -/** - * @deprecated since 1.8.0 - * Kept assertion helpers in root for backwards compatibility. - */ -extend( QUnit.constructor.prototype, assert ); - -/** - * @deprecated since 1.9.0 - * Kept to avoid TypeErrors for undefined methods. - */ -QUnit.constructor.prototype.raises = function() { - QUnit.push( false, false, false, "QUnit.raises has been deprecated since 2012 (fad3c1ea), use QUnit.throws instead" ); -}; - -/** - * @deprecated since 1.0.0, replaced with error pushes since 1.3.0 - * Kept to avoid TypeErrors for undefined methods. - */ -QUnit.constructor.prototype.equals = function() { - QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" ); -}; -QUnit.constructor.prototype.same = function() { - QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" ); -}; - -// Test for equality any JavaScript type. -// Author: Philippe Rathé <prathe@gmail.com> -QUnit.equiv = (function() { - - // Call the o related callback with the given arguments. - function bindCallbacks( o, callbacks, args ) { - var prop = QUnit.objectType( o ); - if ( prop ) { - if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) { - return callbacks[ prop ].apply( callbacks, args ); - } else { - return callbacks[ prop ]; // or undefined - } - } - } - - // the real equiv function - var innerEquiv, - // stack to decide between skip/abort functions - callers = [], - // stack to avoiding loops from circular referencing - parents = [], - parentsB = [], - - getProto = Object.getPrototypeOf || function ( obj ) { - /*jshint camelcase:false */ - return obj.__proto__; - }, - callbacks = (function () { - - // for string, boolean, number and null - function useStrictEquality( b, a ) { - /*jshint eqeqeq:false */ - if ( b instanceof a.constructor || a instanceof b.constructor ) { - // to catch short annotation VS 'new' annotation of a - // declaration - // e.g. var i = 1; - // var j = new Number(1); - return a == b; - } else { - return a === b; - } - } - - return { - "string": useStrictEquality, - "boolean": useStrictEquality, - "number": useStrictEquality, - "null": useStrictEquality, - "undefined": useStrictEquality, - - "nan": function( b ) { - return isNaN( b ); - }, - - "date": function( b, a ) { - return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf(); - }, - - "regexp": function( b, a ) { - return QUnit.objectType( b ) === "regexp" && - // the regex itself - a.source === b.source && - // and its modifiers - a.global === b.global && - // (gmi) ... - a.ignoreCase === b.ignoreCase && - a.multiline === b.multiline && - a.sticky === b.sticky; - }, - - // - skip when the property is a method of an instance (OOP) - // - abort otherwise, - // initial === would have catch identical references anyway - "function": function() { - var caller = callers[callers.length - 1]; - return caller !== Object && typeof caller !== "undefined"; - }, - - "array": function( b, a ) { - var i, j, len, loop, aCircular, bCircular; - - // b could be an object literal here - if ( QUnit.objectType( b ) !== "array" ) { - return false; - } - - len = a.length; - if ( len !== b.length ) { - // safe and faster - return false; - } - - // track reference to avoid circular references - parents.push( a ); - parentsB.push( b ); - for ( i = 0; i < len; i++ ) { - loop = false; - for ( j = 0; j < parents.length; j++ ) { - aCircular = parents[j] === a[i]; - bCircular = parentsB[j] === b[i]; - if ( aCircular || bCircular ) { - if ( a[i] === b[i] || aCircular && bCircular ) { - loop = true; - } else { - parents.pop(); - parentsB.pop(); - return false; - } - } - } - if ( !loop && !innerEquiv(a[i], b[i]) ) { - parents.pop(); - parentsB.pop(); - return false; - } - } - parents.pop(); - parentsB.pop(); - return true; - }, - - "object": function( b, a ) { - /*jshint forin:false */ - var i, j, loop, aCircular, bCircular, - // Default to true - eq = true, - aProperties = [], - bProperties = []; - - // comparing constructors is more strict than using - // instanceof - if ( a.constructor !== b.constructor ) { - // Allow objects with no prototype to be equivalent to - // objects with Object as their constructor. - if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) || - ( getProto(b) === null && getProto(a) === Object.prototype ) ) ) { - return false; - } - } - - // stack constructor before traversing properties - callers.push( a.constructor ); - - // track reference to avoid circular references - parents.push( a ); - parentsB.push( b ); - - // be strict: don't ensure hasOwnProperty and go deep - for ( i in a ) { - loop = false; - for ( j = 0; j < parents.length; j++ ) { - aCircular = parents[j] === a[i]; - bCircular = parentsB[j] === b[i]; - if ( aCircular || bCircular ) { - if ( a[i] === b[i] || aCircular && bCircular ) { - loop = true; - } else { - eq = false; - break; - } - } - } - aProperties.push(i); - if ( !loop && !innerEquiv(a[i], b[i]) ) { - eq = false; - break; - } - } - - parents.pop(); - parentsB.pop(); - callers.pop(); // unstack, we are done - - for ( i in b ) { - bProperties.push( i ); // collect b's properties - } - - // Ensures identical properties name - return eq && innerEquiv( aProperties.sort(), bProperties.sort() ); - } - }; - }()); - - innerEquiv = function() { // can take multiple arguments - var args = [].slice.apply( arguments ); - if ( args.length < 2 ) { - return true; // end transition - } - - return (function( a, b ) { - if ( a === b ) { - return true; // catch the most you can - } else if ( a === null || b === null || typeof a === "undefined" || - typeof b === "undefined" || - QUnit.objectType(a) !== QUnit.objectType(b) ) { - return false; // don't lose time with error prone cases - } else { - return bindCallbacks(a, callbacks, [ b, a ]); - } - - // apply transition with (1..n) arguments - }( args[0], args[1] ) && innerEquiv.apply( this, args.splice(1, args.length - 1 )) ); - }; - - return innerEquiv; -}()); - -/** - * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | - * http://flesler.blogspot.com Licensed under BSD - * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008 - * - * @projectDescription Advanced and extensible data dumping for Javascript. - * @version 1.0.0 - * @author Ariel Flesler - * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html} - */ -QUnit.jsDump = (function() { - function quote( str ) { - return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\""; - } - function literal( o ) { - return o + ""; - } - function join( pre, arr, post ) { - var s = jsDump.separator(), - base = jsDump.indent(), - inner = jsDump.indent(1); - if ( arr.join ) { - arr = arr.join( "," + s + inner ); - } - if ( !arr ) { - return pre + post; - } - return [ pre, inner + arr, base + post ].join(s); - } - function array( arr, stack ) { - var i = arr.length, ret = new Array(i); - this.up(); - while ( i-- ) { - ret[i] = this.parse( arr[i] , undefined , stack); - } - this.down(); - return join( "[", ret, "]" ); - } - - var reName = /^function (\w+)/, - jsDump = { - // type is used mostly internally, you can fix a (custom)type in advance - parse: function( obj, type, stack ) { - stack = stack || [ ]; - var inStack, res, - parser = this.parsers[ type || this.typeOf(obj) ]; - - type = typeof parser; - inStack = inArray( obj, stack ); - - if ( inStack !== -1 ) { - return "recursion(" + (inStack - stack.length) + ")"; - } - if ( type === "function" ) { - stack.push( obj ); - res = parser.call( this, obj, stack ); - stack.pop(); - return res; - } - return ( type === "string" ) ? parser : this.parsers.error; - }, - typeOf: function( obj ) { - var type; - if ( obj === null ) { - type = "null"; - } else if ( typeof obj === "undefined" ) { - type = "undefined"; - } else if ( QUnit.is( "regexp", obj) ) { - type = "regexp"; - } else if ( QUnit.is( "date", obj) ) { - type = "date"; - } else if ( QUnit.is( "function", obj) ) { - type = "function"; - } else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) { - type = "window"; - } else if ( obj.nodeType === 9 ) { - type = "document"; - } else if ( obj.nodeType ) { - type = "node"; - } else if ( - // native arrays - toString.call( obj ) === "[object Array]" || - // NodeList objects - ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) ) - ) { - type = "array"; - } else if ( obj.constructor === Error.prototype.constructor ) { - type = "error"; - } else { - type = typeof obj; - } - return type; - }, - separator: function() { - return this.multiline ? this.HTML ? "<br />" : "\n" : this.HTML ? " " : " "; - }, - // extra can be a number, shortcut for increasing-calling-decreasing - indent: function( extra ) { - if ( !this.multiline ) { - return ""; - } - var chr = this.indentChar; - if ( this.HTML ) { - chr = chr.replace( /\t/g, " " ).replace( / /g, " " ); - } - return new Array( this.depth + ( extra || 0 ) ).join(chr); - }, - up: function( a ) { - this.depth += a || 1; - }, - down: function( a ) { - this.depth -= a || 1; - }, - setParser: function( name, parser ) { - this.parsers[name] = parser; - }, - // The next 3 are exposed so you can use them - quote: quote, - literal: literal, - join: join, - // - depth: 1, - // This is the list of parsers, to modify them, use jsDump.setParser - parsers: { - window: "[Window]", - document: "[Document]", - error: function(error) { - return "Error(\"" + error.message + "\")"; - }, - unknown: "[Unknown]", - "null": "null", - "undefined": "undefined", - "function": function( fn ) { - var ret = "function", - // functions never have name in IE - name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1]; - - if ( name ) { - ret += " " + name; - } - ret += "( "; - - ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" ); - return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" ); - }, - array: array, - nodelist: array, - "arguments": array, - object: function( map, stack ) { - /*jshint forin:false */ - var ret = [ ], keys, key, val, i; - QUnit.jsDump.up(); - keys = []; - for ( key in map ) { - keys.push( key ); - } - keys.sort(); - for ( i = 0; i < keys.length; i++ ) { - key = keys[ i ]; - val = map[ key ]; - ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) ); - } - QUnit.jsDump.down(); - return join( "{", ret, "}" ); - }, - node: function( node ) { - var len, i, val, - open = QUnit.jsDump.HTML ? "<" : "<", - close = QUnit.jsDump.HTML ? ">" : ">", - tag = node.nodeName.toLowerCase(), - ret = open + tag, - attrs = node.attributes; - - if ( attrs ) { - for ( i = 0, len = attrs.length; i < len; i++ ) { - val = attrs[i].nodeValue; - // IE6 includes all attributes in .attributes, even ones not explicitly set. - // Those have values like undefined, null, 0, false, "" or "inherit". - if ( val && val !== "inherit" ) { - ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" ); - } - } - } - ret += close; - - // Show content of TextNode or CDATASection - if ( node.nodeType === 3 || node.nodeType === 4 ) { - ret += node.nodeValue; - } - - return ret + open + "/" + tag + close; - }, - // function calls it internally, it's the arguments part of the function - functionArgs: function( fn ) { - var args, - l = fn.length; - - if ( !l ) { - return ""; - } - - args = new Array(l); - while ( l-- ) { - // 97 is 'a' - args[l] = String.fromCharCode(97+l); - } - return " " + args.join( ", " ) + " "; - }, - // object calls it internally, the key part of an item in a map - key: quote, - // function calls it internally, it's the content of the function - functionCode: "[code]", - // node calls it internally, it's an html attribute value - attribute: quote, - string: quote, - date: quote, - regexp: literal, - number: literal, - "boolean": literal - }, - // if true, entities are escaped ( <, >, \t, space and \n ) - HTML: false, - // indentation unit - indentChar: " ", - // if true, items in a collection, are separated by a \n, else just a space. - multiline: true - }; - - return jsDump; -}()); - -/* - * Javascript Diff Algorithm - * By John Resig (http://ejohn.org/) - * Modified by Chu Alan "sprite" - * - * Released under the MIT license. - * - * More Info: - * http://ejohn.org/projects/javascript-diff-algorithm/ - * - * Usage: QUnit.diff(expected, actual) - * - * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over" - */ -QUnit.diff = (function() { - /*jshint eqeqeq:false, eqnull:true */ - function diff( o, n ) { - var i, - ns = {}, - os = {}; - - for ( i = 0; i < n.length; i++ ) { - if ( !hasOwn.call( ns, n[i] ) ) { - ns[ n[i] ] = { - rows: [], - o: null - }; - } - ns[ n[i] ].rows.push( i ); - } - - for ( i = 0; i < o.length; i++ ) { - if ( !hasOwn.call( os, o[i] ) ) { - os[ o[i] ] = { - rows: [], - n: null - }; - } - os[ o[i] ].rows.push( i ); - } - - for ( i in ns ) { - if ( hasOwn.call( ns, i ) ) { - if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) { - n[ ns[i].rows[0] ] = { - text: n[ ns[i].rows[0] ], - row: os[i].rows[0] - }; - o[ os[i].rows[0] ] = { - text: o[ os[i].rows[0] ], - row: ns[i].rows[0] - }; - } - } - } - - for ( i = 0; i < n.length - 1; i++ ) { - if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null && - n[ i + 1 ] == o[ n[i].row + 1 ] ) { - - n[ i + 1 ] = { - text: n[ i + 1 ], - row: n[i].row + 1 - }; - o[ n[i].row + 1 ] = { - text: o[ n[i].row + 1 ], - row: i + 1 - }; - } - } - - for ( i = n.length - 1; i > 0; i-- ) { - if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null && - n[ i - 1 ] == o[ n[i].row - 1 ]) { - - n[ i - 1 ] = { - text: n[ i - 1 ], - row: n[i].row - 1 - }; - o[ n[i].row - 1 ] = { - text: o[ n[i].row - 1 ], - row: i - 1 - }; - } - } - - return { - o: o, - n: n - }; - } - - return function( o, n ) { - o = o.replace( /\s+$/, "" ); - n = n.replace( /\s+$/, "" ); - - var i, pre, - str = "", - out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ), - oSpace = o.match(/\s+/g), - nSpace = n.match(/\s+/g); - - if ( oSpace == null ) { - oSpace = [ " " ]; - } - else { - oSpace.push( " " ); - } - - if ( nSpace == null ) { - nSpace = [ " " ]; - } - else { - nSpace.push( " " ); - } - - if ( out.n.length === 0 ) { - for ( i = 0; i < out.o.length; i++ ) { - str += "<del>" + out.o[i] + oSpace[i] + "</del>"; - } - } - else { - if ( out.n[0].text == null ) { - for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) { - str += "<del>" + out.o[n] + oSpace[n] + "</del>"; - } - } - - for ( i = 0; i < out.n.length; i++ ) { - if (out.n[i].text == null) { - str += "<ins>" + out.n[i] + nSpace[i] + "</ins>"; - } - else { - // `pre` initialized at top of scope - pre = ""; - - for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) { - pre += "<del>" + out.o[n] + oSpace[n] + "</del>"; - } - str += " " + out.n[i].text + nSpace[i] + pre; - } - } - } - - return str; - }; -}()); - -// For browser, export only select globals -if ( typeof window !== "undefined" ) { - extend( window, QUnit.constructor.prototype ); - window.QUnit = QUnit; -} - -// For CommonJS environments, export everything -if ( typeof module !== "undefined" && module.exports ) { - module.exports = QUnit; -} - - -// Get a reference to the global object, like window in browsers -}( (function() { - return this; -})() )); diff --git a/dev/tests/js/JsTestDriver/framework/requirejs-util.js b/dev/tests/js/JsTestDriver/framework/requirejs-util.js deleted file mode 100644 index b9d6b833d36af..0000000000000 --- a/dev/tests/js/JsTestDriver/framework/requirejs-util.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -(function ($, window) { - "use strict"; - - // List of define() calls with arguments and call stack - var defineCalls = []; - - // Get current call stack, including script path information - var getFileStack = function() { - try { - throw new Error(); - } catch (e) { - if (!e.stack) { - throw new Error('The browser needs to support Error.stack property'); - } - return e.stack; - } - }; - - // Intercept RequireJS define() calls, which are performed by AMD scripts upon loading - window.define = function () { - var stack = getFileStack(); - defineCalls.push({ - stack: stack, - args: arguments - }); - }; - - window.require = function(dependencies, callback){ - return callback && callback(); - }; - - // Exposed interface - var requirejsUtil = { - getDefineArgsInScript: function (scriptPath) { - var result; - for (var i = 0; i < defineCalls.length; i++) { - if (defineCalls[i].stack.indexOf(scriptPath) >= 0) { - result = defineCalls[i].args; - break; - } - } - return result; - } - }; - - window.jsunit = window.jsunit || {}; - $.extend(window.jsunit, {requirejsUtil: requirejsUtil}); -})(jQuery, window); diff --git a/dev/tests/js/JsTestDriver/framework/stub.js b/dev/tests/js/JsTestDriver/framework/stub.js deleted file mode 100644 index c966ab578cac8..0000000000000 --- a/dev/tests/js/JsTestDriver/framework/stub.js +++ /dev/null @@ -1,132 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -(function ($, window) { - "use strict"; - - function wrapMethod(object, property, method, copyProperties) { - if (!object) { - throw new TypeError("Should wrap property of object"); - } - - if (typeof method != "function") { - throw new TypeError("Method wrapper should be function"); - } - - var wrappedMethod = object[property], - error; - - if ($.type(wrappedMethod) !== 'function') { - error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " + - property + " as function"); - } - - if (wrappedMethod.restore) { - error = new TypeError("Attempted to wrap " + property + " which is already wrapped"); - } - - if (error) { - if (wrappedMethod._stack) { - error.stack += '\n--------------\n' + wrappedMethod._stack; - } - throw error; - } - - // IE 8 does not support hasOwnProperty. - var owned = object.hasOwnProperty ? - object.hasOwnProperty(property) : - Object.prototype.hasOwnProperty.call(object, property); - - object[property] = method; - method.displayName = property; - // Stack trace which can be used to find what line of code the original method was created on. - method._stack = (new Error('Stack Trace for original')).stack; - - method.restore = function () { - if (!owned) { - delete object[property]; - } - if (object[property] === method) { - object[property] = wrappedMethod; - } - }; - - if (copyProperties) { - for (var prop in wrappedMethod) { - if (!Object.prototype.hasOwnProperty.call(method, prop)) { - method[prop] = wrappedMethod[prop]; - } - } - } - - return method; - } - - function stub(object, property, func, copyProperties) { - if (!!func && typeof func != "function") { - throw new TypeError("Custom stub should be function"); - } - - var wrapper; - - if (func) { - wrapper = func; - } else { - wrapper = stub.create(); - } - - if (!object && typeof property === "undefined") { - return stub.create(); - } - - if (typeof property === "undefined" && typeof object == "object") { - for (var prop in object) { - if (typeof object[prop] === "function") { - stub(object, prop); - } - } - - return object; - } - - return wrapMethod(object, property, wrapper, copyProperties); - } - - $.extend(stub, (function () { - var proto = { - create: function create() { - var functionStub = function () { - functionStub.callCount = functionStub.callCount ? functionStub.callCount + 1 : 1; - functionStub.lastCallArgs = arguments; - functionStub.callArgsStack.push(arguments); - if (functionStub.returnCallback && $.type(functionStub.returnCallback) === 'function') { - return functionStub.returnCallback.apply(functionStub.returnCallback, arguments); - } else if (functionStub.returnValue) { - return functionStub.returnValue; - } - }; - $.extend(functionStub, stub); - functionStub.reset(); - functionStub.displayName = "stub"; - return functionStub; - }, - - reset: function() { - this.callCount = null; - this.lastCallArgs = []; - this.callArgsStack = []; - this.returnValue = null; - this.returnCallback = null; - } - }; - - return proto; - }())); - - window.jsunit = window.jsunit || {}; - $.extend(window.jsunit, { - stub: stub - }); -})(jQuery, window); diff --git a/dev/tests/js/JsTestDriver/jsTestDriver.php.dist b/dev/tests/js/JsTestDriver/jsTestDriver.php.dist deleted file mode 100644 index 089e5220f2d8f..0000000000000 --- a/dev/tests/js/JsTestDriver/jsTestDriver.php.dist +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * Returns an array containing the configuration used to generate the JsTestDriver configuration - * file that gets used by JsTestDriver when it executes the Javascript unit tests. - * - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - * - * @return array - */ -return array( - 'server' => 'http://localhost:9876', - 'load' => array( - '/dev/tests/js/JsTestDriver/framework', - '/lib/web/mage/webapi.js', - '/lib/web/mage/validation/validation.js', - '/lib/web/jquery/jstree/jquery.jstree.js', - '/lib/web/jquery/jquery-ui-timepicker-addon.js', - '/lib/web/mage/cookies.js', - '/lib/web/mage/calendar.js', - '/lib/web/mage/loader_old.js', - '/lib/web/mage/edit-trigger.js', - '/lib/web/mage/translate-inline.js', - '/lib/web/mage/translate-inline-vde.js', - '/lib/web/mage/backend/form.js', - '/lib/web/mage/backend/button.js', - '/lib/web/mage/backend/tabs.js', - '/lib/web/mage/backend/menu.js', - '/lib/web/mage/backend/suggest.js', - '/lib/web/mage/backend/tree-suggest.js', - '/lib/web/mage/zoom.js', - ), - 'test' => array('/dev/tests/js/JsTestDriver/testsuite'), - 'JsTestDriver' => '{{path_to_jstestdriver_jar}}' -); diff --git a/dev/tests/js/JsTestDriver/jsTestDriverOrder.php b/dev/tests/js/JsTestDriver/jsTestDriverOrder.php deleted file mode 100644 index 8ee790a281655..0000000000000 --- a/dev/tests/js/JsTestDriver/jsTestDriverOrder.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php -/** - * Returns an array of Javascript files that should be loaded first by JsTestDriver in the - * order that they appear in the array when the Javascript unit tests are run. - * - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - * - * @return array - */ -return [ - '/lib/web/jquery.js', - '/lib/web/jquery/jquery-migrate.js', - '/lib/web/underscore.js', - '/lib/web/mage/template.js', - '/lib/web/jquery/jquery-ui-1.9.2.js', - '/dev/tests/js/JsTestDriver/framework/requirejs-util.js', - '/lib/web/jquery/jquery.cookie.js', - '/lib/web/mage/apply/main.js', - '/lib/web/mage/mage.js', - '/lib/web/mage/decorate.js', - '/lib/web/jquery/jquery.validate.js', - '/lib/web/jquery/jquery.metadata.js', - '/lib/web/mage/translate.js' -]; diff --git a/dev/tests/js/JsTestDriver/run_js_tests.php b/dev/tests/js/JsTestDriver/run_js_tests.php deleted file mode 100644 index 77ce98a6b3b03..0000000000000 --- a/dev/tests/js/JsTestDriver/run_js_tests.php +++ /dev/null @@ -1,245 +0,0 @@ -<?php -/** - * This script executes all Magento JavaScript unit tests. - * - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -define('RELATIVE_APP_ROOT', '../../../..'); -require __DIR__ . '/../../../../app/autoload.php'; - -$userConfig = normalize('jsTestDriver.php'); -$defaultConfig = normalize('jsTestDriver.php.dist'); - -$configFile = file_exists($userConfig) ? $userConfig : $defaultConfig; -$config = require $configFile; - -if (isset($config['JsTestDriver'])) { - $jsTestDriver = $config['JsTestDriver']; -} else { - echo "Value for the 'JsTestDriver' configuration parameter is not specified." . PHP_EOL; - showUsage(); -} -if (!file_exists($jsTestDriver)) { - reportError('JsTestDriver jar file does not exist: ' . $jsTestDriver); -} - -if (isset($config['Browser'])) { - $browser = $config['Browser']; -} else { - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { - $browser = 'C:\Program Files (x86)\Mozilla Firefox\firefox.exe'; - } elseif (PHP_OS === 'Darwin') { - $browser = '/Applications/Firefox.app/Contents/MacOS/firefox'; - } else { - $browser = exec('which firefox'); - } -} -if (!file_exists($browser)) { - reportError('Browser executable not found: ' . $browser); -} - -$server = isset($config['server']) ? $config['server'] : "http://localhost:9876"; -$port = substr(strrchr($server, ':'), 1); - -$proxies = isset($config['proxy']) ? $config['proxy'] : []; - -$testFilesPath = isset($config['test']) ? $config['test'] : []; -$testFiles = listFiles($testFilesPath); - -$loadFilesPath = isset($config['load']) ? $config['load'] : []; -$loadFiles = listFiles($loadFilesPath); -if (empty($loadFiles)) { - reportError('Could not find any files to load.'); -} - -$serveFilesPath = isset($config['serve']) ? $config['serve'] : []; -$serveFiles = listFiles($serveFilesPath); - -$sortedFiles = []; - -$fileOrder = normalize('jsTestDriverOrder.php'); -if (file_exists($fileOrder)) { - $loadOrder = require $fileOrder; - foreach ($loadOrder as $file) { - $sortedFiles[] = RELATIVE_APP_ROOT . $file; - } - foreach ($loadFiles as $loadFile) { - $found = false; - $normalizedLoadFile = normalize($loadFile); - foreach ($loadOrder as $orderFile) { - if (strcmp(normalize(RELATIVE_APP_ROOT . $orderFile), $normalizedLoadFile) == 0) { - $found = true; - break; - } - } - if (!$found) { - array_push($sortedFiles, $loadFile); - } - } -} - -$jsTestDriverConf = __DIR__ . '/jsTestDriver.conf'; -$fh = fopen($jsTestDriverConf, 'w'); - -fwrite($fh, "server: $server" . PHP_EOL); - -if (count($proxies) > 0) { - fwrite($fh, "proxy:" . PHP_EOL); - foreach ($proxies as $proxy) { - $proxyServer = sprintf($proxy['server'], $server, normalize(RELATIVE_APP_ROOT)); - fwrite($fh, ' - {matcher: "' . $proxy['matcher'] . '", server: "' . $proxyServer . '"}' . PHP_EOL); - } -} - -fwrite($fh, "load:" . PHP_EOL); -foreach ($sortedFiles as $file) { - if (!in_array($file, $serveFiles)) { - fwrite($fh, " - " . $file . PHP_EOL); - } -} - -fwrite($fh, "test:" . PHP_EOL); -foreach ($testFiles as $file) { - fwrite($fh, " - " . $file . PHP_EOL); -} - -if (count($serveFiles) > 0) { - fwrite($fh, "serve:" . PHP_EOL); - foreach ($serveFiles as $file) { - fwrite($fh, " - " . $file . PHP_EOL); - } -} - -fclose($fh); - -$testOutput = __DIR__ . '/test-output'; - -$filesystemAdapter = new \Magento\Framework\Filesystem\Driver\File(); -if ($filesystemAdapter->isExists($testOutput)) { - $filesystemAdapter->deleteDirectory($testOutput); -} -mkdir($testOutput); - -$command - = 'java -jar "' . $jsTestDriver . '" --config "' . $jsTestDriverConf . '" --reset --port ' . $port . - ' --browser "' . $browser . '" --raiseOnFailure true --tests all --testOutput "' . $testOutput . '"'; - -echo $command . PHP_EOL; - -if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { - system($command); -} else { - $commandFile = __DIR__ . '/run_js_tests.sh'; - $fh = fopen($commandFile, 'w'); - - $shellCommand - = 'LSOF=`/usr/sbin/lsof -i :' . $port . ' -t` - if [ "$LSOF" != "" ]; - then - kill -9 $LSOF - fi - - # Skip Xvfb setup for OS X since there browsers do not support headless display that way - if [ "$(uname)" != "Darwin" ]; then - DISPLAY_NUM=99 - ps -ef | egrep "[X]vfb.*:$DISPLAY_NUM" - if [ $? -eq 0 ] ; then - pkill Xvfb - fi - - XVFB=`which Xvfb` - if [ "$?" -eq 1 ]; - then - echo "Xvfb not found." - exit 1 - fi - - $XVFB :$DISPLAY_NUM -nolisten inet6 -ac & - PID_XVFB="$!" # take the process ID - export DISPLAY=:$DISPLAY_NUM # set display to use that of the Xvfb - fi - - USER=`whoami` - SUDO=`which sudo` - - # run the tests - $SUDO -u $USER ' . $command . ' - - if [ "$(uname)" != "Darwin" ]; then - kill -9 $PID_XVFB # shut down Xvfb (firefox will shut down cleanly by JsTestDriver) - fi - echo "Done."'; - - fwrite($fh, $shellCommand . PHP_EOL); - fclose($fh); - chmod($commandFile, 0750); - - exec($commandFile); -} - -/** - * Show a message that displays how to use (invoke) this PHP script and exit. - */ -function showUsage() -{ - reportError('Usage: php run_js_tests.php'); -} - -/** - * Reports an error given an error message and exits, effectively halting the PHP script's execution. - * - * @param string $message - Error message to be displayed to the user. - * - * @SuppressWarnings(PHPMD.ExitExpression) - */ -function reportError($message) -{ - echo $message . PHP_EOL; - exit(1); -} - -/** - * Takes a file or directory path in any form and normalizes it to fully absolute canonical form - * relative to this PHP script's location. - * - * @param string $filePath - File or directory path to be fully normalized to canonical form. - * - * @return string - The fully resolved path converted to absolute form. - */ -function normalize($filePath) -{ - return str_replace('\\', '/', realpath(__DIR__ . '/' . $filePath)); -} - -/** - * Accepts an array of directories and generates a list of Javascript files (.js) in those directories and - * all subdirectories recursively. - * - * @param array $dirs - An array of directories as specified in the configuration file (i.e. $configFile). - * - * @return array - An array of directory paths to all Javascript files found by recursively searching the - * specified array of directories. - */ -function listFiles($dirs) -{ - $baseDir = normalize(RELATIVE_APP_ROOT); - $result = []; - foreach ($dirs as $dir) { - $path = $baseDir . $dir; - if (is_file($path)) { - $path = substr_replace($path, RELATIVE_APP_ROOT, 0, strlen($baseDir)); - array_push($result, $path); - } else { - $paths = glob($path . '/*', GLOB_ONLYDIR | GLOB_NOSORT); - $paths = substr_replace($paths, '', 0, strlen($baseDir)); - $result = array_merge($result, listFiles($paths)); - - $files = glob($path . '/*.js', GLOB_NOSORT); - $files = substr_replace($files, RELATIVE_APP_ROOT, 0, strlen($baseDir)); - $result = array_merge($result, $files); - } - } - return $result; -} diff --git a/dev/tests/js/JsTestDriver/testsuite/lib/ko/datepicker/datepicker.js b/dev/tests/js/JsTestDriver/testsuite/lib/ko/datepicker/datepicker.js deleted file mode 100644 index 267c5d3df9a91..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/lib/ko/datepicker/datepicker.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -test('DatepickerBinding', function () { - expect(1); - - var element = $('#datepicker'), - observable = ko.observable(), - openBtn, - todayBtn, - todayDate, - dateFormat, - result; - - ko.applyBindingsToNode(element, { - datepicker: observable - }); - - dateFormat = $(element).datepicker('option', 'dateFormat'); - todayDate = moment().format(dateFormat); - - btn = $('img.ui-datepicker-trigger'); - todayBtn = $('[data-handler="today"]'); - - btn.click(); - todayBtn.click(); - - result = moment(observable()).format(dateFormat); - - equal(todayDate, result); -}); diff --git a/dev/tests/js/JsTestDriver/testsuite/lib/ko/datepicker/index.html b/dev/tests/js/JsTestDriver/testsuite/lib/ko/datepicker/index.html deleted file mode 100644 index e66e34da43945..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/lib/ko/datepicker/index.html +++ /dev/null @@ -1,29 +0,0 @@ -<!-- -/** - * @category storage - * @package test - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<!DOCTYPE html> -<html> -<head> - <title>Unit test - - - - - - - - - -
    -
    - -
    - - - diff --git a/dev/tests/js/JsTestDriver/testsuite/lib/storage/index.html b/dev/tests/js/JsTestDriver/testsuite/lib/storage/index.html deleted file mode 100644 index cd33350031db3..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/lib/storage/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - Unit test - - - - - - - - - - - -
    -
    -
    - - - diff --git a/dev/tests/js/JsTestDriver/testsuite/lib/storage/test-storage.js b/dev/tests/js/JsTestDriver/testsuite/lib/storage/test-storage.js deleted file mode 100644 index c0eebc166ec50..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/lib/storage/test-storage.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @category mage.collapsible - * @package test - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -test('Storage', function() { - expect(2); - var key = 'test-storage'; - var storage = $.localStorage; - if(window.localStorage !== null) { - localStorage.setItem(key,'false'); - storage.set(key,'true'); - equal(localStorage.getItem(key),"true"); - equal(localStorage.getItem(key),storage.get(key)); - } else { - $.cookie(key,'false'); - storage.set(key,'true'); - equal($.cookie(key),"true"); - equal($.cookie(key),storage.get(key)); - } -}); diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/_demo/index.html b/dev/tests/js/JsTestDriver/testsuite/mage/_demo/index.html deleted file mode 100644 index e541c6212a7a4..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/_demo/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Unit test - - - - - - - -
    -
    - - diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/_demo/test.js b/dev/tests/js/JsTestDriver/testsuite/mage/_demo/test.js deleted file mode 100644 index 1d148f4318993..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/_demo/test.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -TestCase( "hello test", function() { - ok( 1 == "1", "Passed!" ); -}); diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/accordion/accordion.js b/dev/tests/js/JsTestDriver/testsuite/mage/accordion/accordion.js deleted file mode 100644 index 562c5c096b654..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/accordion/accordion.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @category mage.js - * @package test - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -/* - - */ -test( "Initialization", function() { - expect(2); - var accordion = $("
    "); - accordion.accordion(); - ok( accordion.is(':mage-accordion'), "widget instantiated" ); - accordion.accordion('destroy'); - ok( !accordion.is(':mage-accordion'), "widget destroyed" ); -}); - - - -test( "One-collapsible element", function() { - expect(4); - var accordion = $('
    '); - var title1 = $('
    ').appendTo(accordion); - var content1 = $('
    ').appendTo(accordion); - var title2 = $('
    ').appendTo(accordion); - var content2 = $('
    ').appendTo(accordion); - accordion.appendTo("body"); - - accordion.accordion(); - ok( content1.is(':visible'), "content visible" ); - ok( content2.is(':hidden'), "content hidden" ); - title2.trigger('click'); - ok( content1.is(':hidden'), "content hidden" ); - ok( content2.is(':visible'), "content visible" ); - accordion.accordion('destroy'); - -}); - -test( "Multi-collapsible elements", function() { - expect(4); - var accordion = $('
    '); - var title1 = $('
    ').appendTo(accordion); - var content1 = $('
    ').appendTo(accordion); - var title2 = $('
    ').appendTo(accordion); - var content2 = $('
    ').appendTo(accordion); - accordion.appendTo("body"); - - accordion.accordion({multipleCollapsible:true}); - ok( content1.is(':visible'), "content visible" ); - ok( content2.is(':hidden'), "content hidden" ); - title2.trigger('click'); - ok( content1.is(':visible'), "content visible" ); - ok( content2.is(':visible'), "content visible" ); - accordion.accordion('destroy'); -}); diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/accordion/index.html b/dev/tests/js/JsTestDriver/testsuite/mage/accordion/index.html deleted file mode 100644 index 093284c6f4fa8..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/accordion/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - Accordion Widget: QUnit Tests - - - - - - - - - - - - -
    -
    -
    - - diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/button/button-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/button/button-test.js deleted file mode 100644 index b980acdc40545..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/button/button-test.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -ButtonTest = TestCase('ButtonTest'); -ButtonTest.prototype.testInit = function() { - /*:DOC += */ - assertTrue(jQuery('#test-button').button().is(':ui-button')); -}; -ButtonTest.prototype.testBind = function() { - /*:DOC +=
    */ - var testEventTriggered = false; - jQuery('#event-target').on('testEvent', function(e) { - testEventTriggered = true; - }); - jQuery('#test-button').button({ - event: 'testEvent', - target: '#event-target' - }).click(); - assertTrue(testEventTriggered); -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar-qunit.js b/dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar-qunit.js deleted file mode 100644 index 60dffe84db0fc..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar-qunit.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -test( "initialization", function() { - var calendar = $('#calendar').calendar(); - ok( calendar.is(':mage-calendar'), "this test is fine" ); - calendar.calendar('destroy'); -}); -test( "global configuration merge", function() { - $.extend(true, $, { - calendarConfig: { - showOn: 'button', - showAnim: '', - buttonImageOnly: true, - showButtonPanel: true, - showWeek: true, - timeFormat: '', - showTime: false, - showHour: false, - showMinute: false - } - }); - var calendar = $('#calendar').calendar(); - equal('button', calendar.calendar('option', 'showOn')); - equal('', calendar.calendar('option', 'showAnim')); - ok(calendar.calendar('option', 'buttonImageOnly')); - ok(calendar.calendar('option', 'showButtonPanel')); - ok(calendar.calendar('option', 'showWeek')); - equal('', calendar.calendar('option', 'timeFormat')); - equal(false, calendar.calendar('option', 'showTime')); - equal(false, calendar.calendar('option', 'showHour')); - equal(false, calendar.calendar('option', 'showMinute')); - calendar.calendar('destroy'); - delete $.calendarConfig; -}); -test( "specifying AM/PM in timeformat option changes AMPM option to true", function(){ - var calendar = $('#calendar').calendar({timeFormat: 'hh:mm tt', ampm: false}); - ok(calendar.calendar('option', 'ampm')); - calendar.calendar('destroy'); -}); -test( "omitting AM/PM in timeformat option changes AMPM option to false", function(){ - var calendar = $('#calendar').calendar({timeFormat: 'hh:mm'}); - notEqual(true, calendar.calendar('option', 'ampm')); - calendar.calendar('destroy'); -}); -test( "with server timezone offset", function(){ - var serverTimezoneSeconds = 1346122095, - calendar = $('#calendar').calendar({serverTimezoneSeconds: serverTimezoneSeconds}), - currentDate = new Date(); - currentDate.setTime((serverTimezoneSeconds + currentDate.getTimezoneOffset() * 60) * 1000); - ok(currentDate.toString() === calendar.calendar('getTimezoneDate').toString()); - calendar.calendar('destroy'); -}); -test( "without sever timezone offset", function() { - var calendar = $('#calendar').calendar(), - currentDate = new Date(); - ok(currentDate.toString() === calendar.calendar('getTimezoneDate').toString()); - calendar.calendar('destroy'); -}); -test( "dateTime format conversions", function() { - var calendar = $('#calendar').calendar({dateFormat: 'M/d/yy', timeFormat: 'h:mm a'}); - equal('mm/d/yy', calendar.calendar('option', 'dateFormat')); - equal('h:mm tt', calendar.calendar('option', 'timeFormat')); - calendar.calendar('destroy'); - calendar.calendar({dateFormat: 'MMMM/EEEE/yyyy', timeFormat: 'HH:mm'}); - equal('MM/DD/yy', calendar.calendar('option', 'dateFormat')); - equal('hh:mm', calendar.calendar('option', 'timeFormat')); - calendar.calendar('destroy'); -}); -test( "destroy", function() { - var calendar = $('#calendar').calendar(), - calendarExist = calendar.is(':mage-calendar'); - calendar.calendar('destroy'); - equal(true, calendarExist != calendar.is(':mage-calendar')); -}); diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar-test.js deleted file mode 100644 index 7748106b303c3..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar-test.js +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -CalendarTest = TestCase('CalendarTest'); -CalendarTest.prototype.testInit = function() { - /*:DOC += */ - var calendar = jQuery('#calendar').calendar(); - assertEquals(true, calendar.is(':mage-calendar')); - calendar.calendar('destroy'); -}; -CalendarTest.prototype.testGlobalConfigurationMerge = function() { - /*:DOC += */ - $.extend(true, $, { - calendarConfig: { - showOn: 'button', - showAnim: '', - buttonImageOnly: true, - showButtonPanel: true, - showWeek: true, - timeFormat: '', - showTime: false, - showHour: false, - showMinute: false - } - }); - var calendar = $('#calendar').calendar(); - assertEquals('button', calendar.calendar('option', 'showOn')); - assertEquals('', calendar.calendar('option', 'showAnim')); - assertEquals(true, calendar.calendar('option', 'buttonImageOnly')); - assertEquals(true, calendar.calendar('option', 'showButtonPanel')); - assertEquals(true, calendar.calendar('option', 'showWeek')); - assertEquals('', calendar.calendar('option', 'timeFormat')); - assertEquals(false, calendar.calendar('option', 'showTime')); - assertEquals(false, calendar.calendar('option', 'showHour')); - assertEquals(false, calendar.calendar('option', 'showMinute')); - calendar.calendar('destroy'); - delete $.calendarConfig; -}; -CalendarTest.prototype.testEnableAMPM = function() { - /*:DOC += */ - var calendar = $('#calendar').calendar({timeFormat: 'hh:mm tt', ampm: false}); - assertEquals(true, calendar.calendar('option', 'ampm')); - calendar.calendar('destroy'); -}; -CalendarTest.prototype.testDisableAMPM = function() { - /*:DOC += */ - var calendar = $('#calendar').calendar({timeFormat: 'hh:mm'}); - assertTrue(!calendar.calendar('option', 'ampm')); - calendar.calendar('destroy'); -}; -CalendarTest.prototype.testWithServerTimezoneOffset = function() { - /*:DOC += */ - var serverTimezoneSeconds = 1346122095, - calendar = $('#calendar').calendar({serverTimezoneSeconds: serverTimezoneSeconds}), - currentDate = new Date(); - currentDate.setTime((serverTimezoneSeconds + currentDate.getTimezoneOffset() * 60) * 1000); - assertEquals(true, currentDate.toString() === calendar.calendar('getTimezoneDate').toString()); - calendar.calendar('destroy'); -}; -CalendarTest.prototype.testWithServerTimezoneShift = function() { - /*:DOC += */ - var serverTimezoneOffset = 43200, - calendar = $('#calendar').calendar({serverTimezoneOffset: serverTimezoneOffset}), - currentDate = new Date(); - - setTimeout(function () { - currentDate.setTime(currentDate.getTime() + (serverTimezoneOffset + currentDate.getTimezoneOffset() * 60) * 1000); - assertEquals(true, currentDate.toString() === calendar.calendar('getTimezoneDate').toString()); - calendar.calendar('destroy'); - }, 61000); -}; -CalendarTest.prototype.testWithoutServerTimezoneOffset = function() { - /*:DOC += */ - var calendar = $('#calendar').calendar(), - currentDate = new Date(); - assertEquals(true, currentDate.toString() === calendar.calendar('getTimezoneDate').toString()); - calendar.calendar('destroy'); -}; -CalendarTest.prototype.testInitDateTimePicker = function() { - /*:DOC += */ - var calendar = $('#calendar').calendar(); - assertEquals(true, calendar.hasClass('_has-datepicker')); - calendar.calendar('destroy'); -}; -CalendarTest.prototype.testDateTimeMapping = function() { - /*:DOC += */ - var calendar = $('#calendar').calendar({dateFormat: 'M/d/yy', timeFormat: 'h:mm a'}); - assertEquals('mm/d/yy', calendar.calendar('option', 'dateFormat')); - assertEquals('h:mm TT', calendar.calendar('option', 'timeFormat')); - calendar.calendar('destroy'); - calendar.calendar({dateFormat: 'MMMM/EEEE/yyyy'}); - assertEquals('MM/DD/yy', calendar.calendar('option', 'dateFormat')); - calendar.calendar('destroy'); -}; -CalendarTest.prototype.testDestroy = function() { - /*:DOC += */ - var calendar = $('#calendar').calendar(), - calendarExist = calendar.is(':mage-calendar'); - calendar.calendar('destroy'); - assertEquals(true, calendarExist != calendar.is(':mage-calendar')); -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar.html b/dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar.html deleted file mode 100644 index b474dc2d5ce95..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/calendar/calendar.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - Calendar Widget: QUnit Tests - - - - - - - - - - - -
    -
    - -
    - - diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/calendar/date-range-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/calendar/date-range-test.js deleted file mode 100644 index 61211c067ad12..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/calendar/date-range-test.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -DaterangeTest = TestCase('DaterangeTest'); -DaterangeTest.prototype.testInit = function() { - /*:DOC += -
    - */ - var dateRange = jQuery('#date-range').dateRange(); - assertEquals(true, dateRange.is(':mage-dateRange')); - dateRange.dateRange('destroy'); -}; -DaterangeTest.prototype.testInitDateRangeDatepickers = function() { - /*:DOC += -
    - - -
    - */ - var options = { - from: { - id: "from" - }, - to: { - id: "to" - } - }, - dateRange = $('#date-range').dateRange(options), - from = $('#'+options.from.id), - to = $('#'+options.to.id); - - assertEquals(true, from.hasClass('_has-datepicker')); - assertEquals(true, to.hasClass('_has-datepicker')); - dateRange.dateRange('destroy'); -}; -DaterangeTest.prototype.testDestroy = function() { - /*:DOC += -
    - - -
    - */ - var options = { - from: { - id: "from" - }, - to: { - id: "to" - } - }, - dateRange = $('#date-range').dateRange(options), - from = $('#'+options.from.id), - to = $('#'+options.to.id), - dateRangeExist = dateRange.is(':mage-dateRange'), - fromExist = from.hasClass('_has-datepicker'), - toExist = to.hasClass('_has-datepicker'); - - dateRange.dateRange('destroy'); - assertEquals(true, dateRangeExist != dateRange.is(':mage-dateRange')); - assertEquals(true, fromExist != from.hasClass('_has-datepicker')); - assertEquals(true, toExist != to.hasClass('_has-datepicker')); -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/collapsible/content.html b/dev/tests/js/JsTestDriver/testsuite/mage/collapsible/content.html deleted file mode 100644 index e81938dfbeaba..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/collapsible/content.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - -

    Test text

    - - diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/collapsible/index.html b/dev/tests/js/JsTestDriver/testsuite/mage/collapsible/index.html deleted file mode 100644 index ccfd4d97f0331..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/collapsible/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - Unit test - - - - - - - - - - - -
    -
    -
    - - - diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/collapsible/test-collapsible.js b/dev/tests/js/JsTestDriver/testsuite/mage/collapsible/test-collapsible.js deleted file mode 100644 index 1a22e5a79eb1d..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/collapsible/test-collapsible.js +++ /dev/null @@ -1,180 +0,0 @@ -/** - * @category mage.collapsible - * @package test - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -/* - Test if the collapsible widget gets initialized when is called and destroy function works - */ -test('initialization & destroy', function() { - expect(2); - var group = $('
    '); - group.collapsible(); - ok( group.is(':mage-collapsible'), "widget instantiated" ); - group.collapsible('destroy'); - ok( !group.is(':mage-collapsible'), "widget destroyed" ); -}); - -/* - Test enable, disable, activate, deactivate functions - */ -test('Enable, disable, activate, deactivate methods', function() { - expect(5); - var group = $('
    '); - var title = $('
    '); - var content = $('
    '); - title.appendTo(group); - content.appendTo(group); - group.appendTo("body"); - group.collapsible(); - group.collapsible("deactivate"); - ok(content.is(':hidden'), "Content is collapsed"); - group.collapsible("activate"); - ok(content.is(':visible'), "Content is expanded"); - group.collapsible("disable"); - ok(content.is(':hidden'), "Content is collapsed"); - group.collapsible("activate"); - ok(content.is(':hidden'), "Content is collapsed"); - group.collapsible("enable"); - group.collapsible("activate"); - ok(content.is(':visible'), "Content is expanded"); - group.collapsible('destroy'); -}); - -/* - Test if the widget gets expanded/collapsed when the title is clicked - */ -test('Collapse and expand', function() { - expect(3); - var group = $('
    '); - var title = $('
    '); - var content = $('
    '); - title.appendTo(group); - content.appendTo(group); - group.appendTo("body"); - group.collapsible(); - group.collapsible("deactivate"); - ok(content.is(':hidden'), "Content is collapsed"); - title.trigger("click"); - ok(content.is(':visible'), "Content gets expanded on click title"); - title.trigger("click"); - ok(content.is(':hidden'), "Content gets collapsed on click again"); - group.collapsible('destroy'); -}); - - -/* - Test state Classes - */ -test('State classes', function() { - expect(3); - var group = $('
    '); - var title = $('
    '); - var content = $('
    '); - title.appendTo(group); - content.appendTo(group); - group.collapsible({openedState:"opened", closedState:"closed", disabledState:"disabled"}); - ok( group.hasClass("closed")); - title.trigger("click"); - ok( group.hasClass("opened")); - group.collapsible("disable"); - ok( group.hasClass("disabled")); - group.collapsible('destroy'); -}); - -/* - Test if icons are added to title when widget gets initialized and are removed when gets destroyed - */ -test('Create & destroy icons', function() { - expect(2); - var group = $('
    '); - var title = $('
    '); - var content = $('
    '); - title.appendTo(group); - content.appendTo(group); - group.collapsible({icons: {header:"minus",activeHeader:"plus"}}); - ok(title.children("[data-role=icons]").length, "Icons added to title" ); - group.collapsible('destroy'); - ok(!title.children("[data-role=icons]").length, "Icons removed from title" ); -}); - -/* - Test if icon classes are changed when content gets expanded/collapsed - */ -test('Change icons when content gets expanded/collapsed', function() { - expect(2); - var group = $('
    '); - var title = $('
    '); - var content = $('
    '); - title.appendTo(group); - content.appendTo(group); - group.collapsible({icons: {header:"minus",activeHeader:"plus"}}); - group.collapsible("deactivate"); - var icons = group.collapsible("option","icons"); - ok(title.children("[data-role=icons]").hasClass(icons.header), "When content is collapsed,header has the right class for icons" ); - title.trigger("click"); - ok(title.children("[data-role=icons]").hasClass(icons.activeHeader), "When content is expanded,header has the right class for icons" ); - group.collapsible('destroy'); -}); - - -/* - Test if content gets expanded/collapsed when certain keys are pressed - */ -asyncTest( "keyboard support", function() { - - expect( 5 ); - var group = $('
    '); - var title = $('
    '); - var content = $('
    '); - title.appendTo(group); - content.appendTo(group); - group.appendTo("body"); - group.collapsible(); - group.collapsible("deactivate"); - - title.on("focus",function(ev){ - ok(content.is(':hidden'), "Content is collapsed"); - title.trigger($.Event( 'keydown', { keyCode: $.ui.keyCode.ENTER } )); - ok(content.is(':visible'), "Content is expanded"); - title.trigger($.Event( 'keydown', { keyCode: $.ui.keyCode.ENTER } )); - ok(content.is(':hidden'), "Content is collapsed"); - title.trigger($.Event( 'keydown', { keyCode: $.ui.keyCode.SPACE } )); - ok(content.is(':visible'), "Content is expanded"); - title.trigger($.Event( 'keydown', { keyCode: $.ui.keyCode.SPACE } )); - ok(content.is(':hidden'), "Content is collapsed"); - group.collapsible('destroy'); - start(); - } ); - - setTimeout(function(){ - title.focus(); - },10); - -}); - -/* - Test if content gets updated via Ajax when title is clicked - */ -test('Update content via ajax', function() { - expect(2); - var group = $('
    '); - var title = $('
    '); - var content = $('
    '); - var ajax = $(''); - title.appendTo(group); - content.appendTo(group); - ajax.appendTo(content); - group.appendTo("body"); - group.collapsible({ajaxContent : true}); - group.collapsible("deactivate"); - ok(!content.children("p").length, "Content has no data"); - title.trigger("click"); - ok(content.children("p"), "Content gets data from content.html"); - group.collapsible('destroy'); -}); - - - diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/decorate-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/decorate-test.js deleted file mode 100644 index 96bad35a17e2e..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/decorate-test.js +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -DecoratorTest = TestCase('DecoratorTest'); -DecoratorTest.prototype.testDecoratorList = function () { - /*:DOC +=
      -
    • item1
    • -
    • item2
    • -
    • item3
    • -
    • item4
    • -
    - */ - var list = $('#list'); - list.decorate('list'); - assertTrue($(list.find('li')[0]).hasClass('odd')); - assertFalse($(list.find('li')[0]).hasClass('even')); - assertTrue($(list.find('li')[1]).hasClass('even')); - assertFalse($(list.find('li')[1]).hasClass('odd')); - assertTrue($(list.find('li')[2]).hasClass('odd')); - assertFalse($(list.find('li')[2]).hasClass('even')); - assertTrue($(list.find('li')[3]).hasClass('even')); - assertFalse($(list.find('li')[3]).hasClass('odd')); - assertTrue($(list.find('li')[3]).hasClass('last')); -}; - -DecoratorTest.prototype.testDecoratorGeneral = function () { - /*:DOC +=
    -
    item1
    -
    item2
    -
    item3
    -
    item4
    -
    - */ - var itemClass = '.item'; - $(itemClass).decorate('generic'); - assertTrue($($(itemClass)[0]).hasClass('odd')); - assertFalse($($(itemClass)[0]).hasClass('even')); - assertTrue($($(itemClass)[0]).hasClass('first')); - assertFalse($($(itemClass)[0]).hasClass('last')); - - assertFalse($($(itemClass)[1]).hasClass('odd')); - assertTrue($($(itemClass)[1]).hasClass('even')); - assertFalse($($(itemClass)[1]).hasClass('first')); - assertFalse($($(itemClass)[1]).hasClass('last')); - - assertTrue($($(itemClass)[2]).hasClass('odd')); - assertFalse($($(itemClass)[2]).hasClass('even')); - assertFalse($($(itemClass)[2]).hasClass('first')); - assertFalse($($(itemClass)[2]).hasClass('last')); - - assertFalse($($(itemClass)[3]).hasClass('odd')); - assertTrue($($(itemClass)[3]).hasClass('even')); - assertFalse($($(itemClass)[3]).hasClass('first')); - assertTrue($($(itemClass)[3]).hasClass('last')); -}; - -DecoratorTest.prototype.testDecoratorTable = function (){ - /*:DOC += - - - - - - - - - - - - - - - - - - - - - - -
    MonthSavings
    Sum$180
    January$100
    February$80
    - */ - var tableId = '#foo'; - $(tableId).decorate('table'); - assertTrue($(tableId).find('thead tr').hasClass('first')); - assertTrue($(tableId).find('thead tr').hasClass('last')); - assertFalse($(tableId).find('thead tr').hasClass('odd')); - assertFalse($(tableId).find('thead tr').hasClass('even')); - - assertTrue($(tableId).find('tfoot tr').hasClass('first')); - assertTrue($(tableId).find('tfoot tr').hasClass('last')); - assertFalse($(tableId).find('tfoot tr').hasClass('odd')); - assertFalse($(tableId).find('tfoot tr').hasClass('even')); - - assertFalse($(tableId).find('tfoot tr td').last().hasClass('first')); - assertTrue($(tableId).find('tfoot tr td').last().hasClass('last')); - assertFalse($(tableId).find('tfoot tr td').last().hasClass('odd')); - assertFalse($(tableId).find('tfoot tr td').last().hasClass('even')); - - assertTrue($(tableId).find('tbody tr').first().hasClass('first')); - assertTrue($(tableId).find('tbody tr').first().hasClass('odd')); - assertFalse($(tableId).find('tbody tr').first().hasClass('last')); - assertFalse($(tableId).find('tbody tr').first().hasClass('even')); - assertFalse($(tableId).find('tbody tr').last().hasClass('first')); - assertFalse($(tableId).find('tbody tr').last().hasClass('odd')); - assertTrue($(tableId).find('tbody tr').last().hasClass('last')); - assertTrue($(tableId).find('tbody tr').last().hasClass('even')); - - assertFalse($(tableId).find('tbody tr td').last().hasClass('first')); - assertFalse($(tableId).find('tbody tr td').last().hasClass('odd')); - assertTrue($(tableId).find('tbody tr td').last().hasClass('last')); - assertFalse($(tableId).find('tbody tr td').last().hasClass('even')); -}; - -DecoratorTest.prototype.testDecoratorDataList = function () { - /*:DOC +=
    -
    item
    -
    item
    -
    item
    -
    item
    -
    - */ - var listId = '#data-list'; - $(listId).decorate('dataList'); - assertTrue($(listId).find('dt').first().hasClass('odd')); - assertFalse($(listId).find('dt').first().hasClass('even')); - assertFalse($(listId).find('dt').first().hasClass('last')); - - assertTrue($(listId).find('dt').last().hasClass('even')); - assertFalse($(listId).find('dt').last().hasClass('odd')); - assertTrue($(listId).find('dt').last().hasClass('last')); - - assertTrue($(listId).find('dd').first().hasClass('odd')); - assertFalse($(listId).find('dd').first().hasClass('even')); - assertFalse($(listId).find('dd').first().hasClass('last')); - - assertTrue($(listId).find('dd').last().hasClass('even')); - assertFalse($(listId).find('dd').last().hasClass('odd')); - assertTrue($(listId).find('dd').last().hasClass('last')); -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/dropdown/index.html b/dev/tests/js/JsTestDriver/testsuite/mage/dropdown/index.html deleted file mode 100644 index 3d6ed5a7c1d28..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/dropdown/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - Unit test - - - - - - - - - - - - -
    -
    -
    - - diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/dropdown/test-dropdown.js b/dev/tests/js/JsTestDriver/testsuite/mage/dropdown/test-dropdown.js deleted file mode 100644 index e67c92b3d4018..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/dropdown/test-dropdown.js +++ /dev/null @@ -1,270 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -/* - testing if dialog opens when the triggerEvent is triggered - */ -test( "triggerEvent", function() { - expect(2); - var opener = $('
    '); - var dialog = $('
    '); - dialog.dropdownDialog({"triggerEvent":"click", "triggerTarget":opener}); - opener.trigger("click"); - equal(dialog.dropdownDialog("isOpen"), true, "Dropdown opens when click opener"); - dialog.dropdownDialog( "destroy" ); - - dialog.dropdownDialog({"triggerEvent":null, "triggerTarget":opener}); - opener.trigger("click"); - equal(dialog.dropdownDialog("isOpen"), false, "Dropdown doesn't open when click opener"); - dialog.dropdownDialog( "destroy" ); - -}); - -/* - testing if a specified class is added to the trigger - */ -test( "triggerClass", function() { - expect(2); - var opener = $('
    '); - var dialog = $('
    '); - dialog.dropdownDialog({"triggerTarget":opener,"triggerClass":"active"}); - dialog.dropdownDialog("open"); - ok( opener.hasClass("active"), "Class added to opener when dialog opens" ); - dialog.dropdownDialog("close"); - dialog.dropdownDialog( "destroy" ); - - dialog.dropdownDialog({"triggerEvent":opener, "triggerClass":null}); - dialog.dropdownDialog("open"); - ok( !opener.hasClass("active"), "Class added to opener when dialog opens" ); - dialog.dropdownDialog("close"); - dialog.dropdownDialog( "destroy" ); - -}); - -/* - testing if a specified class is added to the element which the dialog appends to - */ -test( "parentClass", function() { - expect(2); - var parent = $('
    '); - var dialog = $('
    '); - - dialog.dropdownDialog({"parentClass":"active","appendTo":parent}); - dialog.dropdownDialog("open"); - ok( parent.hasClass("active"), "Class is added to parent when dialog opens" ); - dialog.dropdownDialog("close"); - dialog.dropdownDialog( "destroy" ); - - dialog.dropdownDialog({"parentClass":null,"appendTo":parent}); - dialog.dropdownDialog("open"); - ok( !parent.hasClass("active"), "No class is added to parent when dialog opens" ); - dialog.dropdownDialog("close"); - dialog.dropdownDialog( "destroy" ); - -}); - -/* - testing if a specified class is added to the element that becomes dialog - */ -test( "dialogContentClass", function() { - expect(2); - var dialog = $('
    '); - - dialog.dropdownDialog({"dialogContentClass":"active"}); - dialog.dropdownDialog("open"); - ok( $('.ui-dialog-content').hasClass("active"), "Class is added to dialog content when dialog opens" ); - dialog.dropdownDialog("close"); - dialog.dropdownDialog( "destroy" ); - - dialog.dropdownDialog({"dialogContentClass": null}); - dialog.dropdownDialog("open"); - ok( !$('.ui-dialog-content').hasClass("active"), "No class is added to dialog content" ); - dialog.dropdownDialog("close"); - dialog.dropdownDialog( "destroy" ); -}); - -/* - testing if a specified class is added to dialog - */ -test( "defaultDialogClass", function() { - expect(3); - var dialog = $('
    '); - - dialog.dropdownDialog({"defaultDialogClass":"custom"}); - ok( $('.ui-dialog').hasClass("custom"), "Class is added to dialog" ); - ok( !$('.ui-dialog').hasClass("mage-dropdown-dialog"), "Default class has been overwritten" ); - dialog.dropdownDialog( "destroy" ); - - dialog.dropdownDialog({}); - ok( $('.ui-dialog').hasClass("mage-dropdown-dialog"), "Default class hasn't been overwritten" ); - dialog.dropdownDialog( "destroy" ); -}); - -/* - testing if the specified trigger actually opens the dialog - */ -test( "triggerTarget", function() { - expect(2); - var opener = $('
    '); - var dialog = $('
    '); - - dialog.dropdownDialog({"triggerTarget":opener}); - opener.trigger("click"); - equal(dialog.dropdownDialog("isOpen"), true, "Dropdown opens when click opener"); - dialog.dropdownDialog("close"); - dialog.dropdownDialog( "destroy" ); - - dialog.dropdownDialog({"triggerTarget":null}); - opener.trigger("click"); - equal(dialog.dropdownDialog("isOpen"), false, "Dropdown doesn't open when click opener"); - dialog.dropdownDialog( "destroy" ); -}); - -/* - testing if the dialog gets closed when clicking outside of it - */ -test( "closeOnClickOutside", function() { - expect(2); - var outside = $('
    ').attr({"id":"outside"}); - var dialog = $('
    ').attr({"id":"dialog"}); - outside.appendTo("#qunit-fixture"); - dialog.appendTo("#qunit-fixture"); - - dialog.dropdownDialog({"closeOnClickOutside":true}); - dialog.dropdownDialog("open"); - outside.trigger("click"); - equal(dialog.dropdownDialog("isOpen"), false, "Dropdown closes when click outside dropdown"); - dialog.dropdownDialog( "destroy" ); - - dialog.dropdownDialog({"closeOnClickOutside":false}); - dialog.dropdownDialog("open"); - outside.trigger("click"); - equal(dialog.dropdownDialog("isOpen"), true, "Dropdown doesn't close when click outside dropdown"); - dialog.dropdownDialog( "destroy" ); -}); - -/* - testing if the dialog gets closed when mouse leaves the dialog area - */ -asyncTest( "closeOnMouseLeave true", function() { - expect(1); - var outside = $('
    ').attr({"id":"outside"}); - var dialog = $('
    ').attr({"id":"dialog"}); - var opener = $('
    ').attr({"id":"opener"}); - outside.appendTo("#qunit-fixture"); - dialog.appendTo("#qunit-fixture"); - opener.appendTo("#qunit-fixture"); - - dialog.dropdownDialog({"closeOnMouseLeave":true}); - dialog.dropdownDialog("open"); - dialog.trigger("mouseenter"); - dialog.trigger("mouseleave"); - - setTimeout(function() { - equal(dialog.dropdownDialog("isOpen"), false, "Dropdown closes when mouseleave the dropdown area"); - dialog.dropdownDialog( "destroy" ); - start(); - }, 3000); - -}); - -/* - testing if the dialog gets closed when mouse leaves the dialog area - */ -asyncTest( "closeOnMouseLeave false", function() { - expect(1); - var outside = $('
    ').attr({"id":"outside"}); - var dialog = $('
    ').attr({"id":"dialog"}); - var opener = $('
    ').attr({"id":"opener"}); - outside.appendTo("#qunit-fixture"); - dialog.appendTo("#qunit-fixture"); - opener.appendTo("#qunit-fixture"); - - dialog.dropdownDialog({"closeOnMouseLeave":false}); - dialog.dropdownDialog("open"); - dialog.trigger("mouseenter"); - dialog.trigger("mouseleave"); - - setTimeout(function() { - equal(dialog.dropdownDialog("isOpen"), true, "Dropdown doesn't close when mouseleave the dropdown area"); - dialog.dropdownDialog( "destroy" ); - start(); - }, 3000); - -}); - -/* - testing if the dialog gets closed with the specified delay - */ -asyncTest( "timeout", function() { - expect(2); - var outside = $('
    ').attr({"id":"outside"}); - var dialog = $('
    ').attr({"id":"dialog"}); - var opener = $('
    ').attr({"id":"opener"}); - outside.appendTo("#qunit-fixture"); - dialog.appendTo("#qunit-fixture"); - opener.appendTo("#qunit-fixture"); - - dialog.dropdownDialog({"timeout":2000}); - dialog.dropdownDialog("open"); - dialog.trigger("mouseenter"); - dialog.trigger("mouseleave"); - equal(dialog.dropdownDialog("isOpen"), true, "Dropdown doesn't close when mouseleave the dropdown area"); - setTimeout(function() { - equal(dialog.dropdownDialog("isOpen"), false, "Dropdown closes when mouseleave the dropdown area, after timeout passed"); - dialog.dropdownDialog( "destroy" ); - start(); - }, 3000); - -}); - -/* - testing if the title bar is prevented from being created - */ -test( "createTitileBar", function() { - expect(2); - var dialog = $('
    '); - dialog.dropdownDialog({"createTitleBar":true}); - ok(($(".ui-dialog").find(".ui-dialog-titlebar").length > 0), "Title bar is created"); - dialog.dropdownDialog( "destroy" ); - - dialog.dropdownDialog({"createTitleBar":false}); - ok($(".ui-dialog").find(".ui-dialog-titlebar").length <= 0, "Title bar isn't created"); - dialog.dropdownDialog( "destroy" ); -}); - -/* - testing if the position function gets disabled - */ -test( "autoPosition", function() { - expect(2); - var dialog = $('
    '); - dialog.dropdownDialog({"autoPosition":false}); - dialog.dropdownDialog("open"); - ok(($(".ui-dialog").css("top") === 'auto'), "_position function disabled"); - dialog.dropdownDialog( "destroy" ); - - dialog.dropdownDialog({"autoPosition":true}); - dialog.dropdownDialog("open"); - ok(($(".ui-dialog").css("top") !== '0px'), "_position function enabled"); - dialog.dropdownDialog( "destroy" ); -}); - -/* - testing if the size function gets disabled - */ -test( "autoSize", function() { - expect(2); - var dialog = $('
    '); - dialog.dropdownDialog({"autoSize":true, width:"300"}); - dialog.dropdownDialog("open"); - ok(($(".ui-dialog").css("width") === '300px'), "_size function enabled"); - dialog.dropdownDialog( "destroy" ); - - dialog.dropdownDialog({"autoSize":false, width:"300"}); - dialog.dropdownDialog("open"); - ok($(".ui-dialog").css("width") !== '300px', "_size function disabled"); - dialog.dropdownDialog( "destroy" ); -}); diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/edit_trigger/edit-trigger-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/edit_trigger/edit-trigger-test.js deleted file mode 100644 index c28f1e4943438..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/edit_trigger/edit-trigger-test.js +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -EditTriggerTest = TestCase('EditTriggerTest'); -EditTriggerTest.prototype.testInit = function() { - var editTrigger = jQuery('body').editTrigger(); - assertEquals(true, !!editTrigger.data('mageEditTrigger')); - editTrigger.editTrigger('destroy'); -}; -EditTriggerTest.prototype.testCreate = function() { - /*:DOC += - */ - var options = { - img: 'img.gif', - alt: 'translate' - }, - editTrigger = jQuery('body').editTrigger(options); - var trigger = jQuery('.translate-edit-icon'); - assertNotNull(trigger); - assertTrue(trigger.is('img')); - assertEquals(true, trigger.attr('src') === options.img); - assertEquals(true, trigger.attr('alt') === options.alt); - assertEquals(true, trigger.is(':hidden')); - editTrigger.editTrigger('destroy'); -}; -EditTriggerTest.prototype.testShowHideOnMouseMove = function() { - /*:DOC +=
    -
    text
    -
    - - */ - var editTrigger = jQuery('body').editTrigger({ - editSelector: '.edit', - delay: 0 - }), - trigger = jQuery('.translate-edit-icon'), - editElement = jQuery('.edit'), - container = jQuery('.container'); - editElement.trigger('mousemove'); - assertEquals(true, trigger.is(':visible')); - container.trigger('mousemove'); - assertEquals(true, trigger.is(':hidden')); - editTrigger.editTrigger('destroy'); -}; -EditTriggerTest.prototype.testTriggerClick = function() { - /*:DOC +=
    text
    - - */ - var editTrigger = jQuery('body').editTrigger({ - editSelector: '.edit' - }), - trigger = jQuery('.translate-edit-icon'), - editElement = jQuery('.edit'), - editTriggered = false; - $('body').on('edit.editTrigger', function() { editTriggered = true; }); - editElement.trigger('mousemove'); - trigger.trigger('click'); - assertEquals(true, editTriggered); - editTrigger.editTrigger('destroy'); -}; -EditTriggerTest.prototype.testDestroy = function() { - var editTrigger = jQuery('body').editTrigger(), - editProcessed = false, - mousemoveProcessed = false; - - $('body') - .on('edit.editTrigger', function() {editProcessed = true;}) - .on('mousemove.editTrigger', function() {mousemoveProcessed = true;}); - - editTrigger.editTrigger('destroy'); - assertEquals(false, !!editTrigger.data('mageEditTrigger')); - - $('body').trigger('edit.editTrigger'); - assertEquals(false, editProcessed); - - $('body').trigger('mousemove.editTrigger'); - assertEquals(false, mousemoveProcessed); -}; -var EditTriggerTestAsync = AsyncTestCase('EditTriggerTestAsync'); -EditTriggerTestAsync.prototype.testHideEditTriggerWithDelay = function(queue) { - /*:DOC +=
    -
    text
    -
    - - */ - var editTrigger = jQuery(document).editTrigger({ - editSelector: '.edit', - delay: 1000 - }), - trigger = jQuery('.translate-edit-icon'), - editElement = jQuery('.edit'), - container = jQuery('.container'), - visibleOnMouseout, - hiddenAfterDelay; - editElement.trigger('mousemove'); - container.trigger('mousemove'); - queue.call('Step 1: Start hiding with delay', function(callbacks) { - visibleOnMouseout = trigger.is(':visible'); - setTimeout(callbacks.add(function() { - hiddenAfterDelay = trigger.is(':hidden'); - }), 1050); - }); - queue.call('Step 2: Check is trigger are hidden after delay', function() { - assertEquals(true, visibleOnMouseout); - assertEquals(true, hiddenAfterDelay); - editTrigger.editTrigger('destroy'); - }); -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/form/form-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/form/form-test.js deleted file mode 100644 index 83bdefd399eaf..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/form/form-test.js +++ /dev/null @@ -1,241 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -FormTest = TestCase('FormTest'); -FormTest.prototype.setUp = function() { - /*:DOC +=
    */ -}; -FormTest.prototype.tearDown = function() { - var formInstance = jQuery('#form').data('form'); - if(formInstance && formInstance.destroy) { - formInstance.destroy(); - } -}; -FormTest.prototype.testInit = function() { - var form = jQuery('#form').form(); - assertTrue(form.is(':mage-form')); -}; -FormTest.prototype.testRollback = function() { - var form = jQuery('#form').form(), - initialFormAttrs = { - action: form.prop('action'), - target: form.prop('target'), - method: form.prop('method') - }; - - form.data("form").oldAttributes = initialFormAttrs; - form.prop({ - action: 'new/action/url', - target: '_blank', - method: 'POST' - }); - - assertNotEquals(form.prop('action'), initialFormAttrs.action); - assertNotEquals(form.prop('target'), initialFormAttrs.target); - assertNotEquals(form.prop('method'), initialFormAttrs.method); - form.data("form")._rollback(); - assertEquals(form.prop('action'), initialFormAttrs.action); - assertEquals(form.prop('target'), initialFormAttrs.target); - assertEquals(form.prop('method'), initialFormAttrs.method); -}; -FormTest.prototype.testGetHandlers = function() { - var form = jQuery('#form').form(), - handlersData = form.form('option', 'handlersData'), - handlers = []; - $.each(handlersData, function(key) { - handlers.push(key); - }); - assertEquals(handlers.join(' '), form.data("form")._getHandlers().join(' ')); -}; -FormTest.prototype.testStoreAttribute = function() { - var form = jQuery('#form').form(), - initialFormAttrs = { - action: form.attr('action'), - target: form.attr('target'), - method: form.attr('method') - }; - form.data("form")._storeAttribute('action'); - form.data("form")._storeAttribute('target'); - form.data("form")._storeAttribute('method'); - - assertEquals(form.data("form").oldAttributes.action, initialFormAttrs.action); - assertEquals(form.data("form").oldAttributes.target, initialFormAttrs.target); - assertEquals(form.data("form").oldAttributes.method, initialFormAttrs.method); -}; -FormTest.prototype.testBind = function() { - var form = jQuery('#form').form(), - submitted = false, - handlersData = form.form('option', 'handlersData'); - - form.on('submit', function(e) { - submitted = true; - e.stopImmediatePropagation(); - e.preventDefault(); - }); - $.each(handlersData, function(key) { - form.trigger(key); - assertTrue(submitted); - submitted = false; - }); - form.off('submit'); -}; -FormTest.prototype.testGetActionUrl = function() { - var form = jQuery('#form').form(), - action = form.attr('action'), - testUrl = 'new/action/url', - testArgs = { - args: {arg: 'value'} - }; - - form.data("form")._storeAttribute('action'); - assertEquals(form.data("form")._getActionUrl(testArgs), action + '/arg/value/'); - assertEquals(form.data("form")._getActionUrl(testUrl), testUrl); - assertEquals(form.data("form")._getActionUrl(), action); -}; -FormTest.prototype.testProcessData = function() { - var form = jQuery('#form').form(), - initialFormAttrs = { - action: form.attr('action'), - target: form.attr('target'), - method: form.attr('method') - }, - testSimpleData = { - action: 'new/action/url', - target: '_blank', - method: 'POST' - }, - testActionArgsData = { - action: { - args: { - arg: 'value' - } - } - }; - var processedData = form.data("form")._processData(testSimpleData); - - assertEquals(form.data("form").oldAttributes.action, initialFormAttrs.action); - assertEquals(form.data("form").oldAttributes.target, initialFormAttrs.target); - assertEquals(form.data("form").oldAttributes.method, initialFormAttrs.method); - - assertEquals(processedData.action, testSimpleData.action); - assertEquals(processedData.target, testSimpleData.target); - assertEquals(processedData.method, testSimpleData.method); - - form.data("form")._rollback(); - - processedData = form.data("form")._processData(testActionArgsData); - form.data("form")._storeAttribute('action'); - var newActionUrl = form.data("form")._getActionUrl(testActionArgsData.action); - - assertEquals(processedData.action, newActionUrl); -}; -FormTest.prototype.testBeforeSubmit = function() { - /*:DOC +=
    */ - var testHandler = { - action: { - args: { - arg1: 'value1' - } - } - }, - form = jQuery('#form').form({handlersData: { - testHandler: testHandler - } - }), - beforeSubmitData = { - action: { - args: { - arg2: 'value2' - } - }, - target: '_blank' - }, - eventData = { - method: 'POST' - }, - resultData = $.extend( - true, - {}, - testHandler, - beforeSubmitData, - eventData - ); - form.data("form")._storeAttribute('action'); - - var testForm = jQuery('#test-form'); - resultData = form.data("form")._processData(resultData); - testForm.prop(resultData); - - form.on('beforeSubmit', function(e, data) { - jQuery.extend(data, beforeSubmitData); - }); - form.on('submit', function(e) { - e.stopImmediatePropagation(); - e.preventDefault(); - }); - form.data("form")._beforeSubmit('testHandler', eventData); - - assertEquals(testForm.prop('action'), form.prop('action')); - assertEquals(testForm.prop('target'), form.prop('target')); - assertEquals(testForm.prop('method'), form.prop('method')); -}; -FormTest.prototype.testSubmit = function() { - var form = jQuery('#form').form({ - handlersData: { - save: {} - } - }), - formSubmitted = false; - - form.data("form")._storeAttribute('action'); - form.data("form")._storeAttribute('target'); - form.data("form")._storeAttribute('method'); - form - .on('submit', function(e) { - e.preventDefault(); - e.stopImmediatePropagation(); - e.preventDefault(); - formSubmitted = true; - }) - .prop({ - action: 'new/action/url', - target: '_blank', - method: 'POST' - }); - - form.data("form")._submit({type: 'save'}); - - assertEquals(form.attr('action'), form.data("form").oldAttributes.action); - assertEquals(form.attr('target'), form.data("form").oldAttributes.target); - assertEquals(form.attr('method'), form.data("form").oldAttributes.method); - assertTrue(formSubmitted); - form.off('submit'); -}; -FormTest.prototype.testBuildURL = function() { - var dataProvider = [ - { - params: ['http://domain.com//', {'key[one]': 'value 1', 'key2': '# value'}], - expected: 'http://domain.com/key[one]/value%201/key2/%23%20value/' - }, - { - params: ['http://domain.com', {'key[one]': 'value 1', 'key2': '# value'}], - expected: 'http://domain.com/key[one]/value%201/key2/%23%20value/' - }, - { - params: ['http://domain.com?some=param', {'key[one]': 'value 1', 'key2': '# value'}], - expected: 'http://domain.com?some=param&key[one]=value%201&key2=%23%20value' - }, - { - params: ['http://domain.com?some=param&', {'key[one]': 'value 1', 'key2': '# value'}], - expected: 'http://domain.com?some=param&key[one]=value%201&key2=%23%20value' - } - ], - method = jQuery.mage.form._proto._buildURL, - quantity = dataProvider.length; - - expectAsserts(quantity); - for (var i = 0; i < quantity; i++) { - assertEquals(dataProvider[i].expected, method.apply(null, dataProvider[i].params)); - } -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/list/index.html b/dev/tests/js/JsTestDriver/testsuite/mage/list/index.html deleted file mode 100644 index 3d4672640bc3b..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/list/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - Unit test - - - - - - - - - - - -
    -
    - - diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/list/jquery-list-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/list/jquery-list-test.js deleted file mode 100644 index affe9f11574ef..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/list/jquery-list-test.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * @category mage.loader - * @package test - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -test('init & destroy', function() { - expect(2); - var element = $('
    '); - element.list(); - ok(element.hasClass('list-widget'), "Class added" ); - element.list('destroy'); - ok(!element.hasClass('list-widget'), "Class removed" ); -}); - -test('add to list', function() { - expect(1); - var element = $('
    '); - var button = $(''); - button.appendTo(element); - element.appendTo('body'); - var destination = $('
    '); - destination.appendTo('body'); - element.list({ - template : 'test', - templateWrapper : '
    ', - templateClass : 'fieldset' - }); - button.trigger('click'); - ok(destination.children('[data-role="addedItem"]').length, "Content is added to list"); - element.list('destroy'); - element.remove(); - destination.remove(); -}); - -test('remove from list', function() { - expect(1); - var button = $(''); - var removeButton = $('[data-button=remove]'); - var destination = $('
    '); - button.list({template: '#template',destinationSelector: '#test',listLimit: 5}); - button.trigger('click'); - removeButton.trigger('click'); - ok(!destination.children('[data-role=item]').length, "Content is removed from the list"); - button.list('destroy'); -}); diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/loader/jquery-loader-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/loader/jquery-loader-test.js deleted file mode 100644 index 174a4efc14da1..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/loader/jquery-loader-test.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -TestCase('options', function() { - expect(3); - - var element = $('
    '); - element.appendTo('body'); - element.loader(); - element.loader('show'); - equal( element.find('p').text(), 'Please wait...', '.loader() text matches' ); - equal( element.find('img').prop('src').split('/').pop(), 'icon.gif', '.loader() icons match' ); - equal( element.find('img').prop('alt'), 'Loading...', '.loader() image alt text matches' ); - element.loader('destroy'); - -}); - -TestCase( 'element init', function() { - expect(1); - - var element = $('
    '); - element.appendTo('body'); - element.loader(); - element.loader('show'); - equal(element.is(':mage-loader'), true, '.loader() init on element'); - element.loader('destroy'); - -}); - -TestCase( 'body init', function() { - expect(1); - - //Initialize Loader on Body - var body = $('body').loader(); - body.loader('show'); - equal(body.is(':mage-loader'), true, '.loader() init on body'); - body.loader('destroy'); -}); - -TestCase( 'show/hide', function() { - expect(3); - - var element = $('
    '); - element.appendTo('body'); - element.loader(); - - //Loader show - element.loader('show'); - equal($('.loading-mask').is(':visible'), true, '.loader() open'); - - //Loader hide - element.loader('hide'); - equal($('.loading-mask').is( ":hidden" ), true, '.loader() closed' ); - - //Loader hide on process complete - element.loader('show'); - element.trigger('processStop'); - equal($('.loading-mask').is('visible'), false, '.loader() closed after process'); - - element.loader('destroy'); - -}); - -TestCase( 'destroy', function() { - expect(1); - - var element = $("#loader").loader(); - element.loader('show'); - element.loader('destroy'); - equal( $('.loading-mask').is(':visible'), false, '.loader() destroyed'); - -}); diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/loader/loader-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/loader/loader-test.js deleted file mode 100644 index 3dd08f57ab8b3..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/loader/loader-test.js +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -LoaderTest = TestCase('LoaderTest'); -LoaderTest.prototype.setUp = function() { - /*:DOC +=
    */ -}; -LoaderTest.prototype.tearDown = function() { - var loaderInstance = jQuery('#loader').data('loader'); - if(loaderInstance && loaderInstance.destroy) { - loaderInstance.destroy(); - } -}; -LoaderTest.prototype.getInstance = function() { - return jQuery('#loader').data('loader'); -}; -LoaderTest.prototype.testInit = function() { - var div = jQuery('#loader').loader(); - div.loader('show'); - assertEquals(true, div.is(':mage-loader')); -}; -// @TODO Need to be fixed to avoid errors on the bamboo server in context of MAGETWO-5085 ticket -/*LoaderTest.prototype._testCreateOnBeforeSend = function() { - /*:DOC +=
    */ -/* var loader = jQuery('#loader').trigger('ajaxSend'); - assertEquals(true, loader.is(':mage-loader')); - loader.loader('destroy'); -};*/ -LoaderTest.prototype.testLoaderOnBody = function() { - var body = jQuery('body').loader(); - body.loader('show'); - assertEquals(true, jQuery('body div:first').is('.loading-mask')); - body.loader('destroy'); -}; -LoaderTest.prototype.testLoaderOnDOMElement = function() { - var div = jQuery('#loader').loader(), - loaderInstance = this.getInstance(); - div.loader('show'); - assertEquals(true, div.find(':first-child').is(loaderInstance.spinner)); -}; -LoaderTest.prototype.testLoaderOptions = function() { - /*:DOC +=
    */ - var div = jQuery('#loader').loader({ - icon: 'icon.gif', - texts: { - loaderText: 'Loader Text', - imgAlt: 'Image Alt Text' - } - }), - loaderInstance = this.getInstance(); - div.loader('show'); - assertEquals('icon.gif', loaderInstance.spinner.find('img').attr('src')); - assertEquals('Image Alt Text', loaderInstance.spinner.find('img').attr('alt')); - assertEquals('Loader Text', loaderInstance.spinner.find('div.popup-inner').text()); - div.loader('destroy'); - div.loader({ - template:'
    ' - }); - div.loader('show'); - loaderInstance = this.getInstance(); - assertEquals(true, loaderInstance.spinner.is('#test-template')); - div.loader('destroy'); -}; -LoaderTest.prototype.testHideOnComplete = function() { - /*:DOC +=
    */ - var div = jQuery('#loader').loader(); - div.loader('show'); - loaderIsVisible = jQuery('.loading-mask').is(':visible'); - div.trigger('processStop'); - assertEquals(false, jQuery('.loading-mask').is(':visible') === loaderIsVisible); -}; -LoaderTest.prototype.testRender = function() { - /*:DOC +=
    */ - var div = jQuery('#loader').loader(); - div.loader('show'); - assertEquals(true, $('.loading-mask').is(':visible')); -}; -LoaderTest.prototype.testShowHide = function() { - /*:DOC +=
    */ - var div = jQuery('#loader').loader(); - div.loader('show'); - assertEquals(true, $('.loading-mask').is(':visible')); - div.loader('hide'); - assertEquals(false, $('.loading-mask').is(':visible')); -}; -LoaderTest.prototype.testDestroy = function() { - /*:DOC +=
    */ - var div = jQuery('#loader').loader(), - loaderExist = div.is(':mage-loader'); - div.loader('destroy'); - assertEquals(false, div.is(':mage-loader') === loaderExist); -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/loader/loader.html b/dev/tests/js/JsTestDriver/testsuite/mage/loader/loader.html deleted file mode 100644 index 362dec7138276..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/loader/loader.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - Unit test - - - - - - - - - - - -
    -
    - - diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/mage-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/mage-test.js deleted file mode 100644 index 445f6619e7e35..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/mage-test.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -MageTest = TestCase('MageTest'); - -MageTest.prototype.setUp = function() { - /*:DOC += */ -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/menu/test-menu.js b/dev/tests/js/JsTestDriver/testsuite/mage/menu/test-menu.js deleted file mode 100644 index 0e1c4a3682b89..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/menu/test-menu.js +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @category mage.js - * @package test - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - - /* - Set key logger to check key press event - */ - function KeyLogger( target ) { - if ( !(this instanceof KeyLogger) ) { - return new KeyLogger( target ); - } - this.target = target; - this.log = []; - - var self = this; - - this.target.off( 'keydown' ).on( 'keydown', function( event ) { - self.log.push( event.keyCode ); - }); -} -/* - testing if menu get expanded class when option set to true - */ -test( 'Menu Expanded', function() { - expect(1); - var menu = $('#menu'); - var menuItems = menu.find('li'); - var submenu = menuItems.find('ul'); - menu.menu({ - expanded: true - }); - ok(submenu.hasClass('expanded'), 'Expanded Class added'); -}); -/* - testing if down arrow is pressed - */ -test( 'Down Arrow', function() { - expect(1); - var event, - menu = $('#menu'), - keys = KeyLogger(menu); - event = $.Event('keydown'); - event.keyCode = $.ui.keyCode.DOWN; - menu.trigger( event ); - equal( keys.log[ 0 ], 40, 'Down Arrow Was Pressed' ); -}); -/* - testing if up arrow is pressed - */ -test( 'Up Arrow', function() { - expect(1); - var event, - menu = $('#menu'), - keys = KeyLogger(menu); - event = $.Event('keydown'); - event.keyCode = $.ui.keyCode.UP; - menu.trigger( event ); - equal( keys.log[ 0 ], 38, 'Up Arrow Was Pressed' ); -}); -/* - testing if left arrow is pressed - */ -test( 'Left Arrow', function() { - expect(1); - var event, - menu = $('#menu'), - keys = KeyLogger(menu); - event = $.Event('keydown'); - event.keyCode = $.ui.keyCode.LEFT; - menu.trigger( event ); - equal( keys.log[ 0 ], 37, 'Left Arrow Was Pressed' ); -}); -/* - testing if right arrow is pressed - */ -test( 'Right Arrow', function() { - expect(1); - var event, - menu = $('#menu'), - keys = KeyLogger(menu); - event = $.Event('keydown'); - event.keyCode = $.ui.keyCode.RIGHT; - menu.trigger( event ); - equal( keys.log[ 0 ], 39, 'Right Arrow Was Pressed' ); -}); -/* - testing if max limit being set - */ -test( 'Max Limit', function() { - expect(1); - var menu = $('#menu'); - menu.navigation({ - maxItems: 3 - }); - var menuItems = menu.find('> li:visible'); - equal(menuItems.length, 4, 'Max Limit Reach'); -}); -/* - testing if responsive menu is set - */ -test( 'Responsive: More Menu', function() { - expect(1); - var menu = $('#menu'); - menu.navigation({ - responsive: 'onResize' - }); - ok($('body').find('.ui-menu.more'), 'More Menu Created'); -}); - diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/search/regular-search-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/search/regular-search-test.js deleted file mode 100644 index a79d05ba8a246..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/search/regular-search-test.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * @category mage.js - * @package test - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -//Code to be tested for /app/code/Magento/Search/view/frontend/form-mini.js (_onSubmit) -function regularSearch() { - if (this.document.getElementById('search').value === this.document.getElementById('search').placeholder || this.document.getElementById('search').value === '') { - this.document.getElementById('search').placeholder = 'Please specify at least one search term'; - this.document.getElementById('search').value = this.document.getElementById('search').placeholder; - } -} -//The test case -RegularSearchTest = TestCase("RegularSearchTest"); -RegularSearchTest.prototype.setUp = function() { - /*:DOC += -
    -
    -
    - -
    - -
    -
    - -
    - -
    */ -}; -RegularSearchTest.prototype.testRegularSearch = function(){ - //before - var inputValue = document.getElementById('search'); - assertEquals("", inputValue.value); - regularSearch(); - //after - inputValue = document.getElementById('search'); - assertEquals("Please specify at least one search term", inputValue.value); -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/suggest/suggest-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/suggest/suggest-test.js deleted file mode 100644 index 4b2b961f753ee..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/suggest/suggest-test.js +++ /dev/null @@ -1,952 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -SuggestTest = TestCase('SuggestTest'); -SuggestTest.prototype.setUp = function() { - /*:DOC += */ - this.suggestElement = jQuery('#suggest'); -}; -SuggestTest.prototype.tearDown = function() { - this.suggestDestroy(); -}; -SuggestTest.prototype.suggestDestroy = function() { - if(this.suggestElement.data('suggest')) { - this.suggestElement.suggest('destroy'); - } -}; -SuggestTest.prototype.suggestCreate = function(options, element) { - return (element || this.suggestElement).suggest(options || {} ).data('suggest'); -}; -SuggestTest.prototype.uiHash = { - item: { - id: 1, - label: 'Test Label' - } -}; - -SuggestTest.prototype.testInit = function() { - this.suggestElement.suggest(); - assertTrue(this.suggestElement.is(':mage-suggest')); -}; -SuggestTest.prototype.testCreate = function() { - var suggestOptions = { - controls: { - selector: '.test', - eventsMap: { - focus: ['testfocus'], - blur: ['testblur'], - select: ['testselect'] - } - }, - showRecent: true, - storageKey: 'jsTestDriver-test-suggest-recent', - multiselect: true - }, - recentItems = [{ - id: "1", - "label": "TestLabel1" - }, - { - id: "2", - label: "TestLabel2" - }], - setTemplateExecuted, - prepareValueFieldExecuted, - renderExecuted, - bindExecuted; - - if(window.localStorage) { - localStorage.setItem(suggestOptions.storageKey, JSON.stringify(recentItems)); - } - - var suggestInstance = this.suggestCreate(suggestOptions), - nonSelectedItem = {id: '', label: ''}; - - assertEquals(null, suggestInstance._term); - assertEquals(suggestInstance._nonSelectedItem, nonSelectedItem); - assertNull(suggestInstance._renderedContext); - assertEquals(suggestInstance._selectedItem, nonSelectedItem); - var control = suggestInstance.options.controls; - assertEquals(suggestInstance._control, control); - assertEquals(suggestInstance._recentItems, window.localStorage ? recentItems : []); - assertTrue(suggestInstance.valueField.is(':hidden')); - if(window.localStorage) { - localStorage.removeItem(suggestOptions.storageKey); - } -}; -SuggestTest.prototype.testRender = function() { - var suggestOptions = { - dropdownWrapper: '
    ', - className: 'test-suggest', - inputWrapper: '
    ' - }; - - var suggestInstance = this.suggestCreate(suggestOptions); - suggestInstance._render(); - - assertTrue(suggestInstance.dropdown.hasClass('wrapper-test')); - assertTrue(suggestInstance.dropdown.is(':hidden')); - assertTrue(suggestInstance.element.closest('.test-input-wrapper').size() > 0); - assertTrue(suggestInstance.element.closest('.' + suggestOptions.className).size() > 0); - assertEquals(suggestInstance.element.attr('autocomplete'), 'off'); - - suggestOptions.appendMethod = 'before'; - this.suggestDestroy(); - suggestInstance = this.suggestCreate(suggestOptions); - suggestInstance._render(); - assertTrue(suggestInstance.element.prev().is(suggestInstance.dropdown)); - - suggestOptions.appendMethod = 'after'; - this.suggestDestroy(); - suggestInstance = this.suggestCreate(suggestOptions); - suggestInstance._render(); - assertTrue(suggestInstance.element.next().is(suggestInstance.dropdown)); -}; -SuggestTest.prototype.testCreateValueField = function() { - var suggestInstance = this.suggestCreate(), - valueField = suggestInstance._createValueField(); - assertTrue(valueField.is('input')); - assertTrue(valueField.is(':hidden')); - this.suggestDestroy(); - - suggestInstance = this.suggestCreate({multiselect: true}); - valueField = suggestInstance._createValueField(); - assertTrue(valueField.is('select')); - assertTrue(valueField.is(':hidden')); - assertEquals(valueField.attr('multiple'), 'multiple'); -}; -SuggestTest.prototype.testPrepareValueField = function() { - var suggestInstance = this.suggestCreate(), - suggestName = this.suggestElement.attr('name'); - suggestInstance._prepareValueField(); - - assertNotUndefined(suggestInstance.valueField); - assertTrue(suggestInstance.element.prev().is(suggestInstance.valueField)); - assertUndefined(suggestInstance.element.attr('name')); - assertEquals(suggestInstance.valueField.attr('name'), suggestName); - this.suggestDestroy(); - - - var valueField = jQuery(''); - jQuery('body').append(valueField); - suggestInstance = this.suggestCreate({valueField: '#suggest-single-select-value'}); - assertTrue(suggestInstance.valueField.is(valueField)); -}; -SuggestTest.prototype.testDestroy = function() { - var suggestOptions = { - inputWrapper: '
    ', - valueField: null - }, - suggestInstance = this.suggestCreate(suggestOptions), - suggestName = suggestInstance.valueField.attr('name'); - - assertNotUndefined(suggestInstance.dropdown); - assertNotUndefined(suggestInstance.valueField); - assertUndefined(this.suggestElement.attr('name')); - - this.suggestElement.suggest('destroy'); - - assertEquals(this.suggestElement.closest('.test-input-wrapper').length, 0); - assertUndefined(this.suggestElement.attr('autocomplete')); - assertEquals(this.suggestElement.attr('name'), suggestName); - assertFalse(suggestInstance.valueField.parents('html').length > 0); - assertFalse(suggestInstance.dropdown.parents('html').length > 0); -}; -SuggestTest.prototype.testValue = function() { - var value = 'test-value'; - this.suggestElement.val(value); - jQuery('body').append('
    ' + value + '
    '); - - var suggestInputInsatnce = this.suggestCreate(), - suggestDivInsatnce = this.suggestCreate(null, jQuery('#suggest-div')); - - assertEquals(suggestInputInsatnce._value(), value); - assertEquals(suggestDivInsatnce._value(), value); -}; -SuggestTest.prototype.testProxyEvents = function() { - var fakeEvent = $.extend({}, $.Event('keydown'), { - ctrlKey: false, - keyCode: $.ui.keyCode.ENTER, - which: $.ui.keyCode.ENTER - }), - suggestInstance = this.suggestCreate({controls: {selector: null}}), - ctrlKey, - keyCode, - which; - - suggestInstance.dropdown.on('keydown', function(e) { - ctrlKey = e.ctrlKey; - keyCode = e.keyCode; - which = e.which; - }); - - suggestInstance._proxyEvents(fakeEvent); - - assertEquals(ctrlKey, fakeEvent.ctrlKey); - assertEquals(keyCode, fakeEvent.keyCode); - assertEquals(which, fakeEvent.which); -}; -SuggestTest.prototype.testBind = function() { - var eventIsBinded = false, - suggestOptions = { - events: { - click: function() { - eventIsBinded = true; - } - } - }; - this.suggestCreate(suggestOptions); - - this.suggestElement.trigger('click'); - assertTrue(eventIsBinded); -}; -SuggestTest.prototype.testChange = function() { - var changeIsTriggered, - suggestInstance = this.suggestCreate(); - - suggestInstance._term = 'changed'; - this.suggestElement.on('suggestchange', function(e) { - changeIsTriggered = true; - }); - - suggestInstance._change($.Event('click')); - assertTrue(changeIsTriggered); -}; -SuggestTest.prototype.testBindDropdown = function() { - var suggestOptions = { - controls: { - eventsMap: { - focus: ['testFocus'], - blur: ['testBlur'], - select: ['testSelect'] - } - } - }, - suggestInstance = this.suggestCreate(suggestOptions), - focusTriggered, - blurTriggered, - selectTriggered; - - suggestInstance._onSelectItem = function() { - selectTriggered = true; - }; - suggestInstance._focusItem = function() { - focusTriggered = true; - }; - suggestInstance._blurItem = function() { - blurTriggered = true; - }; - suggestInstance._bindDropdown(); - - suggestInstance.dropdown.trigger('testFocus'); - suggestInstance.dropdown.trigger('testBlur'); - suggestInstance.dropdown.trigger('testSelect'); - - assertTrue(focusTriggered); - assertTrue(blurTriggered); - assertTrue(selectTriggered); -}; -SuggestTest.prototype.testTrigger = function() { - var propogationStopped = true, - suggestInstance = this.suggestCreate(); - - this.suggestElement - .on('suggesttestevent', function() { - return false; - }); - this.suggestElement.parent().on('suggesttestevent', function() { - propogationStopped = false; - }); - suggestInstance._trigger('testevent'); - - assertTrue(propogationStopped); -}; -SuggestTest.prototype.testFocusItem = function() { - var focusUiParam = false, - suggestInstance = this.suggestCreate(); - - this.suggestElement.on('suggestfocus', function(e, ui) { - focusUiParam = ui; - }); - - assertUndefined(suggestInstance._focused); - assertEquals(suggestInstance.element.val(), ''); - - suggestInstance._focusItem($.Event('focus'), this.uiHash); - assertEquals(suggestInstance._focused, this.uiHash.item); - assertEquals(focusUiParam, this.uiHash); - assertEquals(suggestInstance.element.val(), this.uiHash.item.label); -}; -SuggestTest.prototype.testBlurItem = function() { - var suggestInstance = this.suggestCreate(); - - suggestInstance._focusItem($.Event('focus'), this.uiHash); - assertEquals(suggestInstance._focused, this.uiHash.item); - assertEquals(suggestInstance.element.val(), this.uiHash.item.label); - - suggestInstance._blurItem(); - assertNull(suggestInstance._focused); - //assertEquals(suggestInstance.element.val(), suggestInstance._term.toString()); -}; -SuggestTest.prototype.testOnSelectItem = function() { - var item = this.uiHash.item, - beforeSelect, - beforeSelectUI, - beforeSelectPropagationStopped = true, - select, - selectUI, - selectPropagationStopped = true, - suggestInstance = this.suggestCreate(); - - suggestInstance._focused = item; - this.suggestElement - .on('suggestbeforeselect', function(e, ui) { - beforeSelect = true; - beforeSelectUI = ui; - }) - .on('suggestselect', function(e, ui) { - select = true; - selectUI = ui; - }) - .parent() - .on('suggestbeforeselect', function() { - beforeSelectPropagationStopped = false; - }) - .on('suggestselect', function() { - selectPropagationStopped = false; - }); - - suggestInstance._onSelectItem($.Event('select')); - - assertTrue(beforeSelect); - assertTrue(select); - assertFalse(beforeSelectPropagationStopped); - assertFalse(selectPropagationStopped); - assertEquals(beforeSelectUI.item, item); - assertEquals(selectUI.item, item); - - beforeSelect = select = beforeSelectUI = selectUI = null; - beforeSelectPropagationStopped = selectPropagationStopped = true; - - this.suggestElement - .on('suggestbeforeselect.returnfalse', function(e, ui) { - return false; - }); - - suggestInstance._focused = item; - suggestInstance._onSelectItem($.Event('select')); - assertTrue(beforeSelect); - assertNull(select); - assertTrue(beforeSelectPropagationStopped); - assertTrue(selectPropagationStopped); - assertEquals(beforeSelectUI.item, item); - assertNull(selectUI); - - beforeSelect = select = beforeSelectUI = selectUI = null; - beforeSelectPropagationStopped = selectPropagationStopped = true; - - this.suggestElement - .off('suggestbeforeselect.returnfalse') - .on('suggestselect.returnfalse', function() { - return false; - }); - - suggestInstance._focused = item; - suggestInstance._onSelectItem($.Event('select')); - assertTrue(beforeSelect); - assertTrue(select); - assertFalse(beforeSelectPropagationStopped); - assertTrue(selectPropagationStopped); - assertEquals(beforeSelectUI.item, item); - assertEquals(selectUI.item, item); - - beforeSelect = select = beforeSelectUI = selectUI = null; - beforeSelectPropagationStopped = selectPropagationStopped = true; - - this.suggestElement.off('suggestselect.returnfalse'); - var event = $.Event('select'); - event.target = this.suggestElement[0]; - - suggestInstance._onSelectItem(event, item); - assertEquals(suggestInstance._selectedItem, item); -}; -SuggestTest.prototype.testSelectItem = function() { - var suggestInstance = this.suggestCreate(); - - suggestInstance._focused = suggestInstance._term = suggestInstance._selectedItem = null; - suggestInstance.valueField.val(''); - - suggestInstance._selectItem($.Event('select')); - assertNull(suggestInstance._selectedItem); - assertNull(suggestInstance._term); - assertEquals(suggestInstance.valueField.val(), ''); - - suggestInstance._focused = this.uiHash.item; - - suggestInstance._selectItem($.Event('select')); - assertEquals(suggestInstance._selectedItem, suggestInstance._focused); - assertEquals(suggestInstance._term, suggestInstance._focused.label); - assertEquals(suggestInstance.valueField.val(), suggestInstance._focused.id); - assertTrue(suggestInstance.dropdown.is(':hidden')); - - this.suggestDestroy(); - - var suggestOptions; - if(window.localStorage) { - suggestOptions = { - showRecent: true, - storageKey: 'jsTestDriver-test-suggest-recent' - }; - suggestInstance = this.suggestCreate(suggestOptions); - suggestInstance._focused = this.uiHash.item; - - suggestInstance._selectItem($.Event('select')); - - var storedItem = localStorage.getItem(suggestOptions.storageKey); - assertEquals(storedItem, JSON.stringify([this.uiHash.item])); - localStorage.removeItem(suggestOptions.storageKey); - } -}; -SuggestTest.prototype.testSelectItemMultiselect = function() { - var suggestInstance = this.suggestCreate({multiselect: true}); - - suggestInstance._focused = suggestInstance._term = suggestInstance._selectedItem = null; - suggestInstance.valueField.val(''); - - suggestInstance._selectItem($.Event('select')); - assertNull(suggestInstance._selectedItem); - assertNull(suggestInstance._term); - assertFalse(suggestInstance.valueField.find('option').length > 0); - assertTrue(suggestInstance.dropdown.is(':hidden')); - - suggestInstance._focused = this.uiHash.item; - var selectedElement = jQuery('
    '); - var event = $.Event('select'); - event.target = selectedElement[0]; - - suggestInstance._selectItem(event); - assertEquals(suggestInstance._selectedItem, suggestInstance._focused); - assertEquals(suggestInstance._term, ''); - assertTrue(suggestInstance._getOption(suggestInstance._focused).length > 0); - assertTrue(selectedElement.hasClass(suggestInstance.options.selectedClass)); - assertTrue(suggestInstance.dropdown.is(':hidden')); - - suggestInstance._selectItem(event); - assertEquals(suggestInstance._selectedItem, suggestInstance._nonSelectedItem); - assertFalse(suggestInstance._getOption(suggestInstance._focused).length > 0); - assertFalse(selectedElement.hasClass(suggestInstance.options.selectedClass)); - assertTrue(suggestInstance.dropdown.is(':hidden')); -}; -SuggestTest.prototype.testResetSuggestValue = function() { - var suggestInstance = this.suggestCreate(); - suggestInstance.valueField.val('test'); - suggestInstance._resetSuggestValue(); - assertEquals(suggestInstance.valueField.val(), suggestInstance._nonSelectedItem.id); -}; -SuggestTest.prototype.testResetSuggestValueMultiselect = function() { - var suggestInstance = this.suggestCreate({multiselect: true}); - suggestInstance._focused = this.uiHash.item; - var selectedElement = jQuery('
    '); - var event = $.Event('select'); - event.target = selectedElement[0]; - - suggestInstance._selectItem(event); - suggestInstance._resetSuggestValue(); - - var suggestValue = suggestInstance.valueField.val(); - assertArray(suggestValue); - assertNotUndefined(suggestValue[0]); - assertEquals(suggestValue[0], this.uiHash.item.id); -}; -SuggestTest.prototype.testReadItemData = function() { - var testElement = jQuery('
    '), - suggestInstance = this.suggestCreate(); - assertEquals(suggestInstance._readItemData(testElement), suggestInstance._nonSelectedItem); - testElement.data('suggestOption', 'test'); - assertEquals(suggestInstance._readItemData(testElement), 'test'); -}; -SuggestTest.prototype.testIsDropdownShown = function() { - var suggestInstance = this.suggestCreate(); - suggestInstance.dropdown.hide(); - assertFalse(suggestInstance.isDropdownShown()); - suggestInstance.dropdown.show(); - assertTrue(suggestInstance.isDropdownShown()); -}; -SuggestTest.prototype.testOpen = function() { - var openTriggered = false, - suggestInstance = this.suggestCreate(); - - this.suggestElement.on('suggestopen', function() { - openTriggered = true; - }); - - suggestInstance.dropdown.show(); - suggestInstance.open($.Event('open')); - assertFalse(openTriggered); - - suggestInstance.dropdown.hide(); - suggestInstance.open($.Event('open')); - assertTrue(openTriggered); - assertTrue(suggestInstance.dropdown.is(':visible')); -}; -SuggestTest.prototype.testClose = function() { - var closeTriggered = false, - suggestInstance = this.suggestCreate(); - - suggestInstance.element.val('test'); - suggestInstance._renderedContext = 'test'; - suggestInstance.dropdown.show().append('
    '); - - this.suggestElement.on('suggestclose', function() { - closeTriggered = true; - }); - - suggestInstance.close($.Event('close')); - assertNull(suggestInstance._renderedContext); - assertTrue(suggestInstance.dropdown.is(':hidden')); - assertFalse(suggestInstance.dropdown.children().length > 0); - assertTrue(closeTriggered); -}; -SuggestTest.prototype.testSetTemplate = function() { - /*:DOC += */ - var suggestInstance = this.suggestCreate({template: '
    <%= data.test %>
    '}), - tmpl, - html; - - tmpl = suggestInstance.templates[suggestInstance.templateName] - - html = jQuery('
    ').append(tmpl({ - data: { - test: 'test' - } - })).html(); - - assertEquals(html, '
    test
    '); - - suggestInstance = this.suggestCreate({ - template: '#test-template' - }); - - tmpl = suggestInstance.templates[suggestInstance.templateName]; - - html = jQuery('
    ').append(tmpl({ - data: { - test: 'test' - } - })).html(); - - assertEquals(html, '
    test
    '); -}; -SuggestTest.prototype.testSearch = function() { - var searchTriggered = false, - seachPropagationStopped = true, - suggestInstance = this.suggestCreate(); - - this.suggestElement - .on('suggestsearch', function() { - searchTriggered = true; - }) - .parent() - .on('suggestsearch', function() { - seachPropagationStopped = false; - }); - - suggestInstance._term = suggestInstance._value(); - suggestInstance._selectedItem = null; - - suggestInstance.preventBlur = true; - suggestInstance.search($.Event('search')); - - assertNull(suggestInstance._selectedItem); - assertFalse(searchTriggered); - suggestInstance.preventBlur = false; - - this.suggestElement.val('test'); - suggestInstance.search($.Event('search')); - - assertEquals(suggestInstance._term, suggestInstance._value()); - assertTrue(searchTriggered); - assertFalse(seachPropagationStopped); - - searchTriggered = false; - seachPropagationStopped = true; - suggestInstance._selectedItem = null; - suggestInstance.options.minLength = 10; - this.suggestElement.val('testtest'); - - suggestInstance.search($.Event('search')); - - assertEquals(suggestInstance._selectedItem, suggestInstance._nonSelectedItem); - assertEquals(suggestInstance.valueField.val(), suggestInstance._selectedItem.id); - assertFalse(searchTriggered); - - searchTriggered = false; - seachPropagationStopped = true; - suggestInstance._selectedItem = null; - suggestInstance.options.minLength = 1; - this.suggestElement.val('test'); - - this.suggestElement - .on('suggestsearch.returnfalse', function() { - return false; - }); - - suggestInstance.search($.Event('search')); - - assertEquals(suggestInstance._term, suggestInstance._value()); - assertTrue(searchTriggered); - assertTrue(seachPropagationStopped); -}; -SuggestTest.prototype.testUderscoreSearch = function() { - var sourceLaunched = false, - sorceTerm = null, - responceExists = false, - suggestOptions = { - source: function(term, response){ - sourceLaunched = true; - sorceTerm = term; - responceExists = (response && jQuery.type(response) === 'function'); - }, - delay: null - }, - suggestInstance = this.suggestCreate(suggestOptions); - - suggestInstance._search($.Event('search'), 'test', {}); - assertTrue(sourceLaunched); - assertEquals(sorceTerm, 'test'); - assertTrue(responceExists); - assertTrue(this.suggestElement.hasClass(suggestInstance.options.loadingClass)); - assertUndefined(suggestInstance._searchTimeout); - - suggestInstance.options.delay = 100; - suggestInstance._search($.Event('search'), 'test', {}); - assertNotUndefined(suggestInstance._searchTimeout); -}; -SuggestTest.prototype.testPrepareDropdownContext = function() { - var suggestInstance = this.suggestCreate(); - - suggestInstance._items = [this.uiHash.item]; - suggestInstance._term = 'test'; - suggestInstance._selectedItem = this.uiHash.item; - - var context = suggestInstance._prepareDropdownContext({}); - - assertEquals(context.items, suggestInstance._items); - assertEquals(context.term, suggestInstance._term); - assertEquals(context.optionData(this.uiHash.item), - 'data-suggest-option="' + JSON.stringify(this.uiHash.item).replace(/"/g, '"') + '"'); - assertTrue(context.itemSelected(this.uiHash.item)); - assertNotUndefined(context.noRecordsText); - assertFalse(context.recentShown()); - assertNotUndefined(context.recentTitle); - assertNotUndefined(context.showAllTitle); - assertFalse(context.allShown()); -}; -SuggestTest.prototype.testIsItemSelected = function() { - var suggestInstance = this.suggestCreate(); - assertFalse(suggestInstance._isItemSelected(this.uiHash.item)); - suggestInstance._selectedItem = this.uiHash.item; - assertTrue(suggestInstance._isItemSelected(this.uiHash.item)); - this.suggestDestroy(); - - suggestInstance = this.suggestCreate({multiselect: true}); - assertFalse(suggestInstance._isItemSelected(this.uiHash.item)); - suggestInstance.valueField.append(''); - assertTrue(suggestInstance._isItemSelected(this.uiHash.item)); -}; -SuggestTest.prototype.testRenderDropdown = function() { - var testContext = { - test: 'test' - }, - contentUpdatedTriggered = false, - suggestOptions = { - template: '
    <%= data.test %>
    ' - }, - suggestInstance = this.suggestCreate(suggestOptions); - - suggestInstance.dropdown.on('contentUpdated', function() { - contentUpdatedTriggered = true; - }); - suggestInstance.element.addClass(suggestInstance.options.loadingClass); - - suggestInstance._renderDropdown(null, [this.uiHash.item], testContext); - - assertEquals(suggestInstance._items, [this.uiHash.item]); - assertEquals(suggestInstance.dropdown.html(), '
    test
    '); - assertTrue(contentUpdatedTriggered); - assertEquals(suggestInstance._renderedContext, suggestInstance._prepareDropdownContext(testContext)); - assertFalse(suggestInstance.element.hasClass(suggestInstance.options.loadingClass)); - assertTrue(suggestInstance.dropdown.is(':visible')); -}; -SuggestTest.prototype.testProcessResponse = function() { - var testContext = { - test: 'test' - }, - responseTriggered = false, - suggestOptions = { - template: '
    <%= data.test %>
    ' - }, - responcePropagationStopped = true, - rendererExists, - responseData, - suggestInstance = this.suggestCreate(suggestOptions); - - this.suggestElement - .on('suggestresponse', function(e, data, renderer) { - responseTriggered = true; - rendererExists = (renderer && jQuery.type(renderer) === 'function'); - responseData = data; - }) - .parent() - .on('suggestresponse', function() { - responcePropagationStopped = false; - }); - suggestInstance._processResponse($.Event('response'), [this.uiHash.item], testContext); - - assertTrue(responseTriggered); - assertTrue(rendererExists); - assertEquals(responseData, [this.uiHash.item]); - assertFalse(responcePropagationStopped); - assertEquals(suggestInstance.dropdown.html(), '
    test
    '); - - suggestInstance.dropdown.empty(); - this.suggestElement - .on('suggestresponse.returnfalse', function() { - return false; - }); - responcePropagationStopped = true; - - suggestInstance._processResponse($.Event('response'), [this.uiHash.item], testContext); - - assertTrue(responcePropagationStopped); - assertFalse(suggestInstance.dropdown.children().tength > 0); -}; -SuggestTest.prototype.testSource = function() { - var sourceArray = [this.uiHash.item], - sourceUrl = 'www.test.url', - sourceFuncExecuted = false, - responseExecuted = false, - responseItems = null, - sourceFuncTerm = "", - sourceFuncResponse = null, - ajaxData = '', - ajaxUrl = '', - sourceFunc = function(term, response) { - sourceFuncExecuted = true; - sourceFuncTerm = term; - sourceFuncResponse = (response && jQuery.type(response) === 'function'); - }, - response = function (items) { - responseExecuted = true; - responseItems = items; - }; - - var suggestInstance = this.suggestCreate({ - source: sourceArray - }); - - suggestInstance._source('test', response); - - assertTrue(responseExecuted); - assertEquals(responseItems, sourceArray); - this.suggestDestroy(); - - responseExecuted = false; - responseItems = null; - - suggestInstance = this.suggestCreate({ - source: sourceUrl, - ajaxOptions: { - beforeSend: function(xhr, settings) { - xhr.abort(); - ajaxData = settings.data; - ajaxUrl = settings.url; - settings.success(sourceArray); - } - }, - termAjaxArgument: 'test' - }); - suggestInstance._source('test', response); - - assertTrue(responseExecuted); - assertEquals(responseItems, sourceArray); - assertEquals(ajaxData, 'test=test'); - assertEquals(ajaxUrl, sourceUrl); - this.suggestDestroy(); - - responseExecuted = false; - responseItems = null; - - suggestInstance = this.suggestCreate({ - source: sourceFunc - }); - suggestInstance._source('test', response); - - assertTrue(sourceFuncExecuted); - assertEquals(sourceFuncTerm, 'test'); - assertTrue(sourceFuncResponse); -}; -SuggestTest.prototype.testAbortSearch = function() { - var searchAborted = false, - suggestInstance = this.suggestCreate(); - - this.suggestElement.addClass(suggestInstance.options.loadingClass); - suggestInstance._xhr = { - abort: function() { - searchAborted = true; - } - }; - - suggestInstance._abortSearch(); - - assertFalse(this.suggestElement.hasClass(suggestInstance.options.loadingClass)); - assertTrue(searchAborted); -}; -SuggestTest.prototype.testShowAll = function() { - var searchAborted, - showAllTerm, - showAllContext, - suggestInstance = this.suggestCreate(); - suggestInstance._abortSearch = function() { - searchAborted = true; - }; - suggestInstance._search = function(e, term, context) { - showAllTerm = term; - showAllContext = context; - }; - - suggestInstance._showAll(jQuery.Event('showAll')); - - assertTrue(searchAborted); - assertEquals(showAllTerm, ''); - assertEquals(showAllContext, {_allShown: true}); -}; -SuggestTest.prototype.testAddRecent = function() { - var recentItems = [ - {id: 2, label: 'Test Label 2'}, - {id: 3, label: 'Test Label 3'} - ], - suggestInstance = this.suggestCreate(); - - suggestInstance._recentItems = recentItems; - suggestInstance.options.storageKey = 'jsTestDriver-test-suggest-recent'; - suggestInstance._addRecent(this.uiHash.item); - - recentItems.unshift(this.uiHash.item); - assertEquals(recentItems, suggestInstance._recentItems); - if(window.localStorage) { - assertEquals(localStorage.getItem(suggestInstance.options.storageKey), JSON.stringify(recentItems)); - } - - suggestInstance._addRecent(this.uiHash.item); - assertEquals(recentItems, suggestInstance._recentItems); - if(window.localStorage) { - assertEquals(localStorage.getItem(suggestInstance.options.storageKey), JSON.stringify(recentItems)); - } - - suggestInstance.options.storageLimit = 1; - var newRecentItem = {id: 4, label: 'Test Label 4'}; - suggestInstance._addRecent(newRecentItem); - - assertEquals([newRecentItem], suggestInstance._recentItems); - if(window.localStorage) { - assertEquals(localStorage.getItem(suggestInstance.options.storageKey), JSON.stringify([newRecentItem])); - localStorage.removeItem(suggestInstance.options.storageKey); - } -}; -SuggestTest.prototype.testRenderMultiselect = function() { - var suggestOptions = { - multiselect: true, - multiSuggestWrapper: '
    ' - }, - suggestInstance = this.suggestCreate(suggestOptions); - - assertTrue(this.suggestElement.closest('[data-role="parent-choice-element"]').is('#test-multisuggest-wrapper')); - assertTrue(suggestInstance.elementWrapper.is('#test-multisuggest-wrapper')); -}; -SuggestTest.prototype.testGetOptions = function() { - var suggestInstance = this.suggestCreate(); - - assertFalse(suggestInstance._getOptions().length > 0); - - var option = jQuery(''); - suggestInstance.valueField.append(option); - assertTrue(suggestInstance._getOptions().is(option)); -}; -SuggestTest.prototype.testFilterSelected = function() { - var items = [this.uiHash.item, {id: 2, label: 'Test Label2'}], - suggestInstance = this.suggestCreate(); - - suggestInstance.valueField.append(''); - assertEquals(suggestInstance._filterSelected(items), [this.uiHash.item]); -}; -SuggestTest.prototype.testCreateOption = function() { - var suggestInstance = this.suggestCreate(); - - var option = suggestInstance._createOption(this.uiHash.item); - assertEquals(option.val(), "1"); - assertEquals(option.prop('selected'), true); - assertEquals(option.text(), "Test Label"); - assertNotUndefined(option.data('renderedOption')); -}; -SuggestTest.prototype.testAddOption = function() { - var selectTarget = jQuery('
    '), - event = jQuery.Event('add'), - suggestInstance = this.suggestCreate(); - - event.target = selectTarget[0]; - suggestInstance._addOption(event, this.uiHash.item); - - var option = suggestInstance.valueField.find('option[value=' + this.uiHash.item.id + ']'); - assertTrue(option.length > 0); - assertTrue(option.data('selectTarget').is(selectTarget)); -}; -SuggestTest.prototype.testGetOption = function() { - var suggestInstance = this.suggestCreate(); - - assertFalse(suggestInstance._getOption(this.uiHash.item).length > 0); - - var option = jQuery(''); - suggestInstance.valueField.append(option); - assertTrue(suggestInstance._getOption(this.uiHash.item).length > 0); - assertTrue(suggestInstance._getOption(option).length > 0); -}; -SuggestTest.prototype.testRemoveLastAdded = function() { - var suggestInstance = this.suggestCreate({multiselect: true}); - - suggestInstance._addOption({}, this.uiHash.item); - assertTrue(suggestInstance.valueField.find('option').length > 0); - suggestInstance._removeLastAdded(); - assertFalse(suggestInstance.valueField.find('option').length > 0); -}; -SuggestTest.prototype.testRemoveOption = function() { - var selectTarget = jQuery('
    '), - event = jQuery.Event('select'), - suggestInstance = this.suggestCreate({multiselect: true}); - - selectTarget.addClass(suggestInstance.options.selectedClass); - event.target = selectTarget[0]; - - suggestInstance._addOption(event, this.uiHash.item); - assertTrue(suggestInstance.valueField.find('option').length > 0); - suggestInstance.removeOption(event, this.uiHash.item); - assertFalse(suggestInstance.valueField.find('option').length > 0); - assertFalse(selectTarget.hasClass(suggestInstance.options.selectedClass)); -}; -SuggestTest.prototype.testRenderOption = function() { - var suggestInstance = this.suggestCreate(), - choiceTmpl; - - suggestInstance.elementWrapper = jQuery('
    ').appendTo('body'); - - choiceTmpl = mageTemplate(suggestInstance.options.choiceTemplate, { - text: this.uiHash.item.label - }); - - var testOption = jQuery(choiceTmpl), - option = suggestInstance._renderOption(this.uiHash.item); - - assertTrue(option.next().is(suggestInstance.elementWrapper)); - assertEquals(jQuery('
    ').append(testOption).html(), jQuery('
    ').append(option).html()); -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/suggest/tree-suggest-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/suggest/tree-suggest-test.js deleted file mode 100644 index 2a63c6953ef87..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/suggest/tree-suggest-test.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -TreeSuggestTest = TestCase('TreeSuggestTest'); -TreeSuggestTest.prototype.setUp = function() { - /*:DOC += */ - this.suggestElement = jQuery('#tree-suggest'); -}; -TreeSuggestTest.prototype.tearDown = function() { - this.treeSuggestDestroy(); -}; -TreeSuggestTest.prototype.treeSuggestDestroy = function() { - if(this.suggestElement.data('treeSuggest')) { - this.suggestElement.treeSuggest('destroy'); - } -}; -TreeSuggestTest.prototype.treeSuggestCreate = function(options, element) { - return (element || this.suggestElement).treeSuggest(options || {} ).data('treeSuggest'); -}; -TreeSuggestTest.prototype.uiHash = { - item: { - id: 1, - label: 'Test Label' - } -}; -TreeSuggestTest.prototype.stub = function(instance, methodName, retVal) { - var d = $.Deferred(); - if(instance && instance[methodName]) { - instance[methodName] = function() { - d.resolve(arguments); - if(retVal) { - return retVal; - } - }; - } - return d.promise(); -}; - -TreeSuggestTest.prototype.testInit = function() { - var treeSuggestInstance = this.treeSuggestCreate(); - assertTrue(this.suggestElement.is(':mage-treeSuggest')); - assertEquals(treeSuggestInstance.widgetEventPrefix, 'suggest'); -}; - -TreeSuggestTest.prototype.testClose = function() { - var treeSuggestInstance = this.treeSuggestCreate(), - elementFocused = false; - treeSuggestInstance.element.on('focus', function() { - elementFocused = true; - }); - treeSuggestInstance.dropdown.text('test').show(); - treeSuggestInstance.close(); - assertEquals(treeSuggestInstance.dropdown.text(), ''); - assertTrue(treeSuggestInstance.dropdown.is(':hidden')); - - treeSuggestInstance.dropdown.text('test').show(); - treeSuggestInstance.close(jQuery.Event('select')); - assertEquals(treeSuggestInstance.dropdown.text(), ''); - assertTrue(treeSuggestInstance.dropdown.is(':hidden')); - - treeSuggestInstance.dropdown.text('test').show(); - treeSuggestInstance.close(jQuery.Event('select_tree_node')); - assertEquals(treeSuggestInstance.dropdown.text(), 'test'); - assertTrue(treeSuggestInstance.dropdown.is(':visible')); -}; -TreeSuggestTest.prototype.testFilterSelected = function() { - var treeSuggestInstance = this.treeSuggestCreate(); - assertEquals(treeSuggestInstance._filterSelected([this.uiHash.item], {_allShown: true}), [this.uiHash.item]); -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/tabs/index.html b/dev/tests/js/JsTestDriver/testsuite/mage/tabs/index.html deleted file mode 100644 index 30c29e38cc102..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/tabs/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - Tabs Widget: QUnit Tests - - - - - - - - - - - -
    -
    -
    - - diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/tabs/tabs-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/tabs/tabs-test.js deleted file mode 100644 index 7129357159f9f..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/tabs/tabs-test.js +++ /dev/null @@ -1,203 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -TabsTest = TestCase('TabsTest'); -TabsTest.prototype.testInit = function() { - /*:DOC +=
    */ - var tabs = jQuery('#tabs').tabs(); - assertTrue(tabs.is(':mage-tabs')); -}; - -TabsTest.prototype.testCreate = function() { - /*:DOC +=
      -
    • - -
      -
    • -
    • - -
      -
    • -
    */ - var tabs = jQuery('#tabs').tabs({active: 'tab2'}); - assertEquals(tabs.tabs('option', 'active'), tabs.data("tabs").anchors.index(jQuery('#tab2'))); -}; - -TabsTest.prototype.testActiveAnchor = function() { - /*:DOC +=
      -
    • - -
      -
    • -
    • - -
      -
    • -
    */ - var tabs = jQuery('#tabs').tabs({active: 'tab2'}); - assertTrue(tabs.tabs('activeAnchor').is(tabs.data("tabs").anchors.eq(tabs.tabs('option', 'active')))); -}; - -TabsTest.prototype.testGetTabIndex = function() { - /*:DOC +=
      -
    • - -
      -
    • -
    • - -
      -
    • -
    */ - var tabs = jQuery('#tabs').tabs(); - assertEquals(0, tabs.data("tabs")._getTabIndex('tab1')); - assertEquals(1, tabs.data("tabs")._getTabIndex('tab2')); -}; - -TabsTest.prototype.testGetPanelForTab = function() { - /*:DOC +=
      -
    • - -
    • -
    -
    -
    -
    */ - var tabs = jQuery('#tabs').tabs({destination: '#destination'}); - assertTrue(jQuery(tabs.data("tabs")._getPanelForTab(jQuery('#tab1').closest('li'))).is('#tab1_content')); -}; - -TabsTest.prototype.testMovePanelsInDestination = function() { - /*:DOC +=
      -
    • - -
      -
    • -
    -
    -
    */ - var tabs = jQuery('#tabs').tabs({destination: '#destination'}); - var panel = jQuery('#tab1_content'); - tabs.append(panel); - assertTrue(panel.parents('#tabs').length > 0); - assertEquals(panel.parents(tabs.tabs('option', 'destination')).length, 0); - - tabs.data("tabs")._movePanelsInDestination(panel); - assertEquals(panel.parents('#tabs').length, 0); - assertTrue(panel.parents(tabs.tabs('option', 'destination')).length > 0); - - tabs.tabs('option', 'destination', null); - tabs.append(panel); - assertTrue(panel.parents('#tabs').length > 0); - - tabs.data("tabs")._movePanelsInDestination(panel); - assertTrue(panel.parents('#tabs').length > 0); -}; - -TabsTest.prototype.testAjaxLoad = function() { - /*:DOC +=
    - */ - var tabs = jQuery('#tabs').tabs(), - ui = { - tab: jQuery('#tab1'), - panel: jQuery('#tab1_content') - }; - tabs.tabs('option', 'load')({}, ui); - assertEquals(jQuery('#tab1').attr('href'), '#tab1_content'); -}; - -TabsTest.prototype.testOnContentChange = function() { - /*:DOC +=
    - */ - var eventMock = { - data: { - index: 0 - } - }, - tabs = jQuery('#tabs').tabs(); - - tabs.data("tabs")._onContentChange(eventMock); - assertTrue(jQuery('#tab1').hasClass('_changed')); -}; - -TabsTest.prototype.testOnFocus = function() { - /*:DOC +=
      -
    • - -
      -
    • -
    • - -
      -
    • -
    - */ - var eventMock = { - data: { - index: 1 - } - }, - tabs = jQuery('#tabs').tabs(); - - assertNotEquals(tabs.tabs('option', '_active'), eventMock.data.index); - - tabs.data("tabs")._onFocus(eventMock); - assertEquals(tabs.tabs('option', '_active'), eventMock.data.index); -}; - -TabsTest.prototype.testOnBeforeSubmit = function() { - /*:DOC +=
      -
    • - -
      -
    • -
    - */ - var tabs = jQuery('#tabs').tabs({active: 'tab1'}), - data= {}, - testData = { - action: { - args: { - tab: 'tab1' - } - } - }, - testDataTabArgument = { - action: { - args: { - testtab: 'tab1' - } - } - }, - tabPrefix = 'test-', - tabIdArgument = 'testtab'; - - tabs.data("tabs")._onBeforeSubmit({}, data); - assertEquals(data, testData); - data = {}; - - jQuery('#tab1').prop('id', 'test-tab1'); - tabs.tabs('option', 'tabsBlockPrefix', tabPrefix); - tabs.data("tabs")._onBeforeSubmit({}, data); - assertEquals(data, testData); - tabs.tabs('option', 'tabsBlockPrefix', null); - jQuery('#test-tab1').prop('id', 'tab1'); - data = {}; - - tabs.tabs('option', 'tabIdArgument', tabIdArgument); - tabs.data("tabs")._onBeforeSubmit({}, data); - assertEquals(data, testDataTabArgument); -}; - - diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/tabs/tabs.js b/dev/tests/js/JsTestDriver/testsuite/mage/tabs/tabs.js deleted file mode 100644 index 582c55da344d3..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/tabs/tabs.js +++ /dev/null @@ -1,124 +0,0 @@ -/** - * @category mage.js - * @package test - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -/* - - */ -test( "Initialization", function() { - expect(2); - var tabs = $("
    "); - tabs.tabs(); - ok( tabs.is(':mage-tabs'), "widget instantiated" ); - tabs.tabs('destroy'); - ok( !tabs.is(':mage-tabs'), "widget destroyed" ); -}); - -test( "Collapsible instantiation", function() { - expect(2); - var tabs = $("
    "); - var title = $("
    ").attr("data-role","collapsible"); - title.appendTo(tabs); - tabs.tabs(); - ok( title.is(':mage-collapsible'), "widget instantiated" ); - tabs.tabs('destroy'); - ok( !title.is(':mage-collapsible'), "widget destroyed" ); -}); - -test( "Tabs behavior - closing others tabs when one gets activated", function() { - expect(4); - var tabs = $('
    '); - var title1 = $('
    ').appendTo(tabs); - var content1 = $('
    ').appendTo(tabs); - var title2 = $('
    ').appendTo(tabs); - var content2 = $('
    ').appendTo(tabs); - tabs.appendTo("body"); - tabs.tabs(); - ok( content1.is(':visible'), "content visible" ); - ok( content2.is(':hidden'), "content hidden" ); - title2.trigger('click'); - ok( content1.is(':hidden'), "content hidden" ); - ok( content2.is(':visible'), "content visible" ); - tabs.tabs('destroy'); -}); - -test( "Testing enable,disable,activate,deactivate options", function() { - expect(6); - var tabs = $('
    '); - var title = $('
    ').appendTo(tabs); - var content = $('
    ').appendTo(tabs); - tabs.appendTo("body"); - tabs.tabs(); - ok( content.is(':visible'), "content visible" ); - tabs.tabs("deactivate",0); - ok( content.is(':hidden'), "content hidden" ); - tabs.tabs("activate",0); - ok( content.is(':visible'), "content visible" ); - tabs.tabs("disable",0); - ok( content.is(':hidden'), "content hidden" ); - title.trigger("click"); - ok( content.is(':hidden'), "content hidden" ); - tabs.tabs("enable",0); - title.trigger("click"); - ok( content.is(':visible'), "content visible" ); - tabs.tabs('destroy'); -}); - -asyncTest( "Keyboard support for tabs view", function() { - - expect( 5 ); - var tabs = $('
    '); - var title1 = $('
    ').appendTo(tabs); - var content1 = $('
    ').appendTo(tabs); - var title2 = $('
    ').appendTo(tabs); - var content2 = $('
    ').appendTo(tabs); - tabs.appendTo("body"); - tabs.tabs(); - - title1.on("focus",function(ev){ - ok(content1.is(':visible'), "Content is expanded"); - title1.trigger($.Event( 'keydown', { keyCode: $.ui.keyCode.RIGHT } )); - ok(content2.is(':visible'), "Content is expanded"); - ok(content1.is(':hidden'), "Content is collapsed"); - title2.trigger($.Event( 'keydown', { keyCode: $.ui.keyCode.LEFT } )); - ok(content1.is(':visible'), "Content is expanded"); - ok(content2.is(':hidden'), "Content is collapsed"); - tabs.tabs('destroy'); - start(); - } ); - - setTimeout(function(){ - title1.focus(); - },10); -}); - -asyncTest( "Keyboard support for accordion view", function() { - - expect( 5 ); - var tabs = $('
    '); - var title1 = $('
    ').appendTo(tabs); - var content1 = $('
    ').appendTo(tabs); - var title2 = $('
    ').appendTo(tabs); - var content2 = $('
    ').appendTo(tabs); - tabs.appendTo("body"); - tabs.tabs({openOnFocus:false}); - - title1.on("focus",function(ev){ - ok(content1.is(':visible'), "Content is expanded"); - title1.trigger($.Event( 'keydown', { keyCode: $.ui.keyCode.RIGHT } )); - ok(content1.is(':visible'), "Content is expanded"); - ok(content2.is(':hidden'), "Content is collapsed"); - title2.trigger($.Event( 'keydown', { keyCode: $.ui.keyCode.ENTER } )); - ok(content2.is(':visible'), "Content is expanded"); - ok(content1.is(':hidden'), "Content is collapsed"); - tabs.tabs('destroy'); - start(); - } ); - - setTimeout(function(){ - title1.focus(); - },10); -}); diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/translate/translate-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/translate/translate-test.js deleted file mode 100644 index a9bbc7fb10d2d..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/translate/translate-test.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -TranslateTest = TestCase('TranslateTest'); -TranslateTest.prototype.testTranslateExist = function() { - assertNotUndefined(jQuery.mage.translate); -}; -TranslateTest.prototype.testTranslationParametersOneArgument = function() { - jQuery.mage.translate.add('Hello World!'); - assertEquals( - 'Hello World!', - jQuery.mage.translate.translate('Hello World!')); -}; -TranslateTest.prototype.testTranslationParametersArray = function() { - jQuery.mage.translate.add(['Hello World!', 'Bonjour tout le monde!']); - assertEquals( - 'Hello World!', - jQuery.mage.translate.translate('Hello World!')); -}; -TranslateTest.prototype.testTranslationParametersObject = function() { - var translation = {'Hello World!': 'Bonjour tout le monde!'}; - jQuery.mage.translate.add(translation); - assertEquals( - translation['Hello World!'], - jQuery.mage.translate.translate('Hello World!')); - - translation = { - 'Hello World!': 'Hallo Welt!', - 'Some text with symbols!-+"%#*': 'Ein Text mit Symbolen!-+"%#*' - }; - jQuery.mage.translate.add(translation); - jQuery.each(translation, function(key) { - assertEquals(translation[key], jQuery.mage.translate.translate(key)); - }); -}; -TranslateTest.prototype.testTranslationParametersTwoArguments = function() { - jQuery.mage.translate.add('Hello World!', 'Bonjour tout le monde!'); - assertEquals( - 'Bonjour tout le monde!', - jQuery.mage.translate.translate('Hello World!')); -}; -TranslateTest.prototype.testTranslationAlias = function() { - var translation = {'Hello World!': 'Bonjour tout le monde!'}; - jQuery.mage.translate.add(translation); - assertEquals(translation['Hello World!'], jQuery.mage.__('Hello World!')); -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/translate_inline/translate-inline-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/translate_inline/translate-inline-test.js deleted file mode 100644 index 18a117f1913b1..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/translate_inline/translate-inline-test.js +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -TranslateInlineTest = TestCase('TranslateInlineTest'); -TranslateInlineTest.prototype.testInit = function() { - /*:DOC += -
    - */ - var translateInline = jQuery('[data-role="translate-dialog"]').translateInline(); - assertTrue(translateInline.is(':mage-translateInline')); - translateInline.translateInline('destroy'); -}; -TranslateInlineTest.prototype.testDialogOpenOnEdit = function() { - /*:DOC += -
    - */ - var options= { - dialog: { - id: 'dialog-id' - } - }; - var translateInline = jQuery('[data-role="translate-dialog"]').translateInline(options), - isDialogHiddenOnInit = translateInline.is(':hidden'); - translateInline.trigger('edit.editTrigger'); - var dialogVisibleAfterTriggerEdit = translateInline.is(':visible'); - assertTrue(isDialogHiddenOnInit); - assertTrue(dialogVisibleAfterTriggerEdit); - translateInline.translateInline('destroy'); -}; -TranslateInlineTest.prototype.testTranslationFormTemplate = function() { - /*:DOC += -
    - */ - var options = { - translateForm: { - data:{ - id: 'translate-form-id', - newTemplateVariable: 'New Template Variable' - } - } - }, - translateInline = jQuery('[data-role="translate-dialog"]').translateInline(options); - translateInline.trigger('edit.editTrigger'); - var translateForm = jQuery('#' + options.translateForm.data.id); - assertTrue(translateForm.size() > 0); - assertEquals(translateForm.text(), options.translateForm.data.newTemplateVariable); - translateInline.translateInline('destroy'); -}; -// @TODO Need to be fixed to avoid errors on the bamboo server in context of MAGETWO-5085 ticket -/*TranslateInlineTest.prototype._testTranslateFormSubmit = function() { - FORM_KEY = 'form_key'; - var options = { - ajaxUrl: 'www.test.com', - area: 'test', - translateForm: { - template:'
    ', - data:{ - id: 'translate-form-id' - } - }, - dialog: { - id: 'dialog-id', - buttons : [{ - 'class': 'submit-button' - }] - } - }, - translateInline = jQuery(document).translateInline(options), - submit = jQuery('.ui-dialog-buttonset .submit-button'), - ajaxParametersCorrect = false; - - translateInline.trigger('edit.editTrigger'); - var parameters = jQuery.param({area: options.area}) + - '&' + jQuery('#' + options.translateForm.data.id).serialize(), - dialog = jQuery('#' + options.dialog.id), - dialogVisibleOnAjaxSend = false, - dialogHiddenAfterAjaxComplete = false; - jQuery(document) - .on('ajaxSend', function(e, jqXHR, settings){ - jqXHR.abort(); - dialogVisibleOnAjaxSend = dialog.is(':visible'); - ajaxParametersCorrect = settings.data.indexOf(parameters) >= 0; - jQuery(this).trigger('ajaxComplete'); - }); - submit.trigger('click'); - assertEquals(true, dialogVisibleOnAjaxSend); - assertEquals(true, ajaxParametersCorrect); - assertEquals(true, dialog.is(':hidden')); - translateInline.translateInline('destroy'); -};*/ -TranslateInlineTest.prototype.testDestroy = function() { - /*:DOC += -
    - - */ - var options = { - translateForm: { - data:{ - id: 'translate-form-id', - newTemplateVariable: '' - } - } - }, - translateInline = jQuery('[data-role="translate-dialog"]').translateInline(options), - editTrigger = jQuery('#edit-trigger-id').editTrigger(), - editTriggerCreated = editTrigger.size() && jQuery('#edit-trigger-id').is(':mage-editTrigger'), - editTriggerEventIsBound = false; - - assertTrue(translateInline.is(':mage-translateInline')); - assertTrue(editTriggerCreated); - translateInline.on('edit.editTrigger', function(){editTriggerEventIsBound = true;}); - translateInline.translateInline('destroy'); - translateInline.trigger('edit.editTrigger'); - assertFalse(translateInline.is(':mage-translateInline')); - assertFalse(editTriggerEventIsBound); -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/translate_inline_vde/translate-inline-vde-dialog-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/translate_inline_vde/translate-inline-vde-dialog-test.js deleted file mode 100644 index 358235eb13bf8..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/translate_inline_vde/translate-inline-vde-dialog-test.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -TranslateInlineDialogVdeTest = TestCase('TranslateInlineDialogVdeTest'); - -TranslateInlineDialogVdeTest.prototype.testInit = function() { - /*:DOC += - -
    - */ - var translateInlineDialogVde = jQuery('#translate-dialog').translateInlineDialogVde(); - assertTrue(translateInlineDialogVde.is(':mage-translateInlineDialogVde')); - translateInlineDialogVde.translateInlineDialogVde('destroy'); -}; -TranslateInlineDialogVdeTest.prototype.testWithTemplate = function() { - /*:DOC += - -
    - */ - var translateInlineDialogVde = jQuery('#translate-dialog').translateInlineDialogVde(); - assertEquals(true, translateInlineDialogVde.is(':mage-translateInlineDialogVde')); - translateInlineDialogVde.translateInlineDialogVde('destroy'); -}; -TranslateInlineDialogVdeTest.prototype.testOpenAndClose = function() { - /*:DOC += -
    - -
    - */ - var options = { - textTranslations: jQuery('[data-translate-mode="text"]'), - imageTranslations: jQuery('[data-translate-mode="alt"]'), - scriptTranslations: jQuery('[data-translate-mode="script"]') - }; - - var translateInlineDialogVde = jQuery('#translate-dialog').translateInlineDialogVde(options); - - var widget = { - element : jQuery('#randomElement') - }; - - jQuery('#translate-dialog').translateInlineDialogVde('openWithWidget', null, widget, function() { }); - assertTrue(jQuery('#translate-dialog').translateInlineDialogVde('isOpen')); - - jQuery('#translate-dialog').translateInlineDialogVde('close'); - assertFalse(jQuery('#translate-dialog').translateInlineDialogVde('isOpen')); - - jQuery('#translate-dialog').translateInlineDialogVde('destroy'); -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/translate_inline_vde/translate-inline-vde-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/translate_inline_vde/translate-inline-vde-test.js deleted file mode 100644 index 3822310460132..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/translate_inline_vde/translate-inline-vde-test.js +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -TranslateInlineVdeTest = TestCase('TranslateInlineVdeTest'); -TranslateInlineVdeTest.prototype.testInit = function() { - /*:DOC +=
    text
    - - */ - var translateInlineVde = jQuery('[data-translate]').translateInlineVde(); - assertTrue(translateInlineVde.is(':mage-translateInlineVde')); - translateInlineVde.translateInlineVde('destroy'); -}; -TranslateInlineVdeTest.prototype.testCreate = function() { - /*:DOC +=
    text
    - - */ - assertEquals(0, jQuery('[data-translate] > img').size()); - var translateInlineVde = jQuery('[data-translate]').translateInlineVde(); - assertEquals(1, jQuery('[data-translate] > img').size()); - translateInlineVde.translateInlineVde('destroy'); -}; -TranslateInlineVdeTest.prototype.testHideAndShow = function() { - /*:DOC +=
    text
    - - */ - var translateInlineVde = jQuery('[data-translate]').translateInlineVde(), - iconImg = jQuery('[data-translate] > img'); - assertFalse(iconImg.is('.hidden')); - - translateInlineVde.translateInlineVde('hide'); - assertTrue(iconImg.is('.hidden') ); - - translateInlineVde.translateInlineVde('show'); - assertFalse(iconImg.is('.hidden') ); - assertFalse(jQuery('[data-translate]').is(':hidden') ); - - translateInlineVde.translateInlineVde('destroy'); -}; -TranslateInlineVdeTest.prototype.testReplaceTextNormal = function() { - /*:DOC +=
    text
    - - */ - var translateInlineVde = jQuery('[data-translate]').translateInlineVde(); - var newValue = 'New value'; - - jQuery('[data-translate]').translateInlineVde('replaceText', 0, newValue); - - var translateData = jQuery('#translateElem').data('translate'); - assertEquals(newValue, translateData[0]['shown']); - assertEquals(newValue, translateData[0]['translated']); - - translateInlineVde.translateInlineVde('destroy'); -}; -TranslateInlineVdeTest.prototype.testReplaceTextNullOrBlank = function() { - /*:DOC +=
    text
    - - */ - var translateInlineVde = jQuery('[data-translate]').translateInlineVde(); - var newValue = null; - - jQuery('[data-translate]').translateInlineVde('replaceText', 0, newValue); - - var translateData = jQuery('#translateElem').data('translate'); - assertEquals(' ', translateData[0]['shown']); - assertEquals(' ', translateData[0]['translated']); - - newValue = 'Some value'; - jQuery('[data-translate]').translateInlineVde('replaceText', 0, newValue); - - translateData = jQuery('#translateElem').data('translate'); - assertEquals(newValue, translateData[0]['shown']); - assertEquals(newValue, translateData[0]['translated']); - - newValue = ''; - jQuery('[data-translate]').translateInlineVde('replaceText', 0, newValue); - - translateData = jQuery('#translateElem').data('translate'); - assertEquals(' ', translateData[0]['shown']); - assertEquals(' ', translateData[0]['translated']); - - translateInlineVde.translateInlineVde('destroy'); -}; -TranslateInlineVdeTest.prototype.testClick = function() { - /*:DOC +=
    text
    - - */ - var counter = 0; - var callback = function() { - counter++; - }; - var translateInlineVde = jQuery('[data-translate]').translateInlineVde({ - onClick: callback - }), - iconImg = jQuery('[data-translate] > img'); - - iconImg.trigger('click'); - assertEquals(1, counter); - assertTrue(jQuery('#translateElem').hasClass('invisible')); - - translateInlineVde.translateInlineVde('destroy'); -}; -TranslateInlineVdeTest.prototype.testDblClick = function() { - /*:DOC +=
    text
    - - */ - var counter = 0; - var callback = function() { - counter++; - }; - var translateInlineVde = jQuery('[data-translate]').translateInlineVde({ - onClick: callback - }), - iconImg = jQuery('[data-translate] > img'); - - assertEquals(1, jQuery('#translateElem').find('img').size()); - - translateInlineVde.trigger('dblclick'); - assertEquals(1, counter); - - assertEquals(0, jQuery('#translateElem').find('img').size()); - assertTrue(jQuery('#translateElem').hasClass('invisible')); - - translateInlineVde.translateInlineVde('destroy'); -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/validation/index.html b/dev/tests/js/JsTestDriver/testsuite/mage/validation/index.html deleted file mode 100644 index 00661de6d8153..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/validation/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - Validation - - - - - - - - - - - - - - - - - -
    -
    -
    - - diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/validation/test-validation.js b/dev/tests/js/JsTestDriver/testsuite/mage/validation/test-validation.js deleted file mode 100644 index 602ba4b8d3e60..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/validation/test-validation.js +++ /dev/null @@ -1,611 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -test( "testValidateNoHtmlTags", function() { - expect(4); - equal($.validator.methods['validate-no-html-tags'].call(this, ""),true); - equal($.validator.methods['validate-no-html-tags'].call(this, null),true); - equal($.validator.methods['validate-no-html-tags'].call(this, "abc"),true); - equal($.validator.methods['validate-no-html-tags'].call(this, "
    abc
    "),false); - -}); - -test( "testAllowContainerClassName", function() { - expect(4); - var radio = $(''); - radio.appendTo("#qunit-fixture"); - equal($.validator.methods['allow-container-className'].call(this, radio[0]),true); - var checkbox = $(''); - equal($.validator.methods['allow-container-className'].call(this, checkbox[0]),true); - var radio2 = $(''); - equal($.validator.methods['allow-container-className'].call(this, radio2[0]),false); - var checkbox2 = $(''); - equal($.validator.methods['allow-container-className'].call(this, checkbox2[0]),false); -}); - -test( "testValidateSelect", function() { - expect(5); - equal($.validator.methods['validate-select'].call(this, ""),false); - equal($.validator.methods['validate-select'].call(this, "none"),false); - equal($.validator.methods['validate-select'].call(this, null),false); - equal($.validator.methods['validate-select'].call(this, undefined),false); - equal($.validator.methods['validate-select'].call(this, "abc"),true); -}); - -test( "testValidateNotEmpty", function() { - expect(5); - ok(!$.validator.methods['validate-no-empty'].call(this, "")); - ok(!$.validator.methods['validate-no-empty'].call(this, null)); - ok(!$.validator.methods['validate-no-empty'].call(this, undefined)); - ok(!$.validator.methods['validate-no-empty'].call(this, " ")); - ok($.validator.methods['validate-no-empty'].call(this, "test")); -}); - -test( "testValidateStreet", function() { - expect(9); - equal($.validator.methods['validate-alphanum-with-spaces'].call(this, ""),true); - equal($.validator.methods['validate-alphanum-with-spaces'].call(this, null),true); - equal($.validator.methods['validate-alphanum-with-spaces'].call(this, undefined),true); - equal($.validator.methods['validate-alphanum-with-spaces'].call(this, " "),true); - equal($.validator.methods['validate-alphanum-with-spaces'].call(this, "abc "),true); - equal($.validator.methods['validate-alphanum-with-spaces'].call(this, " 123 "),true); - equal($.validator.methods['validate-alphanum-with-spaces'].call(this, " abc123 "),true); - equal($.validator.methods['validate-alphanum-with-spaces'].call(this, " !@# "),false); - equal($.validator.methods['validate-alphanum-with-spaces'].call(this, " abc.123 "),false); -}); - -test( "testValidatePhoneStrict", function() { - expect(9); - equal($.validator.methods['validate-phoneStrict'].call(this, ""),true); - equal($.validator.methods['validate-phoneStrict'].call(this, null),true); - equal($.validator.methods['validate-phoneStrict'].call(this, undefined),true); - equal($.validator.methods['validate-phoneStrict'].call(this, " "),false); - equal($.validator.methods['validate-phoneStrict'].call(this, "5121231234"),false); - equal($.validator.methods['validate-phoneStrict'].call(this, "512.123.1234"),false); - equal($.validator.methods['validate-phoneStrict'].call(this, "512-123-1234"),true); - equal($.validator.methods['validate-phoneStrict'].call(this, "(512)123-1234"),true); - equal($.validator.methods['validate-phoneStrict'].call(this, "(512) 123-1234"),true); -}); - -test( "testValidatePhoneLax", function() { - expect(11); - equal($.validator.methods['validate-phoneLax'].call(this, ""),true); - equal($.validator.methods['validate-phoneLax'].call(this, null),true); - equal($.validator.methods['validate-phoneLax'].call(this, undefined),true); - equal($.validator.methods['validate-phoneLax'].call(this, " "),false); - equal($.validator.methods['validate-phoneLax'].call(this, "5121231234"),true); - equal($.validator.methods['validate-phoneLax'].call(this, "512.123.1234"),true); - equal($.validator.methods['validate-phoneLax'].call(this, "512-123-1234"),true); - equal($.validator.methods['validate-phoneLax'].call(this, "(512)123-1234"),true); - equal($.validator.methods['validate-phoneLax'].call(this, "(512) 123-1234"),true); - equal($.validator.methods['validate-phoneLax'].call(this, "(512)1231234"),true); - equal($.validator.methods['validate-phoneLax'].call(this, "(512)_123_1234"),false); -}); - -test( "testValidateFax", function() { - expect(9); - equal($.validator.methods['validate-fax'].call(this, ""),true); - equal($.validator.methods['validate-fax'].call(this, null),true); - equal($.validator.methods['validate-fax'].call(this, undefined),true); - equal($.validator.methods['validate-fax'].call(this, " "),false); - equal($.validator.methods['validate-fax'].call(this, "5121231234"),false); - equal($.validator.methods['validate-fax'].call(this, "512.123.1234"),false); - equal($.validator.methods['validate-fax'].call(this, "512-123-1234"),true); - equal($.validator.methods['validate-fax'].call(this, "(512)123-1234"),true); - equal($.validator.methods['validate-fax'].call(this, "(512) 123-1234"),true); -}); - -test( "testValidateEmail", function() { - expect(11); - equal($.validator.methods['validate-email'].call(this, ""),true); - equal($.validator.methods['validate-email'].call(this, null),true); - equal($.validator.methods['validate-email'].call(this, undefined),true); - equal($.validator.methods['validate-email'].call(this, " "),false); - equal($.validator.methods['validate-email'].call(this, "123@123.com"),true); - equal($.validator.methods['validate-email'].call(this, "abc@124.en"),true); - equal($.validator.methods['validate-email'].call(this, "abc@abc.commmmm"),true); - equal($.validator.methods['validate-email'].call(this, "abc.abc.abc@abc.commmmm"),true); - equal($.validator.methods['validate-email'].call(this, "abc.abc-abc@abc.commmmm"),true); - equal($.validator.methods['validate-email'].call(this, "abc.abc_abc@abc.commmmm"),true); - equal($.validator.methods['validate-email'].call(this, "abc.abc_abc@abc"),false); -}); - -test( "testValidateEmailSender", function() { - expect(10); - equal($.validator.methods['validate-emailSender'].call(this, ""),true); - equal($.validator.methods['validate-emailSender'].call(null),true); - equal($.validator.methods['validate-emailSender'].call(undefined),true); - equal($.validator.methods['validate-emailSender'].call(" "),true); - equal($.validator.methods['validate-emailSender'].call("123@123.com"),true); - equal($.validator.methods['validate-emailSender'].call("abc@124.en"),true); - equal($.validator.methods['validate-emailSender'].call("abc@abc.commmmm"),true); - equal($.validator.methods['validate-emailSender'].call("abc.abc.abc@abc.commmmm"),true); - equal($.validator.methods['validate-emailSender'].call("abc.abc-abc@abc.commmmm"),true); - equal($.validator.methods['validate-emailSender'].call("abc.abc_abc@abc.commmmm"),true); -}); - -test( "testValidatePassword", function() { - expect(9); - equal($.validator.methods['validate-password'].call(this, ""),true); - equal($.validator.methods['validate-password'].call(this, null),false); - equal($.validator.methods['validate-password'].call(this, undefined),false); - equal($.validator.methods['validate-password'].call(this, " "),true); - equal($.validator.methods['validate-password'].call(this, "123@123.com"),true); - equal($.validator.methods['validate-password'].call(this, "abc"),false); - equal($.validator.methods['validate-password'].call(this, "abc "),false); - equal($.validator.methods['validate-password'].call(this, " abc "),false); - equal($.validator.methods['validate-password'].call(this, "dddd"),false); -}); - -test( "testValidateAdminPassword", function() { - expect(9); - equal(true, $.validator.methods['validate-admin-password'].call(this, "")); - equal(false, $.validator.methods['validate-admin-password'].call(this, null)); - equal(false, $.validator.methods['validate-admin-password'].call(this, undefined)); - equal(true, $.validator.methods['validate-admin-password'].call(this, " ")); - equal(true, $.validator.methods['validate-admin-password'].call(this, "123@123.com")); - equal(false, $.validator.methods['validate-admin-password'].call(this, "abc")); - equal(false, $.validator.methods['validate-admin-password'].call(this, "abc ")); - equal(false, $.validator.methods['validate-admin-password'].call(this, " abc ")); - equal(false, $.validator.methods['validate-admin-password'].call(this, "dddd")); -}); - -test( "testValidateUrl", function() { - expect(8); - equal(true, $.validator.methods['validate-url'].call(this, "")); - equal(true, $.validator.methods['validate-url'].call(this, null)); - equal(true, $.validator.methods['validate-url'].call(this, undefined)); - equal(false, $.validator.methods['validate-url'].call(this, " ")); - equal(true, $.validator.methods['validate-url'].call(this, "http://www.google.com")); - equal(true, $.validator.methods['validate-url'].call(this, "http://127.0.0.1:8080/index.php")); - equal(true, $.validator.methods['validate-url'].call(this, "http://app-spot.com/index.php")); - equal(true, $.validator.methods['validate-url'].call(this, "http://app-spot_space.com/index.php")); -}); - -test( "testValidateCleanUrl", function() { - expect(8); - equal(true, $.validator.methods['validate-clean-url'].call(this, "")); - equal(true, $.validator.methods['validate-clean-url'].call(this, null)); - equal(true, $.validator.methods['validate-clean-url'].call(this, undefined)); - equal(false, $.validator.methods['validate-clean-url'].call(this, " ")); - equal(true, $.validator.methods['validate-clean-url'].call(this, "http://www.google.com")); - equal(false, $.validator.methods['validate-clean-url'].call(this, "http://127.0.0.1:8080/index.php")); - equal(false, $.validator.methods['validate-clean-url'].call(this, "http://127.0.0.1:8080")); - equal(false, $.validator.methods['validate-clean-url'].call(this, "http://127.0.0.1")); -}); - -test( "testValidateXmlIdentifier", function() { - expect(8); - equal(true, $.validator.methods['validate-xml-identifier'].call(this, "")); - equal(true, $.validator.methods['validate-xml-identifier'].call(this, null)); - equal(true, $.validator.methods['validate-xml-identifier'].call(this, undefined)); - equal(false, $.validator.methods['validate-xml-identifier'].call(this, " ")); - equal(true, $.validator.methods['validate-xml-identifier'].call(this, "abc")); - equal(true, $.validator.methods['validate-xml-identifier'].call(this, "abc_123")); - equal(true, $.validator.methods['validate-xml-identifier'].call(this, "abc-123")); - equal(false, $.validator.methods['validate-xml-identifier'].call(this, "123-abc")); -}); - -test( "testValidateSsn", function() { - expect(8); - equal(true, $.validator.methods['validate-ssn'].call(this, "")); - equal(true, $.validator.methods['validate-ssn'].call(this, null)); - equal(true, $.validator.methods['validate-ssn'].call(this, undefined)); - equal(false, $.validator.methods['validate-ssn'].call(this, " ")); - equal(false, $.validator.methods['validate-ssn'].call(this, "abc")); - equal(true, $.validator.methods['validate-ssn'].call(this, "123-13-1234")); - equal(true, $.validator.methods['validate-ssn'].call(this, "012-12-1234")); - equal(false, $.validator.methods['validate-ssn'].call(this, "23-12-1234")); -}); - -test( "testValidateZip", function() { - expect(8); - equal(true, $.validator.methods['validate-zip-us'].call(this, "")); - equal(true, $.validator.methods['validate-zip-us'].call(this, null)); - equal(true, $.validator.methods['validate-zip-us'].call(this, undefined)); - equal(false, $.validator.methods['validate-zip-us'].call(this, " ")); - equal(true, $.validator.methods['validate-zip-us'].call(this, "12345-1234")); - equal(true, $.validator.methods['validate-zip-us'].call(this, "02345")); - equal(false, $.validator.methods['validate-zip-us'].call(this, "1234")); - equal(false, $.validator.methods['validate-zip-us'].call(this, "1234-1234")); -}); - -test( "testValidateDateAu", function() { - expect(8); - equal(true, $.validator.methods['validate-date-au'].call(this, "")); - equal(true, $.validator.methods['validate-date-au'].call(this, null)); - equal(true, $.validator.methods['validate-date-au'].call(this, undefined)); - equal(false, $.validator.methods['validate-date-au'].call(this, " ")); - equal(true, $.validator.methods['validate-date-au'].call(this, "01/01/2012")); - equal(true, $.validator.methods['validate-date-au'].call(this, "30/01/2012")); - equal(false, $.validator.methods['validate-date-au'].call(this, "01/30/2012")); - equal(false, $.validator.methods['validate-date-au'].call(this, "1/1/2012")); -}); - -test( "testValidateCurrencyDollar", function() { - expect(8); - equal(true, $.validator.methods['validate-currency-dollar'].call(this, "")); - equal(true, $.validator.methods['validate-currency-dollar'].call(this, null)); - equal(true, $.validator.methods['validate-currency-dollar'].call(this, undefined)); - equal(false, $.validator.methods['validate-currency-dollar'].call(this, " ")); - equal(true, $.validator.methods['validate-currency-dollar'].call(this, "$123")); - equal(true, $.validator.methods['validate-currency-dollar'].call(this, "$1,123.00")); - equal(true, $.validator.methods['validate-currency-dollar'].call(this, "$1234")); - equal(false, $.validator.methods['validate-currency-dollar'].call(this, "$1234.1234")); -}); - -test( "testValidateNotNegativeNumber", function() { - expect(11); - equal(true, $.validator.methods['validate-not-negative-number'].call(this, "")); - equal(true, $.validator.methods['validate-not-negative-number'].call(this, null)); - equal(true, $.validator.methods['validate-not-negative-number'].call(this, undefined)); - equal(false, $.validator.methods['validate-not-negative-number'].call(this, " ")); - equal(true, $.validator.methods['validate-not-negative-number'].call(this, "0")); - equal(true, $.validator.methods['validate-not-negative-number'].call(this, "1")); - equal(true, $.validator.methods['validate-not-negative-number'].call(this, "1234")); - equal(true, $.validator.methods['validate-not-negative-number'].call(this, "1,234.1234")); - equal(false, $.validator.methods['validate-not-negative-number'].call(this, "-1")); - equal(false, $.validator.methods['validate-not-negative-number'].call(this, "-1e")); - equal(false, $.validator.methods['validate-not-negative-number'].call(this, "-1,234.1234")); -}); - -test( "testValidateGreaterThanZero", function() { - expect(11); - equal(true, $.validator.methods['validate-greater-than-zero'].call(this, "")); - equal(true, $.validator.methods['validate-greater-than-zero'].call(this, null)); - equal(true, $.validator.methods['validate-greater-than-zero'].call(this, undefined)); - equal(false, $.validator.methods['validate-greater-than-zero'].call(this, " ")); - equal(false, $.validator.methods['validate-greater-than-zero'].call(this, "0")); - equal(true, $.validator.methods['validate-greater-than-zero'].call(this, "1")); - equal(true, $.validator.methods['validate-greater-than-zero'].call(this, "1234")); - equal(true, $.validator.methods['validate-greater-than-zero'].call(this, "1,234.1234")); - equal(false, $.validator.methods['validate-greater-than-zero'].call(this, "-1")); - equal(false, $.validator.methods['validate-greater-than-zero'].call(this, "-1e")); - equal(false, $.validator.methods['validate-greater-than-zero'].call(this, "-1,234.1234")); -}); - -test( "testValidateCssLength", function() { - expect(11); - equal(true, $.validator.methods['validate-css-length'].call(this, "")); - equal(true, $.validator.methods['validate-css-length'].call(this, null)); - equal(true, $.validator.methods['validate-css-length'].call(this, undefined)); - equal(false, $.validator.methods['validate-css-length'].call(this, " ")); - equal(false, $.validator.methods['validate-css-length'].call(this, "0")); - equal(true, $.validator.methods['validate-css-length'].call(this, "1")); - equal(true, $.validator.methods['validate-css-length'].call(this, "1234")); - equal(true, $.validator.methods['validate-css-length'].call(this, "1,234.1234")); - equal(false, $.validator.methods['validate-css-length'].call(this, "-1")); - equal(false, $.validator.methods['validate-css-length'].call(this, "-1e")); - equal(false, $.validator.methods['validate-css-length'].call(this, "-1,234.1234")); -}); - -test( "testValidateData", function() { - expect(9); - equal(true, $.validator.methods['validate-data'].call(this, "")); - equal(true, $.validator.methods['validate-data'].call(this, null)); - equal(true, $.validator.methods['validate-data'].call(this, undefined)); - equal(false, $.validator.methods['validate-data'].call(this, " ")); - equal(false, $.validator.methods['validate-data'].call(this, "123abc")); - equal(true, $.validator.methods['validate-data'].call(this, "abc")); - equal(false, $.validator.methods['validate-data'].call(this, " abc")); - equal(true, $.validator.methods['validate-data'].call(this, "abc123")); - equal(false, $.validator.methods['validate-data'].call(this, "abc-123")); -}); - - -test( "testValidateOneRequiredByName", function() { - expect(4); - var radio = $(''); - radio.appendTo("#qunit-fixture"); - ok(!$.validator.methods['validate-one-required-by-name'].call(this, - null, radio[0])); - var radio2 = $(''); - radio2.appendTo("#qunit-fixture"); - ok($.validator.methods['validate-one-required-by-name'].call(this, - null, radio2[0])); - - var checkbox = $(''); - checkbox.appendTo("#qunit-fixture"); - ok(!$.validator.methods['validate-one-required-by-name'].call(this, - null, checkbox[0])); - var checkbox2 = $(''); - checkbox2.appendTo("#qunit-fixture"); - ok($.validator.methods['validate-one-required-by-name'].call(this, - null, checkbox2[0])); -}); - -test( "testLessThanEqualsTo", function() { - expect(5); - var elm1 = $(''); - var elm2 = $(''); - ok(!$.validator.methods['less-than-equals-to'].call(this, elm1[0].value, - elm1, elm2)); - elm1[0].value = 4; - ok($.validator.methods['less-than-equals-to'].call(this, elm1[0].value, - elm1, elm2)); - - var elm3 = $(''); - var elm4= $(''); - ok($.validator.methods['less-than-equals-to'].call(this, elm3[0].value, - elm3, elm4)); - - var elm5 = $(''); - var elm6= $(''); - ok($.validator.methods['less-than-equals-to'].call(this, elm5[0].value, - elm5, elm6)); - - var elm7 = $(''); - var elm8= $(''); - ok($.validator.methods['less-than-equals-to'].call(this, elm7[0].value, - elm7, elm8)); -}); - -test( "testGreaterThanEqualsTo", function() { - expect(5); - - var elm1 = $(''); - var elm2 = $(''); - ok(!$.validator.methods['greater-than-equals-to'].call(this, elm1[0].value, - elm1, elm2)); - elm1[0].value = 9; - ok($.validator.methods['greater-than-equals-to'].call(this, elm1[0].value, - elm1, elm2)); - - var elm3 = $(''); - var elm4= $(''); - ok($.validator.methods['greater-than-equals-to'].call(this, elm3[0].value, - elm3, elm4)); - - var elm5 = $(''); - var elm6= $(''); - ok($.validator.methods['greater-than-equals-to'].call(this, elm5[0].value, - elm5, elm6)); - - var elm7 = $(''); - var elm8= $(''); - ok($.validator.methods['greater-than-equals-to'].call(this, elm7[0].value, - elm7, elm8)); -}); - -test( "testValidateGroupedQty", function() { - expect(5); - var div1 = $('
    '); - $('').attr("data-validate","{'validate-grouped-qty':'#super-product-table'}") - .appendTo(div1); - $('').attr("data-validate","{'validate-grouped-qty':'#super-product-table'}") - .appendTo(div1); - $('').appendTo(div1); - - ok(!$.validator.methods['validate-grouped-qty'].call(this, null, null, div1[0])); - - var div2 = $('
    '); - $('').attr("data-validate","{'validate-grouped-qty':'#super-product-table'}") - .appendTo(div2); - $('').attr("data-validate","{'validate-grouped-qty':'#super-product-table'}") - .appendTo(div2); - $('').appendTo(div2); - ok(!$.validator.methods['validate-grouped-qty'].call(this, null, null, div2[0])); - - var div3 = $('
    '); - $('').attr("data-validate","{'validate-grouped-qty':'#super-product-table'}") - .appendTo(div3); - $('').attr("data-validate","{'validate-grouped-qty':'#super-product-table'}") - .appendTo(div3); - $('').appendTo(div3); - ok(!$.validator.methods['validate-grouped-qty'].call(this, null, null, div3[0])); - - var div4 = $('
    '); - $('').attr("data-validate","{'validate-grouped-qty':'#super-product-table'}") - .appendTo(div4); - $('').attr("data-validate","{'validate-grouped-qty':'#super-product-table'}") - .appendTo(div4); - $('').appendTo(div4); - ok($.validator.methods['validate-grouped-qty'].call(this, null, null, div4[0])); - - var div5 = $('
    '); - $('').attr("data-validate","{'validate-grouped-qty':'#super-product-table'}") - .appendTo(div5); - $('').attr("data-validate","{'validate-grouped-qty':'#super-product-table'}") - .appendTo(div5); - $('').appendTo(div5); - ok($.validator.methods['validate-grouped-qty'].call(this, null, null, div5[0])); - -}); - -test( "testValidateCCTypeSelect", function() { - expect(14); - var visaValid = $(''); - var visaInvalid = $(''); - var mcValid = $(''); - var mcInvalid = $(''); - var aeValid = $(''); - var aeInvalid = $(''); - - var diValid = $(''); - var diInvalid = $(''); - var dnValid = $(''); - var dnInvalid = $(''); - var jcbValid = $(''); - var jcbInvalid = $(''); - var upValid = $(''); - var upInvalid = $(''); - - ok($.validator.methods['validate-cc-type-select'].call(this, 'VI', null, visaValid)); - ok(!$.validator.methods['validate-cc-type-select'].call(this, 'VI', null, visaInvalid)); - ok($.validator.methods['validate-cc-type-select'].call(this, 'MC', null, mcValid)); - ok(!$.validator.methods['validate-cc-type-select'].call(this, 'MC', null, mcInvalid)); - ok($.validator.methods['validate-cc-type-select'].call(this, 'AE', null, aeValid)); - ok(!$.validator.methods['validate-cc-type-select'].call(this, 'AE', null, aeInvalid)); - ok($.validator.methods['validate-cc-type-select'].call(this, 'DI', null, diValid)); - ok(!$.validator.methods['validate-cc-type-select'].call(this, 'DI', null, diInvalid)); - ok($.validator.methods['validate-cc-type-select'].call(this, 'DN', null, dnValid)); - ok(!$.validator.methods['validate-cc-type-select'].call(this, 'DN', null, dnInvalid)); - ok($.validator.methods['validate-cc-type-select'].call(this, 'JCB', null, jcbValid)); - ok(!$.validator.methods['validate-cc-type-select'].call(this, 'JCB', null, jcbInvalid)); - ok($.validator.methods['validate-cc-type-select'].call(this, 'UP', null, upValid)); - ok(!$.validator.methods['validate-cc-type-select'].call(this, 'UP', null, upInvalid)); -}); - -test( "testValidateCCNumber", function() { - expect(37); - ok($.validator.methods['validate-cc-number'].call(this, '4916835098995909', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '5265071363284878', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '6011120623356953', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '371293266574617', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '4916835098995901', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '5265071363284870', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '6011120623356951', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '371293266574619', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '2221220000000003', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '2721220000000008', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '601109020000000003', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '6011111144444444', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '6011222233334444', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '6011522233334447', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '601174455555553', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '6011745555555550', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '601177455555556', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '601182455555556', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '601187999555558', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '601287999555556', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '6444444444444443', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '6644444444444441', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '3044444444444444', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '3064444444444449', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '3095444444444442', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '3096444444444441', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '3696444444444445', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '3796444444444444', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '3896444444444443', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '3528444444444449', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '3529444444444448', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '6221262244444440', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '6229981111111111', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '6249981111111117', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '6279981111111110', null, null)); - ok($.validator.methods['validate-cc-number'].call(this, '6282981111111115', null, null)); - ok(!$.validator.methods['validate-cc-number'].call(this, '6289981111111118', null, null)); -}); - -test( "testValidateCCType", function() { - expect(14); - var select = $(''); - - select.val('VI'); - ok($.validator.methods['validate-cc-type'].call(this, '4916835098995909', null, select)); - ok(!$.validator.methods['validate-cc-type'].call(this, '5265071363284878', null, select)); - select.val('MC'); - ok($.validator.methods['validate-cc-type'].call(this, '5265071363284878', null, select)); - ok(!$.validator.methods['validate-cc-type'].call(this, '4916835098995909', null, select)); - select.val('AE'); - ok($.validator.methods['validate-cc-type'].call(this, '371293266574617', null, select)); - ok(!$.validator.methods['validate-cc-type'].call(this, '5265071363284878', null, select)); - select.val('DI'); - ok($.validator.methods['validate-cc-type'].call(this, '6011050000000009', null, select)); - ok(!$.validator.methods['validate-cc-type'].call(this, '371293266574617', null, select)); - select.val('DN'); - ok($.validator.methods['validate-cc-type'].call(this, '3095434000000001', null, select)); - ok(!$.validator.methods['validate-cc-type'].call(this, '6011050000000009', null, select)); - select.val('JCB'); - ok($.validator.methods['validate-cc-type'].call(this, '3528000000000007', null, select)); - ok(!$.validator.methods['validate-cc-type'].call(this, '3095434000000001', null, select)); - select.val('UP'); - ok($.validator.methods['validate-cc-type'].call(this, '6221260000000000', null, select)); - ok(!$.validator.methods['validate-cc-type'].call(this, '3528000000000007', null, select)); -}); - -test( "testValidateCCExp", function() { - expect(3); - var year = $(''), - currentTime = new Date(), - currentMonth = currentTime.getMonth() + 1, - currentYear = currentTime.getFullYear(); - year.val(currentYear); - if (currentMonth > 1) { - ok(!$.validator.methods['validate-cc-exp'].call(this, currentMonth - 1, null, year)); - } - ok($.validator.methods['validate-cc-exp'].call(this, currentMonth, null, year)); - year.val(currentYear + 1); - ok($.validator.methods['validate-cc-exp'].call(this, currentMonth, null, year)); - -}); - -test( "testValidateCCCvn", function() { - expect(8); - var ccType = $(''); - - ccType.val('VI'); - ok($.validator.methods['validate-cc-cvn'].call(this, '123', null, ccType)); - ok(!$.validator.methods['validate-cc-cvn'].call(this, '1234', null, ccType)); - ccType.val('MC'); - ok($.validator.methods['validate-cc-cvn'].call(this, '123', null, ccType)); - ok(!$.validator.methods['validate-cc-cvn'].call(this, '1234', null, ccType)); - ccType.val('AE'); - ok($.validator.methods['validate-cc-cvn'].call(this, '1234', null, ccType)); - ok(!$.validator.methods['validate-cc-cvn'].call(this, '123', null, ccType)); - ccType.val('DI'); - ok($.validator.methods['validate-cc-cvn'].call(this, '123', null, ccType)); - ok(!$.validator.methods['validate-cc-cvn'].call(this, '1234', null, ccType)); -}); - -test( "testValidateNumberRange", function() { - expect(14); - ok($.validator.methods['validate-number-range'].call(this, '-1', null, null)); - ok($.validator.methods['validate-number-range'].call(this, '1', null, null)); - ok($.validator.methods['validate-number-range'].call(this, '', null, null)); - ok($.validator.methods['validate-number-range'].call(this, null, null, null)); - ok($.validator.methods['validate-number-range'].call(this, '0', null, null)); - ok(!$.validator.methods['validate-number-range'].call(this, 'asds', null, null)); - - ok($.validator.methods['validate-number-range'].call(this, '10', null, '10-20.06')); - ok($.validator.methods['validate-number-range'].call(this, '15', null, '10-20.06')); - ok(!$.validator.methods['validate-number-range'].call(this, '1', null, '10-20.06')); - ok(!$.validator.methods['validate-number-range'].call(this, '30', null, '10-20.06')); - - var el1 = $('').get(0); - ok($.validator.methods['validate-number-range'].call(this, '10', el1, null)); - ok($.validator.methods['validate-number-range'].call(this, '15', el1, null)); - ok(!$.validator.methods['validate-number-range'].call(this, '1', el1, null)); - ok($.validator.methods['validate-number-range'].call(this, '30', el1, null)); -}); - - - -test( "testValidateDigitsRange", function() { - expect(15); - ok($.validator.methods['validate-digits-range'].call(this, '-1', null, null)); - ok($.validator.methods['validate-digits-range'].call(this, '1', null, null)); - ok($.validator.methods['validate-digits-range'].call(this, '', null, null)); - ok($.validator.methods['validate-digits-range'].call(this, null, null, null)); - ok($.validator.methods['validate-digits-range'].call(this, '0', null, null)); - ok(!$.validator.methods['validate-digits-range'].call(this, 'asds', null, null)); - - ok($.validator.methods['validate-digits-range'].call(this, '10', null, '10-20')); - ok($.validator.methods['validate-digits-range'].call(this, '15', null, '10-20')); - ok(!$.validator.methods['validate-digits-range'].call(this, '1', null, '10-20')); - ok(!$.validator.methods['validate-digits-range'].call(this, '30', null, '10-20')); - ok($.validator.methods['validate-digits-range'].call(this, '30', null, '10-20.06')); - - var el1 = $('').get(0); - ok($.validator.methods['validate-digits-range'].call(this, '10', el1, null)); - ok($.validator.methods['validate-digits-range'].call(this, '15', el1, null)); - ok(!$.validator.methods['validate-digits-range'].call(this, '1', el1, null)); - ok(!$.validator.methods['validate-digits-range'].call(this, '30', el1, null)); -}); diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/webapi-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/webapi-test.js deleted file mode 100644 index b03b3bc3d889a..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/webapi-test.js +++ /dev/null @@ -1,121 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -WebapiTest = TestCase('WebapiTest'); - -WebapiTest.prototype.testConstructorSuccess = function() { - var successCallback = function(){}; - new $.mage.Webapi('baseUrl', {'timeout': 100, 'success': successCallback}); -}; - -WebapiTest.prototype.testConstructorSuccessEmptyArgs = function() { - new $.mage.Webapi('baseUrl'); -}; - -WebapiTest.prototype.testConstructorInvalidBaseUrl = function() { - expectAsserts(1); - try { - var invalidBaseUrl = 1; - new $.mage.Webapi(invalidBaseUrl); - } catch (e) { - var expectedException = "String baseUrl parameter required"; - assertEquals("Invalid exception was thrown.", expectedException, e); - } -}; - -WebapiTest.prototype.testCallInvalidMethod = function() { - var Webapi = new $.mage.Webapi('baseUrl'); - expectAsserts(1); - try { - Webapi.call('resourceUri', 'INVALID_HTTP_METHOD'); - } catch (e) { - var expectedException = "Method name is not valid: INVALID_HTTP_METHOD"; - assertEquals("Invalid exception was thrown.", expectedException, e); - } -}; - -WebapiTest.prototype.testCallSuccessCallback = function() { - // ensure that custom successCallback was executed - expectAsserts(1); - var successCallback = function(response) { - assertObject("Response is expected to be an object", response); - }; - var Webapi = new $.mage.Webapi('baseUrl', {'success': successCallback}); - $.ajax = function(settings) { - settings.success({}); - }; - Webapi.call('products', 'GET'); -}; - -WebapiTest.prototype.testCallErrorCallback = function() { - // ensure that custom successCallback was executed - expectAsserts(1); - var errorCallback = function(response) { - assertObject("Response is expected to be an object", response); - }; - var Webapi = new $.mage.Webapi('baseUrl', {'error': errorCallback}); - $.ajax = function(settings) { - settings.error({}); - }; - Webapi.call('products', 'GET'); -}; - -WebapiTest.prototype.testCallProductGet = function() { - var baseUri = 'baseUrl'; - var Webapi = new $.mage.Webapi(baseUri); - var httpMethod = Webapi.method.get; - var idObj = {id: 1}; - var productResourceUri = '/products/'; - var resourceVersion = 'v1'; - var expectedUri = baseUri + '/webapi/rest/' + resourceVersion + productResourceUri + '1'; - // ensure that $.ajax() was executed - expectAsserts(3); - $.ajax = function(settings) { - assertEquals("URI for API call does not match with expected one.", expectedUri, settings.url); - assertEquals("HTTP method for API call does not match with expected one.", httpMethod, settings.type); - assertEquals("Data for API call does not match with expected one.", '1', settings.data); - }; - Webapi.Product(resourceVersion).get(idObj); -}; - -WebapiTest.prototype.testCallProductCreate = function() { - var baseUri = 'baseUrl'; - var Webapi = new $.mage.Webapi(baseUri); - var httpMethod = Webapi.method.create; - var productResourceUri = '/products/'; - var resourceVersion = 'v1'; - var expectedUri = baseUri + '/webapi/rest/' + resourceVersion + productResourceUri; - productData = { - "type_id": "simple", - "attribute_set_id": 4, - "sku": "1234567890", - "weight": 1, - "status": 1, - "visibility": 4, - "name": "Simple Product", - "description": "Simple Description", - "price": 99.95, - "tax_class_id": 0 - }; - // ensure that $.ajax() was executed - expectAsserts(3); - $.ajax = function(settings) { - assertEquals("URI for API call does not match with expected one.", expectedUri, settings.url); - assertEquals("HTTP method for API call does not match with expected one.", httpMethod, settings.type); - assertEquals("Data for API call does not match with expected one.", productData, settings.data); - }; - Webapi.Product(resourceVersion).create(productData); -}; - -WebapiTest.prototype.testCallProductCreateInvalidVersion = function() { - expectAsserts(1); - var invalidVersion = 'invalidVersion'; - try { - var Webapi = new $.mage.Webapi('BaseUrl'); - Webapi.Product(invalidVersion); - } catch (e) { - var expectedException = "Incorrect version format: " + invalidVersion; - assertEquals("Invalid exception was thrown.", expectedException, e); - } -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/zoom/zoom-test.js b/dev/tests/js/JsTestDriver/testsuite/mage/zoom/zoom-test.js deleted file mode 100644 index a9dc0fd239a28..0000000000000 --- a/dev/tests/js/JsTestDriver/testsuite/mage/zoom/zoom-test.js +++ /dev/null @@ -1,337 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -ZoomTest = TestCase('ZoomTest'); -ZoomTest.prototype.setUp = function() { - /*:DOC += - - - - - -
    - -
    - */ - this.zoomElement = jQuery('[data-role=zoom-test]'); -}; -ZoomTest.prototype.tearDown = function() { - this.zoomDestroy(); -}; -ZoomTest.prototype.zoomDestroy = function() { - if(this.zoomElement.data('zoom')) { - this.zoomElement.zoom('destroy'); - } -}; -ZoomTest.prototype.zoomCreate = function(options, element) { - return (element || this.zoomElement).zoom(options || {} ).data('zoom'); -}; -ZoomTest.prototype.testInit = function() { - this.zoomElement.zoom(); - assertTrue(this.zoomElement.is(':mage-zoom')); -}; -ZoomTest.prototype.testCreate = function() { - var zoomInstance = this.zoomCreate(), - _setZoomData = jsunit.stub(zoomInstance, '_setZoomData'), - _render = jsunit.stub(zoomInstance, '_render'), - _bind = jsunit.stub(zoomInstance, '_bind'), - _hide = jsunit.stub(zoomInstance, '_hide'), - _largeImageLoaded = jsunit.stub(zoomInstance, '_largeImageLoaded'); - - zoomInstance.largeImage = [{ - complete: false - }]; - - zoomInstance._create(); - assertTrue(_setZoomData.callCount === 1); - assertTrue(_render.callCount === 1); - assertTrue(_bind.callCount === 1); - assertNull(_largeImageLoaded.callCount); - assertTrue(_hide.callCount === 2); - _setZoomData.reset(); - _render.reset(); - _bind.reset(); - _hide.reset(); - - zoomInstance.largeImage[0].complete = true; - zoomInstance._create(); - assertTrue(_setZoomData.callCount === 1); - assertTrue(_render.callCount === 1); - assertTrue(_bind.callCount === 1); - assertTrue(_largeImageLoaded.callCount === 1); - assertTrue(_hide.callCount === 2); -}; -ZoomTest.prototype.testRender = function() { - var zoomInstance = this.zoomCreate(), - _renderControl = jsunit.stub(zoomInstance, '_renderControl'), - _renderLargeImage = jsunit.stub(zoomInstance, '_renderLargeImage'); - _renderControl.returnCallback = function(control) { - return jQuery('

    ', {'data-control': control}); - }; - - zoomInstance._render(); - assertTrue(_renderControl.callCount === 4); - assertTrue(zoomInstance.element.find('[data-control=track]').length > 0); - assertTrue(zoomInstance.element.find('[data-control=lens]').length > 0); - assertTrue(zoomInstance.element.find('[data-control=display]').length > 0); - assertTrue(zoomInstance.element.find('[data-control=notice]').length > 0); - assertTrue(_renderLargeImage.callCount === 1); -}; -ZoomTest.prototype.testToggleNotice = function() { - var zoomInstance = this.zoomCreate(), - getZoomRatio = jsunit.stub(zoomInstance, 'getZoomRatio'); - - zoomInstance.noticeOriginal = 'notice original'; - zoomInstance.options.controls.notice = { - text: 'test text' - }; - - zoomInstance.notice.text(''); - zoomInstance.largeImageSrc = 'image.large.jpg'; - zoomInstance.activated = false; - getZoomRatio.returnValue = 2; - zoomInstance._toggleNotice(); - assertEquals(zoomInstance.notice.text(), zoomInstance.options.controls.notice.text); - assertTrue(getZoomRatio.callCount === 1); - - zoomInstance.notice.text(''); - zoomInstance.largeImageSrc = null; - zoomInstance.activated = false; - getZoomRatio.returnValue = 2; - zoomInstance._toggleNotice(); - assertEquals(zoomInstance.notice.text(), zoomInstance.noticeOriginal); - - zoomInstance.notice.text(''); - zoomInstance.largeImageSrc = 'image.large.jpg'; - zoomInstance.activated = true; - getZoomRatio.returnValue = 2; - zoomInstance._toggleNotice(); - assertEquals(zoomInstance.notice.text(), zoomInstance.noticeOriginal); - - zoomInstance.notice.text(''); - zoomInstance.largeImageSrc = 'image.large.jpg'; - zoomInstance.activated = false; - getZoomRatio.returnValue = 0; - zoomInstance._toggleNotice(); - assertEquals(zoomInstance.notice.text(), zoomInstance.noticeOriginal); -}; - -ZoomTest.prototype.testRefresh = function() { - var zoomInstance = this.zoomCreate(), - _refreshControl = jsunit.stub(zoomInstance, '_refreshControl'); - - zoomInstance._refresh(); - assertTrue(_refreshControl.callCount === 3); - assertTrue(_refreshControl.callArgsStack[0][0] === 'display'); - assertTrue(_refreshControl.callArgsStack[1][0] === 'track'); - assertTrue(_refreshControl.callArgsStack[2][0] === 'lens'); -}; - -ZoomTest.prototype.testBind = function() { - var zoomInstance = this.zoomCreate(), - _on = jsunit.stub(zoomInstance, '_on'), - events = {}; - - zoomInstance.largeImage = jQuery('

    '); - zoomInstance._bind(); - assertTrue(_on.callCount > 0); - assertTrue( - _on.callArgsStack[0][0][ - zoomInstance.options.startZoomEvent + - ' ' + - zoomInstance.options.selectors.image - ] === 'show' - ); - assertTrue( - jQuery.type(_on.callArgsStack[0][0][ - zoomInstance.options.stopZoomEvent + - ' ' + - zoomInstance.options.selectors.track - ]) === 'function' - ); - assertTrue(_on.callArgsStack[0][0]['mousemove ' + zoomInstance.options.selectors.track] === '_move'); - assertTrue(_on.callArgsStack[0][0].imageupdated === '_onImageUpdated'); - assertTrue(_on.callArgsStack[1][0].is(zoomInstance.largeImage)); - assertTrue(_on.callArgsStack[1][1].load === '_largeImageLoaded'); -}; -ZoomTest.prototype.testEnable = function() { - var zoomInstance = this.zoomCreate(), - _onImageUpdated = jsunit.stub(zoomInstance, '_onImageUpdated'); - - zoomInstance.enable(); - assertTrue(_onImageUpdated.callCount === 1); -}; -ZoomTest.prototype.testDisable = function() { - var zoomInstance = this.zoomCreate(); - - zoomInstance.noticeOriginal = 'original notice'; - zoomInstance.notice.text(''); - zoomInstance.disable(); - assertEquals(zoomInstance.noticeOriginal, zoomInstance.notice.text()); -}; -ZoomTest.prototype.testShow = function() { - var zoomInstance = this.zoomCreate(), - e = { - preventDefault: jsunit.stub(), - stopImmediatePropagation: jsunit.stub() - }, - getZoomRatio = jsunit.stub(zoomInstance, 'getZoomRatio'), - _show = jsunit.stub(zoomInstance, '_show'), - _refresh = jsunit.stub(zoomInstance, '_refresh'), - _toggleNotice = jsunit.stub(zoomInstance, '_toggleNotice'), - _trigger = jsunit.stub(zoomInstance, '_trigger'); - - getZoomRatio.returnValue = 0; - zoomInstance.show(e); - assertTrue(e.preventDefault.callCount === 1); - - e.preventDefault.reset(); - getZoomRatio.reset(); - getZoomRatio.returnValue = 2; - zoomInstance.largeImageSrc = 'image.large.jpg'; - zoomInstance.show(e); - assertTrue(e.preventDefault.callCount === 1); - assertTrue(e.stopImmediatePropagation.callCount === 1); - assertTrue(zoomInstance.activated); - assertTrue(_show.callCount > 0); - assertTrue(_refresh.callCount === 1); - assertTrue(_toggleNotice.callCount === 1); - assertTrue(_trigger.callCount === 1); - assertTrue(_trigger.lastCallArgs[0] === 'show'); -}; -ZoomTest.prototype.testHide = function() { - var zoomInstance = this.zoomCreate(), - _hide = jsunit.stub(zoomInstance, '_hide'), - _toggleNotice = jsunit.stub(zoomInstance, '_toggleNotice'), - _trigger = jsunit.stub(zoomInstance, '_trigger'); - - zoomInstance.hide(); - assertTrue(_hide.callCount > 0); - assertTrue(_toggleNotice.callCount === 1); - assertTrue(_trigger.callCount === 1); - assertTrue(_trigger.lastCallArgs[0] === 'hide'); -}; -ZoomTest.prototype.testOnImageUpdated = function() { - var zoomInstance = this.zoomCreate(), - _setZoomData = jsunit.stub(zoomInstance, '_setZoomData'), - _refreshLargeImage = jsunit.stub(zoomInstance, '_refreshLargeImage'), - _refresh = jsunit.stub(zoomInstance, '_refresh'), - hide = jsunit.stub(zoomInstance, 'hide'), - testImage = jQuery('

    '); - - zoomInstance.options.selectors.image = "[data-role=test-image]"; - zoomInstance.element.append(testImage); - zoomInstance.image = testImage; - zoomInstance._onImageUpdated(); - assertNull(_setZoomData.callCount); - assertNull(_refreshLargeImage.callCount); - assertNull(_refresh.callCount); - assertNull(hide.callCount); - - zoomInstance.image = jQuery('

    '); - zoomInstance.largeImageSrc = null; - zoomInstance._onImageUpdated(); - assertTrue(_setZoomData.callCount === 1); - assertNull(_refreshLargeImage.callCount); - assertNull(_refresh.callCount); - assertTrue(hide.callCount === 1); - - _setZoomData.reset(); - hide.reset(); - zoomInstance.largeImageSrc = 'image.large.jpg'; - zoomInstance._onImageUpdated(); - assertTrue(_setZoomData.callCount === 1); - assertTrue(_refreshLargeImage.callCount === 1); - assertTrue(_refresh.callCount === 1); - assertNull(hide.callCount); -}; -ZoomTest.prototype.testLargeImageLoaded = function() { - var zoomInstance = this.zoomCreate(), - _toggleNotice = jsunit.stub(zoomInstance, '_toggleNotice'), - _getAspectRatio = jsunit.stub(zoomInstance, '_getAspectRatio'), - _getWhiteBordersOffset = jsunit.stub(zoomInstance, '_getWhiteBordersOffset'), - processStopTriggered = false, - image = jQuery('

    '); - - _getWhiteBordersOffset.returnValue = 1; - zoomInstance.element.append(image); - zoomInstance.options.selectors.image = '[data-role=test-image]'; - zoomInstance.image = image; - _getAspectRatio.returnCallback = function(image) { - if (image.is(zoomInstance.image)) { - return 0; - } else { - return 1; - } - }; - - jQuery(zoomInstance.options.selectors.image).on('processStop', function() { - processStopTriggered = true; - }); - zoomInstance.ratio = 1; - - zoomInstance._largeImageLoaded(); - assertNull(zoomInstance.ratio); - assertTrue(_toggleNotice.callCount === 1); - assertTrue(processStopTriggered); - assertTrue(_getAspectRatio.callCount > 0); - assertTrue(_getWhiteBordersOffset.callCount === 1); - assertEquals(zoomInstance.whiteBordersOffset, _getWhiteBordersOffset.returnValue); -}; -ZoomTest.prototype.testRefreshLargeImage = function() { - var zoomInstance = this.zoomCreate(), - css = {top: 0, left: 0}; - zoomInstance.largeImage = jQuery(''); - zoomInstance.largeImageSrc = 'large.image.jpg'; - - zoomInstance._refreshLargeImage(); - assertNotUndefined(zoomInstance.largeImage.prop('src')); - assertEquals(zoomInstance.largeImage.css('top'), css.top + 'px'); - assertEquals(zoomInstance.largeImage.css('left'), css.left + 'px'); -}; -ZoomTest.prototype.testRenderLargeImage = function() { - var zoomInstance = this.zoomCreate(); - - zoomInstance.element.append(jQuery('

    ')); - zoomInstance.options.selectors.image = '[data-role=test-image]'; - - var image = zoomInstance._renderLargeImage(); - assertTrue(image.is('img')); - assertTrue(image.is(zoomInstance.largeImage)); -}; -ZoomTest.prototype.testGetZoomRatio = function() { - var zoomInstance = this.zoomCreate(), - imageSize = {width: 100, height: 100}, - largeImageSize = {width: 200, height: 200}; - - zoomInstance.ratio = null; - zoomInstance.image = jQuery('', imageSize); - zoomInstance.largeImageSize = largeImageSize; - var zoomRatio = zoomInstance.getZoomRatio(); - - assertEquals(zoomRatio, (largeImageSize.width / imageSize.width)); - zoomInstance.ratio = 100; - zoomRatio = zoomInstance.getZoomRatio(); - assertEquals(zoomRatio, zoomInstance.ratio); -}; -ZoomTest.prototype.testGetAspectRatio = function() { - var zoomInstance = this.zoomCreate(), - aspectRatio = zoomInstance._getAspectRatio(), - size = {width: 200, height: 100}; - assertNull(aspectRatio); - aspectRatio = zoomInstance._getAspectRatio(jQuery('

    ', size)); - assertEquals((Math.round((size.width / size.height) * 100) / 100), aspectRatio); -}; diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/menu/index.html b/dev/tests/js/jasmine/assets/lib/web/mage/menu.html similarity index 50% rename from dev/tests/js/JsTestDriver/testsuite/mage/menu/index.html rename to dev/tests/js/jasmine/assets/lib/web/mage/menu.html index d0a3b9b873801..03c673a7dac5f 100644 --- a/dev/tests/js/JsTestDriver/testsuite/mage/menu/index.html +++ b/dev/tests/js/jasmine/assets/lib/web/mage/menu.html @@ -1,36 +1,10 @@ - - - - - - Unit test - - - - - - - - - - - - -
    -
    - - +
\ No newline at end of file diff --git a/dev/tests/js/jasmine/assets/lib/web/mage/tabs.html b/dev/tests/js/jasmine/assets/lib/web/mage/tabs.html new file mode 100644 index 0000000000000..dd4d665ca188e --- /dev/null +++ b/dev/tests/js/jasmine/assets/lib/web/mage/tabs.html @@ -0,0 +1,8 @@ +
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/dev/tests/js/jasmine/assets/lib/web/mage/translate-inline.html b/dev/tests/js/jasmine/assets/lib/web/mage/translate-inline.html new file mode 100644 index 0000000000000..5e48598a081a2 --- /dev/null +++ b/dev/tests/js/jasmine/assets/lib/web/mage/translate-inline.html @@ -0,0 +1,4 @@ + +
\ No newline at end of file diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/cc-form.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/cc-form.test.js index d71f517b5e7f9..52739eec2782b 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/cc-form.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Braintree/frontend/js/view/payment/method-renderer/cc-form.test.js @@ -27,7 +27,7 @@ define([ ), 'Magento_Braintree/js/view/payment/adapter': jasmine.createSpyObj( 'adapter', - ['setup', 'setConfig'] + ['setup', 'setConfig', 'showError'] ) }, braintreeCcForm; @@ -43,14 +43,17 @@ define([ }; injector.mock(mocks); injector.require(['Magento_Braintree/js/view/payment/method-renderer/cc-form'], function (Constr) { - braintreeCcForm = new Constr({ - provider: 'provName', - name: 'test', - index: 'test' - }); - - done(); + braintreeCcForm = new Constr({ + provider: 'provName', + name: 'test', + index: 'test', + item: { + title: 'Braintree' + } }); + + done(); + }); }); it('Check if payment code and message container are restored after onActiveChange call.', function () { @@ -65,5 +68,21 @@ define([ expect(braintreeCcForm.getCode()).toEqual(expectedCode); expect(braintreeCcForm.messageContainer).toEqual(expectedMessageContainer); }); + + it('Check if form validation fails when "Place Order" button should be active.', function () { + var errorMessage = 'Something went wrong.', + + /** + * Anonymous wrapper + */ + func = function () { + braintreeCcForm.clientConfig.onError({ + 'message': errorMessage + }); + }; + + expect(func).toThrow(errorMessage); + expect(braintreeCcForm.isPlaceOrderActionAllowed()).toBeTruthy(); + }); }); }); diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/CheckoutAgreements/frontend/js/model/place-order-mixin.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/CheckoutAgreements/frontend/js/model/place-order-mixin.test.js new file mode 100644 index 0000000000000..545daf0a330c9 --- /dev/null +++ b/dev/tests/js/jasmine/tests/app/code/Magento/CheckoutAgreements/frontend/js/model/place-order-mixin.test.js @@ -0,0 +1,55 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'squire' +], function (Squire) { + 'use strict'; + + var injector = new Squire(), + mocks = { + 'Magento_Checkout/js/action/place-order': jasmine.createSpy('placeOrderAction'), + 'Magento_CheckoutAgreements/js/model/agreements-assigner': jasmine.createSpy('agreementsAssigner') + }, + defaultContext = require.s.contexts._, + mixin, + placeOrderAction; + + beforeEach(function (done) { + window.checkoutConfig = { + checkoutAgreements: { + isEnabled: true + } + }; + injector.mock(mocks); + injector.require([ + 'Magento_CheckoutAgreements/js/model/place-order-mixin', + 'Magento_Checkout/js/action/place-order' + ], function (Mixin, placeOrder) { + mixin = Mixin; + placeOrderAction = placeOrder; + done(); + }); + }); + + describe('Magento_CheckoutAgreements/js/model/place-order-mixin', function () { + it('mixin is applied to Magento_Checkout/js/action/place-order', function () { + var placeOrderMixins = defaultContext.config.config.mixins['Magento_Checkout/js/action/place-order']; + + expect(placeOrderMixins['Magento_CheckoutAgreements/js/model/place-order-mixin']).toBe(true); + }); + + it('Magento_CheckoutAgreements/js/model/agreements-assigner is called', function () { + var messageContainer = jasmine.createSpy('messageContainer'), + paymentData = {}; + + mixin(placeOrderAction)(paymentData, messageContainer); + expect(mocks['Magento_CheckoutAgreements/js/model/agreements-assigner']) + .toHaveBeenCalledWith(paymentData); + expect(mocks['Magento_Checkout/js/action/place-order']) + .toHaveBeenCalledWith(paymentData, messageContainer); + }); + }); +}); diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/CheckoutAgreements/frontend/js/model/set-payment-information-mixin.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/CheckoutAgreements/frontend/js/model/set-payment-information-mixin.test.js new file mode 100644 index 0000000000000..ed525bfd96a6c --- /dev/null +++ b/dev/tests/js/jasmine/tests/app/code/Magento/CheckoutAgreements/frontend/js/model/set-payment-information-mixin.test.js @@ -0,0 +1,56 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'squire' +], function (Squire) { + 'use strict'; + + var injector = new Squire(), + mocks = { + 'Magento_Checkout/js/action/set-payment-information': jasmine.createSpy('placeOrderAction'), + 'Magento_CheckoutAgreements/js/model/agreements-assigner': jasmine.createSpy('agreementsAssigner') + }, + defaultContext = require.s.contexts._, + mixin, + placeOrderAction; + + beforeEach(function (done) { + window.checkoutConfig = { + checkoutAgreements: { + isEnabled: true + } + }; + injector.mock(mocks); + injector.require([ + 'Magento_CheckoutAgreements/js/model/set-payment-information-mixin', + 'Magento_Checkout/js/action/set-payment-information' + ], function (Mixin, setPaymentInformation) { + mixin = Mixin; + placeOrderAction = setPaymentInformation; + done(); + }); + }); + + describe('Magento_CheckoutAgreements/js/model/set-payment-information-mixin', function () { + it('mixin is applied to Magento_Checkout/js/action/set-payment-information', function () { + var placeOrderMixins = defaultContext + .config.config.mixins['Magento_Checkout/js/action/set-payment-information']; + + expect(placeOrderMixins['Magento_CheckoutAgreements/js/model/set-payment-information-mixin']).toBe(true); + }); + + it('Magento_CheckoutAgreements/js/model/agreements-assigner is called', function () { + var messageContainer = jasmine.createSpy('messageContainer'), + paymentData = {}; + + mixin(placeOrderAction)(messageContainer, paymentData); + expect(mocks['Magento_CheckoutAgreements/js/model/agreements-assigner']) + .toHaveBeenCalledWith(paymentData); + expect(mocks['Magento_Checkout/js/action/set-payment-information']) + .toHaveBeenCalledWith(messageContainer, paymentData); + }); + }); +}); diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Paypal/frontend/js/view/payment/method-renderer/paypal-express-abstract.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Paypal/frontend/js/view/payment/method-renderer/paypal-express-abstract.test.js index dc520c5238568..47e3507ea1321 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Paypal/frontend/js/view/payment/method-renderer/paypal-express-abstract.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Paypal/frontend/js/view/payment/method-renderer/paypal-express-abstract.test.js @@ -16,6 +16,13 @@ define([ describe('paypal/js/view/payment/method-renderer/paypal-express-abstract', function () { var injector = new Squire(), + successPromise = jasmine.createSpyObj('successPromise', ['done']), + setPaymentMock = jasmine.createSpy('set-payment-information', function () { + return successPromise; + }).and.callThrough(), + validateMock = jasmine.createSpy('validate', function () { + return true; + }).and.callThrough(), mocks = { 'Magento_Checkout/js/model/quote': { billingAddress: ko.observable(), @@ -23,6 +30,10 @@ define([ paymentMethod: ko.observable(), totals: ko.observable({}) + }, + 'Magento_Checkout/js/action/set-payment-information': setPaymentMock, + 'Magento_Checkout/js/model/payment/additional-validators': { + validate: validateMock } }, paypalExpressAbstract, @@ -85,6 +96,23 @@ define([ }, 500); }); + it('setPaymentMethodAction is called before redirect to paypal', function () { + spyOn(paypalExpressAbstract, 'selectPaymentMethod'); + paypalExpressAbstract.continueToPayPal(); + expect(paypalExpressAbstract.selectPaymentMethod).toHaveBeenCalled(); + expect(validateMock).toHaveBeenCalled(); + expect(validateMock.calls.mostRecent()).toEqual(jasmine.objectContaining({ + object: mocks['Magento_Checkout/js/model/payment/additional-validators'], + args: [], + returnValue: true + })); + expect(setPaymentMock).toHaveBeenCalled(); + expect(setPaymentMock.calls.mostRecent()).toEqual(jasmine.objectContaining({ + returnValue: successPromise + })); + expect(successPromise.done).toHaveBeenCalledWith(jasmine.any(Function)); + }); + afterAll(function (done) { tplElement.remove(); done(); 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 ca2509c4ea707..de3387e31af88 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 @@ -43,8 +43,8 @@ define([ }); expect(multiSelect.allSelected()).toBeFalsy(); - expect(multiSelect.excluded()).toEqual([]); - expect(multiSelect.selected()).toEqual([]); + expect(multiSelect.excluded().toString()).toEqual(''); + expect(multiSelect.selected().toString()).toEqual(''); }); it('Select specific several rows on several pages', function () { @@ -52,8 +52,8 @@ define([ multiSelect.selected.push(5); expect(multiSelect.allSelected()).toBeFalsy(); - expect(multiSelect.excluded()).toEqual([]); - expect(multiSelect.selected()).toEqual([4, 5]); + expect(multiSelect.excluded().toString()).toEqual(''); + expect(multiSelect.selected().toString()).toEqual('4,5'); }); it('Select all rows on several pages', function () { @@ -71,8 +71,8 @@ define([ multiSelect.selectPage(); expect(multiSelect.allSelected()).toBeFalsy(); - expect(multiSelect.excluded()).toEqual([]); - expect(multiSelect.selected()).toEqual([1, 2, 3, 4]); + expect(multiSelect.excluded().toString()).toEqual(''); + expect(multiSelect.selected().toString()).toEqual('1,2,3,4'); }); it('Select all rows on current page with some specific rows on another page', function () { @@ -94,8 +94,8 @@ define([ }]); multiSelect.selected.push(6); expect(multiSelect.allSelected()).toBeFalsy(); - expect(multiSelect.excluded()).toEqual([5]); - expect(multiSelect.selected()).toEqual([3, 4, 6]); + expect(multiSelect.excluded().toString()).toEqual('5'); + expect(multiSelect.selected().toString()).toEqual('3,4,6'); }); it('Select all rows on several pages without some specific rows', function () { @@ -113,8 +113,8 @@ define([ multiSelect.selected.remove(4); // remove second expect(multiSelect.allSelected()).toBeFalsy(); - expect(multiSelect.excluded()).toEqual([4]); - expect(multiSelect.selected()).toEqual([3]); + expect(multiSelect.excluded().toString()).toEqual('4'); + expect(multiSelect.selected().toString()).toEqual('3'); }); it('Select all rows all over the Grid', function () { @@ -131,8 +131,8 @@ define([ }]); expect(multiSelect.allSelected()).toBeFalsy(); - expect(multiSelect.excluded()).toEqual([]); - expect(multiSelect.selected()).toEqual([3, 4, 1, 2]); + expect(multiSelect.excluded().toString()).toEqual(''); + expect(multiSelect.selected().toString()).toEqual('3,4,1,2'); }); it('Select all rows all over the Grid without all rows on current page but with specific rows on another page', @@ -156,8 +156,8 @@ define([ }]); expect(multiSelect.allSelected()).toBeFalsy(); - expect(multiSelect.excluded()).toEqual([3, 4]); - expect(multiSelect.selected()).toEqual([5, 6]); + expect(multiSelect.excluded().toString()).toEqual('3,4'); + expect(multiSelect.selected().toString()).toEqual('5,6'); }); }); }); diff --git a/dev/tests/js/jasmine/tests/lib/mage/accordion.test.js b/dev/tests/js/jasmine/tests/lib/mage/accordion.test.js new file mode 100644 index 0000000000000..19a54d95cf704 --- /dev/null +++ b/dev/tests/js/jasmine/tests/lib/mage/accordion.test.js @@ -0,0 +1,80 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'jquery', + 'mage/accordion' +], function ($) { + 'use strict'; + + describe('Test for mage/accordion jQuery plugin', function () { + it('check if accordion can be initialized', function () { + var accordion = $('
'); + + accordion.accordion(); + expect(accordion.is(':mage-accordion')).toBeTruthy(); + + accordion.accordion('destroy'); + expect(accordion.is(':mage-accordion')).toBeFalsy(); + }); + it('check one-collapsible element accordion', function () { + var accordion = $('
'), + title1 = $('
').appendTo(accordion), + content1 = $('
').appendTo(accordion), + title2 = $('
').appendTo(accordion), + content2 = $('
').appendTo(accordion); + + accordion.appendTo('body'); + + accordion.accordion(); + + expect(accordion.is(':mage-accordion')).toBeTruthy(); + + expect(content1.is(':visible')).toBeTruthy(); + expect(content2.is(':hidden')).toBeTruthy(); + + title2.trigger('click'); + + expect(content1.is(':hidden')).toBeTruthy(); + expect(content2.is(':visible')).toBeTruthy(); + + title1.trigger('click'); + + expect(content1.is(':visible')).toBeTruthy(); + expect(content2.is(':hidden')).toBeTruthy(); + + accordion.accordion('destroy'); + + expect(accordion.is(':mage-accordion')).toBeFalsy(); + }); + it('check multi-collapsible element accordion', function () { + var accordion = $('
'), + title1 = $('
').appendTo(accordion), + content1 = $('
').appendTo(accordion), + title2 = $('
').appendTo(accordion), + content2 = $('
').appendTo(accordion); + + accordion.appendTo('body'); + + accordion.accordion({ + multipleCollapsible: true + }); + + expect(accordion.is(':mage-accordion')).toBeTruthy(); + expect(content1.is(':visible')).toBeTruthy(); + expect(content2.is(':hidden')).toBeTruthy(); + + $(title1).trigger('click'); + expect(content1.is(':visible')).toBeTruthy(); + expect(content2.is(':hidden')).toBeTruthy(); + + $(title2).trigger('click'); + expect(content1.is(':visible')).toBeTruthy(); + expect(content2.is(':visible')).toBeTruthy(); + + accordion.accordion('destroy'); + expect(accordion.is(':mage-accordion')).toBeFalsy(); + }); + }); +}); diff --git a/dev/tests/js/jasmine/tests/lib/mage/backend/bootstrap.test.js b/dev/tests/js/jasmine/tests/lib/mage/backend/bootstrap.test.js index 538c7e60b60fd..834a6df75843f 100644 --- a/dev/tests/js/jasmine/tests/lib/mage/backend/bootstrap.test.js +++ b/dev/tests/js/jasmine/tests/lib/mage/backend/bootstrap.test.js @@ -20,14 +20,19 @@ define([ }); }); describe('"sendPostponeRequest" method', function () { - it('should insert "Error" notification if request failed', function () { + it('should insert "Error" notification if request failed', function (done) { jQuery('
').appendTo('body'); jQuery('body').notification(); jQuery.ajax().abort(); - expect(jQuery('.message-error').length).toBe(1); - expect(jQuery('body:contains("A technical problem with the server created an error")').length).toBe(1); + setTimeout(function () { + expect(jQuery('.message-error').length).toBe(1); + expect( + jQuery('body:contains("A technical problem with the server created an error")').length + ).toBe(1); + done(); + }, 1); }); }); }); diff --git a/dev/tests/js/jasmine/tests/lib/mage/backend/suggest.test.js b/dev/tests/js/jasmine/tests/lib/mage/backend/suggest.test.js new file mode 100644 index 0000000000000..84880e6af72c5 --- /dev/null +++ b/dev/tests/js/jasmine/tests/lib/mage/backend/suggest.test.js @@ -0,0 +1,524 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/* eslint-disable max-nested-callbacks */ +define([ + 'jquery', + 'mage/backend/suggest' +], function ($) { + 'use strict'; + + describe('mage/backend/suggest', function () { + var suggestSelector = '#suggest'; + + beforeEach(function () { + var $suggest = $(''); + + $('body').append($suggest); + $('body').append(''); + }); + + afterEach(function () { + $(suggestSelector).remove(); + $('#test-template').remove(); + $(suggestSelector).suggest('destroy'); + }); + + it('Check that suggest inited', function () { + var $suggest = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ' + }); + + expect($suggest.is(':mage-suggest')).toBe(true); + }); + + it('Check suggest create', function () { + var options = { + template: '#test-template', + choiceTemplate: '
  • ', + controls: { + selector: '.test', + eventsMap: { + focus: ['testfocus'], + blur: ['testblur'], + select: ['testselect'] + } + }, + showRecent: true, + storageKey: 'test-suggest-recent', + multiselect: true + }, + recentItems = [{ + id: '1', + label: 'TestLabel1' + }, + { + id: '2', + label: 'TestLabel2' + } + ], + nonSelectedItem = { + id: '', + label: '' + }, + suggestInstance; + + if (window.localStorage) { + localStorage.setItem(options.storageKey, JSON.stringify(recentItems)); + } + + suggestInstance = $(suggestSelector).suggest(options).data('mage-suggest'); + + expect(suggestInstance._term).toBe(null); + expect(suggestInstance._nonSelectedItem).toEqual(nonSelectedItem); + expect(suggestInstance._renderedContext).toBe(null); + expect(suggestInstance._selectedItem).toEqual(nonSelectedItem); + expect(suggestInstance._control).toEqual(suggestInstance.options.controls); + expect(suggestInstance._recentItems).toEqual(window.localStorage ? recentItems : []); + expect(suggestInstance.valueField.is(':hidden')).toBe(true); + + if (window.localStorage) { + localStorage.removeItem(options.storageKey); + } + }); + + it('Check suggest render', function () { + var options = { + template: '#test-template', + choiceTemplate: '
  • ', + dropdownWrapper: '
    ', + className: 'test-suggest', + inputWrapper: '
    ' + }, + suggestInstance = $(suggestSelector).suggest(options).data('mage-suggest'); + + suggestInstance._render(); + + expect(suggestInstance.dropdown.hasClass('wrapper-test')).toBe(true); + expect(suggestInstance.dropdown.is(':hidden')).toBe(true); + expect(suggestInstance.element.closest('.test-input-wrapper').size()).toBeGreaterThan(0); + expect(suggestInstance.element.closest('.' + options.className).size()).toBeGreaterThan(0); + expect(suggestInstance.element.attr('autocomplete')).toBe('off'); + + options.appendMethod = 'before'; + $(suggestSelector).suggest('destroy'); + suggestInstance = $(suggestSelector).suggest(options).data('mage-suggest'); + suggestInstance._render(); + expect(suggestInstance.element.prev().is(suggestInstance.dropdown)).toBe(true); + + options.appendMethod = 'after'; + $(suggestSelector).suggest('destroy'); + suggestInstance = $(suggestSelector).suggest(options).data('mage-suggest'); + suggestInstance._render(); + expect(suggestInstance.element.next().is(suggestInstance.dropdown)).toBe(true); + }); + + it('Check suggest createValueField', function () { + var suggestInstance = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ' + }).data('mage-suggest'), + valueField = suggestInstance._createValueField(); + + expect(valueField.is('input')).toBe(true); + expect(valueField.is(':hidden')).toBe(true); + + $(suggestSelector).suggest('destroy'); + suggestInstance = $(suggestSelector).suggest({ + multiselect: true, + template: '#test-template', + choiceTemplate: '
  • ' + }).data('mage-suggest'); + valueField = suggestInstance._createValueField(); + + expect(valueField.is('select')).toBe(true); + expect(valueField.is(':hidden')).toBe(true); + expect(valueField.attr('multiple')).toBe('multiple'); + }); + + it('Check suggest prepareValueField', function () { + var $suggest = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ' + }), + suggestInstance = $suggest.data('mage-suggest'), + suggestName = $suggest.attr('name'); + + suggestInstance._prepareValueField(); + + expect(suggestInstance.valueField).not.toBe(true); + expect(suggestInstance.element.prev().is(suggestInstance.valueField)).toBe(true); + expect(suggestInstance.element.attr('name')).toBe(undefined); + expect(suggestInstance.valueField.attr('name')).toBe(suggestName); + }); + + it('Check suggest destroy', function () { + var options = { + template: '#test-template', + choiceTemplate: '
  • ', + inputWrapper: '
    ', + valueField: null + }, + $suggest = $(suggestSelector).suggest(options), + suggestInstance = $suggest.data('mage-suggest'), + suggestName = $suggest.attr('name'); + + expect(suggestInstance.dropdown).not.toBe(undefined); + expect(suggestInstance.valueField).not.toBe(undefined); + expect(suggestName).toBe(undefined); + + $suggest.suggest('destroy'); + + expect($suggest.closest('.test-input-wrapper').length).toBe(0); + expect($suggest.attr('autocomplete')).toBe(undefined); + expect($suggest.attr('name')).toBe(suggestInstance.valueField.attr('name')); + expect(suggestInstance.valueField.parents('html').length).not.toBeGreaterThan(0); + expect(suggestInstance.dropdown.parents('html').length).not.toBeGreaterThan(0); + }); + + it('Check suggest value', function () { + var value = 'test-value', + suggestInstance, suggestDivInstance; + + $(suggestSelector).val(value); + $('body').append('
    ' + value + '
    '); + + suggestInstance = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ' + }).data('mage-suggest'); + suggestDivInstance = $('#suggest-div').suggest({ + template: '#test-template', + choiceTemplate: '
  • ' + }).data('mage-suggest'); + + expect(suggestInstance._value()).toBe(value); + expect(suggestDivInstance._value()).toBe(value); + $('#suggest-div').remove(); + }); + + it('Check suggest bind', function () { + var eventIsBinded = false, + options = { + template: '#test-template', + choiceTemplate: '
  • ', + events: { + /** Stub function */ + click: function () { + eventIsBinded = true; + } + } + }, + $suggest = $(suggestSelector).suggest(options); + + $suggest.trigger('click'); + expect(eventIsBinded).toBe(true); + }); + + it('Check suggest focus/blur', function () { + var suggestInstance = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ' + }).data('mage-suggest'), + uiHash = { + item: { + id: 1, + label: 'Test Label' + } + }; + + expect(suggestInstance._focused).toBe(undefined); + expect(suggestInstance.element.val()).toBe(''); + + suggestInstance._focusItem($.Event('focus'), uiHash); + + expect(suggestInstance._focused).toEqual(uiHash.item); + expect(suggestInstance.element.val()).toBe(uiHash.item.label); + + suggestInstance._blurItem(); + + expect(suggestInstance._focused).toBe(null); + expect(suggestInstance.element.val()).toBe(''); + }); + + it('Check suggest select', function () { + var suggestInstance = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ' + }).data('mage-suggest'), + uiHash = { + item: { + id: 1, + label: 'Test Label' + } + }; + + suggestInstance._focused = suggestInstance._term = suggestInstance._selectedItem = null; + suggestInstance.valueField.val(''); + suggestInstance._selectItem($.Event('select')); + + expect(suggestInstance._selectedItem).toBe(null); + expect(suggestInstance._term).toBe(null); + expect(suggestInstance.valueField.val()).toBe(''); + expect(suggestInstance.dropdown.is(':hidden')).toBe(true); + + suggestInstance._focused = uiHash.item; + suggestInstance._selectItem($.Event('select')); + + expect(suggestInstance._selectedItem).toEqual(suggestInstance._focused); + expect(suggestInstance._term).toBe(suggestInstance._focused.label); + expect(suggestInstance.valueField.val()).toBe(suggestInstance._focused.id.toString()); + expect(suggestInstance.dropdown.is(':hidden')).toBe(true); + }); + + it('Check suggest multiselect', function () { + var suggestInstance = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ', + multiselect: true + }).data('mage-suggest'), + uiHash = { + item: { + id: 1, + label: 'Test Label' + } + }, + event = $.Event('select'), + selectedElement = $('
    '); + + event.target = selectedElement[0]; + suggestInstance._focused = suggestInstance._term = suggestInstance._selectedItem = null; + suggestInstance.valueField.val(''); + suggestInstance._selectItem(event); + + expect(suggestInstance._selectedItem).toBe(null); + expect(suggestInstance._term).toBe(null); + expect(suggestInstance.valueField.find('option').length).not.toBeGreaterThan(0); + expect(suggestInstance.dropdown.is(':hidden')).toBe(true); + + suggestInstance._focused = uiHash.item; + suggestInstance._selectItem(event); + + expect(suggestInstance._selectedItem).toEqual(suggestInstance._focused); + expect(suggestInstance._term).toBe(''); + expect(suggestInstance._getOption(suggestInstance._focused).length).toBeGreaterThan(0); + expect(selectedElement.hasClass(suggestInstance.options.selectedClass)).toBe(true); + expect(suggestInstance.dropdown.is(':hidden')).toBe(true); + + suggestInstance._selectItem(event); + expect(suggestInstance._selectedItem).toEqual(suggestInstance._nonSelectedItem); + expect(suggestInstance._term).toBe(''); + expect(suggestInstance._getOption(suggestInstance._focused).length).not.toBeGreaterThan(0); + expect(selectedElement.hasClass(suggestInstance.options.selectedClass)).toBe(false); + expect(suggestInstance.dropdown.is(':hidden')).toBe(true); + }); + + it('Check suggest reset value', function () { + var suggestInstance = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ' + }).data('mage-suggest'); + + suggestInstance.valueField.val('test'); + expect(suggestInstance.valueField.val()).toBe('test'); + suggestInstance._resetSuggestValue(); + expect(suggestInstance.valueField.val()).toBe(suggestInstance._nonSelectedItem.id); + }); + + it('Check suggest reset multiselect value', function () { + var suggestInstance = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ', + multiselect: true + }).data('mage-suggest'), + uiHash = { + item: { + id: 1, + label: 'Test Label' + } + }, + event = $.Event('select'); + + event.target = $('
    ')[0]; + suggestInstance._focused = uiHash.item; + + suggestInstance._selectItem(event); + suggestInstance._resetSuggestValue(); + + expect(suggestInstance.valueField.val() instanceof Array).toBe(true); + expect(suggestInstance.valueField.val()[0]).not.toBe(undefined); + expect(suggestInstance.valueField.val()[0]).toBe(uiHash.item.id.toString()); + }); + + it('Check suggest read item data', function () { + var suggestInstance = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ' + }).data('mage-suggest'), + testElement = $('
    '); + + expect(suggestInstance._readItemData(testElement)).toEqual(suggestInstance._nonSelectedItem); + testElement.data('suggestOption', 'test'); + expect(suggestInstance._readItemData(testElement)).toEqual('test'); + }); + + it('Check suggest template', function () { + var suggestInstance = $(suggestSelector).suggest({ + template: '
    <%= data.test %>
    ', + choiceTemplate: '
  • ' + }).data('mage-suggest'), + tmpl = suggestInstance.templates[suggestInstance.templateName], + html = $('
    ').append(tmpl({ + data: { + test: 'test' + } + })).html(); + + expect(html).toEqual('
    test
    '); + suggestInstance.destroy(); + $('body').append(''); + + suggestInstance = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ' + }).data('mage-suggest'); + tmpl = suggestInstance.templates[suggestInstance.templateName]; + html = $('
    ').append(tmpl({ + data: { + test: 'test' + } + })).html(); + + expect(html).toEqual('
    test
    '); + $('#test-template').remove(); + }); + + it('Check suggest dropdown visibility', function () { + var suggestInstance = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ' + }).data('mage-suggest'); + + suggestInstance.dropdown.hide(); + expect(suggestInstance.isDropdownShown()).toBe(false); + expect(suggestInstance.dropdown.is(':hidden')).toBe(true); + + suggestInstance.dropdown.show(); + expect(suggestInstance.isDropdownShown()).toBe(true); + expect(suggestInstance.dropdown.is(':visible')).toBe(true); + }); + + it('Check suggest create option', function () { + var suggestInstance = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ' + }).data('mage-suggest'), + uiHash = { + item: { + id: 1, + label: 'Test Label' + } + }, + option = suggestInstance._createOption(uiHash.item); + + expect(option.val()).toBe('1'); + expect(option.prop('selected')).toBe(true); + expect(option.text()).toBe('Test Label'); + expect(option.data('renderedOption')).not.toBe(undefined); + }); + + it('Check suggest add option', function () { + var suggestInstance = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ' + }).data('mage-suggest'), + uiHash = { + item: { + id: 1, + label: 'Test Label' + } + }, + selectTarget = $('
    '), + event = $.Event('add'), + option; + + event.target = selectTarget[0]; + suggestInstance._addOption(event, uiHash.item); + option = suggestInstance.valueField.find('option[value=' + uiHash.item.id + ']'); + + expect(option.length).toBeGreaterThan(0); + expect(option.data('selectTarget').is(selectTarget)).toBe(true); + }); + + it('Check suggest get option', function () { + var suggestInstance = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ' + }).data('mage-suggest'), + uiHash = { + item: { + id: 1, + label: 'Test Label' + } + }, + option = $(''); + + expect(suggestInstance._getOption(uiHash.item).length).not.toBeGreaterThan(0); + + suggestInstance.valueField.append(option); + expect(suggestInstance._getOption(uiHash.item).length).toBeGreaterThan(0); + expect(suggestInstance._getOption(option).length).toBeGreaterThan(0); + }); + + it('Check suggest last added', function () { + var suggestInstance = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ', + multiselect: true + }).data('mage-suggest'), + uiHash = { + item: { + id: 1, + label: 'Test Label' + } + }; + + suggestInstance._addOption({}, uiHash.item); + expect(suggestInstance.valueField.find('option').length).toBeGreaterThan(0); + suggestInstance._removeLastAdded(); + expect(suggestInstance.valueField.find('option').length).not.toBeGreaterThan(0); + }); + + it('Check suggest remove option', function () { + var suggestInstance = $(suggestSelector).suggest({ + template: '#test-template', + choiceTemplate: '
  • ', + multiselect: true + }).data('mage-suggest'), + uiHash = { + item: { + id: 1, + label: 'Test Label' + } + }, + selectTarget = $('
    '), + event = $.Event('select'); + + selectTarget.addClass(suggestInstance.options.selectedClass); + event.target = selectTarget[0]; + + suggestInstance._addOption(event, uiHash.item); + expect(suggestInstance.valueField.find('option').length).toBeGreaterThan(0); + suggestInstance.removeOption(event, uiHash.item); + expect(suggestInstance.valueField.find('option').length).not.toBeGreaterThan(0); + expect(selectTarget.hasClass(suggestInstance.options.selectedClass)).toBe(false); + }); + }); +}); diff --git a/dev/tests/js/jasmine/tests/lib/mage/backend/tree-suggest.test.js b/dev/tests/js/jasmine/tests/lib/mage/backend/tree-suggest.test.js new file mode 100644 index 0000000000000..b116fc7058808 --- /dev/null +++ b/dev/tests/js/jasmine/tests/lib/mage/backend/tree-suggest.test.js @@ -0,0 +1,52 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/* eslint-disable max-nested-callbacks */ +define([ + 'jquery', + 'mage/backend/tree-suggest' +], function ($) { + 'use strict'; + + describe('mage/backend/tree-suggest', function () { + var treeSuggestSelector = '#tree-suggest'; + + beforeEach(function () { + var $treeSuggest = $(''); + + $('body').append($treeSuggest); + }); + + afterEach(function () { + $(treeSuggestSelector).remove(); + $(treeSuggestSelector).treeSuggest('destroy'); + }); + + it('Check that treeSuggest inited', function () { + var $treeSuggest = $(treeSuggestSelector).treeSuggest(), + treeSuggestInstance = $treeSuggest.data('mage-treeSuggest'); + + expect($treeSuggest.is(':mage-treeSuggest')).toBe(true); + expect(treeSuggestInstance.widgetEventPrefix).toBe('suggest'); + }); + + it('Check treeSuggest filter', function () { + var treeSuggestInstance = $(treeSuggestSelector).treeSuggest().data('mage-treeSuggest'), + uiHash = { + item: { + id: 1, + label: 'Test Label' + } + }; + + expect(treeSuggestInstance._filterSelected( + [uiHash.item], + { + _allShown: true + } + )).toEqual([uiHash.item]); + }); + }); +}); diff --git a/dev/tests/js/jasmine/tests/lib/mage/calendar.test.js b/dev/tests/js/jasmine/tests/lib/mage/calendar.test.js new file mode 100644 index 0000000000000..b2c6aed2c9fba --- /dev/null +++ b/dev/tests/js/jasmine/tests/lib/mage/calendar.test.js @@ -0,0 +1,173 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/* eslint-disable max-nested-callbacks */ +define([ + 'jquery', + 'jquery/ui', + 'mage/calendar' +], function ($) { + 'use strict'; + + describe('mage/calendar', function () { + describe('Check calendar', function () { + var calendarSelector = '#calendar'; + + beforeEach(function () { + var $calendar = $(''); + + $('body').append($calendar); + }); + + afterEach(function () { + $(calendarSelector).remove(); + $(calendarSelector).calendar('destroy'); + }); + + it('Check that calendar inited', function () { + var $calendar = $(calendarSelector).calendar(); + + expect($calendar.is(':mage-calendar')).toBe(true); + }); + + it('Check configuration merge', function () { + var $calendar; + + $.extend(true, $, { + calendarConfig: { + showOn: 'button', + showAnim: '', + buttonImageOnly: true, + showButtonPanel: true, + showWeek: true, + timeFormat: '', + showTime: false, + showHour: false, + showMinute: false + } + }); + + $calendar = $(calendarSelector).calendar(); + + expect($calendar.calendar('option', 'showOn')).toBe('button'); + expect($calendar.calendar('option', 'showAnim')).toBe(''); + expect($calendar.calendar('option', 'buttonImageOnly')).toBe(true); + expect($calendar.calendar('option', 'showButtonPanel')).toBe(true); + expect($calendar.calendar('option', 'showWeek')).toBe(true); + expect($calendar.calendar('option', 'timeFormat')).toBe(''); + expect($calendar.calendar('option', 'showTime')).toBe(false); + expect($calendar.calendar('option', 'showHour')).toBe(false); + expect($calendar.calendar('option', 'showMinute')).toBe(false); + + delete $.calendarConfig; + }); + + it('Specifying AM/PM in timeformat option changes AMPM option to true', function () { + var $calendar = $(calendarSelector).calendar({ + timeFormat: 'hh:mm tt', + ampm: false + }); + + expect($calendar.calendar('option', 'ampm')).toBe(true); + }); + + it('Omitting AM/PM in timeformat option changes AMPM option to false', function () { + var $calendar = $(calendarSelector).calendar({ + timeFormat: 'hh:mm' + }); + + expect($calendar.calendar('option', 'ampm')).toBe(null); + }); + + it('With server timezone offset', function () { + var serverTimezoneSeconds = 1346122095, + $calendar = $(calendarSelector).calendar({ + serverTimezoneSeconds: serverTimezoneSeconds + }), + currentDate = new Date(); + + currentDate.setTime((serverTimezoneSeconds + currentDate.getTimezoneOffset() * 60) * 1000); + + expect($calendar.calendar('getTimezoneDate').toString()).toBe(currentDate.toString()); + }); + + it('Without sever timezone offset', function () { + var $calendar = $(calendarSelector).calendar(), + currentDate = new Date(); + + expect($calendar.calendar('getTimezoneDate').toString()).toBe(currentDate.toString()); + }); + + it('Check destroy', function () { + var $calendar = $(calendarSelector).calendar(); + + expect($calendar.is(':mage-calendar')).toBe(true); + $calendar.calendar('destroy'); + expect($calendar.is(':mage-calendar')).toBe(false); + }); + }); + describe('Check dateRange', function () { + var dateRangeSelector = '#date-range'; + + beforeEach(function () { + var $dateRange = $('
    ' + + '' + + '' + + '
    '); + + $('body').append($dateRange); + }); + + afterEach(function () { + $(dateRangeSelector).remove(); + $(dateRangeSelector).dateRange('destroy'); + }); + + it('Check that dateRange inited', function () { + var $dateRange = $(dateRangeSelector).dateRange(); + + expect($dateRange.is(':mage-dateRange')).toBe(true); + }); + + it('Check that dateRange inited with additional options', function () { + var $from = $('#from'), + $to = $('#to'); + + $(dateRangeSelector).dateRange({ + from: { + id: 'from' + }, + to: { + id: 'to' + } + }); + + expect($from.hasClass('_has-datepicker')).toBe(true); + expect($to.hasClass('_has-datepicker')).toBe(true); + }); + + it('Check destroy', function () { + var $dateRange = $(dateRangeSelector).dateRange({ + from: { + id: 'from' + }, + to: { + id: 'to' + } + }), + $from = $('#from'), + $to = $('#to'); + + expect($dateRange.is(':mage-dateRange')).toBe(true); + expect($from.hasClass('_has-datepicker')).toBe(true); + expect($to.hasClass('_has-datepicker')).toBe(true); + $dateRange.dateRange('destroy'); + expect($dateRange.is(':mage-dateRange')).toBe(false); + expect($from.hasClass('_has-datepicker')).toBe(false); + expect($to.hasClass('_has-datepicker')).toBe(false); + }); + }); + }); +}); diff --git a/dev/tests/js/jasmine/tests/lib/mage/collapsible.test.js b/dev/tests/js/jasmine/tests/lib/mage/collapsible.test.js new file mode 100644 index 0000000000000..d6c95d2887ec7 --- /dev/null +++ b/dev/tests/js/jasmine/tests/lib/mage/collapsible.test.js @@ -0,0 +1,211 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +/* eslint-disable max-nested-callbacks */ +/* jscs:disable jsDoc */ + +define([ + 'jquery', + 'jquery/ui', + 'mage/collapsible' +], function ($) { + 'use strict'; + + describe('Test for mage/collapsible jQuery plugin', function () { + it('check if collapsible can be initialized and destroyed', function () { + var group = $('
    '); + + group.collapsible(); + expect(group.is(':mage-collapsible')).toBeTruthy(); + + group.collapsible('destroy'); + expect(group.is(':mage-collapsible')).toBeFalsy(); + group.remove(); + }); + + describe('Test enable, disable, activate and deactivate methods', function () { + var group = $('
    '), + content = $('
    ').appendTo(group); + + $('
    ').prependTo(group); + + beforeEach(function () { + group.appendTo('body'); + }); + + afterEach(function () { + group.remove(); + }); + + it('check enable and disable methods', function () { + group.collapsible(); + expect(group.is(':mage-collapsible')).toBeTruthy(); + + group.collapsible('disable'); + expect(content.is(':hidden')).toBeTruthy(); + + group.collapsible('enable'); + expect(content.is(':visible')).toBeTruthy(); + + group.collapsible('destroy'); + expect(group.is(':mage-collapsible')).toBeFalsy(); + }); + + it('check activate and deactivate methods', function () { + group.collapsible(); + expect(group.is(':mage-collapsible')).toBeTruthy(); + + group.collapsible('deactivate'); + expect(content.is(':hidden')).toBeTruthy(); + + group.collapsible('activate'); + expect(content.is(':visible')).toBeTruthy(); + + group.collapsible('destroy'); + expect(group.is(':mage-collapsible')).toBeFalsy(); + }); + }); + + it('check if the widget gets expanded/collapsed when the title is clicked', function () { + var group = $('
    '), + title = $('
    ').appendTo(group), + content = $('
    ').appendTo(group); + + group.appendTo('body'); + + group.collapsible(); + expect(group.is(':mage-collapsible')).toBeTruthy(); + + group.collapsible('deactivate'); + expect(content.is(':hidden')).toBeTruthy(); + + title.trigger('click'); + expect(content.is(':visible')).toBeTruthy(); + + title.trigger('click'); + expect(content.is(':hidden')).toBeTruthy(); + + group.collapsible('destroy'); + expect(group.is(':mage-collapsible')).toBeFalsy(); + group.remove(); + }); + + it('check state classes', function () { + var group = $('
    '), + title = $('
    ').appendTo(group); + + $('
    ').appendTo(group); + + group.appendTo('body'); + + group.collapsible({ + openedState: 'opened', + closedState: 'closed', + disabledState: 'disabled' + }); + expect(group.is(':mage-collapsible')).toBeTruthy(); + expect(group.hasClass('closed')).toBeTruthy(); + + title.trigger('click'); + expect(group.hasClass('opened')).toBeTruthy(); + + group.collapsible('disable'); + expect(group.hasClass('disabled')).toBeTruthy(); + + group.collapsible('destroy'); + expect(group.is(':mage-collapsible')).toBeFalsy(); + group.remove(); + }); + + it('check if icons are added to title when initialized and removed when destroyed', function () { + var group = $('
    '), + title = $('
    ').appendTo(group); + + $('
    ').appendTo(group); + + group.appendTo('body'); + + group.collapsible({ + icons: { + header: 'minus', + activeHeader: 'plus' + } + }); + expect(group.is(':mage-collapsible')).toBeTruthy(); + expect(title.children('[data-role=icons]').length).toBeTruthy(); + + group.collapsible('destroy'); + expect(group.is(':mage-collapsible')).toBeFalsy(); + expect(title.children('[data-role=icons]').length).toBeFalsy(); + group.remove(); + }); + + it('check if icon classes are changed when content gets expanded/collapsed', function () { + var group = $('
    '), + title = $('
    ').appendTo(group), + content = $('
    ').appendTo(group), + icons; + + group.appendTo('body'); + + group.collapsible({ + icons: { + header: 'minus', + activeHeader: 'plus' + } + }); + expect(group.is(':mage-collapsible')).toBeTruthy(); + + icons = group.collapsible('option', 'icons'); + group.collapsible('deactivate'); + expect(content.is(':hidden')).toBeTruthy(); + expect(title.children('[data-role=icons]').hasClass(icons.header)).toBeTruthy(); + + title.trigger('click'); + expect(title.children('[data-role=icons]').hasClass(icons.activeHeader)).toBeTruthy(); + + group.collapsible('destroy'); + expect(group.is(':mage-collapsible')).toBeFalsy(); + group.remove(); + }); + + it('check if content gets updated via Ajax when title is clicked', function () { + var group = $('
    '), + title = $('
    ').appendTo(group), + content = $('
    ').appendTo(group); + + $('').appendTo(group); + + $.get = jasmine.createSpy().and.callFake(function () { + var d = $.Deferred(); + + d.promise().success = function () { + }; + + d.promise().complete = function () { + }; + + return d.promise(); + }); + + group.appendTo('body'); + + group.collapsible({ + ajaxContent: true + }); + expect(group.is(':mage-collapsible')).toBeTruthy(); + + group.collapsible('deactivate'); + expect(content.is(':hidden')).toBeTruthy(); + expect(content.children('p').length).toBeFalsy(); + + title.trigger('click'); + expect(content.children('p')).toBeTruthy(); + + group.collapsible('destroy'); + expect(group.is(':mage-collapsible')).toBeFalsy(); + group.remove(); + }); + }); +}); diff --git a/dev/tests/js/jasmine/tests/lib/mage/decorate.test.js b/dev/tests/js/jasmine/tests/lib/mage/decorate.test.js new file mode 100644 index 0000000000000..898bcf8b51128 --- /dev/null +++ b/dev/tests/js/jasmine/tests/lib/mage/decorate.test.js @@ -0,0 +1,201 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/* eslint-disable max-nested-callbacks */ +define([ + 'mage/decorate', + 'jquery' +], function (decorate, $) { + 'use strict'; + + describe('mage/decorate', function () { + describe('"list" method', function () { + var listId = 'testList'; + + beforeEach(function () { + var list = $('
    '); + + $('body').append(list); + }); + + afterEach(function () { + $('#' + listId).remove(); + }); + + it('Check correct class decoration', function () { + var $list = $('#' + listId); + + $list.decorate('list'); + expect($list.find('li:first').hasClass('first')).toBe(false); + expect($list.find('li:first').hasClass('odd')).toBe(true); + expect($list.find('li:last').hasClass('last')).toBe(true); + expect($list.find('li:odd').hasClass('even')).toBe(true); + expect($list.find('li:even').hasClass('odd')).toBe(true); + }); + }); + + describe('"generic" method', function () { + var listId = 'testList'; + + beforeEach(function () { + var list = $('
    '); + + $('body').append(list); + }); + + afterEach(function () { + $('#' + listId).remove(); + }); + + it('Check correct class decoration with default params', function () { + var $list = $('#' + listId); + + $list.find('li').decorate('generic'); + expect($list.find('li:first').hasClass('first')).toBe(true); + expect($list.find('li:first').hasClass('odd')).toBe(true); + expect($list.find('li:last').hasClass('last')).toBe(true); + expect($list.find('li:odd').hasClass('even')).toBe(true); + expect($list.find('li:even').hasClass('odd')).toBe(true); + }); + + it('Check correct class decoration with custom params', function () { + var $list = $('#' + listId); + + $list.find('li').decorate('generic', ['last', 'first']); + expect($list.find('li:first').hasClass('first')).toBe(true); + expect($list.find('li:first').hasClass('odd')).toBe(false); + expect($list.find('li:last').hasClass('last')).toBe(true); + expect($list.find('li:odd').hasClass('even')).toBe(false); + expect($list.find('li:even').hasClass('odd')).toBe(false); + }); + + it('Check correct class decoration with empty items', function () { + var $list = $('#' + listId); + + $list.find('span').decorate('generic', ['last', 'first']); + expect($list.find('li:first').hasClass('first')).toBe(false); + expect($list.find('li:first').hasClass('odd')).toBe(false); + expect($list.find('li:last').hasClass('last')).toBe(false); + expect($list.find('li:odd').hasClass('even')).toBe(false); + expect($list.find('li:even').hasClass('odd')).toBe(false); + }); + }); + + describe('"table" method', function () { + var tableId = 'testTable'; + + beforeEach(function () { + var table = $('' + + '' + + '' + + '' + + '' + + '' + + '>' + + '' + + '
    '); + + $('body').append(table); + }); + + afterEach(function () { + $('#' + tableId).remove(); + }); + + it('Check correct class decoration with default params', function () { + var $table = $('#' + tableId); + + $table.decorate('table'); + expect($table.find('tbody tr:first').hasClass('first')).toBe(true); + expect($table.find('tbody tr:first').hasClass('odd')).toBe(true); + expect($table.find('tbody tr:odd').hasClass('even')).toBe(true); + expect($table.find('tbody tr:even').hasClass('odd')).toBe(true); + expect($table.find('tbody tr:last').hasClass('last')).toBe(true); + expect($table.find('thead tr:first').hasClass('first')).toBe(true); + expect($table.find('thead tr:last').hasClass('last')).toBe(true); + expect($table.find('tfoot tr:first').hasClass('first')).toBe(true); + expect($table.find('tfoot tr:last').hasClass('last')).toBe(true); + expect($table.find('tr td:last').hasClass('last')).toBe(true); + expect($table.find('tr td:first').hasClass('first')).toBe(false); + }); + + it('Check correct class decoration with custom params', function () { + var $table = $('#' + tableId); + + $table.decorate('table', { + 'tbody': ['first'], + 'tbody tr': ['first'], + 'thead tr': ['first'], + 'tfoot tr': ['last'], + 'tr td': ['first'] + }); + expect($table.find('tbody:first').hasClass('first')).toBe(true); + expect($table.find('tbody tr:first').hasClass('first')).toBe(true); + expect($table.find('tbody tr:first').hasClass('odd')).toBe(false); + expect($table.find('tbody tr:odd').hasClass('even')).toBe(false); + expect($table.find('tbody tr:even').hasClass('odd')).toBe(false); + expect($table.find('tbody tr:last').hasClass('last')).toBe(false); + expect($table.find('thead tr:first').hasClass('first')).toBe(true); + expect($table.find('thead tr:last').hasClass('last')).toBe(false); + expect($table.find('tfoot tr:first').hasClass('first')).toBe(false); + expect($table.find('tfoot tr:last').hasClass('last')).toBe(true); + expect($table.find('tr td:last').hasClass('last')).toBe(false); + expect($table.find('tr td:first').hasClass('first')).toBe(true); + }); + }); + + describe('"dataList" method', function () { + var listId = 'testDataList'; + + beforeEach(function () { + var list = $('
    '); + + $('body').append(list); + }); + + afterEach(function () { + $('#' + listId).remove(); + }); + + it('Check correct class decoration', function () { + var $list = $('#' + listId); + + $list.decorate('dataList'); + expect($list.find('dt:first').hasClass('first')).toBe(false); + expect($list.find('dt:first').hasClass('odd')).toBe(true); + expect($list.find('dt:odd').hasClass('even')).toBe(true); + expect($list.find('dt:even').hasClass('odd')).toBe(true); + expect($list.find('dt:last').hasClass('last')).toBe(true); + expect($list.find('dd:first').hasClass('first')).toBe(false); + expect($list.find('dd:first').hasClass('odd')).toBe(true); + expect($list.find('dd:odd').hasClass('even')).toBe(true); + expect($list.find('dd:even').hasClass('odd')).toBe(true); + expect($list.find('dd:last').hasClass('last')).toBe(true); + }); + }); + + describe('Call decorate with fake method', function () { + var listId = 'testDataList'; + + beforeEach(function () { + var list = $('
    '); + + $('body').append(list); + }); + + afterEach(function () { + $('#' + listId).remove(); + }); + + it('Check error message', function () { + var $list = $('#' + listId); + + spyOn($, 'error'); + $list.decorate('customMethod'); + expect($.error).toHaveBeenCalledWith('Method customMethod does not exist on jQuery.decorate'); + }); + }); + }); +}); diff --git a/dev/tests/js/jasmine/tests/lib/mage/dropdown.test.js b/dev/tests/js/jasmine/tests/lib/mage/dropdown.test.js new file mode 100644 index 0000000000000..1d149efe040e0 --- /dev/null +++ b/dev/tests/js/jasmine/tests/lib/mage/dropdown.test.js @@ -0,0 +1,357 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +/* eslint-disable max-nested-callbacks */ + +define([ + 'jquery', + 'mage/dropdown' +], function ($) { + 'use strict'; + + describe('Test for mage/dropdown jQuery plugin', function () { + it('check if dialog opens when the triggerEvent is triggered', function () { + var opener = $('
    '), + dialog = $('
    '); + + dialog.dropdownDialog({ + 'triggerEvent': 'click', + 'triggerTarget': opener + }); + + opener.trigger('click'); + expect(dialog.dropdownDialog('isOpen')).toBeTruthy(); + + dialog.dropdownDialog('destroy'); + + dialog.dropdownDialog({ + 'triggerEvent': null, + 'triggerTarget': opener + }); + + opener.trigger('click'); + expect(dialog.dropdownDialog('isOpen')).toBeFalsy(); + dialog.dropdownDialog('destroy'); + }); + + it('check if a specified class is added to the trigger', function () { + var opener = $('
    '), + dialog = $('
    '); + + dialog.dropdownDialog({ + 'triggerClass': 'active', + 'triggerTarget': opener + }); + + dialog.dropdownDialog('open'); + expect(opener.hasClass('active')).toBeTruthy(); + + dialog.dropdownDialog('close'); + dialog.dropdownDialog('destroy'); + + dialog.dropdownDialog({ + 'triggerClass': null, + 'triggerTarget': opener + }); + + dialog.dropdownDialog('open'); + expect(opener.hasClass('active')).toBeFalsy(); + + dialog.dropdownDialog('close'); + dialog.dropdownDialog('destroy'); + }); + + it('check if a specified class is added to the element which the dialog appends to', function () { + var parent = $('
    '), + dialog = $('
    '); + + dialog.dropdownDialog({ + 'parentClass': 'active', + 'appendTo': parent + }); + + dialog.dropdownDialog('open'); + expect(parent.hasClass('active')).toBeTruthy(); + + dialog.dropdownDialog('close'); + dialog.dropdownDialog('destroy'); + + dialog.dropdownDialog({ + 'parentClass': null, + 'appendTo': parent + }); + + dialog.dropdownDialog('open'); + expect(parent.hasClass('active')).toBeFalsy(); + + dialog.dropdownDialog('close'); + dialog.dropdownDialog('destroy'); + }); + + it('check if a specified class is added to the element that becomes dialog', function () { + var dialog = $('
    '), + content; + + dialog.dropdownDialog({ + 'dialogContentClass': 'active' + }); + + content = $('.ui-dialog-content'); + dialog.dropdownDialog('open'); + expect(content.hasClass('active')).toBeTruthy(); + + dialog.dropdownDialog('close'); + dialog.dropdownDialog('destroy'); + + dialog.dropdownDialog({ + 'dialogContentClass': null + }); + + dialog.dropdownDialog('open'); + expect(content.hasClass('active')).toBeFalsy(); + + dialog.dropdownDialog('close'); + dialog.dropdownDialog('destroy'); + }); + + it('check if a specified class is added to dialog', function () { + var dialog = $('
    '), + uiClass = '.ui-dialog', + ui; + + dialog.dropdownDialog({ + 'defaultDialogClass': 'custom' + }); + + ui = $(uiClass); + expect(ui.hasClass('custom')).toBeTruthy(); + expect(ui.hasClass('mage-dropdown-dialog')).toBeFalsy(); + + dialog.dropdownDialog('destroy'); + + dialog.dropdownDialog({}); + ui = $(uiClass); + expect(ui.hasClass('mage-dropdown-dialog')).toBeTruthy(); + + dialog.dropdownDialog('destroy'); + }); + + it('check if the specified trigger actually opens the dialog', function () { + var opener = $('
    '), + dialog = $('
    '); + + dialog.dropdownDialog({ + 'triggerTarget': opener + }); + + opener.trigger('click'); + expect(dialog.dropdownDialog('isOpen')).toBeTruthy(); + + dialog.dropdownDialog('close'); + dialog.dropdownDialog('destroy'); + + dialog.dropdownDialog({ + 'triggerTarget': null + }); + + opener.trigger('click'); + expect(dialog.dropdownDialog('isOpen')).toBeFalsy(); + + dialog.dropdownDialog('destroy'); + }); + + it('check if the dialog gets closed when clicking outside of it', function () { + var container = $('
    '), + outside = $('
    ').attr('id', 'outside').appendTo(container), + dialog = $('
    ').attr('id', 'dialog').appendTo(container); + + container.appendTo('body'); + + dialog.dropdownDialog({ + 'closeOnClickOutside': true + }); + + dialog.dropdownDialog('open'); + outside.trigger('click'); + expect(dialog.dropdownDialog('isOpen')).toBeFalsy(); + + dialog.dropdownDialog('destroy'); + + dialog.dropdownDialog({ + 'closeOnClickOutside': false + }); + + dialog.dropdownDialog('open'); + outside.trigger('click'); + expect(dialog.dropdownDialog('isOpen')).toBeTruthy(); + + dialog.dropdownDialog('destroy'); + }); + + it('check if the dialog gets closed when mouse leaves the dialog area', function () { + var container = $('
    '), + dialog = $('
    ').attr('id', 'dialog').appendTo(container); + + $('
    ').attr('id', 'outside').appendTo(container); + $('
    ').attr('id', 'opener').appendTo(container); + + container.appendTo('body'); + + jasmine.clock().install(); + + dialog.dropdownDialog({ + 'closeOnMouseLeave': true + }); + + dialog.dropdownDialog('open'); + dialog.trigger('mouseenter'); + expect(dialog.dropdownDialog('isOpen')).toBeTruthy(); + + dialog.trigger('mouseleave'); + + jasmine.clock().tick(10); + + expect(dialog.dropdownDialog('isOpen')).toBeFalsy(); + dialog.dropdownDialog('destroy'); + + jasmine.clock().uninstall(); + }); + + it('check if the dialog does not close when mouse leaves the dialog area', function () { + var container = $('
    '), + dialog = $('
    ').attr('id', 'dialog').appendTo(container); + + $('
    ').attr('id', 'outside').appendTo(container); + $('
    ').attr('id', 'opener').appendTo(container); + + container.appendTo('body'); + + jasmine.clock().install(); + + dialog.dropdownDialog({ + 'closeOnMouseLeave': false + }); + + dialog.dropdownDialog('open'); + dialog.trigger('mouseenter'); + dialog.trigger('mouseleave'); + jasmine.clock().tick(10); + expect(dialog.dropdownDialog('isOpen')).toBeTruthy(); + dialog.dropdownDialog('destroy'); + + jasmine.clock().uninstall(); + }); + + it('check if the dialog gets closed with the specified delay', function (done) { + var container = $('
    '), + dialog = $('
    ').attr('id', 'dialog').appendTo(container); + + $('
    ').attr('id', 'outside').appendTo(container); + $('
    ').attr('id', 'opener').appendTo(container); + + container.appendTo('body'); + + dialog.dropdownDialog({ + 'timeout': 5 + }); + + dialog.dropdownDialog('open'); + dialog.trigger('mouseenter'); + dialog.trigger('mouseleave'); + expect(dialog.dropdownDialog('isOpen')).toBeTruthy(); + + setTimeout(function () { + expect(dialog.dropdownDialog('isOpen')).toBeFalsy(); + dialog.dropdownDialog('destroy'); + done(); + }, 6); + }); + + /* + * jQuery ui version 1.9.2 belongs to the adminhtml. + * + * This test will fail on backend since backend's jquery.ui will + * add ui-dialog-titlebar class anyway on create. + */ + if ($.ui.version !== '1.9.2') { + it('check if the title bar is prevented from being created', function () { + var dialog = $('
    '), + uiClass = '.ui-dialog', + ui; + + dialog.dropdownDialog({ + 'createTitleBar': true + }); + + ui = $(uiClass); + expect(ui.find('.ui-dialog-titlebar').length > 0).toBeTruthy(); + + dialog.dropdownDialog('destroy'); + + dialog.dropdownDialog({ + 'createTitleBar': false + }); + + ui = $(uiClass); + expect(ui.find('.ui-dialog-titlebar').length <= 0).toBeTruthy(); + + dialog.dropdownDialog('destroy'); + }); + } + + it('check if the position function gets disabled', function () { + var dialog = $('
    '), + uiClass = '.ui-dialog', + ui; + + dialog.dropdownDialog({ + 'autoPosition': false + }); + + ui = $(uiClass); + dialog.dropdownDialog('open'); + expect(ui.css('top') === 'auto').toBeTruthy(); + + dialog.dropdownDialog('destroy'); + + dialog.dropdownDialog({ + 'autoPosition': true + }); + + ui = $(uiClass); + dialog.dropdownDialog('open'); + expect(ui.css('top') !== '0px').toBeTruthy(); + + dialog.dropdownDialog('destroy'); + }); + + it('check if the size function gets disabled', function () { + var dialog = $('
    '), + uiClass = '.ui-dialog', + ui; + + dialog.dropdownDialog({ + 'autoSize': true, + 'width': '300' + }); + + ui = $(uiClass); + dialog.dropdownDialog('open'); + expect(ui.css('width') === '300px').toBeTruthy(); + + dialog.dropdownDialog('destroy'); + + dialog.dropdownDialog({ + 'autoSize': false, + 'width': '300' + }); + + ui = $(uiClass); + dialog.dropdownDialog('open'); + expect(ui.css('width') === '300px').toBeFalsy(); + + dialog.dropdownDialog('destroy'); + }); + }); +}); diff --git a/dev/tests/js/jasmine/tests/lib/mage/form.test.js b/dev/tests/js/jasmine/tests/lib/mage/form.test.js new file mode 100644 index 0000000000000..6202f93da999a --- /dev/null +++ b/dev/tests/js/jasmine/tests/lib/mage/form.test.js @@ -0,0 +1,262 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +/* eslint-disable max-nested-callbacks */ +/* jscs:disable jsDoc */ + +define([ + 'jquery', + 'mage/backend/form' +], function ($) { + 'use strict'; + + /* + * jQuery ui version 1.9.2 belongs to the adminhtml. + * + * This test will fail on frontend since mage/backend/form only belongs to backend. + */ + if ($.ui.version === '1.9.2') { + describe('Test for mage/form jQuery plugin', function () { + var id = 'edit_form', + elementId = '#' + id; + + beforeEach(function () { + var element = $('
    '); + + element.appendTo('body'); + }); + + afterEach(function () { + $(elementId).remove(); + }); + + it('check if form can be initialized', function () { + var form = $(elementId).form(); + + expect(form.is(':mage-form')).toBeTruthy(); + }); + + it('check get handlers', function () { + var form = $(elementId).form(), + handlersData = form.form('option', 'handlersData'), + handlers = []; + + $.each(handlersData, function (key) { + handlers.push(key); + }); + expect(handlers.join(' ')).toBe(form.data('form')._getHandlers().join(' ')); + }); + + it('check store attribute', function () { + var form = $(elementId).form(), + initialFormAttrs = { + action: form.attr('action'), + target: form.attr('target'), + method: form.attr('method') + }; + + form.data('form')._storeAttribute('action'); + form.data('form')._storeAttribute('target'); + form.data('form')._storeAttribute('method'); + + expect(form.data('form').oldAttributes.action).toBe(initialFormAttrs.action); + expect(form.data('form').oldAttributes.target).toBe(initialFormAttrs.target); + expect(form.data('form').oldAttributes.method).toBe(initialFormAttrs.method); + }); + + it('check bind', function () { + var form = $(elementId).form(), + submitted = false, + handlersData = form.form('option', 'handlersData'); + + form.on('submit', function (e) { + submitted = true; + e.stopImmediatePropagation(); + e.preventDefault(); + }); + + $.each(handlersData, function (key) { + form.trigger(key); + expect(submitted).toBeTruthy(); + submitted = false; + }); + + form.off('submit'); + }); + + it('check get action URL', function () { + var form = $(elementId).form(), + action = form.attr('action'), + testUrl = 'new/action/url', + testArgs = { + args: { + arg: 'value' + } + }; + + form.data('form')._storeAttribute('action'); + expect(form.data('form')._getActionUrl(testArgs)).toBe(action + '/arg/value/'); + expect(form.data('form')._getActionUrl(testUrl)).toBe(testUrl); + expect(form.data('form')._getActionUrl()).toBe(action); + }); + + it('check process data', function () { + var form = $(elementId).form(), + initialFormAttrs = { + action: form.attr('action'), + target: form.attr('target'), + method: form.attr('method') + }, + testSimpleData = { + action: 'new/action/url', + target: '_blank', + method: 'POST' + }, + testActionArgsData = { + action: { + args: { + arg: 'value' + } + } + }, + processedData = form.data('form')._processData(testSimpleData); + + expect(form.data('form').oldAttributes.action).toBe(initialFormAttrs.action); + expect(form.data('form').oldAttributes.target).toBe(initialFormAttrs.target); + expect(form.data('form').oldAttributes.method).toBe(initialFormAttrs.method); + expect(processedData.action).toBe(testSimpleData.action); + expect(processedData.target).toBe(testSimpleData.target); + expect(processedData.method).toBe(testSimpleData.method); + + form.data('form')._rollback(); + processedData = form.data('form')._processData(testActionArgsData); + form.data('form')._storeAttribute('action'); + expect(processedData.action).toBe(form.data('form')._getActionUrl(testActionArgsData.action)); + }); + + it('check before submit', function () { + var testForm = $('
    ').appendTo('body'), + testHandler = { + action: { + args: { + arg1: 'value1' + } + } + }, + form = $(elementId).form({ + handlersData: { + testHandler: testHandler + } + }), + beforeSubmitData = { + action: { + args: { + arg2: 'value2' + } + }, + target: '_blank' + }, + eventData = { + method: 'POST' + }, + resultData = $.extend(true, {}, testHandler, beforeSubmitData, eventData); + + form.data('form')._storeAttribute('action'); + resultData = form.data('form')._processData(resultData); + testForm.prop(resultData); + + form.on('beforeSubmit', function (e, data) { + $.extend(data, beforeSubmitData); + }); + + form.on('submit', function (e) { + e.stopImmediatePropagation(); + e.preventDefault(); + }); + + form.data('form')._beforeSubmit('testHandler', eventData); + expect(testForm.prop('action')).toBe(form.prop('action')); + expect(testForm.prop('target')).toBe(form.prop('target')); + expect(testForm.prop('method')).toBe(form.prop('method')); + }); + + it('check submit', function () { + var formSubmitted = false, + form = $(elementId).form({ + handlersData: { + save: {} + } + }); + + form.data('form')._storeAttribute('action'); + form.data('form')._storeAttribute('target'); + form.data('form')._storeAttribute('method'); + + form.on('submit', function (e) { + e.preventDefault(); + e.stopImmediatePropagation(); + e.preventDefault(); + formSubmitted = true; + }).prop({ + action: 'new/action/url', + target: '_blank', + method: 'POST' + }); + + form.data('form')._submit({ + type: 'save' + }); + + expect(form.attr('action')).toBe(form.data('form').oldAttributes.action); + expect(form.attr('target')).toBe(form.data('form').oldAttributes.target); + expect(form.attr('method')).toBe(form.data('form').oldAttributes.method); + expect(formSubmitted).toBeTruthy(); + + form.off('submit'); + }); + + it('check build URL', function () { + var dataProvider = [ + { + params: ['http://domain.com//', { + 'key[one]': 'value 1', + 'key2': '# value' + }], + expected: 'http://domain.com/key[one]/value%201/key2/%23%20value/' + }, + { + params: ['http://domain.com', { + 'key[one]': 'value 1', + 'key2': '# value' + }], + expected: 'http://domain.com/key[one]/value%201/key2/%23%20value/' + }, + { + params: ['http://domain.com?some=param', { + 'key[one]': 'value 1', + 'key2': '# value' + }], + expected: 'http://domain.com?some=param&key[one]=value%201&key2=%23%20value' + }, + { + params: ['http://domain.com?some=param&', { + 'key[one]': 'value 1', + 'key2': '# value' + }], + expected: 'http://domain.com?some=param&key[one]=value%201&key2=%23%20value' + } + ], + method = $.mage.form._proto._buildURL, + quantity = dataProvider.length, + i = 0; + + expect(quantity).toBeTruthy(); + + for (i; i < quantity; i++) { + expect(dataProvider[i].expected).toBe(method.apply(null, dataProvider[i].params)); + } + }); + }); + } +}); diff --git a/dev/tests/js/jasmine/tests/lib/mage/loader.test.js b/dev/tests/js/jasmine/tests/lib/mage/loader.test.js new file mode 100644 index 0000000000000..93dd2ee91902c --- /dev/null +++ b/dev/tests/js/jasmine/tests/lib/mage/loader.test.js @@ -0,0 +1,79 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/* eslint-disable max-nested-callbacks */ +define([ + 'jquery', + 'mage/loader' +], function ($) { + 'use strict'; + + describe('mage/loader', function () { + describe('Check loader', function () { + var loaderSelector = '#loader'; + + beforeEach(function () { + var $loader = $('
    '); + + $('body').append($loader); + }); + + afterEach(function () { + $(loaderSelector).remove(); + $(loaderSelector).loader('destroy'); + }); + + it('Check that loader inited', function () { + var $loader = $(loaderSelector).loader({ + icon: 'icon.gif' + }); + + $loader.loader('show'); + + expect($loader.is(':mage-loader')).toBe(true); + expect($loader.find('p').text()).toBe('Please wait...'); + expect($loader.find('img').prop('src').split('/').pop()).toBe('icon.gif'); + expect($loader.find('img').prop('alt')).toBe('Loading...'); + }); + + it('Body init', function () { + var $loader = $('body').loader(); + + $loader.loader('show'); + + expect($loader.is(':mage-loader')).toBe(true); + $loader.loader('destroy'); + }); + + it('Check show/hide', function () { + var $loader = $(loaderSelector).loader(), + $loadingMask; + + $loader.loader('show'); + $loadingMask = $('.loading-mask'); + expect($loadingMask.is(':visible')).toBe(true); + + $loader.loader('hide'); + expect($loadingMask.is(':hidden')).toBe(true); + + $loader.loader('show'); + $loader.trigger('processStop'); + expect($loadingMask.is(':hidden')).toBe(true); + }); + + it('Check destroy', function () { + var $loader = $(loaderSelector).loader(), + $loadingMask; + + $loader.loader('show'); + $loadingMask = $('.loading-mask'); + expect($loadingMask.is(':visible')).toBe(true); + + $loader.loader('destroy'); + expect($loadingMask.is(':visible')).toBe(false); + }); + }); + }); +}); diff --git a/dev/tests/js/jasmine/tests/lib/mage/menu.test.js b/dev/tests/js/jasmine/tests/lib/mage/menu.test.js new file mode 100644 index 0000000000000..69d8af4ff3dba --- /dev/null +++ b/dev/tests/js/jasmine/tests/lib/mage/menu.test.js @@ -0,0 +1,110 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/* eslint-disable max-nested-callbacks */ +define([ + 'jquery', + 'mage/menu', + 'text!tests/assets/lib/web/mage/menu.html' +], function ($, menu, menuTmpl) { + 'use strict'; + + describe('mage/menu', function () { + describe('Menu expanded', function () { + var menuSelector = '#menu'; + + beforeEach(function () { + var $menu = $(menuTmpl); + + $('body').append($menu); + }); + + afterEach(function () { + $(menuSelector).remove(); + }); + + it('Check that menu expanded', function () { + var $menu = $(menuSelector), + $menuItems = $menu.find('li'), + $submenu = $menuItems.find('ul'); + + menu.menu({ + expanded: true + }, $menu); + expect($submenu.hasClass('expanded')).toBe(true); + }); + }); + + describe('Menu hover event', function () { + var menuSelector = '#menu', + $menu; + + beforeEach(function () { + var $menuObject = $(menuTmpl); + + $('body').append($menuObject); + $menu = $(menuSelector).menu({ + delay: 0, + showDelay: 0, + hideDelay: 0 + }); + }); + + afterEach(function () { + $(menuSelector).remove(); + }); + + it('Check that menu expanded', function (done) { + var $menuItem = $menu.find('li.test-menu-item'), + $submenu = $menuItem.find('ul'); + + $menuItem.trigger('mouseover'); + setTimeout(function () { + expect($submenu.attr('aria-expanded')).toBe('true'); + $menuItem.trigger('mouseout'); + setTimeout(function () { + expect($submenu.attr('aria-expanded')).toBe('false'); + done(); + }, 300); + }, 300); + }); + }); + + describe('Menu navigation', function () { + var menuSelector = '#menu', + $menu; + + beforeEach(function () { + var $menuObject = $(menuTmpl); + + $('body').append($menuObject); + $menu = $(menuSelector).menu(); + }); + + afterEach(function () { + $(menuSelector).remove(); + }); + + it('Check max item limit', function () { + var $menuItems; + + $menu.navigation({ + maxItems: 3 + }); + $menuItems = $menu.find('li:visible'); + + expect($menuItems.length).toBe(4); + }); + + it('Check that More Menu item will be added', function () { + $menu.navigation({ + responsive: 'onResize' + }); + + expect($('body').find('.ui-menu-more').length).toBeGreaterThan(0); + }); + }); + }); +}); diff --git a/dev/tests/js/jasmine/tests/lib/mage/tabs.test.js b/dev/tests/js/jasmine/tests/lib/mage/tabs.test.js new file mode 100644 index 0000000000000..a6138df073434 --- /dev/null +++ b/dev/tests/js/jasmine/tests/lib/mage/tabs.test.js @@ -0,0 +1,93 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/* eslint-disable max-nested-callbacks */ +define([ + 'jquery', + 'jquery/ui', + 'mage/tabs', + 'text!tests/assets/lib/web/mage/tabs.html' +], function ($, ui, tabs, tabsTmpl) { + 'use strict'; + + describe('mage/tabs', function () { + var tabsSelector = '#tabs'; + + beforeEach(function () { + var $tabs = $(tabsTmpl); + + $('body').append($tabs); + }); + + afterEach(function () { + $(tabsSelector).remove(); + $(tabsSelector).tabs('destroy'); + }); + + it('Check tabs inited', function () { + var $tabs = $(tabsSelector).tabs(); + + expect($tabs.is(':mage-tabs')).toBe(true); + }); + + it('Check tabs collapsible inited', function () { + var $title1 = $('#title1'), + $title2 = $('#title2'); + + $(tabsSelector).tabs(); + + expect($title1.is(':mage-collapsible')).toBe(true); + expect($title2.is(':mage-collapsible')).toBe(true); + }); + + it('Check tabs active', function () { + var $content1 = $('#content1'), + $content2 = $('#content2'); + + $(tabsSelector).tabs({ + active: 1 + }); + + expect($content1.is(':hidden')).toBe(true); + expect($content2.is(':visible')).toBe(true); + }); + + it('Check tabs closing others tabs when one gets activated', function () { + var $title2 = $('#title2'), + $content1 = $('#content1'), + $content2 = $('#content2'); + + $(tabsSelector).tabs(); + + expect($content1.is(':visible')).toBe(true); + expect($content2.is(':hidden')).toBe(true); + + $title2.trigger('click'); + + expect($content1.is(':hidden')).toBe(true); + expect($content2.is(':visible')).toBe(true); + }); + + it('Check tabs enable,disable,activate,deactivate options', function () { + var $title1 = $('#title1'), + $content1 = $('#content1'), + $tabs = $(tabsSelector).tabs(); + + expect($content1.is(':visible')).toBe(true); + $tabs.tabs('deactivate', 0); + expect($content1.is(':hidden')).toBe(true); + $tabs.tabs('activate', 0); + expect($content1.is(':visible')).toBe(true); + $tabs.tabs('disable', 0); + expect($content1.is(':hidden')).toBe(true); + $title1.trigger('click'); + expect($content1.is(':hidden')).toBe(true); + $tabs.tabs('enable', 0); + expect($content1.is(':visible')).toBe(true); + $title1.trigger('click'); + expect($content1.is(':visible')).toBe(true); + }); + }); +}); diff --git a/dev/tests/js/jasmine/tests/lib/mage/translate-inline.test.js b/dev/tests/js/jasmine/tests/lib/mage/translate-inline.test.js new file mode 100644 index 0000000000000..bcdfc4cc59705 --- /dev/null +++ b/dev/tests/js/jasmine/tests/lib/mage/translate-inline.test.js @@ -0,0 +1,111 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/* eslint-disable max-nested-callbacks */ +define([ + 'jquery', + 'mage/translate-inline', + 'text!tests/assets/lib/web/mage/translate-inline.html' +], function ($, TranslateInline, translateTmpl) { + 'use strict'; + + describe('mage/translate-inline', function () { + describe('Check translate', function () { + var translateSelector = '[data-role="translate-dialog"]', + translateTemplateSelector = '#translate-form-template'; + + beforeEach(function () { + var translateBlock = $(translateTmpl); + + $('body').append(translateBlock); + }); + + afterEach(function () { + $(translateSelector).remove(); + $(translateSelector).translateInline('destroy'); + $(translateTemplateSelector).remove(); + }); + + it('Check that translate inited', function () { + var translateInline = $(translateSelector).translateInline(); + + expect(translateInline.is(':mage-translateInline')).toBe(true); + }); + + it('Check that translate hidden on init and visible on trigger', function () { + var translateInline = $(translateSelector).translateInline({ + id: 'dialog-id' + }), + isDialogHiddenOnInit = translateInline.is(':hidden'), + dialogVisibleAfterTriggerEdit; + + translateInline.trigger('edit.editTrigger'); + dialogVisibleAfterTriggerEdit = translateInline.is(':visible'); + expect(isDialogHiddenOnInit).toBe(true); + expect(dialogVisibleAfterTriggerEdit).toBe(true); + }); + + it('Check translation form template', function () { + var translateFormId = 'translate-form-id', + translateFormContent = 'New Template Variable', + translateInline = $(translateSelector).translateInline({ + translateForm: { + data: { + id: translateFormId, + newTemplateVariable: translateFormContent + } + } + }), + $translateForm; + + translateInline.trigger('edit.editTrigger'); + $translateForm = $('#' + translateFormId); + + expect($translateForm.length).toBeGreaterThan(0); + expect($translateForm.text()).toBe(translateFormContent); + }); + + it('Check translation submit', function () { + var options = { + ajaxUrl: 'www.test.com', + area: 'test', + translateForm: { + template: '
    ', + data: { + id: 'translate-form-id' + } + } + }, + expectedEequestData = 'area=test&test=test', + translateInline = $(translateSelector).translateInline(options), + $submitButton = $('body').find('.action-primary'), + originalAjax = $.ajax; + + $.ajax = jasmine.createSpy().and.callFake(function (request) { + expect(request.url).toBe(options.ajaxUrl); + expect(request.type).toBe('POST'); + expect(request.data).toBe(expectedEequestData); + + return { + complete: jasmine.createSpy() + }; + }); + + translateInline.trigger('edit.editTrigger'); + $submitButton.trigger('click'); + $.ajax = originalAjax; + }); + + it('Check translation destroy', function () { + var translateInline = $(translateSelector).translateInline(); + + translateInline.trigger('edit.editTrigger'); + expect(translateInline.is(':mage-translateInline')).toBe(true); + translateInline.translateInline('destroy'); + expect(translateInline.is(':mage-translateInline')).toBe(false); + }); + }); + }); +}); diff --git a/dev/tests/js/jasmine/tests/lib/mage/translate.test.js b/dev/tests/js/jasmine/tests/lib/mage/translate.test.js new file mode 100644 index 0000000000000..c87cfa227c1aa --- /dev/null +++ b/dev/tests/js/jasmine/tests/lib/mage/translate.test.js @@ -0,0 +1,49 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +/* eslint-disable max-nested-callbacks */ +define([ + 'jquery', + 'mage/translate' +], function ($) { + 'use strict'; + + describe('Test for mage/translate jQuery plugin', function () { + it('works with one string as parameter', function () { + $.mage.translate.add('Hello World!'); + expect('Hello World!').toEqual($.mage.translate.translate('Hello World!')); + }); + it('works with one array as parameter', function () { + $.mage.translate.add(['Hello World!', 'Bonjour tout le monde!']); + expect('Hello World!').toEqual($.mage.translate.translate('Hello World!')); + }); + it('works with one object as parameter', function () { + var translation = { + 'Hello World!': 'Bonjour tout le monde!' + }; + + $.mage.translate.add(translation); + expect(translation['Hello World!']).toEqual($.mage.translate.translate('Hello World!')); + + translation = { + 'Hello World!': 'Hallo Welt!', + 'Some text with symbols!-+"%#*': 'Ein Text mit Symbolen!-+"%#*' + }; + + $.mage.translate.add(translation); + $.each(translation, function (key) { + expect(translation[key]).toEqual($.mage.translate.translate(key)); + }); + }); + it('works with two string as parameter', function () { + $.mage.translate.add('Hello World!', 'Bonjour tout le monde!'); + expect('Bonjour tout le monde!').toEqual($.mage.translate.translate('Hello World!')); + }); + it('works with translation alias __', function () { + $.mage.translate.add('Hello World!'); + expect('Hello World!').toEqual($.mage.__('Hello World!')); + }); + }); + +}); diff --git a/dev/tests/js/jasmine/tests/lib/mage/validation.test.js b/dev/tests/js/jasmine/tests/lib/mage/validation.test.js index 50931f940c689..1e1203d22a1e3 100644 --- a/dev/tests/js/jasmine/tests/lib/mage/validation.test.js +++ b/dev/tests/js/jasmine/tests/lib/mage/validation.test.js @@ -183,4 +183,963 @@ define([ )).toEqual(true); }); }); + + describe('Testing validate-no-html-tags', function () { + it('validate-no-html-tags', function () { + expect($.validator.methods['validate-no-html-tags'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-no-html-tags'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-no-html-tags'] + .call($.validator.prototype, 'abc')).toEqual(true); + expect($.validator.methods['validate-no-html-tags'] + .call($.validator.prototype, '
    abc
    ')).toEqual(false); + }); + }); + + describe('Testing allow-container-className', function () { + it('allow-container-className', function () { + var radio = $(''), + checkbox = $(''), + radio2 = $(''), + checkbox2 = $(''); + + expect($.validator.methods['allow-container-className'] + .call($.validator.prototype, radio[0])).toEqual(true); + expect($.validator.methods['allow-container-className'] + .call($.validator.prototype, checkbox[0])).toEqual(true); + expect($.validator.methods['allow-container-className'] + .call($.validator.prototype, radio2[0])).toEqual(false); + expect($.validator.methods['allow-container-className'] + .call($.validator.prototype, checkbox2[0])).toEqual(false); + }); + }); + + describe('Testing validate-select', function () { + it('validate-select', function () { + expect($.validator.methods['validate-select'] + .call($.validator.prototype, '')).toEqual(false); + expect($.validator.methods['validate-select'] + .call($.validator.prototype, 'none')).toEqual(false); + expect($.validator.methods['validate-select'] + .call($.validator.prototype, null)).toEqual(false); + expect($.validator.methods['validate-select'] + .call($.validator.prototype, undefined)).toEqual(false); + expect($.validator.methods['validate-select'] + .call($.validator.prototype, 'abc')).toEqual(true); + }); + }); + + describe('Testing validate-no-empty', function () { + it('validate-no-empty', function () { + expect($.validator.methods['validate-no-empty'] + .call($.validator.prototype, '')).toEqual(false); + expect($.validator.methods['validate-no-empty'] + .call($.validator.prototype, null)).toEqual(false); + expect($.validator.methods['validate-no-empty'] + .call($.validator.prototype, undefined)).toEqual(false); + expect($.validator.methods['validate-no-empty'] + .call($.validator.prototype, ' ')).toEqual(false); + expect($.validator.methods['validate-no-empty'] + .call($.validator.prototype, 'test')).toEqual(true); + }); + }); + + describe('Testing validate-alphanum-with-spaces', function () { + it('validate-alphanum-with-spaces', function () { + expect($.validator.methods['validate-alphanum-with-spaces'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-alphanum-with-spaces'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-alphanum-with-spaces'] + .call($.validator.prototype, undefined)).toEqual(true); + expect($.validator.methods['validate-alphanum-with-spaces'] + .call($.validator.prototype, ' ')).toEqual(true); + expect($.validator.methods['validate-alphanum-with-spaces'] + .call($.validator.prototype, 'abc ')).toEqual(true); + expect($.validator.methods['validate-alphanum-with-spaces'] + .call($.validator.prototype, ' 123 ')).toEqual(true); + expect($.validator.methods['validate-alphanum-with-spaces'] + .call($.validator.prototype, ' abc123 ')).toEqual(true); + expect($.validator.methods['validate-alphanum-with-spaces'] + .call($.validator.prototype, ' !@# ')).toEqual(false); + expect($.validator.methods['validate-alphanum-with-spaces'] + .call($.validator.prototype, ' abc.123 ')).toEqual(false); + }); + }); + + describe('Testing validate-phoneStrict', function () { + it('validate-phoneStrict', function () { + expect($.validator.methods['validate-phoneStrict'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-phoneStrict'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-phoneStrict'] + .call($.validator.prototype, undefined)).toEqual(true); + expect($.validator.methods['validate-phoneStrict'] + .call($.validator.prototype, ' ')).toEqual(false); + expect($.validator.methods['validate-phoneStrict'] + .call($.validator.prototype, '5121231234')).toEqual(false); + expect($.validator.methods['validate-phoneStrict'] + .call($.validator.prototype, '512.123.1234')).toEqual(false); + expect($.validator.methods['validate-phoneStrict'] + .call($.validator.prototype, '512-123-1234')).toEqual(true); + expect($.validator.methods['validate-phoneStrict'] + .call($.validator.prototype, '(512)123-1234')).toEqual(true); + expect($.validator.methods['validate-phoneStrict'] + .call($.validator.prototype, '(512) 123-1234')).toEqual(true); + }); + }); + + describe('Testing validate-phoneLax', function () { + it('validate-phoneLax', function () { + expect($.validator.methods['validate-phoneLax'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-phoneLax'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-phoneLax'] + .call($.validator.prototype, undefined)).toEqual(true); + expect($.validator.methods['validate-phoneLax'] + .call($.validator.prototype, ' ')).toEqual(false); + expect($.validator.methods['validate-phoneLax'] + .call($.validator.prototype, '5121231234')).toEqual(true); + expect($.validator.methods['validate-phoneLax'] + .call($.validator.prototype, '512.123.1234')).toEqual(true); + expect($.validator.methods['validate-phoneLax'] + .call($.validator.prototype, '512-123-1234')).toEqual(true); + expect($.validator.methods['validate-phoneLax'] + .call($.validator.prototype, '(512)123-1234')).toEqual(true); + expect($.validator.methods['validate-phoneLax'] + .call($.validator.prototype, '(512) 123-1234')).toEqual(true); + expect($.validator.methods['validate-phoneLax'] + .call($.validator.prototype, '(512)1231234')).toEqual(true); + expect($.validator.methods['validate-phoneLax'] + .call($.validator.prototype, '(512)_123_1234')).toEqual(false); + }); + }); + + describe('Testing validate-fax', function () { + it('validate-fax', function () { + expect($.validator.methods['validate-fax'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-fax'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-fax'] + .call($.validator.prototype, undefined)).toEqual(true); + expect($.validator.methods['validate-fax'] + .call($.validator.prototype, ' ')).toEqual(false); + expect($.validator.methods['validate-fax'] + .call($.validator.prototype, '5121231234')).toEqual(false); + expect($.validator.methods['validate-fax'] + .call($.validator.prototype, '512.123.1234')).toEqual(false); + expect($.validator.methods['validate-fax'] + .call($.validator.prototype, '512-123-1234')).toEqual(true); + expect($.validator.methods['validate-fax'] + .call($.validator.prototype, '(512)123-1234')).toEqual(true); + expect($.validator.methods['validate-fax'] + .call($.validator.prototype, '(512) 123-1234')).toEqual(true); + }); + }); + + describe('Testing validate-email', function () { + it('validate-email', function () { + expect($.validator.methods['validate-email'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-email'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-email'] + .call($.validator.prototype, undefined)).toEqual(true); + expect($.validator.methods['validate-email'] + .call($.validator.prototype, ' ')).toEqual(false); + expect($.validator.methods['validate-email'] + .call($.validator.prototype, '123@123.com')).toEqual(true); + expect($.validator.methods['validate-email'] + .call($.validator.prototype, 'abc@124.en')).toEqual(true); + expect($.validator.methods['validate-email'] + .call($.validator.prototype, 'abc@abc.commmmm')).toEqual(true); + expect($.validator.methods['validate-email'] + .call($.validator.prototype, 'abc.abc.abc@abc.commmmm')).toEqual(true); + expect($.validator.methods['validate-email'] + .call($.validator.prototype, 'abc.abc-abc@abc.commmmm')).toEqual(true); + expect($.validator.methods['validate-email'] + .call($.validator.prototype, 'abc.abc_abc@abc.commmmm')).toEqual(true); + expect($.validator.methods['validate-email'] + .call($.validator.prototype, 'abc.abc_abc@abc')).toEqual(false); + }); + }); + + describe('Testing validate-emailSender', function () { + it('validate-emailSender', function () { + expect($.validator.methods['validate-emailSender'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-emailSender'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-emailSender'] + .call($.validator.prototype, undefined)).toEqual(true); + expect($.validator.methods['validate-emailSender'] + .call($.validator.prototype, ' ')).toEqual(true); + expect($.validator.methods['validate-emailSender'] + .call($.validator.prototype, '123@123.com')).toEqual(true); + expect($.validator.methods['validate-emailSender'] + .call($.validator.prototype, 'abc@124.en')).toEqual(true); + expect($.validator.methods['validate-emailSender'] + .call($.validator.prototype, 'abc@abc.commmmm')).toEqual(true); + expect($.validator.methods['validate-emailSender'] + .call($.validator.prototype, 'abc.abc.abc@abc.commmmm')).toEqual(true); + expect($.validator.methods['validate-emailSender'] + .call($.validator.prototype, 'abc.abc-abc@abc.commmmm')).toEqual(true); + expect($.validator.methods['validate-emailSender'] + .call($.validator.prototype, 'abc.abc_abc@abc.commmmm')).toEqual(true); + }); + }); + + describe('Testing validate-password', function () { + it('validate-password', function () { + expect($.validator.methods['validate-password'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-password'] + .call($.validator.prototype, null)).toEqual(false); + expect($.validator.methods['validate-password'] + .call($.validator.prototype, undefined)).toEqual(false); + expect($.validator.methods['validate-password'] + .call($.validator.prototype, ' ')).toEqual(true); + expect($.validator.methods['validate-password'] + .call($.validator.prototype, '123@123.com')).toEqual(true); + expect($.validator.methods['validate-password'] + .call($.validator.prototype, 'abc')).toEqual(false); + expect($.validator.methods['validate-password'] + .call($.validator.prototype, 'abc ')).toEqual(false); + expect($.validator.methods['validate-password'] + .call($.validator.prototype, ' abc ')).toEqual(false); + expect($.validator.methods['validate-password'] + .call($.validator.prototype, 'dddd')).toEqual(false); + }); + }); + + describe('Testing validate-admin-password', function () { + it('validate-admin-password', function () { + expect($.validator.methods['validate-admin-password'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-admin-password'] + .call($.validator.prototype, null)).toEqual(false); + expect($.validator.methods['validate-admin-password'] + .call($.validator.prototype, undefined)).toEqual(false); + expect($.validator.methods['validate-admin-password'] + .call($.validator.prototype, ' ')).toEqual(true); + expect($.validator.methods['validate-admin-password'] + .call($.validator.prototype, '123@123.com')).toEqual(true); + expect($.validator.methods['validate-admin-password'] + .call($.validator.prototype, 'abc')).toEqual(false); + expect($.validator.methods['validate-admin-password'] + .call($.validator.prototype, 'abc ')).toEqual(false); + expect($.validator.methods['validate-admin-password'] + .call($.validator.prototype, ' abc ')).toEqual(false); + expect($.validator.methods['validate-admin-password'] + .call($.validator.prototype, 'dddd')).toEqual(false); + }); + }); + + describe('Testing validate-url', function () { + it('validate-url', function () { + expect($.validator.methods['validate-url'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-url'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-url'] + .call($.validator.prototype, undefined)).toEqual(true); + expect($.validator.methods['validate-url'] + .call($.validator.prototype, ' ')).toEqual(false); + expect($.validator.methods['validate-url'] + .call($.validator.prototype, 'http://www.google.com')).toEqual(true); + expect($.validator.methods['validate-url'] + .call($.validator.prototype, 'http://127.0.0.1:8080/index.php')).toEqual(true); + expect($.validator.methods['validate-url'] + .call($.validator.prototype, 'http://app-spot.com/index.php')).toEqual(true); + expect($.validator.methods['validate-url'] + .call($.validator.prototype, 'http://app-spot_space.com/index.php')).toEqual(true); + }); + }); + + describe('Testing validate-clean-url', function () { + it('validate-clean-url', function () { + expect($.validator.methods['validate-clean-url'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-clean-url'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-clean-url'] + .call($.validator.prototype, undefined)).toEqual(true); + expect($.validator.methods['validate-clean-url'] + .call($.validator.prototype, ' ')).toEqual(false); + expect($.validator.methods['validate-clean-url'] + .call($.validator.prototype, 'http://www.google.com')).toEqual(true); + expect($.validator.methods['validate-clean-url'] + .call($.validator.prototype, 'http://127.0.0.1:8080/index.php')).toEqual(false); + expect($.validator.methods['validate-clean-url'] + .call($.validator.prototype, 'http://127.0.0.1:8080')).toEqual(false); + expect($.validator.methods['validate-clean-url'] + .call($.validator.prototype, 'http://127.0.0.1')).toEqual(false); + }); + }); + + describe('Testing validate-xml-identifier', function () { + it('validate-xml-identifier', function () { + expect($.validator.methods['validate-xml-identifier'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-xml-identifier'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-xml-identifier'] + .call($.validator.prototype, undefined)).toEqual(true); + expect($.validator.methods['validate-xml-identifier'] + .call($.validator.prototype, ' ')).toEqual(false); + expect($.validator.methods['validate-xml-identifier'] + .call($.validator.prototype, 'abc')).toEqual(true); + expect($.validator.methods['validate-xml-identifier'] + .call($.validator.prototype, 'abc_123')).toEqual(true); + expect($.validator.methods['validate-xml-identifier'] + .call($.validator.prototype, 'abc-123')).toEqual(true); + expect($.validator.methods['validate-xml-identifier'] + .call($.validator.prototype, '123-abc')).toEqual(false); + }); + }); + + describe('Testing validate-ssn', function () { + it('validate-ssn', function () { + expect($.validator.methods['validate-ssn'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-ssn'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-ssn'] + .call($.validator.prototype, undefined)).toEqual(true); + expect($.validator.methods['validate-ssn'] + .call($.validator.prototype, ' ')).toEqual(false); + expect($.validator.methods['validate-ssn'] + .call($.validator.prototype, 'abc')).toEqual(false); + expect($.validator.methods['validate-ssn'] + .call($.validator.prototype, '123-13-1234')).toEqual(true); + expect($.validator.methods['validate-ssn'] + .call($.validator.prototype, '012-12-1234')).toEqual(true); + expect($.validator.methods['validate-ssn'] + .call($.validator.prototype, '23-12-1234')).toEqual(false); + }); + }); + + describe('Testing validate-zip-us', function () { + it('validate-zip-us', function () { + expect($.validator.methods['validate-zip-us'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-zip-us'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-zip-us'] + .call($.validator.prototype, undefined)).toEqual(true); + expect($.validator.methods['validate-zip-us'] + .call($.validator.prototype, ' ')).toEqual(false); + expect($.validator.methods['validate-zip-us'] + .call($.validator.prototype, '12345-1234')).toEqual(true); + expect($.validator.methods['validate-zip-us'] + .call($.validator.prototype, '02345')).toEqual(true); + expect($.validator.methods['validate-zip-us'] + .call($.validator.prototype, '1234')).toEqual(false); + expect($.validator.methods['validate-zip-us'] + .call($.validator.prototype, '1234-1234')).toEqual(false); + }); + }); + + describe('Testing validate-date-au', function () { + it('validate-date-au', function () { + expect($.validator.methods['validate-date-au'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-date-au'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-date-au'] + .call($.validator.prototype, undefined)).toEqual(true); + expect($.validator.methods['validate-date-au'] + .call($.validator.prototype, ' ')).toEqual(false); + expect($.validator.methods['validate-date-au'] + .call($.validator.prototype, '01/01/2012')).toEqual(true); + expect($.validator.methods['validate-date-au'] + .call($.validator.prototype, '30/01/2012')).toEqual(true); + expect($.validator.methods['validate-date-au'] + .call($.validator.prototype, '01/30/2012')).toEqual(false); + expect($.validator.methods['validate-date-au'] + .call($.validator.prototype, '1/1/2012')).toEqual(false); + }); + }); + + describe('Testing validate-currency-dollar', function () { + it('validate-currency-dollar', function () { + expect($.validator.methods['validate-currency-dollar'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-currency-dollar'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-currency-dollar'] + .call($.validator.prototype, undefined)).toEqual(true); + expect($.validator.methods['validate-currency-dollar'] + .call($.validator.prototype, ' ')).toEqual(false); + expect($.validator.methods['validate-currency-dollar'] + .call($.validator.prototype, '$123')).toEqual(true); + expect($.validator.methods['validate-currency-dollar'] + .call($.validator.prototype, '$1,123.00')).toEqual(true); + expect($.validator.methods['validate-currency-dollar'] + .call($.validator.prototype, '$1234')).toEqual(true); + expect($.validator.methods['validate-currency-dollar'] + .call($.validator.prototype, '$1234.1234')).toEqual(false); + }); + }); + + describe('Testing validate-not-negative-number', function () { + it('validate-not-negative-number', function () { + expect($.validator.methods['validate-not-negative-number'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-not-negative-number'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-not-negative-number'] + .call($.validator.prototype, undefined)).toEqual(true); + expect($.validator.methods['validate-not-negative-number'] + .call($.validator.prototype, ' ')).toEqual(false); + expect($.validator.methods['validate-not-negative-number'] + .call($.validator.prototype, '0')).toEqual(true); + expect($.validator.methods['validate-not-negative-number'] + .call($.validator.prototype, '1')).toEqual(true); + expect($.validator.methods['validate-not-negative-number'] + .call($.validator.prototype, '1234')).toEqual(true); + expect($.validator.methods['validate-not-negative-number'] + .call($.validator.prototype, '1,234.1234')).toEqual(true); + expect($.validator.methods['validate-not-negative-number'] + .call($.validator.prototype, '-1')).toEqual(false); + expect($.validator.methods['validate-not-negative-number'] + .call($.validator.prototype, '-1e')).toEqual(false); + expect($.validator.methods['validate-not-negative-number'] + .call($.validator.prototype, '-1,234.1234')).toEqual(false); + }); + }); + + describe('Testing validate-greater-than-zero', function () { + it('validate-greater-than-zero', function () { + expect($.validator.methods['validate-greater-than-zero'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-greater-than-zero'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-greater-than-zero'] + .call($.validator.prototype, undefined)).toEqual(true); + expect($.validator.methods['validate-greater-than-zero'] + .call($.validator.prototype, ' ')).toEqual(false); + expect($.validator.methods['validate-greater-than-zero'] + .call($.validator.prototype, '0')).toEqual(false); + expect($.validator.methods['validate-greater-than-zero'] + .call($.validator.prototype, '1')).toEqual(true); + expect($.validator.methods['validate-greater-than-zero'] + .call($.validator.prototype, '1234')).toEqual(true); + expect($.validator.methods['validate-greater-than-zero'] + .call($.validator.prototype, '1,234.1234')).toEqual(true); + expect($.validator.methods['validate-greater-than-zero'] + .call($.validator.prototype, '-1')).toEqual(false); + expect($.validator.methods['validate-greater-than-zero'] + .call($.validator.prototype, '-1e')).toEqual(false); + expect($.validator.methods['validate-greater-than-zero'] + .call($.validator.prototype, '-1,234.1234')).toEqual(false); + }); + }); + + describe('Testing validate-css-length', function () { + it('validate-css-length', function () { + expect($.validator.methods['validate-css-length'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-css-length'] + .call($.validator.prototype, null)).toEqual(false); + expect($.validator.methods['validate-css-length'] + .call($.validator.prototype, undefined)).toEqual(false); + expect($.validator.methods['validate-css-length'] + .call($.validator.prototype, ' ')).toEqual(false); + expect($.validator.methods['validate-css-length'] + .call($.validator.prototype, '0')).toEqual(true); + expect($.validator.methods['validate-css-length'] + .call($.validator.prototype, '1')).toEqual(true); + expect($.validator.methods['validate-css-length'] + .call($.validator.prototype, '1234')).toEqual(true); + expect($.validator.methods['validate-css-length'] + .call($.validator.prototype, '1,234.1234')).toEqual(false); + expect($.validator.methods['validate-css-length'] + .call($.validator.prototype, '-1')).toEqual(false); + expect($.validator.methods['validate-css-length'] + .call($.validator.prototype, '-1e')).toEqual(false); + expect($.validator.methods['validate-css-length'] + .call($.validator.prototype, '-1,234.1234')).toEqual(false); + }); + }); + + describe('Testing validate-data', function () { + it('validate-data', function () { + expect($.validator.methods['validate-data'] + .call($.validator.prototype, '')).toEqual(true); + expect($.validator.methods['validate-data'] + .call($.validator.prototype, null)).toEqual(true); + expect($.validator.methods['validate-data'] + .call($.validator.prototype, undefined)).toEqual(true); + expect($.validator.methods['validate-data'] + .call($.validator.prototype, ' ')).toEqual(false); + expect($.validator.methods['validate-data'] + .call($.validator.prototype, '123abc')).toEqual(false); + expect($.validator.methods['validate-data'] + .call($.validator.prototype, 'abc')).toEqual(true); + expect($.validator.methods['validate-data'] + .call($.validator.prototype, ' abc')).toEqual(false); + expect($.validator.methods['validate-data'] + .call($.validator.prototype, 'abc123')).toEqual(true); + expect($.validator.methods['validate-data'] + .call($.validator.prototype, 'abc-123')).toEqual(false); + }); + }); + + describe('Testing validate-one-required-by-name', function () { + it('validate-one-required-by-name', function () { + var radio = $(''), + radio2 = $(''), + checkbox = $(''), + checkbox2 = $(''), + $test = $('
    '), + prevForm = $.validator.prototype.currentForm; + + $.validator.prototype.currentForm = $test[0]; + + $test.append(radio); + expect($.validator.methods['validate-one-required-by-name'] + .call($.validator.prototype, null, radio[0], true)).toEqual(false); + $test.append(radio2); + expect($.validator.methods['validate-one-required-by-name'] + .call($.validator.prototype, null, radio2[0], true)).toEqual(true); + $test.append(checkbox); + expect($.validator.methods['validate-one-required-by-name'] + .call($.validator.prototype, null, checkbox[0], true)).toEqual(false); + $test.append(checkbox2); + expect($.validator.methods['validate-one-required-by-name'] + .call($.validator.prototype, null, checkbox2[0], true)).toEqual(true); + + $.validator.prototype.currentForm = prevForm; + }); + }); + + describe('Testing less-than-equals-to', function () { + it('less-than-equals-to', function () { + var elm1 = $(''), + elm2 = $(''), + elm3 = $(''), + elm4 = $(''), + elm5 = $(''), + elm6 = $(''), + elm7 = $(''), + elm8 = $(''); + + expect($.validator.methods['less-than-equals-to'] + .call($.validator.prototype, elm1[0].value, elm1, elm2)).toEqual(false); + elm1[0].value = 4; + expect($.validator.methods['less-than-equals-to'] + .call($.validator.prototype, elm1[0].value, elm1, elm2)).toEqual(true); + expect($.validator.methods['less-than-equals-to'] + .call($.validator.prototype, elm3[0].value, elm3, elm4)).toEqual(true); + expect($.validator.methods['less-than-equals-to'] + .call($.validator.prototype, elm5[0].value, elm5, elm6)).toEqual(true); + expect($.validator.methods['less-than-equals-to'] + .call($.validator.prototype, elm7[0].value, elm7, elm8)).toEqual(true); + }); + }); + + describe('Testing greater-than-equals-to', function () { + it('greater-than-equals-to', function () { + var elm1 = $(''), + elm2 = $(''), + elm3 = $(''), + elm4 = $(''), + elm5 = $(''), + elm6 = $(''), + elm7 = $(''), + elm8 = $(''); + + expect($.validator.methods['greater-than-equals-to'] + .call($.validator.prototype, elm1[0].value, elm1, elm2)).toEqual(false); + elm1[0].value = 9; + expect($.validator.methods['greater-than-equals-to'] + .call($.validator.prototype, elm1[0].value, elm1, elm2)).toEqual(true); + expect($.validator.methods['greater-than-equals-to'] + .call($.validator.prototype, elm3[0].value, elm3, elm4)).toEqual(true); + expect($.validator.methods['greater-than-equals-to'] + .call($.validator.prototype, elm5[0].value, elm5, elm6)).toEqual(true); + expect($.validator.methods['greater-than-equals-to'] + .call($.validator.prototype, elm7[0].value, elm7, elm8)).toEqual(true); + }); + }); + + describe('Testing validate-cc-type-select', function () { + it('validate-cc-type-select', function () { + var visaValid = $(''), + visaInvalid = $(''), + mcValid = $(''), + mcInvalid = $(''), + aeValid = $(''), + aeInvalid = $(''), + diValid = $(''), + diInvalid = $(''), + dnValid = $(''), + dnInvalid = $(''), + jcbValid = $(''), + jcbInvalid = $(''); + + expect($.validator.methods['validate-cc-type-select'] + .call($.validator.prototype, 'VI', null, visaValid)).toEqual(true); + expect($.validator.methods['validate-cc-type-select'] + .call($.validator.prototype, 'VI', null, visaInvalid)).toEqual(false); + expect($.validator.methods['validate-cc-type-select'] + .call($.validator.prototype, 'MC', null, mcValid)).toEqual(true); + expect($.validator.methods['validate-cc-type-select'] + .call($.validator.prototype, 'MC', null, mcInvalid)).toEqual(false); + expect($.validator.methods['validate-cc-type-select'] + .call($.validator.prototype, 'AE', null, aeValid)).toEqual(true); + expect($.validator.methods['validate-cc-type-select'] + .call($.validator.prototype, 'AE', null, aeInvalid)).toEqual(false); + expect($.validator.methods['validate-cc-type-select'] + .call($.validator.prototype, 'DI', null, diValid)).toEqual(true); + expect($.validator.methods['validate-cc-type-select'] + .call($.validator.prototype, 'DI', null, diInvalid)).toEqual(false); + expect($.validator.methods['validate-cc-type-select'] + .call($.validator.prototype, 'DN', null, dnValid)).toEqual(true); + expect($.validator.methods['validate-cc-type-select'] + .call($.validator.prototype, 'DN', null, dnInvalid)).toEqual(false); + expect($.validator.methods['validate-cc-type-select'] + .call($.validator.prototype, 'JCB', null, jcbValid)).toEqual(true); + expect($.validator.methods['validate-cc-type-select'] + .call($.validator.prototype, 'JCB', null, jcbInvalid)).toEqual(false); + }); + }); + + describe('Testing validate-cc-number', function () { + it('validate-cc-number', function () { + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '4916835098995909', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '5265071363284878', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '6011120623356953', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '371293266574617', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '4916835098995901', null, null)).toEqual(false); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '5265071363284870', null, null)).toEqual(false); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '6011120623356951', null, null)).toEqual(false); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '371293266574619', null, null)).toEqual(false); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '2221220000000003', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '2721220000000008', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '601109020000000003', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '6011111144444444', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '6011222233334444', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '6011522233334447', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '601174455555553', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '6011745555555550', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '601177455555556', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '601182455555556', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '601187999555558', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '601287999555556', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '6444444444444443', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '6644444444444441', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '3044444444444444', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '3064444444444449', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '3095444444444442', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '3096444444444441', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '3696444444444445', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '3796444444444444', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '3896444444444443', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '3528444444444449', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '3529444444444448', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '6221262244444440', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '6229981111111111', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '6249981111111117', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '6279981111111110', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '6282981111111115', null, null)).toEqual(true); + expect($.validator.methods['validate-cc-number'] + .call($.validator.prototype, '6289981111111118', null, null)).toEqual(true); + }); + }); + + describe('Testing validate-cc-type', function () { + it('validate-cc-type', function () { + var select = $(''); + + select.val('VI'); + expect($.validator.methods['validate-cc-type'] + .call($.validator.prototype, '4916835098995909', null, select)).toEqual(true); + expect($.validator.methods['validate-cc-type'] + .call($.validator.prototype, '5265071363284878', null, select)).toEqual(false); + + select.val('MC'); + expect($.validator.methods['validate-cc-type'] + .call($.validator.prototype, '5265071363284878', null, select)).toEqual(true); + expect($.validator.methods['validate-cc-type'] + .call($.validator.prototype, '4916835098995909', null, select)).toEqual(false); + + select.val('AE'); + expect($.validator.methods['validate-cc-type'] + .call($.validator.prototype, '371293266574617', null, select)).toEqual(true); + expect($.validator.methods['validate-cc-type'] + .call($.validator.prototype, '5265071363284878', null, select)).toEqual(false); + + select.val('DI'); + expect($.validator.methods['validate-cc-type'] + .call($.validator.prototype, '6011050000000009', null, select)).toEqual(true); + expect($.validator.methods['validate-cc-type'] + .call($.validator.prototype, '371293266574617', null, select)).toEqual(false); + + select.val('DN'); + expect($.validator.methods['validate-cc-type'] + .call($.validator.prototype, '3095434000000001', null, select)).toEqual(true); + expect($.validator.methods['validate-cc-type'] + .call($.validator.prototype, '6011050000000009', null, select)).toEqual(false); + + select.val('JCB'); + expect($.validator.methods['validate-cc-type'] + .call($.validator.prototype, '3528000000000007', null, select)).toEqual(true); + expect($.validator.methods['validate-cc-type'] + .call($.validator.prototype, '3095434000000001', null, select)).toEqual(false); + }); + }); + + describe('Testing validate-cc-exp', function () { + it('validate-cc-exp', function () { + var year = $(''), + currentTime = new Date(), + currentMonth = currentTime.getMonth() + 1, + currentYear = currentTime.getFullYear(); + + year.val(currentYear); + + if (currentMonth > 1) { + expect($.validator.methods['validate-cc-exp'] + .call($.validator.prototype, currentMonth - 1, null, year)).toEqual(false); + } + expect($.validator.methods['validate-cc-exp'] + .call($.validator.prototype, currentMonth, null, year)).toEqual(true); + year.val(currentYear + 1); + expect($.validator.methods['validate-cc-exp'] + .call($.validator.prototype, currentMonth, null, year)).toEqual(true); + }); + }); + + describe('Testing validate-cc-cvn', function () { + it('validate-cc-cvn', function () { + var ccType = $(''); + + ccType.val('VI'); + expect($.validator.methods['validate-cc-cvn'] + .call($.validator.prototype, '123', null, ccType)).toEqual(true); + expect($.validator.methods['validate-cc-cvn'] + .call($.validator.prototype, '1234', null, ccType)).toEqual(false); + + ccType.val('MC'); + expect($.validator.methods['validate-cc-cvn'] + .call($.validator.prototype, '123', null, ccType)).toEqual(true); + expect($.validator.methods['validate-cc-cvn'] + .call($.validator.prototype, '1234', null, ccType)).toEqual(false); + + ccType.val('AE'); + expect($.validator.methods['validate-cc-cvn'] + .call($.validator.prototype, '1234', null, ccType)).toEqual(true); + expect($.validator.methods['validate-cc-cvn'] + .call($.validator.prototype, '123', null, ccType)).toEqual(false); + + ccType.val('DI'); + expect($.validator.methods['validate-cc-cvn'] + .call($.validator.prototype, '123', null, ccType)).toEqual(true); + expect($.validator.methods['validate-cc-cvn'] + .call($.validator.prototype, '1234', null, ccType)).toEqual(false); + }); + }); + + describe('Testing validate-number-range', function () { + it('validate-number-range', function () { + var el1 = $('').get(0); + + expect($.validator.methods['validate-number-range'] + .call($.validator.prototype, '-1', null, null)).toEqual(true); + expect($.validator.methods['validate-number-range'] + .call($.validator.prototype, '1', null, null)).toEqual(true); + expect($.validator.methods['validate-number-range'] + .call($.validator.prototype, '', null, null)).toEqual(true); + expect($.validator.methods['validate-number-range'] + .call($.validator.prototype, null, null, null)).toEqual(true); + expect($.validator.methods['validate-number-range'] + .call($.validator.prototype, '0', null, null)).toEqual(true); + expect($.validator.methods['validate-number-range'] + .call($.validator.prototype, 'asds', null, null)).toEqual(false); + expect($.validator.methods['validate-number-range'] + .call($.validator.prototype, '10', null, '10-20.06')).toEqual(true); + expect($.validator.methods['validate-number-range'] + .call($.validator.prototype, '15', null, '10-20.06')).toEqual(true); + expect($.validator.methods['validate-number-range'] + .call($.validator.prototype, '1', null, '10-20.06')).toEqual(false); + expect($.validator.methods['validate-number-range'] + .call($.validator.prototype, '30', null, '10-20.06')).toEqual(false); + expect($.validator.methods['validate-number-range'] + .call($.validator.prototype, '10', el1, null)).toEqual(true); + expect($.validator.methods['validate-number-range'] + .call($.validator.prototype, '15', el1, null)).toEqual(true); + expect($.validator.methods['validate-number-range'] + .call($.validator.prototype, '1', el1, null)).toEqual(false); + expect($.validator.methods['validate-number-range'] + .call($.validator.prototype, '30', el1, null)).toEqual(true); + }); + }); + + describe('Testing validate-digits-range', function () { + it('validate-digits-range', function () { + var el1 = $('').get(0); + + expect($.validator.methods['validate-digits-range'] + .call($.validator.prototype, '-1', null, null)).toEqual(true); + expect($.validator.methods['validate-digits-range'] + .call($.validator.prototype, '1', null, null)).toEqual(true); + expect($.validator.methods['validate-digits-range'] + .call($.validator.prototype, '', null, null)).toEqual(true); + expect($.validator.methods['validate-digits-range'] + .call($.validator.prototype, null, null, null)).toEqual(true); + expect($.validator.methods['validate-digits-range'] + .call($.validator.prototype, '0', null, null)).toEqual(true); + expect($.validator.methods['validate-digits-range'] + .call($.validator.prototype, 'asds', null, null)).toEqual(false); + expect($.validator.methods['validate-digits-range'] + .call($.validator.prototype, '10', null, '10-20')).toEqual(true); + expect($.validator.methods['validate-digits-range'] + .call($.validator.prototype, '15', null, '10-20')).toEqual(true); + expect($.validator.methods['validate-digits-range'] + .call($.validator.prototype, '1', null, '10-20')).toEqual(false); + expect($.validator.methods['validate-digits-range'] + .call($.validator.prototype, '30', null, '10-20')).toEqual(false); + expect($.validator.methods['validate-digits-range'] + .call($.validator.prototype, '30', null, '10-20.06')).toEqual(false); + expect($.validator.methods['validate-digits-range'] + .call($.validator.prototype, '10', el1, null)).toEqual(true); + expect($.validator.methods['validate-digits-range'] + .call($.validator.prototype, '15', el1, null)).toEqual(true); + expect($.validator.methods['validate-digits-range'] + .call($.validator.prototype, '1', el1, null)).toEqual(false); + expect($.validator.methods['validate-digits-range'] + .call($.validator.prototype, '30', el1, null)).toEqual(false); + }); + }); + + describe('Testing 3 bytes characters only policy (UTF-8)', function () { + it('rejects data, if any of the characters cannot be stored using UTF-8 collation', function () { + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, '😅😂', null + )).toEqual(false); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, '😅 test 😂', null + )).toEqual(false); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, '💩 👻 💀', null + )).toEqual(false); + }); + + it('approves data, if all the characters can be stored using UTF-8 collation', function () { + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, '', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, '!$-_%ç&#?!', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, '1234567890', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, ' ', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, 'test', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, 'испытание', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, 'тест', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, 'փորձարկում', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, 'परीक्षण', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, 'テスト', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, '테스트', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, '测试', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, '測試', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, 'ทดสอบ', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, 'δοκιμή', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, 'اختبار', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, 'تست', null + )).toEqual(true); + expect($.validator.methods['validate-no-utf8mb4-characters'].call( + $.validator.prototype, 'מִבְחָן', null + )).toEqual(true); + }); + }); }); diff --git a/dev/tests/static/framework/Magento/Sniffs/Less/ZeroUnitsSniff.php b/dev/tests/static/framework/Magento/Sniffs/Less/ZeroUnitsSniff.php index c696881588567..1b4fb53c45010 100644 --- a/dev/tests/static/framework/Magento/Sniffs/Less/ZeroUnitsSniff.php +++ b/dev/tests/static/framework/Magento/Sniffs/Less/ZeroUnitsSniff.php @@ -25,7 +25,7 @@ class ZeroUnitsSniff implements Sniff const CSS_PROPERTY_UNIT_REM = 'rem'; /** - * List of available CSS Propery units + * List of available CSS Property units * * @var array */ diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/CircularDependencyTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/CircularDependencyTest.php index deed829838936..e62c4112553b6 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/CircularDependencyTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/CircularDependencyTest.php @@ -44,9 +44,9 @@ protected function buildModulesDependencies() $moduleName = str_replace('/', '_', $moduleName[1]); $config = simplexml_load_file($configFile); $result = $config->xpath("/config/module/depends/module") ?: []; - while (list(, $node) = each($result)) { + foreach ($result as $node) { /** @var \SimpleXMLElement $node */ - $this->moduleDependencies[$moduleName][] = (string)$node['name']; + $this->moduleDependencies[$moduleName][] = (string) $node['name']; } } } diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/ComposerTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/ComposerTest.php index 6752a98e38080..add61e6722227 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/ComposerTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/ComposerTest.php @@ -336,7 +336,8 @@ public function testComponentPathsInRoot() "If there are any component paths specified, then they must be reflected in 'replace' section" ); $flat = $this->getFlatPathsInfo(self::$rootJson['extra']['component_paths']); - while (list(, list($component, $path)) = each($flat)) { + foreach ($flat as $item) { + list($component, $path) = $item; $this->assertFileExists( self::$root . '/' . $path, "Missing or invalid component path: {$component} -> {$path}" diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php index 620b6ad21bf75..505d3e5c3270b 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Backend/ControllerAclTest.php @@ -31,7 +31,7 @@ class ControllerAclTest extends \PHPUnit\Framework\TestCase * * @var array */ - private $whiteListetBackendControllers = []; + private $whiteListedBackendControllers = []; /** * List of ACL resources collected from acl.xml files. @@ -57,7 +57,7 @@ protected function setUp() if (substr($item, 0, 1) === '#') { continue; } - $this->whiteListetBackendControllers[$item] = 1; + $this->whiteListedBackendControllers[$item] = 1; } } @@ -83,7 +83,7 @@ public function testAcl() $controllerClass = $this->getClassByFilePath($controllerPath); // skip whitelisted controllers. - if (isset($this->whiteListetBackendControllers[$controllerClass->getName()])) { + if (isset($this->whiteListedBackendControllers[$controllerClass->getName()])) { continue; } // we don't have to check abstract classes. diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/PublicCodeTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/PublicCodeTest.php index 22ac7a34ce81e..56d00bc725dbd 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/PublicCodeTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/PublicCodeTest.php @@ -31,13 +31,24 @@ class PublicCodeTest extends \PHPUnit\Framework\TestCase */ public function testAllBlocksReferencedInLayoutArePublic($layoutFile) { + // A block can be whitelisted and thus not be required to be public + $whiteListFiles = str_replace('\\', '/', realpath(__DIR__)) + . '/_files/whitelist/public_code*.txt'; + $whiteListBlocks = []; + foreach (glob($whiteListFiles) as $fileName) { + $whiteListBlocks = array_merge( + $whiteListBlocks, + file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) + ); + } + $nonPublishedBlocks = []; $xml = simplexml_load_file($layoutFile); $elements = $xml->xpath('//block | //referenceBlock') ?: []; /** @var $node \SimpleXMLElement */ foreach ($elements as $node) { $class = (string) $node['class']; - if ($class && \class_exists($class)) { + if ($class && \class_exists($class) && !in_array($class, $whiteListBlocks)) { $reflection = (new \ReflectionClass($class)); if (strpos($reflection->getDocComment(), '@api') === false) { $nonPublishedBlocks[] = $class; diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php index 2d115b29a42f0..7c0329153d6e0 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php @@ -2526,5 +2526,6 @@ ['getDataFormTab', 'Magento\Backend\Test\Block\Widget\Tab', 'Magento\Ui\Test\Block\Adminhtml\AbstractContainer::getFieldsData'], ['getBunchImages', 'Magento\CatalogImportExport\Model\Import\Product'], ['_isAttributeValueEmpty', 'Magento\Catalog\Model\ResourceModel\AbstractResource'], - ['var_dump', ''] + ['var_dump', ''], + ['each', ''], ]; diff --git a/dev/tests/static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php b/dev/tests/static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php index 34531b6b7c658..fac14af5ecab8 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php @@ -27,16 +27,14 @@ public function testXssSensitiveOutput() * Static test will cover the following cases: * * 1. /\* @noEscape \*\/ before output. Output doesn't require escaping. Test is green. - * 2. /\* @escapeNotVerified \*\/ before output. Output escaping is not checked and - * should be verified. Test is green. - * 3. Methods which contains "html" in their names (e.g. echo $object->{suffix}Html{postfix}() ). + * 2. Methods which contains "html" in their names (e.g. echo $object->{suffix}Html{postfix}() ). * Data is ready for the HTML output. Test is green. - * 4. AbstractBlock methods escapeHtml, escapeUrl, escapeQuote, escapeXssInUrl are allowed. Test is green. - * 5. Type casting and php function count() are allowed + * 3. AbstractBlock methods escapeHtml, escapeUrl, escapeQuote, escapeXssInUrl are allowed. Test is green. + * 4. Type casting and php function count() are allowed * (e.g. echo (int)$var, echo (float)$var, echo (bool)$var, echo count($var)). Test is green. - * 6. Output in single quotes (e.g. echo 'some text'). Test is green. - * 7. Output in double quotes without variables (e.g. echo "some text"). Test is green. - * 8. Other of p.1-7. Output is not escaped. Test is red. + * 5. Output in single quotes (e.g. echo 'some text'). Test is green. + * 6. Output in double quotes without variables (e.g. echo "some text"). Test is green. + * 7. Other of p.1-6. Output is not escaped. Test is red. * * @param string $file */ diff --git a/lib/internal/Magento/Framework/Api/ExtensionAttributesFactory.php b/lib/internal/Magento/Framework/Api/ExtensionAttributesFactory.php index d7a92460a7f4d..dab0650fc7f6e 100644 --- a/lib/internal/Magento/Framework/Api/ExtensionAttributesFactory.php +++ b/lib/internal/Magento/Framework/Api/ExtensionAttributesFactory.php @@ -97,7 +97,7 @@ public function getExtensibleInterfaceName($extensibleClassName) } $modelReflection = new \ReflectionClass($extensibleClassName); if ($modelReflection->isInterface() - && $modelReflection->isSubClassOf(self::EXTENSIBLE_INTERFACE_NAME) + && $modelReflection->isSubclassOf(self::EXTENSIBLE_INTERFACE_NAME) && $modelReflection->hasMethod('getExtensionAttributes') ) { $this->classInterfaceMap[$extensibleClassName] = $extensibleClassName; diff --git a/lib/internal/Magento/Framework/App/State/CleanupFiles.php b/lib/internal/Magento/Framework/App/State/CleanupFiles.php index 4202fd8883ec0..c95caf8310b77 100644 --- a/lib/internal/Magento/Framework/App/State/CleanupFiles.php +++ b/lib/internal/Magento/Framework/App/State/CleanupFiles.php @@ -106,7 +106,7 @@ private function emptyDir($code, $subPath = null) $messages[] = $dirPath . $path; try { $dir->delete($path); - } catch (FilesystemException $e) { + } catch (FileSystemException $e) { $messages[] = $e->getMessage(); } } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/ResolverTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/ResolverTest.php index 4348177ef326f..f4560ed31ae49 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/ResolverTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/ResolverTest.php @@ -47,7 +47,7 @@ public function testGetTagsForNotObject() public function testGetTagsForObject() { $strategyReturnValue = ['test tag']; - $object = new \StdClass; + $object = new \stdClass; $this->strategy->expects($this->once()) ->method('getTags') ->with($object) diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/DummyTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/DummyTest.php index e8c76048f4eac..ad04326064587 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/DummyTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/DummyTest.php @@ -28,7 +28,7 @@ public function testGetTagsWithObject() { $emptyArray = []; - $this->assertEquals($emptyArray, $this->model->getTags(new \StdClass)); + $this->assertEquals($emptyArray, $this->model->getTags(new \stdClass)); $identityInterface = $this->getMockForAbstractClass(\Magento\Framework\DataObject\IdentityInterface::class); $this->assertEquals($emptyArray, $this->model->getTags($identityInterface)); diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/FactoryTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/FactoryTest.php index 7f570d9f13523..8964bd70f0ba8 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/FactoryTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/FactoryTest.php @@ -55,7 +55,7 @@ public function testGetStrategyWithScalar() public function testGetStrategyWithObject() { - $this->assertEquals($this->dummyStrategy, $this->model->getStrategy(new \StdClass)); + $this->assertEquals($this->dummyStrategy, $this->model->getStrategy(new \stdClass)); } public function testGetStrategyWithIdentityInterface() diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/IdentifierTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/IdentifierTest.php index e2039c0517c53..d0fcf9d8a739d 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/IdentifierTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/IdentifierTest.php @@ -28,7 +28,7 @@ public function testGetWithScalar() public function testGetTagsWithObject() { - $this->assertEquals([], $this->model->getTags(new \StdClass)); + $this->assertEquals([], $this->model->getTags(new \stdClass)); } public function testGetTagsWithIdentityInterface() diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Request/HttpTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Request/HttpTest.php index 450e1ed0b3a00..66eee671e17d3 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Request/HttpTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Request/HttpTest.php @@ -363,7 +363,7 @@ public function testIsSafeMethodTrue($httpMethod) { $this->_model = $this->getModel(); $_SERVER['REQUEST_METHOD'] = $httpMethod; - $this->assertEquals(true, $this->_model->IsSafeMethod()); + $this->assertEquals(true, $this->_model->isSafeMethod()); } /** @@ -375,7 +375,7 @@ public function testIsSafeMethodFalse($httpMethod) { $this->_model = $this->getModel(); $_SERVER['REQUEST_METHOD'] = $httpMethod; - $this->assertEquals(false, $this->_model->IsSafeMethod()); + $this->assertEquals(false, $this->_model->isSafeMethod()); } public function httpSafeMethodProvider() diff --git a/lib/internal/Magento/Framework/Code/Test/Unit/Reader/_files/ClassesForArgumentsReader.php b/lib/internal/Magento/Framework/Code/Test/Unit/Reader/_files/ClassesForArgumentsReader.php index c867e39032e1e..800cd2851eb66 100644 --- a/lib/internal/Magento/Framework/Code/Test/Unit/Reader/_files/ClassesForArgumentsReader.php +++ b/lib/internal/Magento/Framework/Code/Test/Unit/Reader/_files/ClassesForArgumentsReader.php @@ -131,7 +131,7 @@ public function __construct( $this->_arrayVariable = $arrayVariable; } } -class ThirdClassForParentCall extends firstClassForParentCall +class ThirdClassForParentCall extends FirstClassForParentCall { /** * @var stdClass @@ -154,7 +154,7 @@ public function __construct(\stdClass $stdClassObject, \ClassExtendsDefaultPhpTy $this->_secondClass = $secondClass; } } -class WrongArgumentsOrder extends firstClassForParentCall +class WrongArgumentsOrder extends FirstClassForParentCall { /** * @var stdClass @@ -177,7 +177,7 @@ public function __construct(\stdClass $stdClassObject, \ClassExtendsDefaultPhpTy $this->_secondClass = $secondClass; } } -class ArgumentsOnSeparateLines extends firstClassForParentCall +class ArgumentsOnSeparateLines extends FirstClassForParentCall { /** * @var stdClass diff --git a/lib/internal/Magento/Framework/Controller/Result/Redirect.php b/lib/internal/Magento/Framework/Controller/Result/Redirect.php index d68caeb3e4409..120b18d873cff 100644 --- a/lib/internal/Magento/Framework/Controller/Result/Redirect.php +++ b/lib/internal/Magento/Framework/Controller/Result/Redirect.php @@ -9,6 +9,8 @@ use Magento\Framework\App; use Magento\Framework\App\Response\HttpInterface as HttpResponseInterface; use Magento\Framework\Controller\AbstractResult; +use Magento\Framework\App\Response\RedirectInterface; +use Magento\Framework\UrlInterface; /** * In many cases controller actions may result in a redirect @@ -18,13 +20,14 @@ */ class Redirect extends AbstractResult { + /** - * @var \Magento\Framework\App\Response\RedirectInterface + * @var RedirectInterface */ protected $redirect; /** - * @var \Magento\Framework\UrlInterface + * @var UrlInterface */ protected $urlBuilder; @@ -37,11 +40,11 @@ class Redirect extends AbstractResult * Constructor * * @param App\Response\RedirectInterface $redirect - * @param \Magento\Framework\UrlInterface $urlBuilder + * @param UrlInterface $urlBuilder */ public function __construct( App\Response\RedirectInterface $redirect, - \Magento\Framework\UrlInterface $urlBuilder + UrlInterface $urlBuilder ) { $this->redirect = $redirect; $this->urlBuilder = $urlBuilder; @@ -70,6 +73,7 @@ public function setRefererOrBaseUrl() } /** + * URL Setter * @param string $url * @return $this */ @@ -97,7 +101,11 @@ public function setPath($path, array $params = []) */ protected function render(HttpResponseInterface $response) { - $response->setRedirect($this->url); + if (empty($this->httpResponseCode)) { + $response->setRedirect($this->url); + } else { + $response->setRedirect($this->url, $this->httpResponseCode); + } return $this; } } diff --git a/lib/internal/Magento/Framework/Controller/Test/Unit/Result/RedirectTest.php b/lib/internal/Magento/Framework/Controller/Test/Unit/Result/RedirectTest.php index 0295f0713d429..65e7ee489e84c 100644 --- a/lib/internal/Magento/Framework/Controller/Test/Unit/Result/RedirectTest.php +++ b/lib/internal/Magento/Framework/Controller/Test/Unit/Result/RedirectTest.php @@ -6,10 +6,13 @@ namespace Magento\Framework\Controller\Test\Unit\Result; -use Magento\Framework\App\Response\HttpInterface as HttpResponseInterface; +use \PHPUnit\Framework\TestCase; +use \Magento\Framework\App\Response\HttpInterface as HttpResponseInterface; +use \Magento\Framework\App\Response\RedirectInterface; use \Magento\Framework\Controller\Result\Redirect; +use \Magento\Framework\UrlInterface; -class RedirectTest extends \PHPUnit\Framework\TestCase +class RedirectTest extends TestCase { /** @var \Magento\Framework\Controller\Result\Redirect */ protected $redirect; @@ -28,9 +31,9 @@ class RedirectTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $this->redirectInterface = $this->createMock(\Magento\Framework\App\Response\RedirectInterface::class); - $this->urlBuilder = $this->createMock(\Magento\Framework\UrlInterface::class); - $this->urlInterface = $this->createMock(\Magento\Framework\UrlInterface::class); + $this->redirectInterface = $this->createMock(RedirectInterface::class); + $this->urlBuilder = $this->createMock(UrlInterface::class); + $this->urlInterface = $this->createMock(UrlInterface::class); $this->response = $this->createMock(HttpResponseInterface::class); $this->redirect = new Redirect($this->redirectInterface, $this->urlInterface); } @@ -39,7 +42,7 @@ public function testSetRefererUrl() { $this->redirectInterface->expects($this->once())->method('getRefererUrl'); $this->assertInstanceOf( - \Magento\Framework\Controller\Result\Redirect::class, + Redirect::class, $this->redirect->setRefererUrl() ); } @@ -48,7 +51,7 @@ public function testSetRefererOrBaseUrl() { $this->redirectInterface->expects($this->once())->method('getRedirectUrl'); $this->assertInstanceOf( - \Magento\Framework\Controller\Result\Redirect::class, + Redirect::class, $this->redirect->setRefererOrBaseUrl() ); } @@ -56,7 +59,7 @@ public function testSetRefererOrBaseUrl() public function testSetUrl() { $url = 'http://test.com'; - $this->assertInstanceOf(\Magento\Framework\Controller\Result\Redirect::class, $this->redirect->setUrl($url)); + $this->assertInstanceOf(Redirect::class, $this->redirect->setUrl($url)); } public function testSetPath() @@ -67,17 +70,36 @@ public function testSetPath() $this->returnValue($params) ); $this->assertInstanceOf( - \Magento\Framework\Controller\Result\Redirect::class, + Redirect::class, $this->redirect->setPath($path, $params) ); } - public function testRender() + public function httpRedirectResponseStatusCodes() { - $this->response->expects($this->once())->method('setRedirect'); - $this->assertInstanceOf( - \Magento\Framework\Controller\Result\Redirect::class, - $this->redirect->renderResult($this->response) - ); + return [ + [302, null], + [302, 302], + [303, 303] + ]; + } + + /** + * @param int $expectedStatusCode + * @param int|null $actualStatusCode + * @dataProvider httpRedirectResponseStatusCodes + */ + public function testRender($expectedStatusCode, $actualStatusCode) + { + $url = 'http://test.com'; + $this->redirect->setUrl($url); + $this->redirect->setHttpResponseCode($actualStatusCode); + + $this->response + ->expects($this->once()) + ->method('setRedirect') + ->with($url, $expectedStatusCode); + + $this->redirect->renderResult($this->response); } } diff --git a/lib/internal/Magento/Framework/DB/Query/BatchRangeIterator.php b/lib/internal/Magento/Framework/DB/Query/BatchRangeIterator.php index 9871df1b16841..5176c85cfa702 100644 --- a/lib/internal/Magento/Framework/DB/Query/BatchRangeIterator.php +++ b/lib/internal/Magento/Framework/DB/Query/BatchRangeIterator.php @@ -113,7 +113,7 @@ public function __construct( public function current() { if (null === $this->currentSelect) { - $this->isValid = ($this->currentOffset + $this->batchSize) <= $this->totalItemCount; + $this->isValid = $this->currentOffset < $this->totalItemCount; $this->currentSelect = $this->initSelectObject(); } return $this->currentSelect; @@ -144,7 +144,7 @@ public function next() if (null === $this->currentSelect) { $this->current(); } - $this->isValid = ($this->batchSize + $this->currentOffset) <= $this->totalItemCount; + $this->isValid = $this->currentOffset < $this->totalItemCount; $select = $this->initSelectObject(); if ($this->isValid) { $this->iteration++; diff --git a/lib/internal/Magento/Framework/Data/Collection.php b/lib/internal/Magento/Framework/Data/Collection.php index b0b31fa3751a8..f8b82d3122234 100644 --- a/lib/internal/Magento/Framework/Data/Collection.php +++ b/lib/internal/Magento/Framework/Data/Collection.php @@ -492,7 +492,7 @@ public function clear() * * Returns array with results of callback for each item * - * @param string $callback + * @param callable $callback * @param array $args * @return array */ diff --git a/lib/internal/Magento/Framework/Data/Test/Unit/Tree/Node/CollectionTest.php b/lib/internal/Magento/Framework/Data/Test/Unit/Tree/Node/CollectionTest.php index 58e6378759010..e91ec72dae112 100644 --- a/lib/internal/Magento/Framework/Data/Test/Unit/Tree/Node/CollectionTest.php +++ b/lib/internal/Magento/Framework/Data/Test/Unit/Tree/Node/CollectionTest.php @@ -40,7 +40,7 @@ public function testOffsets() $this->assertSame($this->collection->offsetExists('node1'), true); $this->collection->offsetSet('node1', 'Hello'); $this->assertSame($this->collection->offsetExists('node1'), true); - $this->assertSame($this->collection->offsetget('node1'), 'Hello'); + $this->assertSame($this->collection->offsetGet('node1'), 'Hello'); $this->collection->offsetUnset('node1'); $this->assertSame($this->collection->offsetExists('node1'), false); } diff --git a/lib/internal/Magento/Framework/File/Uploader.php b/lib/internal/Magento/Framework/File/Uploader.php index c3316db7be016..07de9941271c3 100644 --- a/lib/internal/Magento/Framework/File/Uploader.php +++ b/lib/internal/Magento/Framework/File/Uploader.php @@ -201,7 +201,7 @@ public function save($destinationFolder, $newFileName = null) if ($this->_enableFilesDispersion) { $fileName = $this->correctFileNameCase($fileName); $this->setAllowCreateFolders(true); - $this->_dispretionPath = self::getDispretionPath($fileName); + $this->_dispretionPath = self::getDispersionPath($fileName); $destinationFile .= $this->_dispretionPath; $this->_createDestinationFolder($destinationFile); } @@ -610,8 +610,20 @@ public static function getNewFileName($destinationFile) * * @param string $fileName * @return string + * @deprecated */ public static function getDispretionPath($fileName) + { + return self::getDispersionPath($fileName); + } + + /** + * Get dispertion path + * + * @param string $fileName + * @return string + */ + public static function getDispersionPath($fileName) { $char = 0; $dispertionPath = ''; diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php new file mode 100644 index 0000000000000..1cc47bb0db12e --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlAuthorizationException.php @@ -0,0 +1,53 @@ +isSafe = $isSafe; + parent::__construct($phrase, $cause, $code); + } + + /** + * {@inheritDoc} + */ + public function isClientSafe() + { + return $this->isSafe; + } + + /** + * {@inheritDoc} + */ + public function getCategory() + { + return self::EXCEPTION_CATEGORY; + } +} diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlInputException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlInputException.php index a72a70bb5035b..b05120f47938a 100644 --- a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlInputException.php +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlInputException.php @@ -14,6 +14,8 @@ */ class GraphQlInputException extends InputException implements \GraphQL\Error\ClientAware { + const EXCEPTION_CATEGORY = 'graphql-input'; + /** * @var boolean */ @@ -46,6 +48,6 @@ public function isClientSafe() */ public function getCategory() { - return 'graphql-input'; + return self::EXCEPTION_CATEGORY; } } diff --git a/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php new file mode 100644 index 0000000000000..26bfddecc3376 --- /dev/null +++ b/lib/internal/Magento/Framework/GraphQl/Exception/GraphQlNoSuchEntityException.php @@ -0,0 +1,53 @@ +isSafe = $isSafe; + parent::__construct($phrase, $cause, $code); + } + + /** + * {@inheritDoc} + */ + public function isClientSafe() + { + return $this->isSafe; + } + + /** + * {@inheritDoc} + */ + public function getCategory() + { + return self::EXCEPTION_CATEGORY; + } +} diff --git a/lib/internal/Magento/Framework/GraphQl/ExceptionFormatter.php b/lib/internal/Magento/Framework/GraphQl/ExceptionFormatter.php index ac7f62f70cf03..02e636e82061b 100644 --- a/lib/internal/Magento/Framework/GraphQl/ExceptionFormatter.php +++ b/lib/internal/Magento/Framework/GraphQl/ExceptionFormatter.php @@ -6,11 +6,38 @@ namespace Magento\Framework\GraphQl; +use Magento\Framework\App\State; +use Magento\Framework\Webapi\ErrorProcessor; +use Psr\Log\LoggerInterface; + /** * Wrapper for GraphQl Exception Formatter */ class ExceptionFormatter { + const HTTP_GRAPH_QL_SCHEMA_ERROR_STATUS = 500; + + /** + * @var State + */ + private $appState; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param State $appState + * @param ErrorProcessor $errorProcessor + */ + public function __construct(State $appState, ErrorProcessor $errorProcessor, LoggerInterface $logger) + { + $this->appState = $appState; + $errorProcessor->registerShutdownFunction(); + $this->logger = $logger; + } + /** * Format a GraphQL error from an exception by converting it to array to conform to GraphQL spec. * @@ -18,13 +45,35 @@ class ExceptionFormatter * (or when debug flags are passed). * * @param \Throwable $exception - * @param bool|int $debug * @param string $internalErrorMessage * @return array * @throws \Throwable */ - public function create(\Throwable $exception, $debug = false, $internalErrorMessage = null) + public function create(\Throwable $exception, $internalErrorMessage = null) + { + if (!$this->shouldShowDetail()) { + $reportId = uniqid("graph-ql-"); + $message = "Report ID: {$reportId}; Message: {$exception->getMessage()}"; + $code = $exception->getCode(); + $loggedException = new \Exception($message, $code, $exception); + $this->logger->critical($loggedException); + } + + return \GraphQL\Error\FormattedError::createFromException( + $exception, + $this->shouldShowDetail() + ? \GraphQL\Error\Debug::INCLUDE_DEBUG_MESSAGE | \GraphQL\Error\Debug::INCLUDE_TRACE : false, + $internalErrorMessage + ); + } + + /** + * Return true if detailed error message should be displayed to client, false otherwise. + * + * @return bool + */ + public function shouldShowDetail() { - return \GraphQL\Error\FormattedError::createFromException($exception, $debug, $internalErrorMessage); + return $this->appState->getMode() === State::MODE_DEVELOPER; } } diff --git a/lib/internal/Magento/Framework/GraphQl/QueryProcessor.php b/lib/internal/Magento/Framework/GraphQl/QueryProcessor.php index 1b55208ba4533..33578c25455c7 100644 --- a/lib/internal/Magento/Framework/GraphQl/QueryProcessor.php +++ b/lib/internal/Magento/Framework/GraphQl/QueryProcessor.php @@ -13,6 +13,19 @@ */ class QueryProcessor { + /** + * @var ExceptionFormatter + */ + private $exceptionFormatter; + + /** + * @param ExceptionFormatter $exceptionFormatter + */ + public function __construct(ExceptionFormatter $exceptionFormatter) + { + $this->exceptionFormatter = $exceptionFormatter; + } + /** * Process a GraphQl query according to defined schema * @@ -32,13 +45,16 @@ public function process( $variableValues = null, $operationName = null ) { - return \GraphQL\GraphQL::execute( + return \GraphQL\GraphQL::executeQuery( $schema, $source, $rootValue, $contextValue, $variableValues, $operationName + )->toArray( + $this->exceptionFormatter->shouldShowDetail() ? + \GraphQL\Error\Debug::INCLUDE_DEBUG_MESSAGE | \GraphQL\Error\Debug::INCLUDE_TRACE : false ); } } diff --git a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php index ff0bf69d5ebfb..cc85a9e9fb752 100644 --- a/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php +++ b/lib/internal/Magento/Framework/GraphQl/Type/Input/InputObjectType.php @@ -6,17 +6,28 @@ namespace Magento\Framework\GraphQl\Type\Input; +use GraphQL\Type\Definition\InputType; +use Magento\Framework\GraphQl\Config\Data\Field; use Magento\Framework\GraphQl\Config\Data\Type as TypeStructure; +use Magento\Framework\GraphQl\Type\Definition\TypeInterface; +use Magento\Framework\GraphQl\TypeFactory; /** * Class InputObjectType */ class InputObjectType extends \GraphQL\Type\Definition\InputObjectType { + /** + * @var TypeFactory + */ + private $typeFactory; + public function __construct( InputMapper $inputMapper, - TypeStructure $structure + TypeStructure $structure, + TypeFactory $typeFactory ) { + $this->typeFactory = $typeFactory; $config = [ 'name' => $structure->getName(), 'description' => $structure->getDescription() @@ -29,6 +40,9 @@ public function __construct( } else { $type = $inputMapper->getFieldRepresentation($field->getType()); } + + $type = $this->processIsNullable($field, $this->processIsList($field, $type)); + $config['fields'][$field->getName()] = [ 'name' => $field->getName(), 'type' => $type @@ -36,4 +50,34 @@ public function __construct( } parent::__construct($config); } + + /** + * Return passed in type wrapped as a non null type if definition determines necessary. + * + * @param Field $field + * @param InputType $object + * @return TypeInterface|\GraphQL\Type\Definition\Type + */ + private function processIsNullable(Field $field, InputType $object) + { + if ($field->isRequired()) { + return $this->typeFactory->createNonNull($object); + } + return $object; + } + + /** + * Return passed in type wrapped as a list if definition determines necessary. + * + * @param Field $field + * @param InputType $object + * @return TypeInterface|\GraphQL\Type\Definition\Type + */ + private function processIsList(Field $field, InputType $object) + { + if ($field->isList()) { + return $this->typeFactory->createList($object); + } + return $object; + } } diff --git a/lib/internal/Magento/Framework/Image/Adapter/Gd2.php b/lib/internal/Magento/Framework/Image/Adapter/Gd2.php index 444ab7113d429..365fa5939b6b5 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/Gd2.php +++ b/lib/internal/Magento/Framework/Image/Adapter/Gd2.php @@ -62,7 +62,10 @@ public function open($filename) throw new \OverflowException('Memory limit has been reached.'); } $this->imageDestroy(); - $this->_imageHandler = call_user_func($this->_getCallback('create'), $this->_fileName); + $this->_imageHandler = call_user_func( + $this->_getCallback('create', null, sprintf('Unsupported image format. File: %s', $this->_fileName)), + $this->_fileName + ); } /** diff --git a/lib/internal/Magento/Framework/Image/Adapter/ImageMagick.php b/lib/internal/Magento/Framework/Image/Adapter/ImageMagick.php index 50b9a5a013273..e0ead031a9ba0 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/ImageMagick.php +++ b/lib/internal/Magento/Framework/Image/Adapter/ImageMagick.php @@ -77,7 +77,7 @@ public function open($filename) try { $this->_imageHandler = new \Imagick($this->_fileName); } catch (\ImagickException $e) { - throw new \Exception('Unsupported image format.', $e->getCode(), $e); + throw new \Exception(sprintf('Unsupported image format. File: %s', $this->_fileName), $e->getCode(), $e); } $this->backgroundColor(); diff --git a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php index 99b35509c4bad..020159985105d 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php +++ b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php @@ -127,12 +127,12 @@ protected function createObject($type, $args) protected function resolveArgument(&$argument, $paramType, $paramDefault, $paramName, $requestedType) { if ($paramType && $argument !== $paramDefault && !is_object($argument)) { - $argumentType = $argument['instance']; if (!isset($argument['instance']) || $argument !== (array)$argument) { throw new \UnexpectedValueException( 'Invalid parameter configuration provided for $' . $paramName . ' argument of ' . $requestedType ); } + $argumentType = $argument['instance']; if (isset($argument['shared'])) { $isShared = $argument['shared']; diff --git a/lib/internal/Magento/Framework/Reflection/Test/Unit/Fixture/TSample.php b/lib/internal/Magento/Framework/Reflection/Test/Unit/Fixture/TSample.php new file mode 100644 index 0000000000000..1d78f9ed0a7d8 --- /dev/null +++ b/lib/internal/Magento/Framework/Reflection/Test/Unit/Fixture/TSample.php @@ -0,0 +1,25 @@ +assertEquals("resNameMethodName", $this->_typeProcessor->getOperationName("resName", "methodName")); } + + /** + * Checks a case when method has only `@inheritdoc` annotation. + */ + public function testGetReturnTypeWithInheritDocBlock() + { + $expected = [ + 'type' => 'string', + 'isRequired' => true, + 'description' => null, + 'parameterCount' => 0 + ]; + + $classReflection = new ClassReflection(TSample::class); + $methodReflection = $classReflection->getMethod('getPropertyName'); + + self::assertEquals($expected, $this->_typeProcessor->getGetterReturnType($methodReflection)); + } + + /** + * Checks a case when method and parent interface don't have `@return` annotation. + * + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Getter return type must be specified using @return annotation. See Magento\Framework\Reflection\Test\Unit\Fixture\TSample::getName() + */ + public function testGetReturnTypeWithoutReturnTag() + { + $classReflection = new ClassReflection(TSample::class); + $methodReflection = $classReflection->getMethod('getName'); + $this->_typeProcessor->getGetterReturnType($methodReflection); + } } diff --git a/lib/internal/Magento/Framework/Reflection/TypeProcessor.php b/lib/internal/Magento/Framework/Reflection/TypeProcessor.php index 5d6054056d35e..74c1bc95b208b 100644 --- a/lib/internal/Magento/Framework/Reflection/TypeProcessor.php +++ b/lib/internal/Magento/Framework/Reflection/TypeProcessor.php @@ -8,6 +8,7 @@ use Magento\Framework\Exception\SerializationException; use Magento\Framework\Phrase; use Zend\Code\Reflection\ClassReflection; +use Zend\Code\Reflection\DocBlock\Tag\ReturnTag; use Zend\Code\Reflection\DocBlockReflection; use Zend\Code\Reflection\MethodReflection; use Zend\Code\Reflection\ParameterReflection; @@ -16,6 +17,7 @@ * Type processor of config reader properties * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) this suppress MUST be removed after removing deprecated methods. */ class TypeProcessor { @@ -275,22 +277,7 @@ protected function dataObjectGetterDescriptionToFieldDescription($shortDescripti */ public function getGetterReturnType($methodReflection) { - $methodDocBlock = $methodReflection->getDocBlock(); - if (!$methodDocBlock) { - throw new \InvalidArgumentException( - "Each getter must have description with @return annotation. " - . "See {$methodReflection->getDeclaringClass()->getName()}::{$methodReflection->getName()}()" - ); - } - $returnAnnotations = $methodDocBlock->getTags('return'); - if (empty($returnAnnotations)) { - throw new \InvalidArgumentException( - "Getter return type must be specified using @return annotation. " - . "See {$methodReflection->getDeclaringClass()->getName()}::{$methodReflection->getName()}()" - ); - } - /** @var \Zend\Code\Reflection\DocBlock\Tag\ReturnTag $returnAnnotation */ - $returnAnnotation = current($returnAnnotations); + $returnAnnotation = $this->getMethodReturnAnnotation($methodReflection); $types = $returnAnnotation->getTypes(); $returnType = current($types); $nullable = in_array('null', $types); @@ -362,7 +349,7 @@ public function isTypeSimple($type) self::NORMALIZED_INT_TYPE, self::NORMALIZED_FLOAT_TYPE, self::NORMALIZED_DOUBLE_TYPE, - self::NORMALIZED_BOOLEAN_TYPE + self::NORMALIZED_BOOLEAN_TYPE, ] ); } @@ -708,4 +695,56 @@ private function getNormalizedType($type) } return $type; } + + /** + * Parses `return` annotation from reflection method. + * + * @param MethodReflection $methodReflection + * @return ReturnTag + * @throws \InvalidArgumentException if doc block is empty or `@return` annotation doesn't exist + */ + private function getMethodReturnAnnotation(MethodReflection $methodReflection) + { + $methodName = $methodReflection->getName(); + $returnAnnotations = $this->getReturnFromDocBlock($methodReflection); + if (empty($returnAnnotations)) { + // method can inherit doc block from implemented interface, like for interceptors + $implemented = $methodReflection->getDeclaringClass()->getInterfaces(); + /** @var ClassReflection $parentClassReflection */ + foreach ($implemented as $parentClassReflection) { + if ($parentClassReflection->hasMethod($methodName)) { + $returnAnnotations = $this->getReturnFromDocBlock( + $parentClassReflection->getMethod($methodName) + ); + break; + } + } + // throw an exception if even implemented interface doesn't have return annotations + if (empty($returnAnnotations)) { + throw new \InvalidArgumentException( + "Getter return type must be specified using @return annotation. " + . "See {$methodReflection->getDeclaringClass()->getName()}::{$methodName}()" + ); + } + } + return $returnAnnotations; + } + + /** + * Parses `return` annotation from doc block. + * + * @param MethodReflection $methodReflection + * @return ReturnTag + */ + private function getReturnFromDocBlock(MethodReflection $methodReflection) + { + $methodDocBlock = $methodReflection->getDocBlock(); + if (!$methodDocBlock) { + throw new \InvalidArgumentException( + "Each getter must have a doc block. " + . "See {$methodReflection->getDeclaringClass()->getName()}::{$methodReflection->getName()}()" + ); + } + return current($methodDocBlock->getTags('return')); + } } diff --git a/lib/internal/Magento/Framework/Session/Config.php b/lib/internal/Magento/Framework/Session/Config.php index 26ae1635f18f1..053bd3e7fd6b9 100644 --- a/lib/internal/Magento/Framework/Session/Config.php +++ b/lib/internal/Magento/Framework/Session/Config.php @@ -134,6 +134,14 @@ public function __construct( $this->setSavePath($savePath); } + /** + * Session save handler - memcache, files, etc + */ + $saveHandler = $deploymentConfig->get(self::PARAM_SESSION_SAVE_METHOD); + if ($saveHandler) { + $this->setOption('session.save_handler', $saveHandler); + } + /** * Session cache limiter */ diff --git a/lib/internal/Magento/Framework/Session/Test/Unit/ConfigTest.php b/lib/internal/Magento/Framework/Session/Test/Unit/ConfigTest.php index 66fc12b493090..12e28cdb3970d 100644 --- a/lib/internal/Magento/Framework/Session/Test/Unit/ConfigTest.php +++ b/lib/internal/Magento/Framework/Session/Test/Unit/ConfigTest.php @@ -350,33 +350,36 @@ public function constructorDataProvider() true, true, [ - 'session.cache_limiter' => 'files', + 'session.cache_limiter' => 'private_no_expire', 'session.cookie_lifetime' => 7200, 'session.cookie_path' => '/', 'session.cookie_domain' => 'init.host', 'session.cookie_httponly' => false, 'session.cookie_secure' => false, + 'session.save_handler' => 'files' ], ], 'all invalid' => [ true, false, [ - 'session.cache_limiter' => 'files', + 'session.cache_limiter' => 'private_no_expire', 'session.cookie_httponly' => false, 'session.cookie_secure' => false, + 'session.save_handler' => 'files' ], ], 'invalid_valid' => [ false, true, [ - 'session.cache_limiter' => 'files', + 'session.cache_limiter' => 'private_no_expire', 'session.cookie_lifetime' => 3600, 'session.cookie_path' => '/', 'session.cookie_domain' => 'init.host', 'session.cookie_httponly' => false, 'session.cookie_secure' => false, + 'session.save_handler' => 'files' ], ], ]; @@ -429,14 +432,18 @@ protected function getModel($validator) ->will($this->returnValue($dirMock)); $deploymentConfigMock = $this->createMock(\Magento\Framework\App\DeploymentConfig::class); - $deploymentConfigMock->expects($this->at(0)) + $deploymentConfigMock ->method('get') - ->with(Config::PARAM_SESSION_SAVE_PATH) - ->will($this->returnValue(null)); - $deploymentConfigMock->expects($this->at(1)) - ->method('get') - ->with(Config::PARAM_SESSION_CACHE_LIMITER) - ->will($this->returnValue('files')); + ->willReturnCallback(function ($configPath) { + switch ($configPath) { + case Config::PARAM_SESSION_SAVE_METHOD: + return 'files'; + case Config::PARAM_SESSION_CACHE_LIMITER: + return 'private_no_expire'; + default: + return null; + } + }); $this->config = $this->helper->getObject( \Magento\Framework\Session\Config::class, diff --git a/lib/internal/Magento/Framework/Test/Unit/DB/Query/BatchRangeIteratorTest.php b/lib/internal/Magento/Framework/Test/Unit/DB/Query/BatchRangeIteratorTest.php index 22fdf0a05686a..9e2014c1b070a 100644 --- a/lib/internal/Magento/Framework/Test/Unit/DB/Query/BatchRangeIteratorTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/DB/Query/BatchRangeIteratorTest.php @@ -116,6 +116,6 @@ public function testIterations() $iterations++; } - $this->assertEquals(10, $iterations); + $this->assertEquals(11, $iterations); } } diff --git a/lib/internal/Magento/Framework/View/Context.php b/lib/internal/Magento/Framework/View/Context.php index 0c3932ffe4bd7..c3f1c3e691c84 100644 --- a/lib/internal/Magento/Framework/View/Context.php +++ b/lib/internal/Magento/Framework/View/Context.php @@ -332,15 +332,11 @@ public function getModuleName() } /** - * Retrieve the module name - * - * @return string - * - * @todo alias of getModuleName + * @see getModuleName */ public function getFrontName() { - return $this->getRequest()->getModuleName(); + return $this->getModuleName(); } /** diff --git a/lib/internal/Magento/Framework/View/Design/Theme/ThemeList.php b/lib/internal/Magento/Framework/View/Design/Theme/ThemeList.php index 826811b55b4bf..000fba24f0822 100644 --- a/lib/internal/Magento/Framework/View/Design/Theme/ThemeList.php +++ b/lib/internal/Magento/Framework/View/Design/Theme/ThemeList.php @@ -234,7 +234,7 @@ protected function _prepareConfigurationData($themePackage) $media = $themeConfig->getMedia(); $parentPathPieces = $themeConfig->getParentTheme(); - if (count($parentPathPieces) == 1) { + if (is_array($parentPathPieces) && count($parentPathPieces) == 1) { $pathPieces = $pathData['theme_path_pieces']; array_pop($pathPieces); $parentPathPieces = array_merge($pathPieces, $parentPathPieces); diff --git a/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd b/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd index ea80380865e6a..39cdec05a65ea 100755 --- a/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd +++ b/lib/internal/Magento/Framework/View/Layout/etc/elements.xsd @@ -138,7 +138,7 @@ - + diff --git a/lib/internal/Magento/Framework/View/Model/Layout/Merge.php b/lib/internal/Magento/Framework/View/Model/Layout/Merge.php index ea8f74107954c..fe5c94ed21b30 100644 --- a/lib/internal/Magento/Framework/View/Model/Layout/Merge.php +++ b/lib/internal/Magento/Framework/View/Model/Layout/Merge.php @@ -811,7 +811,7 @@ private function getXmlErrors($libXmlErrors) protected function _getPhysicalTheme(\Magento\Framework\View\Design\ThemeInterface $theme) { $result = $theme; - while ($result->getId() && !$result->isPhysical()) { + while ($result !== null && $result->getId() && !$result->isPhysical()) { $result = $result->getParentTheme(); } if (!$result) { diff --git a/lib/internal/Magento/Framework/Xml/Security.php b/lib/internal/Magento/Framework/Xml/Security.php index 72af506a3294e..e502429e4511a 100644 --- a/lib/internal/Magento/Framework/Xml/Security.php +++ b/lib/internal/Magento/Framework/Xml/Security.php @@ -72,7 +72,7 @@ function ($errno, $errstr) { E_WARNING ); - $result = (bool)$document->loadXml($xmlContent, LIBXML_NONET); + $result = (bool)$document->loadXML($xmlContent, LIBXML_NONET); restore_error_handler(); // Entity load to previous setting libxml_disable_entity_loader($loadEntities); diff --git a/lib/web/i18n/en_US.csv b/lib/web/i18n/en_US.csv index 21cfb51d5e3c9..5c63a191420a4 100644 --- a/lib/web/i18n/en_US.csv +++ b/lib/web/i18n/en_US.csv @@ -99,6 +99,7 @@ Submit,Submit "Password cannot be the same as email address.","Password cannot be the same as email address." "Please fix this field.","Please fix this field." "Please enter a valid email address.","Please enter a valid email address." +"Please remove invalid characters: {0}.", "Please remove invalid characters: {0}." "Please enter a valid URL.","Please enter a valid URL." "Please enter a valid date (ISO).","Please enter a valid date (ISO)." "Please enter only digits.","Please enter only digits." diff --git a/lib/web/jquery/jstree/jquery.jstree.js b/lib/web/jquery/jstree/jquery.jstree.js index e2f6330ba45eb..4671256b4207b 100644 --- a/lib/web/jquery/jstree/jquery.jstree.js +++ b/lib/web/jquery/jstree/jquery.jstree.js @@ -28,7 +28,7 @@ "use strict"; // top wrapper to prevent multiple inclusion (is this OK?) -(function () { if(jQuery && jQuery.jstree) { return; } +(function () { var is_ie6 = false, is_ie7 = false, is_ff2 = false; /* diff --git a/lib/web/mage/adminhtml/events.js b/lib/web/mage/adminhtml/events.js index a64b3218c5032..67e04c5ca9c15 100644 --- a/lib/web/mage/adminhtml/events.js +++ b/lib/web/mage/adminhtml/events.js @@ -188,4 +188,6 @@ define([ }; window.varienGlobalEvents = new varienEvents(); //jscs:ignore requireCapitalizedConstructors + + return window.varienGlobalEvents; }); diff --git a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/plugins/magentovariable/editor_plugin.js b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/plugins/magentovariable/editor_plugin.js index d96ab6dcc5353..e6f12a2e51acf 100644 --- a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/plugins/magentovariable/editor_plugin.js +++ b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/plugins/magentovariable/editor_plugin.js @@ -5,208 +5,215 @@ /* global tinymce, MagentovariablePlugin, varienGlobalEvents, Base64 */ /* eslint-disable strict */ -tinymce.create('tinymce.plugins.magentovariable', { - - /** - * Initialize editor plugin. - * - * @param {tinymce.editor} editor - Editor instance that the plugin is initialized in. - * @param {String} url - Absolute URL to where the plugin is located. - */ - init: function (editor, url) { - var self = this; - - require([ - 'Magento_Variable/js/config-directive-generator', - 'Magento_Variable/js/custom-directive-generator' - ], function (configDirectiveGenerator, customDirectiveGenerator) { - self.configDirectiveGenerator = configDirectiveGenerator; - self.customDirectiveGenerator = customDirectiveGenerator; - }); +define([ + 'Magento_Variable/js/config-directive-generator', + 'Magento_Variable/js/custom-directive-generator', + 'wysiwygAdapter', + 'jquery' +], function (configDirectiveGenerator, customDirectiveGenerator, wysiwyg, jQuery) { + return function (config) { + tinymce.create('tinymce.plugins.magentovariable', { - /** - * Add new command to open variables selector slideout. - */ - editor.addCommand('openVariablesSlideout', function (commandConfig) { - var selectedElement; + /** + * Initialize editor plugin. + * + * @param {tinymce.editor} editor - Editor instance that the plugin is initialized in. + * @param {String} url - Absolute URL to where the plugin is located. + */ + init: function (editor, url) { + var self = this; + + /** + * Add new command to open variables selector slideout. + */ + editor.addCommand('openVariablesSlideout', function (commandConfig) { + var selectedElement; + + if (commandConfig) { + selectedElement = commandConfig.selectedElement; + } else { + selectedElement = tinymce.activeEditor.selection.getNode(); + } + MagentovariablePlugin.setEditor(editor); + MagentovariablePlugin.loadChooser( + config.url, + wysiwyg.getId(), + selectedElement + ); + }); - if (commandConfig) { - selectedElement = commandConfig.selectedElement; - } else { - selectedElement = tinymce.activeEditor.selection.getNode(); - } - MagentovariablePlugin.setEditor(editor); - MagentovariablePlugin.loadChooser( - self.constructor.config.url, - self.constructor.adapter.id, - selectedElement - ); - }); + /** + * Add button to the editor toolbar. + */ + editor.addButton('magentovariable', { + title: jQuery.mage.__('Insert Variable'), + tooltip: jQuery.mage.__('Insert Variable'), + cmd: 'openVariablesSlideout', + image: url + '/img/icon.png', + + /** + * Highlight or dismiss Insert Variable button when variable is selected or deselected. + */ + onPostRender: function () { + var _this = this, + + /** + * Toggle active state of Insert Variable button. + * + * @param {Object} e + */ + toggleVariableButton = function (e) { + _this.active(false); + + if (jQuery(e.target).hasClass('magento-variable')) { + _this.active(true); + } + }; + + editor.on('click', toggleVariableButton); + editor.on('change', toggleVariableButton); + } + }); - /** - * Add button to the editor toolbar. - */ - editor.addButton('magentovariable', { - title: jQuery.mage.__('Insert Variable'), - tooltip: jQuery.mage.__('Insert Variable'), - cmd: 'openVariablesSlideout', - image: url + '/img/icon.png', + /** + * Double click handler on the editor to handle dbl click on variable placeholder. + */ + editor.on('dblclick', function (evt) { + if (jQuery(evt.target).hasClass('magento-variable')) { + editor.selection.collapse(false); + editor.execCommand('openVariablesSlideout', { + ui: true, + selectedElement: evt.target + }); + } + }); + + /** + * Attach event handler for when wysiwyg editor is about to encode its content + */ + varienGlobalEvents.attachEventHandler('wysiwygEncodeContent', function (content) { + content = self.encodeVariables(content); + + return content; + }); + + /** + * Attach event handler for when wysiwyg editor is about to decode its content + */ + varienGlobalEvents.attachEventHandler('wysiwygDecodeContent', function (content) { + content = self.decodeVariables(content); + + return content; + }); + }, /** - * Highlight or dismiss Insert Variable button when variable is selected or deselected. + * Encode variables in content + * + * @param {String} content + * @returns {*} */ - onPostRender: function () { - var _this = this; + encodeVariables: function (content) { + content = content.gsub(/\{\{config path=\"([^\"]+)\"\}\}/i, function (match) { + var path = match[1], + magentoVariables, + imageHtml; + + magentoVariables = JSON.parse(config.placeholders); + + if (magentoVariables[match[1]] && magentoVariables[match[1]]['variable_type'] === 'default') { + imageHtml = '' + + '%s'; + imageHtml = imageHtml.replace('%s', magentoVariables[match[1]]['variable_name']); + } else { + imageHtml = '' + + 'Not found' + + ''; + } - editor.on('click', function (e) { - _this.active(false); + return imageHtml.replace('%id', Base64.idEncode(path)); + }); - if (jQuery(e.target).hasClass('magento-variable')) { - _this.active(true); + content = content.gsub(/\{\{customVar code=([^\}\"]+)\}\}/i, function (match) { + var path = match[1], + magentoVariables, + imageHtml; + + magentoVariables = JSON.parse(config.placeholders); + + if (magentoVariables[match[1]] && magentoVariables[match[1]]['variable_type'] === 'custom') { + imageHtml = '%s'; + imageHtml = imageHtml.replace('%s', magentoVariables[match[1]]['variable_name']); + } else { + imageHtml = '' + + match[1] + + ''; } + + return imageHtml.replace('%id', Base64.idEncode(path)); }); - } - }); - /** - * Double click handler on the editor to handle dbl click on variable placeholder. - */ - editor.on('dblclick', function (evt) { - if (jQuery(evt.target).hasClass('magento-variable')) { - editor.selection.collapse(false); - editor.execCommand('openVariablesSlideout', { - ui: true, - selectedElement: evt.target + return content; + }, + + /** + * Decode variables in content. + * + * @param {String} content + * @returns {String} + */ + decodeVariables: function (content) { + var doc = (new DOMParser()).parseFromString(content.replace(/"/g, '&quot;'), 'text/html'); + + [].forEach.call(doc.querySelectorAll('span.magento-variable'), function (el) { + var $el = jQuery(el); + + if ($el.hasClass('magento-custom-var')) { + $el.replaceWith( + customDirectiveGenerator.processConfig( + Base64.idDecode( + $el.attr('id') + ) + ) + ); + } else { + $el.replaceWith( + configDirectiveGenerator.processConfig( + Base64.idDecode( + $el.attr('id') + ) + ) + ); + } }); - } - }); - /** - * Attach event handler for when wysiwyg editor is about to encode its content - */ - varienGlobalEvents.attachEventHandler('wysiwygEncodeContent', function (content) { - content = self.encodeVariables(content); + return doc.body ? doc.body.innerHTML.replace(/&quot;/g, '"') : content; + }, - return content; + /** + * @return {Object} + */ + getInfo: function () { + return { + longname: 'Magento Variable Manager Plugin', + author: 'Magento Core Team', + authorurl: 'http://magentocommerce.com', + infourl: 'http://magentocommerce.com', + version: '1.0' + }; + } }); /** - * Attach event handler for when wysiwyg editor is about to decode its content + * Register plugin */ - varienGlobalEvents.attachEventHandler('wysiwygDecodeContent', function (content) { - content = self.decodeVariables(content); - - return content; - }); - }, - - /** - * Encode variables in content - * - * @param {String} content - * @returns {*} - */ - encodeVariables: function (content) { - content = content.gsub(/\{\{config path=\"([^\"]+)\"\}\}/i, function (match) { - var path = match[1], - magentoVariables, - imageHtml; - - magentoVariables = JSON.parse(this.constructor.config.placeholders); - - if (magentoVariables[match[1]] && magentoVariables[match[1]]['variable_type'] === 'default') { - imageHtml = '%s'; - imageHtml = imageHtml.replace('%s', magentoVariables[match[1]]['variable_name']); - } else { - imageHtml = '' + - 'Not found' + - ''; - } - - return imageHtml.replace('%id', Base64.idEncode(path)); - }.bind(this)); - - content = content.gsub(/\{\{customVar code=([^\}\"]+)\}\}/i, function (match) { - var path = match[1], - magentoVariables, - imageHtml; - - magentoVariables = JSON.parse(this.constructor.config.placeholders); - - if (magentoVariables[match[1]] && magentoVariables[match[1]]['variable_type'] === 'custom') { - imageHtml = '%s'; - imageHtml = imageHtml.replace('%s', magentoVariables[match[1]]['variable_name']); - } else { - imageHtml = '' + - match[1] + - ''; - } - - return imageHtml.replace('%id', Base64.idEncode(path)); - }.bind(this)); - - return content; - }, - - /** - * Decode variables in content. - * - * @param {String} content - * @returns {*} - */ - decodeVariables: function (content) { - var i, el, spans, element = document.createElement('elem'); - - element.innerHTML = content; - spans = element.querySelectorAll('span.magento-variable'); - - for (i = 0; i < spans.length; i++) { - el = spans[i]; - - if (el.hasClassName('magento-custom-var')) { - $(el).replaceWith( - this.customDirectiveGenerator.processConfig( - Base64.idDecode( - $(el).getAttribute('id') - ) - ) - ); - } else { - $(el).replaceWith( - this.configDirectiveGenerator.processConfig( - Base64.idDecode( - $(el).getAttribute('id') - ) - ) - ); - } - } - - return element.innerHTML; - }, - - /** - * @return {Object} - */ - getInfo: function () { - return { - longname: 'Magento Variable Manager Plugin', - author: 'Magento Core Team', - authorurl: 'http://magentocommerce.com', - infourl: 'http://magentocommerce.com', - version: '1.0' - }; - } + tinymce.PluginManager.add('magentovariable', tinymce.plugins.magentovariable); + }; }); - -/** - * Register plugin - */ -tinymce.PluginManager.add('magentovariable', tinymce.plugins.magentovariable); diff --git a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/plugins/magentowidget/editor_plugin.js b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/plugins/magentowidget/editor_plugin.js index af8078c0a022d..73fd8658854f2 100644 --- a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/plugins/magentowidget/editor_plugin.js +++ b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/plugins/magentowidget/editor_plugin.js @@ -3,224 +3,232 @@ * See COPYING.txt for license details. */ -/* global tinymce, widgetTools, jQuery, varienGlobalEvents, Base64 */ +/* global tinymce, widgetTools, jQuery, Base64 */ /* eslint-disable strict */ -tinymce.create('tinymce.plugins.magentowidget', { - /** - * @param {tinymce.Editor} editor - Editor instance that the plugin is initialized in. - * @param {String} url - Absolute URL to where the plugin is located. - */ - init: function (editor, url) { - var self = this; - - this.activePlaceholder = null; - - editor.addCommand('mceMagentowidget', function (img) { - if (self.activePlaceholder) { - img = self.activePlaceholder; - } - - widgetTools.setActiveSelectedNode(img); - widgetTools.openDialog( - this.constructor.config['window_url'] + 'widget_target_id/' + editor.getElement().id + '/' - ); - }.bind(this)); - - // Register Widget plugin button - editor.addButton('magentowidget', { - title: jQuery.mage.__('Insert Widget'), - cmd: 'mceMagentowidget', - image: url + '/img/icon.png', +define([ + 'wysiwygAdapter', + 'mage/adminhtml/events' +], function (wysiwyg, varienGlobalEvents) { + return function (config) { + tinymce.create('tinymce.plugins.magentowidget', { /** - * Fires after the rendering has completed. This ensures the editor will be instantiated + * @param {tinymce.Editor} editor - Editor instance that the plugin is initialized in. + * @param {String} url - Absolute URL to where the plugin is located. */ - onPostRender: function () { - var ctrl = this; + init: function (editor, url) { + var self = this; + + this.activePlaceholder = null; + + editor.addCommand('mceMagentowidget', function (img) { + if (self.activePlaceholder) { + img = self.activePlaceholder; + } - // Add a node change handler, selects the button in the UI when a image is selected - editor.on('nodeChange', function (e) { - var placeholder = e.element; + widgetTools.setActiveSelectedNode(img); + widgetTools.openDialog( + config['window_url'] + 'widget_target_id/' + editor.getElement().id + '/' + ); + }); + + // Register Widget plugin button + editor.addButton('magentowidget', { + title: jQuery.mage.__('Insert Widget'), + cmd: 'mceMagentowidget', + image: url + '/img/icon.png', + + /** + * Fires after the rendering has completed. This ensures the editor will be instantiated + */ + onPostRender: function () { + var ctrl = this; + + // Add a node change handler, selects the button in the UI when a image is selected + editor.on('nodeChange', function (e) { + var placeholder = e.element; + + if (self.isWidgetPlaceholderSelected(placeholder)) { + widgetTools.setEditMode(true); + ctrl.active(true); + } else { + widgetTools.setEditMode(false); + ctrl.active(false); + } + }); + } + }); + + // Add a widget placeholder image double click callback + editor.on('dblClick', function (e) { + var placeholder = e.target; if (self.isWidgetPlaceholderSelected(placeholder)) { widgetTools.setEditMode(true); - ctrl.active(true); - } else { - widgetTools.setEditMode(false); - ctrl.active(false); + this.execCommand('mceMagentowidget', null); } }); - } - }); - - // Add a widget placeholder image double click callback - editor.on('dblClick', function (e) { - var placeholder = e.target; - if (self.isWidgetPlaceholderSelected(placeholder)) { - widgetTools.setEditMode(true); - this.execCommand('mceMagentowidget', null); - } - }); + /** + * Attach event handler for when wysiwyg editor is about to encode its content + */ + varienGlobalEvents.attachEventHandler('wysiwygEncodeContent', function (content) { + content = self.encodeWidgets(self.decodeWidgets(content)); + content = self.removeDuplicateAncestorWidgetSpanElement(content); - /** - * Attach event handler for when wysiwyg editor is about to encode its content - */ - varienGlobalEvents.attachEventHandler('wysiwygEncodeContent', function (content) { - content = self.encodeWidgets(self.decodeWidgets(content)); - content = self.removeDuplicateAncestorWidgetSpanElement(content); + return content; + }); - return content; - }); + /** + * Attach event handler for when wysiwyg editor is about to decode its content + */ + varienGlobalEvents.attachEventHandler('wysiwygDecodeContent', function (content) { + content = self.decodeWidgets(content); - /** - * Attach event handler for when wysiwyg editor is about to decode its content - */ - varienGlobalEvents.attachEventHandler('wysiwygDecodeContent', function (content) { - content = self.decodeWidgets(content); + return content; + }); - return content; - }); + /** + * Attach event handler for when popups associated with wysiwyg are about to be closed + */ + varienGlobalEvents.attachEventHandler('wysiwygClosePopups', function () { + wysiwyg.closeEditorPopup('widget_window' + wysiwyg.getId()); + }); + }, - /** - * Attach event handler for when popups associated with wysiwyg are about to be closed - */ - varienGlobalEvents.attachEventHandler('wysiwygClosePopups', function () { - self.constructor.adapter.closeEditorPopup('widget_window' + self.constructor.adapter.id); - }); - }, - - /** - * @param {Object} placeholder - Contains the selected node - * @returns {Boolean} - */ - isWidgetPlaceholderSelected: function (placeholder) { - var isSelected = false; - - if (placeholder.nodeName && - (placeholder.nodeName === 'SPAN' || placeholder.nodeName === 'IMG') && - placeholder.className && placeholder.className.indexOf('magento-widget') !== -1 - ) { - this.activePlaceholder = placeholder; - isSelected = true; - } else { - this.activePlaceholder = null; - } - - return isSelected; - }, - - /** - * Convert {{widget}} style syntax to image placeholder HTML - * @param {String} content - * @return {*} - */ - encodeWidgets: function (content) { - return content.gsub(/\{\{widget(.*?)\}\}/i, function (match) { - var attributes = this.constructor.adapter.parseAttributesString(match[1]), - imageSrc, - imageHtml = ''; - - if (attributes.type) { - attributes.type = attributes.type.replace(/\\\\/g, '\\'); - imageSrc = this.constructor.config.placeholders[attributes.type]; - - if (this.constructor.config.types.indexOf(attributes['type_name']) > -1) { - imageHtml += ''; + /** + * @param {Object} placeholder - Contains the selected node + * @returns {Boolean} + */ + isWidgetPlaceholderSelected: function (placeholder) { + var isSelected = false; + + if (placeholder.nodeName && + (placeholder.nodeName === 'SPAN' || placeholder.nodeName === 'IMG') && + placeholder.className && placeholder.className.indexOf('magento-widget') !== -1 + ) { + this.activePlaceholder = placeholder; + isSelected = true; } else { - imageSrc = this.constructor.config['error_image_url']; - imageHtml += ''; + this.activePlaceholder = null; } - imageHtml += ' -1) { + imageHtml += ''; + } else { + imageSrc = config['error_image_url']; + imageHtml += ''; + } + + imageHtml += ']*>)?]+id="[^>]+)>(([^>]*)<\/span>)?/i, - function (match) { - var attributes = this.constructor.adapter.parseAttributesString(match[2]), - widgetCode; - - if (attributes.id) { - widgetCode = Base64.idDecode(attributes.id); - - if (widgetCode.indexOf('{{widget') !== -1) { - return widgetCode; + /** + * Convert image placeholder HTML to {{widget}} style syntax + * @param {String} content + * @return {*} + */ + decodeWidgets: function (content) { + return content.gsub( + /(]*>)?]+id="[^>]+)>(([^>]*)<\/span>)?/i, + function (match) { + var attributes = wysiwyg.parseAttributesString(match[2]), + widgetCode; + + if (attributes.id) { + widgetCode = Base64.idDecode(attributes.id); + + if (widgetCode.indexOf('{{widget') !== -1) { + return widgetCode; + } + } + + return match[0]; } - } + ); + }, - return match[0]; - }.bind(this) - ); - }, + /** + * Tinymce has strange behavior with html and this removes one of its side-effects + * @param {String} content + * @return {String} + */ + removeDuplicateAncestorWidgetSpanElement: function (content) { + var parser, doc; - /** - * Tinymce has strange behavior with html and this removes one of its side-effects - * @param {String} content - * @return {String} - */ - removeDuplicateAncestorWidgetSpanElement: function (content) { - var parser, doc; + if (!window.DOMParser) { + return content; + } - if (!window.DOMParser) { - return content; - } + parser = new DOMParser(); + doc = parser.parseFromString(content.replace(/"/g, '&quot;'), 'text/html'); - parser = new DOMParser(); - doc = parser.parseFromString(content, 'text/html'); + [].forEach.call(doc.querySelectorAll('.magento-widget'), function (widgetEl) { + var widgetChildEl = widgetEl.querySelector('.magento-widget'); - [].forEach.call(doc.querySelectorAll('.magento-widget'), function (widgetEl) { - var widgetChildEl = widgetEl.querySelector('.magento-widget'); + if (!widgetChildEl) { + return; + } - if (!widgetChildEl) { - return; - } + [].forEach.call(widgetEl.childNodes, function (el) { + widgetEl.parentNode.insertBefore(el, widgetEl); + }); - [].forEach.call(widgetEl.childNodes, function (el) { - widgetEl.parentNode.insertBefore(el, widgetEl); - }); + widgetEl.parentNode.removeChild(widgetEl); + }); - widgetEl.parentNode.removeChild(widgetEl); + return doc.body ? doc.body.innerHTML.replace(/&quot;/g, '"') : content; + }, + + /** + * @return {Object} + */ + getInfo: function () { + return { + longname: 'Magento Widget Manager Plugin', + author: 'Magento Core Team', + authorurl: 'http://magentocommerce.com', + infourl: 'http://magentocommerce.com', + version: '1.0' + }; + } }); - return doc.body.innerHTML; - }, - - /** - * @return {Object} - */ - getInfo: function () { - return { - longname: 'Magento Widget Manager Plugin', - author: 'Magento Core Team', - authorurl: 'http://magentocommerce.com', - infourl: 'http://magentocommerce.com', - version: '1.0' - }; - } + // Register plugin + tinymce.PluginManager.add('magentowidget', tinymce.plugins.magentowidget); + }; }); - -// Register plugin -tinymce.PluginManager.add('magentowidget', tinymce.plugins.magentowidget); diff --git a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js index 4139b58a20aec..ef2e56b2ef66c 100644 --- a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js +++ b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/tinymce4Adapter.js @@ -3,18 +3,17 @@ * See COPYING.txt for license details. */ -/* global varienGlobalEvents, popups, tinyMceEditors, MediabrowserUtility, Base64 */ +/* global popups, tinyMceEditors, MediabrowserUtility, Base64 */ /* eslint-disable strict */ define([ 'jquery', 'underscore', 'tinymce4', + 'mage/adminhtml/events', 'mage/translate', 'prototype', - 'mage/adminhtml/events', - 'jquery/ui', - 'mage/translate' -], function (jQuery, _, tinyMCE4, $t) { + 'jquery/ui' +], function (jQuery, _, tinyMCE4, varienGlobalEvents) { 'use strict'; var tinyMce4Wysiwyg = Class.create(); @@ -67,7 +66,8 @@ define([ * Setup TinyMCE4 editor */ setup: function (mode) { - var settings, + var deferreds = [], + settings, self = this; this.turnOff(); @@ -78,23 +78,26 @@ define([ if (this.config.plugins) { this.config.plugins.forEach(function (plugin) { + var deferred; + self.addPluginToToolbar(plugin.name, '|'); - if (plugin.src) { - tinyMCE4.PluginManager.load(plugin.name, plugin.src, function () { - var pluginConstructor = tinyMCE4.plugins[plugin.name]; + if (!plugin.src) { + return; + } - if (!pluginConstructor) { - throw new Error($t('Could not find plugin with name %1').replace('%1', plugin.name)); - } + deferred = jQuery.Deferred(); + deferreds.push(deferred); - pluginConstructor.config = plugin.options; - pluginConstructor.adapter = self; - }); - } + require([plugin.src], function (factoryFn) { + if (typeof factoryFn === 'function') { + factoryFn(plugin.options); + } + tinyMCE4.PluginManager.load(plugin.name, plugin.src); + deferred.resolve(); + }); }); - } if (jQuery.isReady) { @@ -103,8 +106,11 @@ define([ settings = this.getSettings(); settings.mode = mode; - tinyMCE4.init(settings); - this.getPluginButtons().hide(); + + jQuery.when.apply(jQuery, deferreds).done(function () { + tinyMCE4.init(settings); + this.getPluginButtons().hide(); + }.bind(this)); }, /** @@ -129,6 +135,32 @@ define([ this.config.tinymce4.toolbar = toolbar.join(' '); }, + /** + * Set the status of the toolbar to disabled or enabled (true for enabled, false for disabled) + * @param {Boolean} enabled + */ + setToolbarStatus: function (enabled) { + var controlIds = this.get(this.getId()).theme.panel.rootControl.controlIdLookup; + + _.each(controlIds, function (controlId) { + controlId.disabled(!enabled); + controlId.canFocus = enabled; + + if (controlId.tooltip) { + controlId.tooltip().state.set('rendered', enabled); + + if (enabled) { + jQuery(controlId.getEl()).children('button').andSelf().removeAttr('style'); + } else { + jQuery(controlId.getEl()).children('button').andSelf().attr('style', 'color: inherit;' + + 'background-color: inherit;' + + 'border-color: transparent;' + ); + } + } + }); + }, + /** * @return {Object} */ @@ -136,7 +168,7 @@ define([ var settings; settings = { - selector: 'textarea#' + this.id, + selector: 'textarea#' + this.getId(), theme: 'modern', 'entity_encoding': 'raw', 'convert_urls': false, @@ -186,6 +218,10 @@ define([ editor.on('ExecCommand', function (cmd) { varienGlobalEvents.fireEvent('tinymceExecCommand', cmd); }); + + editor.on('init', function (args) { + varienGlobalEvents.fireEvent('wysiwygEditorInitialized', args.target); + }); } }; @@ -243,6 +279,13 @@ define([ return tinyMCE4.get(id); }, + /** + * @return {String|null} + */ + getId: function () { + return this.id || (this.activeEditor() ? this.activeEditor().id : null) || tinyMceEditors.values()[0].id; + }, + /** * @return {Object} */ @@ -278,7 +321,7 @@ define([ storeId = this.config['store_id'] !== null ? this.config['store_id'] : 0, frameDialog = jQuery('div.mce-container[role="dialog"]'), wUrl = this.config['files_browser_window_url'] + - 'target_element_id/' + this.id + '/' + + 'target_element_id/' + this.getId() + '/' + 'store/' + storeId + '/'; this.mediaBrowserOpener = o.win; @@ -330,14 +373,14 @@ define([ * @return {jQuery|*|HTMLElement} */ getToggleButton: function () { - return $('toggle' + this.id); + return $('toggle' + this.getId()); }, /** * Get plugins button. */ getPluginButtons: function () { - return jQuery('#buttons' + this.id + ' > button.plugin'); + return jQuery('#buttons' + this.getId() + ' > button.plugin'); }, /** @@ -351,7 +394,7 @@ define([ this.getPluginButtons().hide(); - tinyMCE4.execCommand('mceAddControl', false, this.id); + tinyMCE4.execCommand('mceAddControl', false, this.getId()); return this; }, @@ -373,7 +416,7 @@ define([ this.getPluginButtons().show(); - tinyMCE4.execCommand('mceRemoveEditor', false, this.id); + tinyMCE4.execCommand('mceRemoveEditor', false, this.getId()); return this; }, @@ -384,14 +427,14 @@ define([ closePopups: function () { // close all popups to avoid problems with updating parent content area varienGlobalEvents.fireEvent('wysiwygClosePopups'); - this.closeEditorPopup('browser_window' + this.id); + this.closeEditorPopup('browser_window' + this.getId()); }, /** * @return {Boolean} */ toggle: function () { - if (!tinyMCE4.get(this.id)) { + if (!tinyMCE4.get(this.getId())) { this.turnOn(); return true; @@ -405,8 +448,8 @@ define([ * On form validation. */ onFormValidation: function () { - if (tinyMCE4.get(this.id)) { - $(this.id).value = tinyMCE4.get(this.id).getContent(); + if (tinyMCE4.get(this.getId())) { + $(this.getId()).value = tinyMCE4.get(this.getId()).getContent(); } }, @@ -484,7 +527,7 @@ define([ * Update text area. */ updateTextArea: function () { - var editor = tinyMCE4.get(this.id), + var editor = tinyMCE4.get(this.getId()), content; if (!editor) { @@ -497,7 +540,33 @@ define([ content = editor.getContent(); content = this.decodeContent(content); - jQuery('#' + this.id).val(content).trigger('change'); + this.getTextArea().val(content).trigger('change'); + }, + + /** + * @return {Object} jQuery textarea element + */ + getTextArea: function () { + return jQuery('#' + this.getId()); + }, + + /** + * Set the status of the editor and toolbar + * + * @param {Boolean} enabled + */ + setEnabledStatus: function (enabled) { + if (this.activeEditor()) { + this.activeEditor().getBody().setAttribute('contenteditable', enabled); + this.activeEditor().readonly = !enabled; + this.setToolbarStatus(enabled); + } + + if (enabled) { + this.getTextArea().removeProp('disabled'); + } else { + this.getTextArea().prop('disabled', 'disabled'); + } }, /** @@ -506,39 +575,43 @@ define([ * @param {String} directive */ makeDirectiveUrl: function (directive) { - return this.config['directives_url'].replace('directive', 'directive/___directive/' + directive); + return this.config['directives_url'].replace(/directive.*/, 'directive/___directive/' + directive); }, /** + * Convert {{directive}} style attributes syntax to absolute URLs * @param {Object} content * @return {*} */ encodeDirectives: function (content) { // collect all HTML tags with attributes that contain directives return content.gsub(/<([a-z0-9\-\_]+[^>]+?)([a-z0-9\-\_]+=".*?\{\{.+?\}\}.*?".*?)>/i, function (match) { - var attributesString = match[2]; + var attributesString = match[2], + decodedDirectiveString; // process tag attributes string attributesString = attributesString.gsub(/([a-z0-9\-\_]+)="(.*?)(\{\{.+?\}\})(.*?)"/i, function (m) { - return m[1] + '="' + m[2] + this.makeDirectiveUrl(Base64.mageEncode(m[3])) + m[4] + '"'; + decodedDirectiveString = encodeURIComponent(Base64.mageEncode(m[3].replace(/"/g, '"'))); + + return m[1] + '="' + m[2] + this.makeDirectiveUrl(decodedDirectiveString) + m[4] + '"'; }.bind(this)); return '<' + match[1] + attributesString + '>'; - }.bind(this)); }, /** + * Convert absolute URLs to {{directive}} style attributes syntax * @param {Object} content * @return {*} */ decodeDirectives: function (content) { // escape special chars in directives url to use it in regular expression var url = this.makeDirectiveUrl('%directive%').replace(/([$^.?*!+:=()\[\]{}|\\])/g, '\\$1'), - reg = new RegExp(url.replace('%directive%', '([a-zA-Z0-9,_-]+)')); + reg = new RegExp(url.replace('%directive%', '([a-zA-Z0-9%,_-]+)\/?')); return content.gsub(reg, function (match) { //eslint-disable-line no-extra-bind - return Base64.mageDecode(match[1]); + return Base64.mageDecode(decodeURIComponent(match[1])).replace(/"/g, '"'); }); }, diff --git a/lib/web/mage/backend/suggest.js b/lib/web/mage/backend/suggest.js index 81bde35f9e12a..412a80804ae0f 100644 --- a/lib/web/mage/backend/suggest.js +++ b/lib/web/mage/backend/suggest.js @@ -245,6 +245,7 @@ case keyCode.ENTER: case keyCode.NUMPAD_ENTER: + this._toggleEnter(event); if (this.isDropdownShown() && this._focused) { this._proxyEvents(event); @@ -314,6 +315,30 @@ this._bindDropdown(); }, + /** + * @param {Object} event - event object + * @private + */ + _toggleEnter: function (event) { + var suggestList, + activeItems, + selectedItem; + + suggestList = $(event.currentTarget.parentNode).find('ul').first(); + activeItems = suggestList.find('._active'); + + if (activeItems.length >= 0) { + selectedItem = activeItems.first(); + + if (selectedItem.find('a') && selectedItem.find('a').attr('href') !== undefined) { + window.location = selectedItem.find('a').attr('href'); + event.preventDefault(); + + return false; + } + } + }, + /** * @param {Object} e - event object * @private diff --git a/lib/web/mage/collapsible.js b/lib/web/mage/collapsible.js index 0d8cf836c198e..267734605f141 100644 --- a/lib/web/mage/collapsible.js +++ b/lib/web/mage/collapsible.js @@ -243,7 +243,7 @@ define([ }); // For collapsible widget only (not tabs or accordion) - if (this.header.parent().attr('role') != 'presentation') { //eslint-disable-line eqeqeq + if (this.header.parent().attr('role') !== 'presentation') { this.header .parent() .attr('role', 'tablist'); @@ -316,9 +316,9 @@ define([ * Disable. */ disable: function () { + this.options.disabled = true; this._off(this.trigger); this.forceDeactivate(); - this.options.disabled = true; if (this.options.disabledState) { this.element.addClass(this.options.disabledState); @@ -330,12 +330,14 @@ define([ * Enable. */ enable: function () { - this._on(this.trigger, this.events); this.options.disabled = false; + this._on(this.trigger, this.events); + this.forceActivate(); if (this.options.disabledState) { this.element.removeClass(this.options.disabledState); } + this.trigger.attr('tabIndex', 0); }, /** @@ -517,7 +519,7 @@ define([ that = this; if (url) { - this.xhr = $.get({ + that.xhr = $.get({ url: url, dataType: 'html' }, function () { @@ -533,7 +535,8 @@ define([ setTimeout(function () { that.content.html(response); }, 1); - }).complete(function (jqXHR, status) { + }); + that.xhr.complete(function (jqXHR, status) { setTimeout(function () { if (status === 'abort') { that.content.stop(false, true); diff --git a/lib/web/mage/menu.js b/lib/web/mage/menu.js index a59ebbaf8badc..834981402f67f 100644 --- a/lib/web/mage/menu.js +++ b/lib/web/mage/menu.js @@ -21,6 +21,7 @@ define([ expanded: false, showDelay: 42, hideDelay: 300, + delay: 300, mediaBreakpoint: '(max-width: 768px)' }, @@ -30,6 +31,8 @@ define([ _create: function () { var self = this; + this.delay = this.options.delay; + this._super(); $(window).on('resize', function () { self.element.find('.submenu-reverse').removeClass('submenu-reverse'); @@ -586,7 +589,7 @@ define([ html.removeClass('nav-open'); setTimeout(function () { html.removeClass('nav-before-open'); - }, 300); + }, this.options.hideDelay); } }, diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index aaece677a485d..7dee441b2a078 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -395,6 +395,24 @@ $.mage.__('Please enter at least {0} characters') ], + /* detect chars that would require more than 3 bytes */ + 'validate-no-utf8mb4-characters': [ + function (value) { + var validator = this, + message = $.mage.__('Please remove invalid characters: {0}.'), + matches = value.match(/(?:[\uD800-\uDBFF][\uDC00-\uDFFF])/g), + result = matches === null; + + if (!result) { + validator.charErrorMessage = message.replace('{0}', matches.join()); + } + + return result; + }, function () { + return this.charErrorMessage; + } + ], + /* eslint-disable max-len */ 'email2': [ function (value, element) { @@ -826,11 +844,13 @@ result = true; range = param; - if (typeof range === 'object') { + if (typeof range === 'string') { m = dataAttrRange.exec(range); if (m) { result = result && $.mage.isBetween(numValue, m[1], m[2]); + } else { + result = false; } } else if (elm && elm.className) { classes = elm.className.split(' '); @@ -877,11 +897,13 @@ result = true; range = param; - if (typeof range === 'object') { + if (typeof range === 'string') { m = dataAttrRange.exec(range); if (m) { result = result && $.mage.isBetween(numValue, m[1], m[2]); + } else { + result = false; } } else if (elm && elm.className) { classes = elm.className.split(' '); diff --git a/nginx.conf.sample b/nginx.conf.sample index 58c059657c070..1e20a51a511d3 100644 --- a/nginx.conf.sample +++ b/nginx.conf.sample @@ -100,7 +100,7 @@ location /static/ { # Remove signature of the static files that is used to overcome the browser cache location ~ ^/static/version { - rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last; + rewrite ^/static/(version[^/]+/)?(.*)$ /static/$2 last; } location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ { @@ -162,7 +162,7 @@ location /media/import/ { } # PHP entry point for main application -location ~ (index|get|static|report|404|503)\.php$ { +location ~ (index|get|static|report|404|503|health_check)\.php$ { try_files $uri =404; fastcgi_pass fastcgi_backend; fastcgi_buffers 1024 4k; diff --git a/setup/src/Magento/Setup/Console/Command/AdminUserCreateCommand.php b/setup/src/Magento/Setup/Console/Command/AdminUserCreateCommand.php index 940bcbbd6d7f1..4ad8e7c229bfd 100644 --- a/setup/src/Magento/Setup/Console/Command/AdminUserCreateCommand.php +++ b/setup/src/Magento/Setup/Console/Command/AdminUserCreateCommand.php @@ -6,13 +6,14 @@ namespace Magento\Setup\Console\Command; -use Magento\Setup\Model\AdminAccount; use Magento\Framework\Setup\ConsoleLogger; +use Magento\Setup\Model\AdminAccount; use Magento\Setup\Model\InstallerFactory; use Magento\User\Model\UserValidationRules; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\Question; class AdminUserCreateCommand extends AbstractSetupCommand { @@ -50,6 +51,98 @@ protected function configure() parent::configure(); } + /** + * @param \Symfony\Component\Console\Input\InputInterface $input + * @param \Symfony\Component\Console\Output\OutputInterface $output + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ + protected function interact(InputInterface $input, OutputInterface $output) + { + /** @var \Symfony\Component\Console\Helper\QuestionHelper $questionHelper */ + $questionHelper = $this->getHelper('question'); + + if (!$input->getOption(AdminAccount::KEY_USER)) { + $question = new Question('Admin user: ', ''); + $this->addNotEmptyValidator($question); + + $input->setOption( + AdminAccount::KEY_USER, + $questionHelper->ask($input, $output, $question) + ); + } + + if (!$input->getOption(AdminAccount::KEY_PASSWORD)) { + $question = new Question('Admin password: ', ''); + $question->setHidden(true); + + $question->setValidator(function ($value) use ($output) { + $user = new \Magento\Framework\DataObject(); + $user->setPassword($value); + + $validator = new \Magento\Framework\Validator\DataObject(); + $this->validationRules->addPasswordRules($validator); + + $validator->isValid($user); + foreach ($validator->getMessages() as $message) { + throw new \Exception($message); + } + + return $value; + }); + + $input->setOption( + AdminAccount::KEY_PASSWORD, + $questionHelper->ask($input, $output, $question) + ); + } + + if (!$input->getOption(AdminAccount::KEY_EMAIL)) { + $question = new Question('Admin email: ', ''); + $this->addNotEmptyValidator($question); + + $input->setOption( + AdminAccount::KEY_EMAIL, + $questionHelper->ask($input, $output, $question) + ); + } + + if (!$input->getOption(AdminAccount::KEY_FIRST_NAME)) { + $question = new Question('Admin first name: ', ''); + $this->addNotEmptyValidator($question); + + $input->setOption( + AdminAccount::KEY_FIRST_NAME, + $questionHelper->ask($input, $output, $question) + ); + } + + if (!$input->getOption(AdminAccount::KEY_LAST_NAME)) { + $question = new Question('Admin last name: ', ''); + $this->addNotEmptyValidator($question); + + $input->setOption( + AdminAccount::KEY_LAST_NAME, + $questionHelper->ask($input, $output, $question) + ); + } + } + + /** + * @param \Symfony\Component\Console\Question\Question $question + * @return void + */ + private function addNotEmptyValidator(Question $question) + { + $question->setValidator(function ($value) { + if (trim($value) == '') { + throw new \Exception('The value cannot be empty'); + } + + return $value; + }); + } + /** * {@inheritdoc} */ @@ -57,7 +150,7 @@ protected function execute(InputInterface $input, OutputInterface $output) { $errors = $this->validate($input); if ($errors) { - $output->writeln('' . implode('' . PHP_EOL . '', $errors) . ''); + $output->writeln('' . implode('' . PHP_EOL . '', $errors) . ''); // we must have an exit code higher than zero to indicate something was wrong return \Magento\Framework\Console\Cli::RETURN_FAILURE; } @@ -113,7 +206,7 @@ public function validate(InputInterface $input) ? '' : $input->getOption(AdminAccount::KEY_PASSWORD) ); - $validator = new \Magento\Framework\Validator\DataObject; + $validator = new \Magento\Framework\Validator\DataObject(); $this->validationRules->addUserInfoRules($validator); $this->validationRules->addPasswordRules($validator); diff --git a/setup/src/Magento/Setup/Console/Command/InstallCommand.php b/setup/src/Magento/Setup/Console/Command/InstallCommand.php index b0ccbba8c296f..a2e8715b02233 100644 --- a/setup/src/Magento/Setup/Console/Command/InstallCommand.php +++ b/setup/src/Magento/Setup/Console/Command/InstallCommand.php @@ -13,6 +13,9 @@ use Magento\Framework\Setup\ConsoleLogger; use Symfony\Component\Console\Input\InputOption; use Magento\Setup\Model\ConfigModel; +use Symfony\Component\Console\Question\Question; +use Symfony\Component\Console\Question\ChoiceQuestion; +use Symfony\Component\Console\Helper\QuestionHelper; /** * Command to install Magento application @@ -35,6 +38,16 @@ class InstallCommand extends AbstractSetupCommand */ const INPUT_KEY_USE_SAMPLE_DATA = 'use-sample-data'; + /** + * Parameter indicating command for interactive setup + */ + const INPUT_KEY_INTERACTIVE_SETUP = 'interactive'; + + /** + * Parameter indicating command shortcut for interactive setup + */ + const INPUT_KEY_INTERACTIVE_SETUP_SHORTCUT = 'i'; + /** * Regex for sales_order_increment_prefix validation. */ @@ -109,7 +122,13 @@ protected function configure() null, InputOption::VALUE_NONE, 'Use sample data' - ) + ), + new InputOption( + self::INPUT_KEY_INTERACTIVE_SETUP, + self::INPUT_KEY_INTERACTIVE_SETUP_SHORTCUT, + InputOption::VALUE_NONE, + 'Interactive Magento instalation' + ), ]); $this->setName('setup:install') ->setDescription('Installs the Magento application') @@ -139,12 +158,25 @@ protected function initialize(InputInterface $input, OutputInterface $output) { $inputOptions = $input->getOptions(); - $configOptionsToValidate = []; - foreach ($this->configModel->getAvailableOptions() as $option) { - if (array_key_exists($option->getName(), $inputOptions)) { - $configOptionsToValidate[$option->getName()] = $inputOptions[$option->getName()]; + if ($inputOptions['interactive']) { + $configOptionsToValidate = $this->interactiveQuestions($input, $output); + } else { + $configOptionsToValidate = []; + foreach ($this->configModel->getAvailableOptions() as $option) { + if (array_key_exists($option->getName(), $inputOptions)) { + $configOptionsToValidate[$option->getName()] = $inputOptions[$option->getName()]; + } + } + } + + if ($inputOptions['interactive']) { + $command = ''; + foreach ($configOptionsToValidate as $key => $value) { + $command .= " --{$key}={$value}"; } + $output->writeln("Try re-running command: php bin/magento setup:install{$command}"); } + $errors = $this->configModel->validate($configOptionsToValidate); $errors = array_merge($errors, $this->adminUser->validate($input)); $errors = array_merge($errors, $this->validate($input)); @@ -177,4 +209,133 @@ public function validate(InputInterface $input) } return $errors; } + + /** + * Runs interactive questions + * + * It will ask users for interactive questionst regarding setup configuration. + * + * @param InputInterface $input + * @param OutputInterface $output + * @return string[] Array of inputs + */ + private function interactiveQuestions(InputInterface $input, OutputInterface $output) + { + $helper = $this->getHelper('question'); + $configOptionsToValidate = []; + + foreach ($this->configModel->getAvailableOptions() as $option) { + $configOptionsToValidate[$option->getName()] = $this->askQuestion( + $input, + $output, + $helper, + $option, + true + ); + } + + $output->writeln(""); + + foreach ($this->userConfig->getOptionsList() as $option) { + $configOptionsToValidate[$option->getName()] = $this->askQuestion( + $input, + $output, + $helper, + $option + ); + } + + $output->writeln(""); + + foreach ($this->adminUser->getOptionsList() as $option) { + $configOptionsToValidate[$option->getName()] = $this->askQuestion( + $input, + $output, + $helper, + $option + ); + } + + $output->writeln(""); + + $returnConfigOptionsToValidate = []; + foreach ($configOptionsToValidate as $key => $value) { + if ($value != '') { + $returnConfigOptionsToValidate[$key] = $value; + } + } + + return $returnConfigOptionsToValidate; + } + + /** + * Runs interactive questions + * + * It will ask users for interactive questionst regarding setup configuration. + * + * @param InputInterface $input + * @param OutputInterface $output + * @param QuestionHelper $helper + * @param TextConfigOption|FlagConfigOption\SelectConfigOption $option + * @param Boolean $validateInline + * @return string[] Array of inputs + */ + private function askQuestion( + InputInterface $input, + OutputInterface $output, + QuestionHelper $helper, + $option, + $validateInline = false + ) { + if ($option instanceof \Magento\Framework\Setup\Option\SelectConfigOption) { + if ($option->isValueRequired()) { + $question = new ChoiceQuestion( + $option->getDescription() . '? ', + $option->getSelectOptions(), + $option->getDefault() + ); + } else { + $question = new ChoiceQuestion( + $option->getDescription() . ' [optional]? ', + $option->getSelectOptions(), + $option->getDefault() + ); + } + } else { + if ($option->isValueRequired()) { + $question = new Question( + $option->getDescription() . '? ', + $option->getDefault() + ); + } else { + $question = new Question( + $option->getDescription() . ' [optional]? ', + $option->getDefault() + ); + } + } + + $question->setValidator(function ($answer) use ($option, $validateInline) { + + if ($option instanceof \Magento\Framework\Setup\Option\SelectConfigOption) { + $answer = $option->getSelectOptions()[$answer]; + } + + if ($answer == null) { + $answer = ''; + } else { + $answer = trim($answer); + } + + if ($validateInline) { + $option->validate($answer); + } + + return $answer; + }); + + $value = $helper->ask($input, $output, $question); + + return $value; + } } diff --git a/setup/src/Magento/Setup/Model/Installer.php b/setup/src/Magento/Setup/Model/Installer.php index 4a9bfd9063656..63584151fd7ba 100644 --- a/setup/src/Magento/Setup/Model/Installer.php +++ b/setup/src/Magento/Setup/Model/Installer.php @@ -337,7 +337,8 @@ public function install($request) $this->log->log('Starting Magento installation:'); - while (list(, list($message, $method, $params)) = each($script)) { + foreach ($script as $item) { + list($message, $method, $params) = $item; $this->log->log($message); call_user_func_array([$this, $method], $params); $this->logProgress(); @@ -1010,6 +1011,7 @@ private function installOrderIncrementPrefix($orderIncrementPrefix) public function installAdminUser($data) { $this->assertDbConfigExists(); + $data += ['db-prefix' => $this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_DB_PREFIX)]; $setup = $this->setupFactory->create($this->context->getResources()); $adminAccount = $this->adminAccountFactory->create($setup->getConnection(), (array)$data); $adminAccount->save(); diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/AdminUserCreateCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/AdminUserCreateCommandTest.php index 1cfd0c9494a51..d244f48d4e1ea 100644 --- a/setup/src/Magento/Setup/Test/Unit/Console/Command/AdminUserCreateCommandTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/AdminUserCreateCommandTest.php @@ -5,14 +5,21 @@ */ namespace Magento\Setup\Test\Unit\Console\Command; -use Magento\Setup\Model\AdminAccount; use Magento\Setup\Console\Command\AdminUserCreateCommand; +use Magento\Setup\Model\AdminAccount; use Magento\Setup\Mvc\Bootstrap\InitParamListener; use Magento\User\Model\UserValidationRules; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Tester\CommandTester; class AdminUserCreateCommandTest extends \PHPUnit\Framework\TestCase { + /** + * @var \PHPUnit_Framework_MockObject_MockObject|\Symfony\Component\Console\Helper\QuestionHelper + */ + private $questionHelperMock; + /** * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Model\InstallerFactory */ @@ -27,6 +34,10 @@ public function setUp() { $this->installerFactoryMock = $this->createMock(\Magento\Setup\Model\InstallerFactory::class); $this->command = new AdminUserCreateCommand($this->installerFactoryMock, new UserValidationRules()); + + $this->questionHelperMock = $this->getMockBuilder(QuestionHelper::class) + ->setMethods(['ask']) + ->getMock(); } public function testExecute() @@ -50,10 +61,70 @@ public function testExecute() $installerMock = $this->createMock(\Magento\Setup\Model\Installer::class); $installerMock->expects($this->once())->method('installAdminUser')->with($data); $this->installerFactoryMock->expects($this->once())->method('create')->willReturn($installerMock); - $commandTester->execute($options); + $commandTester->execute($options, ['interactive' => false]); $this->assertEquals('Created Magento administrator user named user' . PHP_EOL, $commandTester->getDisplay()); } + public function testInteraction() + { + $application = new Application(); + $application->add($this->command); + + $this->questionHelperMock->expects($this->at(0)) + ->method('ask') + ->will($this->returnValue('admin')); + + $this->questionHelperMock->expects($this->at(1)) + ->method('ask') + ->will($this->returnValue('Password123')); + + $this->questionHelperMock->expects($this->at(2)) + ->method('ask') + ->will($this->returnValue('john.doe@example.com')); + + $this->questionHelperMock->expects($this->at(3)) + ->method('ask') + ->will($this->returnValue('John')); + + $this->questionHelperMock->expects($this->at(4)) + ->method('ask') + ->will($this->returnValue('Doe')); + + // We override the standard helper with our mock + $this->command->getHelperSet()->set($this->questionHelperMock, 'question'); + + $installerMock = $this->createMock(\Magento\Setup\Model\Installer::class); + + $expectedData = [ + 'admin-user' => 'admin', + 'admin-password' => 'Password123', + 'admin-email' => 'john.doe@example.com', + 'admin-firstname' => 'John', + 'admin-lastname' => 'Doe', + 'magento-init-params' => null, + 'help' => false, + 'quiet' => false, + 'verbose' => false, + 'version' => false, + 'ansi' => false, + 'no-ansi' => false, + 'no-interaction' => false, + ]; + + $installerMock->expects($this->once())->method('installAdminUser')->with($expectedData); + $this->installerFactoryMock->expects($this->once())->method('create')->willReturn($installerMock); + + $commandTester = new CommandTester($this->command); + $commandTester->execute([ + 'command' => $this->command->getName(), + ]); + + $this->assertEquals( + 'Created Magento administrator user named admin' . PHP_EOL, + $commandTester->getDisplay() + ); + } + public function testGetOptionsList() { /* @var $argsList \Symfony\Component\Console\Input\InputArgument[] */ diff --git a/setup/src/Magento/Setup/Test/Unit/Module/Di/Code/Reader/FileClassScannerTest.php b/setup/src/Magento/Setup/Test/Unit/Module/Di/Code/Reader/FileClassScannerTest.php index 72a9bcdc4df72..5bc7fd82b3251 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/Di/Code/Reader/FileClassScannerTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/Di/Code/Reader/FileClassScannerTest.php @@ -204,13 +204,38 @@ class ThisIsNotMyTest self::assertContains('This\Is\Not\My\Ns\ThisIsNotMyTest', $result); } - public function testClassKeywordInMiddleOfFile() + public function testMultipleClassKeywordsInMiddleOfFileWithStringVariableParsing() { - $filename = __DIR__ - . '/../../../../../../../../../..' - . '/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/AbstractEav.php'; - $filename = realpath($filename); - $scanner = new FileClassScanner($filename); + $scanner = $this->getMockBuilder(FileClassScanner::class)->disableOriginalConstructor()->setMethods([ + 'getFileContents' + ])->getMock(); + $scanner->expects(self::once())->method('getFileContents')->willReturn(<<<'PHP' +doMethod(stdClass::class)->runAction(); + } +} + +PHP + ); + + /* @var $scanner FileClassScanner */ $result = $scanner->getClassNames(); self::assertCount(1, $result); diff --git a/setup/view/magento/setup/readiness-check/progress.phtml b/setup/view/magento/setup/readiness-check/progress.phtml index c1ac41c6b5f2e..eb9dd0ce9d1aa 100755 --- a/setup/view/magento/setup/readiness-check/progress.phtml +++ b/setup/view/magento/setup/readiness-check/progress.phtml @@ -336,7 +336,7 @@

    For additional assistance, see - PHP settings check help .

    @@ -392,7 +392,7 @@ @@ -413,7 +413,7 @@

    The best way to resolve this is to install the correct missing extensions. The exact fix depends on our server, your host, and other system variables.
    - Our PHP extension help can get you started. + Our PHP extension help can get you started.

    For additional assistance, contact your hosting provider. @@ -477,7 +477,7 @@

    @@ -500,7 +500,7 @@ The best way to resolve this is to allow write permissions for files in the following Magento directories and subdirectories. The exact fix depends on your server, your host, and other system variables.
    - For help, see our File Permission Help or call your hosting provider. + For help, see our File Permission Help or call your hosting provider.