Completed
Push — master ( 87cbf2...406549 )
by Paweł
149:47 queued 134:45
created

iShouldHaveShippingMethodAvailableAsLastChoice()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
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
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\CompletePageInterface;
17
use Sylius\Behat\Page\Shop\Checkout\SelectPaymentPageInterface;
18
use Sylius\Behat\Page\Shop\Checkout\SelectShippingPageInterface;
19
use Sylius\Behat\Page\Shop\HomePageInterface;
20
use Sylius\Behat\Page\Shop\Order\ShowPageInterface;
21
use Sylius\Behat\Page\Shop\Order\ThankYouPageInterface;
22
use Sylius\Behat\Page\SymfonyPageInterface;
23
use Sylius\Behat\Page\UnexpectedPageException;
24
use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
25
use Sylius\Behat\Service\SharedStorageInterface;
26
use Sylius\Component\Addressing\Model\CountryInterface;
27
use Sylius\Component\Core\Formatter\StringInflector;
28
use Sylius\Component\Core\Model\AddressInterface;
29
use Sylius\Component\Core\Model\OrderInterface;
30
use Sylius\Component\Core\Model\ProductInterface;
31
use Sylius\Component\Core\Model\ShippingMethodInterface;
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 ShowPageInterface
79
     */
80
    private $orderDetails;
81
82
    /**
83
     * @var OrderRepositoryInterface
84
     */
85
    private $orderRepository;
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 ShowPageInterface $orderDetails
106
     * @param OrderRepositoryInterface $orderRepository
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
        ShowPageInterface $orderDetails,
119
        OrderRepositoryInterface $orderRepository,
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->orderDetails = $orderDetails;
131
        $this->orderRepository = $orderRepository;
132
        $this->addressFactory = $addressFactory;
133
        $this->currentPageResolver = $currentPageResolver;
134
    }
135
136
    /**
137
     * @Given I was at the checkout summary step
138
     */
139
    public function iWasAtTheCheckoutSummaryStep()
140
    {
141
        $this->iSpecifiedTheShippingAddress($this->createDefaultAddress());
142
        $this->iProceedOrderWithShippingMethodAndPayment('Free', 'Offline');
143
    }
144
145
    /**
146
     * @Given /^I proceed without selecting shipping address$/
147
     */
148
    public function iProceedWithoutSelectingShippingAddress()
149
    {
150
        $this->addressPage->open();
151
        $this->addressPage->nextStep();
152
    }
153
154
    /**
155
     * @Given I have proceeded selecting :shippingMethodName shipping method
156
     */
157
    public function iHaveProceededSelectingShippingMethod($shippingMethodName)
158
    {
159
        $this->iSelectShippingMethod($shippingMethodName);
160
        $this->selectShippingPage->nextStep();
161
    }
162
163
    /**
164
     * @Given I am at the checkout addressing step
165
     * @When I go back to addressing step of the checkout
166
     */
167
    public function iAmAtTheCheckoutAddressingStep()
168
    {
169
        $this->addressPage->open();
170
    }
171
172
    /**
173
     * @When I try to open checkout addressing page
174
     */
175
    public function iTryToOpenCheckoutAddressingPage()
176
    {
177
        $this->addressPage->tryToOpen();
178
    }
179
180
    /**
181
     * @When I try to open checkout shipping page
182
     */
183
    public function iTryToOpenCheckoutShippingPage()
184
    {
185
        $this->selectShippingPage->tryToOpen();
186
    }
187
188
    /**
189
     * @When I try to open checkout payment page
190
     */
191
    public function iTryToOpenCheckoutPaymentPage()
192
    {
193
        $this->selectPaymentPage->tryToOpen();
194
    }
195
196
    /**
197
     * @When I try to open checkout complete page
198
     */
199
    public function iTryToOpenCheckoutCompletePage()
200
    {
201
        $this->completePage->tryToOpen();
202
    }
203
204
    /**
205
     * @When /^I want to browse order details for (this order)$/
206
     */
207
    public function iWantToBrowseOrderDetailsForThisOrder(OrderInterface $order)
208
    {
209
        $this->orderDetails->open(['tokenValue' => $order->getTokenValue()]);
210
    }
211
212
    /**
213
     * @When /^I specify the shipping (address as "[^"]+", "[^"]+", "[^"]+", "[^"]+" for "[^"]+")$/
214
     * @When /^I specify the shipping (address for "[^"]+" from "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+")$/
215
     * @When /^I (do not specify any shipping address) information$/
216
     * @When /^I change the shipping (address to "[^"]+", "[^"]+", "[^"]+", "[^"]+" for "[^"]+")$/
217
     */
218
    public function iSpecifyTheShippingAddressAs(AddressInterface $address)
219
    {
220
        $key = sprintf(
221
            'shipping_address_%s_%s',
222
            strtolower($address->getFirstName()),
223
            strtolower($address->getLastName())
224
        );
225
        $this->sharedStorage->set($key, $address);
226
227
        $this->addressPage->specifyShippingAddress($address);
228
    }
229
230
    /**
231
     * @When I specify shipping country province as :province
232
     */
233
    public function iSpecifyShippingCountryProvinceAs($province)
234
    {
235
        $this->addressPage->selectShippingAddressProvince($province);
236
    }
237
238
    /**
239
     * @When I specify billing country province as :province
240
     */
