PageRenderTime 60ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/testsuite/Core/Mage/Product/Helper.php

https://github.com/KNXSebastian/taf
PHP | 1474 lines | 1129 code | 66 blank | 279 comment | 199 complexity | 2b8de88335016255c3937ee60775de46 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category tests
  22. * @package selenium
  23. * @subpackage tests
  24. * @author Magento Core Team <core@magentocommerce.com>
  25. * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
  26. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  27. */
  28. /**
  29. * Helper class
  30. *
  31. * @package selenium
  32. * @subpackage tests
  33. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  34. */
  35. class Core_Mage_Product_Helper extends Mage_Selenium_TestCase
  36. {
  37. public static $arrayToReturn = array();
  38. /**
  39. * Fill in Product Settings tab
  40. *
  41. * @param array $productData
  42. * @param string $productType Value - simple|virtual|bundle|configurable|downloadable|grouped
  43. */
  44. public function fillProductSettings($productData, $productType = 'simple')
  45. {
  46. $attributeSet = (isset($productData['product_attribute_set']))
  47. ? $productData['product_attribute_set']
  48. : null;
  49. $attributeSetXpath = $this->_getControlXpath('dropdown', 'product_attribute_set');
  50. $productTypeXpath = $this->_getControlXpath('dropdown', 'product_type');
  51. if (!empty($attributeSet)) {
  52. $this->select($attributeSetXpath, 'label=' . $attributeSet);
  53. $attributeSetID = $this->getValue($attributeSetXpath . '/option[text()=\'' . $attributeSet . '\']');
  54. } else {
  55. $attributeSetID = $this->getValue($attributeSetXpath . "/option[@selected='selected']");
  56. }
  57. $this->select($productTypeXpath, 'value=' . $productType);
  58. $this->addParameter('setId', $attributeSetID);
  59. $this->addParameter('productType', $productType);
  60. $this->clickButton('continue');
  61. }
  62. /**
  63. * Select Dropdown Attribute(s) for configurable product creation
  64. *
  65. * @param array $productData
  66. */
  67. public function fillConfigurableSettings(array $productData)
  68. {
  69. $attributes = (isset($productData['configurable_attribute_title']))
  70. ? explode(',', $productData['configurable_attribute_title'])
  71. : null;
  72. if (!empty($attributes)) {
  73. $attributesId = array();
  74. $attributes = array_map('trim', $attributes);
  75. foreach ($attributes as $attributeTitle) {
  76. $this->addParameter('attributeTitle', $attributeTitle);
  77. $xpath = $this->_getControlXpath('checkbox', 'configurable_attribute_title');
  78. if ($this->isElementPresent($xpath)) {
  79. $attributesId[] = $this->getAttribute($xpath . '/@value');
  80. $this->click($xpath);
  81. } else {
  82. $this->fail("Dropdown attribute with title '$attributeTitle' is not present on the page");
  83. }
  84. }
  85. $attributesUrl = urlencode(base64_encode(implode(',', $attributesId)));
  86. $this->addParameter('attributesUrl', $attributesUrl);
  87. $this->clickButton('continue');
  88. } else {
  89. $this->fail('Dropdown attribute for configurable product creation is not set');
  90. }
  91. }
  92. /**
  93. * Fill Product Tab
  94. *
  95. * @param array $productData
  96. * @param string $tabName Value - general|prices|meta_information|images|recurring_profile
  97. * |design|gift_options|inventory|websites|categories|related|up_sells
  98. * |cross_sells|custom_options|bundle_items|associated|downloadable_information
  99. *
  100. * @return bool
  101. */
  102. public function fillProductTab(array $productData, $tabName = 'general')
  103. {
  104. $tabData = array();
  105. $needFilling = false;
  106. foreach ($productData as $key => $value) {
  107. if (preg_match('/^' . $tabName . '/', $key)) {
  108. $tabData[$key] = $value;
  109. }
  110. }
  111. if ($tabData) {
  112. $needFilling = true;
  113. }
  114. $tabXpath = $this->_getControlXpath('tab', $tabName);
  115. if ($tabName == 'websites' && !$this->isElementPresent($tabXpath)) {
  116. $needFilling = false;
  117. }
  118. if (!$needFilling) {
  119. return true;
  120. }
  121. $this->openTab($tabName);
  122. switch ($tabName) {
  123. case 'prices':
  124. $arrayKey = 'prices_tier_price_data';
  125. if (array_key_exists($arrayKey, $tabData) && is_array($tabData[$arrayKey])) {
  126. foreach ($tabData[$arrayKey] as $value) {
  127. $this->addTierPrice($value);
  128. }
  129. }
  130. $this->fillForm($tabData, 'prices');
  131. $this->fillUserAttributesOnTab($tabData, $tabName);
  132. break;
  133. case 'websites':
  134. $websites = explode(',', $tabData[$tabName]);
  135. $websites = array_map('trim', $websites);
  136. foreach ($websites as $value) {
  137. $this->selectWebsite($value);
  138. }
  139. break;
  140. case 'categories':
  141. $categories = explode(',', $tabData[$tabName]);
  142. $categories = array_map('trim', $categories);
  143. foreach ($categories as $value) {
  144. $this->categoryHelper()->selectCategory($value);
  145. }
  146. break;
  147. case 'related':
  148. case 'up_sells':
  149. case 'cross_sells':
  150. $arrayKey = $tabName . '_data';
  151. if (array_key_exists($arrayKey, $tabData) && is_array($tabData[$arrayKey])) {
  152. foreach ($tabData[$arrayKey] as $value) {
  153. $this->assignProduct($value, $tabName);
  154. }
  155. }
  156. break;
  157. case 'custom_options':
  158. $arrayKey = $tabName . '_data';
  159. if (array_key_exists($arrayKey, $tabData) && is_array($tabData[$arrayKey])) {
  160. foreach ($tabData[$arrayKey] as $value) {
  161. $this->addCustomOption($value);
  162. }
  163. }
  164. break;
  165. case 'bundle_items':
  166. $arrayKey = $tabName . '_data';
  167. if (array_key_exists($arrayKey, $tabData) && is_array($tabData[$arrayKey])) {
  168. if (array_key_exists('ship_bundle_items', $tabData[$arrayKey])) {
  169. $array['ship_bundle_items'] = $tabData[$arrayKey]['ship_bundle_items'];
  170. $this->fillForm($array, 'bundle_items');
  171. }
  172. foreach ($tabData[$arrayKey] as $value) {
  173. if (is_array($value)) {
  174. $this->addBundleOption($value);
  175. }
  176. }
  177. }
  178. break;
  179. case 'associated':
  180. $arrayKey = $tabName . '_grouped_data';
  181. $arrayKey1 = $tabName . '_configurable_data';
  182. if (array_key_exists($arrayKey, $tabData) && is_array($tabData[$arrayKey])) {
  183. foreach ($tabData[$arrayKey] as $value) {
  184. $this->assignProduct($value, $tabName);
  185. }
  186. } elseif (array_key_exists($arrayKey1, $tabData) && is_array($tabData[$arrayKey1])) {
  187. $attributeTitle = (isset($productData['configurable_attribute_title']))
  188. ? $productData['configurable_attribute_title']
  189. : null;
  190. if (!$attributeTitle) {
  191. $this->fail('Attribute Title for configurable product is not set');
  192. }
  193. $this->addParameter('attributeTitle', $attributeTitle);
  194. $this->fillForm($tabData[$arrayKey1], $tabName);
  195. foreach ($tabData[$arrayKey1] as $value) {
  196. if (is_array($value)) {
  197. $this->assignProduct($value, $tabName, $attributeTitle);
  198. }
  199. }
  200. }
  201. break;
  202. case 'downloadable_information':
  203. $arrayKey = $tabName . '_data';
  204. if (array_key_exists($arrayKey, $tabData) && is_array($tabData[$arrayKey])) {
  205. foreach ($tabData[$arrayKey] as $key => $value) {
  206. if (preg_match('/^downloadable_sample_/', $key) && is_array($value)) {
  207. $this->addDownloadableOption($value, 'sample');
  208. }
  209. if (preg_match('/^downloadable_link_/', $key) && is_array($value)) {
  210. $this->addDownloadableOption($value, 'link');
  211. }
  212. }
  213. }
  214. $this->fillForm($tabData[$arrayKey], $tabName);
  215. break;
  216. default:
  217. $this->fillForm($tabData, $tabName);
  218. $this->fillUserAttributesOnTab($tabData, $tabName);
  219. break;
  220. }
  221. return true;
  222. }
  223. /**
  224. * Add Tier Price
  225. *
  226. * @param array $tierPriceData
  227. */
  228. public function addTierPrice(array $tierPriceData)
  229. {
  230. $rowNumber = $this->getXpathCount($this->_getControlXpath('fieldset', 'tier_price_row'));
  231. $this->addParameter('tierPriceId', $rowNumber);
  232. $this->clickButton('add_tier_price', false);
  233. $this->fillForm($tierPriceData, 'prices');
  234. }
  235. /**
  236. * Add Custom Option
  237. *
  238. * @param array $customOptionData
  239. */
  240. public function addCustomOption(array $customOptionData)
  241. {
  242. $fieldSetXpath = $this->_getControlXpath('fieldset', 'custom_option_set');
  243. $optionId = $this->getXpathCount($fieldSetXpath) + 1;
  244. $this->addParameter('optionId', $optionId);
  245. $this->clickButton('add_option', false);
  246. $this->fillForm($customOptionData, 'custom_options');
  247. foreach ($customOptionData as $rowKey => $rowValue) {
  248. if (preg_match('/^custom_option_row/', $rowKey) && is_array($rowValue)) {
  249. $rowId = $this->getXpathCount($fieldSetXpath . "//tr[contains(@id,'product_option_')][not(@style)]");
  250. $this->addParameter('rowId', $rowId);
  251. $this->clickButton('add_row', false);
  252. $this->fillForm($rowValue, 'custom_options');
  253. }
  254. }
  255. }
  256. /**
  257. * Select Website by Website name
  258. *
  259. * @param $websiteName
  260. * @param $action
  261. */
  262. public function selectWebsite($websiteName, $action = 'select')
  263. {
  264. $this->addParameter('websiteName', $websiteName);
  265. $websiteXpath = $this->_getControlXpath('checkbox', 'websites');
  266. if ($this->isElementPresent($websiteXpath)) {
  267. if ($this->getValue($websiteXpath) == 'off') {
  268. switch ($action) {
  269. case 'select':
  270. $this->click($websiteXpath);
  271. break;
  272. case 'verify':
  273. $this->addVerificationMessage('Website with name "' . $websiteName . '" is not selected');
  274. break;
  275. }
  276. }
  277. } else {
  278. $this->fail('Website with name "' . $websiteName . '" does not exist');
  279. }
  280. }
  281. /**
  282. * Assign product. Use for fill in 'Related Products', 'Up-sells' or 'Cross-sells' tabs
  283. *
  284. * @param array $data
  285. * @param string $tabName
  286. * @param string $attributeTitle
  287. */
  288. public function assignProduct(array $data, $tabName, $attributeTitle = null)
  289. {
  290. $fillingData = array();
  291. foreach ($data as $key => $value) {
  292. if (!preg_match('/^' . $tabName . '_search_/', $key)) {
  293. $fillingData[$key] = $value;
  294. unset($data[$key]);
  295. }
  296. }
  297. if ($attributeTitle) {
  298. $attributeCode = $this->getAttribute("//a[span[text()='$attributeTitle']]/@name");
  299. $this->addParameter('attributeCode', $attributeCode);
  300. $this->addParameter('attributeTitle', $attributeTitle);
  301. }
  302. $this->searchAndChoose($data, $tabName);
  303. //Fill in additional data
  304. if ($fillingData) {
  305. $xpathTR = $this->formSearchXpath($data);
  306. if ($attributeTitle) {
  307. $xpath = $this->_getControlXpath('fieldset', 'associated') . '//table[@id]';
  308. $number = $this->getColumnIdByName($attributeTitle, $xpath);
  309. $setXpath = $this->_getControlXpath('fieldset', 'associated');
  310. $attributeValue = $this->getText($setXpath . $xpathTR . "//td[$number]");
  311. $this->addParameter('attributeValue', $attributeValue);
  312. } else {
  313. $this->addParameter('productXpath', $xpathTR);
  314. }
  315. $this->fillForm($fillingData, $tabName);
  316. }
  317. }
  318. /**
  319. * Add Bundle Option
  320. *
  321. * @param array $bundleOptionData
  322. */
  323. public function addBundleOption(array $bundleOptionData)
  324. {
  325. $fieldSetXpath = $this->_getControlXpath('fieldset', 'bundle_items');
  326. $optionsCount = $this->getXpathCount($fieldSetXpath . "//div[@class='option-box']");
  327. $this->addParameter('optionId', $optionsCount);
  328. $this->clickButton('add_new_option', false);
  329. $this->fillForm($bundleOptionData, 'bundle_items');
  330. foreach ($bundleOptionData as $value) {
  331. $productSearch = array();
  332. $selectionSettings = array();
  333. if (is_array($value)) {
  334. foreach ($value as $k => $v) {
  335. if ($k == 'bundle_items_search_name' or $k == 'bundle_items_search_sku') {
  336. $this->addParameter('productSku', $v);
  337. }
  338. if (preg_match('/^bundle_items_search_/', $k)) {
  339. $productSearch[$k] = $v;
  340. } elseif ($k == 'bundle_items_qty_to_add') {
  341. $selectionSettings['selection_item_default_qty'] = $v;
  342. } elseif (preg_match('/^selection_item_/', $k)) {
  343. $selectionSettings[$k] = $v;
  344. }
  345. }
  346. if ($productSearch) {
  347. $this->clickButton('add_selection', false);
  348. $this->pleaseWait();
  349. $this->searchAndChoose($productSearch, 'select_product_to_bundle_option');
  350. $this->clickButton('add_selected_products', false);
  351. if ($selectionSettings) {
  352. $this->fillForm($selectionSettings);
  353. }
  354. }
  355. }
  356. }
  357. }
  358. /**
  359. * Add Sample for Downloadable product
  360. *
  361. * @param array $optionData
  362. * @param string $type
  363. */
  364. public function addDownloadableOption(array $optionData, $type)
  365. {
  366. $fieldSet = $this->_getControlXpath('link', 'downloadable_' . $type);
  367. if (!$this->isElementPresent($fieldSet . "/parent::*[normalize-space(@class)='open']")) {
  368. $this->clickControl('link', 'downloadable_' . $type, false);
  369. }
  370. $fieldSetXpath = $this->_getControlXpath('fieldset', 'downloadable_' . $type);
  371. $rowNumber = $this->getXpathCount($fieldSetXpath . "//*[@id='" . $type . "_items_body']/tr");
  372. $this->addParameter('rowId', $rowNumber);
  373. $this->clickButton('downloadable_' . $type . '_add_new_row', false);
  374. $this->fillForm($optionData, 'downloadable_information');
  375. }
  376. /**
  377. * Fill user product attribute
  378. *
  379. * @param array $productData
  380. * @param string $tabName
  381. */
  382. public function fillUserAttributesOnTab(array $productData, $tabName)
  383. {
  384. $userFieldData = $tabName . '_user_attr';
  385. if (array_key_exists($userFieldData, $productData) && is_array($productData[$userFieldData])) {
  386. foreach ($productData[$userFieldData] as $fieldType => $dataArray) {
  387. if (is_array($dataArray)) {
  388. foreach ($dataArray as $fieldKey => $fieldValue) {
  389. $this->addParameter('attributeCode' . ucfirst(strtolower($fieldType)), $fieldKey);
  390. $xpath = $this->_getControlXpath($fieldType, $tabName . '_user_attr_' . $fieldType);
  391. switch ($fieldType) {
  392. case 'dropdown':
  393. $this->select($xpath, $fieldValue);
  394. break;
  395. case 'field':
  396. $this->type($xpath, $fieldValue);
  397. break;
  398. case 'multiselect':
  399. $this->removeAllSelections($xpath);
  400. $values = explode(',', $fieldValue);
  401. $values = array_map('trim', $values);
  402. foreach ($values as $v) {
  403. $this->addSelection($xpath, $v);
  404. }
  405. break;
  406. }
  407. }
  408. }
  409. }
  410. }
  411. }
  412. /**
  413. * Create Product
  414. *
  415. * @param array $productData
  416. * @param string $productType
  417. */
  418. public function createProduct(array $productData, $productType = 'simple')
  419. {
  420. $productData = $this->arrayEmptyClear($productData);
  421. $this->clickButton('add_new_product');
  422. $this->fillProductSettings($productData, $productType);
  423. if ($productType == 'configurable') {
  424. $this->fillConfigurableSettings($productData);
  425. }
  426. $this->fillProductInfo($productData, $productType);
  427. $this->saveForm('save');
  428. }
  429. /**
  430. * Fill Product info
  431. *
  432. * @param array $productData
  433. * @param string $productType
  434. */
  435. public function fillProductInfo(array $productData, $productType = 'simple')
  436. {
  437. $this->fillProductTab($productData);
  438. $this->fillProductTab($productData, 'prices');
  439. $this->fillProductTab($productData, 'meta_information');
  440. //@TODO Fill in Images Tab
  441. if ($productType == 'simple' || $productType == 'virtual') {
  442. $this->fillProductTab($productData, 'recurring_profile');
  443. }
  444. $this->fillProductTab($productData, 'design');
  445. $this->fillProductTab($productData, 'gift_options');
  446. $this->fillProductTab($productData, 'inventory');
  447. $this->fillProductTab($productData, 'websites');
  448. $this->fillProductTab($productData, 'categories');
  449. $this->fillProductTab($productData, 'related');
  450. $this->fillProductTab($productData, 'up_sells');
  451. $this->fillProductTab($productData, 'cross_sells');
  452. $this->fillProductTab($productData, 'custom_options');
  453. if ($productType == 'grouped' || $productType == 'configurable') {
  454. $this->fillProductTab($productData, 'associated');
  455. }
  456. if ($productType == 'bundle') {
  457. $this->fillProductTab($productData, 'bundle_items');
  458. }
  459. if ($productType == 'downloadable') {
  460. $this->fillProductTab($productData, 'downloadable_information');
  461. }
  462. }
  463. /**
  464. * Open product.
  465. *
  466. * @param array $productSearch
  467. */
  468. public function openProduct(array $productSearch)
  469. {
  470. $this->_prepareDataForSearch($productSearch);
  471. $xpathTR = $this->search($productSearch, 'product_grid');
  472. $this->assertNotNull($xpathTR, 'Product is not found');
  473. $cellId = $this->getColumnIdByName('Name');
  474. $this->addParameter('productName', $this->getText($xpathTR . '//td[' . $cellId . ']'));
  475. $this->addParameter('id', $this->defineIdFromTitle($xpathTR));
  476. $this->click($xpathTR . "//a[text()='Edit']");
  477. $this->waitForPageToLoad($this->_browserTimeoutPeriod);
  478. $this->validatePage();
  479. }
  480. /**
  481. * Verify product info
  482. *
  483. * @param array $productData
  484. * @param array $skipElements
  485. */
  486. public function verifyProductInfo(array $productData, $skipElements = array())
  487. {
  488. $productData = $this->arrayEmptyClear($productData);
  489. $nestedArrays = array();
  490. foreach ($productData as $key => $value) {
  491. if (is_array($value)) {
  492. $nestedArrays[$key] = $value;
  493. unset($productData[$key]);
  494. }
  495. if ($key == 'websites' or $key == 'categories') {
  496. $nestedArrays[$key] = $value;
  497. unset($productData[$key]);
  498. }
  499. }
  500. $this->verifyForm($productData, null, $skipElements);
  501. // Verify tier prices
  502. if (array_key_exists('prices_tier_price_data', $nestedArrays)) {
  503. $this->verifyTierPrices($nestedArrays['prices_tier_price_data']);
  504. }
  505. //Verify selected websites
  506. if (array_key_exists('websites', $nestedArrays)) {
  507. $tabXpath = $this->_getControlXpath('tab', 'websites');
  508. if ($this->isElementPresent($tabXpath)) {
  509. $this->openTab('websites');
  510. $websites = explode(',', $nestedArrays['websites']);
  511. $websites = array_map('trim', $websites);
  512. foreach ($websites as $value) {
  513. $this->selectWebsite($value, 'verify');
  514. }
  515. }
  516. }
  517. //Verify selected categories
  518. if (array_key_exists('categories', $nestedArrays)) {
  519. $categories = explode(',', $nestedArrays['categories']);
  520. $categories = array_map('trim', $categories);
  521. $this->openTab('categories');
  522. foreach ($categories as $value) {
  523. $this->isSelectedCategory($value);
  524. }
  525. }
  526. //Verify assigned products for 'Related Products', 'Up-sells', 'Cross-sells' tabs
  527. if (array_key_exists('related_data', $nestedArrays)) {
  528. $this->openTab('related');
  529. foreach ($nestedArrays['related_data'] as $value) {
  530. $this->isAssignedProduct($value, 'related');
  531. }
  532. }
  533. if (array_key_exists('up_sells_data', $nestedArrays)) {
  534. $this->openTab('up_sells');
  535. foreach ($nestedArrays['up_sells_data'] as $value) {
  536. $this->isAssignedProduct($value, 'up_sells');
  537. }
  538. }
  539. if (array_key_exists('cross_sells_data', $nestedArrays)) {
  540. $this->openTab('cross_sells');
  541. foreach ($nestedArrays['cross_sells_data'] as $value) {
  542. $this->isAssignedProduct($value, 'cross_sells');
  543. }
  544. }
  545. // Verify Associated Products tab
  546. if (array_key_exists('associated_grouped_data', $nestedArrays)) {
  547. $this->openTab('associated');
  548. foreach ($nestedArrays['associated_grouped_data'] as $value) {
  549. $this->isAssignedProduct($value, 'associated');
  550. }
  551. }
  552. if (array_key_exists('associated_configurable_data', $nestedArrays)) {
  553. $this->openTab('associated');
  554. $attributeTitle = (isset($productData['configurable_attribute_title']))
  555. ? $productData['configurable_attribute_title']
  556. : null;
  557. if (!$attributeTitle) {
  558. $this->fail('Attribute Title for configurable product is not set');
  559. }
  560. $this->addParameter('attributeTitle', $attributeTitle);
  561. $this->verifyForm($nestedArrays['associated_configurable_data'], 'associated');
  562. foreach ($nestedArrays['associated_configurable_data'] as $value) {
  563. if (is_array($value)) {
  564. $this->isAssignedProduct($value, 'associated', $attributeTitle);
  565. }
  566. }
  567. }
  568. if (array_key_exists('custom_options_data', $nestedArrays)) {
  569. $this->verifyCustomOption($nestedArrays['custom_options_data']);
  570. }
  571. if (array_key_exists('bundle_items_data', $nestedArrays)) {
  572. $this->verifyBundleOptions($nestedArrays['bundle_items_data']);
  573. }
  574. if (array_key_exists('downloadable_information_data', $nestedArrays)) {
  575. $samples = array();
  576. $links = array();
  577. foreach ($nestedArrays['downloadable_information_data'] as $key => $value) {
  578. if (preg_match('/^downloadable_sample_/', $key) && is_array($value)) {
  579. $samples[$key] = $value;
  580. }
  581. if (preg_match('/^downloadable_link_/', $key) && is_array($value)) {
  582. $links[$key] = $value;
  583. }
  584. }
  585. if ($samples) {
  586. $this->verifyDownloadableOptions($samples, 'sample');
  587. }
  588. if ($links) {
  589. $this->verifyDownloadableOptions($links, 'link');
  590. }
  591. $this->verifyForm($nestedArrays['downloadable_information_data'], 'downloadable_information');
  592. }
  593. // Error Output
  594. $this->assertEmptyVerificationErrors();
  595. }
  596. /**
  597. * Verify Tier Prices
  598. *
  599. * @param array $tierPriceData
  600. *
  601. * @return boolean
  602. */
  603. public function verifyTierPrices(array $tierPriceData)
  604. {
  605. $rowQty = $this->getXpathCount($this->_getControlXpath('fieldset', 'tier_price_row'));
  606. $needCount = count($tierPriceData);
  607. if ($needCount != $rowQty) {
  608. $this->addVerificationMessage('Product must be contains ' . $needCount
  609. . 'Tier Price(s), but contains ' . $rowQty);
  610. return false;
  611. }
  612. $i = 0;
  613. foreach ($tierPriceData as $value) {
  614. $this->addParameter('tierPriceId', $i);
  615. $this->verifyForm($value, 'prices');
  616. $i++;
  617. }
  618. return true;
  619. }
  620. /**
  621. * Verify that category is selected
  622. *
  623. * @param string $categoryPath
  624. */
  625. public function isSelectedCategory($categoryPath)
  626. {
  627. $nodes = explode('/', $categoryPath);
  628. $rootCat = array_shift($nodes);
  629. $correctRoot = $this->categoryHelper()->defineCorrectCategory($rootCat);
  630. foreach ($nodes as $value) {
  631. $correctSubCat = array();
  632. for ($i = 0; $i < count($correctRoot); $i++) {
  633. $correctSubCat = array_merge($correctSubCat,
  634. $this->categoryHelper()->defineCorrectCategory($value, $correctRoot[$i]));
  635. }
  636. $correctRoot = $correctSubCat;
  637. }
  638. if ($correctRoot) {
  639. $catXpath = '//*[@id=\'' . array_shift($correctRoot) . '\']/parent::*/input';
  640. if ($this->getValue($catXpath) == 'off') {
  641. $this->addVerificationMessage('Category with path: "' . $categoryPath . '" is not selected');
  642. }
  643. } else {
  644. $this->fail("Category with path='$categoryPath' not found");
  645. }
  646. }
  647. /**
  648. * Verify that product is assigned
  649. *
  650. * @param array $data
  651. * @param string $fieldSetName
  652. * @param string $attributeTitle
  653. */
  654. public function isAssignedProduct(array $data, $fieldSetName, $attributeTitle = null)
  655. {
  656. $fillingData = array();
  657. foreach ($data as $key => $value) {
  658. if (!preg_match('/^' . $fieldSetName . '_search_/', $key)) {
  659. $fillingData[$key] = $value;
  660. unset($data[$key]);
  661. }
  662. }
  663. if ($attributeTitle) {
  664. $attributeCode = $this->getAttribute("//a[span[text()='$attributeTitle']]/@name");
  665. $this->addParameter('attributeCode', $attributeCode);
  666. $this->addParameter('attributeTitle', $attributeTitle);
  667. }
  668. $xpathTR = $this->formSearchXpath($data);
  669. $fieldSetXpath = $this->_getControlXpath('fieldset', $fieldSetName);
  670. if (!$this->isElementPresent($fieldSetXpath . $xpathTR)) {
  671. $this->addVerificationMessage($fieldSetName . " tab: Product is not assigned with data: \n"
  672. . print_r($data, true));
  673. } else {
  674. if ($fillingData) {
  675. if ($attributeTitle) {
  676. $xpath = $this->_getControlXpath('fieldset', 'associated') . '//table[@id]';
  677. $number = $this->getColumnIdByName($attributeTitle, $xpath);
  678. $attributeValue = $this->getText($xpathTR . "//td[$number]");
  679. $this->addParameter('attributeValue', $attributeValue);
  680. } else {
  681. $this->addParameter('productXpath', $xpathTR);
  682. }
  683. $this->verifyForm($fillingData, $fieldSetName);
  684. }
  685. }
  686. }
  687. /**
  688. * Verify Custom Options
  689. *
  690. * @param array $customOptionData
  691. *
  692. * @return boolean
  693. */
  694. public function verifyCustomOption(array $customOptionData)
  695. {
  696. $this->openTab('custom_options');
  697. $fieldSetXpath = $this->_getControlXpath('fieldset', 'custom_option_set');
  698. $optionsQty = $this->getXpathCount($fieldSetXpath);
  699. $needCount = count($customOptionData);
  700. if ($needCount != $optionsQty) {
  701. $this->addVerificationMessage('Product must be contains ' . $needCount
  702. . ' Custom Option(s), but contains ' . $optionsQty);
  703. return false;
  704. }
  705. $id = $this->getAttribute($fieldSetXpath . "[1]/@id");
  706. $id = explode('_', $id);
  707. foreach ($id as $value) {
  708. if (is_numeric($value)) {
  709. $optionId = $value;
  710. }
  711. }
  712. // @TODO Need implement full verification for custom options with type = select (not tested rows)
  713. foreach ($customOptionData as $value) {
  714. if (is_array($value)) {
  715. $this->addParameter('optionId', $optionId);
  716. $this->verifyForm($value, 'custom_options');
  717. $optionId--;
  718. }
  719. }
  720. return true;
  721. }
  722. /**
  723. * verify Bundle Options
  724. *
  725. * @param array $bundleData
  726. *
  727. * @return boolean
  728. */
  729. public function verifyBundleOptions(array $bundleData)
  730. {
  731. $this->openTab('bundle_items');
  732. $fieldSetXpath = $this->_getControlXpath('fieldset', 'bundle_items');
  733. $optionSet = $fieldSetXpath . "//div[@class='option-box']";
  734. $optionsCount = $this->getXpathCount($optionSet);
  735. $needCount = count($bundleData);
  736. if (array_key_exists('ship_bundle_items', $bundleData)) {
  737. $needCount = $needCount - 1;
  738. }
  739. if ($needCount != $optionsCount) {
  740. $this->addVerificationMessage('Product must be contains ' . $needCount
  741. . 'Bundle Item(s), but contains ' . $optionsCount);
  742. return false;
  743. }
  744. $i = 0;
  745. foreach ($bundleData as $option => $values) {
  746. if (is_string($values)) {
  747. $this->verifyForm(array($option => $values), 'bundle_items');
  748. }
  749. if (is_array($values)) {
  750. $this->addParameter('optionId', $i);
  751. $this->verifyForm($values, 'bundle_items');
  752. foreach ($values as $k => $v) {
  753. if (preg_match('/^add_product_/', $k) && is_array($v)) {
  754. $selectionSettings = array();
  755. foreach ($v as $field => $data) {
  756. if ($field == 'bundle_items_search_name' or $field == 'bundle_items_search_sku') {
  757. $productSku = $data;
  758. }
  759. if (!preg_match('/^bundle_items_search/', $field)) {
  760. if ($field == 'bundle_items_qty_to_add') {
  761. $selectionSettings['selection_item_default_qty'] = $data;
  762. } else {
  763. $selectionSettings[$field] = $data;
  764. }
  765. }
  766. }
  767. $k = $i + 1;
  768. if (!$this->isElementPresent($optionSet . "[$k]"
  769. . "//tr[@class='selection' and contains(.,'$productSku')]")
  770. ) {
  771. $this->addVerificationMessage("Product with sku(name)'" . $productSku
  772. . "' is not assigned to bundle item $i");
  773. } else {
  774. if ($selectionSettings) {
  775. $this->addParameter('productSku', $productSku);
  776. $this->verifyForm($selectionSettings, 'bundle_items');
  777. }
  778. }
  779. }
  780. }
  781. $i++;
  782. }
  783. }
  784. return true;
  785. }
  786. /**
  787. * Verify Downloadable Options
  788. *
  789. * @param array $optionsData
  790. * @param string $type
  791. *
  792. * @return bool
  793. */
  794. public function verifyDownloadableOptions(array $optionsData, $type)
  795. {
  796. $fieldSetXpath = $this->_getControlXpath('fieldset', 'downloadable_' . $type);
  797. $rowQty = $this->getXpathCount($fieldSetXpath . "//*[@id='" . $type . "_items_body']/tr");
  798. $needCount = count($optionsData);
  799. if ($needCount != $rowQty) {
  800. $this->addVerificationMessage('Product must be contains ' . $needCount
  801. . ' Downloadable ' . $type . '(s), but contains ' . $rowQty);
  802. return false;
  803. }
  804. $i = 0;
  805. foreach ($optionsData as $value) {
  806. $this->addParameter('rowId', $i);
  807. $this->verifyForm($value, 'downloadable_information');
  808. $i++;
  809. }
  810. return true;
  811. }
  812. /**
  813. * Unselect any associated product(as up_sells, cross_sells, related) to opened product
  814. *
  815. * @param $type
  816. */
  817. public function unselectAssociatedProduct($type)
  818. {
  819. $this->openTab($type);
  820. $message = $this->_getControlXpath('fieldset', $type) . $this->_getMessageXpath('no_records_found');
  821. if (!$this->isElementPresent($message)) {
  822. $this->fillFieldset(array($type . '_select_all'=> 'No'), $type);
  823. $this->saveAndContinueEdit('button', 'save_and_continue_edit');
  824. $this->assertElementPresent($message, 'There are products assigned to "' . $type . '" tab');
  825. }
  826. }
  827. #*******************************************
  828. #* Frontend Helper Methods *
  829. #*******************************************
  830. /**
  831. * Open product on FrontEnd
  832. *
  833. * @param string $productName
  834. * @param $categoryPath
  835. */
  836. public function frontOpenProduct($productName, $categoryPath = null)
  837. {
  838. if (!is_string($productName)) {
  839. $this->fail('Wrong data to open a product');
  840. }
  841. $productUrl = trim(strtolower(preg_replace('#[^0-9a-z]+#i', '-', $productName)), '-');
  842. $this->addParameter('productUrl', $productUrl);
  843. if ($categoryPath) {
  844. $nodes = explode('/', $categoryPath);
  845. if (count($nodes) > 1) {
  846. array_shift($nodes);
  847. }
  848. $nodes = array_reverse($nodes);
  849. $categoryName = '';
  850. foreach ($nodes as $value) {
  851. $categoryName = $categoryName . ' - ' . trim($value);
  852. }
  853. $this->addParameter('productTitle', $productName . $categoryName);
  854. } else {
  855. $this->addParameter('productTitle', $productName);
  856. }
  857. $this->frontend('product_page');
  858. $this->addParameter('productName', $productName);
  859. $openedProductName = $this->getText($this->_getControlXpath('pageelement', 'product_name'));
  860. $this->assertEquals($productName, $openedProductName,
  861. "Product with name '$openedProductName' is opened, but should be '$productName'");
  862. }
  863. /**
  864. * Add product to shopping cart
  865. *
  866. * @param array|null $dataForBuy
  867. */
  868. public function frontAddProductToCart($dataForBuy = null)
  869. {
  870. if ($dataForBuy) {
  871. $this->frontFillBuyInfo($dataForBuy);
  872. }
  873. $xpathName = $this->getCurrentUimapPage()->getMainForm()->findPageelement('product_name');
  874. $openedProductName = $this->getText($xpathName);
  875. $this->addParameter('productName', $openedProductName);
  876. $this->saveForm('add_to_cart');
  877. $this->assertMessageNotPresent('validation');
  878. }
  879. /**
  880. * Choose custom options and additional products
  881. *
  882. * @param array $dataForBuy
  883. */
  884. public function frontFillBuyInfo($dataForBuy)
  885. {
  886. foreach ($dataForBuy as $value) {
  887. $fill = (isset($value['options_to_choose']))
  888. ? $value['options_to_choose']
  889. : array();
  890. $params = (isset($value['parameters']))
  891. ? $value['parameters']
  892. : array();
  893. foreach ($params as $k => $v) {
  894. $this->addParameter($k, $v);
  895. }
  896. $this->fillForm($fill);
  897. }
  898. }
  899. /**
  900. * Verify product info on frontend
  901. *
  902. * @param array $productData
  903. */
  904. public function frontVerifyProductInfo(array $productData)
  905. {
  906. $productData = $this->arrayEmptyClear($productData);
  907. $this->frontOpenProduct($productData['general_name']);
  908. $xpathArray = $this->getCustomOptionsXpathes($productData);
  909. foreach ($xpathArray as $fieldName => $data) {
  910. if (is_string($data)) {
  911. if (!$this->isElementPresent($data)) {
  912. $this->addVerificationMessage('Could not find element ' . $fieldName);
  913. }
  914. } else {
  915. foreach ($data as $optionData) {
  916. foreach ($optionData as $x => $y) {
  917. if (!preg_match('/xpath/', $x)) {
  918. continue;
  919. }
  920. if (!$this->isElementPresent($y)) {
  921. $this->addVerificationMessage('Could not find element type "' . $optionData['type'] .
  922. '" and title "' . $optionData['title'] . '"');
  923. }
  924. }
  925. }
  926. }
  927. }
  928. $this->assertEmptyVerificationErrors();
  929. }
  930. /**
  931. * Gets the xpathes for validation on frontend
  932. *
  933. * @param array $productData
  934. *
  935. * @return array
  936. */
  937. public function getCustomOptionsXpathes(array $productData)
  938. {
  939. $xpathArray = array();
  940. $date = strtotime(date("m/d/Y"));
  941. $startDate = isset($productData['prices_special_price_from'])
  942. ? strtotime($productData['prices_special_price_from'])
  943. : 1;
  944. $expirationDate = isset($productData['prices_special_price_to'])
  945. ? strtotime($productData['prices_special_price_to'])
  946. : 1;
  947. if ($startDate <= $date && $expirationDate >= $date) {
  948. $priceToCalc = $productData['prices_special_price'];
  949. } else {
  950. $priceToCalc = $productData['prices_price'];
  951. }
  952. $avail = (isset($productData['inventory_stock_availability']))
  953. ? $productData['inventory_stock_availability']
  954. : null;
  955. $allowedQty = (isset($productData['inventory_min_allowed_qty']))
  956. ? $productData['inventory_min_allowed_qty']
  957. : null;
  958. $shortDescription = (isset($productData['general_short_description']))
  959. ? $productData['general_short_description']
  960. : null;
  961. $longDescription = (isset($productData['general_description'])) ? $productData['general_description'] : null;
  962. if ($shortDescription) {
  963. $this->addParameter('shortDescription', $shortDescription);
  964. $xpathArray['Short Description'] = $this->_getControlXpath('pageelement', 'short_description');
  965. }
  966. if ($longDescription) {
  967. $this->addParameter('longDescription', $longDescription);
  968. $xpathArray['Description'] = $this->_getControlXpath('pageelement', 'description');
  969. }
  970. $avail = ($avail == 'In Stock') ? 'In stock' : 'Out of stock';
  971. if ($avail == 'Out of stock') {
  972. $this->addParameter('avail', $avail);
  973. $xpathArray['Availability'] = $this->_getControlXpath('pageelement', 'availability_param');
  974. return $xpathArray;
  975. }
  976. $allowedQty = ($allowedQty == null) ? '1' : $allowedQty;
  977. $this->addParameter('price', $allowedQty);
  978. $xpathArray['Quantity'] = $this->_getControlXpath('pageelement', 'qty');
  979. $i = 0;
  980. foreach ($productData['custom_options_data'] as $value) {
  981. $title = $value['custom_options_general_title'];
  982. $optionType = $value['custom_options_general_input_type'];
  983. $xpathArray['custom_options']['option_' . $i]['title'] = $title;
  984. $xpathArray['custom_options']['option_' . $i]['type'] = $optionType;
  985. $this->addParameter('title', $title);
  986. if ($value['custom_options_general_input_type'] == 'Drop-down'
  987. || $value['custom_options_general_input_type'] == 'Multiple Select') {
  988. $someArr = $this->_formXpathForCustomOptionsRows($value, $priceToCalc, $i, 'custom_option_select');
  989. $xpathArray = array_merge_recursive($xpathArray, $someArr);
  990. } elseif ($value['custom_options_general_input_type'] == 'Radio Buttons'
  991. || $value['custom_options_general_input_type'] == 'Checkbox') {
  992. $someArr = $this->_formXpathForCustomOptionsRows($value, $priceToCalc, $i, 'custom_option_check');
  993. $xpathArray = array_merge_recursive($xpathArray, $someArr);
  994. } else {
  995. $someArr = $this->_formXpathesForFieldsArray($value, $i, $priceToCalc);
  996. $xpathArray = array_merge_recursive($xpathArray, $someArr);
  997. }
  998. $i++;
  999. }
  1000. return $xpathArray;
  1001. }
  1002. /**
  1003. * @param array $value
  1004. * @param int $i
  1005. * @param string $priceToCalc
  1006. *
  1007. * @return array
  1008. */
  1009. private function _formXpathesForFieldsArray(array $value, $i, $priceToCalc)
  1010. {
  1011. $xpathArray = array();
  1012. if (array_key_exists('custom_options_price_type', $value)) {
  1013. if ($value['custom_options_price_type'] == 'Fixed' && isset($value['custom_options_price'])) {
  1014. $price = '$' . number_format((float)$value['custom_options_price'], 2);
  1015. $this->addParameter('price', $price);
  1016. $xpath = $this->_getControlXpath('pageelement', 'custom_option_non_select');
  1017. $someArr = $this->_defineXpathForAdditionalOptions($value, $i, $xpath);
  1018. $xpathArray = array_merge_recursive($xpathArray, $someArr);
  1019. } elseif ($value['custom_options_price_type'] == 'Percent' && isset($value['custom_options_price'])) {
  1020. $price = '$' . number_format(round($priceToCalc / 100 * $value['custom_options_price'], 2), 2);
  1021. $this->addParameter('price', $price);
  1022. $xpath = $this->_getControlXpath('pageelement', 'custom_option_non_select');
  1023. $someArr = $this->_defineXpathForAdditionalOptions($value, $i, $xpath);
  1024. $xpathArray = array_merge_recursive($xpathArray, $someArr);
  1025. } else {
  1026. $xpath = $this->_getControlXpath('pageelement', 'custom_option_non_select_wo_price');
  1027. $someArr = $this->_defineXpathForAdditionalOptions($value, $i, $xpath);
  1028. $xpathArray = array_merge_recursive($xpathArray, $someArr);
  1029. }
  1030. }
  1031. return $xpathArray;
  1032. }
  1033. /**
  1034. * @param array $value
  1035. * @param int $i
  1036. * @param string $xpath
  1037. *
  1038. * @return array
  1039. */
  1040. private function _defineXpathForAdditionalOptions(array $value, $i, $xpath)
  1041. {
  1042. $xpathArray = array();
  1043. $count = 0;
  1044. if (array_key_exists('custom_options_max_characters', $value)
  1045. || array_key_exists('custom_options_allowed_file_extension', $value)
  1046. || array_key_exists('custom_options_image_size_x', $value)
  1047. || array_key_exists('custom_options_image_size_y', $value)) {
  1048. if (array_key_exists('custom_options_max_characters', $value)) {
  1049. $this->addParameter('maxChars', $value['custom_options_max_characters']);
  1050. $xpathMax = $this->_getControlXpath('pageelement', 'custom_option_max_chars');
  1051. $xpathArray['custom_options']['option_' . $i]['xpath_' . $count++] = $xpathMax;
  1052. }
  1053. if (array_key_exists('custom_options_allowed_file_extension', $value)) {
  1054. $this->addParameter('fileExt', $value['custom_options_allowed_file_extension']);
  1055. $xpathExt = $this->_getControlXpath('pageelement', 'custom_option_file_ext');
  1056. $xpathArray['custom_options']['option_' . $i]['xpath_' . $count++] = $xpathExt;
  1057. }
  1058. if (array_key_exists('custom_options_image_size_x', $value)) {
  1059. $this->addParameter('fileWidth', $value['custom_options_image_size_x']);
  1060. $xpathExt = $this->_getControlXpath('pageelement', 'custom_option_file_max_width');
  1061. $xpathArray['custom_options']['option_' . $i]['xpath_' . $count++] = $xpathExt;
  1062. }
  1063. if (array_key_exists('custom_options_image_size_y', $value)) {
  1064. $this->addParameter('fileHeight', $value['custom_options_image_size_y']);
  1065. $xpathExt = $this->_getControlXpath('pageelement', 'custom_option_file_max_height');
  1066. $xpathArray['custom_options']['option_' . $i]['xpath_' . $count++] = $xpathExt;
  1067. }
  1068. } else {
  1069. $xpathArray['custom_options']['option_' . $i]['xpath_' . $count++] = $xpath;
  1070. }
  1071. return $xpathArray;
  1072. }
  1073. /**
  1074. * @param array $options
  1075. * @param string $priceToCalc
  1076. * @param int $i
  1077. * @param string $pageelement
  1078. *
  1079. * @return array
  1080. */
  1081. private function _formXpathForCustomOptionsRows(array $options, $priceToCalc, $i, $pageelement)
  1082. {
  1083. $xpathArray = array();
  1084. $count = 0;
  1085. foreach ($options as $k => $v) {
  1086. if (!preg_match('/^custom_option_row_/', $k)) {
  1087. continue;
  1088. }
  1089. $optionTitle = $v['custom_options_title'];
  1090. $this->addParameter('optionTitle', $optionTitle);
  1091. if (array_key_exists('custom_options_price_type', $v)) {
  1092. if ($v['custom_options_price_type'] == 'Fixed' && isset($v['custom_options_price'])) {
  1093. $optionPrice = '$' . number_format((float)$v['custom_options_price'], 2);
  1094. $this->addParameter('optionPrice', $optionPrice);
  1095. $xpathArray['custom_options']['option_' . $i]['xpath_' . $count++] =
  1096. $this->_getControlXpath('pageelement', $pageelement);
  1097. } elseif ($v['custom_options_price_type'] == 'Percent' && isset($v['custom_options_price'])) {
  1098. $optionPrice = '$' . number_format(round
  1099. ($priceToCalc / 100 * $v['custom_options_price'], 2), 2);
  1100. $this->addParameter('optionPrice', $optionPrice);
  1101. $xpathArray['custom_options']['option_' . $i]['xpath_' . $count++] =
  1102. $this->_getControlXpath('pageelement', $pageelement);
  1103. } else {
  1104. $xpathArray['custom_options']['option_' . $i]['xpath_' . $count++] =
  1105. $this->_getControlXpath('pageelement', $pageelement . '_wo_price');
  1106. }
  1107. } else {
  1108. $xpathArray['custom_options']['option_' . $i]['xpath_' . $count++] =
  1109. $this->_getControlXpath('pageelement', $pageelement . '_wo_price');
  1110. }
  1111. }
  1112. return $xpathArray;
  1113. }
  1114. /**
  1115. * Create Configurable product
  1116. *
  1117. * @param bool $inSubCategory
  1118. *
  1119. * @return array
  1120. */
  1121. public function createConfigurableProduct($inSubCategory = false)
  1122. {
  1123. //Create category
  1124. if ($inSubCategory) {
  1125. $category = $this->loadDataSet('Category', 'sub_category_required');
  1126. $catPath = $category['parent_category'] . '/' . $category['name'];
  1127. $this->navigate('manage_categories', false);
  1128. $this->categoryHelper()->checkCategoriesPage();
  1129. $this->categoryHelper()->createCategory($category);
  1130. $this->assertMessagePresent('success', 'success_saved_category');
  1131. $returnCategory = array('name' => $category['name'],
  1132. 'path' => $catPath);
  1133. } else {
  1134. $returnCategory = array('name' => 'Default Category',
  1135. 'path' => 'Default Category');
  1136. }
  1137. //Create …

Large files files are truncated, but you can click here to view the full file