Completed
Push — upgrade ( c4e463 )
by Kamil
22:47
created

CreateSimpleProductPage::waitForSlugGenerationIfNecessary()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
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
namespace Sylius\Behat\Page\Admin\Product;
13
14
use Behat\Mink\Driver\Selenium2Driver;
15
use Behat\Mink\Element\NodeElement;
16
use Sylius\Behat\Behaviour\SpecifiesItsCode;
17
use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
18
use Sylius\Behat\Service\SlugGenerationHelper;
19
use Sylius\Component\Core\Model\ChannelInterface;
20
use Sylius\Component\Currency\Model\CurrencyInterface;
21
use Sylius\Component\Product\Model\ProductAssociationTypeInterface;
22
use Webmozart\Assert\Assert;
23
24
/**
25
 * @author Łukasz Chruściel <[email protected]>
26
 * @author Gorka Laucirica <[email protected]>
27
 */
28
class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProductPageInterface
29
{
30
    use SpecifiesItsCode;
31
32
    /**
33
     * {@inheritdoc}
34
     */
35
    public function getRouteName()
36
    {
37
        return parent::getRouteName() . '_simple';
38
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function nameItIn($name, $localeCode)
44
    {
45
        $this->activateLanguageTab($localeCode);
46
        $this->getElement('name', ['%locale%' => $localeCode])->setValue($name);
47
48
        if ($this->getDriver() instanceof Selenium2Driver) {
49
            SlugGenerationHelper::waitForSlugGeneration(
50
                $this->getSession(),
51
                $this->getElement('slug', ['%locale%' => $localeCode])
52
            );
53
        }
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59
    public function specifySlugIn($slug, $locale)
60
    {
61
        $this->activateLanguageTab($locale);
62
63
        $this->getElement('slug', ['%locale%' => $locale])->setValue($slug);
64
    }
65
66
    /**
67
     * {@inheritdoc}
68
     */
69
    public function specifyPrice($channelName, $price)
70
    {
71
        $this->getElement('price', ['%channelName%' => $channelName])->setValue($price);
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77
    public function specifyOriginalPrice($channelName, $originalPrice)
78
    {
79
        $this->getElement('original_price', ['%channelName%' => $channelName])->setValue($originalPrice);
80
    }
81
82
    /**
83
     * {@inheritdoc}
84
     */
85
    public function addAttribute($attributeName, $value, $localeCode)
86
    {
87
        $this->clickTabIfItsNotActive('attributes');
88
        $this->clickLocaleTabIfItsNotActive($localeCode);
89
90
        $attributeOption = $this->getElement('attributes_choice')->find('css', sprintf('option:contains("%s")', $attributeName));
91
        $this->selectElementFromAttributesDropdown($attributeOption->getAttribute('value'));
92
93
        $this->getDocument()->pressButton('Add attributes');
94
        $this->waitForFormElement();
95
96
        $this->getElement('attribute_value', ['%attributeName%' => $attributeName, '%localeCode%' => $localeCode])->setValue($value);
97
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102
    public function removeAttribute($attributeName, $localeCode)
103
    {
104
        $this->clickTabIfItsNotActive('attributes');
105
106
        $this->getElement('attribute_delete_button', ['%attributeName%' => $attributeName, '%localeCode%' => $localeCode])->press();
107
    }
108
109
    /**
110
     * {@inheritdoc}
111
     */
112
    public function attachImage($path, $type = null)
113
    {
114
        $this->clickTabIfItsNotActive('media');
115
116
        $filesPath = $this->getParameter('files_path');
117
118
        $this->getDocument()->clickLink('Add');
119
120
        $imageForm = $this->getLastImageElement();
121
        if (null !== $type) {
122
            $imageForm->fillField('Type', $type);
123
        }
124
125
        $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath.$path);
126
    }
127
128
    /**
129
     * {@inheritdoc}
130
     */
131
    public function associateProducts(ProductAssociationTypeInterface $productAssociationType, array $productsNames)
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $productAssociationType exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
132
    {
133
        $this->clickTab('associations');
134
135
        Assert::isInstanceOf($this->getDriver(), Selenium2Driver::class);
136
137
        $dropdown = $this->getElement('association_dropdown', [
138
            '%association%' => $productAssociationType->getName()
139
        ]);
140
        $dropdown->click();
141
142
        foreach ($productsNames as $productName) {
143
            $dropdown->waitFor(5, function () use ($productName, $productAssociationType) {
144
                return $this->hasElement('association_dropdown_item', [
145
                    '%association%' => $productAssociationType->getName(),
146
                    '%item%' => $productName,
147
                ]);
148
            });
149
150
            $item = $this->getElement('association_dropdown_item', [
151
                '%association%' => $productAssociationType->getName(),
152
                '%item%' => $productName,
153
            ]);
154
            $item->click();
155
        }
156
    }
157
158
    /**
159
     * {@inheritdoc}
160
     */
161
    public function removeAssociatedProduct($productName, ProductAssociationTypeInterface $productAssociationType)
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $productAssociationType exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
162
    {
163
        $this->clickTabIfItsNotActive('associations');
164
165
        $item = $this->getElement('association_dropdown_item_selected', [
166
            '%association%' => $productAssociationType->getName(),
167
            '%item%' => $productName,
168
        ]);
169
        $item->find('css', 'i.delete')->click();
170
    }
171
172
    /**
173
     * {@inheritdoc}
174
     */
175
    public function choosePricingCalculator($name)
176
    {
177
        $this->getElement('price_calculator')->selectOption($name);
178
    }
179
180
    /**
181
     * {@inheritdoc}
182
     */
183
    public function checkChannel($channelName)
184
    {
185
        $this->getElement('channel_checkbox', ['%channelName%' => $channelName])->check();
186
    }
187
188
    /**
189
     * {@inheritdoc}
190
     */
191
    public function specifyPriceForChannelAndCurrency($price, ChannelInterface $channel, CurrencyInterface $currency)
192
    {
193
        $calculatorElement = $this->getElement('calculator');
194
        $calculatorElement
195
            ->waitFor(5, function () use ($channel, $currency) {
196
                return $this->getElement('calculator')->hasField(sprintf('%s %s', $channel->getName(), $currency->getCode()));
197
            })
198
        ;
199
200
        $calculatorElement->fillField(sprintf('%s %s', $channel->getName(), $currency->getCode()), $price);
201
    }
202
203
    /**
204
     * {@inheritdoc}
205
     */
206
    public function activateLanguageTab($locale)
207
    {
208
        if (!$this->getDriver() instanceof Selenium2Driver) {
209
            return;
210
        }
211
212
        $languageTabTitle = $this->getElement('language_tab', ['%locale%' => $locale]);
213
        if (!$languageTabTitle->hasClass('active')) {
214
            $languageTabTitle->click();
215
        }
216
    }
217
218
    /**
219
     * {@inheritdoc}
220
     */
221
    public function selectShippingCategory($shippingCategoryName)
222
    {
223
        $this->getElement('shipping_category')->selectOption($shippingCategoryName);
224
    }
225
226
    /**
227
     * {@inheritdoc}
228
     */
229
    public function setShippingRequired($isShippingRequired)
230
    {
231
        if ($isShippingRequired) {
232
            $this->getElement('shipping_required')->check();
233
234
            return;
235
        }
236
237
        $this->getElement('shipping_required')->uncheck();
238
    }
239
240
    /**
241
     * {@inheritdoc}
242
     */
243
    protected function getElement($name, array $parameters = [])
244
    {
245
        if (!isset($parameters['%locale%'])) {
246
            $parameters['%locale%'] = 'en_US';
247
        }
248
249
        return parent::getElement($name, $parameters);
250
    }
251
252
    /**
253
     * {@inheritdoc}
254
     */
255
    protected function getDefinedElements()
256
    {
257
        return array_merge(parent::getDefinedElements(), [
258
            'association_dropdown' => '.field > label:contains("%association%") ~ .product-select',
259
            'association_dropdown_item' => '.field > label:contains("%association%") ~ .product-select > div.menu > div.item:contains("%item%")',
260
            'association_dropdown_item_selected' => '.field > label:contains("%association%") ~ .product-select > a.label:contains("%item%")',
261
            'attribute_delete_button' => '.tab[data-tab="%localeCode%"] .attribute .label:contains("%attributeName%") ~ button',
262
            'attribute_value' => '.tab[data-tab="%localeCode%"] .attribute .label:contains("%attributeName%") ~ input',
263
            'attributes_choice' => '#sylius_product_attribute_choice',
264
            'calculator' => '#sylius_calculator_container',
265
            'channel_checkbox' => '.checkbox:contains("%channelName%") input',
266
            'channel_pricings' => '#sylius_product_variant_channelPricings',
267
            'code' => '#sylius_product_code',
268
            'form' => 'form[name="sylius_product"]',
269
            'images' => '#sylius_product_images',
270
            'language_tab' => '[data-locale="%locale%"] .title',
271
            'locale_tab' => '#attributesContainer .menu [data-tab="%localeCode%"]',
272
            'name' => '#sylius_product_translations_%locale%_name',
273
            'price' => '#sylius_product_variant_channelPricings > .field:contains("%channelName%") input[name$="[price]"]',
274
            'original_price' => '#sylius_product_variant_channelPricings > .field:contains("%channelName%") input[name$="[originalPrice]"]',
275
            'price_calculator' => '#sylius_product_variant_pricingCalculator',
276
            'shipping_category' => '#sylius_product_variant_shippingCategory',
277
            'shipping_required' => '#sylius_product_variant_shippingRequired',
278
            'slug' => '#sylius_product_translations_%locale%_slug',
279
            'tab' => '.menu [data-tab="%name%"]',
280
            'toggle_slug_modification_button' => '.toggle-product-slug-modification',
281
        ]);
282
    }
283
284
    /**
285
     * @param int $id
286
     */
287
    private function selectElementFromAttributesDropdown($id)
288
    {
289
        /** @var Selenium2Driver $driver */
290
        $driver = $this->getDriver();
291
        Assert::isInstanceOf($driver, Selenium2Driver::class);
292
293
        $driver->executeScript('$(\'#sylius_product_attribute_choice\').dropdown(\'show\');');
294
        $driver->executeScript(sprintf('$(\'#sylius_product_attribute_choice\').dropdown(\'set selected\', \'%s\');', $id));
295
    }
296
297
    /**
298
     * @param int $timeout
299
     */
300
    private function waitForFormElement($timeout = 5)
301
    {
302
        $form = $this->getElement('form');
303
        $this->getDocument()->waitFor($timeout, function () use ($form) {
304
            return false === strpos($form->getAttribute('class'), 'loading');
305
        });
306
    }
307
308
    /**
309
     * @param string $tabName
310
     */
311
    private function clickTabIfItsNotActive($tabName)
312
    {
313
        $attributesTab = $this->getElement('tab', ['%name%' => $tabName]);
314
        if (!$attributesTab->hasClass('active')) {
315
            $attributesTab->click();
316
        }
317
    }
318
319
    /**
320
     * @param string $tabName
321
     */
322
    private function clickTab($tabName)
323
    {
324
        $attributesTab = $this->getElement('tab', ['%name%' => $tabName]);
325
        $attributesTab->click();
326
    }
327
328
    /**
329
     * @param string $localeCode
330
     */
331
    private function clickLocaleTabIfItsNotActive($localeCode)
332
    {
333
        $localeTab = $this->getElement('locale_tab', ['%localeCode%' => $localeCode]);
334
        if (!$localeTab->hasClass('active')) {
335
            $localeTab->click();
336
        }
337
    }
338
339
    /**
340
     * @return NodeElement
341
     */
342
    private function getLastImageElement()
343
    {
344
        $images = $this->getElement('images');
345
        $items = $images->findAll('css', 'div[data-form-collection="item"]');
346
347
        Assert::notEmpty($items);
348
349
        return end($items);
350
    }
351
}
352