Completed
Push — master ( 8fac40...c170a7 )
by Kamil
42:58
created

CreatePage::selectAutocompleteValue()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 32
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 17
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
namespace Sylius\Behat\Page\Admin\Promotion;
13
14
use Behat\Mink\Driver\Selenium2Driver;
15
use Behat\Mink\Element\NodeElement;
16
use Behat\Mink\Exception\ElementNotFoundException;
17
use Sylius\Behat\Behaviour\NamesIt;
18
use Sylius\Behat\Behaviour\SpecifiesItsCode;
19
use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
20
use Webmozart\Assert\Assert;
21
22
/**
23
 * @author Mateusz Zalewski <[email protected]>
24
 * @author Łuksaz Zalewski <[email protected]>
25
 */
26
class CreatePage extends BaseCreatePage implements CreatePageInterface
27
{
28
    use NamesIt;
29
    use SpecifiesItsCode;
30
31
    /**
32
     * {@inheritdoc}
33
     */
34
    public function addRule($ruleName)
35
    {
36
        $count = count($this->getCollectionItems('rules'));
37
38
        $this->getDocument()->clickLink('Add rule');
39
40
        $this->getDocument()->waitFor(5, function () use ($count) {
41
            return $count + 1 === count($this->getCollectionItems('rules'));
42
        });
43
44
        $this->selectRuleOption('Type', $ruleName);
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50
    public function selectRuleOption($option, $value, $multiple = false)
51
    {
52
        $this->getLastCollectionItem('rules')->find('named', array('select', $option))->selectOption($value, $multiple);
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58
    public function selectAutocompleteRuleOption($option, $value, $multiple = false)
59
    {
60
        $option = strtolower(str_replace(' ', '_', $option));
61
62
        $ruleAutoComplete = $this
63
            ->getLastCollectionItem('rules')
64
            ->find('css', sprintf('input[type="hidden"][name*="[%s]"]', $option))
65
            ->getParent()
66
        ;
67
68
        $this->selectAutocompleteValue($ruleAutoComplete, $value);
69
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74
    public function fillRuleOption($option, $value)
75
    {
76
        $this->getLastCollectionItem('rules')->fillField($option, $value);
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82
    public function fillRuleOptionForChannel($channelName, $option, $value)
83
    {
84
        $lastAction = $this->getChannelConfigurationOfLastRule($channelName);
85
        $lastAction->fillField($option, $value);
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91
    public function addAction($actionName)
92
    {
93
        $count = count($this->getCollectionItems('actions'));
94
95
        $this->getDocument()->clickLink('Add action');
96
97
        $this->getDocument()->waitFor(5, function () use ($count) {
98
            return $count + 1 === count($this->getCollectionItems('actions'));
99
        });
100
101
        $this->selectActionOption('Type', $actionName);
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function selectActionOption($option, $value, $multiple = false)
108
    {
109
        $this->getLastCollectionItem('actions')->find('named', array('select', $option))->selectOption($value, $multiple);
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115
    public function fillActionOption($option, $value)
116
    {
117
        $this->getLastCollectionItem('actions')->fillField($option, $value);
118
    }
119
120
    /**
121
     * {@inheritdoc}
122
     */
123
    public function fillActionOptionForChannel($channelName, $option, $value)
124
    {
125
        $lastAction = $this->getChannelConfigurationOfLastAction($channelName);
126
        $lastAction->fillField($option, $value);
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     */
132
    public function fillUsageLimit($limit)
133
    {
134
        $this->getDocument()->fillField('Usage limit', $limit);
135
    }
136
137
    public function makeExclusive()
138
    {
139
        $this->getDocument()->checkField('Exclusive');
140
    }
141
142
    public function checkCouponBased()
143
    {
144
        $this->getDocument()->checkField('Coupon based');
145
    }
146
147
    public function checkChannel($name)
148
    {
149
        $this->getDocument()->checkField($name);
150
    }
151
152
    /**
153
     * {@inheritdoc}
154
     */
155
    public function setStartsAt(\DateTime $dateTime)
156
    {
157
        $timestamp = $dateTime->getTimestamp();
158
159
        $this->getDocument()->fillField('sylius_promotion_startsAt_date', date('Y-m-d', $timestamp));
160
        $this->getDocument()->fillField('sylius_promotion_startsAt_time', date('H:i', $timestamp));
161
    }
162
163
    /**
164
     * {@inheritdoc}
165
     */
166
    public function setEndsAt(\DateTime $dateTime)
167
    {
168
        $timestamp = $dateTime->getTimestamp();
169
170
        $this->getDocument()->fillField('sylius_promotion_endsAt_date', date('Y-m-d', $timestamp));
171
        $this->getDocument()->fillField('sylius_promotion_endsAt_time', date('H:i', $timestamp));
172
    }
173
174
    /**
175
     * {@inheritdoc}
176
     */
177
    public function getValidationMessageForAction()
178
    {
179
        $actionForm = $this->getLastCollectionItem('actions');
180
181
        $foundElement = $actionForm->find('css', '.sylius-validation-error');
182
        if (null === $foundElement) {
183
            throw new ElementNotFoundException($this->getSession(), 'Tag', 'css', '.sylius-validation-error');
184
        }
185
186
        return $foundElement->getText();
187
    }
188
189
    /**
190
     * {@inheritdoc}
191
     */
192
    public function selectAutoCompleteFilterOption($option, $value, $multiple = false)
193
    {
194
        $option = strtolower(str_replace(' ', '_', $option));
195
196
        $filterAutoComplete = $this
197
            ->getLastCollectionItem('actions')
198
            ->find('css', sprintf('input[type="hidden"][name*="[%s_filter]"]', $option))
199
            ->getParent()
200
        ;
201
202
        $this->selectAutocompleteValue($filterAutoComplete, $value);
203
    }
204
205
    /**
206
     * {@inheritdoc}
207
     */
208
    protected function getDefinedElements()
209
    {
210
        return [
211
            'actions' => '#sylius_promotion_actions',
212
            'code' => '#sylius_promotion_code',
213
            'ends_at' => '#sylius_promotion_endsAt',
214
            'minimum' => '#sylius_promotion_actions_0_configuration_WEB-US_filters_price_range_filter_min',
215
            'maximum' => '#sylius_promotion_actions_0_configuration_WEB-US_filters_price_range_filter_max',
216
            'name' => '#sylius_promotion_name',
217
            'rules' => '#sylius_promotion_rules',
218
            'starts_at' => '#sylius_promotion_startsAt',
219
        ];
220
    }
221
222
    /**
223
     * @param string $channelName
224
     *
225
     * @return NodeElement
0 ignored issues
show
Documentation introduced by
Should the return type not be NodeElement|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
226
     */
227
    private function getChannelConfigurationOfLastAction($channelName)
228
    {
229
        return $this
230
            ->getLastCollectionItem('actions')
231
            ->find('css', sprintf('[id*="sylius_promotion_actions"] .configuration .field:contains("%s")', $channelName))
232
        ;
233
    }
234
235
    /**
236
     * @param string $channelName
237
     *
238
     * @return NodeElement
0 ignored issues
show
Documentation introduced by
Should the return type not be NodeElement|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
239
     */
240
    private function getChannelConfigurationOfLastRule($channelName)
241
    {
242
        return $this
243
            ->getLastCollectionItem('rules')
244
            ->find('css', sprintf('[id*="sylius_promotion_rules"] .configuration .field:contains("%s")', $channelName))
245
        ;
246
    }
247
248
    /**
249
     * @param string $collection
250
     *
251
     * @return NodeElement
252
     */
253
    private function getLastCollectionItem($collection)
254
    {
255
        $items = $this->getCollectionItems($collection);
256
257
        Assert::notEmpty($items);
258
259
        return end($items);
260
    }
261
262
    /**
263
     * @param string $collection
264
     *
265
     * @return NodeElement[]
266
     */
267
    private function getCollectionItems($collection)
268
    {
269
        $items = $this->getElement($collection)->findAll('css', 'div[data-form-collection="item"]');
270
271
        Assert::isArray($items);
272
273
        return $items;
274
    }
275
276
    /**
277
     * @param NodeElement $autocomplete
278
     * @param string $value
279
     */
280
    private function selectAutocompleteValue(NodeElement $autocomplete, $value)
281
    {
282
        Assert::isInstanceOf($this->getDriver(), Selenium2Driver::class);
283
284
        $isAnyAsyncActionInProgressScript = 'jQuery.active';
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $isAnyAsyncActionInProgressScript 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...
285
        $isVisibleScript = sprintf(
286
            '$(document.evaluate("%s", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue).dropdown("is visible")',
287
            $autocomplete->getXpath()
288
        );
289
290
        $this->getDocument()->waitFor(5, function () use ($isAnyAsyncActionInProgressScript) {
291
            return !(bool) $this->getDriver()->evaluateScript($isAnyAsyncActionInProgressScript);
292
        });
293
294
        $autocomplete->click();
295
296
        $this->getDocument()->waitFor(5, function () use ($isAnyAsyncActionInProgressScript) {
297
            return !(bool) $this->getDriver()->evaluateScript($isAnyAsyncActionInProgressScript);
298
        });
299
300
        $this->getDocument()->waitFor(5, function () use ($isVisibleScript) {
301
            return $this->getDriver()->evaluateScript($isVisibleScript);
302
        });
303
304
        $autocompleteItem = $autocomplete->find('css', sprintf('div.item:contains("%s")', $value));
305
306
        $autocompleteItem->click();
307
308
        $this->getDocument()->waitFor(5, function () use ($isVisibleScript) {
309
            return !$this->getDriver()->evaluateScript($isVisibleScript);
310
        });
311
    }
312
}
313