@shopware-ag/acceptance-test-suite 12.14.0 → 12.15.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
@@ -3893,11 +3893,28 @@ async function createNewAdminPageContext(browser, SalesChannelBaseConfig) {
3893
3893
  baseURL: SalesChannelBaseConfig.adminUrl,
3894
3894
  serviceWorkers: "block"
3895
3895
  });
3896
+ await mockApiCalls(context);
3896
3897
  const adminPage = await context.newPage();
3897
3898
  await adminPage.goto("#/login");
3898
- await mockApiCalls(adminPage);
3899
3899
  return adminPage;
3900
3900
  }
3901
+ function hideSymfonyToolbarOnReload(page) {
3902
+ const originalReload = page.reload.bind(page);
3903
+ page.reload = async () => {
3904
+ const res = await originalReload();
3905
+ await page.addStyleTag({
3906
+ content: `
3907
+ .sf-toolbar {
3908
+ width: 0 !important;
3909
+ height: 0 !important;
3910
+ display: none !important;
3911
+ pointer-events: none !important;
3912
+ }
3913
+ `.trim()
3914
+ });
3915
+ return res;
3916
+ };
3917
+ }
3901
3918
  async function loginToAdministration(adminLoginPage, merchant, AdminApiContext) {
3902
3919
  const usernamePattern = new RegExp(`${translate("administration:login:username")}|${translate("administration:login:emailAddress")}`);
3903
3920
  const passwordLabel = translate("administration:login:password");
@@ -3914,21 +3931,7 @@ async function loginToAdministration(adminLoginPage, merchant, AdminApiContext)
3914
3931
  const loginButtonLabel = translate("administration:login:loginButton");
3915
3932
  await adminLoginPage.getByRole("button", { name: loginButtonLabel, exact: true }).click();
3916
3933
  await Promise.all(jsLoadingPromises);
3917
- const originalReload = adminLoginPage.reload.bind(adminLoginPage);
3918
- adminLoginPage.reload = async () => {
3919
- const res = await originalReload();
3920
- await adminLoginPage.addStyleTag({
3921
- content: `
3922
- .sf-toolbar {
3923
- width: 0 !important;
3924
- height: 0 !important;
3925
- display: none !important;
3926
- pointer-events: none !important;
3927
- }
3928
- `.trim()
3929
- });
3930
- return res;
3931
- };
3934
+ hideSymfonyToolbarOnReload(adminLoginPage);
3932
3935
  await clearDelayedCache(AdminApiContext);
3933
3936
  await expect(adminLoginPage.locator(".sw-skeleton")).toHaveCount(0);
3934
3937
  await adminLoginPage.waitForURL((url) => {
@@ -3939,32 +3942,47 @@ async function loginToAdministration(adminLoginPage, merchant, AdminApiContext)
3939
3942
  }
3940
3943
 
3941
3944
  const test$b = test$e.extend({
3942
- AdminPage: async ({ IdProvider, AdminApiContext, SalesChannelBaseConfig, browser, CustomTranslationResources }, use) => {
3945
+ AdminSession: [
3946
+ async ({ IdProvider, AdminApiContext, SalesChannelBaseConfig, browser }, use) => {
3947
+ const { id, uuid } = IdProvider.getIdPair();
3948
+ const adminUser = {
3949
+ id: uuid,
3950
+ username: `admin_${id}`,
3951
+ firstName: `${id} admin`,
3952
+ lastName: `${id} admin`,
3953
+ localeId: SalesChannelBaseConfig.currentLocaleId,
3954
+ email: `admin_${id}@example.com`,
3955
+ timeZone: "Europe/Berlin",
3956
+ password: "shopware",
3957
+ admin: true
3958
+ };
3959
+ const response = await AdminApiContext.post("user", {
3960
+ data: adminUser
3961
+ });
3962
+ expect(response.ok()).toBeTruthy();
3963
+ const loginPage = await loginToAdministration(await createNewAdminPageContext(browser, SalesChannelBaseConfig), adminUser, AdminApiContext);
3964
+ const context = loginPage.context();
3965
+ await loginPage.close();
3966
+ await use({ context, user: adminUser });
3967
+ await context.close();
3968
+ await AdminApiContext.delete(`user/${uuid}`);
3969
+ },
3970
+ { scope: "worker" }
3971
+ ],
3972
+ AdminPage: async ({ AdminSession, CustomTranslationResources }, use) => {
3943
3973
  const locale = getLocale();
3944
3974
  const languageHelper = await LanguageHelper.createInstance(locale, CustomTranslationResources);
3945
- const { id, uuid } = IdProvider.getIdPair();
3946
- const adminUser = {
3947
- id: uuid,
3948
- username: `admin_${id}`,
3949
- firstName: `${id} admin`,
3950
- lastName: `${id} admin`,
3951
- localeId: SalesChannelBaseConfig.currentLocaleId,
3952
- email: `admin_${id}@example.com`,
3953
- timezone: "Europe/Berlin",
3954
- password: "shopware",
3955
- admin: true
3956
- };
3957
- const response = await AdminApiContext.post("user", {
3958
- data: adminUser
3959
- });
3960
- expect(response.ok()).toBeTruthy();
3961
- const page = await loginToAdministration(await createNewAdminPageContext(browser, SalesChannelBaseConfig), adminUser, AdminApiContext);
3975
+ const page = await AdminSession.context.newPage();
3976
+ hideSymfonyToolbarOnReload(page);
3977
+ await page.goto("./");
3978
+ await page.waitForURL((url) => url.hash.startsWith("#/") && !url.hash.startsWith("#/login"));
3979
+ await expect(page.getByText(AdminSession.user.firstName + " " + AdminSession.user.lastName).first()).toBeVisible({ timeout: 6e4 });
3980
+ await expect(page.locator(".sw-skeleton")).toHaveCount(0);
3962
3981
  LanguageHelper.setForContext(page.context(), languageHelper);
3963
3982
  setCurrentContext(page.context());
3964
3983
  await use(page);
3965
3984
  await page.close();
3966
3985
  setCurrentContext(null);
3967
- await AdminApiContext.delete(`user/${uuid}`);
3968
3986
  },
3969
3987
  StorefrontPage: async ({ DefaultSalesChannel, SalesChannelBaseConfig, browser, AdminApiContext, StoreApiContext, InstanceMeta, CustomTranslationResources }, use) => {
3970
3988
  const { url, salesChannel } = DefaultSalesChannel;
@@ -4293,16 +4311,20 @@ class TestDataService {
4293
4311
  * Creates a digital product with a text file as its download.
4294
4312
  * The product will be added to the default sales channel category if configured.
4295
4313
  *
4314
+ * Digital products default to `maxPurchase: 1`, mirroring the Administration
4315
+ * which forces this limit when a product is created as a digital type.
4316
+ * Pass `maxPurchase` in the overrides to change it.
4317
+ *
4296
4318
  * @param content - The content of the text file for the product download.
4297
4319
  * @param overrides - Specific data overrides that will be applied to the product data struct.
4298
4320
  * @param taxId - The uuid of the tax rule to use for the product pricing.
4299
4321
  * @param currencyId - The uuid of the currency to use for the product pricing.
4300
4322
  */
4301
4323
  async createDigitalProduct(content = "Lorem ipsum dolor", overrides = {}, taxId = this.defaultTaxId, currencyId = this.defaultCurrencyId) {
4302
- const product = await this.createBasicProduct({ type: "digital", ...overrides }, taxId, currencyId);
4324
+ const product = await this.createBasicProduct({ type: "digital", maxPurchase: 1, ...overrides }, taxId, currencyId);
4303
4325
  const media = await this.createMediaTXT(content);
4304
4326
  await this.assignProductDownload(product.id, media.id);
4305
- return product;
4327
+ return { ...product, states: [...product.states ?? [], "is-download"] };
4306
4328
  }
4307
4329
  /**
4308
4330
  * Creates a basic product with a price range matrix.
@@ -6683,7 +6705,10 @@ class IdProvider {
6683
6705
  bytes[6] = 1 << 5;
6684
6706
  bytes[8] = 128;
6685
6707
  return {
6686
- id: `${this.workerIndex}`,
6708
+ // Derived from the hash like the uuid, so ids (and names/emails built from
6709
+ // them, e.g. the worker customer email) stay distinct between runs with
6710
+ // different seeds. A plain worker index collides across concurrent suites.
6711
+ id: `${buffer.readUIntBE(16, 6)}`,
6687
6712
  uuid: stringify(bytes).replaceAll("-", "")
6688
6713
  };
6689
6714
  }
@@ -6692,7 +6717,8 @@ class IdProvider {
6692
6717
  const test$8 = test$e.extend({
6693
6718
  IdProvider: [
6694
6719
  async ({}, use, workerInfo) => {
6695
- const seed = process.env.SHOPWARE_ACCESS_KEY_ID || process.env.SHOPWARE_ADMIN_PASSWORD || "test-suite";
6720
+ const baseSeed = process.env.SHOPWARE_ACCESS_KEY_ID || process.env.SHOPWARE_ADMIN_PASSWORD || "test-suite";
6721
+ const seed = process.env.ATS_ID_SEED ? `${process.env.ATS_ID_SEED}:${baseSeed}` : baseSeed;
6696
6722
  const idProvider = new IdProvider(workerInfo.parallelIndex, seed);
6697
6723
  await use(idProvider);
6698
6724
  },
@@ -8733,8 +8759,13 @@ class CustomerGroupListing {
8733
8759
  customerGroupActionButton
8734
8760
  };
8735
8761
  }
8736
- url() {
8737
- return "#/sw/settings/customer/group/index";
8762
+ url(searchTerms = [], page = 1) {
8763
+ let url = "#/sw/settings/customer/group/index";
8764
+ if (searchTerms.length > 0) {
8765
+ const term = searchTerms.join("+");
8766
+ url += `?limit=25&page=${page}&term=${encodeURIComponent(term)}`;
8767
+ }
8768
+ return url;
8738
8769
  }
8739
8770
  }
8740
8771
 
@@ -12385,7 +12416,14 @@ const AddProductToCart = test$e.extend({
12385
12416
  AddProductToCart: async ({ ShopCustomer, StorefrontProductDetail }, use) => {
12386
12417
  const task = (ProductData, quantity = "1") => {
12387
12418
  return async function AddProductToCart2() {
12388
- await ShopCustomer.fillsIn(StorefrontProductDetail.quantitySelect, quantity);
12419
+ const isDownloadProduct = ProductData.type === "digital" || (ProductData.states ?? []).includes("is-download");
12420
+ const showsQuantitySelect = !(isDownloadProduct && ProductData.maxPurchase === 1);
12421
+ if (showsQuantitySelect) {
12422
+ await ShopCustomer.expects(StorefrontProductDetail.quantitySelect).toBeVisible();
12423
+ await ShopCustomer.fillsIn(StorefrontProductDetail.quantitySelect, quantity);
12424
+ } else {
12425
+ await ShopCustomer.expects(StorefrontProductDetail.quantitySelect).toBeHidden();
12426
+ }
12389
12427
  await ShopCustomer.presses(StorefrontProductDetail.addToCartButton);
12390
12428
  await ShopCustomer.expects(StorefrontProductDetail.offCanvasCartTitle).toBeVisible();
12391
12429
  await ShopCustomer.expects(StorefrontProductDetail.offCanvasCart.getByText(ProductData.name)).toBeVisible();
@@ -12451,6 +12489,7 @@ const ConfirmTermsAndConditions = test$e.extend({
12451
12489
  ConfirmTermsAndConditions: async ({ ShopCustomer, StorefrontCheckoutConfirm }, use) => {
12452
12490
  const task = () => {
12453
12491
  return async function ConfirmTermsAndConditions2() {
12492
+ await ShopCustomer.expects(StorefrontCheckoutConfirm.termsAndConditionsCheckbox.or(StorefrontCheckoutConfirm.termsAutoConfirmedText).first()).toBeVisible();
12454
12493
  if (await StorefrontCheckoutConfirm.termsAndConditionsCheckbox.isVisible()) {
12455
12494
  await ShopCustomer.presses(StorefrontCheckoutConfirm.termsAndConditionsCheckbox);
12456
12495
  await ShopCustomer.expects(StorefrontCheckoutConfirm.termsAndConditionsCheckbox).toBeChecked();
@@ -13198,4 +13237,4 @@ const test = mergeTests(
13198
13237
  test$3
13199
13238
  );
13200
13239
 
13201
- export { Actor, AdminPageObjects, BUNDLED_RESOURCES, COUNTRY_ADDRESS_DATA, FeatureService, IdProvider, LanguageHelper, RuleType, StorefrontPageObjects, TestDataService, assertScreenshot, baseNamespaces, clearDelayedCache, compareFlowTemplateWithFlow, createNewAdminPageContext, createRandomImage, createSolidColorImage, encodeImage, extractIdFromUrl, formatPrice, getCountryAddressData, getCountryCodeFromLocale, getCountryId, getCurrency, getCurrencyCodeFromLocale, getCurrencySymbolFromLocale, getCurrentContext, getDefaultShippingMethodId, getFlow, getFlowId, getFlowTemplate, getLanguageCode, getLanguageData, getLocale, getMediaId, getOrderTransactionId, getPaymentMethodId, getPromotionWithDiscount, getSalutationId, getShippingMethodId, getSnippetSetId, getStateMachineId, getStateMachineStateId, getTaxId, getThemeId, hideElements, isPaaSInstance, isSaaSInstance, isThemeCompiled, loginToAdministration, mockApiCalls, replaceElements, replaceElementsIndividually, setCurrentContext, setOrderStatus, setViewport, test, translate, updateAdminUser, uploadRandomPngMedia };
13240
+ export { Actor, AdminPageObjects, BUNDLED_RESOURCES, COUNTRY_ADDRESS_DATA, FeatureService, IdProvider, LanguageHelper, RuleType, StorefrontPageObjects, TestDataService, assertScreenshot, baseNamespaces, clearDelayedCache, compareFlowTemplateWithFlow, createNewAdminPageContext, createRandomImage, createSolidColorImage, encodeImage, extractIdFromUrl, formatPrice, getCountryAddressData, getCountryCodeFromLocale, getCountryId, getCurrency, getCurrencyCodeFromLocale, getCurrencySymbolFromLocale, getCurrentContext, getDefaultShippingMethodId, getFlow, getFlowId, getFlowTemplate, getLanguageCode, getLanguageData, getLocale, getMediaId, getOrderTransactionId, getPaymentMethodId, getPromotionWithDiscount, getSalutationId, getShippingMethodId, getSnippetSetId, getStateMachineId, getStateMachineStateId, getTaxId, getThemeId, hideElements, hideSymfonyToolbarOnReload, isPaaSInstance, isSaaSInstance, isThemeCompiled, loginToAdministration, mockApiCalls, replaceElements, replaceElementsIndividually, setCurrentContext, setOrderStatus, setViewport, test, translate, updateAdminUser, uploadRandomPngMedia };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shopware-ag/acceptance-test-suite",
3
- "version": "12.14.0",
3
+ "version": "12.15.0",
4
4
  "description": "Shopware Acceptance Test Suite",
5
5
  "keywords": [
6
6
  "fixtures",
@@ -35,7 +35,7 @@
35
35
  "format": "oxfmt --write .",
36
36
  "typecheck": "tsgo --noEmit",
37
37
  "build": "unbuild",
38
- "prepare": "lefthook install",
38
+ "prepare": "(lefthook install || true) && npm run build",
39
39
  "prepublishOnly": "npm run build"
40
40
  },
41
41
  "dependencies": {