241
    public function iSpecifyBillingCountryProvinceAs($province)
242
    {
243
        $this->addressPage->selectBillingAddressProvince($province);
244
    }
245
246
    /**
247
     * @When /^I specify the billing (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
248
     * @When /^I specify the billing (address for "([^"]+)" from "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)")$/
249
     * @When /^I (do not specify any billing address) information$/
250
     */
251
    public function iSpecifyTheBillingAddressAs(AddressInterface $address)
252
    {
253
        $this->iChooseTheDifferentBillingAddress();
254
        $key = sprintf(
255
            'billing_address_%s_%s',
256
            strtolower($address->getFirstName()),
257
            strtolower($address->getLastName())
258
        );
259
        $this->sharedStorage->set($key, $address);
260
261
        $this->addressPage->specifyBillingAddress($address);
262
    }
263
264
    /**
265
     * @When /^I specified the shipping (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
266
     */
267
    public function iSpecifiedTheShippingAddress(AddressInterface $address)
268
    {
269
        $this->addressPage->open();
270
        $this->iSpecifyTheShippingAddressAs($address);
271
272
        $key = sprintf('billing_address_%s_%s', strtolower($address->getFirstName()), strtolower($address->getLastName()));
273
        $this->sharedStorage->set($key, $address);
274
275
        $this->iCompleteTheAddressingStep();
276
    }
277
278
    /**
279
     * @When I choose the different billing address
280
     */
281
    public function iChooseTheDifferentBillingAddress()
282
    {
283
        $this->addressPage->chooseDifferentBillingAddress();
284
    }
285
286
    /**
287
     * @When I specify the email as :email
288
     * @When I do not specify the email
289
     */
290
    public function iSpecifyTheEmail($email = null)
291
    {
292
        $this->addressPage->specifyEmail($email);
293
    }
294
295
    /**
296
     * @Given I have selected :shippingMethod shipping method
297
     * @When I select :shippingMethod shipping method
298
     */
299
    public function iSelectShippingMethod($shippingMethod)
300
    {
301
        $this->selectShippingPage->selectShippingMethod($shippingMethod);
302
    }
303
304
    /**
305
     * @Then I should not be able to select :shippingMethodName shipping method
306
     */
307
    public function iShouldNotBeAbleToSelectShippingMethod($shippingMethodName)
308
    {
309
        Assert::false(
310
            in_array($shippingMethodName, $this->selectShippingPage->getShippingMethods(), true),
311
            sprintf('Shipping method "%s" should not be available but it does.', $shippingMethodName)
312
        );
313
    }
314
315
    /**
316
     * @Then I should have :shippingMethodName shipping method available as the first choice
317
     */
318
    public function iShouldHaveShippingMethodAvailableAsFirstChoice($shippingMethodName)
319
    {
320
        $shippingMethods = $this->selectShippingPage->getShippingMethods();
321
        $firstShippingMethod = reset($shippingMethods);
322
323
        Assert::same($shippingMethodName, $firstShippingMethod);
324
    }
325
326
    /**
327
     * @Then I should have :shippingMethodName shipping method available as the last choice
328
     */
329
    public function iShouldHaveShippingMethodAvailableAsLastChoice($shippingMethodName)
330
    {
331
        $shippingMethods = $this->selectShippingPage->getShippingMethods();
332
        $lastShippingMethod = end($shippingMethods);
333
334
        Assert::same($shippingMethodName, $lastShippingMethod);
335
    }
336
337
    /**
338
     * @Then I should have :countryName selected as country
339
     */
340
    public function iShouldHaveSelectedAsCountry($countryName)
341
    {
342
        Assert::eq(
343
            $countryName,
344
            $this->addressPage->getShippingAddressCountry(),
345
            sprintf('Shipping country should be %s but is not.', $countryName)
346
        );
347
    }
348
349
    /**
350
     * @Then I should have no country selected
351
     */
352
    public function iShouldHaveNoCountrySelected()
353
    {
354
        Assert::eq(
355
            'Select',
356
            $this->addressPage->getShippingAddressCountry(),
357
            'Shipping country should not be selected.'
358
        );
359
    }
360
361
    /**
362
     * @When I complete the addressing step
363
     * @When I try to complete the addressing step
364
     */
365
    public function iCompleteTheAddressingStep()
366
    {
367
        $this->addressPage->nextStep();
368
    }
369
370
    /**
371
     * @When I go back to store
372
     */
373
    public function iGoBackToStore()
374
    {
375
        $this->addressPage->backToStore();
376
    }
377
378
    /**
379
     * @When /^I(?:| try to) complete the shipping step$/
380
     */
381
    public function iCompleteTheShippingStep()
382
    {
383
        $this->selectShippingPage->nextStep();
384
    }
385
386
    /**
387
     * @When I decide to change my address
388
     */
389
    public function iDecideToChangeMyAddress()
390
    {
391
        $this->selectShippingPage->changeAddress();
392
    }
393
394
    /**
395
     * @When I decide to change order shipping method
396
     */
397
    public function iDecideToChangeMyShippingMethod()
398
    {
399
        $this->selectPaymentPage->changeShippingMethod();
400
    }
401
402
    /**
403
     * @When I want to browse thank you page
404
     */
405
    public function iWantToBrowseThankYouPageForThisOrder()
406
    {
407
        $this->thankYouPage->open();
408
    }
