diff --git a/.changeset/calm-trainers-fly.md b/.changeset/calm-trainers-fly.md
new file mode 100644
index 00000000000..a2a1e57adbf
--- /dev/null
+++ b/.changeset/calm-trainers-fly.md
@@ -0,0 +1,5 @@
+---
+"saleor-dashboard": minor
+---
+
+Update variant information in existing product
diff --git a/playwright.config.ts b/playwright.config.ts
index d4540f0819f..5447b2c0768 100644
--- a/playwright.config.ts
+++ b/playwright.config.ts
@@ -8,10 +8,11 @@ export default defineConfig({
   testDir: "playwright/tests",
   fullyParallel: true,
   forbidOnly: !!process.env.CI,
+  // TODO hardcoded values should be extracted to ENVs
   retries: process.env.CI ? 2 : 0,
   workers: process.env.CI ? 2 : undefined,
   reporter: process.env.CI ? "blob" : "html",
-  timeout: 60000,
+  timeout: process.env.CI ? 60000 : 10000,
   // webServer: {
   //   command: "npm run dev",
   //   url: "http://localhost:9000/",
diff --git a/playwright/data/e2eTestData.ts b/playwright/data/e2eTestData.ts
index cd4a64fa0e5..44a3437a8eb 100644
--- a/playwright/data/e2eTestData.ts
+++ b/playwright/data/e2eTestData.ts
@@ -26,6 +26,13 @@ export const PRODUCTS = {
     id: "UHJvZHVjdDo3MzM%3D",
     info: "Product that contains single variant",
   },
+  productWithVariantWhichWillBeUpdated: {
+    id: "UHJvZHVjdDo3NjU%3D",
+    name: "product with variant which will be updated",
+    variantId: "UHJvZHVjdFZhcmlhbnQ6MTIzMg%3D%3D",
+    variantName: "update variant",
+    info: "Product with variant which will be updated",
+  },
   productWithOneVariantToBeDeletedFromDetails: {
     name: "beer to be deleted",
     id: "UHJvZHVjdDo3NTc%3D",
diff --git a/playwright/pages/dialogs/channelSelectDialog.ts b/playwright/pages/dialogs/channelSelectDialog.ts
index 13999dfe750..3675e0b4ccc 100644
--- a/playwright/pages/dialogs/channelSelectDialog.ts
+++ b/playwright/pages/dialogs/channelSelectDialog.ts
@@ -24,6 +24,12 @@ export class ChannelSelectDialog {
       .locator(this.displayedChannelsCheckboxes)
       .click();
   }
+  async selectLastChannel() {
+    await this.displayedChannels
+      .last()
+      .locator(this.displayedChannelsCheckboxes)
+      .click();
+  }
   async clickConfirmButton() {
     await this.confirmButton.first().click();
   }
diff --git a/playwright/pages/productPage.ts b/playwright/pages/productPage.ts
index e96c88aa9fe..3063392e7c9 100644
--- a/playwright/pages/productPage.ts
+++ b/playwright/pages/productPage.ts
@@ -56,7 +56,8 @@ export class ProductPage {
     readonly addWarehouseButton = page.getByTestId("add-warehouse"),
     readonly stockInput = page.getByTestId("stock-input"),
     readonly productImage = page.getByTestId("product-image"),
-    readonly uploadImageButton = page.getByTestId("button-upload-image"),
+    readonly uploadProductImageButton = page.getByTestId("button-upload-image"),
+    readonly chooseMediaVariantButton = page.getByTestId("choose-media-button"),
     readonly uploadSavedImagesButton = page.getByTestId("upload-images"),
     readonly uploadMediaUrlButton = page.getByTestId("upload-media-url"),
     readonly saveUploadUrlButton = page.getByTestId("upload-url-button"),
@@ -113,11 +114,14 @@ export class ProductPage {
   async clickCogShowMoreButtonButton() {
     await this.cogShowMoreButtonButton.click();
   }
-  async clickUploadImagesButtonButton() {
+  async clickUploadImagesButton() {
     await this.uploadSavedImagesButton.click();
   }
   async clickUploadMediaButton() {
-    await this.uploadImageButton.click();
+    await this.uploadProductImageButton.click();
+  }
+  async clickChooseMediaVariantButton() {
+    await this.chooseMediaVariantButton.click();
   }
   async clickBulkDeleteButton() {
     await this.bulkDeleteButton.click();
@@ -203,7 +207,7 @@ export class ProductPage {
 
   async uploadProductImage(fileName: string) {
     const fileChooserPromise = this.page.waitForEvent("filechooser");
-    await this.clickUploadImagesButtonButton();
+    await this.clickUploadImagesButton();
     const fileChooser = await fileChooserPromise;
     await fileChooser.setFiles(path.join("playwright/data/images/", fileName));
     await this.page.waitForLoadState("domcontentloaded");
diff --git a/playwright/pages/variantsPage.ts b/playwright/pages/variantsPage.ts
index 8df122da8b0..19f0628b46a 100644
--- a/playwright/pages/variantsPage.ts
+++ b/playwright/pages/variantsPage.ts
@@ -1,3 +1,4 @@
+import { URL_LIST } from "@data/url";
 import type { Page } from "@playwright/test";
 
 import { BasePage } from "./basePage";
@@ -46,30 +47,36 @@ export class VariantsPage {
   }
 
   async typeVariantName(variantName = "XXL beverage") {
+    await this.variantNameInput.clear();
     await this.variantNameInput.fill(variantName);
   }
   async typeShippingWeight(weight = "150") {
+    await this.shippingWeightInput.clear();
     await this.shippingWeightInput.fill(weight);
   }
   async typeCheckoutLimit(checkoutLimit = "10") {
+    await this.checkoutLimitInput.clear();
     await this.checkoutLimitInput.fill(checkoutLimit);
   }
   async typeSellingPriceInChannel(
     channelName: string,
     sellingPriceValue = "99",
   ) {
-    await this.page
+    const sellingPriceInput = await this.page
       .locator(`[data-test-id="Channel-${channelName}"]`)
       .locator(this.priceFieldInput)
-      .first()
-      .fill(sellingPriceValue);
+      .first();
+    await sellingPriceInput.clear();
+    await sellingPriceInput.fill(sellingPriceValue);
   }
   async typeCostPriceInChannel(channelName: string, costPriceValue = "10") {
-    await this.page
+    const costPriceInput = await this.page
       .locator(`[data-test-id="Channel-${channelName}"]`)
       .locator(this.priceFieldInput)
-      .last()
-      .fill(costPriceValue);
+      .last();
+
+    await costPriceInput.clear();
+    await costPriceInput.fill(costPriceValue);
   }
 
   async clickMageChannelsButton() {
@@ -83,6 +90,7 @@ export class VariantsPage {
   }
 
   async typeSku(sku = "sku dummy e2e") {
+    await this.skuTextField.clear();
     await this.skuTextField.fill(sku);
   }
   async clickAssignWarehouseButton() {
@@ -98,6 +106,11 @@ export class VariantsPage {
     await this.attributeSelector.click();
     await this.attributeOption.first().click();
   }
+  async selectLastAttributeValue() {
+    await this.attributeSelector.locator("input").clear();
+    await this.attributeSelector.click();
+    await this.attributeOption.last().click();
+  }
   async selectWarehouse(warehouse = "Oceania") {
     await this.clickAssignWarehouseButton();
     await this.warehouseOption.locator(`text=${warehouse}`).click();
@@ -112,4 +125,14 @@ export class VariantsPage {
   async addAllMetaData() {
     await this.metadataSeoPage.expandAndAddAllMetadata();
   }
+
+  async gotoExistingVariantPage(productId: string, variantId: string) {
+    console.log(
+      `Navigating to existing variant: ${URL_LIST.products}${productId}/${URL_LIST.variant}${variantId}`,
+    );
+    await this.page.goto(
+      `${URL_LIST.products}${productId}/${URL_LIST.variant}${variantId}`,
+    );
+    await this.variantNameInput.waitFor({ state: "visible" });
+  }
 }
diff --git a/playwright/tests/product.spec.ts b/playwright/tests/product.spec.ts
index 66bfcc18b05..4beb6b57cc9 100644
--- a/playwright/tests/product.spec.ts
+++ b/playwright/tests/product.spec.ts
@@ -277,3 +277,42 @@ test("TC: SALEOR_59 As an admin I should be able to filter products by channel o
     `Product: ${PRODUCTS.productAvailableOnlyInPlnChannel.name} should be visible on grid table`,
   ).toContainText(PRODUCTS.productAvailableOnlyInPlnChannel.name);
 });
+test("TC: SALEOR_60 As an admin I should be able update existing variant @basic-regression @product @e2e", async ({
+  page,
+}) => {
+  const variantName = `TC: SALEOR_60 - variant name - ${new Date().toISOString()}`;
+  const sku = `SALEOR_60-sku-${new Date().toISOString()}`;
+
+  const productPage = new ProductPage(page);
+  const variantsPage = new VariantsPage(page);
+  await variantsPage.gotoExistingVariantPage(
+    PRODUCTS.productWithVariantWhichWillBeUpdated.id,
+    PRODUCTS.productWithVariantWhichWillBeUpdated.variantId,
+  );
+  await variantsPage.typeVariantName(variantName);
+  await variantsPage.clickMageChannelsButton();
+  await variantsPage.channelSelectDialog.clickAllChannelsCheckbox();
+  await variantsPage.channelSelectDialog.selectLastChannel();
+  await variantsPage.channelSelectDialog.clickConfirmButton();
+  await variantsPage.selectLastAttributeValue();
+  await variantsPage.typeCheckoutLimit("50");
+  await variantsPage.typeShippingWeight("1000");
+  await variantsPage.typeSellingPriceInChannel("USD", "120");
+  await variantsPage.typeCostPriceInChannel("USD", "100");
+  await variantsPage.typeSku(sku);
+  await variantsPage.clickSaveVariantButton();
+
+  await variantsPage.expectSuccessBanner();
+  await expect(
+    variantsPage.variantsList.locator(variantsPage.variantsNames, {
+      hasText: variantName,
+    }),
+  ).toBeVisible();
+
+  await variantsPage.selectWarehouse("Africa");
+  await variantsPage.typeQuantityInStock("Africa", "5000");
+  await variantsPage.clickSaveVariantButton();
+
+  await variantsPage.expectSuccessBanner();
+  await productPage.productImage.waitFor({ state: "visible" });
+});