Completed
Push — master ( f258b8...883a46 )
by Paweł
81:43 queued 66:40
created

UpdateSimpleProductPage::saveImageUrlForType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Sylius\Behat\Page\Admin\Product;
15
16
use Behat\Mink\Driver\Selenium2Driver;
17
use Behat\Mink\Element\NodeElement;
18
use Sylius\Behat\Behaviour\ChecksCodeImmutability;
19
use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage;
20
use Sylius\Behat\Service\AutocompleteHelper;
21
use Sylius\Behat\Service\SlugGenerationHelper;
22
use Sylius\Component\Core\Model\ChannelInterface;
23
use Sylius\Component\Core\Model\TaxonInterface;
24
use Sylius\Component\Currency\Model\CurrencyInterface;
25
use Sylius\Component\Product\Model\ProductAssociationTypeInterface;
26
use Webmozart\Assert\Assert;
27
28
/**
29
 * @author Łukasz Chruściel <[email protected]>
30
 * @author Gorka Laucirica <[email protected]>
31
 */
32
class UpdateSimpleProductPage extends BaseUpdatePage implements UpdateSimpleProductPageInterface
33
{
34
    use ChecksCodeImmutability;
35
36
    /** @var array */
37
    private $imageUrls = [];
38
39
    /**
40
     * {@inheritdoc}
41
     */
42
    public function nameItIn($name, $localeCode)
43
    {
44
        $this->activateLanguageTab($localeCode);
45
        $this->getElement('name', ['%locale%' => $localeCode])->setValue($name);
46
47
        if ($this->getDriver() instanceof Selenium2Driver) {
48
            SlugGenerationHelper::waitForSlugGeneration(
49
                $this->getSession(),
50
                $this->getElement('slug', ['%locale%' => $localeCode])
51
            );
52
        }
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58
    public function specifyPrice($channelName, $price)
59
    {
60
        $this->getElement('price', ['%channelName%' => $channelName])->setValue($price);
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66
    public function specifyOriginalPrice($channelName, $originalPrice)
67
    {
68
        $this->getElement('original_price', ['%channelName%' => $channelName])->setValue($originalPrice);
69
    }
70
71
    public function addSelectedAttributes()
72
    {
73
        $this->clickTabIfItsNotActive('attributes');
74
        $this->getDocument()->pressButton('Add attributes');
75
76
        $form = $this->getDocument()->find('css', 'form');
77
78
        $this->getDocument()->waitFor(1, function () use ($form) {
79
            return $form->hasClass('loading');
80
        });
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86
    public function removeAttribute($attributeName, $localeCode)
87
    {
88
        $this->clickTabIfItsNotActive('attributes');
89
90
        $this->getElement('attribute_delete_button', ['%attributeName%' => $attributeName, '$localeCode%' => $localeCode])->press();
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96
    public function getAttributeValue($attribute, $localeCode)
97
    {
98
        $this->clickTabIfItsNotActive('attributes');
99
        $this->clickLocaleTabIfItsNotActive($localeCode);
100
101
        return $this->getElement('attribute', ['%attributeName%' => $attribute, '%localeCode%' => $localeCode])->getValue();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getElement...caleCode))->getValue(); (string|boolean|array) is incompatible with the return type declared by the interface Sylius\Behat\Page\Admin\...face::getAttributeValue of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function getAttributeValidationErrors($attributeName, $localeCode)
108
    {
109
        $this->clickTabIfItsNotActive('attributes');
110
        $this->clickLocaleTabIfItsNotActive($localeCode);
111
112
        $validationError = $this->getElement('attribute_element')->find('css', '.sylius-validation-error');
113
114
        return $validationError->getText();
115
    }
116
117
    /**
118
     * {@inheritdoc}
119
     */
120
    public function getNumberOfAttributes()
121
    {
122
        return count($this->getDocument()->findAll('css', '.attribute'));
123
    }
124
125
    /**
126
     * {@inheritdoc}
127
     */
128
    public function hasAttribute($attributeName)
129
    {
130
        return null !== $this->getDocument()->find('css', sprintf('.attribute .label:contains("%s")', $attributeName));
131
    }
132
133
    /**
134
     * {@inheritdoc}
135
     */
136
    public function selectMainTaxon(TaxonInterface $taxon)
137
    {
138
        $this->openTaxonBookmarks();
139
140
        $mainTaxonElement = $this->getElement('main_taxon')->getParent();
141
142
        AutocompleteHelper::chooseValue($this->getSession(), $mainTaxonElement, $taxon->getName());
0 ignored issues
show
Bug introduced by
It seems like $mainTaxonElement defined by $this->getElement('main_taxon')->getParent() on line 140 can be null; however, Sylius\Behat\Service\Aut...teHelper::chooseValue() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
143
    }
144
145
    /**
146
     * {@inheritdoc}
147
     */
148
    public function isMainTaxonChosen($taxonName)
149
    {
150
        $this->openTaxonBookmarks();
151
152
        return $taxonName === $this->getDocument()->find('css', '.search > .text')->getText();
153
    }
154
155
    public function disableTracking()
156
    {
157
        $this->getElement('tracked')->uncheck();
158
    }
159
160
    public function enableTracking()
161
    {
162
        $this->getElement('tracked')->check();
163
    }
164
165
    /**
166
     * {@inheritdoc}
167
     */
168
    public function isTracked()
169
    {
170
        return $this->getElement('tracked')->isChecked();
171
    }
172
173
    /**
174
     * {@inheritdoc}
175
     */
176
    public function enableSlugModification($locale)
177
    {
178
        SlugGenerationHelper::enableSlugModification(
179
            $this->getSession(),
180
            $this->getElement('toggle_slug_modification_button', ['%locale%' => $locale])
181
        );
182
    }
183
184
    /**
185
     * {@inheritdoc}
186
     */
187
    public function isImageWithTypeDisplayed($type)
188
    {
189
        $imageElement = $this->getImageElementByType($type);
190
191
        $imageUrl = $imageElement ? $imageElement->find('css', 'img')->getAttribute('src') : $this->provideImageUrlForType($type);
192
        if (null === $imageElement && null === $imageUrl) {
193
            return false;
194
        }
195
196
        $this->getDriver()->visit($imageUrl);
197
        $pageText = $this->getDocument()->getText();
198
        $this->getDriver()->back();
199
200
        return false === stripos($pageText, '404 Not Found');
201
    }
202
203
    /**
204
     * {@inheritdoc}
205
     */
206
    public function attachImage($path, $type = null)
207
    {
208
        $this->clickTabIfItsNotActive('media');
209
210
        $filesPath = $this->getParameter('files_path');
211
212
        $this->getDocument()->clickLink('Add');
213
214
        $imageForm = $this->getLastImageElement();
215
        if (null !== $type) {
216
            $imageForm->fillField('Type', $type);
217
        }
218
219
        $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath.$path);
220
    }
221
222
    /**
223
     * {@inheritdoc}
224
     */
225
    public function changeImageWithType($type, $path)
226
    {
227
        $filesPath = $this->getParameter('files_path');
228
229
        $imageForm = $this->getImageElementByType($type);
230
        $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath.$path);
231
    }
232
233
    /**
234
     * {@inheritdoc}
235
     */
236
    public function removeImageWithType($type)
237
    {
238
        $this->clickTabIfItsNotActive('media');
239
240
        $imageElement = $this->getImageElementByType($type);
241
        $imageSourceElement = $imageElement->find('css', 'img');
242
        if (null !== $imageSourceElement) {
243
            $this->saveImageUrlForType($type, $imageSourceElement->getAttribute('src'));
244
        }
245
246
        $imageElement->clickLink('Delete');
247
    }
248
249
    public function removeFirstImage()
250
    {
251
        $this->clickTabIfItsNotActive('media');
252
        $imageElement = $this->getFirstImageElement();
253
        $imageTypeElement = $imageElement->find('css', 'input[type=text]');
254
        $imageSourceElement = $imageElement->find('css', 'img');
255
256
        if (null !== $imageTypeElement && null !== $imageSourceElement) {
257
            $this->saveImageUrlForType(
258
                $imageTypeElement->getValue(),
259
                $imageSourceElement->getAttribute('src')
260
            );
261
        }
262
        $imageElement->clickLink('Delete');
263
    }
264
265
    /**
266
     * {@inheritdoc}
267
     */
268
    public function modifyFirstImageType($type)
269
    {
270
        $this->clickTabIfItsNotActive('media');
271
272
        $firstImage = $this->getFirstImageElement();
273
        $this->setImageType($firstImage, $type);
274
    }
275
276
    /**
277
     * {@inheritdoc}
278
     */
279
    public function countImages()
280
    {
281
        $imageElements = $this->getImageElements();
282
283
        return count($imageElements);
284
    }
285
286
    /**
287
     * {@inheritdoc}
288
     */
289
    public function isSlugReadonlyIn($locale)
290
    {
291
        return SlugGenerationHelper::isSlugReadonly(
292
            $this->getSession(),
293
            $this->getElement('slug', ['%locale%' => $locale])
294
        );
295
    }
296
297
    /**
298
     * {@inheritdoc}
299
     */
300
    public function associateProducts(ProductAssociationTypeInterface $productAssociationType, array $productsNames)
301
    {
302
        $this->clickTab('associations');
303
304
        Assert::isInstanceOf($this->getDriver(), Selenium2Driver::class);
305
306
        $dropdown = $this->getElement('association_dropdown', [
307
            '%association%' => $productAssociationType->getName()
308
        ]);
309
        $dropdown->click();
310
311
        foreach ($productsNames as $productName) {
312
            $dropdown->waitFor(5, function () use ($productName, $productAssociationType) {
313
                return $this->hasElement('association_dropdown_item', [
314
                    '%association%' => $productAssociationType->getName(),
315
                    '%item%' => $productName,
316
                ]);
317
            });
318
319
            $item = $this->getElement('association_dropdown_item', [
320
                '%association%' => $productAssociationType->getName(),
321
                '%item%' => $productName,
322
            ]);
323
            $item->click();
324
        }
325
    }
326
327
    /**
328
     * {@inheritdoc}
329
     */
330
    public function hasAssociatedProduct($productName, ProductAssociationTypeInterface $productAssociationType)
331
    {
332
        $this->clickTabIfItsNotActive('associations');
333
334
        return $this->hasElement('association_dropdown_item', [
335
            '%association%' => $productAssociationType->getName(),
336
            '%item%' => $productName,
337
        ]);
338
    }
339
340
    /**
341
     * {@inheritdoc}
342
     */
343
    public function removeAssociatedProduct($productName, ProductAssociationTypeInterface $productAssociationType)
344
    {
345
        $this->clickTabIfItsNotActive('associations');
346
347
        $item = $this->getElement('association_dropdown_item_selected', [
348
            '%association%' => $productAssociationType->getName(),
349
            '%item%' => $productName,
350
        ]);
351
352
        $deleteIcon = $item->find('css', 'i.delete');
353
        Assert::notNull($deleteIcon);
354
        $deleteIcon->click();
355
    }
356
357
    /**
358
     * {@inheritdoc}
359
     */
360
    public function getPricingConfigurationForChannelAndCurrencyCalculator(ChannelInterface $channel, CurrencyInterface $currency)
361
    {
362
        $priceConfigurationElement = $this->getElement('pricing_configuration');
363
        $priceElement = $priceConfigurationElement
364
            ->find('css', sprintf('label:contains("%s %s")', $channel->getCode(), $currency->getCode()))->getParent();
365
366
        return $priceElement->find('css', 'input')->getValue();
367
    }
368
369
    /**
370
     * {@inheritdoc}
371
     */
372
    public function getSlug($locale)
373
    {
374
        $this->activateLanguageTab($locale);
375
376
        return $this->getElement('slug', ['%locale%' => $locale])->getValue();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getElement... $locale))->getValue(); (string|boolean|array) is incompatible with the return type declared by the interface Sylius\Behat\Page\Admin\...tPageInterface::getSlug of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
377
    }
