Completed
Push — travis-xenial ( 762d22...317bf8 )
by Kamil
05:24
created

CreateSimpleProductPage::activateLanguageTab()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 4
nc 3
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
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 DMore\ChromeDriver\ChromeDriver;
19
use Sylius\Behat\Behaviour\SpecifiesItsCode;
20
use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
21
use Sylius\Behat\Service\AutocompleteHelper;
22
use Sylius\Behat\Service\SlugGenerationHelper;
23
use Sylius\Component\Core\Model\TaxonInterface;
24
use Sylius\Component\Product\Model\ProductAssociationTypeInterface;
25
use WebDriver\Exception;
26
use Webmozart\Assert\Assert;
27
28
class CreateSimpleProductPage extends BaseCreatePage implements CreateSimpleProductPageInterface
0 ignored issues
show
Bug introduced by
There is one abstract method getDocument in this class; you could implement it, or declare this class as abstract.
Loading history...
29
{
30
    use SpecifiesItsCode;
31
32
    public function getRouteName(): string
33
    {
34
        return parent::getRouteName() . '_simple';
35
    }
36
37
    public function nameItIn(string $name, string $localeCode): void
38
    {
39
        $this->clickTabIfItsNotActive('details');
40
        $this->activateLanguageTab($localeCode);
41
        $this->getElement('name', ['%locale%' => $localeCode])->setValue($name);
42
43
        if ($this->getDriver() instanceof Selenium2Driver || $this->getDriver() instanceof ChromeDriver) {
0 ignored issues
show
Bug introduced by
The class DMore\ChromeDriver\ChromeDriver does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
44
            SlugGenerationHelper::waitForSlugGeneration(
45
                $this->getSession(),
46
                $this->getElement('slug', ['%locale%' => $localeCode])
47
            );
48
        }
49
    }
50
51
    public function specifySlugIn(?string $slug, string $locale): void
52
    {
53
        $this->activateLanguageTab($locale);
54
55
        $this->getElement('slug', ['%locale%' => $locale])->setValue($slug);
56
    }
57
58
    public function specifyPrice(string $channelName, string $price): void
59
    {
60
        $this->getElement('price', ['%channelName%' => $channelName])->setValue($price);
61
    }
62
63
    public function specifyOriginalPrice(string $channelName, int $originalPrice): void
64
    {
65
        $this->getElement('original_price', ['%channelName%' => $channelName])->setValue($originalPrice);
66
    }
67
68
    public function addAttribute(string $attributeName, string $value, string $localeCode): void
69
    {
70
        $this->clickTabIfItsNotActive('attributes');
71
        $this->clickLocaleTabIfItsNotActive($localeCode);
72
73
        $attributeOption = $this->getElement('attributes_choice')->find('css', sprintf('option:contains("%s")', $attributeName));
74
        $this->selectElementFromAttributesDropdown($attributeOption->getAttribute('value'));
75
76
        $this->getDocument()->pressButton('Add attributes');
77
        $this->waitForFormElement();
78
79
        $this->getElement('attribute_value', ['%attributeName%' => $attributeName, '%localeCode%' => $localeCode])->setValue($value);
80
    }
81
82
    public function getAttributeValidationErrors(string $attributeName, string $localeCode): string
83
    {
84
        $this->clickTabIfItsNotActive('attributes');
85
        $this->clickLocaleTabIfItsNotActive($localeCode);
86
87
        $validationError = $this->getElement('attribute')->find('css', '.sylius-validation-error');
88
89
        return $validationError->getText();
90
    }
91
92
    public function removeAttribute(string $attributeName, string $localeCode): void
93
    {
94
        $this->clickTabIfItsNotActive('attributes');
95
96
        $this->getElement('attribute_delete_button', ['%attributeName%' => $attributeName, '%localeCode%' => $localeCode])->press();
97
    }
98
99
    public function checkAttributeErrors($attributeName, $localeCode): void
100
    {
101
        $this->clickTabIfItsNotActive('attributes');
102
        $this->clickLocaleTabIfItsNotActive($localeCode);
103
    }
104
105
    public function selectMainTaxon(TaxonInterface $taxon): void
106
    {
107
        $this->openTaxonBookmarks();
108
109
        $mainTaxonElement = $this->getElement('main_taxon')->getParent();
110
111
        AutocompleteHelper::chooseValue($this->getSession(), $mainTaxonElement, $taxon->getName());
112
    }
113
114
    public function isMainTaxonChosen(string $taxonName): bool
115
    {
116
        $this->openTaxonBookmarks();
117
118
        return $taxonName === $this->getDocument()->find('css', '.search > .text')->getText();
119
    }
120
121
    public function attachImage(string $path, string $type = null): void
122
    {
123
        $this->clickTabIfItsNotActive('media');
124
125
        $filesPath = $this->getParameter('files_path');
126
127
        $this->getDocument()->clickLink('Add');
128
129
        $imageForm = $this->getLastImageElement();
130
        if (null !== $type) {
131
            $imageForm->fillField('Type', $type);
132
        }
133
134
        $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path);
135
    }
