Skip to content

Commit d2e6c55

Browse files
committed
Merge remote-tracking branch 'origin/MFTF3.0.0-RC2' into MQE-2077
# Conflicts: # etc/di.xml
2 parents 44fad37 + e9b96a3 commit d2e6c55

File tree

16 files changed

+283
-22
lines changed

16 files changed

+283
-22
lines changed

dev/tests/functional/standalone_bootstrap.php

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@
5353
defined('WAIT_TIMEOUT') || define('WAIT_TIMEOUT', 30);
5454
$env->setEnvironmentVariable('WAIT_TIMEOUT', WAIT_TIMEOUT);
5555

56+
defined('VERBOSE_ARTIFACTS') || define('VERBOSE_ARTIFACTS', false);
57+
$env->setEnvironmentVariable('VERBOSE_ARTIFACTS', VERBOSE_ARTIFACTS);
58+
5659
try {
5760
new DateTimeZone(DEFAULT_TIMEZONE);
5861
} catch (\Exception $e) {

dev/tests/phpunit.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
<phpunit
99
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10-
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd"
10+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.1/phpunit.xsd"
1111
convertNoticesToExceptions="false"
1212
bootstrap="_bootstrap.php"
1313
backupGlobals="false">

dev/tests/unit/Magento/FunctionalTestFramework/Util/Sorter/ParallelGroupSorterTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ public function testSortWithSuites()
101101
$this->assertCount(5, $actualResult);
102102

103103
$expectedResults = [
104-
1 => ['mockSuite1_0'],
105-
2 => ['mockSuite1_1'],
104+
1 => ['mockSuite1_0_G'],
105+
2 => ['mockSuite1_1_G'],
106106
3 => ['test3'],
107107
4 => ['test2','test5', 'test4'],
108108
5 => ['test1'],

dev/tests/verification/Resources/AssertTest.txt

+8-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class AssertTestCest
6565
$I->assertStringNotContainsStringIgnoringCase("apple", "banana", "pass"); // stepKey: assertStringNotContainsStringIgnoringCase
6666
$I->assertNotEmpty([1, 2], "pass"); // stepKey: assertNotEmpty1
6767
$I->assertNotEmpty($text, "pass"); // stepKey: assertNotEmpty2
68-
$I->assertNotEquals(2, 5, "pass", 0); // stepKey: assertNotEquals
68+
$I->assertNotEquals(2, 5, "pass"); // stepKey: assertNotEquals
6969
$I->assertNotNull("abc", "pass"); // stepKey: assertNotNull1
7070
$I->assertNotNull($text, "pass"); // stepKey: assertNotNull2
7171
$I->assertNotRegExp("/foo/", "bar", "pass"); // stepKey: assertNotRegExp
@@ -97,7 +97,7 @@ class AssertTestCest
9797
$I->assertNotContains("bc", $text, "pass"); // stepKey: assertNotContains2BackwardCompatible
9898
$I->assertNotEmpty([1, 2], "pass"); // stepKey: assertNotEmpty1BackwardCompatible
9999
$I->assertNotEmpty($text, "pass"); // stepKey: assertNotEmpty2BackwardCompatible
100-
$I->assertNotEquals(2, 5, "pass", 0); // stepKey: assertNotEqualsBackwardCompatible
100+
$I->assertNotEquals(2, 5, "pass"); // stepKey: assertNotEqualsBackwardCompatible
101101
$I->assertNotNull("abc", "pass"); // stepKey: assertNotNull1BackwardCompatible
102102
$I->assertNotNull($text, "pass"); // stepKey: assertNotNull2BackwardCompatible
103103
$I->assertNotRegExp("/foo/", "bar", "pass"); // stepKey: assertNotRegExpBackwardCompatible
@@ -145,5 +145,11 @@ class AssertTestCest
145145
$I->assertElementContainsAttribute("#username", "value", $I->retrieveEntityField('createData1', 'firstname', 'test')); // stepKey: assertElementContainsAttribute8
146146
$I->comment("assert entity resolution");
147147
$I->assertEquals("John", "Doe", "pass"); // stepKey: assertEqualsEntity
148+
$I->assertEqualsWithDelta(10.0000, 10.0000, 1, "pass"); // stepKey: a1
149+
$I->assertNotEqualsWithDelta(10.0000, 12.0000, 1, "pass"); // stepKey: a2
150+
$I->assertEqualsCanonicalizing(["4", "2", "1", "3"], ["1", "2", "3", "4"], "pass"); // stepKey: a3
151+
$I->assertNotEqualsCanonicalizing(["5", "8", "7", "9"], ["1", "2", "3", "4"], "pass"); // stepKey: a4
152+
$I->assertEqualsIgnoringCase("Cat", "cat", "pass"); // stepKey: a5
153+
$I->assertNotEqualsIgnoringCase("Cat", "Dog", "pass"); // stepKey: a6
148154
}
149155
}

