@shopware-ag/acceptance-test-suite 12.22.0 → 12.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1113,7 +1113,7 @@ const common$b = {
1113
1113
  const listing$n = {
1114
1114
  addNewSet: "Add new set"
1115
1115
  };
1116
- const create$d = {
1116
+ const create$e = {
1117
1117
  assignTo: "Assign To",
1118
1118
  save: "Save",
1119
1119
  cancel: "Cancel"
@@ -1145,7 +1145,7 @@ const dialogs$7 = {
1145
1145
  const administrationCustomField = {
1146
1146
  common: common$b,
1147
1147
  listing: listing$n,
1148
- create: create$d,
1148
+ create: create$e,
1149
1149
  detail: detail$n,
1150
1150
  general: general$9,
1151
1151
  actions: actions$g,
@@ -1206,7 +1206,7 @@ const administrationDocument = {
1206
1206
  detail: detail$m
1207
1207
  };
1208
1208
 
1209
- const create$c = {
1209
+ const create$d = {
1210
1210
  searchLayoutsPlaceholder: "Search layouts...",
1211
1211
  assignLayout: "Assign layout",
1212
1212
  createNewLayout: "Create new layout",
@@ -1225,7 +1225,7 @@ const layout$1 = {
1225
1225
  editInDesigner: "Edit in designer"
1226
1226
  };
1227
1227
  const administrationLandingPage = {
1228
- create: create$c,
1228
+ create: create$d,
1229
1229
  general: general$8,
1230
1230
  layout: layout$1
1231
1231
  };
@@ -1233,7 +1233,7 @@ const administrationLandingPage = {
1233
1233
  const listing$l = {
1234
1234
  createNewLayout: "Create new layout"
1235
1235
  };
1236
- const create$b = {
1236
+ const create$c = {
1237
1237
  shopPage: "Shop page",
1238
1238
  landingPage: "Landing page",
1239
1239
  listingPage: "Listing page",
@@ -1255,7 +1255,7 @@ const detail$l = {
1255
1255
  };
1256
1256
  const administrationLayout = {
1257
1257
  listing: listing$l,
1258
- create: create$b,
1258
+ create: create$c,
1259
1259
  detail: detail$l
1260
1260
  };
1261
1261
 
@@ -1276,7 +1276,7 @@ const listing$k = {
1276
1276
  testFlow: "Test flow",
1277
1277
  flowTemplates: "Flow templates"
1278
1278
  };
1279
- const create$a = {
1279
+ const create$b = {
1280
1280
  addAction: "Add action",
1281
1281
  addConditionIf: "Add condition (IF)",
1282
1282
  addActionThen: "Add action (THEN)",
@@ -1299,7 +1299,7 @@ const messages$6 = {
1299
1299
  };
1300
1300
  const administrationFlowBuilder = {
1301
1301
  listing: listing$k,
1302
- create: create$a,
1302
+ create: create$b,
1303
1303
  detail: detail$k,
1304
1304
  templates: templates$1,
1305
1305
  messages: messages$6
@@ -1334,7 +1334,7 @@ const administrationDashboard = {
1334
1334
  const listing$j = {
1335
1335
  addManufacturer: "Add manufacturer"
1336
1336
  };
1337
- const create$9 = {
1337
+ const create$a = {
1338
1338
  name: "Name",
1339
1339
  website: "Website",
1340
1340
  save: "Save",
@@ -1353,7 +1353,7 @@ const dialogs$6 = {
1353
1353
  };
1354
1354
  const administrationManufacturer = {
1355
1355
  listing: listing$j,
1356
- create: create$9,
1356
+ create: create$a,
1357
1357
  detail: detail$j,
1358
1358
  actions: actions$f,
1359
1359
  dialogs: dialogs$6
@@ -1612,7 +1612,7 @@ const listing$g = {
1612
1612
  const detail$f = {
1613
1613
  technicalUrl: "Technical URL"
1614
1614
  };
1615
- const create$8 = {
1615
+ const create$9 = {
1616
1616
  title: "New customer group",
1617
1617
  cardTitle: "Customer group",
1618
1618
  save: "Save",
@@ -1624,7 +1624,7 @@ const create$8 = {
1624
1624
  const administrationCustomerGroup = {
1625
1625
  listing: listing$g,
1626
1626
  detail: detail$f,
1627
- create: create$8
1627
+ create: create$9
1628
1628
  };
1629
1629
 
1630
1630
  const welcome$1 = {
@@ -1720,7 +1720,16 @@ const detail$e = {
1720
1720
  colorProperty: "Color",
1721
1721
  sizeProperty: "Size",
1722
1722
  stockPlaceholder: "Enter quantity in stock...",
1723
- restockTimePlaceholder: "Enter restock time in days..."
1723
+ restockTimePlaceholder: "Enter restock time in days...",
1724
+ name: "Name",
1725
+ productNumber: "Product number",
1726
+ stock: "Stock",
1727
+ copySuffix: "Copy",
1728
+ width: "Width",
1729
+ height: "Height",
1730
+ length: "Length",
1731
+ weight: "Weight",
1732
+ description: "Description"
1724
1733
  };
1725
1734
  const variants$1 = {
1726
1735
  properties: "Properties"
@@ -1737,8 +1746,11 @@ const bulkEdit$2 = {
1737
1746
  close: "Close"
1738
1747
  };
1739
1748
  const listing$f = {
1749
+ addProduct: "Add product",
1740
1750
  bulkEdit: "Bulk edit",
1741
- startBulkEdit: "Start bulk edit"
1751
+ startBulkEdit: "Start bulk edit",
1752
+ addDigitalProduct: "Add digital product",
1753
+ digitalIndicator: "digital"
1742
1754
  };
1743
1755
  const tabs$7 = {
1744
1756
  specifications: "Specifications",
@@ -1754,7 +1766,10 @@ const buttons$b = {
1754
1766
  uploadFile: "Upload file",
1755
1767
  generateVariants: "Generate variants",
1756
1768
  next: "Next",
1757
- saveVariants: "Save variants"
1769
+ saveVariants: "Save variants",
1770
+ cancel: "Cancel",
1771
+ saveAndDuplicate: "Save and duplicate",
1772
+ "delete": "Delete"
1758
1773
  };
1759
1774
  const modals$2 = {
1760
1775
  generateVariants: "Generate variants"
@@ -1767,6 +1782,9 @@ const propertyValues$1 = {
1767
1782
  medium: "Medium",
1768
1783
  large: "Large"
1769
1784
  };
1785
+ const create$8 = {
1786
+ title: "New product"
1787
+ };
1770
1788
  const administrationProduct = {
1771
1789
  detail: detail$e,
1772
1790
  variants: variants$1,
@@ -1777,7 +1795,8 @@ const administrationProduct = {
1777
1795
  tabs: tabs$7,
1778
1796
  buttons: buttons$b,
1779
1797
  modals: modals$2,
1780
- propertyValues: propertyValues$1
1798
+ propertyValues: propertyValues$1,
1799
+ create: create$8
1781
1800
  };
1782
1801
 
1783
1802
  const tabs$6 = {
@@ -2765,9 +2784,11 @@ const deAdministrationPayment = {
2765
2784
  };
2766
2785
 
2767
2786
  const listing$4 = {
2768
- addProduct: "Produkt hinzufügen",
2787
+ addProduct: "Produkt anlegen",
2769
2788
  bulkEdit: "Massenbearbeitung",
2770
- startBulkEdit: "Bearbeiten"
2789
+ startBulkEdit: "Bearbeiten",
2790
+ addDigitalProduct: "Digitales Produkt anlegen",
2791
+ digitalIndicator: "digital"
2771
2792
  };
2772
2793
  const create$1 = {
2773
2794
  title: "Neues Produkt",
@@ -2786,7 +2807,12 @@ const detail$3 = {
2786
2807
  colorProperty: "Color",
2787
2808
  sizeProperty: "Size",
2788
2809
  stockPlaceholder: "Gib den Lagerbestand ein ...",
2789
- restockTimePlaceholder: "Lagerbestand"
2810
+ restockTimePlaceholder: "Lagerbestand",
2811
+ copySuffix: "Kopie",
2812
+ width: "Breite",
2813
+ height: "Höhe",
2814
+ length: "Länge",
2815
+ weight: "Gewicht"
2790
2816
  };
2791
2817
  const errors$1 = {
2792
2818
  flows: {
@@ -2819,7 +2845,10 @@ const buttons$5 = {
2819
2845
  uploadFile: "Hochladen",
2820
2846
  generateVariants: "Generate variants",
2821
2847
  next: "Weiter",
2822
- saveVariants: "Speichern"
2848
+ saveVariants: "Speichern",
2849
+ cancel: "Abbrechen",
2850
+ saveAndDuplicate: "Speichern und duplizieren",
2851
+ "delete": "Löschen"
2823
2852
  };
2824
2853
  const modals$1 = {
2825
2854
  generateVariants: "Generate variants"
@@ -6687,7 +6716,7 @@ class TestDataService {
6687
6716
  displayGross: true,
6688
6717
  registrationActive: true,
6689
6718
  registrationTitle: customerGroupName,
6690
- registrationIntroduction: `${customerGroupName}-Introduction`,
6719
+ registrationIntroduction: `<p>${customerGroupName}-Introduction</p>`,
6691
6720
  registrationSeoMetaDescription: `${customerGroupName}-SEO-Description`,
6692
6721
  registrationOnlyCompanyRegistration: false,
6693
6722
  customFields: {},
@@ -8581,6 +8610,9 @@ async function getCustomFieldCardLocators(page, customFieldSetName, customFieldN
8581
8610
  };
8582
8611
  }
8583
8612
 
8613
+ function fieldName$1(label) {
8614
+ return new RegExp(`^${label.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s*\\*?$`);
8615
+ }
8584
8616
  class ProductDetail {
8585
8617
  contentView;
8586
8618
  productHeadline;
@@ -8590,9 +8622,17 @@ class ProductDetail {
8590
8622
  savePhysicalProductButton;
8591
8623
  saveButtonLoadingSpinner;
8592
8624
  saveButtonCheckMark;
8625
+ /**
8626
+ * "Save and duplicate" is only reachable through the split button next to "Save".
8627
+ */
8628
+ saveContextMenuButton;
8629
+ saveAndDuplicateButton;
8593
8630
  /**
8594
8631
  * General Info
8595
8632
  */
8633
+ nameInput;
8634
+ productNumberInput;
8635
+ descriptionEditor;
8596
8636
  manufacturerDropdownText;
8597
8637
  /**
8598
8638
  * Prices
@@ -8609,6 +8649,13 @@ class ProductDetail {
8609
8649
  activeForAllSalesChannelsToggle;
8610
8650
  tagsInput;
8611
8651
  saleChannelsInput;
8652
+ saleChannelsSearchInput;
8653
+ selectedSaleChannel;
8654
+ categoriesInput;
8655
+ categoriesSearchInput;
8656
+ selectedCategory;
8657
+ categorySearchResult;
8658
+ saleChannelSearchResult;
8612
8659
  /**
8613
8660
  * Labelling
8614
8661
  */
@@ -8616,9 +8663,16 @@ class ProductDetail {
8616
8663
  /**
8617
8664
  * Media Upload interactions
8618
8665
  */
8666
+ mediaCard;
8619
8667
  uploadMediaButton;
8620
8668
  coverImage;
8621
8669
  productImage;
8670
+ /**
8671
+ * Files of a digital product
8672
+ */
8673
+ downloadsCard;
8674
+ uploadDownloadFileButton;
8675
+ downloadFileName;
8622
8676
  /**
8623
8677
  * Tabs
8624
8678
  */
@@ -8664,6 +8718,14 @@ class ProductDetail {
8664
8718
  * Cards
8665
8719
  */
8666
8720
  customFieldCard;
8721
+ /**
8722
+ * Specifications tab, product measurements
8723
+ */
8724
+ measurementCard;
8725
+ widthInput;
8726
+ heightInput;
8727
+ lengthInput;
8728
+ weightInput;
8667
8729
  page;
8668
8730
  instanceMeta;
8669
8731
  constructor(page, instanceMeta) {
@@ -8671,59 +8733,131 @@ class ProductDetail {
8671
8733
  this.instanceMeta = instanceMeta;
8672
8734
  this.contentView = page.locator(".sw-desktop__content");
8673
8735
  this.productHeadline = page.locator(".smart-bar__header");
8674
- this.savePhysicalProductButton = page.getByRole("button", { name: translate("administration:product:buttons.save") });
8736
+ this.savePhysicalProductButton = page.getByRole("button", {
8737
+ name: translate("administration:product:buttons.save")
8738
+ });
8675
8739
  this.saveButtonCheckMark = page.locator(".icon--regular-checkmark-xs");
8676
8740
  this.saveButtonLoadingSpinner = page.locator("sw-loader");
8677
- this.specificationsTabLink = page.getByRole("tab", { name: translate("administration:product:tabs.specifications") });
8678
- this.advancedPricingTabLink = page.getByRole("tab", { name: translate("administration:product:tabs.advancedPricing") });
8679
- this.variantsTabLink = page.getByRole("tab", { name: translate("administration:product:tabs.variants") });
8680
- this.layoutTabLink = page.getByRole("tab", { name: translate("administration:product:tabs.layout") });
8681
- this.crossSellingTabLink = page.getByRole("tab", { name: translate("administration:product:tabs.crossSelling") });
8682
- this.SEOTabLink = page.getByRole("tab", { name: translate("administration:product:tabs.seo") });
8683
- this.reviewsTabLink = page.getByRole("tab", { name: translate("administration:product:tabs.reviews") });
8741
+ this.saveContextMenuButton = page.locator(".sw-product-detail__button-context-menu");
8742
+ this.saveAndDuplicateButton = page.locator(".sw-product-detail__save-duplicate-action");
8743
+ this.specificationsTabLink = page.getByRole("tab", {
8744
+ name: translate("administration:product:tabs.specifications")
8745
+ });
8746
+ this.advancedPricingTabLink = page.getByRole("tab", {
8747
+ name: translate("administration:product:tabs.advancedPricing")
8748
+ });
8749
+ this.variantsTabLink = page.getByRole("tab", {
8750
+ name: translate("administration:product:tabs.variants")
8751
+ });
8752
+ this.layoutTabLink = page.getByRole("tab", {
8753
+ name: translate("administration:product:tabs.layout")
8754
+ });
8755
+ this.crossSellingTabLink = page.getByRole("tab", {
8756
+ name: translate("administration:product:tabs.crossSelling")
8757
+ });
8758
+ this.SEOTabLink = page.getByRole("tab", {
8759
+ name: translate("administration:product:tabs.seo")
8760
+ });
8761
+ this.reviewsTabLink = page.getByRole("tab", {
8762
+ name: translate("administration:product:tabs.reviews")
8763
+ });
8764
+ this.nameInput = page.getByRole("textbox", {
8765
+ name: fieldName$1(translate("administration:product:detail.name"))
8766
+ });
8767
+ this.productNumberInput = page.getByRole("textbox", {
8768
+ name: fieldName$1(translate("administration:product:detail.productNumber"))
8769
+ });
8684
8770
  this.manufacturerDropdownText = page.locator(".sw-select-product__select_manufacturer");
8771
+ this.descriptionEditor = instanceMeta.features["METEOR_TEXT_EDITOR"] ?? satisfies(instanceMeta.version, ">=6.8") ? page.locator(".mt-text-editor__content-editor") : page.locator(".sw-text-editor__content-editor");
8685
8772
  this.priceGrossInput = page.locator("#sw-price-field-gross").first();
8686
8773
  this.stockInput = page.getByPlaceholder(translate("administration:product:detail.stockPlaceholder"));
8687
8774
  this.restockTimeInput = page.getByPlaceholder(translate("administration:product:detail.restockTimePlaceholder"));
8688
8775
  this.activeForAllSalesChannelsToggle = page.locator(".sw-field--product-active").getByRole("checkbox");
8689
8776
  this.tagsInput = page.locator(".sw-product-category-form__tag-field");
8690
8777
  this.saleChannelsInput = page.locator(".sw-product-detail__select-visibility");
8778
+ this.saleChannelsSearchInput = this.saleChannelsInput.locator(".sw-select-selection-list__input");
8779
+ this.selectedSaleChannel = this.saleChannelsInput.locator(".sw-select-selection-list__item-holder");
8780
+ this.categoriesInput = page.locator(".sw-product-detail__select-category");
8781
+ this.categoriesSearchInput = this.categoriesInput.locator(".sw-category-tree__input-field");
8782
+ this.selectedCategory = page.locator(".sw-category-tree-field__selected-label");
8783
+ this.categorySearchResult = (categoryName) => page.locator(".sw-category-tree-field__search-result").filter({ hasText: categoryName });
8784
+ this.saleChannelSearchResult = (salesChannelName) => page.locator(".sw-select-result").filter({ hasText: salesChannelName });
8691
8785
  if (satisfies(instanceMeta.version, "<6.7")) {
8692
8786
  this.releaseDateInput = page.locator(".sw-product-detail-base__labelling-card").locator(".form-control");
8693
8787
  } else {
8694
8788
  this.releaseDateInput = page.locator(".dp__input");
8695
8789
  }
8696
- this.uploadMediaButton = page.getByRole("button", { name: translate("administration:product:buttons.uploadFile") });
8790
+ this.mediaCard = page.locator(".sw-product-detail-base__media");
8791
+ this.uploadMediaButton = this.mediaCard.getByRole("button", {
8792
+ name: translate("administration:product:buttons.uploadFile")
8793
+ });
8697
8794
  this.coverImage = page.locator(".sw-product-media-form__cover-image");
8698
8795
  this.productImage = page.locator(".sw-media-preview-v2__item");
8699
- this.generateVariantsButton = page.getByRole("button", { name: translate("administration:product:buttons.generateVariants") });
8700
- this.variantsModal = page.getByRole("dialog", { name: translate("administration:product:modals.generateVariants") });
8701
- this.variantsModalHeadline = this.variantsModal.getByRole("heading", { name: translate("administration:product:modals.generateVariants") });
8702
- this.variantsNextButton = this.variantsModal.getByRole("button", { name: translate("administration:product:buttons.next"), exact: true });
8703
- this.variantsSaveButton = this.variantsModal.getByRole("button", { name: translate("administration:product:buttons.saveVariants") });
8796
+ this.downloadsCard = page.locator(".sw-product-detail-base__downloads");
8797
+ this.uploadDownloadFileButton = this.downloadsCard.getByRole("button", {
8798
+ name: translate("administration:product:buttons.uploadFile")
8799
+ });
8800
+ this.downloadFileName = this.downloadsCard.locator(".sw-product-download-form-row__name");
8801
+ this.generateVariantsButton = page.getByRole("button", {
8802
+ name: translate("administration:product:buttons.generateVariants")
8803
+ });
8804
+ this.variantsModal = page.getByRole("dialog", {
8805
+ name: translate("administration:product:modals.generateVariants")
8806
+ });
8807
+ this.variantsModalHeadline = this.variantsModal.getByRole("heading", {
8808
+ name: translate("administration:product:modals.generateVariants")
8809
+ });
8810
+ this.variantsNextButton = this.variantsModal.getByRole("button", {
8811
+ name: translate("administration:product:buttons.next"),
8812
+ exact: true
8813
+ });
8814
+ this.variantsSaveButton = this.variantsModal.getByRole("button", {
8815
+ name: translate("administration:product:buttons.saveVariants")
8816
+ });
8704
8817
  this.propertyName = (propertyName) => this.variantsModal.getByText(propertyName);
8705
8818
  this.propertyValueCheckbox = (propertyValueName) => this.variantsModal.getByRole("row", { name: propertyValueName }).getByRole("checkbox");
8706
8819
  this.propertyGroupColor = this.variantsModal.getByText(translate("administration:product:detail.colorProperty")).first();
8707
8820
  this.propertyGroupSize = this.variantsModal.getByText(translate("administration:product:detail.sizeProperty")).first();
8708
8821
  this.propertyOptionGrid = this.variantsModal.locator(".sw-property-search__tree-selection__option_grid");
8709
- this.propertyOptionColorBlue = this.propertyOptionGrid.getByRole("row", { name: translate("administration:product:propertyValues.blue") }).getByRole("checkbox");
8710
- this.propertyOptionColorRed = this.propertyOptionGrid.getByRole("row", { name: translate("administration:product:propertyValues.red") }).getByRole("checkbox");
8711
- this.propertyOptionColorGreen = this.propertyOptionGrid.getByRole("row", { name: translate("administration:product:propertyValues.green") }).getByRole("checkbox");
8712
- this.propertyOptionSizeSmall = this.propertyOptionGrid.getByRole("row", { name: translate("administration:product:propertyValues.small") }).getByRole("checkbox");
8713
- this.propertyOptionSizeMedium = this.propertyOptionGrid.getByRole("row", { name: translate("administration:product:propertyValues.medium") }).getByRole("checkbox");
8714
- this.propertyOptionSizeLarge = this.propertyOptionGrid.getByRole("row", { name: translate("administration:product:propertyValues.large") }).getByRole("checkbox");
8822
+ this.propertyOptionColorBlue = this.propertyOptionGrid.getByRole("row", {
8823
+ name: translate("administration:product:propertyValues.blue")
8824
+ }).getByRole("checkbox");
8825
+ this.propertyOptionColorRed = this.propertyOptionGrid.getByRole("row", {
8826
+ name: translate("administration:product:propertyValues.red")
8827
+ }).getByRole("checkbox");
8828
+ this.propertyOptionColorGreen = this.propertyOptionGrid.getByRole("row", {
8829
+ name: translate("administration:product:propertyValues.green")
8830
+ }).getByRole("checkbox");
8831
+ this.propertyOptionSizeSmall = this.propertyOptionGrid.getByRole("row", {
8832
+ name: translate("administration:product:propertyValues.small")
8833
+ }).getByRole("checkbox");
8834
+ this.propertyOptionSizeMedium = this.propertyOptionGrid.getByRole("row", {
8835
+ name: translate("administration:product:propertyValues.medium")
8836
+ }).getByRole("checkbox");
8837
+ this.propertyOptionSizeLarge = this.propertyOptionGrid.getByRole("row", {
8838
+ name: translate("administration:product:propertyValues.large")
8839
+ }).getByRole("checkbox");
8715
8840
  if (satisfies(instanceMeta.version, "<6.7")) {
8716
8841
  this.customFieldCard = page.locator(".sw-card").getByText(translate("administration:customField:general.customFields"));
8717
8842
  } else {
8718
8843
  this.customFieldCard = page.locator(".mt-card").getByText(translate("administration:customField:general.customFields"));
8719
8844
  }
8845
+ this.measurementCard = satisfies(instanceMeta.version, "<6.7.1") ? page.locator(".sw-product-detail-specification__measures-packaging") : page.locator(".sw-product-detail-specification__measurement");
8846
+ this.widthInput = this.measurementCard.getByRole("textbox", { name: translate("administration:product:detail.width"), exact: true });
8847
+ this.heightInput = this.measurementCard.getByRole("textbox", { name: translate("administration:product:detail.height"), exact: true });
8848
+ this.lengthInput = this.measurementCard.getByRole("textbox", { name: translate("administration:product:detail.length"), exact: true });
8849
+ this.weightInput = this.measurementCard.getByRole("textbox", { name: translate("administration:product:detail.weight"), exact: true });
8720
8850
  }
8721
8851
  async getCustomFieldSetCardContentByName(customFieldSetName) {
8722
8852
  let customFieldCard;
8723
8853
  if (satisfies(this.instanceMeta.version, "<6.7")) {
8724
- customFieldCard = this.page.locator(".sw-card").filter({ hasText: translate("administration:customField:general.customFields") });
8854
+ customFieldCard = this.page.locator(".sw-card").filter({
8855
+ hasText: translate("administration:customField:general.customFields")
8856
+ });
8725
8857
  } else {
8726
- customFieldCard = this.page.locator(".mt-card").filter({ hasText: translate("administration:customField:general.customFields") });
8858
+ customFieldCard = this.page.locator(".mt-card").filter({
8859
+ hasText: translate("administration:customField:general.customFields")
8860
+ });
8727
8861
  }
8728
8862
  const customFieldSetTab = customFieldCard.getByText(customFieldSetName);
8729
8863
  const customFieldSetTabCustomContent = customFieldCard.locator(`.sw-custom-field-set-renderer-tab-content__${customFieldSetName}`);
@@ -8740,6 +8874,57 @@ class ProductDetail {
8740
8874
  }
8741
8875
  }
8742
8876
 
8877
+ function fieldName(label) {
8878
+ return new RegExp(`^${label.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s*\\*?$`);
8879
+ }
8880
+ class ProductCreate {
8881
+ page;
8882
+ instanceMeta;
8883
+ headline;
8884
+ /**
8885
+ * General information
8886
+ */
8887
+ nameInput;
8888
+ productNumberInput;
8889
+ /**
8890
+ * Prices
8891
+ */
8892
+ priceGrossInput;
8893
+ priceNetInput;
8894
+ /**
8895
+ * Deliverability
8896
+ */
8897
+ stockInput;
8898
+ constructor(page, instanceMeta) {
8899
+ this.page = page;
8900
+ this.instanceMeta = instanceMeta;
8901
+ this.headline = page.locator(".smart-bar__header");
8902
+ this.nameInput = page.getByRole("textbox", {
8903
+ name: fieldName(translate("administration:product:detail.name"))
8904
+ });
8905
+ this.productNumberInput = page.getByRole("textbox", {
8906
+ name: fieldName(translate("administration:product:detail.productNumber"))
8907
+ });
8908
+ this.priceGrossInput = page.locator("#sw-price-field-gross").first();
8909
+ this.priceNetInput = page.locator("#sw-price-field-net").first();
8910
+ this.stockInput = page.getByRole("textbox", {
8911
+ name: translate("administration:product:detail.stock"),
8912
+ exact: true
8913
+ });
8914
+ }
8915
+ /**
8916
+ * Returns the url to the creation page.
8917
+ *
8918
+ * @param creationType - Physical products are created by default, digital products carry a file instead of stock.
8919
+ */
8920
+ url(creationType = "physical") {
8921
+ if (satisfies(this.instanceMeta.version, "<6.7.7")) {
8922
+ return `#/sw/product/create/base?creationStates=${creationType === "digital" ? "is-download" : "is-physical"}`;
8923
+ }
8924
+ return `#/sw/product/create/base?creationType=${creationType}`;
8925
+ }
8926
+ }
8927
+
8743
8928
  class OrderDetail {
8744
8929
  saveButton;
8745
8930
  dataGridContextButton;
@@ -9057,11 +9242,7 @@ class CustomerGroupCreate {
9057
9242
  this.customerGroupPriceBasisNet = page.locator("#sw-field--customerGroup-priceBasis-1");
9058
9243
  this.customSignupFormToggle = page.getByLabel(translate("administration:customerGroup:create.customSignupForm"));
9059
9244
  this.signupFormTitle = page.locator("#sw-field--customerGroup-registrationTitle");
9060
- if (satisfies(instanceMeta.version, "<6.8")) {
9061
- this.signupFormIntroduction = page.locator(".sw-text-editor__content-editor");
9062
- } else {
9063
- this.signupFormIntroduction = page.locator(".mt-text-editor__content-editor");
9064
- }
9245
+ this.signupFormIntroduction = instanceMeta.features["METEOR_TEXT_EDITOR"] ?? satisfies(instanceMeta.version, ">=6.8") ? page.locator(".mt-text-editor__content-editor") : page.locator(".sw-text-editor__content-editor");
9065
9246
  if (satisfies(instanceMeta.version, "<6.7")) {
9066
9247
  this.signupFormSeoDescription = page.locator("#sw-field--customerGroup-registrationSeoMetaDescription");
9067
9248
  } else {
@@ -10354,6 +10535,14 @@ class ManufacturerDetail extends ManufacturerCreate {
10354
10535
  }
10355
10536
 
10356
10537
  class ProductListing {
10538
+ /**
10539
+ * Smart bar
10540
+ *
10541
+ * A digital product is only reachable through the split button next to "Add product".
10542
+ */
10543
+ addProductButton;
10544
+ addProductContextMenuButton;
10545
+ addDigitalProductLink;
10357
10546
  /**
10358
10547
  * Multi selection
10359
10548
  */
@@ -10365,12 +10554,33 @@ class ProductListing {
10365
10554
  */
10366
10555
  bulkEditModal;
10367
10556
  startBulkEditButton;
10557
+ /**
10558
+ * Row actions and deletion
10559
+ */
10560
+ deleteContextMenuItem;
10561
+ deleteConfirmationModal;
10562
+ confirmDeleteButton;
10368
10563
  constructor(page) {
10369
10564
  this.page = page;
10565
+ this.addProductButton = page.locator(".smart-bar__actions .sw-product-list__add-physical-button");
10566
+ this.addProductContextMenuButton = page.locator(".sw-product-list__button-context-menu");
10567
+ this.addDigitalProductLink = page.getByRole("link", {
10568
+ name: translate("administration:product:listing.addDigitalProduct")
10569
+ });
10370
10570
  this.productsTable = page.locator(".sw-data-grid__table");
10371
- this.bulkEditButton = page.getByRole("button", { name: translate("administration:product:listing.bulkEdit") });
10571
+ this.bulkEditButton = page.getByRole("button", {
10572
+ name: translate("administration:product:listing.bulkEdit")
10573
+ });
10574
+ this.deleteContextMenuItem = page.locator(".sw-entity-listing__context-menu-edit-delete");
10575
+ this.deleteConfirmationModal = page.locator(".sw-modal");
10576
+ this.confirmDeleteButton = this.deleteConfirmationModal.getByRole("button", {
10577
+ name: translate("administration:product:buttons.delete"),
10578
+ exact: true
10579
+ });
10372
10580
  this.bulkEditModal = page.locator(".sw-product-bulk-edit-modal");
10373
- this.startBulkEditButton = this.bulkEditModal.getByRole("button", { name: translate("administration:product:listing.startBulkEdit") });
10581
+ this.startBulkEditButton = this.bulkEditModal.getByRole("button", {
10582
+ name: translate("administration:product:listing.startBulkEdit")
10583
+ });
10374
10584
  }
10375
10585
  /**
10376
10586
  * Returns the url to the listing page.
@@ -10397,21 +10607,31 @@ class ProductListing {
10397
10607
  * @param productNumber - Product number you are looking for.
10398
10608
  */
10399
10609
  async getProductRow(productNumber) {
10400
- const productTableRow = this.productsTable.locator(".sw-data-grid__row", { hasText: productNumber });
10610
+ const productTableRow = this.productsTable.locator(".sw-data-grid__row", {
10611
+ hasText: productNumber
10612
+ });
10401
10613
  const productNameSelector = ".sw-data-grid__cell--name";
10402
10614
  const productNumberSelector = ".sw-data-grid__cell--productNumber";
10403
10615
  const productManufacturerSelector = ".sw-data-grid__cell--manufacturer-name";
10404
- const productActiveSelector = "sw-icon__regular-checkmark-xs";
10405
- const productInactiveSelector = "sw-icon__regular-times-s";
10616
+ const productDigitalIndicatorSelector = ".sw-product-list__digital-indicator";
10617
+ const productActiveSelector = ".icon--regular-checkmark-xs";
10618
+ const productInactiveSelector = ".icon--regular-times-s";
10619
+ const productStockSelector = ".sw-data-grid__cell--stock";
10620
+ const productAvailableStockSelector = ".sw-data-grid__cell--availableStock";
10621
+ const productActionsMenuSelector = ".sw-data-grid__actions-menu";
10406
10622
  const productPriceSelector = ".sw-data-grid__cell--price-EUR";
10407
10623
  return {
10408
10624
  selectionCheckbox: productTableRow.getByRole("checkbox"),
10409
10625
  productName: productTableRow.locator(productNameSelector),
10626
+ productDigitalIndicator: productTableRow.locator(productDigitalIndicatorSelector),
10410
10627
  productNumber: productTableRow.locator(productNumberSelector),
10411
10628
  productManufacturer: productTableRow.locator(productManufacturerSelector),
10412
- productActive: productTableRow.getByTestId(productActiveSelector),
10413
- productInactive: productTableRow.getByTestId(productInactiveSelector),
10414
- productPrice: productTableRow.locator(productPriceSelector)
10629
+ productActive: productTableRow.locator(productActiveSelector),
10630
+ productInactive: productTableRow.locator(productInactiveSelector),
10631
+ productPrice: productTableRow.locator(productPriceSelector),
10632
+ productStock: productTableRow.locator(productStockSelector),
10633
+ productAvailableStock: productTableRow.locator(productAvailableStockSelector),
10634
+ actionsMenuButton: productTableRow.locator(productActionsMenuSelector)
10415
10635
  };
10416
10636
  }
10417
10637
  }
@@ -11315,6 +11535,7 @@ class DataSharingConsentModal {
11315
11535
 
11316
11536
  const AdminPageObjects = {
11317
11537
  ProductDetail,
11538
+ ProductCreate,
11318
11539
  OrderDetail,
11319
11540
  CustomerListing,
11320
11541
  CustomerDetail,
@@ -11370,6 +11591,9 @@ const test$6 = test$e.extend({
11370
11591
  AdminProductDetail: async ({ AdminPage, InstanceMeta }, use) => {
11371
11592
  await use(new ProductDetail(AdminPage, InstanceMeta));
11372
11593
  },
11594
+ AdminProductCreate: async ({ AdminPage, InstanceMeta }, use) => {
11595
+ await use(new ProductCreate(AdminPage, InstanceMeta));
11596
+ },
11373
11597
  AdminOrderDetail: async ({ AdminPage, InstanceMeta }, use) => {
11374
11598
  await use(new OrderDetail(AdminPage, InstanceMeta));
11375
11599
  },
@@ -12087,6 +12311,88 @@ const SaveProduct = test$e.extend({
12087
12311
  }
12088
12312
  });
12089
12313
 
12314
+ const SaveAndDuplicateProduct = test$e.extend({
12315
+ SaveAndDuplicateProduct: async ({ AdminProductDetail, TestDataService }, use) => {
12316
+ const task = () => {
12317
+ return async function SaveAndDuplicateProduct2() {
12318
+ const page = AdminProductDetail.page;
12319
+ await AdminProductDetail.saveContextMenuButton.click();
12320
+ const cloneRequest = page.waitForResponse((response) => response.url().includes("/api/_action/clone/product/"));
12321
+ await AdminProductDetail.saveAndDuplicateButton.click();
12322
+ const cloneResponse = await cloneRequest;
12323
+ expect(cloneResponse.ok()).toBeTruthy();
12324
+ TestDataService.addCreatedRecord("product", extractIdFromUrl(cloneResponse.url()));
12325
+ const { id: duplicateId } = await cloneResponse.json();
12326
+ TestDataService.addCreatedRecord("product", duplicateId);
12327
+ await page.waitForURL(new RegExp(`#/sw/product/detail/${duplicateId}/`));
12328
+ };
12329
+ };
12330
+ await use(task);
12331
+ }
12332
+ });
12333
+
12334
+ const FillProductBaseData = test$e.extend({
12335
+ FillProductBaseData: async ({ AdminProductCreate, ShopAdmin }, use) => {
12336
+ const task = (product) => {
12337
+ return async function FillProductBaseData2() {
12338
+ await ShopAdmin.fillsIn(AdminProductCreate.nameInput, product.name);
12339
+ if (product.productNumber) {
12340
+ await AdminProductCreate.productNumberInput.fill(product.productNumber);
12341
+ }
12342
+ const priceCalculation = AdminProductCreate.page.waitForResponse((response) => response.url().includes("/api/_action/calculate-price") && response.ok());
12343
+ await ShopAdmin.fillsIn(AdminProductCreate.priceGrossInput, product.grossPrice);
12344
+ await priceCalculation;
12345
+ if (product.stock) {
12346
+ await AdminProductCreate.stockInput.fill(product.stock);
12347
+ }
12348
+ };
12349
+ };
12350
+ await use(task);
12351
+ }
12352
+ });
12353
+
12354
+ const MEDIA_UPLOAD_URL_PATTERN = /\/api\/_action\/media\/(?<mediaId>[0-9a-f]{32})\/(?:finalize-)?upload/;
12355
+ const UploadProductDownloadFile = test$e.extend({
12356
+ UploadProductDownloadFile: async ({ AdminProductDetail, TestDataService }, use) => {
12357
+ const task = (fileName) => {
12358
+ return async function UploadProductDownloadFile2() {
12359
+ const page = AdminProductDetail.page;
12360
+ const fileChooserPromise = page.waitForEvent("filechooser");
12361
+ await AdminProductDetail.uploadDownloadFileButton.click();
12362
+ const fileChooser = await fileChooserPromise;
12363
+ const fileUpload = page.waitForResponse((response) => MEDIA_UPLOAD_URL_PATTERN.test(response.url()) && response.ok());
12364
+ await fileChooser.setFiles({
12365
+ name: `${fileName}.txt`,
12366
+ mimeType: "text/plain",
12367
+ buffer: Buffer.from(`Digital product file of ${fileName}.`)
12368
+ });
12369
+ const uploadResponse = await fileUpload;
12370
+ const mediaId = MEDIA_UPLOAD_URL_PATTERN.exec(uploadResponse.url())?.groups?.["mediaId"];
12371
+ TestDataService.addCreatedRecord("media", mediaId);
12372
+ };
12373
+ };
12374
+ await use(task);
12375
+ }
12376
+ });
12377
+
12378
+ const DeleteProduct = test$e.extend({
12379
+ DeleteProduct: async ({ AdminProductListing }, use) => {
12380
+ const task = (productNumber) => {
12381
+ return async function DeleteProduct2() {
12382
+ const page = AdminProductListing.page;
12383
+ const productRow = await AdminProductListing.getProductRow(productNumber);
12384
+ await productRow["actionsMenuButton"].click();
12385
+ await AdminProductListing.deleteContextMenuItem.click();
12386
+ const deleteRequest = page.waitForResponse((response) => response.request().method() === "DELETE" && response.url().includes("/api/product/"));
12387
+ await AdminProductListing.confirmDeleteButton.click();
12388
+ const deleteResponse = await deleteRequest;
12389
+ expect(deleteResponse.ok()).toBeTruthy();
12390
+ };
12391
+ };
12392
+ await use(task);
12393
+ }
12394
+ });
12395
+
12090
12396
  const ExpectNotification = test$e.extend({
12091
12397
  ExpectNotification: async ({ ShopAdmin, InstanceMeta }, use) => {
12092
12398
  const task = (message, close = true) => {
@@ -12572,6 +12878,10 @@ const SelectExtensionCategory = test$e.extend({
12572
12878
 
12573
12879
  const test$4 = mergeTests(
12574
12880
  SaveProduct,
12881
+ SaveAndDuplicateProduct,
12882
+ FillProductBaseData,
12883
+ UploadProductDownloadFile,
12884
+ DeleteProduct,
12575
12885
  ExpectNotification,
12576
12886
  CreateLinkTypeCategory,
12577
12887
  BulkEditProducts,