Completed
Push — travis-xenial ( 84a270...92e80e )
by Kamil
26:32 queued 04:30
created

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