Completed
Push — master ( 0916fa...5a50ca )
by Michał
17s
created

CheckoutContext::resolveCurrentStepPage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 10
rs 9.4285
cc 1
eloc 6
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
namespace Sylius\Behat\Context\Ui;
13
14
use Behat\Behat\Context\Context;
15
use Sylius\Behat\Page\Shop\Checkout\AddressPageInterface;
16
use Sylius\Behat\Page\Shop\Checkout\SelectPaymentPageInterface;
17
use Sylius\Behat\Page\Shop\Checkout\SelectShippingPageInterface;
18
use Sylius\Behat\Page\Shop\Checkout\CompletePageInterface;
19
use Sylius\Behat\Page\Shop\HomePageInterface;
20
use Sylius\Behat\Page\Shop\Checkout\ThankYouPageInterface;
21
use Sylius\Behat\Page\SymfonyPageInterface;
22
use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
23
use Sylius\Behat\Service\SharedSecurityServiceInterface;
24
use Sylius\Component\Addressing\Model\CountryInterface;
25
use Sylius\Behat\Page\UnexpectedPageException;
26
use Sylius\Component\Core\Formatter\StringInflector;
27
use Sylius\Component\Core\Model\AddressInterface;
28
use Sylius\Component\Core\Model\ProductInterface;
29
use Sylius\Component\Core\Model\ShippingMethodInterface;
30
use Sylius\Component\Core\Model\ShopUserInterface;
31
use Sylius\Behat\Service\SharedStorageInterface;
32
use Sylius\Component\Order\Repository\OrderRepositoryInterface;
33
use Sylius\Component\Payment\Model\PaymentMethodInterface;
34
use Sylius\Component\Resource\Factory\FactoryInterface;
35
use Webmozart\Assert\Assert;
36
37
/**
38
 * @author Arkadiusz Krakowiak <[email protected]>
39
 */