409
410
    /**
411
     * @When I go to the addressing step
412
     */
413
    public function iGoToTheAddressingStep()
414
    {
415
        if ($this->selectShippingPage->isOpen()) {
416
            $this->selectShippingPage->changeAddressByStepLabel();
417
418
            return;
419
        }
420
421
        if ($this->selectPaymentPage->isOpen()) {
422
            $this->selectPaymentPage->changeAddressByStepLabel();
423
424
            return;
425
        }
426
427
        if ($this->completePage->isOpen()) {
428
            $this->completePage->changeAddress();
429
430
            return;
431
        }
432
433
        throw new UnexpectedPageException('It is impossible to go to addressing step from current page.');
434
    }
435
436
    /**
437
     * @When I go to the shipping step
438
     */
439
    public function iGoToTheShippingStep()
440
    {
441
        if ($this->selectPaymentPage->isOpen()) {
442
            $this->selectPaymentPage->changeShippingMethodByStepLabel();
443
444
            return;
445
        }
446
447
        if ($this->completePage->isOpen()) {
448
            $this->completePage->changeShippingMethod();
449
450
            return;
451
        }
452
453
        throw new UnexpectedPageException('It is impossible to go to shipping step from current page.');
454
    }
455
456
    /**
457
     * @When I decide to change the payment method
458
     */
459
    public function iGoToThePaymentStep()
460
    {
461
        $this->completePage->changePaymentMethod();
462
    }
463
464
    /**
465
     * @When /^I proceed selecting ("[^"]+" as shipping country)$/
466
     */
467
    public function iProceedSelectingShippingCountry(CountryInterface $shippingCountry = null)
468
    {
469
        $this->addressPage->open();
470
        $shippingAddress = $this->createDefaultAddress();
471
        if (null !== $shippingCountry) {
472
            $shippingAddress->setCountryCode($shippingCountry->getCode());
473
        }
474
475
        $this->addressPage->specifyShippingAddress($shippingAddress);
476
        $this->addressPage->nextStep();
477
    }
478
479
    /**
480
     * @When /^I proceed selecting ("[^"]+" as shipping country) with "([^"]+)" method$/
481
     */
482
    public function iProceedSelectingShippingCountryAndShippingMethod(CountryInterface $shippingCountry = null, $shippingMethodName)
483
    {
484
        $this->iProceedSelectingShippingCountry($shippingCountry);
485
486
        $this->selectShippingPage->selectShippingMethod($shippingMethodName ?: 'Free');
487
        $this->selectShippingPage->nextStep();
488
    }
489
490
    /**
491
     * @When /^I proceed selecting "([^"]+)" shipping method$/
492
     * @Given /^I chose "([^"]*)" shipping method$/
493
     */
494
    public function iProceedSelectingShippingMethod($shippingMethodName)
495
    {
496
        $this->iProceedSelectingShippingCountryAndShippingMethod(null, $shippingMethodName);
497
    }
498
499
    /**
500
     * @When /^I choose "([^"]*)" payment method$/
501
     */
502
    public function iChoosePaymentMethod($paymentMethodName)
503
    {
504
        $this->selectPaymentPage->selectPaymentMethod($paymentMethodName ?: 'Offline');
505
        $this->selectPaymentPage->nextStep();
506
    }
507
508
    /**
509
     * @When I change payment method to :paymentMethodName
510
     */
511
    public function iChangePaymentMethodTo($paymentMethodName)
512
    {
513
        $this->orderDetails->choosePaymentMethod($paymentMethodName);
514
    }
515
516
    /**
517
     * @When /^I proceed selecting "([^"]*)" as shipping country with "([^"]*)" payment method$/
518
     */
519
    public function iProceedSelectingShippingCountryAndPaymentMethod($shippingCountry, $paymentMethodName)
520
    {
521
        $this->iProceedSelectingShippingCountryAndShippingMethod($shippingCountry, null);
522
523
        $this->iChoosePaymentMethod($paymentMethodName);
524
    }
525
526
    /**
527
     * @When I go back to shipping step of the checkout
528
     */
529
    public function iGoBackToShippingStepOfTheCheckout()
530
    {
531
        $this->selectShippingPage->open();
532
    }
533
534
    /**
535
     * @Given I have proceeded selecting :paymentMethodName payment method
536
     * @When /^I (?:proceed|proceeded) selecting "([^"]+)" payment method$/
537
     */
538
    public function iProceedSelectingPaymentMethod($paymentMethodName = 'Offline')
539
    {
540
        $this->iProceedSelectingShippingCountryAndPaymentMethod(null, $paymentMethodName);
541
    }
542
543
    /**
544
     * @When /^I change shipping method to "([^"]*)"$/
545
     */
546
    public function iChangeShippingMethod($shippingMethodName)
547
    {
548
        $this->selectPaymentPage->changeShippingMethod();
549
        $this->selectShippingPage->selectShippingMethod($shippingMethodName);
550
        $this->selectShippingPage->nextStep();
551
    }
552
553
    /**
554
     * @When /^I provide additional note like "([^"]+)"$/
555
     */
556
    public function iProvideAdditionalNotesLike($notes)
557
    {
558
        $this->sharedStorage->set('additional_note', $notes);
559
        $this->completePage->addNotes($notes);
560
    }