378
379
    /**
380
     * {@inheritdoc}
381
     */
382
    public function specifySlugIn($slug, $locale)
383
    {
384
        $this->activateLanguageTab($locale);
385
386
        $this->getElement('slug', ['%locale%' => $locale])->setValue($slug);
387
    }
388
389
    /**
390
     * {@inheritdoc}
391
     */
392
    public function activateLanguageTab($locale)
393
    {
394
        if (!$this->getDriver() instanceof Selenium2Driver) {
395
            return;
396
        }
397
398
        $languageTabTitle = $this->getElement('language_tab', ['%locale%' => $locale]);
399
        if (!$languageTabTitle->hasClass('active')) {
400
            $languageTabTitle->click();
401
        }
402
    }
403
404
    public function getPriceForChannel($channelName)
405
    {
406
        return $this->getElement('price', ['%channelName%' => $channelName])->getValue();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getElement...nnelName))->getValue(); (string|boolean|array) is incompatible with the return type declared by the interface Sylius\Behat\Page\Admin\...ace::getPriceForChannel of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
407
    }
408
409
    /**
410
     * {@inheritdoc}
411
     */
412
    public function getOriginalPriceForChannel($channelName)
413
    {
414
        return $this->getElement('original_price', ['%channelName%' => $channelName])->getValue();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getElement...nnelName))->getValue(); (string|boolean|array) is incompatible with the return type declared by the interface Sylius\Behat\Page\Admin\...OriginalPriceForChannel of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