dev/tests/verification/TestModule/Test/AssertTest.xml

+27-2
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
<assertNotEmpty stepKey="assertNotEmpty2" message="pass">
114114
<actualResult type="variable">text</actualResult>
115115
</assertNotEmpty>
116-
<assertNotEquals stepKey="assertNotEquals" message="pass" delta="">
116+
<assertNotEquals stepKey="assertNotEquals" message="pass">
117117
<expectedResult type="int">2</expectedResult>
118118
<actualResult type="int">5</actualResult>
119119
</assertNotEquals>
@@ -227,7 +227,7 @@
227227
<assertNotEmpty stepKey="assertNotEmpty2BackwardCompatible" message="pass">
228228
<actualResult type="variable">text</actualResult>
229229
</assertNotEmpty>
230-
<assertNotEquals stepKey="assertNotEqualsBackwardCompatible" message="pass" delta="">
230+
<assertNotEquals stepKey="assertNotEqualsBackwardCompatible" message="pass">
231231
<actualResult type="int">5</actualResult>
232232
<expectedResult type="int">2</expectedResult>
233233
</assertNotEquals>
@@ -375,5 +375,30 @@
375375
<expectedResult type="string">{{simpleData.firstname}}</expectedResult>
376376
<actualResult type="string">{{simpleData.lastname}}</actualResult>
377377
</assertEquals>
378+
379+
<assertEqualsWithDelta stepKey="a1" message="pass" delta="1">
380+
<expectedResult type="const">10.0000</expectedResult>
381+
<actualResult type="const">10.0000</actualResult>
382+
</assertEqualsWithDelta>
383+
<assertNotEqualsWithDelta stepKey="a2" message="pass" delta="1">
384+
<expectedResult type="const">10.0000</expectedResult>
385+
<actualResult type="const">12.0000</actualResult>
386+
</assertNotEqualsWithDelta>
387+
<assertEqualsCanonicalizing stepKey="a3" message="pass">
388+
<expectedResult type="array">[4, 2, 1, 3]</expectedResult>
389+
<actualResult type="array">[1, 2, 3, 4]</actualResult>
390+
</assertEqualsCanonicalizing>
391+
<assertNotEqualsCanonicalizing stepKey="a4" message="pass">
392+
<expectedResult type="array">[5, 8, 7, 9]</expectedResult>
393+
<actualResult type="array">[1, 2, 3, 4]</actualResult>
394+
</assertNotEqualsCanonicalizing>
395+
<assertEqualsIgnoringCase stepKey="a5" message="pass">
396+
<expectedResult type="string">Cat</expectedResult>
397+
<actualResult type="string">cat</actualResult>
398+
</assertEqualsIgnoringCase>
399+
<assertNotEqualsIgnoringCase stepKey="a6" message="pass">
400+
<expectedResult type="string">Cat</expectedResult>
401+
<actualResult type="string">Dog</actualResult>
402+
</assertNotEqualsIgnoringCase>
378403
</test>
379404
</tests>

dev/tests/verification/Tests/SuiteGenerationTest.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,10 @@ public function testSuiteGenerationParallel()
118118
$groupName = 'functionalSuite1';
119119