561
562
    /**
563
     * @When /^I proceed as guest "([^"]*)" with ("[^"]+" as shipping country)$/
564
     */
565
    public function iProceedLoggingAsGuestWithAsShippingCountry($email, CountryInterface $shippingCountry = null)
566
    {
567
        $this->addressPage->open();
568
        $this->addressPage->specifyEmail($email);
569
        $shippingAddress = $this->createDefaultAddress();
570
        if (null !== $shippingCountry) {
571
            $shippingAddress->setCountryCode($shippingCountry->getCode());
572
        }
573
574
        $this->addressPage->specifyShippingAddress($shippingAddress);
575
        $this->addressPage->nextStep();
576
    }
577
578
    /**
579
     * @When I return to the checkout summary step
580
     */
581
    public function iReturnToTheCheckoutSummaryStep()
582
    {
583
        $this->completePage->open();
584
    }
585
586
    /**
587
     * @When I want to complete checkout
588
     */
589
    public function iWantToCompleteCheckout()
590
    {
591
        $this->completePage->tryToOpen();
592
    }
593
594
    /**
595
     * @Given I have confirmed my order
596
     * @When I confirm my order
597
     */
598
    public function iConfirmMyOrder()
599
    {
600
        $this->completePage->confirmOrder();
601
    }
602
603
    /**
604
     * @When I specify the password as :password
605
     */
606
    public function iSpecifyThePasswordAs($password)
607
    {
608
        $this->addressPage->specifyPassword($password);
609
    }
610
611
    /**
612
     * @When I sign in
613
     */
614
    public function iSignIn()
615
    {
616
        $this->addressPage->signIn();
617
    }
618
619
    /**
620
     * @Then I should see the thank you page
621
     */
622
    public function iShouldSeeTheThankYouPage()
623
    {
624
        Assert::true(
625
            $this->thankYouPage->hasThankYouMessage(),
626
            'I should see thank you message, but I do not.'
627
        );
628
    }
629
630
    /**
631
     * @Then I should not see the thank you page
632
     */
633
    public function iShouldNotSeeTheThankYouPage()
634
    {
635
        Assert::false(
636
            $this->thankYouPage->isOpen(),
637
            'I should not see thank you message, but I do.'
638
        );
639
    }
640
641
    /**
642
     * @Given I should be informed with :paymentMethod payment method instructions
643
     */
644
    public function iShouldBeInformedWithPaymentMethodInstructions(PaymentMethodInterface $paymentMethod)
645
    {
646
        Assert::same(
647
            $this->thankYouPage->getInstructions(),
648
            $paymentMethod->getInstructions()
649
        );
650
    }
651
652
    /**
653
     * @Then /^I should be redirected (?:|back )to the thank you page$/
654
     */
655
    public function iShouldBeRedirectedBackToTheThankYouPage()
656
    {
657
        $this->thankYouPage->waitForResponse(5);
658
659
        Assert::true(
660
            $this->thankYouPage->isOpen(),
661
            'I should be on thank you page, but I am not.'
662
        );
663
    }
664
665
    /**
666
     * @Then I should be on the checkout shipping step
667
     */
668
    public function iShouldBeOnTheCheckoutShippingStep()
669
    {
670
        Assert::true(
671
            $this->selectShippingPage->isOpen(),
672
            'Checkout shipping page should be opened, but it is not.'
673
        );
674
    }
675
676
    /**
677
     * @Then I should be on the checkout payment step
678
     */
679
    public function iShouldBeOnTheCheckoutPaymentStep()
680
    {
681
        Assert::true(
682
            $this->selectPaymentPage->isOpen(),
683
            'Checkout payment page should be opened, but it is not.'
684
        );
685
    }
686
687
    /**
688
     * @Then I should be on the checkout summary step
689
     */
690
    public function iShouldBeOnTheCheckoutSummaryStep()
691
    {
692
        Assert::true(
693
            $this->completePage->isOpen(),
694
            'Checkout summary page should be opened, but it is not.'
695
        );
696
    }
697
698
    /**
699
     * @Then /^I should(?:| also) be notified that the "([^"]+)" and the "([^"]+)" in (shipping|billing) details are required$/
700
     */
701
    public function iShouldBeNotifiedThatTheAndTheInShippingDetailsAreRequired($firstElement, $secondElement, $type)
702
    {
703
        $this->assertElementValidationMessage($type, $firstElement, sprintf('Please enter %s.', $firstElement));
704
        $this->assertElementValidationMessage($type, $secondElement, sprintf('Please enter %s.', $secondElement));
705
    }
706
707
    /**
708
     * @Then I should be informed that my order cannot be shipped to this address
709
     */
710
    public function iShouldBeInformedThatMyOrderCannotBeShippedToThisAddress()
711
    {
712
        Assert::true(
713
            $this->selectShippingPage->hasNoShippingMethodsMessage(),
714
            'Shipping page should have no shipping methods message but it does not.'
715
        );
716
    }
717
718
    /**
719
     * @Then I should be able to log in
720
     */
721
    public function iShouldBeAbleToLogIn()
722
    {
723
        Assert::true(
724
            $this->addressPage->canSignIn(),
725
            'I should be able to login, but I am not.'
726
        );
727
    }
728
729
    /**
730
     * @Then the login form should no longer be accessible
731
     */
732
    public function theLoginFormShouldNoLongerBeAccessible()
