Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit 031257c

Browse files
committed
Merge remote-tracking branch 'mainline/2.3-develop' into MAGETWO-91606
2 parents e370b46 + 0915691 commit 031257c

File tree

103 files changed

+1017
-200
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+1017
-200
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ To learn more about issue gate labels click [here](https://github.com/magento/ma
5858

5959
<h2>Reporting security issues</h2>
6060

61-
To report security vulnerabilities in Magento software or web sites, please e-mail <a href="mailto:[email protected]">[email protected]</a>. Please do not report security issues using GitHub. Be sure to encrypt your e-mail with our <a href="https://info2.magento.com/rs/magentoenterprise/images/security_at_magento.asc">encryption key</a> if it includes sensitive information. Learn more about reporting security issues <a href="https://magento.com/security/reporting-magento-security-issue">here</a>.
61+
To report security vulnerabilities in Magento software or web sites, please create a Bugcrowd researcher account <a href="https://bugcrowd.com/magento">there</a> to submit and follow-up your issue. Learn more about reporting security issues <a href="https://magento.com/security/reporting-magento-security-issue">here</a>.
6262

6363
Stay up-to-date on the latest security news and patches for Magento by signing up for <a href="https://magento.com/security/sign-up">Security Alert Notifications</a>.
6464

app/code/Magento/AdvancedPricingImportExport/Test/Unit/Model/Export/AdvancedPricingTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ protected function setUp()
219219
'_getCustomerGroupById',
220220
'correctExportData'
221221
]);
222-
$this->advancedPricing = $this->getMockbuilder(
222+
$this->advancedPricing = $this->getMockBuilder(
223223
\Magento\AdvancedPricingImportExport\Model\Export\AdvancedPricing::class
224224
)
225225
->setMethods($mockMethods)

app/code/Magento/Analytics/Test/Unit/Block/Adminhtml/System/Config/AdditionalCommentTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,11 @@ public function testRender()
6565
->method('getLabel')
6666
->willReturn('Comment label');
6767
$html = $this->additionalComment->render($this->abstractElementMock);
68-
$this->assertRegexp(
68+
$this->assertRegExp(
6969
"/New comment/",
7070
$html
7171
);
72-
$this->assertRegexp(
72+
$this->assertRegExp(
7373
"/Comment label/",
7474
$html
7575
);

app/code/Magento/Analytics/Test/Unit/Block/Adminhtml/System/Config/CollectionTimeLabelTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public function testRender()
8787
$this->localeResolver->expects($this->once())
8888
->method('getLocale')
8989
->willReturn('en_US');
90-
$this->assertRegexp(
90+
$this->assertRegExp(
9191
"/Eastern Standard Time \(America\/New_York\)/",
9292
$this->collectionTimeLabel->render($this->abstractElementMock)
9393
);

app/code/Magento/Analytics/Test/Unit/Block/Adminhtml/System/Config/SubscriptionStatusLabelTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public function testRender()
7474
$this->abstractElementMock->expects($this->any())
7575
->method('getComment')
7676
->willReturn('Subscription status: Enabled');
77-
$this->assertRegexp(
77+
$this->assertRegExp(
7878
"/Subscription status: Enabled/",
7979
$this->subscriptionStatusLabel->render($this->abstractElementMock)
8080
);

app/code/Magento/Analytics/Test/Unit/Block/Adminhtml/System/Config/VerticalTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public function testRender()
6565
->method('getHint')
6666
->willReturn('New hint');
6767
$html = $this->vertical->render($this->abstractElementMock);
68-
$this->assertRegexp(
68+
$this->assertRegExp(
6969
"/New comment/",
7070
$html
7171
);

app/code/Magento/Backend/Block/Widget/Grid/Column/Filter/Datetime.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ public function getValue($index = null)
2626
{
2727
if ($index) {
2828
if ($data = $this->getData('value', 'orig_' . $index)) {
29-
// date('Y-m-d', strtotime($data));
3029
return $data;
3130
}
3231
return null;

app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,13 +277,13 @@ public function getGridIdsJson()
277277
}
278278
/** @var \Magento\Framework\Data\Collection $allIdsCollection */
279279
$allIdsCollection = clone $this->getParentBlock()->getCollection();
280-
280+
281281
if ($this->getMassactionIdField()) {
282282
$massActionIdField = $this->getMassactionIdField();
283283
} else {
284284
$massActionIdField = $this->getParentBlock()->getMassactionIdField();
285285
}
286-
286+
287287
$gridIds = $allIdsCollection->setPageSize(0)->getColumnValues($massActionIdField);
288288
if (!empty($gridIds)) {
289289
return join(",", $gridIds);

app/code/Magento/Backend/Block/Widget/Grid/Massaction/Extended.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,13 +274,13 @@ public function getGridIdsJson()
274274

275275
/** @var \Magento\Framework\Data\Collection $allIdsCollection */
276276
$allIdsCollection = clone $this->getParentBlock()->getCollection();
277-
277+
278278
if ($this->getMassactionIdField()) {
279279
$massActionIdField = $this->getMassactionIdField();
280280
} else {
281281
$massActionIdField = $this->getParentBlock()->getMassactionIdField();
282282
}
283-
283+
284284
$gridIds = $allIdsCollection->setPageSize(0)->getColumnValues($massActionIdField);
285285

286286
if (!empty($gridIds)) {

app/code/Magento/Backend/view/adminhtml/ui_component/design_config_form.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
</select>
9393
</formElements>
9494
</field>
95-
<actionDelete template="Magento_Backend/dynamic-rows/cells/action-delete" sortOrder="50">
95+
<actionDelete template="Magento_Backend/dynamic-rows/cells/action-delete">
9696
<argument name="data" xsi:type="array">
9797
<item name="config" xsi:type="array">
9898
<item name="fit" xsi:type="boolean">false</item>

app/code/Magento/Braintree/Gateway/Response/CardDetailsHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public function handle(array $handlingSubject, array $response)
8585
private function getCreditCardType($type)
8686
{
8787
$replaced = str_replace(' ', '-', strtolower($type));
88-
$mapper = $this->config->getCctypesMapper();
88+
$mapper = $this->config->getCcTypesMapper();
8989

9090
return $mapper[$replaced];
9191
}

app/code/Magento/Braintree/Gateway/Response/VaultDetailsHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ private function convertDetailsToJSON($details)
157157
private function getCreditCardType($type)
158158
{
159159
$replaced = str_replace(' ', '-', strtolower($type));
160-
$mapper = $this->config->getCctypesMapper();
160+
$mapper = $this->config->getCcTypesMapper();
161161

162162
return $mapper[$replaced];
163163
}

app/code/Magento/Braintree/Model/Ui/ConfigProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public function getConfig()
7070
self::CODE => [
7171
'isActive' => $this->config->isActive($storeId),
7272
'clientToken' => $this->getClientToken(),
73-
'ccTypesMapper' => $this->config->getCctypesMapper(),
73+
'ccTypesMapper' => $this->config->getCcTypesMapper(),
7474
'sdkUrl' => $this->config->getSdkUrl(),
7575
'countrySpecificCardTypes' => $this->config->getCountrySpecificCardTypeConfig($storeId),
7676
'availableCardTypes' => $this->config->getAvailableCardTypes($storeId),

app/code/Magento/Braintree/Test/Unit/Gateway/Config/ConfigTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public function testGetCcTypesMapper($value, $expected)
142142

143143
static::assertEquals(
144144
$expected,
145-
$this->model->getCctypesMapper()
145+
$this->model->getCcTypesMapper()
146146
);
147147
}
148148

app/code/Magento/Catalog/Model/Product/Option.php

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
use Magento\Catalog\Api\Data\ProductCustomOptionInterface;
1010
use Magento\Catalog\Api\Data\ProductCustomOptionValuesInterface;
11+
use Magento\Catalog\Api\Data\ProductCustomOptionValuesInterfaceFactory;
1112
use Magento\Catalog\Api\Data\ProductInterface;
1213
use Magento\Catalog\Model\Product;
1314
use Magento\Catalog\Model\ResourceModel\Product\Option\Value\Collection;
@@ -102,6 +103,11 @@ class Option extends AbstractExtensibleModel implements ProductCustomOptionInter
102103
*/
103104
private $metadataPool;
104105

106+
/**
107+
* @var ProductCustomOptionValuesInterfaceFactory
108+
*/
109+
private $customOptionValuesFactory;
110+
105111
/**
106112
* @param \Magento\Framework\Model\Context $context
107113
* @param \Magento\Framework\Registry $registry
@@ -114,6 +120,7 @@ class Option extends AbstractExtensibleModel implements ProductCustomOptionInter
114120
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
115121
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
116122
* @param array $data
123+
* @param ProductCustomOptionValuesInterfaceFactory|null $customOptionValuesFactory
117124
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
118125
*/
119126
public function __construct(
@@ -127,12 +134,16 @@ public function __construct(
127134
Option\Validator\Pool $validatorPool,
128135
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
129136
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
130-
array $data = []
137+
array $data = [],
138+
ProductCustomOptionValuesInterfaceFactory $customOptionValuesFactory = null
131139
) {
132140
$this->productOptionValue = $productOptionValue;
133141
$this->optionTypeFactory = $optionFactory;
134142
$this->validatorPool = $validatorPool;
135143
$this->string = $string;
144+
$this->customOptionValuesFactory = $customOptionValuesFactory ?:
145+
\Magento\Framework\App\ObjectManager::getInstance()->get(ProductCustomOptionValuesInterfaceFactory::class);
146+
136147
parent::__construct(
137148
$context,
138149
$registry,
@@ -390,20 +401,21 @@ public function beforeSave()
390401
*/
391402
public function afterSave()
392403
{
393-
$this->getValueInstance()->unsetValues();
394404
$values = $this->getValues() ?: $this->getData('values');
395405
if (is_array($values)) {
396406
foreach ($values as $value) {
397-
if ($value instanceof \Magento\Catalog\Api\Data\ProductCustomOptionValuesInterface) {
407+
if ($value instanceof ProductCustomOptionValuesInterface) {
398408
$data = $value->getData();
399409
} else {
400410
$data = $value;
401411
}
402-
$this->getValueInstance()->addValue($data);
403-
}
404412

405-
$this->getValueInstance()->setOption($this)->saveValues();
406-
} elseif ($this->getGroupByType($this->getType()) == self::OPTION_GROUP_SELECT) {
413+
$this->customOptionValuesFactory->create()
414+
->addValue($data)
415+
->setOption($this)
416+
->saveValues();
417+
}
418+
} elseif ($this->getGroupByType($this->getType()) === self::OPTION_GROUP_SELECT) {
407419
throw new LocalizedException(__('Select type options required values rows.'));
408420
}
409421

@@ -804,7 +816,7 @@ public function setImageSizeY($imageSizeY)
804816
}
805817

806818
/**
807-
* @param \Magento\Catalog\Api\Data\ProductCustomOptionValuesInterface[] $values
819+
* @param ProductCustomOptionValuesInterface[] $values
808820
* @return $this
809821
*/
810822
public function setValues(array $values = null)

app/code/Magento/Catalog/Model/Product/Option/Type/Text.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public function validateUserValue($values)
8484
*/
8585
public function prepareForCart()
8686
{
87-
if ($this->getIsValid() && strlen($this->getUserValue()) > 0) {
87+
if ($this->getIsValid() && ($this->getUserValue() !== '')) {
8888
return $this->getUserValue();
8989
} else {
9090
return null;

app/code/Magento/Catalog/Model/Product/Option/Value.php

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class Value extends AbstractModel implements \Magento\Catalog\Api\Data\ProductCu
7676
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
7777
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
7878
* @param array $data
79+
* @param CustomOptionPriceCalculator|null $customOptionPriceCalculator
7980
*/
8081
public function __construct(
8182
\Magento\Framework\Model\Context $context,
@@ -89,6 +90,7 @@ public function __construct(
8990
$this->_valueCollectionFactory = $valueCollectionFactory;
9091
$this->customOptionPriceCalculator = $customOptionPriceCalculator
9192
?? \Magento\Framework\App\ObjectManager::getInstance()->get(CustomOptionPriceCalculator::class);
93+
9294
parent::__construct(
9395
$context,
9496
$registry,
@@ -201,19 +203,15 @@ public function getProduct()
201203
*/
202204
public function saveValues()
203205
{
206+
$option = $this->getOption();
207+
204208
foreach ($this->getValues() as $value) {
205209
$this->isDeleted(false);
206-
$this->setData(
207-
$value
208-
)->setData(
209-
'option_id',
210-
$this->getOption()->getId()
211-
)->setData(
212-
'store_id',
213-
$this->getOption()->getStoreId()
214-
);
215-
216-
if ($this->getData('is_delete') == '1') {
210+
$this->setData($value)
211+
->setData('option_id', $option->getId())
212+
->setData('store_id', $option->getStoreId());
213+
214+
if ((bool) $this->getData('is_delete') === true) {
217215
if ($this->getId()) {
218216
$this->deleteValues($this->getId());
219217
$this->delete();
@@ -222,7 +220,7 @@ public function saveValues()
222220
$this->save();
223221
}
224222
}
225-
//eof foreach()
223+
226224
return $this;
227225
}
228226

app/code/Magento/Catalog/Pricing/Price/ConfiguredRegularPrice.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public function setItem(ItemInterface $item) : ConfiguredRegularPrice
6363

6464
return $this;
6565
}
66-
66+
6767
/**
6868
* Price value of product with configured options.
6969
*
@@ -73,7 +73,7 @@ public function getValue()
7373
{
7474
$basePrice = parent::getValue();
7575

76-
return $this->item
76+
return $this->item && $basePrice !== false
7777
? $basePrice + $this->configuredOptions->getItemOptionsValue($basePrice, $this->item)
7878
: $basePrice;
7979
}

app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@
157157
<click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="openSeoSection"/>
158158
<fillField userInput="{{simpleProduct.urlKey}}" selector="{{AdminProductSEOSection.urlKeyInput}}" stepKey="fillUrlKey"/>
159159

160-
<click selector="{{AdminProductCustomizableOptionsSection.customezableOptions}}" stepKey="openCustomOptionsSection"/>
160+
<click selector="{{AdminProductCustomizableOptionsSection.customizableOptions}}" stepKey="openCustomOptionsSection"/>
161161
<click selector="{{AdminProductCustomizableOptionsSection.addOptionBtn}}" stepKey="clickAddOption"/>
162162
<fillField userInput="option1" selector="{{AdminProductCustomizableOptionsSection.optionTitleInput}}" stepKey="fillOptionTitle"/>
163163
<click selector="{{AdminProductCustomizableOptionsSection.optionTypeOpenDropDown}}" stepKey="openTypeDropDown"/>

app/code/Magento/Catalog/Test/Mftf/ActionGroup/CustomOptionsActionGroup.xml

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,8 @@
66
*/
77
-->
88

9-
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10-
xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd">
11-
12-
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd">
1310
<actionGroup name="CreateCustomRadioOptions">
14-
1511
<!-- ActionGroup will add a single custom option to a product -->
1612
<!-- You must already be on the product creation page -->
1713
<arguments>
@@ -39,8 +35,23 @@
3935

4036
<fillField stepKey="fillInValueTitle2" selector="{{AdminProductCustomizableOptionsSection.valueTitle}}" userInput="{{productOption2.title}}"/>
4137
<fillField stepKey="fillInValuePrice2" selector="{{AdminProductCustomizableOptionsSection.valuePrice}}" userInput="{{productOption2.price}}"/>
38+
</actionGroup>
4239

43-
40+
<!--Add a custom option of type "file" to a product-->
41+
<actionGroup name="AddProductCustomOptionFile">
42+
<arguments>
43+
<argument name="option" defaultValue="ProductOptionFile"/>
44+
</arguments>
45+
<conditionalClick selector="{{AdminProductCustomizableOptionsSection.customizableOptions}}" dependentSelector="{{AdminProductCustomizableOptionsSection.addOptionBtn}}" visible="false" stepKey="openCustomOptionSection"/>
46+
<click selector="{{AdminProductCustomizableOptionsSection.addOptionBtn}}" stepKey="clickAddOption"/>
47+
<waitForElementVisible selector="{{AdminProductCustomizableOptionsSection.lastOptionTitle}}" stepKey="waitForOption"/>
48+
<fillField selector="{{AdminProductCustomizableOptionsSection.lastOptionTitle}}" userInput="{{option.title}}" stepKey="fillTitle"/>
49+
<click selector="{{AdminProductCustomizableOptionsSection.lastOptionTypeParent}}" stepKey="openTypeSelect"/>
50+
<click selector="{{AdminProductCustomizableOptionsSection.optionType('File')}}" stepKey="selectTypeFile"/>
51+
<waitForElementVisible selector="{{AdminProductCustomizableOptionsSection.optionPrice}}" stepKey="waitForElements"/>
52+
<fillField selector="{{AdminProductCustomizableOptionsSection.optionPrice}}" userInput="{{option.price}}" stepKey="fillPrice"/>
53+
<selectOption selector="{{AdminProductCustomizableOptionsSection.optionPriceType}}" userInput="{{option.price_type}}" stepKey="selectPriceType"/>
54+
<fillField selector="{{AdminProductCustomizableOptionsSection.optionFileExtensions}}" userInput="{{option.file_extension}}" stepKey="fillCompatibleExtensions"/>
4455
</actionGroup>
4556

4657
</actionGroups>

app/code/Magento/Catalog/Test/Mftf/Section/AdminProductCustomizableOptionsSection.xml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd">
1111
<section name="AdminProductCustomizableOptionsSection">
1212
<element name="checkIfCustomizableOptionsTabOpen" type="text" selector="//span[text()='Customizable Options']/parent::strong/parent::*[@data-state-collapsible='closed']"/>
13-
<element name="customezableOptions" type="text" selector="//strong[contains(@class, 'admin__collapsible-title')]/span[text()='Customizable Options']"/>
13+
<element name="customizableOptions" type="text" selector="//strong[contains(@class, 'admin__collapsible-title')]/span[text()='Customizable Options']"/>
1414
<element name="useDefaultOptionTitle" type="text" selector="[data-index='options'] tr.data-row [data-index='title'] [name^='options_use_default']"/>
1515
<element name="useDefaultOptionTitleByIndex" type="text" selector="[data-index='options'] [data-index='values'] tr[data-repeat-index='{{var1}}'] [name^='options_use_default']" parameterized="true"/>
1616
<element name="addOptionBtn" type="button" selector="button[data-index='button_add']"/>
@@ -20,7 +20,6 @@
2020
<element name="optionTypeTextField" type="button" selector=".admin__dynamic-rows[data-index='options'] .action-menu._active li li"/>
2121
<element name="maxCharactersInput" type="input" selector="input[name='product[options][0][max_characters]']"/>
2222

23-
2423
<element name="checkSelect" type="select" selector="//span[text()='{{var1}}']/parent::div/parent::div/parent::div//span[text()='Option Type']/parent::label/parent::div//div[@data-role='selected-option']" parameterized="true"/>
2524
<element name="checkDropDown" type="select" selector="//span[text()='{{var1}}']/parent::div/parent::div/parent::div//parent::label/parent::div//li[@class='admin__action-multiselect-menu-inner-item']//label[text()='Drop-down']" parameterized="true"/>
2625
<element name="clickAddValue" type="button" selector="//span[text()='{{var1}}']/parent::div/parent::div/parent::div//tfoot//button" parameterized="true"/>
@@ -38,5 +37,10 @@
3837
<element name="addValue" type="button" selector="//*[@data-index='custom_options']//*[@data-index='options']/tbody/tr[last()]//*[@data-action='add_new_row']" />
3938
<element name="valueTitle" type="input" selector="//*[@data-index='custom_options']//*[@data-index='options']/tbody/tr[last()]//*[contains(@class, 'admin__control-table')]//tbody/tr[last()]//*[@data-index='title']//input" />
4039
<element name="valuePrice" type="input" selector="//*[@data-index='custom_options']//*[@data-index='options']/tbody/tr[last()]//*[contains(@class, 'admin__control-table')]//tbody/tr[last()]//*[@data-index='price']//input" />
40+
41+
<element name="optionPrice" type="input" selector="//*[@data-index='custom_options']//*[@data-index='options']/tbody/tr[last()]//*[@name='product[options][0][price]']"/>
42+
<element name="optionPriceType" type="select" selector="//*[@data-index='custom_options']//*[@data-index='options']/tbody/tr[last()]//*[@name='product[options][0][price_type]']"/>
43+
<element name="optionSku" type="input" selector="//*[@data-index='custom_options']//*[@data-index='options']/tbody/tr[last()]//*[@name='product[options][0][sku]']"/>
44+
<element name="optionFileExtensions" type="input" selector="//*[@data-index='custom_options']//*[@data-index='options']/tbody/tr[last()]//*[@name='product[options][0][file_extension]']"/>
4145
</section>
4246
</sections>

0 commit comments

Comments
 (0)