Completed
Push — unused-definitions ( d9908f )
by Kamil
18:33
created

iShouldBeNotifiedThatTheShippingMethodIsRequired()   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 0
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Behat\Context\Ui;
13
14
use Behat\Behat\Context\Context;
15
use Sylius\Behat\Page\Shop\Checkout\AddressPageInterface;
16
use Sylius\Behat\Page\Shop\Checkout\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 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 choose ("[^"]+" street) for shipping address$/
214
     */
215
    public function iChooseForShippingAddress(AddressInterface $address)
216
    {
217
        $this->addressPage->selectShippingAddressFromAddressBook($address);
218
    }
219
220
    /**
221
     * @When /^I choose ("[^"]+" street) for billing address$/
222
     */
223
    public function iChooseForBillingAddress(AddressInterface $address)
224
    {
225
        $this->addressPage->chooseDifferentBillingAddress();
226
        $this->addressPage->selectBillingAddressFromAddressBook($address);
227
    }
228
229
    /**
230
     * @When /^I specify the shipping (address as "[^"]+", "[^"]+", "[^"]+", "[^"]+" for "[^"]+")$/
231
     * @When /^I specify the shipping (address for "[^"]+" from "[^"]+", "[^"]+", "[^"]+", "[^"]+", "[^"]+")$/
232
     * @When /^I (do not specify any shipping address) information$/
233
     * @When /^I change the shipping (address to "[^"]+", "[^"]+", "[^"]+", "[^"]+" for "[^"]+")$/
234
     */
235
    public function iSpecifyTheShippingAddressAs(AddressInterface $address)
236
    {
237
        $key = sprintf(
238
            'shipping_address_%s_%s',
239
            strtolower($address->getFirstName()),
240
            strtolower($address->getLastName())
241
        );
242
        $this->sharedStorage->set($key, $address);
243
244
        $this->addressPage->specifyShippingAddress($address);
245
    }
246
247
    /**
248
     * @When I specify shipping country province as :province
249
     */
250
    public function iSpecifyShippingCountryProvinceAs($province)
251
    {
252
        $this->addressPage->selectShippingAddressProvince($province);
253
    }
254
255
    /**
256
     * @When I specify billing country province as :province
257
     */
258
    public function iSpecifyBillingCountryProvinceAs($province)
259
    {
260
        $this->addressPage->selectBillingAddressProvince($province);
261
    }
262
263
    /**
264
     * @When /^I specify the billing (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
265
     * @When /^I specify the billing (address for "([^"]+)" from "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)")$/
266
     * @When /^I (do not specify any billing address) information$/
267
     */
268
    public function iSpecifyTheBillingAddressAs(AddressInterface $address)
269
    {
270
        $this->iChooseTheDifferentBillingAddress();
0 ignored issues
show
Bug introduced by
The method iChooseTheDifferentBillingAddress() does not seem to exist on object<Sylius\Behat\Context\Ui\CheckoutContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
271
        $key = sprintf(
272
            'billing_address_%s_%s',
273
            strtolower($address->getFirstName()),
274
            strtolower($address->getLastName())
275
        );
276
        $this->sharedStorage->set($key, $address);
277
278
        $this->addressPage->specifyBillingAddress($address);
279
    }
280
281
    /**
282
     * @When /^I specified the shipping (address as "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)" for "([^"]+)")$/
283
     */
284
    public function iSpecifiedTheShippingAddress(AddressInterface $address)
285
    {
286
        $this->addressPage->open();
287
        $this->iSpecifyTheShippingAddressAs($address);
288
289
        $key = sprintf('billing_address_%s_%s', strtolower($address->getFirstName()), strtolower($address->getLastName()));
290
        $this->sharedStorage->set($key, $address);
291
292
        $this->iCompleteTheAddressingStep();
293
    }
294
295
    /**
296
     * @When I specify the email as :email
297
     * @When I do not specify the email
298
     */