733
    {
734
        Assert::false(
735
            $this->addressPage->canSignIn(),
736
            'I should not be able to login, but I am.'
737
        );
738
    }
739
740
    /**
741
     * @Then I should be notified about bad credentials
742
     */
743
    public function iShouldBeNotifiedAboutBadCredentials()
744
    {
745
        Assert::true(
746
            $this->addressPage->checkInvalidCredentialsValidation(),
747
            'I should see validation error, but I do not.'
748
        );
749
    }
750
751
    /**
752
     * @Then my order's shipping address should be to :fullName
753
     */
754
    public function iShouldSeeThisShippingAddressAsShippingAddress($fullName)
755
    {
756
        $address = $this->sharedStorage->get('shipping_address_'.StringInflector::nameToLowercaseCode($fullName));
757
        Assert::true(
758
            $this->completePage->hasShippingAddress($address),
759
            'Shipping address is improper.'
760
        );
761
    }
762
763
    /**
764
     * @Then my order's billing address should be to :fullName
765
     */
766
    public function iShouldSeeThisBillingAddressAsBillingAddress($fullName)
767
    {
768
        $address = $this->sharedStorage->get('billing_address_'.StringInflector::nameToLowercaseCode($fullName));
769
        Assert::true(
770
            $this->completePage->hasBillingAddress($address),
771
            'Billing address is improper.'
772
        );
773
    }
774
775
    /**
776
     * @Then address to :fullName should be used for both shipping and billing of my order
777
     */
778
    public function iShouldSeeThisShippingAddressAsShippingAndBillingAddress($fullName)
779
    {
780
        $this->iShouldSeeThisShippingAddressAsShippingAddress($fullName);
781
        $this->iShouldSeeThisBillingAddressAsBillingAddress($fullName);
782
    }
783
784
    /**
785
     * @Given I am at the checkout payment step
786
     * @When I go back to payment step of the checkout
787
     */
788
    public function iAmAtTheCheckoutPaymentStep()
789
    {
790
        $this->selectPaymentPage->open();
791
    }
792
793
    /**
794
     * @When I complete the payment step
795
     */
796
    public function iCompleteThePaymentStep()
797
    {
798
        $this->selectPaymentPage->nextStep();
799
    }
800
801
    /**
802
     * @When I select :name payment method
803
     */
804
    public function iSelectPaymentMethod($name)
805
    {
806
        $this->selectPaymentPage->selectPaymentMethod($name);
807
    }
808
809
    /**
810
     * @When /^I do not modify anything$/
811
     */
812
    public function iDoNotModifyAnything()
813
    {
814
        // Intentionally left blank to fulfill context expectation
815
    }
816
817
    /**
818
     * @Then I should not be able to select :paymentMethodName payment method
819
     */
820
    public function iShouldNotBeAbleToSelectPaymentMethod($paymentMethodName)
821
    {
822
        Assert::false(
823
            $this->selectPaymentPage->hasPaymentMethod($paymentMethodName),
824
            sprintf('Payment method "%s" should not be available, but it does.', $paymentMethodName)
825
        );
826
    }
827
828
    /**
829
     * @Then I should be able to select :paymentMethodName payment method
830
     */
831
    public function iShouldBeAbleToSelectPaymentMethod($paymentMethodName)
832
    {
833
        Assert::true(
834
            $this->selectPaymentPage->hasPaymentMethod($paymentMethodName),
835
            sprintf('Payment method "%s" should be available, but it does not.', $paymentMethodName)
836
        );
837
    }
838
839
    /**
840
     * @Given I have proceeded order with :shippingMethod shipping method and :paymentMethod payment
841
     * @When I proceed with :shippingMethod shipping method and :paymentMethod payment
842
     */
843
    public function iProceedOrderWithShippingMethodAndPayment($shippingMethod, $paymentMethod)
844
    {
845
        $this->iSelectShippingMethod($shippingMethod);
846
        $this->iCompleteTheShippingStep();
847
        $this->iSelectPaymentMethod($paymentMethod);
848
        $this->iCompleteThePaymentStep();
849
    }
850
851
    /**
852
     * @Given I should have :quantity :productName products in the cart
853
     */
854
    public function iShouldHaveProductsInTheCart($quantity, $productName)
855
    {
856
        Assert::true(
857
            $this->completePage->hasItemWithProductAndQuantity($productName, $quantity),
858
            sprintf('There is no "%s" with quantity %s on order summary page, but it should.', $productName, $quantity)
859
        );
860
    }
861
862
    /**
863
     * @Then my order shipping should be :price
864
     */
865
    public function myOrderShippingShouldBe($price)
866
    {
867
        Assert::true(
868
            $this->completePage->hasShippingTotal($price),
869
            sprintf('The shipping total should be %s, but it is not.',$price)
870
        );
871
    }
872
873
    /**
874
     * @Then /^the ("[^"]+" product) should have unit price discounted by ("\$\d+")$/
875
     */
876
    public function theShouldHaveUnitPriceDiscountedFor(ProductInterface $product, $amount)
877
    {
878
        Assert::true(
879
            $this->completePage->hasProductDiscountedUnitPriceBy($product, $amount),
880
            sprintf('Product %s should have discounted price by %s, but it does not have.', $product->getName(), $amount)
881
        );
882
    }
883
884
    /**
885
     * @Then /^my order total should be ("(?:\£|\$)\d+")$/
886
     */
