Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(cms-base): push errors from add to cart API call #795

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/sour-lobsters-bow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@shopware-pwa/cms-base": minor
---

Push errors from add to cart API call in SwProductAddTOCart component
10 changes: 10 additions & 0 deletions apps/e2e-tests/page-objects/ProductPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { expect, Locator, Page } from "@playwright/test";

export class ProductPage {
readonly page: Page;
readonly productQuantity: Locator;
readonly addToCartButton: Locator;
readonly variant: Locator;
readonly variantText: Locator;
Expand All @@ -15,6 +16,7 @@ export class ProductPage {

constructor(page: Page) {
this.page = page;
this.productQuantity = page.getByTestId("product-quantity");
this.addToCartButton = page.getByTestId("add-to-cart-button");
this.variant = page.getByTestId("product-variant");
this.variantText = page.getByTestId("product-variant-text");
Expand Down Expand Up @@ -42,6 +44,14 @@ export class ProductPage {
});
}

async addToCartQuantity(quantity: number) {
await this.addToCartButton.waitFor();
await this.productQuantity.waitFor();
await this.productQuantity.fill(String(quantity));
await this.addToCartButton.click();
await this.page.waitForLoadState("networkidle");
}

async addVariantToCart() {
for (const variant of await this.page
.getByTestId("product-variant-text")
Expand Down
9 changes: 9 additions & 0 deletions apps/e2e-tests/tests/addToCart.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ test.describe.parallel.only("Add product to cart / Remove from cart", () => {
await expect(page.getByTestId("cart-product-image")).toBeVisible();
});

test("Add product to cart & show error", async ({ page }) => {
await homePage.openCartPage();
await productPage.addToCartQuantity(99999);

await expect(page.getByTestId("notification-element-message")).toHaveText(
/The product YORK 3 is only available 100 times$/,
);
});

test("Add product to cart from wishlist", async ({ page }) => {
await page.waitForEvent("requestfinished");
await homePage.addProductToWishlist();
Expand Down
16 changes: 12 additions & 4 deletions packages/cms-base/components/SwProductAddToCart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { toRefs } from "vue";
import { defu } from "defu";
import type { Schemas } from "#shopware";
const { pushSuccess } = useNotifications();
const { pushSuccess, pushError } = useNotifications();
const props = defineProps<{
product: Schemas["Product"];
}>();
Expand Down Expand Up @@ -33,7 +33,15 @@ const { product } = toRefs(props);
const { addToCart, quantity } = useAddToCart(product);
const addToCartProxy = async () => {
await addToCart();
const res = await addToCart();
const errors = Object.values(res.errors);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cart errors should be transformed and translated. Please check how it's done in the demo store

https://github.com/shopware/frontends/blob/main/templates/vue-demo-store/components/product/ProductAddToCart.vue#L12

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah nice thanks! Do we also need to handle any translations or can we rely that the API Response is already translated?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello 👋

I have created a new Branch from your PR, and changed the part @mdanilowicz mentioned.

Look here: d8e28c8

But to be honest I do not like the part about the quantity. Currently, we would need to search in the line items for the quantity that was added to the cart. Maybe a more generic error message would be easier.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah nice thanks! Do we also need to handle any translations or can we rely that the API Response is already translated?

Unfortunately, all API errors are in English, even if the context language is different. So, we have to translate it "locally"

if (errors.length > 0) {
const errorMessages = errors.map((error) => error.message);
pushError(errorMessages.join(". "));
return;
}
pushSuccess(
`${props.product?.translated?.name} ${translations.product.addedToCart}`,
);
Expand All @@ -46,8 +54,8 @@ const addToCartProxy = async () => {
<label for="qty" class="text-sm">{{ translations.product.qty }}</label>
<input
id="qty"
type="number"
v-model="quantity"
type="number"
:min="product.minPurchase || 1"
:max="product.calculatedMaxPurchase"
:step="product.purchaseSteps || 1"
Expand All @@ -57,9 +65,9 @@ const addToCartProxy = async () => {
</div>
<div class="basis-3/4 ml-4">
<button
@click="addToCartProxy"
class="py-2 px-6 w-full mt-4 bg-gradient-to-r from-cyan-500 to-blue-500 transition ease-in-out hover:bg-gradient-to-l duration-300 cursor-pointer border border-transparent rounded-md flex items-center justify-center text-base font-medium text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
data-testid="add-to-cart-button"
@click="addToCartProxy"
>
🛍 {{ translations.product.addToCart }}
</button>
Expand Down