40
final class CheckoutContext implements Context
41
{
42
    /**
43
     * @var SharedStorageInterface
44
     */
45
    private $sharedStorage;
46
47
    /**
48
     * @var HomePageInterface
49
     */
50
    private $homePage;
51
52
    /**
53
     * @var AddressPageInterface
54
     */
55
    private $addressPage;
56
57
    /**
58
     * @var SelectPaymentPageInterface
59
     */
60
    private $selectPaymentPage;
61
62
    /**
63
     * @var ThankYouPageInterface
64
     */
65
    private $thankYouPage;
66
67
    /**
68
     * @var SelectShippingPageInterface
69
     */
70
    private $selectShippingPage;
71
72
    /**
73
     * @var CompletePageInterface
74
     */
75
    private $completePage;
76
77
    /**
78
     * @var OrderRepositoryInterface
79
     */
80
    private $orderRepository;
81
82
    /**
83
     * @var SharedSecurityServiceInterface
84
     */
85
    private $sharedSecurityService;
86
87
    /**
88
     * @var FactoryInterface
89
     */
90
    private $addressFactory;
91
92
    /**
93
     * @var CurrentPageResolverInterface
94
     */
95
    private $currentPageResolver;
96
97
    /**
98
     * @param SharedStorageInterface $sharedStorage
99
     * @param HomePageInterface $homePage
100
     * @param AddressPageInterface $addressPage
101
     * @param SelectPaymentPageInterface $selectPaymentPage
102
     * @param ThankYouPageInterface $thankYouPage
103
     * @param SelectShippingPageInterface $selectShippingPage
104
     * @param CompletePageInterface $completePage
105
     * @param OrderRepositoryInterface $orderRepository
106
     * @param SharedSecurityServiceInterface $sharedSecurityService
107
     * @param FactoryInterface $addressFactory
108
     * @param CurrentPageResolverInterface $currentPageResolver
109
     */
110
    public function __construct(
111
        SharedStorageInterface $sharedStorage,
112
        HomePageInterface $homePage,
113
        AddressPageInterface $addressPage,
114
        SelectPaymentPageInterface $selectPaymentPage,
115
        ThankYouPageInterface $thankYouPage,
116
        SelectShippingPageInterface $selectShippingPage,
117
        CompletePageInterface $completePage,
118
        OrderRepositoryInterface $orderRepository,
119
        SharedSecurityServiceInterface $sharedSecurityService,
120
        FactoryInterface $addressFactory,
121
        CurrentPageResolverInterface $currentPageResolver
122
    ) {
123
        $this->sharedStorage = $sharedStorage;
124
        $this->homePage = $homePage;
125
        $this->addressPage = $addressPage;
126
        $this->selectPaymentPage = $selectPaymentPage;
127
        $this->thankYouPage = $thankYouPage;
128
        $this->selectShippingPage = $selectShippingPage;
129
        $this->completePage = $completePage;
130
        $this->orderRepository = $orderRepository;
131
        $this->sharedSecurityService = $sharedSecurityService;
132
        $this->addressFactory = $addressFactory;
133
        $this->currentPageResolver = $currentPageResolver;
134
    }
135
136
    /**
137
     * @Given /^I proceed without selecting shipping address$/
138
     */
139
    public function iProceedWithoutSelectingShippingAddress()
140
    {
141
        $this->addressPage->open();
142
        $this->addressPage->nextStep();
143
    }
144
145
    /**
146
     * @Given I am at the checkout addressing step
147
     */
148
    public function iAmAtTheCheckoutAddressingStep()
149
    {
150
        $this->addressPage->open();
151
    }
152
153
    /**
154
     * @Given /^(this user) bought this product$/
155
     */
156
    public function thisUserBought(ShopUserInterface $user)
157
    {
158
        $this->sharedSecurityService->performActionAsShopUser($user, function () {
159
            $this->iProceedSelectingPaymentMethod();
160
            $this->iConfirmMyOrder();
161
        });
162
    }
163
164
    /**
165
     * @When /^I specify the shipping (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
166
     * @When /^I (do not specify any shipping address) information$/
167
     */
168
    public function iSpecifyTheShippingAddressAs(AddressInterface $address)
169
    {
170
        $key = sprintf(
171
            'shipping_address_%s_%s',
172
            strtolower($address->getFirstName()),
173
            strtolower($address->getLastName())
174
        );
175
        $this->sharedStorage->set($key, $address);
176
177
        $this->addressPage->specifyShippingAddress($address);
178
    }
179
180
    /**
181
     * @When I specify shipping country province as :province
182
     */
183
    public function iSpecifyShippingCountryProvinceAs($province)
184
    {
185
        $this->addressPage->specifyShippingAddressProvince($province);
186
    }
187
188
    /**
189
     * @When I specify billing country province as :province
190
     */
191
    public function iSpecifyBillingCountryProvinceAs($province)
192
    {
193
        $this->addressPage->specifyBillingAddressProvince($province);
194
    }
195
196
    /**
197
     * @When /^I specify the billing (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
198
     * @When /^I (do not specify any billing address) information$/
199
     */
200
    public function iSpecifyTheBillingAddressAs(AddressInterface $address)
201
    {
202
        $this->iChooseTheDifferentBillingAddress();
203
        $key = sprintf(
204
            'billing_address_%s_%s',
205
            strtolower($address->getFirstName()),
206
            strtolower($address->getLastName())
207
        );
208
        $this->sharedStorage->set($key, $address);
209
210
        $this->addressPage->specifyBillingAddress($address);
211
    }
212
213
    /**
214
     * @When /^I specified the shipping (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
215
     */
216
    public function iSpecifiedTheShippingAddress(AddressInterface $address)
217
    {
218
        $this->addressPage->open();
219
        $this->iSpecifyTheShippingAddressAs($address);
220
221
        $key = sprintf('billing_address_%s_%s', strtolower($address->getFirstName()), strtolower($address->getLastName()));
222
        $this->sharedStorage->set($key, $address);
223
224
        $this->iCompleteTheAddressingStep();
225
    }
226
227
    /**
228
     * @When I choose the different billing address
229
     */
230
    public function iChooseTheDifferentBillingAddress()
231
    {
232
        $this->addressPage->chooseDifferentBillingAddress();
233
    }
234
235
    /**
236
     * @When I specify the email as :email
237
     * @When I do not specify the email
238
     */
239
    public function iSpecifyTheEmail($email = null)
240
    {
241
        $this->addressPage->specifyEmail($email);
242
    }
243
244
    /**
245
     * @Given I have selected :shippingMethod shipping method
246
     * @When I select :shippingMethod shipping method
247
     */
248
    public function iSelectShippingMethod($shippingMethod)
249
    {
250
        $this->selectShippingPage->selectShippingMethod($shippingMethod);
251
    }
252
253
    /**
254
     * @Then I should not be able to select :shippingMethod shipping method
255
     */
256
    public function iShouldNotBeAbleToSelectShippingMethod($shippingMethod)
257
    {
258
        Assert::false(
259
            $this->selectShippingPage->hasShippingMethod($shippingMethod),
260
            sprintf('Shipping method "%s" should not be available but it does.', $shippingMethod)
261
        );
262
    }
263
264
    /**
265
     * @When I complete the addressing step
266
     * @When I try to complete the addressing step
267
     */
268
    public function iCompleteTheAddressingStep()
269
    {
270
        $this->addressPage->nextStep();
271
    }
272
273
    /**
274
     * @When I go back to store
275
     */
276
    public function iGoBackToStore()
277
    {
278
        $this->addressPage->backToStore();
279
    }
280
281
    /**
282
     * @When I complete the shipping step
283
     */
284
    public function iCompleteTheShippingStep()
285
    {
286
        $this->selectShippingPage->nextStep();
287
    }
288
289
    /**
290
     * @When I decide to change my address
291
     */
292
    public function iDecideToChangeMyAddress()
293
    {
294
        $this->selectShippingPage->changeAddress();
295
    }
296
297
    /**
298
     * @When I decide to change order shipping method
299
     */
300
    public function iDecideToChangeMyShippingMethod()
301
    {
302
        $this->selectPaymentPage->changeShippingMethod();
303
    }
304
305
    /**
306
     * @When I go to the addressing step
307
     */
308
    public function iGoToTheAddressingStep()
309
    {
310
        if ($this->selectShippingPage->isOpen()) {
311
            $this->selectShippingPage->changeAddressByStepLabel();
312
313
            return;
314
        }
315
316
        if ($this->selectPaymentPage->isOpen()) {
317
            $this->selectPaymentPage->changeAddressByStepLabel();
318
319
            return;
320
        }
321
322
        if ($this->completePage->isOpen()) {
323
            $this->completePage->changeAddress();
324
325
            return;
326
        }
327
328
        throw new UnexpectedPageException('It is impossible to go to addressing step from current page.');
329
    }
330
331
    /**
332
     * @When I go to the shipping step
333
     */
334
    public function iGoToTheShippingStep()
335
    {
336
        if ($this->selectPaymentPage->isOpen()) {
337
            $this->selectPaymentPage->changeShippingMethodByStepLabel();
338
339
            return;
340
        }
341
342
        if ($this->completePage->isOpen()) {
343
            $this->completePage->changeShippingMethod();
344
345
            return;
346
        }
347
348
        throw new UnexpectedPageException('It is impossible to go to shipping step from current page.');
349
    }
350
351
    /**
352
     * @When I decide to change the payment method
353
     */
354
    public function iGoToThePaymentStep()
355
    {
356
        $this->completePage->changePaymentMethod();
357
    }
358
359
    /**
360
     * @When /^I proceed selecting ("[^"]+" as shipping country)$/
361
     */
362
    public function iProceedSelectingShippingCountry(CountryInterface $shippingCountry = null)
363
    {
364
        $this->addressPage->open();
365
        $shippingAddress = $this->createDefaultAddress();
366
        if (null !== $shippingCountry) {
367
            $shippingAddress->setCountryCode($shippingCountry->getCode());
368
        }
369
370
        $this->addressPage->specifyShippingAddress($shippingAddress);
371
        $this->addressPage->nextStep();
372
    }
373
374
    /**
375
     * @When /^I proceed selecting ("[^"]+" as shipping country) with "([^"]+)" method$/
376
     */
377
    public function iProceedSelectingShippingCountryAndShippingMethod(CountryInterface $shippingCountry = null, $shippingMethodName)
378
    {
379
        $this->iProceedSelectingShippingCountry($shippingCountry);
380
381
        $this->selectShippingPage->selectShippingMethod($shippingMethodName ?: 'Free');
382
        $this->selectShippingPage->nextStep();
383
    }
384
385
    /**
386
     * @When /^I proceed selecting "([^"]+)" shipping method$/
387
     * @Given /^I chose "([^"]*)" shipping method$/
388
     */
389
    public function iProceedSelectingShippingMethod($shippingMethodName)
390
    {
391
        $this->iProceedSelectingShippingCountryAndShippingMethod(null, $shippingMethodName);
392
    }
393
394
    /**
395
     * @When /^I choose "([^"]*)" payment method$/
396
     */
397
    public function iChoosePaymentMethod($paymentMethodName)
398
    {
399
        $this->selectPaymentPage->selectPaymentMethod($paymentMethodName ?: 'Offline');
400
        $this->selectPaymentPage->nextStep();
401
    }
402
403
    /**
404
     * @When I change payment method to :paymentMethodName
405
     */
406
    public function iChangePaymentMethodTo($paymentMethodName)
407
    {
408
        $this->thankYouPage->choosePaymentMethod($paymentMethodName);
409
    }
410
411
    /**
412
     * @When /^I proceed selecting "([^"]*)" as shipping country with "([^"]*)" payment method$/
413
     */
414
    public function iProceedSelectingShippingCountryAndPaymentMethod($shippingCountry, $paymentMethodName)
415
    {
416
        $this->iProceedSelectingShippingCountryAndShippingMethod($shippingCountry, null);
417
418
        $this->iChoosePaymentMethod($paymentMethodName);
419
    }
420
421
    /**
422
     * @Given I have proceeded selecting :paymentMethodName payment method
423
     * @When /^I (?:proceed|proceeded) selecting "([^"]+)" payment method$/
424
     */
425
    public function iProceedSelectingPaymentMethod($paymentMethodName = 'Offline')
426
    {
427
        $this->iProceedSelectingShippingCountryAndPaymentMethod(null, $paymentMethodName);
428
    }
429
430
    /**
431
     * @When /^I change shipping method to "([^"]*)"$/
432
     */
433
    public function iChangeShippingMethod($shippingMethodName)
434
    {
435
        $this->selectPaymentPage->changeShippingMethod();
436
        $this->selectShippingPage->selectShippingMethod($shippingMethodName);
437
        $this->selectShippingPage->nextStep();
438
    }
439
440
    /**
441
     * @When /^I provide additional note like "([^"]+)"$/
442
     */
443
    public function iProvideAdditionalNotesLike($notes)
444
    {
445
        $this->sharedStorage->set('additional_note', $notes);
446
        $this->completePage->addNotes($notes);
447
    }
448
449
    /**
450
     * @When /^I proceed as guest "([^"]*)" with ("[^"]+" as shipping country)$/
451
     */
452
    public function iProceedLoggingAsGuestWithAsShippingCountry($email, CountryInterface $shippingCountry = null)
453
    {
454
        $this->addressPage->open();
455
        $this->addressPage->specifyEmail($email);
456
        $shippingAddress = $this->createDefaultAddress();
457
        if (null !== $shippingCountry) {
458
            $shippingAddress->setCountryCode($shippingCountry->getCode());
459
        }
460
461
        $this->addressPage->specifyShippingAddress($shippingAddress);
462
        $this->addressPage->nextStep();
463
    }
464
465
    /**
466
     * @Given I have confirmed my order
467
     * @When I confirm my order
468
     */
469
    public function iConfirmMyOrder()
470
    {
471
        $this->completePage->confirmOrder();
472
    }
473
474
    /**
475
     * @When I specify the password as :password
476
     */
477
    public function iSpecifyThePasswordAs($password)
478
    {
479
        $this->addressPage->specifyPassword($password);
480
    }
481
482
    /**
483
     * @When I sign in
484
     */
485
    public function iSignIn()
486
    {
487
        $this->addressPage->signIn();
488
    }
489
490
    /**
491
     * @Then I should see the thank you page
492
     */
493
    public function iShouldSeeTheThankYouPage()
494
    {
495
        Assert::true(
496
            $this->thankYouPage->hasThankYouMessage(),
497
            'I should see thank you message, but I do not.'
498
        );
499
    }
500
501
    /**
502
     * @Then I should not see the thank you page
503
     */
504
    public function iShouldNotSeeTheThankYouPage()
505
    {
506
        Assert::false(
507
            $this->thankYouPage->isOpen(),
508
            'I should not see thank you message, but I do.'
509
        );
510
    }
511
512
    /**
513
     * @Given I should be informed with :paymentMethod payment method instructions
514
     */
515
    public function iShouldBeInformedWithPaymentMethodInstructions(PaymentMethodInterface $paymentMethod)
516
    {
517
        Assert::same(
518
            $this->thankYouPage->getInstructions(),
519
            $paymentMethod->getInstructions()
520
        );
521
    }
522
523
    /**
524
     * @Then /^I should be redirected (?:|back )to the thank you page$/
525
     */
526
    public function iShouldBeRedirectedBackToTheThankYouPage()
527
    {
528
        $this->thankYouPage->waitForResponse(5);
529
530
        Assert::true(
531
            $this->thankYouPage->isOpen(),
532
            'I should be on thank you page, but I am not.'
533
        );
534
    }
535
536
    /**
537
     * @Then I should be on the checkout shipping step
538
     */
539
    public function iShouldBeOnTheCheckoutShippingStep()
540
    {
541
        Assert::true(
542
            $this->selectShippingPage->isOpen(),
543
            'Checkout shipping page should be opened, but it is not.'
544
        );
545
    }
546
547
    /**
548
     * @Then I should be on the checkout summary step
549
     */
550
    public function iShouldBeOnTheCheckoutSummaryStep()
551
    {
552
        Assert::true(
553
            $this->completePage->isOpen(),
554
            'Checkout summary page should be opened, but it is not.'
555
        );
556
    }
557
558
    /**
559
     * @Then /^I should(?:| also) be notified that the "([^"]+)" and the "([^"]+)" in (shipping|billing) details are required$/
560
     */
561
    public function iShouldBeNotifiedThatTheAndTheInShippingDetailsAreRequired($firstElement, $secondElement, $type)
562
    {
563
        $this->assertElementValidationMessage($type, $firstElement, sprintf('Please enter %s.', $firstElement));
564
        $this->assertElementValidationMessage($type, $secondElement, sprintf('Please enter %s.', $secondElement));
565
    }
566
567
    /**
568
     * @Then I should be informed that my order cannot be shipped to this address
569
     */
570
    public function iShouldBeInformedThatMyOrderCannotBeShippedToThisAddress()
571
    {
572
        Assert::true(
573
            $this->selectShippingPage->hasNoShippingMethodsMessage(),
574
            'Shipping page should have no shipping methods message but it does not.'
575
        );
576
    }
577
578
    /**
579
     * @Then I should be able to log in
580
     */
581
    public function iShouldBeAbleToLogIn()
582
    {
583
        Assert::true(
584
            $this->addressPage->canSignIn(),
585
            'I should be able to login, but I am not.'
586
        );
587
    }
588
589
    /**
590
     * @Then the login form should no longer be accessible
591
     */
592
    public function theLoginFormShouldNoLongerBeAccessible()
593
    {
594
        Assert::false(
595
            $this->addressPage->canSignIn(),
596
            'I should not be able to login, but I am.'
597
        );
598
    }
599
600
    /**
601
     * @Then I should be notified about bad credentials
602
     */
603
    public function iShouldBeNotifiedAboutBadCredentials()
604
    {
605
        Assert::true(
606
            $this->addressPage->checkInvalidCredentialsValidation(),
607
            'I should see validation error, but I do not.'
608
        );
609
    }
610
611
    /**
612
     * @Then my order's shipping address should be to :fullName
613
     */
614
    public function iShouldSeeThisShippingAddressAsShippingAddress($fullName)
615
    {
616
        $address = $this->sharedStorage->get('shipping_address_'.StringInflector::nameToLowercaseCode($fullName));
617
        Assert::true(
618
            $this->completePage->hasShippingAddress($address),
619
            'Shipping address is improper.'
620
        );
621
    }
622
623
    /**
624
     * @Then my order's billing address should be to :fullName
625
     */
626
    public function iShouldSeeThisBillingAddressAsBillingAddress($fullName)
627
    {
628
        $address = $this->sharedStorage->get('billing_address_'.StringInflector::nameToLowercaseCode($fullName));
629
        Assert::true(
630
            $this->completePage->hasBillingAddress($address),
631
            'Billing address is improper.'
632
        );
633
    }
634
635
    /**
636
     * @Then address to :fullName should be used for both shipping and billing of my order
637
     */
638
    public function iShouldSeeThisShippingAddressAsShippingAndBillingAddress($fullName)
639
    {
640
        $this->iShouldSeeThisShippingAddressAsShippingAddress($fullName);
641
        $this->iShouldSeeThisBillingAddressAsBillingAddress($fullName);
642
    }
643
644
    /**
645
     * @Given I am at the checkout payment step
646
     */
647
    public function iAmAtTheCheckoutPaymentStep()
648
    {
649
        $this->selectPaymentPage->open();
650
    }
651
652
    /**
653
     * @When I complete the payment step
654
     */
655
    public function iCompleteThePaymentStep()
656
    {
657
        $this->selectPaymentPage->nextStep();
658
    }
659
660
    /**
661
     * @When I select :paymentMethodName payment method
662
     */
663
    public function iSelectPaymentMethod($paymentMethodName)
664
    {
665
        $this->selectPaymentPage->selectPaymentMethod($paymentMethodName);
666
    }
667
668
    /**
669
     * @Then I should not be able to select :paymentMethodName payment method
670
     */
671
    public function iShouldNotBeAbleToSelectPaymentMethod($paymentMethodName)
672
    {
673
        Assert::false(
674
            $this->selectPaymentPage->hasPaymentMethod($paymentMethodName),
675
            sprintf('Payment method "%s" should not be available, but it does.', $paymentMethodName)
676
        );
677
    }
678
679
    /**
680
     * @Then I should be able to select :paymentMethodName payment method
681
     */
682
    public function iShouldBeAbleToSelectPaymentMethod($paymentMethodName)
683
    {
684
        Assert::true(
685
            $this->selectPaymentPage->hasPaymentMethod($paymentMethodName),
686
            sprintf('Payment method "%s" should be available, but it does not.', $paymentMethodName)
687
        );
688
    }
689
690
    /**
691
     * @When I proceed order with :shippingMethod shipping method and :paymentMethod payment
692
     */
693
    public function iProceedOrderWithShippingMethodAndPayment($shippingMethod, $paymentMethod)
694
    {
695
        $this->iSelectShippingMethod($shippingMethod);
696
        $this->iCompleteTheShippingStep();
697
        $this->iSelectPaymentMethod($paymentMethod);
698
        $this->iCompleteThePaymentStep();
699
    }
700
701
    /**
702
     * @Given I should have :quantity :productName products in the cart
703
     */
704
    public function iShouldHaveProductsInTheCart($quantity, $productName)
705
    {
706
        Assert::true(
707
            $this->completePage->hasItemWithProductAndQuantity($productName, $quantity),
708
            sprintf('There is no "%s" with quantity %s on order summary page, but it should.', $productName, $quantity)
709
        );
710
    }
711
712
    /**
713
     * @Then my order shipping should be :price
714
     */
715
    public function myOrderShippingShouldBe($price)
716
    {
717
        Assert::true(
718
            $this->completePage->hasShippingTotal($price),
719
            sprintf('The shipping total should be %s, but it is not.',$price)
720
        );
721
    }
722
723
    /**
724
     * @Then /^the ("[^"]+" product) should have unit price discounted by ("\$\d+")$/
725
     */
726
    public function theShouldHaveUnitPriceDiscountedFor(ProductInterface $product, $amount)
727
    {
728
        Assert::true(
729
            $this->completePage->hasProductDiscountedUnitPriceBy($product, $amount),
730
            sprintf('Product %s should have discounted price by %s, but it does not have.', $product->getName(), $amount)
731
        );
732
    }
733
734
    /**
735
     * @Then /^my order total should be ("(?:\£|\$)\d+")$/
736
     */
737
    public function myOrderTotalShouldBe($total)
738
    {
739
        Assert::true(
740
            $this->completePage->hasOrderTotal($total),
741
            sprintf('Order total should have %s total, but it does not have.', $total)
742
        );
743
    }
744
745
    /**
746
     * @Then my order promotion total should be :promotionTotal
747
     */
748
    public function myOrderPromotionTotalShouldBe($promotionTotal)
749
    {
750
        Assert::true(
751
            $this->completePage->hasPromotionTotal($promotionTotal),
752
            sprintf('The total discount should be %s, but it does not.', $promotionTotal)
753
        );
754
    }
755
756
    /**
757
     * @Then :promotionName should be applied to my order
758
     */
759
    public function shouldBeAppliedToMyOrder($promotionName)
760
    {
761
        Assert::true(
762
            $this->completePage->hasPromotion($promotionName),
763
            sprintf('The promotion %s should appear on the page, but it does not.', $promotionName)
764
        );
765
    }
766
767
    /**
768
     * @Given my tax total should be :taxTotal
769
     */
770
    public function myTaxTotalShouldBe($taxTotal)
771
    {
772
        Assert::true(
773
            $this->completePage->hasTaxTotal($taxTotal),
774
            sprintf('The tax total should be %s, but it does not.', $taxTotal)
775
        );
776
    }
777
778
    /**
779
     * @Then my order's shipping method should be :shippingMethod
780
     */
781
    public function myOrderSShippingMethodShouldBe(ShippingMethodInterface $shippingMethod)
782
    {
783
        Assert::true(
784
            $this->completePage->hasShippingMethod($shippingMethod),
785
            sprintf('I should see %s shipping method, but I do not.', $shippingMethod->getName())
786
        );
787
    }
788
789
    /**
790
     * @Then my order's payment method should be :paymentMethod
791
     */
792
    public function myOrderSPaymentMethodShouldBe(PaymentMethodInterface $paymentMethod)
793
    {
794
        Assert::true(
795
            $this->completePage->hasPaymentMethod($paymentMethod),
796
            sprintf('I should see %s payment method, but I do not.', $paymentMethod->getName())
797
        );
798
    }
799
800
    /**
801
     * @Then I should be redirected to the homepage
802
     */
803
    public function iShouldBeRedirectedToTheHomepage()
804
    {
805
        Assert::true(
806
            $this->homePage->isOpen(),
807
            'Shop homepage should be opened, but it is not.'
808
        );
809
    }
810
811
    /**
812
     * @Then I should be redirected to the addressing step
813
     */
814
    public function iShouldBeRedirectedToTheAddressingStep()
815
    {
816
        Assert::true(
817
            $this->addressPage->isOpen(),
818
            'Checkout addressing step should be opened, but it is not.'
819
        );
820
    }
821
822
    /**
823
     * @Given I should be able to go to the shipping step again
824
     */
825
    public function iShouldBeAbleToGoToTheShippingStepAgain()
826
    {
827
        $this->addressPage->nextStep();
828
829
        Assert::true(
830
            $this->selectShippingPage->isOpen(),
831
            'Checkout shipping step should be opened, but it is not.'
832
        );
833
    }
834
835
    /**
836
     * @Then I should be redirected to the shipping step
837
     */
838
    public function iShouldBeRedirectedToTheShippingStep()
839
    {
840
        Assert::true(
841
            $this->selectShippingPage->isOpen(),
842
            'Checkout shipping step should be opened, but it is not.'
843
        );
844
    }
845
846
    /**
847
     * @Then I should be able to pay again
848
     */
849
    public function iShouldBeAbleToPayAgain()
850
    {
851
        Assert::true(
852
            $this->thankYouPage->isOpen(),
853
            'I should be on thank you page, but I am not.'
854
        );
855
856
        Assert::true(
857
            $this->thankYouPage->hasPayAction(),
858
            'I should be able to pay, but I am not able to.'
859
        );
860
    }
861
862
    /**
863
     * @Given I should be able to go to the payment step again
864
     */
865
    public function iShouldBeAbleToGoToThePaymentStepAgain()
866
    {
867
        $this->selectShippingPage->nextStep();
868
869
        Assert::true(
870
            $this->selectPaymentPage->isOpen(),
871
            'Checkout payment step should be opened, but it is not.'
872
        );
873
    }
874
875
    /**
876
     * @Then I should be redirected to the payment step
877
     */
878
    public function iShouldBeRedirectedToThePaymentStep()
879
    {
880
        Assert::true(
881
            $this->selectPaymentPage->isOpen(),
882
            'Checkout payment step should be opened, but it is not.'
883
        );
884
    }
885
886
    /**
887
     * @Given I should be able to go to the summary page again
888
     */
889
    public function iShouldBeAbleToGoToTheSummaryPageAgain()
890
    {
891
        $this->selectPaymentPage->nextStep();
892
893
        Assert::true(
894
            $this->completePage->isOpen(),
895
            'Checkout summary page should be opened, but it is not.'
896
        );
897
    }
898
899
    /**
900
     * @Given I should see shipping method :shippingMethodName with fee :fee
901
     */
902
    public function iShouldSeeShippingFee($shippingMethodName, $fee)
903
    {
904
        Assert::true(
905
            $this->selectShippingPage->hasShippingMethodFee($shippingMethodName, $fee),
906
            sprintf('The shipping fee should be %s, but it does not.', $fee)
907
        );
908
    }
909
910
    /**
911
     * @When /^I complete addressing step with email "([^"]+)" and ("([^"]+)" as shipping country)$/
912
     */
913
    public function iCompleteAddressingStepWithEmail($email, AddressInterface $address)
914
    {
915
        $this->addressPage->open();
916
        $this->iSpecifyTheEmail($email);
917
        $this->iSpecifyTheShippingAddressAs($address);
918
        $this->iCompleteTheAddressingStep();
919
    }
920
921
    /**
922
     * @Given I confirm my changes
923
     */
924
    public function iConfirmMyChanges()
925
    {
926
        $this->thankYouPage->saveChanges();
927
    }
928
929
    /**
930
     * @Then the subtotal of :item item should be :price
931
     */
932
    public function theSubtotalOfItemShouldBe($item, $price)
933
    {
934
        $currentPage = $this->resolveCurrentStepPage();
935
        $actualPrice = $currentPage->getItemSubtotal($item);
936
937
        Assert::eq(
938
            $actualPrice,
939
            $price,
940
            sprintf('The %s subtotal should be %s, but is %s', $item, $price, $actualPrice)
941
        );
942
    }
943
944
    /**
945
     * @Then the :product product should have unit price :price
946
     */
947
    public function theProductShouldHaveUnitPrice(ProductInterface $product, $price)
948
    {
949
        Assert::true(
950
            $this->completePage->hasProductUnitPrice($product, $price),
951
            sprintf('Product %s should have unit price %s, but it does not have.', $product->getName(), $price)
952
        );
953
    }
954
955
    /**
956
     * @Given /^I should be notified that (this product) does not have sufficient stock$/
957
     */
958
    public function iShouldBeNotifiedThatThisProductDoesNotHaveSufficientStock(ProductInterface $product)
959
    {
960
        Assert::true(
961
            $this->completePage->hasProductOutOfStockValidationMessage($product),
962
            sprintf('I should see validation message for %s product', $product->getName())
963
        );
964
    }
965
966
    /**
967
     * @return AddressInterface
968
     */
969
    private function createDefaultAddress()
970
    {
971
        /** @var AddressInterface $address */
972
        $address = $this->addressFactory->createNew();
973
        $address->setFirstName('John');
974
        $address->setLastName('Doe');
975
        $address->setCountryCode('US');
976
        $address->setCity('North Bridget');
977
        $address->setPostcode('93-554');
978
        $address->setStreet('0635 Myron Hollow Apt. 711');
979
        $address->setPhoneNumber('321123456');
980
981
        return $address;
982
    }
983
984
    /**
985
     * @param string $type
986
     * @param string $element
987
     * @param string $expectedMessage
988
     *
989
     * @throws \InvalidArgumentException
990
     */
991
    private function assertElementValidationMessage($type, $element, $expectedMessage)
992
    {
993
        $element = sprintf('%s_%s', $type, implode('_', explode(' ', $element)));
994
        Assert::true(
995
            $this->addressPage->checkValidationMessageFor($element, $expectedMessage),
996
            sprintf('The %s should be required.', $element)
997
        );
998
    }
999
1000
    /**
1001
     * @return SymfonyPageInterface
1002
     */
1003
    private function resolveCurrentStepPage()
1004
    {
1005
        $possiblePages = [
1006
            $this->addressPage,
1007
            $this->selectPaymentPage,
1008
            $this->selectShippingPage,
1009
        ];
1010
1011
        return $this->currentPageResolver->getCurrentPageWithForm($possiblePages);
1012
    }
1013
}
1014