Completed
Push — symfony3-fqcn-sylius ( 26083b...02605f )
by Kamil
20:07
created

CheckoutContext::iShouldSeeShippingMethod()   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\Comparator\AddressComparatorInterface;
27
use Sylius\Component\Addressing\Model\CountryInterface;
28
use Sylius\Component\Core\Formatter\StringInflector;
29
use Sylius\Component\Core\Model\AddressInterface;
30
use Sylius\Component\Core\Model\OrderInterface;
31
use Sylius\Component\Core\Model\ProductInterface;
32
use Sylius\Component\Core\Model\ShippingMethodInterface;
33
use Sylius\Component\Order\Repository\OrderRepositoryInterface;
34
use Sylius\Component\Payment\Model\PaymentMethodInterface;
35
use Sylius\Component\Resource\Factory\FactoryInterface;
36
use Webmozart\Assert\Assert;
37
38
/**
39
 * @author Arkadiusz Krakowiak <[email protected]>
40
 */
41
final class CheckoutContext implements Context
42
{
43
    /**
44
     * @var SharedStorageInterface
45
     */
46
    private $sharedStorage;
47
48
    /**
49
     * @var HomePageInterface
50
     */
51
    private $homePage;
52
53
    /**
54
     * @var AddressPageInterface
55
     */
56
    private $addressPage;
57
58
    /**
59
     * @var SelectPaymentPageInterface
60
     */
61
    private $selectPaymentPage;
62
63
    /**
64
     * @var ThankYouPageInterface
65
     */
66
    private $thankYouPage;
67
68
    /**
69
     * @var SelectShippingPageInterface
70
     */
71
    private $selectShippingPage;
72
73
    /**
74
     * @var CompletePageInterface
75
     */
76
    private $completePage;
77
78
    /**
79
     * @var ShowPageInterface
80
     */
81
    private $orderDetails;
82
83
    /**
84
     * @var OrderRepositoryInterface
85
     */
86
    private $orderRepository;
87
88
    /**
89
     * @var FactoryInterface
90
     */
91
    private $addressFactory;
92
93
    /**
94
     * @var CurrentPageResolverInterface
95
     */
96
    private $currentPageResolver;
97
98
    /**
99
     * @var AddressComparatorInterface
100
     */
101
    private $addressComparator;
102
103
    /**
104
     * @param SharedStorageInterface $sharedStorage
105
     * @param HomePageInterface $homePage
106
     * @param AddressPageInterface $addressPage
107
     * @param SelectPaymentPageInterface $selectPaymentPage
108
     * @param ThankYouPageInterface $thankYouPage
109
     * @param SelectShippingPageInterface $selectShippingPage
110
     * @param CompletePageInterface $completePage
111
     * @param ShowPageInterface $orderDetails
112
     * @param OrderRepositoryInterface $orderRepository
113
     * @param FactoryInterface $addressFactory
114
     * @param CurrentPageResolverInterface $currentPageResolver
115
     * @param AddressComparatorInterface $addressComparator
116
     */
117
    public function __construct(
118
        SharedStorageInterface $sharedStorage,
119
        HomePageInterface $homePage,
120
        AddressPageInterface $addressPage,
121
        SelectPaymentPageInterface $selectPaymentPage,
122
        ThankYouPageInterface $thankYouPage,
123
        SelectShippingPageInterface $selectShippingPage,
124
        CompletePageInterface $completePage,
125
        ShowPageInterface $orderDetails,
126
        OrderRepositoryInterface $orderRepository,
127
        FactoryInterface $addressFactory,
128
        CurrentPageResolverInterface $currentPageResolver,
129
        AddressComparatorInterface $addressComparator
130
    ) {
131
        $this->sharedStorage = $sharedStorage;
132
        $this->homePage = $homePage;
133
        $this->addressPage = $addressPage;
134
        $this->selectPaymentPage = $selectPaymentPage;
135
        $this->thankYouPage = $thankYouPage;
136
        $this->selectShippingPage = $selectShippingPage;
137
        $this->completePage = $completePage;
138
        $this->orderDetails = $orderDetails;
139
        $this->orderRepository = $orderRepository;
140
        $this->addressFactory = $addressFactory;
141
        $this->currentPageResolver = $currentPageResolver;
142
        $this->addressComparator = $addressComparator;
143
    }
144
145
    /**
146
     * @Given I was at the checkout summary step
147
     */
148
    public function iWasAtTheCheckoutSummaryStep()
149
    {
150
        $this->iSpecifiedTheShippingAddress($this->createDefaultAddress());
151
        $this->iProceedOrderWithShippingMethodAndPayment('Free', 'Offline');
152
    }
153
154
    /**
155
     * @Given /^I proceed without selecting shipping address$/
156
     */
157
    public function iProceedWithoutSelectingShippingAddress()
158
    {
159
        $this->addressPage->open();
160
        $this->addressPage->nextStep();
161
    }
162
163
    /**
164
     * @Given I have proceeded selecting :shippingMethodName shipping method
165
     */
166
    public function iHaveProceededSelectingShippingMethod($shippingMethodName)
167
    {
168
        $this->iSelectShippingMethod($shippingMethodName);
169
        $this->selectShippingPage->nextStep();
170
    }
171
172
    /**
173
     * @Given I am at the checkout addressing step
174
     * @When I go back to addressing step of the checkout
175
     */
176
    public function iAmAtTheCheckoutAddressingStep()
177
    {
178
        $this->addressPage->open();
179
    }
180
181
    /**
182
     * @When I try to open checkout addressing page
183
     */
184
    public function iTryToOpenCheckoutAddressingPage()
185
    {
186
        $this->addressPage->tryToOpen();
187
    }
188
189
    /**
190
     * @When I try to open checkout shipping page
191
     */
192
    public function iTryToOpenCheckoutShippingPage()
193
    {
194
        $this->selectShippingPage->tryToOpen();
195
    }
196
197
    /**
198
     * @When I try to open checkout payment page
199
     */
200
    public function iTryToOpenCheckoutPaymentPage()
201
    {
202
        $this->selectPaymentPage->tryToOpen();
203
    }
204
205
    /**
206
     * @When I try to open checkout complete page
207
     */
208
    public function iTryToOpenCheckoutCompletePage()
209
    {
210
        $this->completePage->tryToOpen();
211
    }
212
213
    /**
214
     * @When /^I want to browse order details for (this order)$/
215
     */
216
    public function iWantToBrowseOrderDetailsForThisOrder(OrderInterface $order)
217
    {
218
        $this->orderDetails->open(['tokenValue' => $order->getTokenValue()]);
219
    }
220
221
    /**
222
     * @When /^I choose ("[^"]+" street) for shipping address$/
223
     */
224
    public function iChooseForShippingAddress(AddressInterface $address)
225
    {
226
        $this->addressPage->selectShippingAddressFromAddressBook($address);
227
    }
228
229
    /**
230
     * @When /^I choose ("[^"]+" street) for billing address$/
231
     */
232
    public function iChooseForBillingAddress(AddressInterface $address)
233
    {
234
        $this->addressPage->chooseDifferentBillingAddress();
235
        $this->addressPage->selectBillingAddressFromAddressBook($address);
236
    }
237
238
    /**
239
     * @When /^I specify the shipping (address as "[^"]+", "[^"]+", "[^"]+", "[^"]+" for "[^"]+")$/
240
     * @When /^I specify the shipping (address for "[^"]+" from "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+")$/
241
     * @When /^I (do not specify any shipping address) information$/
242
     * @When /^I change the shipping (address to "[^"]+", "[^"]+", "[^"]+", "[^"]+" for "[^"]+")$/
243
     */
244
    public function iSpecifyTheShippingAddressAs(AddressInterface $address)
245
    {
246
        $key = sprintf(
247
            'shipping_address_%s_%s',
248
            strtolower($address->getFirstName()),
249
            strtolower($address->getLastName())
250
        );
251
        $this->sharedStorage->set($key, $address);
252
253
        $this->addressPage->specifyShippingAddress($address);
254
    }
255
256
    /**
257
     * @When I specify shipping country province as :province
258
     */
259
    public function iSpecifyShippingCountryProvinceAs($province)
260
    {
261
        $this->addressPage->selectShippingAddressProvince($province);
262
    }
263
264
    /**
265
     * @When I specify billing country province as :province
266
     */
267
    public function iSpecifyBillingCountryProvinceAs($province)
268
    {
269
        $this->addressPage->selectBillingAddressProvince($province);
270
    }
271
272
    /**
273
     * @When /^I specify the billing (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
274
     * @When /^I specify the billing (address for "([^"]+)" from "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)")$/
275
     * @When /^I (do not specify any billing address) information$/
276
     */
277
    public function iSpecifyTheBillingAddressAs(AddressInterface $address)
278
    {
279
        $this->iChooseTheDifferentBillingAddress();
280
        $key = sprintf(
281
            'billing_address_%s_%s',
282
            strtolower($address->getFirstName()),
283
            strtolower($address->getLastName())
284
        );
285
        $this->sharedStorage->set($key, $address);
286
287
        $this->addressPage->specifyBillingAddress($address);
288
    }
289
290
    /**
291
     * @When /^I specified the shipping (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
292
     */
293
    public function iSpecifiedTheShippingAddress(AddressInterface $address)
294
    {
295
        $this->addressPage->open();
296
        $this->iSpecifyTheShippingAddressAs($address);
297
298
        $key = sprintf('billing_address_%s_%s', strtolower($address->getFirstName()), strtolower($address->getLastName()));
299
        $this->sharedStorage->set($key, $address);
300
301
        $this->iCompleteTheAddressingStep();
302
    }
303
304
    /**
305
     * @When I choose the different billing address
306
     */
307
    public function iChooseTheDifferentBillingAddress()
308
    {
309
        $this->addressPage->chooseDifferentBillingAddress();
310
    }
311
312
    /**
313
     * @When I specify the email as :email
314
     * @When I do not specify the email
315
     */
316
    public function iSpecifyTheEmail($email = null)
317
    {
318
        $this->addressPage->specifyEmail($email);
319
    }
320
321
    /**
322
     * @Given I have selected :shippingMethod shipping method
323
     * @When I select :shippingMethod shipping method
324
     */
325
    public function iSelectShippingMethod($shippingMethod)
326
    {
327
        $this->selectShippingPage->selectShippingMethod($shippingMethod);
328
    }
329
330
    /**
331
     * @Then I should not be able to select :shippingMethodName shipping method
332
     */
333
    public function iShouldNotBeAbleToSelectShippingMethod($shippingMethodName)
334
    {
335
        Assert::false(
336
            in_array($shippingMethodName, $this->selectShippingPage->getShippingMethods(), true),
337
            sprintf('Shipping method "%s" should not be available but it does.', $shippingMethodName)
338
        );
339
    }
340
341
    /**
342
     * @Then I should have :shippingMethodName shipping method available as the first choice
343
     */
344
    public function iShouldHaveShippingMethodAvailableAsFirstChoice($shippingMethodName)
345
    {
346
        $shippingMethods = $this->selectShippingPage->getShippingMethods();
347
        $firstShippingMethod = reset($shippingMethods);
348
349
        Assert::same($shippingMethodName, $firstShippingMethod);
350
    }
351
352
    /**
353
     * @Then I should have :shippingMethodName shipping method available as the last choice
354
     */
355
    public function iShouldHaveShippingMethodAvailableAsLastChoice($shippingMethodName)
356
    {
357
        $shippingMethods = $this->selectShippingPage->getShippingMethods();
358
        $lastShippingMethod = end($shippingMethods);
359
360
        Assert::same($shippingMethodName, $lastShippingMethod);
361
    }
362
363
    /**
364
     * @Then I should have :countryName selected as country
365
     */
366
    public function iShouldHaveSelectedAsCountry($countryName)
367
    {
368
        Assert::eq(
369
            $countryName,
370
            $this->addressPage->getShippingAddressCountry(),
371
            sprintf('Shipping country should be %s but is not.', $countryName)
372
        );
373
    }
374
375
    /**
376
     * @Then I should have no country selected
377
     */
378
    public function iShouldHaveNoCountrySelected()
379
    {
380
        Assert::eq(
381
            'Select',
382
            $this->addressPage->getShippingAddressCountry(),
383
            'Shipping country should not be selected.'
384
        );
385
    }
386
387
    /**
388
     * @When I complete the addressing step
389
     * @When I try to complete the addressing step
390
     */
391
    public function iCompleteTheAddressingStep()
392
    {
393
        $this->addressPage->nextStep();
394
    }
395
396
    /**
397
     * @When I go back to store
398
     */
399
    public function iGoBackToStore()
400
    {
401
        $this->addressPage->backToStore();
402
    }
403
404
    /**
405
     * @When /^I(?:| try to) complete the shipping step$/
406
     */
407
    public function iCompleteTheShippingStep()
408
    {
409
        $this->selectShippingPage->nextStep();
410
    }
411
412
    /**
413
     * @When I decide to change my address
414
     */
415
    public function iDecideToChangeMyAddress()
416
    {
417
        $this->selectShippingPage->changeAddress();
418
    }
419
420
    /**
421
     * @When I decide to change order shipping method
422
     */
423
    public function iDecideToChangeMyShippingMethod()
424
    {
425
        $this->selectPaymentPage->changeShippingMethod();
426
    }
427
428
    /**
429
     * @When I want to browse thank you page
430
     */
431
    public function iWantToBrowseThankYouPageForThisOrder()
432
    {
433
        $this->thankYouPage->open();
434
    }
435
436
    /**
437
     * @When I go to the addressing step
438
     */
439
    public function iGoToTheAddressingStep()
440
    {
441
        if ($this->selectShippingPage->isOpen()) {
442
            $this->selectShippingPage->changeAddressByStepLabel();
443
444
            return;
445
        }
446
447
        if ($this->selectPaymentPage->isOpen()) {
448
            $this->selectPaymentPage->changeAddressByStepLabel();
449
450
            return;
451
        }
452
453
        if ($this->completePage->isOpen()) {
454
            $this->completePage->changeAddress();
455
456
            return;
457
        }
458
459
        throw new UnexpectedPageException('It is impossible to go to addressing step from current page.');
460
    }
461
462
    /**
463
     * @When I go to the shipping step
464
     */
465
    public function iGoToTheShippingStep()
466
    {
467
        if ($this->selectPaymentPage->isOpen()) {
468
            $this->selectPaymentPage->changeShippingMethodByStepLabel();
469
470
            return;
471
        }
472
473
        if ($this->completePage->isOpen()) {
474
            $this->completePage->changeShippingMethod();
475
476
            return;
477
        }
478
479
        throw new UnexpectedPageException('It is impossible to go to shipping step from current page.');
480
    }
481
482
    /**
483
     * @When I decide to change the payment method
484
     */
485
    public function iGoToThePaymentStep()
486
    {
487
        $this->completePage->changePaymentMethod();
488
    }
489
490
    /**
491
     * @When /^I proceed selecting ("[^"]+" as shipping country)$/
492
     */
493
    public function iProceedSelectingShippingCountry(CountryInterface $shippingCountry = null)
494
    {
495
        $this->addressPage->open();
496
        $shippingAddress = $this->createDefaultAddress();
497
        if (null !== $shippingCountry) {
498
            $shippingAddress->setCountryCode($shippingCountry->getCode());
499
        }
500
501
        $this->addressPage->specifyShippingAddress($shippingAddress);
502
        $this->addressPage->nextStep();
503
    }
504
505
    /**
506
     * @When /^I proceed selecting ("[^"]+" as shipping country) with "([^"]+)" method$/
507
     */
508
    public function iProceedSelectingShippingCountryAndShippingMethod(CountryInterface $shippingCountry = null, $shippingMethodName)
0 ignored issues
show
Coding Style introduced by
Parameters which have default values should be placed at the end.

If you place a parameter with a default value before a parameter with a default value, the default value of the first parameter will never be used as it will always need to be passed anyway:

// $a must always be passed; it's default value is never used.
function someFunction($a = 5, $b) { }
Loading history...
509
    {
510
        $this->iProceedSelectingShippingCountry($shippingCountry);
511
512
        $this->selectShippingPage->selectShippingMethod($shippingMethodName ?: 'Free');
513
        $this->selectShippingPage->nextStep();
514
    }
515
516
    /**
517
     * @When /^I proceed selecting "([^"]+)" shipping method$/
518
     * @Given /^I chose "([^"]*)" shipping method$/
519
     */
520
    public function iProceedSelectingShippingMethod($shippingMethodName)
521
    {
522
        $this->iProceedSelectingShippingCountryAndShippingMethod(null, $shippingMethodName);
523
    }
524
525
    /**
526
     * @When /^I choose "([^"]*)" payment method$/
527
     */
528
    public function iChoosePaymentMethod($paymentMethodName)
529
    {
530
        $this->selectPaymentPage->selectPaymentMethod($paymentMethodName ?: 'Offline');
531
        $this->selectPaymentPage->nextStep();
532
    }
533
534
    /**
535
     * @When I change payment method to :paymentMethodName
536
     */
537
    public function iChangePaymentMethodTo($paymentMethodName)
538
    {
539
        $this->orderDetails->choosePaymentMethod($paymentMethodName);
540
    }
541
542
    /**
543
     * @When /^I proceed selecting "([^"]*)" as shipping country with "([^"]*)" payment method$/
544
     */
545
    public function iProceedSelectingShippingCountryAndPaymentMethod($shippingCountry, $paymentMethodName)
546
    {
547
        $this->iProceedSelectingShippingCountryAndShippingMethod($shippingCountry, null);
548
549
        $this->iChoosePaymentMethod($paymentMethodName);
550
    }
551
552
    /**
553
     * @When I go back to shipping step of the checkout
554
     */
555
    public function iGoBackToShippingStepOfTheCheckout()
556
    {
557
        $this->selectShippingPage->open();
558
    }
559
560
    /**
561
     * @Given I have proceeded selecting :paymentMethodName payment method
562
     * @When /^I (?:proceed|proceeded) selecting "([^"]+)" payment method$/
563
     */
564
    public function iProceedSelectingPaymentMethod($paymentMethodName = 'Offline')
565
    {
566
        $this->iProceedSelectingShippingCountryAndPaymentMethod(null, $paymentMethodName);
567
    }
568
569
    /**
570
     * @When /^I change shipping method to "([^"]*)"$/
571
     */
572
    public function iChangeShippingMethod($shippingMethodName)
573
    {
574
        $this->selectPaymentPage->changeShippingMethod();
575
        $this->selectShippingPage->selectShippingMethod($shippingMethodName);
576
        $this->selectShippingPage->nextStep();
577
    }
578
579
    /**
580
     * @When /^I provide additional note like "([^"]+)"$/
581
     */
582
    public function iProvideAdditionalNotesLike($notes)
583
    {
584
        $this->sharedStorage->set('additional_note', $notes);
585
        $this->completePage->addNotes($notes);
586
    }
587
588
    /**
589
     * @When /^I proceed as guest "([^"]*)" with ("[^"]+" as shipping country)$/
590
     */
591
    public function iProceedLoggingAsGuestWithAsShippingCountry($email, CountryInterface $shippingCountry = null)
592
    {
593
        $this->addressPage->open();
594
        $this->addressPage->specifyEmail($email);
595
        $shippingAddress = $this->createDefaultAddress();
596
        if (null !== $shippingCountry) {
597
            $shippingAddress->setCountryCode($shippingCountry->getCode());
598
        }
599
600
        $this->addressPage->specifyShippingAddress($shippingAddress);
601
        $this->addressPage->nextStep();
602
    }
603
604
    /**
605
     * @When I return to the checkout summary step
606
     */
607
    public function iReturnToTheCheckoutSummaryStep()
608
    {
609
        $this->completePage->open();
610
    }
611
612
    /**
613
     * @When I want to complete checkout
614
     */
615
    public function iWantToCompleteCheckout()
616
    {
617
        $this->completePage->tryToOpen();
618
    }
619
620
    /**
621
     * @Given I have confirmed my order
622
     * @When I confirm my order
623
     */
624
    public function iConfirmMyOrder()
625
    {
626
        $this->completePage->confirmOrder();
627
    }
628
629
    /**
630
     * @When I specify the password as :password
631
     */
632
    public function iSpecifyThePasswordAs($password)
633
    {
634
        $this->addressPage->specifyPassword($password);
635
    }
636
637
    /**
638
     * @When I sign in
639
     */
640
    public function iSignIn()
641
    {
642
        $this->addressPage->signIn();
643
    }
644
645
    /**
646
     * @Then I should see the thank you page
647
     */
648
    public function iShouldSeeTheThankYouPage()
649
    {
650
        Assert::true(
651
            $this->thankYouPage->hasThankYouMessage(),
652
            'I should see thank you message, but I do not.'
653
        );
654
    }
655
656
    /**
657
     * @Then I should not see the thank you page
658
     */
659
    public function iShouldNotSeeTheThankYouPage()
660
    {
661
        Assert::false(
662
            $this->thankYouPage->isOpen(),
663
            'I should not see thank you message, but I do.'
664
        );
665
    }
666
667
    /**
668
     * @Given I should be informed with :paymentMethod payment method instructions
669
     */
670
    public function iShouldBeInformedWithPaymentMethodInstructions(PaymentMethodInterface $paymentMethod)
671
    {
672
        Assert::same(
673
            $this->thankYouPage->getInstructions(),
674
            $paymentMethod->getInstructions()
675
        );
676
    }
677
678
    /**
679
     * @Then /^I should be redirected (?:|back )to the thank you page$/
680
     */
681
    public function iShouldBeRedirectedBackToTheThankYouPage()
682
    {
683
        $this->thankYouPage->waitForResponse(5);
684
685
        Assert::true(
686
            $this->thankYouPage->isOpen(),
687
            'I should be on thank you page, but I am not.'
688
        );
689
    }
690
691
    /**
692
     * @Then I should be on the checkout shipping step
693
     */
694
    public function iShouldBeOnTheCheckoutShippingStep()
695
    {
696
        Assert::true(
697
            $this->selectShippingPage->isOpen(),
698
            'Checkout shipping page should be opened, but it is not.'
699
        );
700
    }
701
702
    /**
703
     * @Then I should be on the checkout payment step
704
     */
705
    public function iShouldBeOnTheCheckoutPaymentStep()
706
    {
707
        Assert::true(
708
            $this->selectPaymentPage->isOpen(),
709
            'Checkout payment page should be opened, but it is not.'
710
        );
711
    }
712
713
    /**
714
     * @Then I should be on the checkout summary step
715
     */
716
    public function iShouldBeOnTheCheckoutSummaryStep()
717
    {
718
        Assert::true(
719
            $this->completePage->isOpen(),
720
            'Checkout summary page should be opened, but it is not.'
721
        );
722
    }
723
724
    /**
725
     * @Then /^I should(?:| also) be notified that the "([^"]+)" and the "([^"]+)" in (shipping|billing) details are required$/
726
     */
727
    public function iShouldBeNotifiedThatTheAndTheInShippingDetailsAreRequired($firstElement, $secondElement, $type)
728
    {
729
        $this->assertElementValidationMessage($type, $firstElement, sprintf('Please enter %s.', $firstElement));
730
        $this->assertElementValidationMessage($type, $secondElement, sprintf('Please enter %s.', $secondElement));
731
    }
732
733
    /**
734
     * @Then I should be informed that my order cannot be shipped to this address
735
     */
736
    public function iShouldBeInformedThatMyOrderCannotBeShippedToThisAddress()
737
    {
738
        Assert::true(
739
            $this->selectShippingPage->hasNoShippingMethodsMessage(),
740
            'Shipping page should have no shipping methods message but it does not.'
741
        );
742
    }
743
744
    /**
745
     * @Then I should be able to log in
746
     */
747
    public function iShouldBeAbleToLogIn()
748
    {
749
        Assert::true(
750
            $this->addressPage->canSignIn(),
751
            'I should be able to login, but I am not.'
752
        );
753
    }
754
755
    /**
756
     * @Then the login form should no longer be accessible
757
     */
758
    public function theLoginFormShouldNoLongerBeAccessible()
759
    {
760
        Assert::false(
761
            $this->addressPage->canSignIn(),
762
            'I should not be able to login, but I am.'
763
        );
764
    }
765
766
    /**
767
     * @Then I should be notified about bad credentials
768
     */
769
    public function iShouldBeNotifiedAboutBadCredentials()
770
    {
771
        Assert::true(
772
            $this->addressPage->checkInvalidCredentialsValidation(),
773
            'I should see validation error, but I do not.'
774
        );
775
    }
776
777
    /**
778
     * @Then my order's shipping address should be to :fullName
779
     */
780
    public function iShouldSeeThisShippingAddressAsShippingAddress($fullName)
781
    {
782
        $address = $this->sharedStorage->get('shipping_address_'.StringInflector::nameToLowercaseCode($fullName));
783
        Assert::true(
784
            $this->completePage->hasShippingAddress($address),
785
            'Shipping address is improper.'
786
        );
787
    }
788
789
    /**
790
     * @Then my order's billing address should be to :fullName
791
     */
792
    public function iShouldSeeThisBillingAddressAsBillingAddress($fullName)
793
    {
794
        $address = $this->sharedStorage->get('billing_address_'.StringInflector::nameToLowercaseCode($fullName));
795
        Assert::true(
796
            $this->completePage->hasBillingAddress($address),
797
            'Billing address is improper.'
798
        );
799
    }
800
801
    /**
802
     * @Then address to :fullName should be used for both shipping and billing of my order
803
     */
804
    public function iShouldSeeThisShippingAddressAsShippingAndBillingAddress($fullName)
805
    {
806
        $this->iShouldSeeThisShippingAddressAsShippingAddress($fullName);
807
        $this->iShouldSeeThisBillingAddressAsBillingAddress($fullName);
808
    }
809
810
    /**
811
     * @Given I am at the checkout payment step
812
     * @When I go back to payment step of the checkout
813
     */
814
    public function iAmAtTheCheckoutPaymentStep()
815
    {
816
        $this->selectPaymentPage->open();
817
    }
818
819
    /**
820
     * @When I complete the payment step
821
     */
822
    public function iCompleteThePaymentStep()
823
    {
824
        $this->selectPaymentPage->nextStep();
825
    }
826
827
    /**
828
     * @When I select :name payment method
829
     */
830
    public function iSelectPaymentMethod($name)
831
    {
832
        $this->selectPaymentPage->selectPaymentMethod($name);
833
    }
834
835
    /**
836
     * @When /^I do not modify anything$/
837
     */
838
    public function iDoNotModifyAnything()
839
    {
840
        // Intentionally left blank to fulfill context expectation
841
    }
842
843
    /**
844
     * @Then I should not be able to select :paymentMethodName payment method
845
     */
846
    public function iShouldNotBeAbleToSelectPaymentMethod($paymentMethodName)
847
    {
848
        Assert::false(
849
            $this->selectPaymentPage->hasPaymentMethod($paymentMethodName),
850
            sprintf('Payment method "%s" should not be available, but it does.', $paymentMethodName)
851
        );
852
    }
853
854
    /**
855
     * @Then I should be able to select :paymentMethodName payment method
856
     */
857
    public function iShouldBeAbleToSelectPaymentMethod($paymentMethodName)
858
    {
859
        Assert::true(
860
            $this->selectPaymentPage->hasPaymentMethod($paymentMethodName),
861
            sprintf('Payment method "%s" should be available, but it does not.', $paymentMethodName)
862
        );
863
    }
864
865
    /**
866
     * @Given I have proceeded order with :shippingMethod shipping method and :paymentMethod payment
867
     * @When I proceed with :shippingMethod shipping method and :paymentMethod payment
868
     */
869
    public function iProceedOrderWithShippingMethodAndPayment($shippingMethod, $paymentMethod)
870
    {
871
        $this->iSelectShippingMethod($shippingMethod);
872
        $this->iCompleteTheShippingStep();
873
        $this->iSelectPaymentMethod($paymentMethod);
874
        $this->iCompleteThePaymentStep();
875
    }
876
877
    /**
878
     * @Given I should have :quantity :productName products in the cart
879
     */
880
    public function iShouldHaveProductsInTheCart($quantity, $productName)
881
    {
882
        Assert::true(
883
            $this->completePage->hasItemWithProductAndQuantity($productName, $quantity),
884
            sprintf('There is no "%s" with quantity %s on order summary page, but it should.', $productName, $quantity)
885
        );
886
    }
887
888
    /**
889
     * @Then my order shipping should be :price
890
     */
891
    public function myOrderShippingShouldBe($price)
892
    {
893
        Assert::true(
894
            $this->completePage->hasShippingTotal($price),
895
            sprintf('The shipping total should be %s, but it is not.',$price)
896
        );
897
    }
898
899
    /**
900
     * @Then /^the ("[^"]+" product) should have unit price discounted by ("\$\d+")$/
901
     */
902
    public function theShouldHaveUnitPriceDiscountedFor(ProductInterface $product, $amount)
903
    {
904
        Assert::true(
905
            $this->completePage->hasProductDiscountedUnitPriceBy($product, $amount),
906
            sprintf('Product %s should have discounted price by %s, but it does not have.', $product->getName(), $amount)
907
        );
908
    }
909
910
    /**
911
     * @Then /^my order total should be ("(?:\£|\$)\d+")$/
912
     */
913
    public function myOrderTotalShouldBe($total)
914
    {
915
        Assert::true(
916
            $this->completePage->hasOrderTotal($total),
917
            sprintf('Order total should have %s total, but it does not have.', $total)
918
        );
919
    }
920
921
    /**
922
     * @Then my order promotion total should be :promotionTotal
923
     */
924
    public function myOrderPromotionTotalShouldBe($promotionTotal)
925
    {
926
        Assert::true(
927
            $this->completePage->hasPromotionTotal($promotionTotal),
928
            sprintf('The total discount should be %s, but it does not.', $promotionTotal)
929
        );
930
    }
931
932
    /**
933
     * @Then :promotionName should be applied to my order
934
     */
935
    public function shouldBeAppliedToMyOrder($promotionName)
936
    {
937
        Assert::true(
938
            $this->completePage->hasPromotion($promotionName),
939
            sprintf('The promotion %s should appear on the page, but it does not.', $promotionName)
940
        );
941
    }
942
943
    /**
944
     * @Given my tax total should be :taxTotal
945
     */
946
    public function myTaxTotalShouldBe($taxTotal)
947
    {
948
        Assert::true(
949
            $this->completePage->hasTaxTotal($taxTotal),
950
            sprintf('The tax total should be %s, but it does not.', $taxTotal)
951
        );
952
    }
953
954
    /**
955
     * @Then my order's shipping method should be :shippingMethod
956
     */
957
    public function myOrderSShippingMethodShouldBe(ShippingMethodInterface $shippingMethod)
958
    {
959
        Assert::true(
960
            $this->completePage->hasShippingMethod($shippingMethod),
961
            sprintf('I should see %s shipping method, but I do not.', $shippingMethod->getName())
962
        );
963
    }
964
965
    /**
966
     * @Then my order's payment method should be :paymentMethod
967
     */
968
    public function myOrderSPaymentMethodShouldBe(PaymentMethodInterface $paymentMethod)
969
    {
970
        Assert::true(
971
            $this->completePage->hasPaymentMethod($paymentMethod),
972
            sprintf('I should see %s payment method, but I do not.', $paymentMethod->getName())
973
        );
974
    }
975
976
    /**
977
     * @Then I should be redirected to the homepage
978
     */
979
    public function iShouldBeRedirectedToTheHomepage()
980
    {
981
        Assert::true(
982
            $this->homePage->isOpen(),
983
            'Shop homepage should be opened, but it is not.'
984
        );
985
    }
986
987
    /**
988
     * @Then I should be redirected to the addressing step
989
     */
990
    public function iShouldBeRedirectedToTheAddressingStep()
991
    {
992
        Assert::true(
993
            $this->addressPage->isOpen(),
994
            'Checkout addressing step should be opened, but it is not.'
995
        );
996
    }
997
998
    /**
999
     * @Given I should be able to go to the shipping step again
1000
     */
1001
    public function iShouldBeAbleToGoToTheShippingStepAgain()
1002
    {
1003
        $this->addressPage->nextStep();
1004
1005
        Assert::true(
1006
            $this->selectShippingPage->isOpen(),
1007
            'Checkout shipping step should be opened, but it is not.'
1008
        );
1009
    }
1010
1011
    /**
1012
     * @Then I should be redirected to the shipping step
1013
     */
1014
    public function iShouldBeRedirectedToTheShippingStep()
1015
    {
1016
        Assert::true(
1017
            $this->selectShippingPage->isOpen(),
1018
            'Checkout shipping step should be opened, but it is not.'
1019
        );
1020
    }
1021
1022
    /**
1023
     * @Then /^I should be able to pay(?| again)$/
1024
     */
1025
    public function iShouldBeAbleToPayAgain()
1026
    {
1027
        Assert::true(
1028
            $this->orderDetails->hasPayAction(),
1029
            'I should be able to pay, but I am not able to.'
1030
        );
1031
    }
1032
1033
    /**
1034
     * @Then I should not be able to pay
1035
     */
1036
    public function iShouldNotBeAbleToPayAgain()
1037
    {
1038
        Assert::false(
1039
            $this->orderDetails->hasPayAction(),
1040
            'I should not be able to pay, but I am able to.'
1041
        );
1042
    }
1043
1044
    /**
1045
     * @Given I should be able to go to the payment step again
1046
     */
1047
    public function iShouldBeAbleToGoToThePaymentStepAgain()
1048
    {
1049
        $this->selectShippingPage->nextStep();
1050
1051
        Assert::true(
1052
            $this->selectPaymentPage->isOpen(),
1053
            'Checkout payment step should be opened, but it is not.'
1054
        );
1055
    }
1056
1057
    /**
1058
     * @Then I should be redirected to the payment step
1059
     */
1060
    public function iShouldBeRedirectedToThePaymentStep()
1061
    {
1062
        Assert::true(
1063
            $this->selectPaymentPage->isOpen(),
1064
            'Checkout payment step should be opened, but it is not.'
1065
        );
1066
    }
1067
1068
    /**
1069
     * @Given I should be able to go to the summary page again
1070
     */
1071
    public function iShouldBeAbleToGoToTheSummaryPageAgain()
1072
    {
1073
        $this->selectPaymentPage->nextStep();
1074
1075
        Assert::true(
1076
            $this->completePage->isOpen(),
1077
            'Checkout summary page should be opened, but it is not.'
1078
        );
1079
    }
1080
1081
    /**
1082
     * @Given I should see shipping method :shippingMethodName with fee :fee
1083
     */
1084
    public function iShouldSeeShippingFee($shippingMethodName, $fee)
1085
    {
1086
        Assert::true(
1087
            $this->selectShippingPage->hasShippingMethodFee($shippingMethodName, $fee),
1088
            sprintf('The shipping fee should be %s, but it does not.', $fee)
1089
        );
1090
    }
1091
1092
    /**
1093
     * @Given /^I have completed addressing step with email "([^"]+)" and ("[^"]+" based shipping address)$/
1094
     * @When /^I complete addressing step with email "([^"]+)" and ("[^"]+" based shipping address)$/
1095
     */
1096
    public function iCompleteAddressingStepWithEmail($email, AddressInterface $address)
1097
    {
1098
        $this->addressPage->open();
1099
        $this->iSpecifyTheEmail($email);
1100
        $this->iSpecifyTheShippingAddressAs($address);
1101
        $this->iCompleteTheAddressingStep();
1102
    }
1103
1104
    /**
1105
     * @Then the subtotal of :item item should be :price
1106
     */
1107
    public function theSubtotalOfItemShouldBe($item, $price)
1108
    {
1109
        $currentPage = $this->resolveCurrentStepPage();
1110
        $actualPrice = $currentPage->getItemSubtotal($item);
1111
1112
        Assert::eq(
1113
            $actualPrice,
1114
            $price,
1115
            sprintf('The %s subtotal should be %s, but is %s', $item, $price, $actualPrice)
1116
        );
1117
    }
1118
1119
    /**
1120
     * @Then the :product product should have unit price :price
1121
     */
1122
    public function theProductShouldHaveUnitPrice(ProductInterface $product, $price)
1123
    {
1124
        Assert::true(
1125
            $this->completePage->hasProductUnitPrice($product, $price),
1126
            sprintf('Product %s should have unit price %s, but it does not have.', $product->getName(), $price)
1127
        );
1128
    }
1129
1130
    /**
1131
     * @Given /^I should be notified that (this product) does not have sufficient stock$/
1132
     */
1133
    public function iShouldBeNotifiedThatThisProductDoesNotHaveSufficientStock(ProductInterface $product)
1134
    {
1135
        Assert::true(
1136
            $this->completePage->hasProductOutOfStockValidationMessage($product),
1137
            sprintf('I should see validation message for %s product', $product->getName())
1138
        );
1139
    }
1140
1141
    /**
1142
     * @Then my order's locale should be :localeName
1143
     */
1144
    public function myOrderSLocaleShouldBe($localeName)
1145
    {
1146
        Assert::true(
1147
            $this->completePage->hasLocale($localeName),
1148
            'Order locale code is improper.'
1149
        );
1150
    }
1151
1152
    /**
1153
     * @Then my order's currency should be :currencyCode
1154
     */
1155
    public function myOrderSCurrencyShouldBe($currencyCode)
1156
    {
1157
        Assert::true(
1158
            $this->completePage->hasCurrency($currencyCode),
1159
            'Order currency code is improper.'
1160
        );
1161
    }
1162
1163
    /**
1164
     * @Then /^I should not be notified that (this product) does not have sufficient stock$/
1165
     */
1166
    public function iShouldNotBeNotifiedThatThisProductDoesNotHaveSufficientStock(ProductInterface $product)
1167
    {
1168
        Assert::false(
1169
            $this->completePage->hasProductOutOfStockValidationMessage($product),
1170
            sprintf('I should see validation message for %s product', $product->getName())
1171
        );
1172
    }
1173
1174
    /**
1175
     * @Then I should be on the checkout addressing step
1176
     */
1177
    public function iShouldBeOnTheCheckoutAddressingStep()
1178
    {
1179
        Assert::true(
1180
            $this->addressPage->isOpen(),
1181
            'Checkout addressing page should be opened, but it is not.'
1182
        );
1183
    }
1184
1185
    /**
1186
     * @When I specify the province name manually as :provinceName for shipping address
1187
     */
1188
    public function iSpecifyTheProvinceNameManuallyAsForShippingAddress($provinceName)
1189
    {
1190
        $this->addressPage->specifyShippingAddressProvince($provinceName);
1191
    }
1192
1193
    /**
1194
     * @When I specify the province name manually as :provinceName for billing address
1195
     */
1196
    public function iSpecifyTheProvinceNameManuallyAsForBillingAddress($provinceName)
1197
    {
1198
        $this->addressPage->specifyBillingAddressProvince($provinceName);
1199
    }
1200
1201
    /**
1202
     * @Then I should not be able to specify province name manually for shipping address
1203
     */
1204
    public function iShouldNotBeAbleToSpecifyProvinceNameManuallyForShippingAddress()
1205
    {
1206
        Assert::false(
1207
            $this->addressPage->hasShippingAddressInput(),
1208
            'I should not be able to specify manually the province for shipping address, but I can.'
1209
        );
1210
    }
1211
1212
    /**
1213
     * @Then I should not be able to specify province name manually for billing address
1214
     */
1215
    public function iShouldNotBeAbleToSpecifyProvinceNameManuallyForBillingAddress()
1216
    {
1217
        Assert::false(
1218
            $this->addressPage->hasBillingAddressInput(),
1219
            'I should not be able to specify manually the province for billing address, but I can.'
1220
        );
1221
    }
1222
1223
    /**
1224
     * @Then I should see :provinceName in the shipping address
1225
     */
1226
    public function iShouldSeeInTheShippingAddress($provinceName)
1227
    {
1228
        Assert::true(
1229
            $this->completePage->hasShippingProvinceName($provinceName),
1230
            sprintf('Cannot find shipping address with province %s', $provinceName)
1231
        );
1232
    }
1233
1234
    /**
1235
     * @Then I should see :provinceName in the billing address
1236
     */
1237
    public function iShouldSeeInTheBillingAddress($provinceName)
1238
    {
1239
        Assert::true(
1240
            $this->completePage->hasBillingProvinceName($provinceName),
1241
            sprintf('Cannot find billing address with province %s', $provinceName)
1242
        );
1243
    }
1244
1245
    /**
1246
     * @When I do not select any shipping method
1247
     */
1248
    public function iDoNotSelectAnyShippingMethod()
1249
    {
1250
        // Intentionally left blank to fulfill context expectation
1251
    }
1252
1253
    /**
1254
     * @Then I should still be on the shipping step
1255
     */
1256
    public function iShouldStillBeOnTheShippingStep()
1257
    {
1258
        Assert::true(
1259
            $this->selectShippingPage->isOpen(),
1260
            'Select shipping page should be open, but it does not.'
1261
        );
1262
    }
1263
1264
    /**
1265
     * @Then I should be notified that the shipping method is required
1266
     */
1267
    public function iShouldBeNotifiedThatTheShippingMethodIsRequired()
1268
    {
1269
        Assert::same(
1270
            $this->selectShippingPage->getValidationMessageForShipment(),
1271
            'Please select shipping method.'
1272
        );
1273
    }
1274
1275
    /**
1276
     * @Then there should be information about no available shipping methods
1277
     * @Then there should be information about no shipping methods available for my shipping address
1278
     */
1279
    public function thereShouldBeInformationAboutNoShippingMethodsAvailableForMyShippingAddress()
1280
    {
1281
        Assert::true(
1282
            $this->selectShippingPage->hasNoAvailableShippingMethodsWarning(),
1283
            'There should be warning about no available shipping methods, but it does not.'
1284
        );
1285
    }
1286
1287
    /**
1288
     * @Then I should not be able to complete the shipping step
1289
     */
1290
    public function iShouldNotBeAbleToCompleteTheShippingStep()
1291
    {
1292
        Assert::true(
1293
            $this->selectShippingPage->isNextStepButtonUnavailable(),
1294
            'The next step button should be disabled, but it does not.'
1295
        );
1296
    }
1297
1298
    /**
1299
     * @When I do not select any payment method
1300
     */
1301
    public function iDoNotSelectAnyPaymentMethod()
1302
    {
1303
        // Intentionally left blank to fulfill context expectation
1304
    }
1305
1306
    /**
1307
     * @Then I should not be able to complete the payment step
1308
     */
1309
    public function iShouldNotBeAbleToCompleteThePaymentStep()
1310
    {
1311
        Assert::true(
1312
            $this->selectPaymentPage->isNextStepButtonUnavailable(),
1313
           'The "next step" button should be disabled.'
1314
        );
1315
    }
1316
1317
    /**
1318
     * @Then there should be information about no payment methods available for my order
1319
     */
1320
    public function thereShouldBeInformationAboutNoPaymentMethodsAvailableForMyOrder()
1321
    {
1322
        Assert::true(
1323
            $this->selectPaymentPage->hasNoAvailablePaymentMethodsWarning(),
1324
            'There should be warning about no available payment methods, but it does not.'
1325
        );
1326
    }
1327
1328
    /**
1329
     * @Then /^(address "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+") should be filled as shipping address$/
1330
     */
1331
    public function addressShouldBeFilledAsShippingAddress(AddressInterface $address)
1332
    {
1333
        Assert::true($this->addressComparator->equal($address, $this->addressPage->getPreFilledShippingAddress()));
1334
    }
1335
1336
    /**
1337
     * @Then /^(address "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+") should be filled as billing address$/
1338
     */
1339
    public function addressShouldBeFilledAsBillingAddress(AddressInterface $address)
1340
    {
1341
        Assert::true($this->addressComparator->equal($address, $this->addressPage->getPreFilledBillingAddress()));
1342
    }
1343
1344
    /**
1345
     * @Then I should have :paymentMethodName payment method available as the first choice
1346
     */
1347
    public function iShouldHavePaymentMethodAvailableAsFirstChoice($paymentMethodName)
1348
    {
1349
        $paymentMethods = $this->selectPaymentPage->getPaymentMethods();
1350
        $firstPaymentMethod = reset($paymentMethods);
1351
1352
        Assert::same($paymentMethodName, $firstPaymentMethod);
1353
    }
1354
1355
    /**
1356
     * @Then I should have :paymentMethodName payment method available as the last choice
1357
     */
1358
    public function iShouldHavePaymentMethodAvailableAsLastChoice($paymentMethodName)
1359
    {
1360
        $paymentMethods = $this->selectPaymentPage->getPaymentMethods();
1361
        $lastPaymentMethod = end($paymentMethods);
1362
1363
        Assert::same($paymentMethodName, $lastPaymentMethod);
1364
    }
1365
1366
    /**
1367
     * @Then I should see :shippingMethodName shipping method
1368
     */
1369
    public function iShouldSeeShippingMethod($shippingMethodName)
1370
    {
1371
        Assert::true(
1372
            $this->selectShippingPage->hasShippingMethod($shippingMethodName),
1373
            sprintf('There should be %s shipping method, but it is not.', $shippingMethodName)
1374
        );
1375
    }
1376
1377
    /**
1378
     * @Then I should not see :shippingMethodName shipping method
1379
     */
1380
    public function iShouldNotSeeShippingMethod($shippingMethodName)
1381
    {
1382
        Assert::false(
1383
            $this->selectShippingPage->hasShippingMethod($shippingMethodName),
1384
            sprintf('There should not be %s shipping method, but it is.', $shippingMethodName)
1385
        );
1386
    }
1387
1388
    /**
1389
     * @return AddressInterface
1390
     */
1391
    private function createDefaultAddress()
1392
    {
1393
        /** @var AddressInterface $address */
1394
        $address = $this->addressFactory->createNew();
1395
        $address->setFirstName('John');
1396
        $address->setLastName('Doe');
1397
        $address->setCountryCode('US');
1398
        $address->setCity('North Bridget');
1399
        $address->setPostcode('93-554');
1400
        $address->setStreet('0635 Myron Hollow Apt. 711');
1401
        $address->setPhoneNumber('321123456');
1402
1403
        return $address;
1404
    }
1405
1406
    /**
1407
     * @param string $type
1408
     * @param string $element
1409
     * @param string $expectedMessage
1410
     *
1411
     * @throws \InvalidArgumentException
1412
     */
1413
    private function assertElementValidationMessage($type, $element, $expectedMessage)
1414
    {
1415
        $element = sprintf('%s_%s', $type, implode('_', explode(' ', $element)));
1416
        Assert::true(
1417
            $this->addressPage->checkValidationMessageFor($element, $expectedMessage),
1418
            sprintf('The %s should be required.', $element)
1419
        );
1420
    }
1421
1422
    /**
1423
     * @return SymfonyPageInterface
1424
     */
1425
    private function resolveCurrentStepPage()
1426
    {
1427
        $possiblePages = [
1428
            $this->addressPage,
1429
            $this->selectPaymentPage,
1430
            $this->selectShippingPage,
1431
        ];
1432
1433
        return $this->currentPageResolver->getCurrentPageWithForm($possiblePages);
1434
    }
1435
}
1436