120120
$expectedGroups = [
121-
'functionalSuite1_0',
122-
'functionalSuite1_1',
123-
'functionalSuite1_2',
124-
'functionalSuite1_3'
121+
'functionalSuite1_0_G',
122+
'functionalSuite1_1_G',
123+
'functionalSuite1_2_G',
124+
'functionalSuite1_3_G'
125125
];
126126

127127
$expectedContents = [

docs/configuration.md

+14
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,20 @@ Example:
299299
CREDENTIAL_AWS_SECRETS_MANAGER_PROFILE=default
300300
```
301301

302+
### VERBOSE_ARTIFACTS
303+
304+
Determines if passed tests should still have all their Allure artifacts. These artifacts include `.txt` attachments for `dontSee` actions and `createData` actions.
305+
306+
If enabled, all tests will have all of their normal Allure artifacts.
307+
308+
If disabled, passed tests will have their Allure artifacts trimmed. Failed tests will still contain all their artifacts.
309+
310+
This is set `false` by default.
311+
312+
```conf
313+
VERBOSE_ARTIFACTS=true
314+
```
315+
302316
### ENABLE_BROWSER_LOG
303317

304318
Enables addition of browser logs to Allure steps

docs/test/assertions.md

+66
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,17 @@ Attribute|Type|Use|Description
167167

168168
See [assertEquals docs on codeception.com](http://codeception.com/docs/modules/Asserts#assertEquals).
169169

170+
Attribute|Type|Use|Description
171+
---|---|---|---
172+
`message`|string|optional|Text of informational message about a cause of failure.
173+
`stepKey`|string|required| A unique identifier of the text step.
174+
`before`|string|optional| `stepKey` of action that must be executed next.
175+
`after`|string|optional| `stepKey` of the preceding action.
176+
177+
### assertEqualsWithDelta
178+
179+
See [assertEqualsWithDelta docs on codeception.com](http://codeception.com/docs/modules/Asserts#assertEqualsWithDelta).
180+
170181
Attribute|Type|Use|Description
171182
---|---|---|---
172183
`delta`|string|optional|
@@ -175,6 +186,28 @@ Attribute|Type|Use|Description
175186
`before`|string|optional| `stepKey` of action that must be executed next.
176187
`after`|string|optional| `stepKey` of the preceding action.
177188

189+
### assertEqualsCanonicalizing
190+
191+
See [assertEqualsCanonicalizing docs on codeception.com](http://codeception.com/docs/modules/Asserts#assertEqualsCanonicalizing).
192+
193+
Attribute|Type|Use|Description
194+
---|---|---|---
195+
`message`|string|optional|Text of informational message about a cause of failure.
196+
`stepKey`|string|required| A unique identifier of the text step.
197+
`before`|string|optional| `stepKey` of action that must be executed next.
198+
`after`|string|optional| `stepKey` of the preceding action.
199+
200+
### assertEqualsIgnoringCase
201+
202+
See [assertEqualsIgnoringCase docs on codeception.com](http://codeception.com/docs/modules/Asserts#assertEqualsIgnoringCase).
203+
204+
Attribute|Type|Use|Description
205+
---|---|---|---
206+
`message`|string|optional|Text of informational message about a cause of failure.
207+
`stepKey`|string|required| A unique identifier of the text step.
208+
`before`|string|optional| `stepKey` of action that must be executed next.
209+
`after`|string|optional| `stepKey` of the preceding action.
210+
178211
### assertFalse
179212

180213
See [assertFalse docs on codeception.com](http://codeception.com/docs/modules/Asserts#assertFalse).
@@ -344,6 +377,17 @@ Attribute|Type|Use|Description
344377

345378
See [assertNotEquals docs on codeception.com](http://codeception.com/docs/modules/Asserts#assertNotEquals).
346379

380+
Attribute|Type|Use|Description
381+
---|---|---|---
382+
`message`|string|optional|Text of informational message about a cause of failure.
383+
`stepKey`|string|required| A unique identifier of the text step.
384+
`before`|string|optional| `stepKey` of action that must be executed next.
385+
`after`|string|optional| `stepKey` of the preceding action.
386+
387+
### assertNotEqualsWithDelta
388+
389+
See [assertNotEqualsWithDelta docs on codeception.com](http://codeception.com/docs/modules/Asserts#assertNotEqualsWithDelta).
390+
347391
Attribute|Type|Use|Description
348392
---|---|---|---
349393
`delta`|string|optional|
@@ -352,6 +396,28 @@ Attribute|Type|Use|Description
352396
`before`|string|optional| `stepKey` of action that must be executed next.
353397
`after`|string|optional| `stepKey` of the preceding action.
354398

399+
### assertNotEqualsCanonicalizing
400+
401+
See [assertNotEqualsCanonicalizing docs on codeception.com](http://codeception.com/docs/modules/Asserts#assertNotEqualsCanonicalizing).
402+
403+
Attribute|Type|Use|Description
404+
---|---|---|---
405+
`message`|string|optional|Text of informational message about a cause of failure.
406+
`stepKey`|string|required| A unique identifier of the text step.
407+
`before`|string|optional| `stepKey` of action that must be executed next.
408+
`after`|string|optional| `stepKey` of the preceding action.
409+
410+
### assertNotEqualsIgnoringCase
411+
412+
See [assertNotEqualsIgnoringCase docs on codeception.com](http://codeception.com/docs/modules/Asserts#assertNotEqualsIgnoringCase).
413+
414+
Attribute|Type|Use|Description
415+
---|---|---|---
416+
`message`|string|optional|Text of informational message about a cause of failure.
417+
`stepKey`|string|required| A unique identifier of the text step.
418+
`before`|string|optional| `stepKey` of action that must be executed next.
419+
`after`|string|optional| `stepKey` of the preceding action.
420+
355421
### assertNotInstanceOf
356422

357423
See [assertNotInstanceOf docs on codeception.com](http://codeception.com/docs/modules/Asserts#assertNotInstanceOf).

etc/config/.env.example

+3
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ MODULE_WHITELIST=Magento_Framework,ConfigurableProductWishlist,ConfigurableProdu
5959
#*** Default timeout for wait actions
6060
#WAIT_TIMEOUT=30
6161

62+
#*** Uncomment and set to enable all tests, regardless of passing status, to have all their Allure artifacts.
63+
#VERBOSE_ARTIFACTS=true
64+
6265
#*** Uncomment and set to enable browser log entries on actions in Allure. Blacklist is used to filter logs of a specific "source"
6366
#ENABLE_BROWSER_LOG=true
6467
#BROWSER_LOG_BLACKLIST=other

etc/di.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
<!-- Entity value gets replaced in Dom.php before reading $xml -->
1010
<!DOCTYPE config [
11-
<!ENTITY commonTestActions "acceptPopup|actionGroup|amOnPage|amOnUrl|amOnSubdomain|appendField|assertArrayIsSortasserted|assertElementContainsAttribute|attachFile|cancelPopup|checkOption|clearField|click|clickWithLeftButton|clickWithRightButton|closeAdminNotification|closeTab|comment|conditionalClick|createData|deleteData|updateData|getData|dontSee|dontSeeJsError|dontSeeCheckboxIsChecked|dontSeeCookie|dontSeeCurrentUrlEquals|dontSeeCurrentUrlMatches|dontSeeElement|dontSeeElementInDOM|dontSeeInCurrentUrl|dontSeeInField|dontSeeInFormFields|dontSeeInPageSource|dontSeeInSource|dontSeeInTitle|dontSeeLink|dontSeeOptionIsSelected|doubleClick|dragAndDrop|entity|executeJS|fillField|formatMoney|generateDate|grabAttributeFrom|grabCookie|grabFromCurrentUrl|grabMultiple|grabPageSource|grabTextFrom|grabValueFrom|loadSessionSnapshot|loginAsAdmin|magentoCLI|magentoCron|makeScreenshot|maximizeWindow|moveBack|moveForward|moveMouseOver|mSetLocale|mResetLocale|openNewTab|pause|parseFloat|pressKey|reloadPage|resetCookie|submitForm|resizeWindow|saveSessionSnapshot|scrollTo|scrollToTopOfPage|searchAndMultiSelectOption|see|seeCheckboxIsChecked|seeCookie|seeCurrentUrlEquals|seeCurrentUrlMatches|seeElement|seeElementInDOM|seeInCurrentUrl|seeInField|seeInFormFields|seeInPageSource|seeInPopup|seeInSource|seeInTitle|seeLink|seeNumberOfElements|seeOptionIsSelected|selectOption|setCookie|submitForm|switchToIFrame|switchToNextTab|switchToPreviousTab|switchToWindow|typeInPopup|uncheckOption|unselectOption|wait|waitForAjaxLoad|waitForElement|waitForElementChange|waitForElementNotVisible|waitForElementVisible|waitForPwaElementNotVisible|waitForPwaElementVisible|waitForJS|waitForLoadingMaskToDisappear|waitForPageLoad|waitForText|assertArrayHasKey|assertArrayNotHasKey|assertContains|assertStringContainsString|assertStringContainsStringIgnoringCase|assertCount|assertEmpty|assertEquals|assertFalse|assertFileExists|assertFileNotExists|assertGreaterOrEquals|assertGreaterThan|assertGreaterThanOrEqual|assertInstanceOf|assertIsEmpty|assertLessOrEquals|assertLessThan|assertLessThanOrEqual|assertNotContains|assertStringNotContainsString|assertStringNotContainsStringIgnoringCase|assertNotEmpty|assertNotEquals|assertNotInstanceOf|assertNotNull|assertNotRegExp|assertNotSame|assertNull|assertRegExp|assertSame|assertStringStartsNotWith|assertStringStartsWith|assertTrue|expectException|fail|dontSeeFullUrlEquals|dontSee|dontSeeFullUrlMatches|dontSeeInFullUrl|seeFullUrlEquals|seeFullUrlMatches|seeInFullUrl|grabFromFullUrl|helper">
11+
<!ENTITY commonTestActions "acceptPopup|actionGroup|amOnPage|amOnUrl|amOnSubdomain|appendField|assertArrayIsSortasserted|assertElementContainsAttribute|attachFile|cancelPopup|checkOption|clearField|click|clickWithLeftButton|clickWithRightButton|closeAdminNotification|closeTab|comment|conditionalClick|createData|deleteData|updateData|getData|dontSee|dontSeeJsError|dontSeeCheckboxIsChecked|dontSeeCookie|dontSeeCurrentUrlEquals|dontSeeCurrentUrlMatches|dontSeeElement|dontSeeElementInDOM|dontSeeInCurrentUrl|dontSeeInField|dontSeeInFormFields|dontSeeInPageSource|dontSeeInSource|dontSeeInTitle|dontSeeLink|dontSeeOptionIsSelected|doubleClick|dragAndDrop|entity|executeJS|fillField|formatMoney|generateDate|grabAttributeFrom|grabCookie|grabFromCurrentUrl|grabMultiple|grabPageSource|grabTextFrom|grabValueFrom|loadSessionSnapshot|loginAsAdmin|magentoCLI|magentoCron|makeScreenshot|maximizeWindow|moveBack|moveForward|moveMouseOver|mSetLocale|mResetLocale|openNewTab|pause|parseFloat|pressKey|reloadPage|resetCookie|submitForm|resizeWindow|saveSessionSnapshot|scrollTo|scrollToTopOfPage|searchAndMultiSelectOption|see|seeCheckboxIsChecked|seeCookie|seeCurrentUrlEquals|seeCurrentUrlMatches|seeElement|seeElementInDOM|seeInCurrentUrl|seeInField|seeInFormFields|seeInPageSource|seeInPopup|seeInSource|seeInTitle|seeLink|seeNumberOfElements|seeOptionIsSelected|selectOption|setCookie|submitForm|switchToIFrame|switchToNextTab|switchToPreviousTab|switchToWindow|typeInPopup|uncheckOption|unselectOption|wait|waitForAjaxLoad|waitForElement|waitForElementChange|waitForElementNotVisible|waitForElementVisible|waitForPwaElementNotVisible|waitForPwaElementVisible|waitForJS|waitForLoadingMaskToDisappear|waitForPageLoad|waitForText|assertArrayHasKey|assertArrayNotHasKey|assertContains|assertStringContainsString|assertStringContainsStringIgnoringCase|assertCount|assertEmpty|assertEquals|assertFalse|assertFileExists|assertFileNotExists|assertGreaterOrEquals|assertGreaterThan|assertGreaterThanOrEqual|assertInstanceOf|assertIsEmpty|assertLessOrEquals|assertLessThan|assertLessThanOrEqual|assertNotContains|assertStringNotContainsString|assertStringNotContainsStringIgnoringCase|assertNotEmpty|assertNotEquals|assertNotInstanceOf|assertNotNull|assertNotRegExp|assertNotSame|assertNull|assertRegExp|assertSame|assertStringStartsNotWith|assertStringStartsWith|assertTrue|expectException|fail|dontSeeFullUrlEquals|dontSee|dontSeeFullUrlMatches|dontSeeInFullUrl|seeFullUrlEquals|seeFullUrlMatches|seeInFullUrl|grabFromFullUrl|helper|assertEqualsWithDelta|assertEqualsCanonicalizing|assertEqualsIgnoringCase|assertNotEqualsWithDelta|assertNotEqualsCanonicalizing|assertNotEqualsIgnoringCase">
1212
]>
1313

1414
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../src/Magento/FunctionalTestingFramework/ObjectManager/etc/config.xsd">

src/Magento/FunctionalTestingFramework/Allure/Adapter/MagentoAllureAdapter.php

+23
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
use Magento\FunctionalTestingFramework\Test\Objects\ActionGroupObject;
1313
use Magento\FunctionalTestingFramework\Test\Objects\ActionObject;
1414
use Magento\FunctionalTestingFramework\Util\TestGenerator;
15+
use Yandex\Allure\Adapter\Model\Failure;
16+
use Yandex\Allure\Adapter\Model\Provider;
1517
use Yandex\Allure\Adapter\Model\Status;
1618
use Yandex\Allure\Adapter\Model\Step;
1719
use Yandex\Allure\Adapter\Allure;
@@ -119,6 +121,7 @@ private function sanitizeGroupName($group)
119121
// if we can't find this group in the generated suites we have to assume that the group was split for generation
120122
$groupNameSplit = explode("_", $group);
121123
array_pop($groupNameSplit);
124+
array_pop($groupNameSplit);
122125
$originalName = implode("_", $groupNameSplit);
123126

124127
// confirm our original name is one of the existing suite names otherwise just return the original group name
@@ -256,13 +259,16 @@ public function testError(FailEvent $failEvent)
256259
*/
257260
public function testEnd(TestEvent $testEvent)
258261
{
262+
// Peek top of testCaseStorage to check of failure
263+
$testFailed = $this->getLifecycle()->getTestCaseStorage()->get()->getFailure();
259264
// Pops top of stepStorage, need to add it back in after processing
260265
$rootStep = $this->getLifecycle()->getStepStorage()->pollLast();
261266
$formattedSteps = [];
262267
$actionGroupStepContainer = null;
263268

264269
$actionGroupStepKey = null;
265270
foreach ($rootStep->getSteps() as $step) {
271+
$this->removeAttachments($step, $testFailed);
266272
$stepKey = str_replace($actionGroupStepKey, '', $step->getName());
267273
if ($stepKey !== '[]' && $stepKey !== null) {
268274
$step->setName($stepKey);
@@ -379,4 +385,21 @@ private function retrieveStepKey($stepLine)
379385

380386
return $stepKey;
381387
}
388+
389+
/**
390+
* Removes attachments from step depending on MFTF configuration
391+
* @param Step $step
392+
* @param Failure $testFailed
393+
* @return void
394+
*/
395+
private function removeAttachments($step, $testFailed)
396+
{
397+
//Remove Attachments if verbose flag is not true AND test did not fail
398+
if (getenv('VERBOSE_ARTIFACTS') !== true && $testFailed === null) {
399+
foreach ($step->getAttachments() as $index => $attachment) {
400+
$step->removeAttachment($index);
401+
unlink(Provider::getOutputDirectory() . DIRECTORY_SEPARATOR . $attachment->getSource());
402+
}
403+
}
404+
}
382405
}

0 commit comments

Comments
 (0)