887
    public function myOrderTotalShouldBe($total)
888
    {
889
        Assert::true(
890
            $this->completePage->hasOrderTotal($total),
891
            sprintf('Order total should have %s total, but it does not have.', $total)
892
        );
893
    }
894
895
    /**
896
     * @Then my order promotion total should be :promotionTotal
897
     */
898
    public function myOrderPromotionTotalShouldBe($promotionTotal)
899
    {
900
        Assert::true(
901
            $this->completePage->hasPromotionTotal($promotionTotal),
902
            sprintf('The total discount should be %s, but it does not.', $promotionTotal)
903
        );
904
    }
905
906
    /**
907
     * @Then :promotionName should be applied to my order
908
     */
909
    public function shouldBeAppliedToMyOrder($promotionName)
910
    {
911
        Assert::true(
912
            $this->completePage->hasPromotion($promotionName),
913
            sprintf('The promotion %s should appear on the page, but it does not.', $promotionName)
914
        );
915
    }
916
917
    /**
918
     * @Given my tax total should be :taxTotal
919
     */
920
    public function myTaxTotalShouldBe($taxTotal)
921
    {
922
        Assert::true(
923
            $this->completePage->hasTaxTotal($taxTotal),
924
            sprintf('The tax total should be %s, but it does not.', $taxTotal)
925
        );
926
    }
927
928
    /**
929
     * @Then my order's shipping method should be :shippingMethod
930
     */
931
    public function myOrderSShippingMethodShouldBe(ShippingMethodInterface $shippingMethod)
932
    {
933
        Assert::true(
934
            $this->completePage->hasShippingMethod($shippingMethod),
935
            sprintf('I should see %s shipping method, but I do not.', $shippingMethod->getName())
936
        );
937
    }
938
939
    /**
940
     * @Then my order's payment method should be :paymentMethod
941
     */
942
    public function myOrderSPaymentMethodShouldBe(PaymentMethodInterface $paymentMethod)
943
    {
944
        Assert::true(
945
            $this->completePage->hasPaymentMethod($paymentMethod),
946
            sprintf('I should see %s payment method, but I do not.', $paymentMethod->getName())
947
        );
948
    }
949
950
    /**
951
     * @Then I should be redirected to the homepage
952
     */
953
    public function iShouldBeRedirectedToTheHomepage()
954
    {
955
        Assert::true(
956
            $this->homePage->isOpen(),
957
            'Shop homepage should be opened, but it is not.'
958
        );
959
    }
960
961
    /**
962
     * @Then I should be redirected to the addressing step
963
     */
964
    public function iShouldBeRedirectedToTheAddressingStep()
965
    {
966
        Assert::true(
967
            $this->addressPage->isOpen(),
968
            'Checkout addressing step should be opened, but it is not.'
969
        );
970
    }
971
972
    /**
973
     * @Given I should be able to go to the shipping step again
974
     */
975
    public function iShouldBeAbleToGoToTheShippingStepAgain()
976
    {
977
        $this->addressPage->nextStep();
978
979
        Assert::true(
980
            $this->selectShippingPage->isOpen(),
981
            'Checkout shipping step should be opened, but it is not.'
982
        );
983
    }
984
985
    /**
986
     * @Then I should be redirected to the shipping step
987
     */
988
    public function iShouldBeRedirectedToTheShippingStep()
989
    {
990
        Assert::true(
991
            $this->selectShippingPage->isOpen(),
992
            'Checkout shipping step should be opened, but it is not.'
993
        );
994
    }
995
996
    /**
997
     * @Then /^I should be able to pay(?| again)$/
998
     */
999
    public function iShouldBeAbleToPayAgain()
1000
    {
1001
        Assert::true(
1002
            $this->orderDetails->hasPayAction(),
1003
            'I should be able to pay, but I am not able to.'
1004
        );
1005
    }
1006
1007
    /**
1008
     * @Then I should not be able to pay
1009
     */
1010
    public function iShouldNotBeAbleToPayAgain()
1011
    {
1012
        Assert::false(
1013
            $this->orderDetails->hasPayAction(),
1014
            'I should not be able to pay, but I am able to.'
1015
        );
1016
    }
1017
1018
    /**
1019
     * @Given I should be able to go to the payment step again
1020
     */
1021
    public function iShouldBeAbleToGoToThePaymentStepAgain()
1022
    {
1023
        $this->selectShippingPage->nextStep();
1024
1025
        Assert::true(
1026
            $this->selectPaymentPage->isOpen(),
1027
            'Checkout payment step should be opened, but it is not.'
1028
        );
1029
    }
1030
1031
    /**
1032
     * @Then I should be redirected to the payment step
1033
     */
1034
    public function iShouldBeRedirectedToThePaymentStep()
1035
    {
1036
        Assert::true(
1037
            $this->selectPaymentPage->isOpen(),
1038
            'Checkout payment step should be opened, but it is not.'
1039
        );
1040
    }
1041
1042
    /**
1043
     * @Given I should be able to go to the summary page again
1044
     */
1045
    public function iShouldBeAbleToGoToTheSummaryPageAgain()
1046
    {
1047
        $this->selectPaymentPage->nextStep();
1048
1049
        Assert::true(
1050
            $this->completePage->isOpen(),
1051
            'Checkout summary page should be opened, but it is not.'
1052
        );
1053
    }
