Skip to content

Commit

Permalink
feat: handle checkout without shipping methods (#830)
Browse files Browse the repository at this point in the history
* feat: handle checkout without shipping methods

* Update changelog_en.md

---------

Co-authored-by: Cristi Sandru <[email protected]>
  • Loading branch information
FabianGerke and csandru-plenty authored Nov 27, 2024
1 parent 288161c commit bccc152
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 32 deletions.
24 changes: 21 additions & 3 deletions apps/web/__tests__/support/pageObjects/CheckoutPageObject.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { PageObject } from './PageObject';
import type { AddressFixtureOverride } from '~/__tests__/types';

export class CheckoutPageObject extends PageObject {
get goToCheckoutButton() {
Expand Down Expand Up @@ -182,15 +183,15 @@ export class CheckoutPageObject extends PageObject {
return this;
}

fillShippingAddressForm() {
fillShippingAddressForm(fixtureOverride?: AddressFixtureOverride) {
cy.intercept('/plentysystems/setCheckoutAddress')
.as('setCheckoutAddress')
.intercept('/plentysystems/getShippingProvider')
.as('getShippingProvider')
.intercept('/plentysystems/getPaymentProviders')
.as('getPaymentProviders');

this.fillAddressForm();
this.fillAddressForm(fixtureOverride);

cy.wait('@setCheckoutAddress').wait('@getShippingProvider').wait('@getPaymentProviders');

Expand Down Expand Up @@ -231,8 +232,13 @@ export class CheckoutPageObject extends PageObject {
return this;
}

fillAddressForm() {
fillAddressForm(fixtureOverride?: AddressFixtureOverride) {
cy.getFixture('addressForm').then((fixture) => {

if (fixtureOverride) {
fixture = { ...fixture, ...fixtureOverride };
}

this.fillForm(fixture);
});
return this;
Expand All @@ -254,4 +260,16 @@ export class CheckoutPageObject extends PageObject {
get payPalButton() {
return cy.get('.paypal-buttons-context-iframe').first();
}

shouldShowShippingMethods() {
cy.getByTestId('shipping-method-list').should('be.visible');
cy.getByTestId('no-payment-method-available').should('not.exist');
return this;
}

shouldNotShowShippingMethods() {
cy.getByTestId('shipping-method-list').should('not.exist');
cy.getByTestId('no-payment-method-available').should('be.visible');
return this;
}
}
16 changes: 16 additions & 0 deletions apps/web/__tests__/test/smoke/checkoutPage.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,20 @@ describe('Smoke: Checkout Page', () => {
.placeOrderButton()
.displaySuccessPage();
});

it('[smoke] Display "no shipping methods available" when shipping country is Denmark', () => {
homePage.goToCategory();
productListPage.addToCart()

cart.openCart();
checkout
.goToCheckout()
.goToGuestCheckout()
.fillContactInformationForm()
.shouldShowShippingMethods()
.fillShippingAddressForm({
country: '7'
})
.shouldNotShowShippingMethods();
});
});
11 changes: 11 additions & 0 deletions apps/web/__tests__/types/checkout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export type AddressFixtureOverride = {
firstName?: string;
lastName?: string;
phoneNumber?: string;
country?: string;
streetName?: string;
apartment?: string;
city?: string;
state?: string;
zipCode?: string;
}
1 change: 1 addition & 0 deletions apps/web/__tests__/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './checkout';
14 changes: 12 additions & 2 deletions apps/web/components/CheckoutPayment/CheckoutPayment.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<fieldset class="md:mx-4 my-6" data-testid="checkout-payment">
<legend class="text-neutral-900 text-lg font-bold mb-4">{{ t('checkoutPayment.heading') }}</legend>
<div class="grid gap-4 grid-cols-2">
<div v-if="paymentMethods.list.length > 0" class="grid gap-4 grid-cols-2">
<label v-for="paymentMethod in paymentMethods.list" :key="paymentMethod.id" class="relative">
<input
type="radio"
Expand Down Expand Up @@ -31,12 +31,22 @@
</span>
</label>
</div>
<div
v-else
class="flex items-start bg-warning-100 shadow-md pr-2 pl-4 ring-1 ring-warning-200 typography-text-sm md:typography-text-base py-1 rounded-md"
data-testid="no-payment-method-available"
>
<SfIconWarning class="mt-2 mr-2 text-warning-700 shrink-0" />
<div class="py-2 mr-2">
<p>{{ t('checkoutPayment.noMethodsAvailable') }}</p>
</div>
</div>
</fieldset>
</template>

<script setup lang="ts">
import { paymentProviderGetters, type PaymentMethod } from '@plentymarkets/shop-api';
import { SfIconCreditCard } from '@storefront-ui/vue';
import { SfIconCreditCard, SfIconWarning } from '@storefront-ui/vue';
import { type CheckoutPaymentEmits, type CheckoutPaymentProps } from '~/components/CheckoutPayment/types';
const { disabled = false } = defineProps<CheckoutPaymentProps>();
Expand Down
26 changes: 19 additions & 7 deletions apps/web/components/ShippingMethod/ShippingMethod.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
<div data-testid="shipping-method" class="md:px-4 my-6">
<h3 class="text-neutral-900 text-lg font-bold">{{ t('shippingMethod.heading') }}</h3>
<div class="mt-4">
<ul v-if="shippingMethods" class="grid gap-y-4 md:grid-cols-2 md:gap-x-4" role="radiogroup">
<ul
v-if="shippingMethods && shippingMethods.length > 0"
class="grid gap-y-4 md:grid-cols-2 md:gap-x-4"
role="radiogroup"
data-testid="shipping-method-list"
>
<SfListItem
v-for="(method, index) in shippingMethods"
:key="`shipping-method-${index}`"
Expand Down Expand Up @@ -30,9 +35,16 @@
</SfListItem>
</ul>

<div v-else class="flex mb-6">
<SfIconBlock class="mr-2 text-neutral-500" />
<p>{{ t('shippingMethod.description') }}</p>
<div
v-else
class="flex items-start bg-warning-100 shadow-md pr-2 pl-4 ring-1 ring-warning-200 typography-text-sm md:typography-text-base py-1 rounded-md"
data-testid="no-shipping-method-available"
>
<SfIconWarning class="mt-2 mr-2 text-warning-700 shrink-0" />
<div class="py-2 mr-2">
<p v-if="hasCheckoutAddress">{{ t('shippingMethod.noMethodsAvailable') }}</p>
<p v-else>{{ t('shippingMethod.description') }}</p>
</div>
</div>
</div>

Expand All @@ -41,12 +53,12 @@
</template>

<script setup lang="ts">
import { shippingProviderGetters } from '@plentymarkets/shop-api';
import { SfIconBlock, SfListItem, SfRadio } from '@storefront-ui/vue';
import { AddressType, shippingProviderGetters } from '@plentymarkets/shop-api';
import { SfIconWarning, SfListItem, SfRadio } from '@storefront-ui/vue';
import { type CheckoutShippingEmits, type ShippingMethodProps } from './types';
const { shippingMethods, disabled = false } = defineProps<ShippingMethodProps>();
const { hasCheckoutAddress } = useCheckoutAddress(AddressType.Shipping);
const emit = defineEmits<CheckoutShippingEmits>();
const { data: cart } = useCart();
Expand Down
22 changes: 12 additions & 10 deletions apps/web/lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@
},
"functional": {
"cookies": {
"scriptDemo": {
"name": "Script-Demo",
"provider": "plentysystems AG",
"status": "Anwendungsbeispiel zum Laden eines Skripts nach Einwilligung."
},
"payPal": {
"name": "paypal",
"provider": "PayPal (Europe) S.à r.l. et Cie, S.C.A.",
"status": "Erforderlich für die Zahlungsabwicklung über PayPal."
},
"scriptDemo": {
"name": "Script-Demo",
"provider": "plentysystems AG",
"status": "Anwendungsbeispiel zum Laden eines Skripts nach Einwilligung."
}
},
"description": "Diese Cookies ermöglichen, dass die von Nutzern getroffenen Auswahlmöglichkeiten und bevorzugte Einstellungen (z.B. das Deaktivieren der Sprachweiterleitung) gespeichert werden können.",
Expand Down Expand Up @@ -346,7 +346,8 @@
"checkoutPayment": {
"comingSoon": "Bald verfügbar",
"creditCard": "Kreditkarte",
"heading": "Zahlungsart"
"heading": "Zahlungsart",
"noMethodsAvailable": "Es sind keine Zahlungsarten verfügbar. Bitte kontaktieren Sie den Webshop-Anbieter."
},
"clear": "Zurücksetzen",
"clearFilters": "Alle Filter löschen",
Expand Down Expand Up @@ -766,15 +767,15 @@
"pagination": "Paginierte Navigation",
"passwordVisibilty": "Sichtbarkeit des Passworts",
"paypal": {
"cookieNotAccepted": "Bitte akzeptieren Sie unsere Cookies, um PayPal zu nutzen.",
"errorMessageCreditCard": "Die eingegebenen Daten sind ungültig. Überprüfen Sie die Felder Kartennummer, Kartenprüfnummer (CVV), Ablaufdatum.",
"openSettings": "Cookie-Einstellungen öffnen",
"unbrandedCancel": "Abbrechen",
"unbrandedCardNumber": "Kartennummer",
"unbrandedCvv": "Kartenprüfnummer",
"unbrandedExpirationDate": "Ablaufdatum",
"unbrandedNameOnCard": "Karteninhaber",
"unbrandedPay": "Bezahlen",
"cookieNotAccepted": "Bitte akzeptieren Sie unsere Cookies, um PayPal zu nutzen.",
"openSettings": "Cookie-Einstellungen öffnen"
"unbrandedPay": "Bezahlen"
},
"perPage": "Pro Seite",
"phone": "Telefonnummer",
Expand Down Expand Up @@ -888,6 +889,7 @@
"description": "Nicht verfügbar, solange keine Versandadresse angegeben wird.",
"free": "Kostenlos",
"heading": "Versandart",
"noMethodsAvailable": "Es sind keine Versandarten verfügbar. Bitte kontaktieren Sie den Webshop-Anbieter.",
"showDataPrivacyAgreementHint": "Ich bin damit einverstanden, dass meine E-Mail-Adresse bzw. meine Telefonnummer an {parcelServiceInformation} weitergegeben wird, damit der Paketdienstleister vor der Zustellung der Ware zum Zwecke der Abstimmung eines Liefertermins per E-Mail oder Telefon Kontakt mit mir aufnehmen bzw. Statusinformationen zur Sendungszustellung übermitteln kann. Meine diesbezüglich erteilte Einwilligung kann ich jederzeit widerrufen"
},
"showAllReviews": "Alle Bewertungen anzeigen",
Expand Down Expand Up @@ -988,4 +990,4 @@
"delete": "Der Artikel wurde von der Wunschliste entfernt."
},
"youAreOfflineText": "Es scheint, dass Sie derzeit offline sind, überprüfen Sie Ihre Internetverbindung"
}
}
22 changes: 12 additions & 10 deletions apps/web/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@
},
"functional": {
"cookies": {
"scriptDemo": {
"name": "Script demo",
"provider": "plentysystems AG",
"status": "Usage example for loading a script after consent."
},
"payPal": {
"name": "paypal",
"provider": "PayPal (Europe) S.à r.l. et Cie, S.C.A.",
"status": "Required for PayPal payments."
},
"scriptDemo": {
"name": "Script demo",
"provider": "plentysystems AG",
"status": "Usage example for loading a script after consent."
}
},
"description": "These cookies are used to store preferred settings and certain options selected by the user.",
Expand Down Expand Up @@ -346,7 +346,8 @@
"checkoutPayment": {
"comingSoon": "Coming soon",
"creditCard": "Credit Card",
"heading": "Payment method"
"heading": "Payment method",
"noMethodsAvailable": "There are no payment methods available. Please contact the webshop provider."
},
"clear": "Clear",
"clearFilters": "Clear all filters",
Expand Down Expand Up @@ -766,15 +767,15 @@
"pagination": "Paginated Navigation",
"passwordVisibilty": "Password visibility",
"paypal": {
"cookieNotAccepted": "Please accept our cookies to use PayPal: ",
"errorMessageCreditCard": "The input data is invalid. Check the fields Card number, CVV, Expiration date.",
"openSettings": "open cookie settings",
"unbrandedCancel": "Cancel",
"unbrandedCardNumber": "Card number",
"unbrandedCvv": "CVV",
"unbrandedExpirationDate": "Expiration date",
"unbrandedNameOnCard": "Name on card",
"unbrandedPay": "Pay",
"cookieNotAccepted": "Please accept our cookies to use PayPal: ",
"openSettings": "open cookie settings"
"unbrandedPay": "Pay"
},
"perPage": "Per page",
"phone": "Phone",
Expand Down Expand Up @@ -888,6 +889,7 @@
"description": "Not available until a shipping address is provided.",
"free": "Free",
"heading": "Shipping method",
"noMethodsAvailable": "There are no shipping methods available. Please contact the webshop provider.",
"showDataPrivacyAgreementHint": "I agree that my email address and my phone number will be transmitted to {parcelServiceInformation}, so that they can contact me via email or phone in order to determine a delivery date or to communicate status information about the delivery of the shipment. I can revoke this agreement at any time."
},
"showAllReviews": "Show all reviews",
Expand Down Expand Up @@ -988,4 +990,4 @@
"delete": "The item was removed from your wish list."
},
"youAreOfflineText": "It seems you are currently offline, check your internet connection"
}
}
1 change: 1 addition & 0 deletions docs/changelog/changelog_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- Added progress loading indicator animation when navigating between pages.
- Added Zoom functionality to product images.
- New Json Editor
- Added a warning alert on the checkout if no payment or shipping method is available
- Added cookie consent management helper functions read more at https://pwa-docs.plentymarkets.com/guide/how-to/cookie#read-and-react-to-a-registered-cookie.
- Added dynamic structured data from the SEO config.

Expand Down

0 comments on commit bccc152

Please sign in to comment.