299
    public function iSpecifyTheEmail($email = null)
300
    {
301
        $this->addressPage->specifyEmail($email);
302
    }
303
304
    /**
305
     * @Given I have selected :shippingMethod shipping method
306
     * @When I select :shippingMethod shipping method
307
     */
308
    public function iSelectShippingMethod($shippingMethod)
309
    {
310
        $this->selectShippingPage->selectShippingMethod($shippingMethod);
311
    }
312
313
    /**
314
     * @Then I should not be able to select :shippingMethodName shipping method
315
     */
316
    public function iShouldNotBeAbleToSelectShippingMethod($shippingMethodName)
317
    {
318
        Assert::false(
319
            in_array($shippingMethodName, $this->selectShippingPage->getShippingMethods(), true),
320
            sprintf('Shipping method "%s" should not be available but it does.', $shippingMethodName)
321
        );
322
    }
323
324
    /**
325
     * @Then I should have :shippingMethodName shipping method available as the first choice
326
     */
327
    public function iShouldHaveShippingMethodAvailableAsFirstChoice($shippingMethodName)
328
    {
329
        $shippingMethods = $this->selectShippingPage->getShippingMethods();
330
        $firstShippingMethod = reset($shippingMethods);
331
332
        Assert::same($shippingMethodName, $firstShippingMethod);
333
    }
334
335
    /**
336
     * @Then I should have :shippingMethodName shipping method available as the last choice
337
     */
338
    public function iShouldHaveShippingMethodAvailableAsLastChoice($shippingMethodName)
339
    {
340
        $shippingMethods = $this->selectShippingPage->getShippingMethods();
341
        $lastShippingMethod = end($shippingMethods);
342
343
        Assert::same($shippingMethodName, $lastShippingMethod);
344
    }
345
346
    /**
347
     * @Then I should have :countryName selected as country
348
     */
349
    public function iShouldHaveSelectedAsCountry($countryName)
350
    {
351
        Assert::eq(
352
            $countryName,
353
            $this->addressPage->getShippingAddressCountry(),
354
            sprintf('Shipping country should be %s but is not.', $countryName)
355
        );
356
    }
357
358
    /**
359
     * @Then I should have no country selected
360
     */
361
    public function iShouldHaveNoCountrySelected()
362
    {
363
        Assert::eq(
364
            'Select',
365
            $this->addressPage->getShippingAddressCountry(),
366
            'Shipping country should not be selected.'
367
        );
368
    }
369
370
    /**
371
     * @When I complete the addressing step
372
     * @When I try to complete the addressing step
373
     */
374
    public function iCompleteTheAddressingStep()
375
    {
376
        $this->addressPage->nextStep();
377
    }
378
379
    /**
380
     * @When I go back to store
381
     */
382
    public function iGoBackToStore()
383
    {
384
        $this->addressPage->backToStore();
385
    }
386
387
    /**
388
     * @When /^I(?:| try to) complete the shipping step$/
389
     */
390
    public function iCompleteTheShippingStep()
391
    {
392
        $this->selectShippingPage->nextStep();
393
    }
394
395
    /**
396
     * @When I decide to change my address
397
     */
398
    public function iDecideToChangeMyAddress()
399
    {
400
        $this->selectShippingPage->changeAddress();
401
    }
402
403
    /**
404
     * @When I decide to change order shipping method
405
     */
406
    public function iDecideToChangeMyShippingMethod()
407
    {
408
        $this->selectPaymentPage->changeShippingMethod();
409
    }
410
411
    /**
412
     * @When I go to the addressing step
413
     */
414
    public function iGoToTheAddressingStep()
