Completed
Push — master ( 895a98...92e5e6 )
by Kamil
12:13 queued 06:44
created

iShouldSeeTheProductOriginalPrice()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
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\Context\Ui\Shop;
15
16
use Behat\Behat\Context\Context;
17
use Behat\Mink\Element\NodeElement;
18
use Sylius\Behat\Page\ErrorPageInterface;
19
use Sylius\Behat\Page\Shop\Product\IndexPageInterface;
20
use Sylius\Behat\Page\Shop\Product\ShowPageInterface;
21
use Sylius\Behat\Page\Shop\ProductReview\IndexPageInterface as ProductReviewIndexPageInterface;
22
use Sylius\Component\Core\Model\ProductInterface;
23
use Sylius\Component\Core\Model\TaxonInterface;
24
use Webmozart\Assert\Assert;
25
26
final class ProductContext implements Context
27
{
28
    /** @var ShowPageInterface */
29
    private $showPage;
30
31
    /** @var IndexPageInterface */
32
    private $indexPage;
33
34
    /** @var ProductReviewIndexPageInterface */
35
    private $productReviewsIndexPage;
36
37
    /** @var ErrorPageInterface */
38
    private $errorPage;
39
40
    public function __construct(
41
        ShowPageInterface $showPage,
42
        IndexPageInterface $indexPage,
43
        ProductReviewIndexPageInterface $productReviewsIndexPage,
44
        ErrorPageInterface $errorPage
45
    ) {
46
        $this->showPage = $showPage;
47
        $this->indexPage = $indexPage;
48
        $this->productReviewsIndexPage = $productReviewsIndexPage;
49
        $this->errorPage = $errorPage;
50
    }
51
52
    /**
53
     * @Then I should be able to access product :product
54
     */
55
    public function iShouldBeAbleToAccessProduct(ProductInterface $product)
56
    {
57
        $this->showPage->tryToOpen(['slug' => $product->getSlug()]);
58
59
        Assert::true($this->showPage->isOpen(['slug' => $product->getSlug()]));
60
    }
61
62
    /**
63
     * @Then I should not be able to access product :product
64
     */
65
    public function iShouldNotBeAbleToAccessProduct(ProductInterface $product)
66
    {
67
        $this->showPage->tryToOpen(['slug' => $product->getSlug()]);
68
69
        Assert::false($this->showPage->isOpen(['slug' => $product->getSlug()]));
70
    }
71
72
    /**
73
     * @When /^I check (this product)'s details$/
74
     * @When /^I check (this product)'s details in the ("([^"]+)" locale)$/
75
     * @When I view product :product
76
     * @When I view product :product in the :localeCode locale
77
     */
78
    public function iOpenProductPage(ProductInterface $product, $localeCode = 'en_US')
79
    {
80
        $this->showPage->open(['slug' => $product->getTranslation($localeCode)->getSlug(), '_locale' => $localeCode]);
81
    }
82
83
    /**
84
     * @When /^I try to check (this product)'s details in the ("([^"]+)" locale)$/
85
     */
86
    public function iTryToOpenProductPage(ProductInterface $product, $localeCode = 'en_US')
87
    {
88
        $this->showPage->tryToOpen([
89
            'slug' => $product->getTranslation($localeCode)->getSlug(),
90
            '_locale' => $localeCode,
91
        ]);
92
    }
93
94
    /**
95
     * @When I try to reach unexistent product
96
     */
97
    public function iTryToReachUnexistentProductPage($localeCode = 'en_US')
98
    {
99
        $this->showPage->tryToOpen([
100
            'slug' => 'unexisten_product',
101
            '_locale' => $localeCode,
102
        ]);
103
    }
104
105
    /**
106
     * @Then /^I should not be able to view (this product) in the ("([^"]+)" locale)$/
107
     */
108
    public function iShouldNotBeAbleToViewThisProductInLocale(ProductInterface $product, $localeCode = 'en_US')
109
    {
110
        Assert::false(
111
            $this->showPage->isOpen([
112
                'slug' => $product->getTranslation($localeCode)->getSlug(),
113
                '_locale' => $localeCode,
114
            ])
115
        );
116
    }
117
118
    /**
119
     * @Then I should see the product name :name
120
     */
121
    public function iShouldSeeProductName($name)
122
    {
123
        Assert::same($this->showPage->getName(), $name);
124
    }
125
126
    /**
127
     * @When I open page :url
128
     */
129
    public function iOpenPage($url)
130
    {
131
        $this->showPage->visit($url);
132
    }
133
134
    /**
135
     * @Then I should be on :product product detailed page
136
     * @Then I should still be on product :product page
137
     */
138
    public function iShouldBeOnProductDetailedPage(ProductInterface $product)
139
    {
140
        Assert::true($this->showPage->isOpen(['slug' => $product->getSlug()]));
141
    }
142
143
    /**
144
     * @Then I should (also) see the product attribute :attributeName with value :expectedAttribute
145
     */
146
    public function iShouldSeeTheProductAttributeWithValue($attributeName, $expectedAttribute)
147
    {
148
        Assert::same($this->showPage->getAttributeByName($attributeName), $expectedAttribute);
149
    }
150
151
    /**
152
     * @Then I should not see the product attribute :attributeName
153
     */
154
    public function iShouldNotSeeTheProductAttribute(string $attributeName): void
155
    {
156
        $this->showPage->getAttributeByName($attributeName);
157
    }
158
159
    /**
160
     * @Then I should (also) see the product attribute :attributeName with date :expectedAttribute
161
     */
162
    public function iShouldSeeTheProductAttributeWithDate($attributeName, $expectedAttribute)
163
    {
164
        Assert::eq(
165
            new \DateTime($this->showPage->getAttributeByName($attributeName)),
166
            new \DateTime($expectedAttribute)
167
        );
168
    }
169
170
    /**
171
     * @Then I should see :count attributes
172
     */
173
    public function iShouldSeeAttributes($count)
174
    {
175
        Assert::same(count($this->getProductAttributes()), (int) $count);
176
    }
177
178
    /**
179
     * @Then the first attribute should be :name
180
     */
181
    public function theFirstAttributeShouldBe($name)
182
    {
183
        $attributes = $this->getProductAttributes();
184
185
        Assert::same(reset($attributes)->getText(), $name);
186
    }
187
188
    /**
189
     * @Then the last attribute should be :name
190
     */
191
    public function theLastAttributeShouldBe($name)
192
    {
193
        $attributes = $this->getProductAttributes();
194
195
        Assert::same(end($attributes)->getText(), $name);
196
    }
197
198
    /**
199
     * @When /^I browse products from (taxon "([^"]+)")$/
200
     */
201
    public function iCheckListOfProductsForTaxon(TaxonInterface $taxon)
202
    {
203
        $this->indexPage->open(['slug' => $taxon->getSlug()]);
204
    }
205
206
    /**
207
     * @When I search for products with name :name
208
     */
209
    public function iSearchForProductsWithName($name)
210
    {
211
        $this->indexPage->search($name);
212
    }
213
214
    /**
215
     * @When I sort products by the lowest price first
216
     */
217
    public function iSortProductsByTheLowestPriceFirst()
218
    {
219
        $this->indexPage->sort('Cheapest first');
220
    }
221
222
    /**
223
     * @When I sort products by the highest price first
224
     */
225
    public function iSortProductsByTheHighestPriceFisrt()
226
    {
227
        $this->indexPage->sort('Most expensive first');
228
    }
229
230
    /**
231
     * @When I sort products alphabetically from a to z
232
     */
233
    public function iSortProductsAlphabeticallyFromAToZ()
234
    {
235
        $this->indexPage->sort('From A to Z');
236
    }
237
238
    /**
239
     * @When I sort products alphabetically from z to a
240
     */
241
    public function iSortProductsAlphabeticallyFromZToA()
242
    {
243
        $this->indexPage->sort('From Z to A');
244
    }
245
246
    /**
247
     * @When I clear filter
248
     */
249
    public function iClearFilter()
250
    {
251
        $this->indexPage->clearFilter();
252
    }
253
254
    /**
255
     * @Then I should see the product :productName
256
     */
257
    public function iShouldSeeProduct($productName)
258
    {
259
        Assert::true($this->indexPage->isProductOnList($productName));
260
    }
261
262
    /**
263
     * @Then I should not see the product :productName
264
     */
265
    public function iShouldNotSeeProduct($productName)
266
    {
267
        Assert::false($this->indexPage->isProductOnList($productName));
268
    }
269
270
    /**
271
     * @Then I should see empty list of products
272
     */
273
    public function iShouldSeeEmptyListOfProducts()
274
    {
275
        Assert::true($this->indexPage->isEmpty());
276
    }
277
278
    /**
279
     * @Then I should see that it is out of stock
280
     */
281
    public function iShouldSeeItIsOutOfStock()
282
    {
283
        Assert::true($this->showPage->isOutOfStock());
284
    }
285
286
    /**
287
     * @Then I should be unable to add it to the cart
288
     */
289
    public function iShouldBeUnableToAddItToTheCart()
290
    {
291
        Assert::false($this->showPage->hasAddToCartButton());
292
    }
293
294
    /**
295
     * @Then the product price should be :price
296
     * @Then I should see the product price :price
297
     */
298
    public function iShouldSeeTheProductPrice($price)
299
    {
300
        Assert::same($this->showPage->getPrice(), $price);
301
    }
302
303
    /**
304
     * @Then the product original price should be :price
305
     * @Then I should see the product original price :price
306
     */
307
    public function iShouldSeeTheProductOriginalPrice($price)
308
    {
309
        Assert::same($this->showPage->getOriginalPrice(), $price);
310
    }
311
312
    /**
313
     * @When I set its :optionName to :optionValue
314
     */
315
    public function iSetItsOptionTo($optionName, $optionValue)
316
    {
317
        $this->showPage->selectOption($optionName, $optionValue);
318
    }
319
320
    /**
321
     * @When I select :variantName variant
322
     */
323
    public function iSelectVariant($variantName)
324
    {
325
        $this->showPage->selectVariant($variantName);
326
    }
327
328
    /**
329
     * @Then its current variant should be named :name
330
     */
331
    public function itsCurrentVariantShouldBeNamed($name)
332
    {
333
        Assert::same($this->showPage->getCurrentVariantName(), $name);
334
    }
335
336
    /**
337
     * @Then I should see the product :productName with price :productPrice
338
     */
339
    public function iShouldSeeTheProductWithPrice($productName, $productPrice)
340
    {
341
        Assert::same($this->indexPage->getProductPrice($productName), $productPrice);
342
    }
343
344
    /**
345
     * @Then /^I should be notified that (this product) does not have sufficient stock$/
346
     */
347
    public function iShouldBeNotifiedThatThisProductDoesNotHaveSufficientStock(ProductInterface $product)
348
    {
349
        Assert::true($this->showPage->hasProductOutOfStockValidationMessage($product));
350
    }
351
352
    /**
353
     * @Then /^I should not be notified that (this product) does not have sufficient stock$/
354
     */
355
    public function iShouldNotBeNotifiedThatThisProductDoesNotHaveSufficientStock(ProductInterface $product)
356
    {
357
        Assert::false($this->showPage->hasProductOutOfStockValidationMessage($product));
358
    }
359
360
    /**
361
     * @Then I should see a main image
362
     */
363
    public function iShouldSeeAMainImage()
364
    {
365
        Assert::true($this->showPage->isMainImageDisplayed());
366
    }
367
368
    /**
369
     * @When /^I view (oldest|newest) products from (taxon "([^"]+)")$/
370
     */
371
    public function iViewSortedProductsFromTaxon($sortDirection, TaxonInterface $taxon)
372
    {
373
        $sorting = ['createdAt' => 'oldest' === $sortDirection ? 'asc' : 'desc'];
374
375
        $this->indexPage->open(['slug' => $taxon->getSlug(), 'sorting' => $sorting]);
376
    }
377
378
    /**
379
     * @Then I should see :numberOfProducts products in the list
380
     */
381
    public function iShouldSeeProductsInTheList($numberOfProducts)
382
    {
383
        Assert::same($this->indexPage->countProductsItems(), (int) $numberOfProducts);
384
    }
385
386
    /**
387
     * @Then I should see a product with name :name
388
     */
389
    public function iShouldSeeProductWithName($name)
390
    {
391
        Assert::true($this->indexPage->isProductOnPageWithName($name));
392
    }
393
394
    /**
395
     * @Then the first product on the list should have name :name
396
     */
397
    public function theFirstProductOnTheListShouldHaveName($name)
398
    {
399
        Assert::same($this->indexPage->getFirstProductNameFromList(), $name);
400
    }
401
402
    /**
403
     * @Then the first product on the list should have name :name and price :price
404
     */
405
    public function theFirstProductOnTheListShouldHaveNameAndPrice($name, $price)
406
    {
407
        Assert::same($this->indexPage->getFirstProductNameFromList(), $name);
408
        Assert::same($this->indexPage->getProductPrice($name), $price);
409
    }
410
411
    /**
412
     * @Then the last product on the list should have name :name
413
     */
414
    public function theLastProductOnTheListShouldHaveName($name)
415
    {
416
        Assert::same($this->indexPage->getLastProductNameFromList(), $name);
417
    }
418
419
    /**
420
     * @Then the last product on the list should have name :name and price :price
421
     */
422
    public function theLastProductOnTheListShouldHaveNameAndPrice($name, $price)
423
    {
424
        Assert::same($this->indexPage->getLastProductNameFromList(), $name);
425
        Assert::same($this->indexPage->getProductPrice($name), $price);
426
    }
427
428
    /**
429
     * @Then I should see :count product reviews
430
     */
431
    public function iShouldSeeProductReviews($count)
432
    {
433
        Assert::same($this->showPage->countReviews(), (int) $count);
434
    }
435
436
    /**
437
     * @Then I should see reviews titled :firstReview, :secondReview and :thirdReview
438
     */
439
    public function iShouldSeeReviewsTitled(...$reviews)
440
    {
441
        foreach ($reviews as $review) {
442
            Assert::true(
443
                $this->showPage->hasReviewTitled($review),
444
                sprintf('Product should have review titled "%s" but it does not.', $review)
445
            );
446
        }
447
    }
448
449
    /**
450
     * @Then I should not see review titled :title
451
     */
452
    public function iShouldNotSeeReviewTitled($title)
453
    {
454
        Assert::false($this->showPage->hasReviewTitled($title));
455
    }
456
457
    /**
458
     * @When /^I check (this product)'s reviews$/
459
     */
460
    public function iCheckThisProductSReviews(ProductInterface $product)
461
    {
462
        $this->productReviewsIndexPage->open(['slug' => $product->getSlug()]);
463
    }
464
465
    /**
466
     * @Then /^I should see (\d+) product reviews in the list$/
467
     */
468
    public function iShouldSeeNumberOfProductReviewsInTheList($count)
469
    {
470
        Assert::same($this->productReviewsIndexPage->countReviews(), (int) $count);
471
    }
472
473
    /**
474
     * @Then I should not see review titled :title in the list
475
     */
476
    public function iShouldNotSeeReviewTitledInTheList($title)
477
    {
478
        Assert::false($this->productReviewsIndexPage->hasReviewTitled($title));
479
    }
480
481
    /**
482
     * @Then /^I should be notified that there are no reviews$/
483
     */
484
    public function iShouldBeNotifiedThatThereAreNoReviews()
485
    {
486
        Assert::true($this->productReviewsIndexPage->hasNoReviewsMessage());
487
    }
488
489
    /**
490
     * @Then I should see :rating as its average rating
491
     */
492
    public function iShouldSeeAsItsAverageRating($rating)
493
    {
494
        Assert::same($this->showPage->getAverageRating(), (float) $rating);
495
    }
496
497
    /**
498
     * @Then /^I should(?:| also) see the product association "([^"]+)" with (products "[^"]+" and "[^"]+")$/
499
     */
500
    public function iShouldSeeTheProductAssociationWithProducts($productAssociationName, array $products)
501
    {
502
        Assert::true(
503
            $this->showPage->hasAssociation($productAssociationName),
504
            sprintf('There should be an association named "%s" but it does not.', $productAssociationName)
505
        );
506
507
        foreach ($products as $product) {
508
            $this->assertProductIsInAssociation($product->getName(), $productAssociationName);
509
        }
510
    }
511
512
    /**
513
     * @Then /^average rating of (product "[^"]+") should be (\d+)$/
514
     */
515
    public function thisProductAverageRatingShouldBe(ProductInterface $product, $averageRating)
516
    {
517
        $this->showPage->tryToOpen(['slug' => $product->getSlug()]);
518
        $this->iShouldSeeAsItsAverageRating($averageRating);
519
    }
520
521
    /**
522
     * @Then they should have order like :firstProductName, :secondProductName and :thirdProductName
523
     */
524
    public function theyShouldHaveOrderLikeAnd(...$productNames)
525
    {
526
        Assert::true($this->indexPage->hasProductsInOrder($productNames));
527
    }
528
529
    /**
530
     * @Then I should be informed that the product does not exist
531
     */
532
    public function iShouldBeInformedThatTheProductDoesNotExist()
533
    {
534
        Assert::eq($this->errorPage->getTitle(), 'The "product" has not been found');
535
    }
536
537
    /**
538
     * @param string $productName
539
     * @param string $productAssociationName
540
     *
541
     * @throws \InvalidArgumentException
542
     */
543
    private function assertProductIsInAssociation($productName, $productAssociationName)
544
    {
545
        Assert::true(
546
            $this->showPage->hasProductInAssociation($productName, $productAssociationName),
547
            sprintf(
548
                'There should be an associated product "%s" under association "%s" but it does not.',
549
                $productName,
550
                $productAssociationName
551
            )
552
        );
553
    }
554
555
    /**
556
     * @return NodeElement[]
557
     *
558
     * @throws \InvalidArgumentException
559
     */
560
    private function getProductAttributes()
561
    {
562
        $attributes = $this->showPage->getAttributes();
563
        Assert::notNull($attributes, 'The product has no attributes.');
564
565
        return $attributes;
566
    }
567
}
568