|
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\Context\Ui\Shop; |
|
13
|
|
|
|
|
14
|
|
|
use Behat\Behat\Context\Context; |
|
15
|
|
|
use Sylius\Behat\Page\Shop\Product\ShowPageInterface; |
|
16
|
|
|
use Sylius\Behat\Page\Shop\ProductReview\IndexPageInterface; |
|
17
|
|
|
use Sylius\Behat\Page\Shop\Taxon\ShowPageInterface as TaxonShowPageInterface; |
|
18
|
|
|
use Sylius\Behat\Page\SymfonyPageInterface; |
|
19
|
|
|
use Sylius\Component\Core\Model\ProductInterface; |
|
20
|
|
|
use Sylius\Component\Core\Model\TaxonInterface; |
|
21
|
|
|
use Webmozart\Assert\Assert; |
|
22
|
|
|
|
|
23
|
|
|
/** |
|
24
|
|
|
* @author Kamil Kokot <[email protected]> |
|
25
|
|
|
* @author Magdalena Banasiak <[email protected]> |
|
26
|
|
|
* @author Anna Walasek <[email protected]> |
|
27
|
|
|
*/ |
|
28
|
|
|
final class ProductContext implements Context |
|
29
|
|
|
{ |
|
30
|
|
|
/** |
|
31
|
|
|
* @var ShowPageInterface |
|
32
|
|
|
*/ |
|
33
|
|
|
private $showPage; |
|
34
|
|
|
|
|
35
|
|
|
/** |
|
36
|
|
|
* @var TaxonShowPageInterface |
|
37
|
|
|
*/ |
|
38
|
|
|
private $taxonShowPage; |
|
39
|
|
|
|
|
40
|
|
|
/** |
|
41
|
|
|
* @var IndexPageInterface |
|
42
|
|
|
*/ |
|
43
|
|
|
private $productReviewsIndexPage; |
|
44
|
|
|
|
|
45
|
|
|
/** |
|
46
|
|
|
* @param ShowPageInterface $showPage |
|
47
|
|
|
* @param TaxonShowPageInterface $taxonShowPage |
|
48
|
|
|
* @param IndexPageInterface $productReviewsIndexPage |
|
49
|
|
|
*/ |
|
50
|
|
|
public function __construct( |
|
51
|
|
|
ShowPageInterface $showPage, |
|
52
|
|
|
TaxonShowPageInterface $taxonShowPage, |
|
53
|
|
|
IndexPageInterface $productReviewsIndexPage |
|
54
|
|
|
) { |
|
55
|
|
|
$this->showPage = $showPage; |
|
56
|
|
|
$this->taxonShowPage = $taxonShowPage; |
|
57
|
|
|
$this->productReviewsIndexPage = $productReviewsIndexPage; |
|
58
|
|
|
} |
|
59
|
|
|
|
|
60
|
|
|
/** |
|
61
|
|
|
* @Then I should be able to access product :product |
|
62
|
|
|
*/ |
|
63
|
|
|
public function iShouldBeAbleToAccessProduct(ProductInterface $product) |
|
64
|
|
|
{ |
|
65
|
|
|
$this->showPage->tryToOpen(['slug' => $product->getSlug()]); |
|
66
|
|
|
|
|
67
|
|
|
Assert::true( |
|
68
|
|
|
$this->showPage->isOpen(['slug' => $product->getSlug()]), |
|
69
|
|
|
'Product show page should be open, but it does not.' |
|
70
|
|
|
); |
|
71
|
|
|
} |
|
72
|
|
|
|
|
73
|
|
|
/** |
|
74
|
|
|
* @Then I should not be able to access product :product |
|
75
|
|
|
*/ |
|
76
|
|
|
public function iShouldNotBeAbleToAccessProduct(ProductInterface $product) |
|
77
|
|
|
{ |
|
78
|
|
|
$this->showPage->tryToOpen(['slug' => $product->getSlug()]); |
|
79
|
|
|
|
|
80
|
|
|
Assert::false( |
|
81
|
|
|
$this->showPage->isOpen(['slug' => $product->getSlug()]), |
|
82
|
|
|
'Product show page should not be open, but it does.' |
|
83
|
|
|
); |
|
84
|
|
|
} |
|
85
|
|
|
|
|
86
|
|
|
/** |
|
87
|
|
|
* @When /^I check (this product)'s details/ |
|
88
|
|
|
* @When I view product :product |
|
89
|
|
|
*/ |
|
90
|
|
|
public function iOpenProductPage(ProductInterface $product) |
|
91
|
|
|
{ |
|
92
|
|
|
$this->showPage->open(['slug' => $product->getSlug()]); |
|
93
|
|
|
} |
|
94
|
|
|
|
|
95
|
|
|
/** |
|
96
|
|
|
* @Given I should see the product name :name |
|
97
|
|
|
*/ |
|
98
|
|
|
public function iShouldSeeProductName($name) |
|
99
|
|
|
{ |
|
100
|
|
|
Assert::same( |
|
101
|
|
|
$name, |
|
102
|
|
|
$this->showPage->getName(), |
|
103
|
|
|
'Product should have name %2$s, but it has %s' |
|
104
|
|
|
); |
|
105
|
|
|
} |
|
106
|
|
|
|
|
107
|
|
|
/** |
|
108
|
|
|
* @When I open page :url |
|
109
|
|
|
*/ |
|
110
|
|
|
public function iOpenPage($url) |
|
111
|
|
|
{ |
|
112
|
|
|
$this->showPage->visit($url); |
|
113
|
|
|
} |
|
114
|
|
|
|
|
115
|
|
|
/** |
|
116
|
|
|
* @Then I should be on :product product detailed page |
|
117
|
|
|
* @Then I should still be on product :product page |
|
118
|
|
|
*/ |
|
119
|
|
|
public function iShouldBeOnProductDetailedPage(ProductInterface $product) |
|
120
|
|
|
{ |
|
121
|
|
|
Assert::true( |
|
122
|
|
|
$this->showPage->isOpen(['slug' => $product->getSlug()]), |
|
123
|
|
|
sprintf('Product %s show page should be open, but it does not.', $product->getName()) |
|
124
|
|
|
); |
|
125
|
|
|
} |
|
126
|
|
|
|
|
127
|
|
|
/** |
|
128
|
|
|
* @Then I should see the product attribute :attributeName with value :AttributeValue |
|
129
|
|
|
*/ |
|
130
|
|
|
public function iShouldSeeTheProductAttributeWithValue($attributeName, $AttributeValue) |
|
|
|
|
|
|
131
|
|
|
{ |
|
132
|
|
|
Assert::true( |
|
133
|
|
|
$this->showPage->hasAttributeWithValue($attributeName, $AttributeValue), |
|
|
|
|
|
|
134
|
|
|
sprintf('Product should have attribute %s with value %s, but it does not.', $attributeName, $AttributeValue) |
|
|
|
|
|
|
135
|
|
|
); |
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
/** |
|
139
|
|
|
* @When /^I browse products from (taxon "([^"]+)")$/ |
|
140
|
|
|
*/ |
|
141
|
|
|
public function iCheckListOfProductsForTaxon(TaxonInterface $taxon) |
|
142
|
|
|
{ |
|
143
|
|
|
$this->taxonShowPage->open(['permalink' => $taxon->getPermalink()]); |
|
144
|
|
|
} |
|
145
|
|
|
|
|
146
|
|
|
/** |
|
147
|
|
|
* @When I search for products with name :name |
|
148
|
|
|
*/ |
|
149
|
|
|
public function iSearchForProductsWithName($name) |
|
150
|
|
|
{ |
|
151
|
|
|
$this->taxonShowPage->search($name); |
|
152
|
|
|
} |
|
153
|
|
|
|
|
154
|
|
|
/** |
|
155
|
|
|
* @When I clear filter |
|
156
|
|
|
*/ |
|
157
|
|
|
public function iClearFilter() |
|
158
|
|
|
{ |
|
159
|
|
|
$this->taxonShowPage->clearFilter(); |
|
160
|
|
|
} |
|
161
|
|
|
|
|
162
|
|
|
/** |
|
163
|
|
|
* @Then I should see the product :productName |
|
164
|
|
|
*/ |
|
165
|
|
|
public function iShouldSeeProduct($productName) |
|
166
|
|
|
{ |
|
167
|
|
|
Assert::true( |
|
168
|
|
|
$this->taxonShowPage->isProductOnList($productName), |
|
169
|
|
|
sprintf("The product %s should appear on page, but it does not.", $productName) |
|
|
|
|
|
|
170
|
|
|
); |
|
171
|
|
|
} |
|
172
|
|
|
|
|
173
|
|
|
/** |
|
174
|
|
|
* @Then I should not see the product :productName |
|
175
|
|
|
*/ |
|
176
|
|
|
public function iShouldNotSeeProduct($productName) |
|
177
|
|
|
{ |
|
178
|
|
|
Assert::false( |
|
179
|
|
|
$this->taxonShowPage->isProductOnList($productName), |
|
180
|
|
|
sprintf("The product %s should not appear on page, but it does.", $productName) |
|
|
|
|
|
|
181
|
|
|
); |
|
182
|
|
|
} |
|
183
|
|
|
|
|
184
|
|
|
/** |
|
185
|
|
|
* @Then I should see empty list of products |
|
186
|
|
|
*/ |
|
187
|
|
|
public function iShouldSeeEmptyListOfProducts() |
|
188
|
|
|
{ |
|
189
|
|
|
Assert::true( |
|
190
|
|
|
$this->taxonShowPage->isEmpty(), |
|
191
|
|
|
'There should appear information about empty list of products, but it does not.' |
|
192
|
|
|
); |
|
193
|
|
|
} |
|
194
|
|
|
|
|
195
|
|
|
/** |
|
196
|
|
|
* @Then I should see that it is out of stock |
|
197
|
|
|
*/ |
|
198
|
|
|
public function iShouldSeeItIsOutOfStock() |
|
199
|
|
|
{ |
|
200
|
|
|
Assert::true( |
|
201
|
|
|
$this->showPage->isOutOfStock(), |
|
202
|
|
|
'Out of stock label should be visible.' |
|
203
|
|
|
); |
|
204
|
|
|
} |
|
205
|
|
|
|
|
206
|
|
|
/** |
|
207
|
|
|
* @Then I should be unable to add it to the cart |
|
208
|
|
|
*/ |
|
209
|
|
|
public function iShouldBeUnableToAddItToTheCart() |
|
210
|
|
|
{ |
|
211
|
|
|
Assert::false( |
|
212
|
|
|
$this->showPage->hasAddToCartButton(), |
|
213
|
|
|
'Add to cart button should not be visible.' |
|
214
|
|
|
); |
|
215
|
|
|
} |
|
216
|
|
|
|
|
217
|
|
|
/** |
|
218
|
|
|
* @Then the product price should be :price |
|
219
|
|
|
* @Then I should see the product price :price |
|
220
|
|
|
*/ |
|
221
|
|
|
public function iShouldSeeTheProductPrice($price) |
|
222
|
|
|
{ |
|
223
|
|
|
Assert::same( |
|
224
|
|
|
$price, |
|
225
|
|
|
$this->showPage->getPrice(), |
|
226
|
|
|
'Product should have price %2$s, but it has %s' |
|
227
|
|
|
); |
|
228
|
|
|
} |
|
229
|
|
|
|
|
230
|
|
|
/** |
|
231
|
|
|
* @When I set its :optionName to :optionValue |
|
232
|
|
|
*/ |
|
233
|
|
|
public function iSetItsOptionTo($optionName, $optionValue) |
|
234
|
|
|
{ |
|
235
|
|
|
$this->showPage->selectOption($optionName, $optionValue); |
|
236
|
|
|
} |
|
237
|
|
|
|
|
238
|
|
|
/** |
|
239
|
|
|
* @When I select :variantName variant |
|
240
|
|
|
*/ |
|
241
|
|
|
public function iSelectVariant($variantName) |
|
242
|
|
|
{ |
|
243
|
|
|
$this->showPage->selectVariant($variantName); |
|
244
|
|
|
} |
|
245
|
|
|
|
|
246
|
|
|
/** |
|
247
|
|
|
* @Then I should see the product :productName with price :productPrice |
|
248
|
|
|
*/ |
|
249
|
|
|
public function iShouldSeeTheProductWithPrice($productName, $productPrice) |
|
250
|
|
|
{ |
|
251
|
|
|
Assert::true( |
|
252
|
|
|
$this->taxonShowPage->isProductWithPriceOnList($productName, $productPrice), |
|
253
|
|
|
sprintf("The product %s with price %s should appear on page, but it does not.", $productName, $productPrice) |
|
|
|
|
|
|
254
|
|
|
); |
|
255
|
|
|
} |
|
256
|
|
|
|
|
257
|
|
|
/** |
|
258
|
|
|
* @Then /^I should be notified that (this product) does not have sufficient stock$/ |
|
259
|
|
|
*/ |
|
260
|
|
|
public function iShouldBeNotifiedThatThisProductDoesNotHaveSufficientStock(ProductInterface $product) |
|
261
|
|
|
{ |
|
262
|
|
|
$this->showPage->waitForValidationErrors(3); |
|
263
|
|
|
|
|
264
|
|
|
Assert::true( |
|
265
|
|
|
$this->showPage->hasProductOutOfStockValidationMessage($product), |
|
266
|
|
|
sprintf('I should see validation message for %s product', $product->getName()) |
|
267
|
|
|
); |
|
268
|
|
|
} |
|
269
|
|
|
|
|
270
|
|
|
/** |
|
271
|
|
|
* @Then /^I should not be notified that (this product) does not have sufficient stock$/ |
|
272
|
|
|
*/ |
|
273
|
|
|
public function iShouldNotBeNotifiedThatThisProductDoesNotHaveSufficientStock(ProductInterface $product) |
|
274
|
|
|
{ |
|
275
|
|
|
Assert::false( |
|
276
|
|
|
$this->showPage->hasProductOutOfStockValidationMessage($product), |
|
277
|
|
|
sprintf('I should see validation message for %s product', $product->getName()) |
|
278
|
|
|
); |
|
279
|
|
|
} |
|
280
|
|
|
|
|
281
|
|
|
/** |
|
282
|
|
|
* @Then I should see a main image |
|
283
|
|
|
*/ |
|
284
|
|
|
public function iShouldSeeAMainImage() |
|
285
|
|
|
{ |
|
286
|
|
|
Assert::true( |
|
287
|
|
|
$this->showPage->isMainImageDisplayed(), |
|
288
|
|
|
'The main image should have been displayed.' |
|
289
|
|
|
); |
|
290
|
|
|
} |
|
291
|
|
|
|
|
292
|
|
|
/** |
|
293
|
|
|
* @When /^I view (oldest|newest) products from (taxon "([^"]+)")$/ |
|
294
|
|
|
*/ |
|
295
|
|
|
public function iViewSortedProductsFromTaxon($sortDirection, TaxonInterface $taxon) |
|
296
|
|
|
{ |
|
297
|
|
|
$sorting = ['createdAt' => 'oldest' === $sortDirection ? 'asc' : 'desc']; |
|
298
|
|
|
|
|
299
|
|
|
$this->taxonShowPage->open(['permalink' => $taxon->getPermalink(), 'sorting' => $sorting]); |
|
300
|
|
|
} |
|
301
|
|
|
|
|
302
|
|
|
/** |
|
303
|
|
|
* @Then I should see :numberOfProducts products in the list |
|
304
|
|
|
*/ |
|
305
|
|
|
public function iShouldSeeProductsInTheList($numberOfProducts) |
|
306
|
|
|
{ |
|
307
|
|
|
$foundRows = $this->taxonShowPage->countProductsItems(); |
|
308
|
|
|
|
|
309
|
|
|
Assert::same( |
|
310
|
|
|
(int) $numberOfProducts, |
|
311
|
|
|
$foundRows, |
|
312
|
|
|
'%s rows with products should appear on page, %s rows has been found' |
|
313
|
|
|
); |
|
314
|
|
|
} |
|
315
|
|
|
|
|
316
|
|
|
/** |
|
317
|
|
|
* @Then I should see a product with name :name |
|
318
|
|
|
*/ |
|
319
|
|
|
public function iShouldSeeProductWithName($name) |
|
320
|
|
|
{ |
|
321
|
|
|
Assert::true( |
|
322
|
|
|
$this->taxonShowPage->isProductOnPageWithName($name), |
|
323
|
|
|
sprintf('The product with name "%s" has not been found.', $name) |
|
324
|
|
|
); |
|
325
|
|
|
} |
|
326
|
|
|
|
|
327
|
|
|
/** |
|
328
|
|
|
* @Then the first product on the list should have name :name |
|
329
|
|
|
*/ |
|
330
|
|
|
public function theFirstProductOnTheListShouldHaveName($name) |
|
331
|
|
|
{ |
|
332
|
|
|
$actualName = $this->taxonShowPage->getFirstProductNameFromList(); |
|
333
|
|
|
|
|
334
|
|
|
Assert::same( |
|
335
|
|
|
$actualName, |
|
336
|
|
|
$name, |
|
337
|
|
|
sprintf('Expected first product\'s name to be "%s", but it is "%s".', $name, $actualName) |
|
338
|
|
|
); |
|
339
|
|
|
} |
|
340
|
|
|
|
|
341
|
|
|
/** |
|
342
|
|
|
* @Then I should see :count product reviews |
|
343
|
|
|
*/ |
|
344
|
|
|
public function iShouldSeeProductReviews($count) |
|
345
|
|
|
{ |
|
346
|
|
|
Assert::same( |
|
347
|
|
|
(int) $count, |
|
348
|
|
|
$this->showPage->countReviews(), |
|
349
|
|
|
'Product has %2$s reviews, but should have %s.' |
|
350
|
|
|
); |
|
351
|
|
|
} |
|
352
|
|
|
|
|
353
|
|
|
/** |
|
354
|
|
|
* @Then I should see reviews titled :firstReview, :secondReview and :thirdReview |
|
355
|
|
|
*/ |
|
356
|
|
|
public function iShouldSeeReviewsTitled(...$reviews) |
|
357
|
|
|
{ |
|
358
|
|
|
foreach ($reviews as $review) { |
|
359
|
|
|
Assert::true( |
|
360
|
|
|
$this->showPage->hasReviewTitled($review), |
|
361
|
|
|
sprintf('Product should have review titled "%s" but it does not.', $review) |
|
362
|
|
|
); |
|
363
|
|
|
} |
|
364
|
|
|
} |
|
365
|
|
|
|
|
366
|
|
|
/** |
|
367
|
|
|
* @Then I should not see review titled :title |
|
368
|
|
|
*/ |
|
369
|
|
|
public function iShouldNotSeeReviewTitled($title) |
|
370
|
|
|
{ |
|
371
|
|
|
Assert::false( |
|
372
|
|
|
$this->showPage->hasReviewTitled($title), |
|
373
|
|
|
sprintf('Product should not have review titled "%s" but it does.', $title) |
|
374
|
|
|
); |
|
375
|
|
|
} |
|
376
|
|
|
|
|
377
|
|
|
/** |
|
378
|
|
|
* @When /^I check (this product)'s reviews$/ |
|
379
|
|
|
*/ |
|
380
|
|
|
public function iCheckThisProductSReviews(ProductInterface $product) |
|
381
|
|
|
{ |
|
382
|
|
|
$this->productReviewsIndexPage->open(['slug' => $product->getSlug()]); |
|
383
|
|
|
} |
|
384
|
|
|
|
|
385
|
|
|
/** |
|
386
|
|
|
* @Then I should see :count product reviews in the list |
|
387
|
|
|
*/ |
|
388
|
|
|
public function iShouldSeeProductReviewsInTheList($count) |
|
389
|
|
|
{ |
|
390
|
|
|
Assert::same( |
|
391
|
|
|
(int) $count, |
|
392
|
|
|
$this->productReviewsIndexPage->countReviews(), |
|
393
|
|
|
'Product has %2$s reviews in the list, but should have %s.' |
|
394
|
|
|
); |
|
395
|
|
|
} |
|
396
|
|
|
|
|
397
|
|
|
/** |
|
398
|
|
|
* @Then I should not see review titled :title in the list |
|
399
|
|
|
*/ |
|
400
|
|
|
public function iShouldNotSeeReviewTitledInTheList($title) |
|
401
|
|
|
{ |
|
402
|
|
|
Assert::false( |
|
403
|
|
|
$this->productReviewsIndexPage->hasReviewTitled($title), |
|
404
|
|
|
sprintf('Product should not have review titled "%s" but it does.', $title) |
|
405
|
|
|
); |
|
406
|
|
|
} |
|
407
|
|
|
|
|
408
|
|
|
/** |
|
409
|
|
|
* @Then /^I should be notified that there are no reviews$/ |
|
410
|
|
|
*/ |
|
411
|
|
|
public function iShouldBeNotifiedThatThereAreNoReviews() |
|
412
|
|
|
{ |
|
413
|
|
|
Assert::true( |
|
414
|
|
|
$this->productReviewsIndexPage->hasNoReviewMessage(), |
|
415
|
|
|
'There should be message about no reviews but there is not.' |
|
416
|
|
|
); |
|
417
|
|
|
} |
|
418
|
|
|
|
|
419
|
|
|
/** |
|
420
|
|
|
* @Then I should see :rating as its average rating |
|
421
|
|
|
*/ |
|
422
|
|
|
public function iShouldSeeAsItsAverageRating($rating) |
|
423
|
|
|
{ |
|
424
|
|
|
Assert::same( |
|
425
|
|
|
(float) $rating, |
|
426
|
|
|
$this->showPage->getAverageRating(), |
|
427
|
|
|
'Product should have average rating %2$s but has %s.' |
|
428
|
|
|
); |
|
429
|
|
|
} |
|
430
|
|
|
} |
|
431
|
|
|
|
This check examines a number of code elements and verifies that they conform to the given naming conventions.
You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.