Completed
Push — master ( 7c0075...645752 )
by Kamil
18:52
created

ShowPage::hasAttributeWithValue()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
c 0
b 0
f 0
rs 9.4285
cc 2
eloc 8
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\Shop\Product;
13
14
use Behat\Mink\Driver\Selenium2Driver;
15
use Behat\Mink\Exception\ElementNotFoundException;
16
use Sylius\Behat\Page\SymfonyPage;
17
use Sylius\Component\Product\Model\ProductInterface;
18
use Sylius\Component\Product\Model\ProductOptionInterface;
19
use Webmozart\Assert\Assert;
20
21
/**
22
 * @author Arkadiusz Krakowiak <[email protected]>
23
 * @author Anna Walasek <[email protected]>
24
 */
25
class ShowPage extends SymfonyPage implements ShowPageInterface
26
{
27
    /**
28
     * {@inheritdoc}
29
     */
30
    public function getRouteName()
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
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function addToCartWithQuantity($quantity)
47
    {
48
        $this->getDocument()->fillField('Quantity', $quantity);
49
        $this->getDocument()->pressButton('Add to cart');
50
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55
    public function addToCartWithVariant($variant)
56
    {
57
        $this->selectVariant($variant);
58
59
        $this->getDocument()->pressButton('Add to cart');
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65
    public function addToCartWithOption(ProductOptionInterface $option, $optionValue)
66
    {
67
        $select = $this->getDocument()->find('css', sprintf('select#sylius_add_to_cart_cartItem_variant_%s', $option->getCode()));
68
69
        $this->getDocument()->selectFieldOption($select->getAttribute('name'), $optionValue);
70
        $this->getDocument()->pressButton('Add to cart');
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76
    public function visit($url)
77
    {
78
        $absoluteUrl = $this->makePathAbsolute($url);
79
        $this->getDriver()->visit($absoluteUrl);
80
    }
81
82
    /**
83
     * {@inheritdoc}
84
     */
85
    public function getName()
86
    {
87
        return $this->getElement('name')->getText();
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93
    public function getAttributeByName($name)
94
    {
95
        $tableWithAttributes = $this->getElement('attributes');
96
97
        $nameTdSelector = sprintf('tr > td.sylius-product-attribute-name:contains("%s")', $name);
98
        $nameTd = $tableWithAttributes->find('css', $nameTdSelector);
99
100
        if (null === $nameTd) {
101
            return false;
102
        }
103
104
        $row = $nameTd->getParent();
105
106
        return trim($row->find('css', 'td.sylius-product-attribute-value')->getText());
107
    }
108
109
    /**
110
     * {@inheritdoc}
111
     */
112
    public function hasProductOutOfStockValidationMessage(ProductInterface $product)
113
    {
114
        $message = sprintf('%s does not have sufficient stock.', $product->getName());
115
116
        if (!$this->hasElement('validation_errors')) {
117
            return false;
118
        }
119
120
        return $this->getElement('validation_errors')->getText() === $message;
121
    }
122
123
    /**
124
     * {@inheritdoc}
125
     */
126
    public function waitForValidationErrors($timeout)
127
    {
128
        $errorsContainer = $this->getElement('selecting_variants');
129
130
        $this->getDocument()->waitFor($timeout, function () use ($errorsContainer) {
131
            return false !== $errorsContainer->has('css', '[class ~="sylius-validation-error"]');
132
        });
133
    }
134
135
    /**
136
     * {@inheritdoc}
137
     */
138
    public function getPrice()
139
    {
140
        return $this->getElement('product_price')->getText();
141
    }
142
143
    /**
144
     * {@inheritdoc}
145
     */
146
    public function countReviews()
147
    {
148
        return count($this->getElement('reviews')->findAll('css', '.comment'));
149
    }
150
151
    /**
152
     * {@inheritdoc}
153
     */
154
    public function hasReviewTitled($title)
155
    {
156
        return null !== $this->getElement('reviews')->find('css', sprintf('.comment:contains("%s")', $title));
157
    }
158
159
    /**
160
     * {@inheritdoc}
161
     */
162
    public function getAverageRating()
163
    {
164
        return (float) $this->getElement('average_rating')->getAttribute('data-average-rating');
165
    }
166
167
    /**
168
     * {@inheritdoc}
169
     */
170
    public function selectOption($optionName, $optionValue)
171
    {
172
        $optionElement = $this->getElement('option_select', ['%option-name%' => strtoupper($optionName)]);
173
        $optionElement->selectOption($optionValue);
174
    }
175
176
    /**
177
     * {@inheritdoc}
178
     */
179
    public function selectVariant($variantName)
180
    {
181
        $variantRadio = $this->getElement('variant_radio', ['%variant-name%' => $variantName]);
182
183
        $driver = $this->getDriver();
184
        if ($driver instanceof Selenium2Driver) {
185
            $variantRadio->click();
186
187
            return;
188
        }
189
190
        $this->getDocument()->fillField($variantRadio->getAttribute('name'), $variantRadio->getAttribute('value'));
191
    }
192
193
    /**
194
     * {@inheritdoc}
195
     */
196
    public function isOutOfStock()
197
    {
198
        return $this->hasElement('out_of_stock');
199
    }
200
201
    /**
202
     * {@inheritdoc}
203
     */
204
    public function hasAddToCartButton()
205
    {
206
        return $this->getDocument()->hasButton('Add to cart');
207
    }
208
209
    /**
210
     * {@inheritdoc}
211
     */
212
    public function isMainImageDisplayed()
213
    {
214
        $imageElement = $this->getElement('main_image');
215
216
        if (null === $imageElement) {
217
            return false;
218
        }
219
220
        $imageUrl = $imageElement->getAttribute('src');
221
        $this->getDriver()->visit($imageUrl);
222
        $pageText = $this->getDocument()->getText();
223
        $this->getDriver()->back();
224
225
        return false === stripos($pageText, '404 Not Found');
226
    }
227
228
    /**
229
     * {@inheritdoc}
230
     */
231
    public function hasAssociation($productAssociationName)
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $productAssociationName 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...
232
    {
233
        return $this->hasElement('association', ['%association-name%' => $productAssociationName]);
234
    }
235
236
    /**
237
     * {@inheritdoc}
238
     */
239
    public function hasProductInAssociation($productName, $productAssociationName)
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $productAssociationName 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...
240
    {
241
        $associationHeader = $this->getElement('association', ['%association-name%' => $productAssociationName]);
242
        $associations = $associationHeader->getParent()->find('css', '.four');
243
244
        Assert::notNull($associations);
245
246
        return null !== $associations->find('css', sprintf('.sylius-product-name:contains("%s")', $productName));
247
    }
248
249
    /**
250
     * {@inheritdoc}
251
     */
252
    protected function getDefinedElements()
253
    {
254
        return array_merge(parent::getDefinedElements(), [
255
            'association' => 'h4:contains("%association-name%")',
256
            'attributes' => '#sylius-product-attributes',
257
            'average_rating' => '#average-rating',
258
            'main_image' => '#main-image',
259
            'name' => '#sylius-product-name',
260
            'option_select' => '#sylius_add_to_cart_cartItem_variant_%option-name%',
261
            'out_of_stock' => '#sylius-product-out-of-stock',
262
            'product_price' => '#product-price',
263
            'reviews' => '[data-tab="reviews"] .comments',
264
            'selecting_variants' => "#sylius-product-selecting-variant",
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal #sylius-product-selecting-variant does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
265
            'validation_errors' => '.sylius-validation-error',
266
            'variant_radio' => '#sylius-product-variants tbody tr:contains("%variant-name%") input',
267
        ]);
268
    }
269
}
270