Completed
Push — remove-content-bundle ( fd7705...1b4274 )
by Kamil
18:36
created

specifyPriceForChannelAndCurrency()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 11
rs 9.4285
cc 1
eloc 6
nc 1
nop 3
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 Behat\Mink\Exception\ElementNotFoundException;
17
use Sylius\Behat\Behaviour\SpecifiesItsCode;
18
use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
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
 */
27
class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProductPageInterface
28
{
29
    use SpecifiesItsCode;
30
31
    /**
32
     * {@inheritdoc}
33
     */
34
    public function getRouteName()
35
    {
36
        return parent::getRouteName() . '_simple';
37
    }
38
39
    /**
40
     * {@inheritdoc}
41
     */
42
    public function nameItIn($name, $localeCode)
43
    {
44
        $this->getDocument()->fillField(
45
            sprintf('sylius_product_translations_%s_name', $localeCode), $name
46
        );
47
48
        $this->waitForSlugGenerationIfNecessary();
49
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54
    public function specifySlug($slug)
55
    {
56
        $this->getDocument()->fillField('Slug', $slug);
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    public function specifyPrice($price)
63
    {
64
        $this->getDocument()->fillField('Price', $price);
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70
    public function addAttribute($attribute, $value)
71
    {
72
        $this->clickTabIfItsNotActive('attributes');
73
74
        $attributeOption = $this->getElement('attributes_choice')->find('css', sprintf('option:contains("%s")', $attribute));
75
        $this->selectElementFromAttributesDropdown($attributeOption->getAttribute('value'));
76
77
        $this->getDocument()->pressButton('Add attributes');
78
        $this->waitForFormElement();
79
80
        $this->getElement('attribute_value', ['%attribute%' => $attribute])->setValue($value);
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86
    public function removeAttribute($attribute)
87
    {
88
        $this->clickTabIfItsNotActive('attributes');
89
90
        $this->getElement('attribute_delete_button', ['%attribute%' => $attribute])->press();
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96
    public function attachImage($path, $code = null)
97
    {
98
        $this->clickTabIfItsNotActive('media');
99
100
        $filesPath = $this->getParameter('files_path');
101
102
        $this->getDocument()->clickLink('Add');
103
104
        $imageForm = $this->getLastImageElement();
105
        if (null !== $code) {
106
            $imageForm->fillField('Code', $code);
107
        }
108
109
        $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath.$path);
110
    }
111
112
    public function enableSlugModification()
113
    {
114
        $this->getElement('toggle_slug_modification_button')->press();
115
    }
116
117
    /**
118
     * {@inheritdoc}
119
     */
120
    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...
121
    {
122
        $this->clickTab('associations');
123
124
        Assert::isInstanceOf($this->getDriver(), Selenium2Driver::class);
125
126
        $dropdown = $this->getElement('association_dropdown', [
127
            '%association%' => $productAssociationType->getName()
128
        ]);
129
        $dropdown->click();
130
        $dropdown->waitFor(10, function () use ($productsNames, $productAssociationType) {
131
            return $this->hasElement('association_dropdown_item', [
132
                '%association%' => $productAssociationType->getName(),
133
                '%item%' => $productsNames[0],
134
            ]);
135
        });
136
137
        foreach ($productsNames as $productName) {
138
            $item = $this->getElement('association_dropdown_item', [
139
                '%association%' => $productAssociationType->getName(),
140
                '%item%' => $productName,
141
            ]);
142
            $item->click();
143
        }
144
    }
145
146
    /**
147
     * {@inheritdoc}
148
     */
149
    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...
150
    {
151
        $this->clickTabIfItsNotActive('associations');
152
153
        $item = $this->getElement('association_dropdown_item_selected', [
154
            '%association%' => $productAssociationType->getName(),
155
            '%item%' => $productName,
156
        ]);
157
        $item->find('css', 'i.delete')->click();
158
    }
159
160
    /**
161
     * {@inheritdoc}
162
     */
163
    public function choosePricingCalculator($name)
164
    {
165
        $this->getElement('price_calculator')->selectOption($name);
166
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171
    public function specifyPriceForChannelAndCurrency($price, ChannelInterface $channel, CurrencyInterface $currency)
172
    {
173
        $calculatorElement = $this->getElement('calculator');
174
        $calculatorElement
175
            ->waitFor(5, function () use ($channel, $currency) {
176
                return $this->getElement('calculator')->hasField(sprintf('%s %s', $channel->getName(), $currency->getCode()));
177
            })
178
        ;
179
180
        $calculatorElement->fillField(sprintf('%s %s', $channel->getName(), $currency->getCode()), $price);
181
    }
182
183
    /**
184
     * {@inheritdoc}
185
     */
186
    protected function getDefinedElements()
187
    {
188
        return array_merge(parent::getDefinedElements(), [
189
            'association_dropdown' => '.field > label:contains("%association%") ~ .product-select',
190
            'association_dropdown_item' => '.field > label:contains("%association%") ~ .product-select > div.menu > div.item:contains("%item%")',
191
            'association_dropdown_item_selected' => '.field > label:contains("%association%") ~ .product-select > a.label:contains("%item%")',
192
            'attribute_delete_button' => '.attribute .label:contains("%attribute%") ~ button',
193
            'attribute_value' => '.attribute .label:contains("%attribute%") ~ input',
194
            'attributes_choice' => 'select[name="sylius_product_attribute_choice"]',
195
            'calculator' => '#sylius_calculator_container',
196
            'code' => '#sylius_product_code',
197
            'form' => 'form[name="sylius_product"]',
198
            'images' => '#sylius_product_images',
199
            'name' => '#sylius_product_translations_en_US_name',
200
            'price' => '#sylius_product_variant_price',
201
            'price_calculator' => '#sylius_product_variant_pricingCalculator',
202
            'slug' => '#sylius_product_translations_en_US_slug',
203
            'tab' => '.menu [data-tab="%name%"]',
204
            'toggle_slug_modification_button' => '#toggle-slug-modification',
205
        ]);
206
    }
207
208
    /**
209
     * @param int $id
210
     */
211
    private function selectElementFromAttributesDropdown($id)
212
    {
213
        /** @var Selenium2Driver $driver */
214
        $driver = $this->getDriver();
215
        Assert::isInstanceOf($driver, Selenium2Driver::class);
216
217
        $driver->executeScript('$(\'[name="sylius_product_attribute_choice"]\').dropdown(\'show\');');
218
        $driver->executeScript(sprintf('$(\'[name="sylius_product_attribute_choice"]\').dropdown(\'set selected\', %s);', $id));
219
    }
220
221
    /**
222
     * @param int $timeout
223
     */
224
    private function waitForFormElement($timeout = 5)
225
    {
226
        $form = $this->getElement('form');
227
        $this->getDocument()->waitFor($timeout, function () use ($form) {
228
            return false === strpos($form->getAttribute('class'), 'loading');
229
        });
230
    }
231
232
    /**
233
     * @param string $tabName
234
     */
235
    private function clickTabIfItsNotActive($tabName)
236
    {
237
        $attributesTab = $this->getElement('tab', ['%name%' => $tabName]);
238
        if (!$attributesTab->hasClass('active')) {
239
            $attributesTab->click();
240
        }
241
    }
242
243
    /**
244
     * @param string $tabName
245
     */
246
    private function clickTab($tabName)
247
    {
248
        $attributesTab = $this->getElement('tab', ['%name%' => $tabName]);
249
        $attributesTab->click();
250
    }
251
252
    /**
253
     * @return NodeElement
254
     */
255
    private function getLastImageElement()
256
    {
257
        $images = $this->getElement('images');
258
        $items = $images->findAll('css', 'div[data-form-collection="item"]');
259
260
        Assert::notEmpty($items);
261
262
        return end($items);
263
    }
264
265
    private function waitForSlugGenerationIfNecessary()
266
    {
267
        if ($this->getDriver() instanceof Selenium2Driver) {
268
            $this->getDocument()->waitFor(10, function () {
269
                return '' !== $this->getElement('slug')->getValue();
270
            });
271
        }
272
    }
273
}
274