1054
1055
    /**
1056
     * @Given I should see shipping method :shippingMethodName with fee :fee
1057
     */
1058
    public function iShouldSeeShippingFee($shippingMethodName, $fee)
1059
    {
1060
        Assert::true(
1061
            $this->selectShippingPage->hasShippingMethodFee($shippingMethodName, $fee),
1062
            sprintf('The shipping fee should be %s, but it does not.', $fee)
1063
        );
1064
    }
1065
1066
    /**
1067
     * @Given /^I have completed addressing step with email "([^"]+)" and ("[^"]+" based shipping address)$/
1068
     * @When /^I complete addressing step with email "([^"]+)" and ("[^"]+" based shipping address)$/
1069
     */
1070
    public function iCompleteAddressingStepWithEmail($email, AddressInterface $address)
1071
    {
1072
        $this->addressPage->open();
1073
        $this->iSpecifyTheEmail($email);
1074
        $this->iSpecifyTheShippingAddressAs($address);
1075
        $this->iCompleteTheAddressingStep();
1076
    }
1077
1078
    /**
1079
     * @Then the subtotal of :item item should be :price
1080
     */
1081
    public function theSubtotalOfItemShouldBe($item, $price)
1082
    {
1083
        $currentPage = $this->resolveCurrentStepPage();
1084
        $actualPrice = $currentPage->getItemSubtotal($item);
1085
1086
        Assert::eq(
1087
            $actualPrice,
1088
            $price,
1089
            sprintf('The %s subtotal should be %s, but is %s', $item, $price, $actualPrice)
1090
        );
1091
    }
1092
1093
    /**
1094
     * @Then the :product product should have unit price :price
1095
     */
1096
    public function theProductShouldHaveUnitPrice(ProductInterface $product, $price)
1097
    {
1098
        Assert::true(
1099
            $this->completePage->hasProductUnitPrice($product, $price),
1100
            sprintf('Product %s should have unit price %s, but it does not have.', $product->getName(), $price)
1101
        );
1102
    }
1103
1104
    /**
1105
     * @Given /^I should be notified that (this product) does not have sufficient stock$/
1106
     */
1107
    public function iShouldBeNotifiedThatThisProductDoesNotHaveSufficientStock(ProductInterface $product)
1108
    {
1109
        Assert::true(
1110
            $this->completePage->hasProductOutOfStockValidationMessage($product),
1111
            sprintf('I should see validation message for %s product', $product->getName())
1112
        );
1113
    }
1114
1115
    /**
1116
     * @Then my order's locale should be :localeName
1117
     */
1118
    public function myOrderSLocaleShouldBe($localeName)
1119
    {
1120
        Assert::true(
1121
            $this->completePage->hasLocale($localeName),
1122
            'Order locale code is improper.'
1123
        );
1124
    }
1125
1126
    /**
1127
     * @Then my order's currency should be :currencyCode
1128
     */
1129
    public function myOrderSCurrencyShouldBe($currencyCode)
1130
    {
1131
        Assert::true(
1132
            $this->completePage->hasCurrency($currencyCode),
1133
            'Order currency code is improper.'
1134
        );
1135
    }
1136
1137
    /**
1138
     * @Then /^I should not be notified that (this product) does not have sufficient stock$/
1139
     */
1140
    public function iShouldNotBeNotifiedThatThisProductDoesNotHaveSufficientStock(ProductInterface $product)
1141
    {
1142
        Assert::false(
1143
            $this->completePage->hasProductOutOfStockValidationMessage($product),
1144
            sprintf('I should see validation message for %s product', $product->getName())
1145
        );
1146
    }
1147
1148
    /**
1149
     * @Then I should be on the checkout addressing step
1150
     */
1151
    public function iShouldBeOnTheCheckoutAddressingStep()
1152
    {
1153
        Assert::true(
1154
            $this->addressPage->isOpen(),
1155
            'Checkout addressing page should be opened, but it is not.'
1156
        );
1157
    }
1158
1159
    /**
1160
     * @When I specify the province name manually as :provinceName for shipping address
1161
     */
1162
    public function iSpecifyTheProvinceNameManuallyAsForShippingAddress($provinceName)
1163
    {
1164
        $this->addressPage->specifyShippingAddressProvince($provinceName);
1165
    }
1166
1167
    /**
1168
     * @When I specify the province name manually as :provinceName for billing address
1169
     */
1170
    public function iSpecifyTheProvinceNameManuallyAsForBillingAddress($provinceName)
1171
    {
1172
        $this->addressPage->specifyBillingAddressProvince($provinceName);
1173
    }
1174
1175
    /**
1176
     * @Then I should not be able to specify province name manually for shipping address
1177
     */
1178
    public function iShouldNotBeAbleToSpecifyProvinceNameManuallyForShippingAddress()
1179
    {
1180
        Assert::false(
1181
            $this->addressPage->hasShippingAddressInput(),
1182
            'I should not be able to specify manually the province for shipping address, but I can.'
1183
        );
1184
    }
1185
1186
    /**
1187
     * @Then I should not be able to specify province name manually for billing address
1188
     */
1189
    public function iShouldNotBeAbleToSpecifyProvinceNameManuallyForBillingAddress()