415
    }
416
417
    /**
418
     * {@inheritdoc}
419
     */
420
    public function isShippingRequired()
421
    {
422
        return $this->getElement('shipping_required')->isChecked();
423
    }
424
425
    /**
426
     * {@inheritdoc}
427
     */
428
    protected function getCodeElement()
429
    {
430
        return $this->getElement('code');
431
    }
432
433
    /**
434
     * {@inheritdoc}
435
     */
436
    protected function getElement($name, array $parameters = [])
437
    {
438
        if (!isset($parameters['%locale%'])) {
439
            $parameters['%locale%'] = 'en_US';
440
        }
441
442
        return parent::getElement($name, $parameters);
443
    }
444
445
    /**
446
     * {@inheritdoc}
447
     */
448
    protected function getDefinedElements()
449
    {
450
        return array_merge(parent::getDefinedElements(), [
451
            'association_dropdown' => '.field > label:contains("%association%") ~ .product-select',
452
            'association_dropdown_item' => '.field > label:contains("%association%") ~ .product-select > div.menu > div.item:contains("%item%")',
453
            'association_dropdown_item_selected' => '.field > label:contains("%association%") ~ .product-select > a.label:contains("%item%")',
454
            'attribute' => '.tab[data-tab="%localeCode%"] .attribute:contains("%attributeName%") input',
455
            'attribute_element' => '.attribute',
456
            'attribute_delete_button' => '.tab[data-tab="%localeCode%"] .attribute .label:contains("%attributeName%") ~ button',
457
            'code' => '#sylius_product_code',
458
            'images' => '#sylius_product_images',
459
            'language_tab' => '[data-locale="%locale%"] .title',
460
            'locale_tab' => '#attributesContainer .menu [data-tab="%localeCode%"]',
461
            'name' => '#sylius_product_translations_%locale%_name',
462
            'original_price' => '#sylius_product_variant_channelPricings > .field:contains("%channelName%") input[name$="[originalPrice]"]',
463
            'price' => '#sylius_product_variant_channelPricings > .field:contains("%channelName%") input[name$="[price]"]',
464
            'pricing_configuration' => '#sylius_calculator_container',
465
            'main_taxon' => '#sylius_product_mainTaxon',
466
            'shipping_required' => '#sylius_product_variant_shippingRequired',
467
            'slug' => '#sylius_product_translations_%locale%_slug',
468
            'tab' => '.menu [data-tab="%name%"]',
469
            'taxonomy' => 'a[data-tab="taxonomy"]',
470
            'tracked' => '#sylius_product_variant_tracked',
471
            'toggle_slug_modification_button' => '[data-locale="%locale%"] .toggle-product-slug-modification',
472
        ]);
473
    }
