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\Exception\ElementNotFoundException; |
18
|
|
|
use Sylius\Behat\NotificationType; |
19
|
|
|
use Sylius\Behat\Page\Shop\Cart\SummaryPageInterface; |
20
|
|
|
use Sylius\Behat\Page\Shop\Product\ShowPageInterface; |
21
|
|
|
use Sylius\Behat\Service\NotificationCheckerInterface; |
22
|
|
|
use Sylius\Behat\Service\SharedStorageInterface; |
23
|
|
|
use Sylius\Component\Product\Model\ProductInterface; |
24
|
|
|
use Sylius\Component\Product\Model\ProductOptionInterface; |
25
|
|
|
use Webmozart\Assert\Assert; |
26
|
|
|
|
27
|
|
|
final class CartContext implements Context |
28
|
|
|
{ |
29
|
|
|
/** @var SharedStorageInterface */ |
30
|
|
|
private $sharedStorage; |
31
|
|
|
|
32
|
|
|
/** @var SummaryPageInterface */ |
33
|
|
|
private $summaryPage; |
34
|
|
|
|
35
|
|
|
/** @var ShowPageInterface */ |
36
|
|
|
private $productShowPage; |
37
|
|
|
|
38
|
|
|
/** @var NotificationCheckerInterface */ |
39
|
|
|
private $notificationChecker; |
40
|
|
|
|
41
|
|
|
public function __construct( |
42
|
|
|
SharedStorageInterface $sharedStorage, |
43
|
|
|
SummaryPageInterface $summaryPage, |
44
|
|
|
ShowPageInterface $productShowPage, |
45
|
|
|
NotificationCheckerInterface $notificationChecker |
46
|
|
|
) { |
47
|
|
|
$this->sharedStorage = $sharedStorage; |
48
|
|
|
$this->summaryPage = $summaryPage; |
49
|
|
|
$this->productShowPage = $productShowPage; |
50
|
|
|
$this->notificationChecker = $notificationChecker; |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* @When I see the summary of my cart |
55
|
|
|
*/ |
56
|
|
|
public function iOpenCartSummaryPage() |
57
|
|
|
{ |
58
|
|
|
$this->summaryPage->open(); |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* @When I update my cart |
63
|
|
|
*/ |
64
|
|
|
public function iUpdateMyCart() |
65
|
|
|
{ |
66
|
|
|
$this->summaryPage->updateCart(); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* @Then my cart should be empty |
71
|
|
|
* @Then cart should be empty with no value |
72
|
|
|
*/ |
73
|
|
|
public function iShouldBeNotifiedThatMyCartIsEmpty() |
74
|
|
|
{ |
75
|
|
|
$this->summaryPage->open(); |
76
|
|
|
|
77
|
|
|
Assert::true($this->summaryPage->isEmpty()); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* @Given I removed product :productName from the cart |
82
|
|
|
* @When I remove product :productName from the cart |
83
|
|
|
*/ |
84
|
|
|
public function iRemoveProductFromTheCart(string $productName): void |
85
|
|
|
{ |
86
|
|
|
$this->summaryPage->open(); |
87
|
|
|
$this->summaryPage->removeProduct($productName); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* @Given I change :productName quantity to :quantity |
92
|
|
|
*/ |
93
|
|
|
public function iChangeQuantityTo($productName, $quantity) |
94
|
|
|
{ |
95
|
|
|
$this->summaryPage->open(); |
96
|
|
|
$this->summaryPage->changeQuantity($productName, $quantity); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* @Then the grand total value should be :total |
101
|
|
|
* @Then my cart total should be :total |
102
|
|
|
*/ |
103
|
|
|
public function myCartTotalShouldBe($total) |
104
|
|
|
{ |
105
|
|
|
$this->summaryPage->open(); |
106
|
|
|
|
107
|
|
|
Assert::same($this->summaryPage->getGrandTotal(), $total); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* @Then the grand total value in base currency should be :total |
112
|
|
|
*/ |
113
|
|
|
public function myBaseCartTotalShouldBe($total) |
114
|
|
|
{ |
115
|
|
|
$this->summaryPage->open(); |
116
|
|
|
|
117
|
|
|
Assert::same($this->summaryPage->getBaseGrandTotal(), $total); |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* @Then my cart taxes should be :taxTotal |
122
|
|
|
*/ |
123
|
|
|
public function myCartTaxesShouldBe(string $taxTotal): void |
124
|
|
|
{ |
125
|
|
|
$this->summaryPage->open(); |
126
|
|
|
|
127
|
|
|
Assert::same($this->summaryPage->getExcludedTaxTotal(), $taxTotal); |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* @Then my included in price taxes should be :taxTotal |
132
|
|
|
*/ |
133
|
|
|
public function myIncludedInPriceTaxesShouldBe(string $taxTotal): void |
134
|
|
|
{ |
135
|
|
|
$this->summaryPage->open(); |
136
|
|
|
|
137
|
|
|
Assert::same($this->summaryPage->getIncludedTaxTotal(), $taxTotal); |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* @Then there should be no taxes charged |
142
|
|
|
*/ |
143
|
|
|
public function thereShouldBeNoTaxesCharged(): void |
144
|
|
|
{ |
145
|
|
|
$this->summaryPage->open(); |
146
|
|
|
|
147
|
|
|
Assert::false($this->summaryPage->areTaxesCharged()); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* @Then my cart shipping total should be :shippingTotal |
152
|
|
|
* @Then my cart shipping should be for free |
153
|
|
|
*/ |
154
|
|
|
public function myCartShippingFeeShouldBe($shippingTotal = '$0.00') |
155
|
|
|
{ |
156
|
|
|
$this->summaryPage->open(); |
157
|
|
|
|
158
|
|
|
Assert::same($this->summaryPage->getShippingTotal(), $shippingTotal); |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* @Then I should not see shipping total for my cart |
163
|
|
|
*/ |
164
|
|
|
public function iShouldNotSeeShippingTotalForMyCart(): void |
165
|
|
|
{ |
166
|
|
|
$this->summaryPage->open(); |
167
|
|
|
|
168
|
|
|
Assert::false($this->summaryPage->hasShippingTotal()); |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
/** |
172
|
|
|
* @Then my discount should be :promotionsTotal |
173
|
|
|
*/ |
174
|
|
|
public function myDiscountShouldBe($promotionsTotal) |
175
|
|
|
{ |
176
|
|
|
$this->summaryPage->open(); |
177
|
|
|
|
178
|
|
|
Assert::same($this->summaryPage->getPromotionTotal(), $promotionsTotal); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* @Given /^there should be no shipping fee$/ |
183
|
|
|
*/ |
184
|
|
|
public function thereShouldBeNoShippingFee() |
185
|
|
|
{ |
186
|
|
|
$this->summaryPage->open(); |
187
|
|
|
|
188
|
|
|
try { |
189
|
|
|
$this->summaryPage->getShippingTotal(); |
190
|
|
|
} catch (ElementNotFoundException $exception) { |
|
|
|
|
191
|
|
|
return; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
throw new \DomainException('Get shipping total should throw an exception!'); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* @Given /^there should be no discount$/ |
199
|
|
|
*/ |
200
|
|
|
public function thereShouldBeNoDiscount() |
201
|
|
|
{ |
202
|
|
|
$this->summaryPage->open(); |
203
|
|
|
|
204
|
|
|
try { |
205
|
|
|
$this->summaryPage->getPromotionTotal(); |
206
|
|
|
} catch (ElementNotFoundException $exception) { |
|
|
|
|
207
|
|
|
return; |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
throw new \DomainException('Get promotion total should throw an exception!'); |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
/** |
214
|
|
|
* @Then /^(its|theirs) price should be decreased by ("[^"]+")$/ |
215
|
|
|
* @Then /^(product "[^"]+") price should be decreased by ("[^"]+")$/ |
216
|
|
|
*/ |
217
|
|
|
public function itsPriceShouldBeDecreasedBy(ProductInterface $product, $amount) |
218
|
|
|
{ |
219
|
|
|
$this->summaryPage->open(); |
220
|
|
|
|
221
|
|
|
$quantity = $this->summaryPage->getQuantity($product->getName()); |
222
|
|
|
$itemTotal = $this->summaryPage->getItemTotal($product->getName()); |
223
|
|
|
$regularUnitPrice = $this->summaryPage->getItemUnitRegularPrice($product->getName()); |
224
|
|
|
|
225
|
|
|
Assert::same($this->getPriceFromString($itemTotal), ($quantity * $regularUnitPrice) - $amount); |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
/** |
229
|
|
|
* @Then /^(product "[^"]+") price should not be decreased$/ |
230
|
|
|
*/ |
231
|
|
|
public function productPriceShouldNotBeDecreased(ProductInterface $product) |
232
|
|
|
{ |
233
|
|
|
$this->summaryPage->open(); |
234
|
|
|
|
235
|
|
|
Assert::false($this->summaryPage->isItemDiscounted($product->getName())); |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
/** |
239
|
|
|
* @Given /^I (?:add|added) (this product) to the cart$/ |
240
|
|
|
* @Given I added product :product to the cart |
241
|
|
|
* @Given /^I (?:have|had) (product "[^"]+") in the cart$/ |
242
|
|
|
* @Given the customer added :product product to the cart |
243
|
|
|
* @When I add product :product to the cart |
244
|
|
|
*/ |
245
|
|
|
public function iAddProductToTheCart(ProductInterface $product): void |
246
|
|
|
{ |
247
|
|
|
$this->productShowPage->open(['slug' => $product->getSlug()]); |
248
|
|
|
$this->productShowPage->addToCart(); |
249
|
|
|
|
250
|
|
|
$this->sharedStorage->set('product', $product); |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
/** |
254
|
|
|
* @When /^I add (products "([^"]+)" and "([^"]+)") to the cart$/ |
255
|
|
|
* @When /^I add (products "([^"]+)", "([^"]+)" and "([^"]+)") to the cart$/ |
256
|
|
|
*/ |
257
|
|
|
public function iAddMultipleProductsToTheCart(array $products) |
258
|
|
|
{ |
259
|
|
|
foreach ($products as $product) { |
260
|
|
|
$this->iAddProductToTheCart($product); |
261
|
|
|
} |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
/** |
265
|
|
|
* @When I add :variantName variant of product :product to the cart |
266
|
|
|
* @When /^I add "([^"]+)" variant of (this product) to the cart$/ |
267
|
|
|
* @Given I have :variantName variant of product :product in the cart |
268
|
|
|
*/ |
269
|
|
|
public function iAddProductToTheCartSelectingVariant($variantName, ProductInterface $product) |
270
|
|
|
{ |
271
|
|
|
$this->productShowPage->open(['slug' => $product->getSlug()]); |
272
|
|
|
$this->productShowPage->addToCartWithVariant($variantName); |
273
|
|
|
|
274
|
|
|
$this->sharedStorage->set('product', $product); |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* @When /^I add (\d+) of (them) to (?:the|my) cart$/ |
279
|
|
|
*/ |
280
|
|
|
public function iAddQuantityOfProductsToTheCart($quantity, ProductInterface $product) |
281
|
|
|
{ |
282
|
|
|
$this->productShowPage->open(['slug' => $product->getSlug()]); |
283
|
|
|
$this->productShowPage->addToCartWithQuantity($quantity); |
284
|
|
|
} |
285
|
|
|
|
286
|
|
|
/** |
287
|
|
|
* @Given /^I have(?:| added) (\d+) (products "([^"]+)") (?:to|in) the cart$/ |
288
|
|
|
* @When /^I add(?:|ed)(?:| again) (\d+) (products "([^"]+)") to the cart$/ |
289
|
|
|
*/ |
290
|
|
|
public function iAddProductsToTheCart($quantity, ProductInterface $product) |
291
|
|
|
{ |
292
|
|
|
$this->productShowPage->open(['slug' => $product->getSlug()]); |
293
|
|
|
$this->productShowPage->addToCartWithQuantity($quantity); |
294
|
|
|
|
295
|
|
|
$this->sharedStorage->set('product', $product); |
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
/** |
299
|
|
|
* @Then /^I should be(?: on| redirected to) my cart summary page$/ |
300
|
|
|
*/ |
301
|
|
|
public function shouldBeOnMyCartSummaryPage() |
302
|
|
|
{ |
303
|
|
|
$this->summaryPage->waitForRedirect(3); |
304
|
|
|
|
305
|
|
|
$this->summaryPage->verify(); |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
/** |
309
|
|
|
* @Then I should be notified that the product has been successfully added |
310
|
|
|
*/ |
311
|
|
|
public function iShouldBeNotifiedThatItHasBeenSuccessfullyAdded() |
312
|
|
|
{ |
313
|
|
|
$this->notificationChecker->checkNotification('Item has been added to cart', NotificationType::success()); |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
/** |
317
|
|
|
* @Then there should be one item in my cart |
318
|
|
|
*/ |
319
|
|
|
public function thereShouldBeOneItemInMyCart() |
320
|
|
|
{ |
321
|
|
|
Assert::true($this->summaryPage->isSingleItemOnPage()); |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
/** |
325
|
|
|
* @Then this item should have name :itemName |
326
|
|
|
*/ |
327
|
|
|
public function thisProductShouldHaveName($itemName) |
328
|
|
|
{ |
329
|
|
|
Assert::true($this->summaryPage->hasItemNamed($itemName)); |
330
|
|
|
} |
331
|
|
|
|
332
|
|
|
/** |
333
|
|
|
* @Then this item should have variant :variantName |
334
|
|
|
*/ |
335
|
|
|
public function thisItemShouldHaveVariant($variantName) |
336
|
|
|
{ |
337
|
|
|
Assert::true($this->summaryPage->hasItemWithVariantNamed($variantName)); |
338
|
|
|
} |
339
|
|
|
|
340
|
|
|
/** |
341
|
|
|
* @Then this item should have code :variantCode |
342
|
|
|
*/ |
343
|
|
|
public function thisItemShouldHaveCode($variantCode) |
344
|
|
|
{ |
345
|
|
|
Assert::true($this->summaryPage->hasItemWithCode($variantCode)); |
346
|
|
|
} |
347
|
|
|
|
348
|
|
|
/** |
349
|
|
|
* @Given I have :product with :productOption :productOptionValue in the cart |
350
|
|
|
* @When I add :product with :productOption :productOptionValue to the cart |
351
|
|
|
*/ |
352
|
|
|
public function iAddThisProductWithToTheCart(ProductInterface $product, ProductOptionInterface $productOption, $productOptionValue) |
353
|
|
|
{ |
354
|
|
|
$this->productShowPage->open(['slug' => $product->getSlug()]); |
355
|
|
|
|
356
|
|
|
$this->productShowPage->addToCartWithOption($productOption, $productOptionValue); |
357
|
|
|
} |
358
|
|
|
|
359
|
|
|
/** |
360
|
|
|
* @Given /^(this product) should have ([^"]+) "([^"]+)"$/ |
361
|
|
|
*/ |
362
|
|
|
public function thisItemShouldHaveOptionValue(ProductInterface $product, $optionName, $optionValue) |
363
|
|
|
{ |
364
|
|
|
Assert::true($this->summaryPage->hasItemWithOptionValue($product->getName(), $optionName, $optionValue)); |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
/** |
368
|
|
|
* @When I clear my cart |
369
|
|
|
*/ |
370
|
|
|
public function iClearMyCart() |
371
|
|
|
{ |
372
|
|
|
$this->summaryPage->clearCart(); |
373
|
|
|
} |
374
|
|
|
|
375
|
|
|
/** |
376
|
|
|
* @Then /^I should see "([^"]+)" with quantity (\d+) in my cart$/ |
377
|
|
|
*/ |
378
|
|
|
public function iShouldSeeWithQuantityInMyCart($productName, $quantity) |
379
|
|
|
{ |
380
|
|
|
Assert::same($this->summaryPage->getQuantity($productName), (int) $quantity); |
381
|
|
|
} |
382
|
|
|
|
383
|
|
|
/** |
384
|
|
|
* @Then /^I should see "([^"]+)" with unit price ("[^"]+") in my cart$/ |
385
|
|
|
*/ |
386
|
|
|
public function iShouldSeeProductWithUnitPriceInMyCart($productName, $unitPrice) |
387
|
|
|
{ |
388
|
|
|
Assert::same($this->summaryPage->getItemUnitPrice($productName), $unitPrice); |
389
|
|
|
} |
390
|
|
|
|
391
|
|
|
/** |
392
|
|
|
* @Given I use coupon with code :couponCode |
393
|
|
|
*/ |
394
|
|
|
public function iUseCouponWithCode($couponCode) |
395
|
|
|
{ |
396
|
|
|
$this->summaryPage->applyCoupon($couponCode); |
397
|
|
|
} |
398
|
|
|
|
399
|
|
|
/** |
400
|
|
|
* @Then I should be notified that the coupon is invalid |
401
|
|
|
*/ |
402
|
|
|
public function iShouldBeNotifiedThatCouponIsInvalid() |
403
|
|
|
{ |
404
|
|
|
Assert::same($this->summaryPage->getPromotionCouponValidationMessage(), 'Coupon code is invalid.'); |
405
|
|
|
} |
406
|
|
|
|
407
|
|
|
/** |
408
|
|
|
* @Then total price of :productName item should be :productPrice |
409
|
|
|
*/ |
410
|
|
|
public function thisItemPriceShouldBe($productName, $productPrice) |
411
|
|
|
{ |
412
|
|
|
$this->summaryPage->open(); |
413
|
|
|
|
414
|
|
|
Assert::same($this->summaryPage->getItemTotal($productName), $productPrice); |
415
|
|
|
} |
416
|
|
|
|
417
|
|
|
/** |
418
|
|
|
* @Then /^I should be notified that (this product) cannot be updated$/ |
419
|
|
|
*/ |
420
|
|
|
public function iShouldBeNotifiedThatThisProductDoesNotHaveSufficientStock(ProductInterface $product) |
421
|
|
|
{ |
422
|
|
|
Assert::true($this->summaryPage->hasProductOutOfStockValidationMessage($product)); |
423
|
|
|
} |
424
|
|
|
|
425
|
|
|
/** |
426
|
|
|
* @Then /^I should not be notified that (this product) cannot be updated$/ |
427
|
|
|
*/ |
428
|
|
|
public function iShouldNotBeNotifiedThatThisProductCannotBeUpdated(ProductInterface $product) |
429
|
|
|
{ |
430
|
|
|
Assert::false($this->summaryPage->hasProductOutOfStockValidationMessage($product)); |
431
|
|
|
} |
432
|
|
|
|
433
|
|
|
/** |
434
|
|
|
* @Then my cart's total should be :total |
435
|
|
|
*/ |
436
|
|
|
public function myCartSTotalShouldBe($total) |
437
|
|
|
{ |
438
|
|
|
$this->summaryPage->open(); |
439
|
|
|
|
440
|
|
|
Assert::same($this->summaryPage->getCartTotal(), $total); |
441
|
|
|
} |
442
|
|
|
|
443
|
|
|
/** |
444
|
|
|
* @Then /^(\d)(st|nd|rd|th) item in my cart should have "([^"]+)" image displayed$/ |
445
|
|
|
*/ |
446
|
|
|
public function itemShouldHaveImageDisplayed(int $itemNumber, string $image): void |
447
|
|
|
{ |
448
|
|
|
Assert::contains($this->summaryPage->getItemImage($itemNumber), $image); |
449
|
|
|
} |
450
|
|
|
|
451
|
|
|
private function getPriceFromString(string $price): int |
452
|
|
|
{ |
453
|
|
|
return (int) round((float) str_replace(['€', '£', '$'], '', $price) * 100, 2); |
454
|
|
|
} |
455
|
|
|
} |
456
|
|
|
|
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.