136
137
    public function associateProducts(ProductAssociationTypeInterface $productAssociationType, array $productsNames): void
138
    {
139
        $this->clickTab('associations');
140
141
        $dropdown = $this->getElement('association_dropdown', [
142
            '%association%' => $productAssociationType->getName(),
143
        ]);
144
        $dropdown->click();
145
146
        foreach ($productsNames as $productName) {
147
            $dropdown->waitFor(5, function () use ($productName, $productAssociationType) {
148
                return $this->hasElement('association_dropdown_item', [
149
                    '%association%' => $productAssociationType->getName(),
150
                    '%item%' => $productName,
151
                ]);
152
            });
153
154
            $item = $this->getElement('association_dropdown_item', [
155
                '%association%' => $productAssociationType->getName(),
156
                '%item%' => $productName,
157
            ]);
158
            $item->click();
159
        }
160
    }
161
162
    public function removeAssociatedProduct(string $productName, ProductAssociationTypeInterface $productAssociationType): void
163
    {
164
        $this->clickTabIfItsNotActive('associations');
165
166
        $item = $this->getElement('association_dropdown_item_selected', [
167
            '%association%' => $productAssociationType->getName(),
168
            '%item%' => $productName,
169
        ]);
170
        $item->find('css', 'i.delete')->click();
171
    }
172
173
    public function choosePricingCalculator(string $name): void
174
    {
175
        $this->getElement('price_calculator')->selectOption($name);
176
    }
177
178
    public function checkChannel(string $channelName): void
179
    {
180
        $this->getElement('channel_checkbox', ['%channelName%' => $channelName])->check();
181
    }
182
183
    public function activateLanguageTab(string $locale): void
184
    {
185
        if (!$this->getDriver() instanceof Selenium2Driver && !$this->getDriver() instanceof ChromeDriver) {
0 ignored issues
show
Bug introduced by
The class DMore\ChromeDriver\ChromeDriver does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
186
            return;
187
        }
188
189
        $languageTabTitle = $this->getElement('language_tab', ['%locale%' => $locale]);
190
        if (!$languageTabTitle->hasClass('active')) {
191
            $languageTabTitle->click();
192
        }
193
    }
194
195
    public function selectShippingCategory(string $shippingCategoryName): void
196
    {
197
        $this->getElement('shipping_category')->selectOption($shippingCategoryName);
198
    }
199
200
    public function setShippingRequired(bool $isShippingRequired): void
201
    {
202
        if ($isShippingRequired) {
203
            $this->getElement('shipping_required')->check();
204
205
            return;
206
        }
207
208
        $this->getElement('shipping_required')->uncheck();
209
    }
210
211
    protected function getElement(string $name, array $parameters = []): NodeElement
212
    {
213
        if (!isset($parameters['%locale%'])) {
214
            $parameters['%locale%'] = 'en_US';
215
        }
216
217
        return parent::getElement($name, $parameters);
218
    }
219
220
    protected function getDefinedElements(): array