474
475
    private function openTaxonBookmarks()
476
    {
477
        $this->getElement('taxonomy')->click();
478
    }
479
480
    /**
481
     * @param string $tabName
482
     */
483
    private function clickTabIfItsNotActive($tabName)
484
    {
485
        $attributesTab = $this->getElement('tab', ['%name%' => $tabName]);
486
        if (!$attributesTab->hasClass('active')) {
487
            $attributesTab->click();
488
        }
489
    }
490
491
    /**
492
     * @param string $tabName
493
     */
494
    private function clickTab($tabName)
495
    {
496
        $attributesTab = $this->getElement('tab', ['%name%' => $tabName]);
497
        $attributesTab->click();
498
    }
499
500
    /**
501
     * @param string $localeCode
502
     */
503
    private function clickLocaleTabIfItsNotActive($localeCode)
504
    {
505
        $localeTab = $this->getElement('locale_tab', ['%localeCode%' => $localeCode]);
506
        if (!$localeTab->hasClass('active')) {
507
            $localeTab->click();
508
        }
509
    }
510
511
    /**
512
     * @param string $type
513
     *
514
     * @return NodeElement
515
     */
516
    private function getImageElementByType($type)
517
    {
518
        $images = $this->getElement('images');
519
        $typeInput = $images->find('css', 'input[value="'.$type.'"]');
520
521
        if (null === $typeInput) {
522
            return null;
523
        }
524
525
        return $typeInput->getParent()->getParent()->getParent();
526
    }
