Completed
Push — travis-xenial ( c9786b...570728 )
by Kamil
05:21
created

ShowPage::addToCartWithOption()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
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
declare(strict_types=1);
13
14
namespace Sylius\Behat\Page\Shop\Product;
15
16
use Behat\Mink\Driver\Selenium2Driver;
17
use Behat\Mink\Element\NodeElement;
18
use Behat\Mink\Exception\ElementNotFoundException;
19
use DMore\ChromeDriver\ChromeDriver;
20
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage;
21
use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException;
22
use Sylius\Behat\Service\JQueryHelper;
23
use Sylius\Component\Product\Model\ProductInterface;
24
use Sylius\Component\Product\Model\ProductOptionInterface;
25
use Webmozart\Assert\Assert;
26
27
class ShowPage extends SymfonyPage implements ShowPageInterface
28
{
29
    public function getRouteName(): string
30
    {
31
        return 'sylius_shop_product_show';
32
    }
33
34
    public function addToCart(): void
35
    {
36
        $this->getElement('add_to_cart_button')->click();
37
38
        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...
39
            JQueryHelper::waitForAsynchronousActionsToFinish($this->getSession());
40
        }
41
    }
42
43
    public function addToCartWithQuantity(string $quantity): void
44
    {
45
        $this->getElement('quantity')->setValue($quantity);
46
        $this->getElement('add_to_cart_button')->click();
47
48
        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...
49
            JQueryHelper::waitForAsynchronousActionsToFinish($this->getSession());
50
        }
51
    }
52
53
    public function addToCartWithVariant(string $variant): void
54
    {
55
        $this->selectVariant($variant);
56
57
        $this->getElement('add_to_cart_button')->click();
58
59
        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...
60
            JQueryHelper::waitForAsynchronousActionsToFinish($this->getSession());
61
        }
62
    }
63
64
    public function addToCartWithOption(ProductOptionInterface $option, string $optionValue): void
65
    {
66
        $select = $this->getElement('option_select', ['%optionCode%' => $option->getCode()]);
67
68
        $this->getDocument()->selectFieldOption($select->getAttribute('name'), $optionValue);
69
        $this->getElement('add_to_cart_button')->click();
70
    }
71
72
    public function getAttributeByName(string $name): ?string
73
    {
74
        $attributesTable = $this->getElement('attributes');
75
76
        $driver = $this->getDriver();
77
        if ($driver instanceof Selenium2Driver || $driver 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...
78
            try {
79
                $attributesTab = $this->getElement('tab', ['%name%' => 'attributes']);
80
                if (!$attributesTab->hasAttribute('[data-test-active]')) {
81
                    $attributesTab->click();
82
                }
83
            } 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...
84
                return null;
85
            }
86
        }
87
88
        $nameTd = $attributesTable->find('css', sprintf('[data-test-product-attribute-name="%s"]', $name));
89
90
        if (null === $nameTd) {
91
            return null;
92
        }
93
94
        $row = $nameTd->getParent();
95
96
        return trim($row->find('css', '[data-test-product-attribute-value]')->getText());
97
    }
98
99
    public function getAttributes(): array
100
    {
101
        $attributesTable = $this->getElement('attributes');
102
103
        return $attributesTable->findAll('css', '[data-test-product-attribute-name]');
104
    }
105
106
    public function getAverageRating(): float
107
    {
108
        return (float) $this->getElement('average_rating')->getAttribute('data-test-average-rating');
109
    }
110
111
    public function getCurrentUrl(): string
112
    {
113
        return $this->getDriver()->getCurrentUrl();
114
    }
115
116
    public function getCurrentVariantName(): string
117
    {
118
        $currentVariantRow = $this->getElement('current_variant_input')->getParent()->getParent();
119
120
        return $currentVariantRow->find('css', 'td:first-child')->getText();
121
    }
122
123
    public function getName(): string
124
    {
125
        return $this->getElement('product_name')->getText();
126
    }
127
128
    public function getPrice(): string
129
    {
130
        return $this->getElement('product_price')->getText();
131
    }
132
133
    public function getOriginalPrice(): string
134
    {
135
        return $this->getElement('product_original_price')->getText();
136
    }
137
138
    public function hasAddToCartButton(): bool
139
    {
140
        if (!$this->hasElement('add_to_cart_button')) {
141
            return false;
142
        }
143
144
        return $this->getElement('add_to_cart_button') !== null && false === $this->getElement('add_to_cart_button')->hasAttribute('disabled');
145
    }
146
147
    public function hasAssociation(string $productAssociationName): bool
148
    {
149
        try {
150
            $this->getElement('association', ['%associationName%' => $productAssociationName]);
151
        } catch (ElementNotFoundException $e) {
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...
152
            return false;
153
        }
154
155
        return true;
156
    }
157
158
    public function hasProductInAssociation(string $productName, string $productAssociationName): bool
159
    {
160
        $products = $this->getElement('association', ['%associationName%' => $productAssociationName]);
161
162
        Assert::notNull($products);
163
164
        return $productName === $products->find('css', sprintf('[data-test-product-name="%s"]', $productName))->getText();
165
    }
