Completed
Push — master ( c66308...141223 )
by Kamil
28:38 queued 09:41
created

CreateSimpleProductPage::associateProducts()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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