221
    {
222
        return array_merge(parent::getDefinedElements(), [
223
            'association_dropdown' => '.field > label:contains("%association%") ~ .product-select',
224
            'association_dropdown_item' => '.field > label:contains("%association%") ~ .product-select > div.menu > div.item:contains("%item%")',
225
            'association_dropdown_item_selected' => '.field > label:contains("%association%") ~ .product-select > a.label:contains("%item%")',
226
            'attribute' => '.attribute',
227
            'attribute_delete_button' => '.tab[data-tab="%localeCode%"] .attribute .label:contains("%attributeName%") ~ button',
228
            'attribute_value' => '.tab[data-tab="%localeCode%"] .attribute .label:contains("%attributeName%") ~ input',
229
            'attributes_choice' => '#sylius_product_attribute_choice',
230
            'channel_checkbox' => '.checkbox:contains("%channelName%") input',
231
            'channel_pricings' => '#sylius_product_variant_channelPricings',
232
            'code' => '#sylius_product_code',
233
            'form' => 'form[name="sylius_product"]',
234
            'images' => '#sylius_product_images',
235
            'language_tab' => '[data-locale="%locale%"] .title',
236
            'locale_tab' => '#attributesContainer .menu [data-tab="%localeCode%"]',
237
            'main_taxon' => '#sylius_product_mainTaxon',
238
            'name' => '#sylius_product_translations_%locale%_name',
239
            'price' => '#sylius_product_variant_channelPricings > .field:contains("%channelName%") input[name$="[price]"]',
240
            'original_price' => '#sylius_product_variant_channelPricings > .field:contains("%channelName%") input[name$="[originalPrice]"]',
241
            'price_calculator' => '#sylius_product_variant_pricingCalculator',
242
            'shipping_category' => '#sylius_product_variant_shippingCategory',
243
            'shipping_required' => '#sylius_product_variant_shippingRequired',
244
            'slug' => '#sylius_product_translations_%locale%_slug',
245
            'tab' => '.menu [data-tab="%name%"]',
246
            'taxonomy' => 'a[data-tab="taxonomy"]',
247
            'toggle_slug_modification_button' => '.toggle-product-slug-modification',
248
        ]);
249
    }
250
251
    private function openTaxonBookmarks(): void
252
    {
253
        $this->getElement('taxonomy')->click();
254
    }
255
256
    private function selectElementFromAttributesDropdown(string $id): void
257
    {
258
        $this->getDriver()->executeScript('$(\'#sylius_product_attribute_choice\').dropdown(\'show\');');
259
        $this->getDriver()->executeScript(sprintf('$(\'#sylius_product_attribute_choice\').dropdown(\'set selected\', \'%s\');', $id));
260
    }
261
262
    private function waitForFormElement(int $timeout = 5): void
263
    {
264
        $form = $this->getElement('form');
265
        $this->getDocument()->waitFor($timeout, function () use ($form) {
266
            return false === strpos($form->getAttribute('class'), 'loading');
267
        });
268
    }
269
270
    private function clickTabIfItsNotActive(string $tabName): void
271
    {
272
        $attributesTab = $this->getElement('tab', ['%name%' => $tabName]);
273
        if (!$attributesTab->hasClass('active')) {
274
            $attributesTab->click();
275
        }
276
    }
277
278
    private function clickTab(string $tabName): void
279
    {
280
        $attributesTab = $this->getElement('tab', ['%name%' => $tabName]);
281
        $attributesTab->click();
282
    }
283
284
    private function clickLocaleTabIfItsNotActive(string $localeCode): void
285
    {
286
        $localeTab = $this->getElement('locale_tab', ['%localeCode%' => $localeCode]);
287
        if (!$localeTab->hasClass('active')) {
288
            $localeTab->click();
289
        }
290
    }
291
292
    private function getLastImageElement(): NodeElement
293
    {
294
        $images = $this->getElement('images');
295
        $items = $images->findAll('css', 'div[data-form-collection="item"]');
296
297
        Assert::notEmpty($items);
298
299
        return end($items);
300
    }
301
}
302