1190
    {
1191
        Assert::false(
1192
            $this->addressPage->hasBillingAddressInput(),
1193
            'I should not be able to specify manually the province for billing address, but I can.'
1194
        );
1195
    }
1196
1197
    /**
1198
     * @Then I should see :provinceName in the shipping address
1199
     */
1200
    public function iShouldSeeInTheShippingAddress($provinceName)
1201
    {
1202
        Assert::true(
1203
            $this->completePage->hasShippingProvinceName($provinceName),
1204
            sprintf('Cannot find shipping address with province %s', $provinceName)
1205
        );
1206
    }
1207
1208
    /**
1209
     * @Then I should see :provinceName in the billing address
1210
     */
1211
    public function iShouldSeeInTheBillingAddress($provinceName)
1212
    {
1213
        Assert::true(
1214
            $this->completePage->hasBillingProvinceName($provinceName),
1215
            sprintf('Cannot find billing address with province %s', $provinceName)
1216
        );
1217
    }
1218
1219
    /**
1220
     * @When I do not select any shipping method
1221
     */
1222
    public function iDoNotSelectAnyShippingMethod()
1223
    {
1224
        // Intentionally left blank to fulfill context expectation
1225
    }
1226
1227
    /**
1228
     * @Then I should still be on the shipping step
1229
     */
1230
    public function iShouldStillBeOnTheShippingStep()
1231
    {
1232
        Assert::true(
1233
            $this->selectShippingPage->isOpen(),
1234
            'Select shipping page should be open, but it does not.'
1235
        );
1236
    }
1237
1238
    /**
1239
     * @Then I should be notified that the shipping method is required
1240
     */
1241
    public function iShouldBeNotifiedThatTheShippingMethodIsRequired()
1242
    {
1243
        Assert::same(
1244
            $this->selectShippingPage->getValidationMessageForShipment(),
1245
            'Please select shipping method.'
1246
        );
1247
    }
1248
1249
    /**
1250
     * @Then there should be information about no shipping methods available for my shipping address
1251
     */
1252
    public function thereShouldBeInformationAboutNoShippingMethodsAvailableForMyShippingAddress()
1253
    {
1254
        Assert::true(
1255
            $this->selectShippingPage->hasNoAvailableShippingMethodsWarning(),
1256
            'There should be warning about no available shipping methods, but it does not.'
1257
        );
1258
    }
1259
1260
    /**
1261
     * @Then I should not be able to complete the shipping step
1262
     */
1263
    public function iShouldNotBeAbleToCompleteTheShippingStep()
1264
    {
1265
        Assert::true(
1266
            $this->selectShippingPage->isNextStepButtonUnavailable(),
1267
            'The next step button should be disabled, but it does not.'
1268
        );
1269
    }
1270
1271
    /**
1272
     * @When I do not select any payment method
1273
     */
1274
    public function iDoNotSelectAnyPaymentMethod()
1275
    {
1276
        // Intentionally left blank to fulfill context expectation
1277
    }
1278
1279
    /**
1280
     * @Then I should not be able to complete the payment step
1281
     */
1282
    public function iShouldNotBeAbleToCompleteThePaymentStep()
1283
    {
1284
        Assert::true(
1285
            $this->selectPaymentPage->isNextStepButtonUnavailable(),
1286
           'The "next step" button should be disabled.'
1287
        );
1288
    }
1289
1290
    /**
1291
     * @Then there should be information about no payment methods available for my order
1292
     */
1293
    public function thereShouldBeInformationAboutNoPaymentMethodsAvailableForMyOrder()
1294
    {
1295
        Assert::true(
1296
            $this->selectPaymentPage->hasNoAvailablePaymentMethodsWarning(),
1297
            'There should be warning about no available payment methods, but it does not.'
1298
        );
1299
    }
1300
1301
    /**
1302
     * @return AddressInterface
1303
     */
1304
    private function createDefaultAddress()
1305
    {
1306
        /** @var AddressInterface $address */
1307
        $address = $this->addressFactory->createNew();
1308
        $address->setFirstName('John');
1309
        $address->setLastName('Doe');
1310
        $address->setCountryCode('US');
1311
        $address->setCity('North Bridget');
1312
        $address->setPostcode('93-554');
1313
        $address->setStreet('0635 Myron Hollow Apt. 711');
1314
        $address->setPhoneNumber('321123456');
1315
1316
        return $address;
1317
    }
1318
1319
    /**
1320
     * @param string $type
1321
     * @param string $element
1322
     * @param string $expectedMessage
1323
     *
1324
     * @throws \InvalidArgumentException
1325
     */
1326
    private function assertElementValidationMessage($type, $element, $expectedMessage)
1327
    {
1328
        $element = sprintf('%s_%s', $type, implode('_', explode(' ', $element)));
1329
        Assert::true(
1330
            $this->addressPage->checkValidationMessageFor($element, $expectedMessage),
1331
            sprintf('The %s should be required.', $element)
1332
        );
1333
    }
1334
1335
    /**
1336
     * @return SymfonyPageInterface
1337
     */
1338
    private function resolveCurrentStepPage()
1339
    {
1340
        $possiblePages = [
1341
            $this->addressPage,
1342
            $this->selectPaymentPage,
1343
            $this->selectShippingPage,
1344
        ];
1345
1346
        return $this->currentPageResolver->getCurrentPageWithForm($possiblePages);
1347
    }
1348
}
1349