415
    {
416
        if ($this->selectShippingPage->isOpen()) {
417
            $this->selectShippingPage->changeAddressByStepLabel();
418
419
            return;
420
        }
421
422
        if ($this->selectPaymentPage->isOpen()) {
423
            $this->selectPaymentPage->changeAddressByStepLabel();
424
425
            return;
426
        }
427
428
        if ($this->completePage->isOpen()) {
429
            $this->completePage->changeAddress();
430
431
            return;
432
        }
433
434
        throw new UnexpectedPageException('It is impossible to go to addressing step from current page.');
435
    }
436
437
    /**
438
     * @When I go to the shipping step
439
     */
440
    public function iGoToTheShippingStep()
441
    {
442
        if ($this->selectPaymentPage->isOpen()) {
443
            $this->selectPaymentPage->changeShippingMethodByStepLabel();
444
445
            return;
446
        }
447
448
        if ($this->completePage->isOpen()) {
449
            $this->completePage->changeShippingMethod();
450
451
            return;
452
        }
453
454
        throw new UnexpectedPageException('It is impossible to go to shipping step from current page.');
455
    }
456
457
    /**
458
     * @When I decide to change the payment method
459
     */
460
    public function iGoToThePaymentStep()
461
    {
462
        $this->completePage->changePaymentMethod();
463
    }
464
465
    /**
466
     * @When /^I proceed selecting ("[^"]+" as shipping country)$/
467
     */
468
    public function iProceedSelectingShippingCountry(CountryInterface $shippingCountry = null)
469
    {
470
        $this->addressPage->open();
471
        $shippingAddress = $this->createDefaultAddress();
472
        if (null !== $shippingCountry) {
473
            $shippingAddress->setCountryCode($shippingCountry->getCode());
474
        }
475
476
        $this->addressPage->specifyShippingAddress($shippingAddress);
477
        $this->addressPage->nextStep();
478
    }
479
480
    /**
481
     * @When /^I proceed selecting ("[^"]+" as shipping country) with "([^"]+)" method$/
482
     */
483
    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...
484
    {
485
        $this->iProceedSelectingShippingCountry($shippingCountry);
486
487
        $this->selectShippingPage->selectShippingMethod($shippingMethodName ?: 'Free');
488
        $this->selectShippingPage->nextStep();
489
    }
490
491
    /**
492
     * @When /^I proceed selecting "([^"]+)" shipping method$/
493
     * @Given /^I chose "([^"]*)" shipping method$/
494
     */
495
    public function iProceedSelectingShippingMethod($shippingMethodName)
496
    {
497
        $this->iProceedSelectingShippingCountryAndShippingMethod(null, $shippingMethodName);
498
    }
499
500
    /**
501
     * @When /^I choose "([^"]*)" payment method$/
502
     */
503
    public function iChoosePaymentMethod($paymentMethodName)
504
    {
505
        $this->selectPaymentPage->selectPaymentMethod($paymentMethodName ?: 'Offline');
506
        $this->selectPaymentPage->nextStep();
507
    }
508
509
    /**
510
     * @When I change payment method to :paymentMethodName
511
     */
512
    public function iChangePaymentMethodTo($paymentMethodName)
513
    {
514
        $this->orderDetails->choosePaymentMethod($paymentMethodName);
515
    }
516
517
    /**
518
     * @When I go back to shipping step of the checkout
519
     */
520
    public function iGoBackToShippingStepOfTheCheckout()
521
    {
522
        $this->selectShippingPage->open();
523
    }
524
525
    /**
526
     * @Given I have proceeded selecting :paymentMethodName payment method
527
     * @When /^I (?:proceed|proceeded) selecting "([^"]+)" payment method$/
528
     */
529
    public function iProceedSelectingPaymentMethod($paymentMethodName = 'Offline')
530
    {
531
        $this->iProceedSelectingShippingCountryAndPaymentMethod(null, $paymentMethodName);
0 ignored issues
show
Bug introduced by
The method iProceedSelectingShippingCountryAndPaymentMethod() does not exist on Sylius\Behat\Context\Ui\CheckoutContext. Did you maybe mean iProceedSelectingShippingCountry()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

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