Completed
Push — 1.3-make-js-behat-faster ( 85e122 )
by Kamil
09:41
created

ShowPage::tryToOpen()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.7
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\Shop\Product;
15
16
use Behat\Mink\Driver\Selenium2Driver;
17
use Behat\Mink\Exception\ElementNotFoundException;
18
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage;
19
use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException;
20
use Sylius\Behat\Service\JQueryHelper;
21
use Sylius\Component\Product\Model\ProductInterface;
22
use Sylius\Component\Product\Model\ProductOptionInterface;
23
use Webmozart\Assert\Assert;
24
25
class ShowPage extends SymfonyPage implements ShowPageInterface
26
{
27
    /**
28
     * {@inheritdoc}
29
     */
30
    public function getRouteName(): string
31
    {
32
        return 'sylius_shop_product_show';
33
    }
34
35
    /**
36
     * {@inheritdoc}
37
     */
38
    public function addToCart()
39
    {
40
        $this->getDocument()->pressButton('Add to cart');
41
42
        if ($this->getDriver() instanceof Selenium2Driver) {
43
            JQueryHelper::waitForAsynchronousActionsToFinish($this->getSession());
44
        }
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50
    public function addToCartWithQuantity($quantity)
51
    {
52
        $this->getDocument()->fillField('Quantity', $quantity);
53
        $this->getDocument()->pressButton('Add to cart');
54
55
        if ($this->getDriver() instanceof Selenium2Driver) {
56
            JQueryHelper::waitForAsynchronousActionsToFinish($this->getSession());
57
        }
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63
    public function addToCartWithVariant($variant)
64
    {
65
        $this->selectVariant($variant);
66
67
        $this->getDocument()->pressButton('Add to cart');
68
69
        if ($this->getDriver() instanceof Selenium2Driver) {
70
            JQueryHelper::waitForAsynchronousActionsToFinish($this->getSession());
71
        }
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77
    public function addToCartWithOption(ProductOptionInterface $option, $optionValue)
78
    {
79
        $select = $this->getDocument()->find('css', sprintf('select#sylius_add_to_cart_cartItem_variant_%s', $option->getCode()));
80
81
        $this->getDocument()->selectFieldOption($select->getAttribute('name'), $optionValue);
82
        $this->getDocument()->pressButton('Add to cart');
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88
    public function visit($url)
89
    {
90
        $absoluteUrl = $this->makePathAbsolute($url);
91
        $this->getDriver()->visit($absoluteUrl);
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     */
97
    public function getName()
98
    {
99
        return $this->getElement('name')->getText();
100
    }
101
102
    /**
103
     * {@inheritdoc}
104
     */
105
    public function getCurrentVariantName()
106
    {
107
        $currentVariantRow = $this->getElement('current_variant_input')->getParent()->getParent();
108
109
        return $currentVariantRow->find('css', 'td:first-child')->getText();
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115
    public function getAttributeByName(string $name): ?string
116
    {
117
        $attributesTable = $this->getElement('attributes');
118
119
        $driver = $this->getDriver();
120
        if ($driver instanceof Selenium2Driver) {
121
            try {
122
                $attributesTab = $this->getElement('tab', ['%name%' => 'attributes']);
123
                if (!$attributesTab->hasClass('active')) {
124
                    $attributesTab->click();
125
                }
126
            } catch (ElementNotFoundException $exception) {
0 ignored issues
show
Bug introduced by
The class Behat\Mink\Exception\ElementNotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
127
                return null;
128
            }
129
        }
130
131
        $nameTdSelector = sprintf('tr > td.sylius-product-attribute-name:contains("%s")', $name);
132
        $nameTd = $attributesTable->find('css', $nameTdSelector);
133
134
        if (null === $nameTd) {
135
            return null;
136
        }
137
138
        $row = $nameTd->getParent();
139
140
        return trim($row->find('css', 'td.sylius-product-attribute-value')->getText());
141
    }
142
143
    /**
144
     * {@inheritdoc}
145
     */
146
    public function getAttributes()
147
    {
148
        $attributesTable = $this->getElement('attributes');
149
150
        return $attributesTable->findAll('css', 'tr > td.sylius-product-attribute-name');
151
    }
152
153
    /**
154
     * {@inheritdoc}
155
     */
156
    public function hasProductOutOfStockValidationMessage(ProductInterface $product)
157
    {
158
        $message = sprintf('%s does not have sufficient stock.', $product->getName());
159
160
        if (!$this->hasElement('validation_errors')) {
161
            return false;
162
        }
163
164
        return $this->getElement('validation_errors')->getText() === $message;
165
    }
166
167
    /**
168
     * {@inheritdoc}
169
     */
170
    public function waitForValidationErrors($timeout)
171
    {
172
        $errorsContainer = $this->getElement('selecting_variants');
173
174
        $this->getDocument()->waitFor($timeout, function () use ($errorsContainer) {
175
            return false !== $errorsContainer->has('css', '[class ~="sylius-validation-error"]');
176
        });
177
    }
178
179
    /**
180
     * {@inheritdoc}
181
     */
182
    public function getPrice()
183
    {
184
        return $this->getElement('product_price')->getText();
185
    }
186
187
    /**
188
     * {@inheritdoc}
189
     */
190
    public function countReviews()
191
    {
192
        return count($this->getElement('reviews')->findAll('css', '.comment'));
193
    }
194
195
    /**
196
     * {@inheritdoc}
197
     */
198
    public function hasReviewTitled($title)
199
    {
200
        return null !== $this->getElement('reviews')->find('css', sprintf('.comment:contains("%s")', $title));
201
    }
202
203
    /**
204
     * {@inheritdoc}
205
     */
206
    public function getAverageRating()
207
    {
208
        return (float) $this->getElement('average_rating')->getAttribute('data-average-rating');
209
    }
210
211
    /**
212
     * {@inheritdoc}
213
     */
214
    public function selectOption($optionName, $optionValue)
215
    {
216
        $optionElement = $this->getElement('option_select', ['%option-name%' => strtoupper($optionName)]);
217
        $optionElement->selectOption($optionValue);
218
    }
219
220
    /**
221
     * {@inheritdoc}
222
     */
223
    public function selectVariant($variantName)
224
    {
225
        $variantRadio = $this->getElement('variant_radio', ['%variant-name%' => $variantName]);
226
227
        $driver = $this->getDriver();
228
        if ($driver instanceof Selenium2Driver) {
229
            $variantRadio->click();
230
231
            return;
232
        }
233
234
        $this->getDocument()->fillField($variantRadio->getAttribute('name'), $variantRadio->getAttribute('value'));
235
    }
236
237
    /**
238
     * {@inheritdoc}
239
     */
240
    public function isOutOfStock()
241
    {
242
        return $this->hasElement('out_of_stock');
243
    }
244
245
    /**
246
     * {@inheritdoc}
247
     */
248
    public function hasAddToCartButton()
249
    {
250
        return $this->getDocument()->hasButton('Add to cart')
251
            && false === $this->getDocument()->findButton('Add to cart')->hasAttribute('disabled');
252
    }
253
254
    /**
255
     * {@inheritdoc}
256
     */
257
    public function isMainImageDisplayed()
258
    {
259
        $imageElement = $this->getElement('main_image');
260
261
        if (null === $imageElement) {
262
            return false;
263
        }
264
265
        $imageUrl = $imageElement->getAttribute('src');
266
        $this->getDriver()->visit($imageUrl);
267
        $pageText = $this->getDocument()->getText();
268
        $this->getDriver()->back();
269
270
        return false === stripos($pageText, '404 Not Found');
271
    }
272
273
    /**
274
     * {@inheritdoc}
275
     */
276
    public function hasAssociation($productAssociationName)
277
    {
278
        return $this->hasElement('association', ['%association-name%' => $productAssociationName]);
279
    }
280
281
    /**
282
     * {@inheritdoc}
283
     */
284
    public function hasProductInAssociation($productName, $productAssociationName)
285
    {
286
        $products = $this->getElement('association', ['%association-name%' => $productAssociationName]);
287
288
        Assert::notNull($products);
289
290
        return null !== $products->find('css', sprintf('.sylius-product-name:contains("%s")', $productName));
291
    }
292
293
    /**
294
     * {@inheritdoc}
295
     */
296
    public function tryToOpen(array $urlParameters = []): void
297
    {
298
        if ($this->getDriver() instanceof Selenium2Driver) {
299
            $start = microtime(true);
300
            $end = $start + 5;
301
302
            parent::tryToOpen($urlParameters);
303
304
            while (!$this->isOpen() && microtime(true) < $end) {
305
                usleep(300 * 1000);
306
            }
307
308
            return;
309
        }
310
311
        parent::tryToOpen($urlParameters);
312
    }
313
314
    /**
315
     * {@inheritdoc}
316
     */
317
    protected function getDefinedElements(): array
318
    {
319
        return array_merge(parent::getDefinedElements(), [
320
            'association' => '#sylius-product-association-%association-name%',
321
            'attributes' => '#sylius-product-attributes',
322
            'average_rating' => '#average-rating',
323
            'current_variant_input' => '#sylius-product-variants td input:checked',
324
            'main_image' => '#main-image',
325
            'name' => '#sylius-product-name',
326
            'option_select' => '#sylius_add_to_cart_cartItem_variant_%option-name%',
327
            'out_of_stock' => '#sylius-product-out-of-stock',
328
            'product_price' => '#product-price',
329
            'reviews' => '[data-tab="reviews"] .comments',
330
            'selecting_variants' => '#sylius-product-selecting-variant',
331
            'tab' => '.menu [data-tab="%name%"]',
332
            'validation_errors' => '.sylius-validation-error',
333
            'variant_radio' => '#sylius-product-variants tbody tr:contains("%variant-name%") input',
334
        ]);
335
    }
336
}
337