527
528
    /**
529
     * @return NodeElement[]
530
     */
531
    private function getImageElements()
532
    {
533
        $images = $this->getElement('images');
534
535
        return $images->findAll('css', 'div[data-form-collection="item"]');
536
    }
537
538
    /**
539
     * @return NodeElement
540
     */
541
    private function getLastImageElement()
542
    {
543
        $imageElements = $this->getImageElements();
544
545
        Assert::notEmpty($imageElements);
546
547
        return end($imageElements);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression end($imageElements); of type Behat\Mink\Element\NodeElement|false adds false to the return on line 547 which is incompatible with the return type documented by Sylius\Behat\Page\Admin\...ge::getLastImageElement of type Behat\Mink\Element\NodeElement. It seems like you forgot to handle an error condition.
Loading history...
548
    }
549
550
    /**
551
     * @return NodeElement
552
     */
553
    private function getFirstImageElement()
554
    {
555
        $imageElements = $this->getImageElements();
556
557
        Assert::notEmpty($imageElements);
558
559
        return reset($imageElements);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression reset($imageElements); of type Behat\Mink\Element\NodeElement|false adds false to the return on line 559 which is incompatible with the return type documented by Sylius\Behat\Page\Admin\...e::getFirstImageElement of type Behat\Mink\Element\NodeElement. It seems like you forgot to handle an error condition.
Loading history...
560
    }
561
562
    /**
563
     * @param NodeElement $imageElement
564
     * @param string $type
565
     */
566
    private function setImageType(NodeElement $imageElement, $type)
567
    {
568
        $typeField = $imageElement->findField('Type');
569
        $typeField->setValue($type);
570
    }
571
572
    private function provideImageUrlForType(string $type): ?string
573
    {
574
        return $this->imageUrls[$type] ?? null;
575
    }
576
577
    private function saveImageUrlForType(string $type, string $imageUrl): void
578
    {
579
        $this->imageUrls[$type] = $imageUrl;
580
    }
581
}
582