@shopware-ag/acceptance-test-suite 11.35.0 → 11.37.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.d.mts CHANGED
@@ -8,6 +8,14 @@ export { APIRequestContext, APIResponse, BrowserContext, Locator, Page, Request
8
8
  import { components } from '@shopware/api-client/admin-api-types';
9
9
  import { Image } from 'image-js';
10
10
 
11
+ declare global {
12
+ namespace PlaywrightTest {
13
+ interface Matchers<R> {
14
+ toHaveVisibleFocus(): Promise<R>;
15
+ }
16
+ }
17
+ }
18
+
11
19
  interface RequestOptions$1<PAYLOAD> {
12
20
  [key: string]: unknown;
13
21
  data?: PAYLOAD;
@@ -3982,6 +3990,10 @@ declare class Actor {
3982
3990
  baseURL: string | undefined;
3983
3991
  constructor(name: string, page: Page, baseURL?: string);
3984
3992
  expects: playwright_test.Expect<{}>;
3993
+ a11y_checks(locator: Locator): Promise<void>;
3994
+ fillsIn(locator: Locator, input: string): Promise<void>;
3995
+ presses(locator: Locator, key?: string): Promise<void>;
3996
+ selectsRadioButton(radioGroup: Locator, inputLabel: string): Promise<void>;
3985
3997
  attemptsTo(task: () => Promise<void>): Promise<void>;
3986
3998
  goesTo(url: string, forceReload?: boolean): Promise<void>;
3987
3999
  private camelCaseToLowerCase;
@@ -5420,12 +5432,16 @@ declare class ProductDetail implements PageObject {
5420
5432
  readonly offCanvasLineItemImages: Locator;
5421
5433
  readonly offCanvasSummaryTotalPrice: Locator;
5422
5434
  readonly offCanvas: Locator;
5435
+ readonly offCanvasLineItemLabel: (productName: string) => Locator;
5436
+ readonly offCanvasLineItemProductNumber: (productNumber: string) => Locator;
5437
+ readonly offCanvasLineItemDeliveryDate: Locator;
5423
5438
  readonly wishlistAddedButton: Locator;
5424
5439
  readonly wishlistNotAddedButton: Locator;
5425
5440
  readonly productDetailConfigurator: Locator;
5426
5441
  readonly productDetailConfiguratorGroupTitle: Locator;
5427
5442
  readonly productDetailConfiguratorOptionInputs: Locator;
5428
5443
  readonly productName: Locator;
5444
+ readonly productDescriptionTitle: Locator;
5429
5445
  readonly reviewsTab: Locator;
5430
5446
  readonly reviewTeaserButton: Locator;
5431
5447
  readonly reviewTeaserText: Locator;
@@ -5478,6 +5494,9 @@ declare class CheckoutCart implements PageObject {
5478
5494
  readonly cartLineItemImages: Locator;
5479
5495
  readonly unitPriceInfo: Locator;
5480
5496
  readonly cartQuantityNumber: Locator;
5497
+ readonly productNameLabel: (productName: string) => Locator;
5498
+ readonly productNumberLabel: (productNumber: string) => Locator;
5499
+ readonly productDeliveryDateLabel: Locator;
5481
5500
  readonly page: Page;
5482
5501
  constructor(page: Page);
5483
5502
  url(): string;
package/dist/index.d.ts CHANGED
@@ -8,6 +8,14 @@ export { APIRequestContext, APIResponse, BrowserContext, Locator, Page, Request
8
8
  import { components } from '@shopware/api-client/admin-api-types';
9
9
  import { Image } from 'image-js';
10
10
 
11
+ declare global {
12
+ namespace PlaywrightTest {
13
+ interface Matchers<R> {
14
+ toHaveVisibleFocus(): Promise<R>;
15
+ }
16
+ }
17
+ }
18
+
11
19
  interface RequestOptions$1<PAYLOAD> {
12
20
  [key: string]: unknown;
13
21
  data?: PAYLOAD;
@@ -3982,6 +3990,10 @@ declare class Actor {
3982
3990
  baseURL: string | undefined;
3983
3991
  constructor(name: string, page: Page, baseURL?: string);
3984
3992
  expects: playwright_test.Expect<{}>;
3993
+ a11y_checks(locator: Locator): Promise<void>;
3994
+ fillsIn(locator: Locator, input: string): Promise<void>;
3995
+ presses(locator: Locator, key?: string): Promise<void>;
3996
+ selectsRadioButton(radioGroup: Locator, inputLabel: string): Promise<void>;
3985
3997
  attemptsTo(task: () => Promise<void>): Promise<void>;
3986
3998
  goesTo(url: string, forceReload?: boolean): Promise<void>;
3987
3999
  private camelCaseToLowerCase;
@@ -5420,12 +5432,16 @@ declare class ProductDetail implements PageObject {
5420
5432
  readonly offCanvasLineItemImages: Locator;
5421
5433
  readonly offCanvasSummaryTotalPrice: Locator;
5422
5434
  readonly offCanvas: Locator;
5435
+ readonly offCanvasLineItemLabel: (productName: string) => Locator;
5436
+ readonly offCanvasLineItemProductNumber: (productNumber: string) => Locator;
5437
+ readonly offCanvasLineItemDeliveryDate: Locator;
5423
5438
  readonly wishlistAddedButton: Locator;
5424
5439
  readonly wishlistNotAddedButton: Locator;
5425
5440
  readonly productDetailConfigurator: Locator;
5426
5441
  readonly productDetailConfiguratorGroupTitle: Locator;
5427
5442
  readonly productDetailConfiguratorOptionInputs: Locator;
5428
5443
  readonly productName: Locator;
5444
+ readonly productDescriptionTitle: Locator;
5429
5445
  readonly reviewsTab: Locator;
5430
5446
  readonly reviewTeaserButton: Locator;
5431
5447
  readonly reviewTeaserText: Locator;
@@ -5478,6 +5494,9 @@ declare class CheckoutCart implements PageObject {
5478
5494
  readonly cartLineItemImages: Locator;
5479
5495
  readonly unitPriceInfo: Locator;
5480
5496
  readonly cartQuantityNumber: Locator;
5497
+ readonly productNameLabel: (productName: string) => Locator;
5498
+ readonly productNumberLabel: (productNumber: string) => Locator;
5499
+ readonly productDeliveryDateLabel: Locator;
5481
5500
  readonly page: Page;
5482
5501
  constructor(page: Page);
5483
5502
  url(): string;
package/dist/index.mjs CHANGED
@@ -3235,6 +3235,59 @@ class Actor {
3235
3235
  this.baseURL = baseURL;
3236
3236
  }
3237
3237
  expects = expect;
3238
+ async a11y_checks(locator) {
3239
+ await locator.focus();
3240
+ await expect(locator).toBeFocused();
3241
+ await expect(locator).toHaveVisibleFocus();
3242
+ }
3243
+ async fillsIn(locator, input) {
3244
+ const stepTitle = `${this.name} fills ${locator} with text "${input}"`;
3245
+ await test$e.step(stepTitle, async () => {
3246
+ await this.a11y_checks(locator);
3247
+ await locator.fill(input);
3248
+ });
3249
+ }
3250
+ async presses(locator, key) {
3251
+ let defaultKey = "Space";
3252
+ const tagName = await locator.evaluate((el) => el.tagName);
3253
+ if (tagName === "BUTTON" || tagName === "A") {
3254
+ await this.page.keyboard.press("Shift");
3255
+ defaultKey = "Enter";
3256
+ }
3257
+ const inputKey = key ?? defaultKey;
3258
+ const stepTitle = `${this.name} presses ${inputKey} on ${locator}`;
3259
+ await test$e.step(stepTitle, async () => {
3260
+ await this.a11y_checks(locator);
3261
+ await locator.press(inputKey);
3262
+ });
3263
+ }
3264
+ async selectsRadioButton(radioGroup, inputLabel) {
3265
+ const stepTitle = `${this.name} selects radio button ${inputLabel}`;
3266
+ await test$e.step(stepTitle, async () => {
3267
+ const desiredOption = radioGroup.getByRole("radio", { name: inputLabel });
3268
+ if (!await desiredOption.isChecked()) {
3269
+ const options = [];
3270
+ for (const labelEl of await radioGroup.locator("label").all()) {
3271
+ const label = await labelEl.innerText();
3272
+ const radioButton = radioGroup.getByRole("radio", { name: label });
3273
+ const isChecked = await radioButton.isChecked();
3274
+ options.push({ label, locator: radioButton, isChecked });
3275
+ }
3276
+ const defaultOptionIndex = options.findIndex((opt) => opt.isChecked);
3277
+ const desiredOptionIndex = options.findIndex((opt) => opt.label === inputLabel);
3278
+ if (defaultOptionIndex === -1) {
3279
+ throw new Error(`No option is selected by default.`);
3280
+ }
3281
+ const step = defaultOptionIndex < desiredOptionIndex ? 1 : -1;
3282
+ const inputKey = step === 1 ? "ArrowDown" : "ArrowUp";
3283
+ for (let i = defaultOptionIndex; i !== desiredOptionIndex; i += step) {
3284
+ await this.presses(options[i].locator, inputKey);
3285
+ await this.page.waitForLoadState("domcontentloaded");
3286
+ }
3287
+ }
3288
+ await this.a11y_checks(desiredOption);
3289
+ });
3290
+ }
3238
3291
  async attemptsTo(task) {
3239
3292
  const stepTitle = `${this.name} attempts to ${this.camelCaseToLowerCase(task.name)}`;
3240
3293
  await test$e.step(stepTitle, async () => await task());
@@ -6342,12 +6395,16 @@ let ProductDetail$1 = class ProductDetail {
6342
6395
  offCanvasLineItemImages;
6343
6396
  offCanvasSummaryTotalPrice;
6344
6397
  offCanvas;
6398
+ offCanvasLineItemLabel;
6399
+ offCanvasLineItemProductNumber;
6400
+ offCanvasLineItemDeliveryDate;
6345
6401
  wishlistAddedButton;
6346
6402
  wishlistNotAddedButton;
6347
6403
  productDetailConfigurator;
6348
6404
  productDetailConfiguratorGroupTitle;
6349
6405
  productDetailConfiguratorOptionInputs;
6350
6406
  productName;
6407
+ productDescriptionTitle;
6351
6408
  //Reviews Tab
6352
6409
  reviewsTab;
6353
6410
  reviewTeaserButton;
@@ -6389,12 +6446,16 @@ let ProductDetail$1 = class ProductDetail {
6389
6446
  this.offCanvasCartGoToCheckoutButton = page.getByRole("link", { name: translate("storefront:checkout:cart.goToCheckout") });
6390
6447
  this.offCanvasLineItemImages = page.locator(".line-item-img-link");
6391
6448
  this.offCanvasSummaryTotalPrice = page.locator(".offcanvas-summary").locator('dt:has-text("Subtotal") + dd');
6449
+ this.offCanvasLineItemLabel = (productName) => page.getByRole("link", { name: productName });
6450
+ this.offCanvasLineItemProductNumber = (productNumber) => page.getByText(productNumber);
6451
+ this.offCanvasLineItemDeliveryDate = page.locator(".line-item-delivery-date");
6392
6452
  this.wishlistAddedButton = page.locator(".product-wishlist-added");
6393
6453
  this.wishlistNotAddedButton = page.locator(".product-wishlist-not-added");
6394
6454
  this.productDetailConfigurator = page.locator(".product-detail-configurator");
6395
6455
  this.productDetailConfiguratorGroupTitle = page.locator(".product-detail-configurator-group-title");
6396
6456
  this.productDetailConfiguratorOptionInputs = page.locator(".product-detail-configurator-option-input");
6397
6457
  this.productName = page.locator(".product-detail-name");
6458
+ this.productDescriptionTitle = page.locator(".product-detail-description-title");
6398
6459
  this.productReviewRating = page.locator(".product-detail-reviews .product-review-rating");
6399
6460
  this.productReviewsLink = page.locator(".product-detail-reviews .product-detail-reviews-link");
6400
6461
  this.reviewsTab = this.page.getByRole("tab", { name: translate("storefront:product:review.tabTitle") });
@@ -6465,6 +6526,9 @@ class CheckoutCart {
6465
6526
  cartLineItemImages;
6466
6527
  unitPriceInfo;
6467
6528
  cartQuantityNumber;
6529
+ productNameLabel;
6530
+ productNumberLabel;
6531
+ productDeliveryDateLabel;
6468
6532
  page;
6469
6533
  constructor(page) {
6470
6534
  this.page = page;
@@ -6477,6 +6541,9 @@ class CheckoutCart {
6477
6541
  this.cartLineItemImages = page.locator(".line-item-img-link");
6478
6542
  this.unitPriceInfo = page.locator(".line-item-unit-price-value");
6479
6543
  this.cartQuantityNumber = page.locator('input[name="quantity"]');
6544
+ this.productNameLabel = (productName) => page.getByRole("link", { name: productName });
6545
+ this.productNumberLabel = (productNumber) => page.getByText(productNumber);
6546
+ this.productDeliveryDateLabel = page.locator(".line-item-delivery-date");
6480
6547
  }
6481
6548
  url() {
6482
6549
  return "checkout/cart";
@@ -11705,6 +11772,40 @@ const test$1 = test$e.extend({
11705
11772
  ]
11706
11773
  });
11707
11774
 
11775
+ expect.extend({
11776
+ async toHaveVisibleFocus(locator) {
11777
+ try {
11778
+ const boxShadowStyle = await locator.evaluate((element) => {
11779
+ const computedStyle = window.getComputedStyle(element);
11780
+ return computedStyle.boxShadow !== "none";
11781
+ });
11782
+ const borderStyle = await locator.evaluate((element) => {
11783
+ const computedStyle = window.getComputedStyle(element);
11784
+ return computedStyle.borderStyle !== "none" && computedStyle.borderWidth !== "0px" && computedStyle.borderColor !== "transparent" && !computedStyle.borderColor.includes("rgba(0, 0, 0, 0)");
11785
+ });
11786
+ const outlineStyle = await locator.evaluate((element) => {
11787
+ const computedStyle = window.getComputedStyle(element);
11788
+ return computedStyle.outline !== "none" && computedStyle.outlineWidth !== "0px" && computedStyle.borderColor !== "transparent" && !computedStyle.borderColor.includes("rgba(0, 0, 0, 0)");
11789
+ });
11790
+ if (!boxShadowStyle && !borderStyle && !outlineStyle) {
11791
+ return {
11792
+ message: () => `expected ${locator} to have visible focus, but no outline, border or box-shadow was detected`,
11793
+ pass: false
11794
+ };
11795
+ }
11796
+ return {
11797
+ message: () => `${locator} has visible focus`,
11798
+ pass: true
11799
+ };
11800
+ } catch (error) {
11801
+ return {
11802
+ message: () => `expected ${locator} to have visible focus, but it failed with error: ${error.message}`,
11803
+ pass: false
11804
+ };
11805
+ }
11806
+ }
11807
+ });
11808
+
11708
11809
  async function applyToElements(page, selectors, stringHandler, locatorHandler) {
11709
11810
  if (!selectors.length) return;
11710
11811
  const stringSelectors = selectors.filter((s) => typeof s === "string");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shopware-ag/acceptance-test-suite",
3
- "version": "11.35.0",
3
+ "version": "11.37.0",
4
4
  "description": "Shopware Acceptance Test Suite",
5
5
  "author": "shopware AG",
6
6
  "license": "MIT",