166
167
    public function hasProductOutOfStockValidationMessage(ProductInterface $product): bool
168
    {
169
        $message = sprintf('%s does not have sufficient stock.', $product->getName());
170
171
        if (!$this->hasElement('validation_errors')) {
172
            return false;
173
        }
174
175
        return $this->getElement('validation_errors')->getText() === $message;
176
    }
177
178
    public function hasReviewTitled(string $title): bool
179
    {
180
        try {
181
            $element = $this->getElement('reviews_comment', ['%title%' => $title]);
182
        } catch (ElementNotFoundException $e) {
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...
183
            return false;
184
        }
185
186
        return $title === $element->getAttribute('data-test-comment');
187
    }
188
189
    public function isOutOfStock(): bool
190
    {
191
        return $this->hasElement('out_of_stock');
192
    }
193
194
    public function isMainImageDisplayed(): bool
195
    {
196
        if (!$this->hasElement('main_image')) {
197
            return false;
198
        }
199
200
        $imageUrl = $this->getElement('main_image')->getAttribute('src');
201
        $this->getDriver()->visit($imageUrl);
202
        $pageText = $this->getDocument()->getText();
203
        $this->getDriver()->back();
204
205
        return false === stripos($pageText, '404 Not Found');
206
    }
207
208
    public function countReviews(): int
209
    {
210
        return count($this->getElement('reviews')->findAll('css', '[data-test-comment]'));
211
    }
212
213
    public function selectOption(string $optionCode, string $optionValue): void
214
    {
215
        $optionElement = $this->getElement('option_select', ['%optionCode%' => strtoupper($optionCode)]);
216
        $optionElement->selectOption($optionValue);
217
    }
218
219
    public function selectVariant(string $variantName): void
220
    {
221
        $variantRadio = $this->getElement('variant_radio', ['%variantName%' => $variantName]);
222
223
        $driver = $this->getDriver();
224
        if ($driver instanceof Selenium2Driver || $driver 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...
225
            $variantRadio->click();
226
227
            return;
228
        }
229
230
        $this->getDocument()->fillField($variantRadio->getAttribute('name'), $variantRadio->getAttribute('value'));
231
    }
232
233
    public function visit($url): void
234
    {
235
        $absoluteUrl = $this->makePathAbsolute($url);
236
        $this->getDriver()->visit($absoluteUrl);
237
    }
238
239
    public function open(array $urlParameters = []): void
240
    {
241
        $start = microtime(true);
242
        $end = $start + 5;
243
        do {
244
            try {
245
                parent::open($urlParameters);
246
                $isOpen = true;
247
            } catch (UnexpectedPageException $exception) {
0 ignored issues
show
Bug introduced by
The class FriendsOfBehat\PageObjec...UnexpectedPageException 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...
248
                $isOpen = false;
249
                sleep(1);
250
            }
251
        } while (!$isOpen && microtime(true) < $end);
252
253
        if (!$isOpen) {
254
            throw new UnexpectedPageException();
255
        }
256
    }
257
258
    public function getVariantsNames(): array
259
    {
260
        $variantsNames = [];
261
        /** @var NodeElement $variantRow */
262
        foreach ($this->getElement('variants_rows')->findAll('css', 'td:first-child') as $variantRow) {
263
            $variantsNames[] = $variantRow->getText();
264
        }
265
266
        return $variantsNames;
267
    }
268
269
    public function getOptionValues(string $optionCode): array
270
    {
271
        $optionElement = $this->getElement('option_select', ['%optionCode%' => strtoupper($optionCode)]);
272
273
        return array_map(
274
            function (NodeElement $element) {
275
                return $element->getText();
276
            },
277
            $optionElement->findAll('css', 'option')
278
        );
279
    }
280
281
    protected function getDefinedElements(): array
282
    {
283
        return array_merge(parent::getDefinedElements(), [
284
            'add_to_cart_button' => '[data-test-add-to-cart-button]',
285
            'association' => '[data-test-product-association="%associationName%"]',
286
            'attributes' => '[data-test-product-attributes]',
287
            'average_rating' => '[data-test-average-rating]',
288
            'current_variant_input' => '[data-test-product-variants] td input:checked',
289
            'main_image' => '[data-test-main-image]',
290
            'name' => '[data-test-product-name]',
291
            'option_select' => '#sylius_add_to_cart_cartItem_variant_%optionCode%',
292
            'out_of_stock' => '[data-test-product-out-of-stock]',
293
            'product_price' => '[data-test-product-price]',
294
            'product_original_price' => '[data-test-product-original-price]',
295
            'product_name' => '[data-test-product-name]',
296
            'reviews' => '[data-test-product-reviews]',
297
            'reviews_comment' => '[data-test-comment="%title%"]',
298
            'selecting_variants' => '[data-test-product-selecting-variant]',
299
            'tab' => '[data-test-tab="%name%"]',
300
            'quantity' => '[data-test-quantity]',
301
            'validation_errors' => '[data-test-cart-validation-error]',
302
            'variant_radio' => '[data-test-product-variants] tbody tr:contains("%variantName%") input',
303
            'variants_rows' => '[data-test-product-variants-row]',
304
        ]);
305
    }
306
}
307