flexpect
Version:
Automated layout validation tool using Playwright. Ensures responsive design accuracy across multiple viewports by inspecting element positions and visual alignment.
1,035 lines (1,014 loc) • 44.1 kB
text/typescript
import { Locator, MatcherReturnType } from '@playwright/test';
/**
* Units available for expressing tolerance values.
*/
declare enum ToleranceUnit {
/**
* Tolerance is expressed as a percentage of a reference dimension
* (e.g., width, height, or distance).
*/
Percent = "percent",
/**
* Tolerance is expressed as an absolute value in pixels.
*/
Pixels = "pixels"
}
/**
* Describes a tolerance value that defines how much deviation
* from the expected result is acceptable for a matcher.
*
* This type can be reused across different matchers (e.g. alignment, spacing,
* size comparison) to allow flexible tolerance configuration.
*
* By default, the tolerance is expressed as a percentage, but a pixel-based
* value can also be used for more precise, fixed-size comparisons.
*
* @example
* // Allow up to 5% difference
* { tolerance: 5, toleranceUnit: ToleranceUnit.Percent }
*
* @example
* // Allow up to 3 pixels difference
* { tolerance: 3, toleranceUnit: ToleranceUnit.Pixels }
*/
interface Tolerance {
/**
* Allowed tolerance value.
*
* Must be greater than or equal to 0. Omitting this option defaults to `0`,
* which will typically cause the assertion to fail or throw an error,
* since zero tolerance is allowed.
*/
tolerance?: number;
/**
* Defines the unit in which the tolerance is expressed.
*
* Defaults to `percent` if not specified.
*
* @default ToleranceUnit.Percent
*/
toleranceUnit?: ToleranceUnit;
}
/**
* Options for the {@link toBeAbove} matcher.
*/
interface ToBeAboveOptions extends Tolerance {
}
/**
* Asserts that an element is positioned above another element.
*
* The element passes if its **bottom edge** is at or above the **top edge** of the reference,
* within the specified tolerance.
*
* - **Strictly above**:
* ```text
* ┌───────────────┐
* │ element │
* └───────────────┘
* |
* ↓
* ┌───────────────┐
* │ reference │
* └───────────────┘
* ```
* - **Touching**:
* ```text
* ┌───────────────┐
* │ element │
* └───────────────┘
* ┌───────────────┐
* │ reference │
* └───────────────┘
* ```
*
* @param element - The element as a {@link Locator} that should be above.
* @param reference - The element as a {@link Locator} that should be below.
* @param options - Optional alignment options.
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* // Element is strictly above reference (no overlap, no tolerance)
* await expect(header).toBeAbove(content);
*
* @example
* // Element can overlap reference by up to 10px
* await expect(title).toBeAbove(subtitle, { tolerance: 10, toleranceUnit: ToleranceUnit.Pixels });
*
* @example
* // Element can overlap reference by up to 5% of reference height
* await expect(icon).toBeAbove(text, {
* tolerance: 5,
* toleranceUnit: ToleranceUnit.Percent
* });
*/
declare function toBeAbove(element: Locator, reference: Locator, options?: ToBeAboveOptions): Promise<MatcherReturnType>;
/**
* Defines possible alignment positions along an axis.
*
* @remarks
* This enum is typically used in layout systems or UI components
* to specify how content should be aligned within a container.
*/
declare enum Alignment {
/**
* Aligns the start edge of the target with the start edge of the container.
*
* - Horizontal: left edge
* - Vertical: top edge
*/
Start = "start",
/**
* Aligns the center of the target with the center of the container.
*/
Center = "center",
/**
* Aligns the end edge of the target with the end edge of the container.
*
* - Horizontal: right edge
* - Vertical: bottom edge
*/
End = "end"
}
/**
* Defines the possible axes for alignment operations.
*
* @remarks
* This enum is used to specify whether an alignment should be performed
* horizontally (along the X-axis) or vertically (along the Y-axis).
*/
declare enum Axis {
/**
* Alignment along the horizontal axis (left/right).
*/
Horizontal = "horizontal",
/**
* Alignment along the vertical axis (top/bottom).
*/
Vertical = "vertical"
}
/**
* Options for the {@link toBeAlignedWith} matcher.
*/
interface ToBeAlignedWithOptions extends Tolerance {
}
/**
* Asserts that the target element is aligned with the specified container element
* based on the provided axis and alignment mode, considering an optional tolerance percentage.
*
* - **Horizontal Start Alignment**:
* ```text
* ┌───────────────────────────────┐
* │┌─────────┐ │
* ││ Element │ │
* │└─────────┘ │
* └───────────────────────────────┘
* ```
* - **Horizontal Center Alignment**:
* ```text
* ┌───────────────────────────────┐
* │ ┌─────────┐ │
* │ │ Element │ │
* │ └─────────┘ │
* └───────────────────────────────┘
* ```
* - **Horizontal End Alignment**:
* ```text
* ┌───────────────────────────────┐
* │ ┌─────────┐│
* │ │ Element ││
* │ └─────────┘│
* └───────────────────────────────┘
* ```
* - **Vertical Start Alignment**:
* ```text
* ┌───────────────────────────────┐
* │┌─────────────────────────────┐│
* ││ Element ││
* │└─────────────────────────────┘│
* │ │
* │ │
* └───────────────────────────────┘
* ```
* - **Vertical Center Alignment**:
* ```text
* ┌───────────────────────────────┐
* │┌─────────────────────────────┐│
* ││ Element ││
* │└─────────────────────────────┘│
* │ │
* └───────────────────────────────┘
* ```
* - **Vertical End Alignment**:
* ```text
* ┌───────────────────────────────┐
* │ │
* │ │
* │┌─────────────────────────────┐│
* ││ Element ││
* │└─────────────────────────────┘│
* └───────────────────────────────┘
* ```
*
* @param element - The element as a {@link Locator} to check for alignment.
* @param container - The container element as a {@link Locator} relative to which alignment is checked.
* @param axis - The axis along which to check alignment (horizontal or vertical).
* @param mode - The alignment mode to check (start, center, or end).
* @param options - Optional alignment options.
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* // Checks that the button is horizontally centered with its parent within 2% tolerance
* await expect(buttonLocator).toBeAlignedWith(parentLocator, Axis.Horizontal, Alignment.Center, {
* tolerance: 2,
* toleranceUnit: ToleranceUnit.Percent
* });
*
* @example
* // Checks that the button is aligned to the start vertically with no tolerance
* await expect(buttonLocator).toBeAlignedWith(parentLocator, Axis.Vertical, Alignment.Start);
*/
declare function toBeAlignedWith(element: Locator, container: Locator, axis: Axis, mode: Alignment, options?: ToBeAlignedWithOptions): Promise<MatcherReturnType>;
/**
* Options for the {@link toHaveAspectRatio} matcher.
*/
interface ToHaveAspectRatioOptions extends Tolerance {
}
/**
* Asserts that the target element has the specified aspect ratio (width divided by height),
* within an optional tolerance percentage.
*
* This assertion calculates the aspect ratio of the element by dividing its width by its height,
* then compares it to the expected ratio. If the actual ratio falls outside the allowed tolerance,
* a detailed message is returned to help diagnose the discrepancy.
*
* The aspect ratio is defined as:
* ```text
* aspectRatio = width / height
* ```
*
* @param element - The element as a {@link Locator} to check for aspect ratio.
* @param expectedRatio - The expected aspect ratio (width / height) to check against.
* @param options - Optional comparison options.
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* // Checks that the element has an aspect ratio of 16:9 exactly (no tolerance)
* await expect(elementLocator).toHaveAspectRatio(16 / 9);
*
* @example
* // Checks that the element has an aspect ratio close to 4:3 within 3% tolerance
* await expect(elementLocator).toHaveAspectRatio(4 / 3, {
* tolerance: 3,
* toleranceUnit: ToleranceUnit.Percent
* });
*/
declare function toHaveAspectRatio(element: Locator, expectedRatio: number, options?: ToHaveAspectRatioOptions): Promise<MatcherReturnType>;
/**
* Defines the sides of an element that can be used when measuring
* distances relative to another element.
*
* @remarks
* This enum is typically used in layout or testing utilities to specify
* on which side of a reference element a distance should be evaluated.
*/
declare enum DistanceSide {
/**
* The top edge of the element.
*/
Top = "top",
/**
* The right edge of the element.
*/
Right = "right",
/**
* The bottom edge of the element.
*/
Bottom = "bottom",
/**
* The left edge of the element.
*/
Left = "left"
}
/**
* Options for the {@link toHaveDistanceFrom} matcher.
*/
interface ToHaveDistanceFromOptions extends Tolerance {
}
/**
* Asserts that the target element has a specific distance from another element on a given side.
*
* - **Top side** (side = `DistanceSide.Top`):
* ```text
* ┌───────────────────────┐
* | Reference Element |
* └───────────────────────┘
* ↑
* | Expected distance = 100px
* ┌───────────────────────┐
* | Target Element |
* └───────────────────────┘
* ```
* - **Bottom side** (side = `DistanceSide.Bottom`):
* ```text
* ┌───────────────────────┐
* | Target Element |
* └───────────────────────┘
* | Expected distance = 100px
* ↓
* ┌───────────────────────┐
* | Reference Element |
* └───────────────────────┘
* ```
* - **Left side** (side = `DistanceSide.Left`):
* ```text
* ┌───────────────────────┐ ┌───────────────────────┐
* | Reference Element | <--100px--> | Target Element |
* └───────────────────────┘ └───────────────────────┘
* ```
* - **Right side** (side = `DistanceSide.Right`):
* ```text
* ┌───────────────────────┐ ┌───────────────────────┐
* | Target Element | <--100px--> | Reference Element |
* └───────────────────────┘ └───────────────────────┘
* ```
*
* @param element - The element as a {@link Locator} to check for distance.
* @param reference - The reference element to compare against.
* @param side - Which side of the reference to measure distance from.
* @param expectedDistanceInPixels - Expected distance in pixels between the elements.
* @param options - Optional distance options.
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* // Check that element is 100px below reference, allowing 10px of tolerance
* await expect(element).toHaveDistanceFrom(reference, DistanceSide.Top, 100, {
* tolerance: 10,
* toleranceUnit: ToleranceUnit.Pixels
* });
*
* @example
* // Check that element is 200px to the right of reference, with a tolerance of 15px
* await expect(element).toHaveDistanceFrom(reference, DistanceSide.Right, 200, {
* tolerance: 15,
* toleranceUnit: ToleranceUnit.Pixels
* });
*/
declare function toHaveDistanceFrom(element: Locator, reference: Locator, side: DistanceSide, expectedDistanceInPixels: number, options?: ToHaveDistanceFromOptions): Promise<MatcherReturnType>;
/**
* Options for the {@link toBeBelow} matcher.
*/
interface toBeBelowOptions extends Tolerance {
}
/**
* Asserts that an element is positioned below another element.
*
* The element passes if its **top edge** is at or below the **bottom edge** of the reference,
* within the specified tolerance.
*
* - **Strictly below**:
* ```text
* ┌───────────────┐
* │ reference │
* └───────────────┘
* |
* ↓
* ┌───────────────┐
* │ element │
* └───────────────┘
* ```
* - **Touching**:
* ```text
* ┌───────────────┐
* │ reference │
* └───────────────┘
* ┌───────────────┐
* │ element │
* └───────────────┘
* ```
*
* @param element - The element as a {@link Locator} that should be below.
* @param reference - The element as a {@link Locator} that should be above.
* @param options - Optional alignment options.
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* // Element is strictly below reference (no overlap, no tolerance)
* await expect(content).toBeBelow(header);
*
* @example
* // Element can overlap reference by up to 10px
* await expect(subtitle).toBeBelow(title, { tolerance: 10, toleranceUnit: ToleranceUnit.Pixels });
*
* @example
* // Element can overlap reference by up to 5% of reference height
* await expect(text).toBeBelow(icon, {
* tolerance: 5,
* toleranceUnit: ToleranceUnit.Percent
* });
*/
declare function toBeBelow(element: Locator, reference: Locator, options?: toBeBelowOptions): Promise<MatcherReturnType>;
/**
* Options for the {@link toBeFullyCentered} matcher.
*/
interface ToBeFullyCenteredOptions extends Tolerance {
}
/**
* Asserts that the target element is fully centered both horizontally and vertically
* within the specified container element.
*
* ```text
* ┌─────────────────┐
* │ │
* │ ┌─────────┐ │
* │ │ element │ │
* │ └─────────┘ │
* │ │
* └─────────────────┘
* ```
*
* @param element - The element as a {@link Locator} to check for centering.
* @param container - The container element as a {@link Locator} relative to which centering is checked.
* @param options - Optional centering options.
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* // Check that a modal is perfectly centered within the viewport, allowing a 2% margin
* const parentLocator = page.locator('#parent');
* await expect(modalLocator).toBeFullyCentered(parentLocator, {
* tolerance: 2,
* toleranceUnit: ToleranceUnit.Percent
* });
*/
declare function toBeFullyCentered(element: Locator, container: Locator, options?: ToBeFullyCenteredOptions): Promise<MatcherReturnType>;
/**
* Defines possible horizontal alignment positions.
*
* @remarks
* This enum is used to specify how an element should be aligned horizontally
* relative to another element or container.
*/
declare enum HorizontalAlignment {
/**
* The horizontal centers of the target and container are equal within the tolerance.
*/
Center = "center",
/**
* The left edges of the target and container are equal within the tolerance.
*/
Left = "left",
/**
* The right edges of the target and container are equal within the tolerance.
*/
Right = "right"
}
/**
* Options for the {@link toBeHorizontallyAlignedWith} matcher.
*/
interface ToBeHorizontallyAlignedWithOptions extends Tolerance {
}
/**
* Asserts that the target element is horizontally aligned with the specified container
* according to the given alignment type.
*
* - **Left alignment** (alignment = `HorizontalAlignment.Left`):
* ```text
* ┌───────────────────────────────┐
* │┌─────────┐ │
* ││ Element │ │
* │└─────────┘ │
* └───────────────────────────────┘
* ```
*
* - **Center alignment** (alignment = `HorizontalAlignment.Center`):
* ```text
* ┌───────────────────────────────┐
* │ ┌─────────┐ │
* │ │ Element │ │
* │ └─────────┘ │
* └───────────────────────────────┘
* ```
*
* - **Right alignment** (alignment = `HorizontalAlignment.Right`):
* ```text
* ┌───────────────────────────────┐
* │ ┌─────────┐│
* │ │ Element ││
* │ └─────────┘│
* └───────────────────────────────┘
* ```
*
* @param element - The element as a {@link Locator} to check for horizontal alignment.
* @param container - The container element as a {@link Locator} relative to which horizontal alignment is checked.
* @param alignment - The type of horizontal alignment to check (left, center, or right).
* @param options - Optional alignment options.
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* // Assert that a button is left-aligned with its card container, allowing 3% horizontal tolerance
* await expect(buttonLocator).toBeHorizontallyAlignedWith(parentLocator, HorizontalAlignment.Left, {
* tolerance: 3, toleranceUnit: ToleranceUnit.Percent
* });
*
* @example
* // Assert that a button is horizontally centered with its card container (default options)
* await expect(buttonLocator).toBeHorizontallyAlignedWith(parentLocator, HorizontalAlignment.Center);
*/
declare function toBeHorizontallyAlignedWith(element: Locator, container: Locator, alignment: HorizontalAlignment, options?: ToBeHorizontallyAlignedWithOptions): Promise<MatcherReturnType>;
/**
* Options for the {@link toBeInside} matcher.
*/
interface ToBeInsideOptions extends Tolerance {
}
/**
* Asserts that the target element is fully contained within the specified container element,
* allowing for an optional margin of tolerance.
*
* The check ensures that all sides of the target element (top, bottom, left, right)
* are strictly within the bounds of the container, with an optional offset based on a
* percentage of the container's dimensions.
*
* @param element - The element as a {@link Locator} to check for containment.
* @param container - The container element as a {@link Locator} within which the element is expected to be fully contained.
* @param options - Optional containment options.
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* // Verify that the modal content is fully inside its container with a 2% tolerance
* await expect(modalContentLocator).toBeInside(parentLocator, {
* tolerance: 2,
* toleranceUnit: ToleranceUnit.Percent
* });
*
* @example
* // Verify that the modal content is strictly inside its container without any tolerance
* await expect(modalContentLocator).toBeInside(parentLocator);
*/
declare function toBeInside(element: Locator, container: Locator, options?: ToBeInsideOptions): Promise<MatcherReturnType>;
/**
* Options for the {@link toBeLeftOf} matcher.
*/
interface ToBeLeftOfOptions extends Tolerance {
}
/**
* Asserts that an element is positioned to the left of another element.
*
* The element passes if its **right edge** is at or to the left of the **left edge** of the reference,
* within the specified tolerance.
*
* - **Strictly to the left**:
* ```text
* ┌───────────────┐ ┌───────────────┐
* │ element │ │ reference │
* └───────────────┘ └───────────────┘
* | |
* ←─────────────────────────→
* ```
* - **Touching**:
* ```text
* ┌───────────────┐┌───────────────┐
* │ element ││ reference │
* └───────────────┘└───────────────┘
* ```
*
* @param element - The element as a {@link Locator} that should be to the left.
* @param reference - The element as a {@link Locator} that should be to the right.
* @param options - Optional alignment options.
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* // Element is strictly to the left of reference (no overlap, no tolerance)
* await expect(sidebar).toBeLeftOf(content);
*
* @example
* // Element can overlap reference by up to 10px
* await expect(icon).toBeLeftOf(text, { tolerance: 10, toleranceUnit: ToleranceUnit.Pixels });
*
* @example
* // Element can overlap reference by up to 5% of reference width
* await expect(label).toBeLeftOf(input, {
* tolerance: 5,
* toleranceUnit: ToleranceUnit.Percent
* });
*/
declare function toBeLeftOf(element: Locator, reference: Locator, options?: ToBeLeftOfOptions): Promise<MatcherReturnType>;
/**
* Options for the {@link toBeRightOf} matcher.
*/
interface ToBeRightOfOptions extends Tolerance {
}
/**
* Asserts that an element is positioned to the right of another element.
*
* The element passes if its **left edge** is at or to the right of the **right edge** of the reference,
* within the specified tolerance.
*
* - **Strictly to the right**:
* ```text
* ┌───────────────┐ ┌───────────────┐
* │ reference │ │ element │
* └───────────────┘ └───────────────┘
* | |
* ←─────────────────────────→
* ```
* - **Touching**:
* ```text
* ┌───────────────┐┌───────────────┐
* │ reference ││ element │
* └───────────────┘└───────────────┘
* ```
*
* @param element - The element as a {@link Locator} that should be to the right.
* @param reference - The element as a {@link Locator} that should be to the left.
* @param options - Optional alignment options.
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* // Element is strictly to the right of reference (no overlap, no tolerance)
* await expect(content).toBeRightOf(sidebar);
*
* @example
* // Element can overlap reference by up to 10px
* await expect(text).toBeRightOf(icon, { tolerance: 10, toleranceUnit: ToleranceUnit.Pixels });
*
* @example
* // Element can overlap reference by up to 5% of reference width
* await expect(input).toBeRightOf(label, {
* tolerance: 5,
* toleranceUnit: ToleranceUnit.Percent
* });
*/
declare function toBeRightOf(element: Locator, reference: Locator, options?: ToBeRightOfOptions): Promise<MatcherReturnType>;
/**
* Options for the {@link toHaveSameSizeAs} matcher.
*/
interface ToHaveSameSizeAsOptions extends Tolerance {
}
/**
* Asserts that the target element has the same width and height as the specified container element.
*
* @param element - The element as a {@link Locator} to check for size.
* @param container - A `Locator` representing the element to compare size with.
* @param options - Optional comparison options.
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* // Checks that the element matches the container's size, with up to 5% tolerance in width and height
* await expect(elementLocator).toHaveSameSizeAs(containerLocator, {
* tolerance: 5,
* toleranceUnit: ToleranceUnit.Percent
* });
*
* @example
* // Checks that the element has exactly the same width and height as its container using default alignment options
* await expect(elementLocator).toHaveSameSizeAs(containerLocator);
*/
declare function toHaveSameSizeAs(element: Locator, container: Locator, options?: ToHaveSameSizeAsOptions): Promise<MatcherReturnType>;
/**
* Axis along which spacing is measured.
*/
declare enum SpacingAxis {
/**
* Measures horizontal spacing (left → right).
*
* The gap is calculated between:
* - The **right edge** of the left element
* - The **left edge** of the right element
*/
Horizontal = "horizontal",
/**
* Measures vertical spacing (top → bottom).
*
* The gap is calculated between:
* - The **bottom edge** of the upper element
* - The **top edge** of the lower element
*/
Vertical = "vertical"
}
/**
* Options for the {@link toHaveSpacingBetween} matcher.
*/
interface ToHaveSpacingBetweenOptions extends Tolerance {
}
/**
* Asserts that the spacing between two elements matches the expected value along the specified axis.
*
* The spacing is calculated as the gap **between** the edges of the two elements:
* - **Horizontal**: distance between the right edge of the left element and the left edge of the right element.
* - **Vertical**: distance between the bottom edge of the top element and the top edge of the bottom element.
*
* Elements are automatically ordered by position (left → right or top → bottom), regardless of parameter order.
*
* - **Horizontal spacing** (axis = `SpacingAxis.Horizontal`):
* ```text
* ┌───────────┐ ┌───────────┐
* │ Element A │◄── 16px gap ──►│ Element B │
* └───────────┘ └───────────┘
* ```
*
* - **Vertical spacing** (axis = `SpacingAxis.Vertical`):
* ```text
* ┌───────────────┐
* │ Element A │
* └───────────────┘
* ▲
* │ 16px gap
* ▼
* ┌───────────────┐
* │ Element B │
* └───────────────┘
* ```
*
* - **No spacing** (elements touching):
* ```text
* ┌───────────┐┌───────────┐
* │ Element A ││ Element B │
* └───────────┘└───────────┘
* ◄─ 0px gap ─►
* ```
*
* - **Overlapping elements** (negative spacing):
* ```text
* ┌───────────┼───────────┐
* │ Element A │ Element B │
* └───────────┼───────────┘
* │
* ◄─overlap─►
* ```
*
* @param element - The first element as a {@link Locator}.
* @param reference - The reference element as a {@link Locator} relative to which spacing is measured.
* @param expectedSpacing - Expected gap between the two elements, in pixels (≥ 0).
* @param axis - The axis along which to measure spacing.
* @param options - Optional spacing options.
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* // Horizontal spacing: exactly 16px
* await expect(button1).toHaveSpacingBetween(button2, 16, SpacingAxis.Horizontal);
*
* @example
* // Vertical spacing: 24px ± 5%
* await expect(header).toHaveSpacingBetween(content, 24, SpacingAxis.Vertical, {
* tolerance: 5,
* toleranceUnit: ToleranceUnit.Percent
* });
*/
declare function toHaveSpacingBetween(element: Locator, reference: Locator, expectedSpacing: number, axis: SpacingAxis, options?: ToHaveSpacingBetweenOptions): Promise<MatcherReturnType>;
/**
* Defines possible vertical alignment positions.
*
* @remarks
* This enum is used to specify how an element should be aligned vertically
* relative to another element or container.
*/
declare enum VerticalAlignment {
/**
* The bottom edges of the target and container are equal within the tolerance.
*/
Bottom = "bottom",
/**
* The vertical centers of the target and container are equal within the tolerance.
*/
Center = "center",
/**
* The top edges of the target and container are equal within the tolerance.
*/
Top = "top"
}
/**
* Options for the {@link toBeVerticallyAlignedWith} matcher.
*/
interface ToBeVerticallyAlignedWithOptions extends Tolerance {
}
/**
* Asserts that the target element is vertically aligned with the specified container
* according to the given alignment type.
*
* - **Top alignment** (alignment = `VerticalAlignment.Top`):
* ```text
* ┌───────────────────────────────┐
* │┌─────────┐ │
* ││ Element │ │
* │└─────────┘ │
* │ │
* │ │
* │ │
* └───────────────────────────────┘
* ```
* - **Center alignment** (alignment = `VerticalAlignment.Center`):
* ```text
* ┌───────────────────────────────┐
* │ │
* │ │
* │┌─────────┐ │
* ││ Element │ │
* │└─────────┘ │
* │ │
* │ │
* └───────────────────────────────┘
* ```
*
* - **Bottom alignment** (alignment = `VerticalAlignment.Bottom`):
* ```text
* ┌───────────────────────────────┐
* │ │
* │ │
* │ │
* │┌─────────┐ │
* ││ Element │ │
* │└─────────┘ │
* └───────────────────────────────┘
* ```
*
* @param element - The element as a {@link Locator} to check for vertical alignment.
* @param container - The container element as a {@link Locator} relative to which vertical alignment is checked.
* @param alignment - The type of vertical alignment to check (top, center, or bottom).
* @param options - Optional size comparison options.
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* // Check that a header is bottom-aligned with its section container, allowing a 2% vertical tolerance
* await expect(headerLocator).toBeVerticallyAlignedWith(parentLocator, VerticalAlignment.Bottom, {
* tolerance: 2,
* toleranceUnit: ToleranceUnit.Percent,
* });
*
* @example
* // Check that a header is vertically centered within its section container (default options)
* await expect(headerLocator).toBeVerticallyAlignedWith(parentLocator, VerticalAlignment.Center);
*/
declare function toBeVerticallyAlignedWith(element: Locator, container: Locator, alignment: VerticalAlignment, options?: ToBeVerticallyAlignedWithOptions): Promise<MatcherReturnType>;
/**
* Options for the {@link toBeWithinViewport} matcher.
*/
interface ToBeWithinViewportOptions {
/**
* Margin in pixels to apply around the viewport edges.
*
* This creates a "safe zone" inside the viewport. The element must be fully contained
* within this inner rectangle to pass the assertion.
*
* Useful for:
* - Avoiding sticky headers/footers
* - Accounting for floating action buttons
* - Ensuring visibility in scrollable containers with padding
*
* @default 0
*/
marginPixel?: number;
}
/**
* Asserts that the element is **fully visible within the current viewport**, optionally
* respecting a safety margin from the viewport edges.
*
* ```text
* ┌────────────────────────────────────┐
* │ Viewport │
* │ │
* │ ┌──marginPixel──┐ │
* │ │ │ │
* │ │ [element] │ ← must be here │
* │ │ │ │
* │ └───────────────┘ │
* └────────────────────────────────────┘
* ```
*
* @param element - The {@link Locator} of the element to check.
* @param options - Optional configuration for margin.
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* // Element must be fully in viewport (no margin)
* await expect(card).toBeWithinViewport();
*
* @example
* // Element must be fully visible with 50px margin from all edges
* await expect(modal).toBeWithinViewport({ marginPixel: 50 });
*/
declare function toBeWithinViewport(element: Locator, options?: ToBeWithinViewportOptions): Promise<MatcherReturnType>;
/**
* Asserts that the target element has sufficient color contrast between its text color and background color,
* according to the WCAG 2.1 contrast ratio formula.
*
* The matcher calculates the contrast ratio using the relative luminance of the text color and background color.
* It fails if the contrast ratio is below the specified minimum, as per WCAG 2.1 guidelines (e.g., 4.5:1 for normal text, 3:1 for large text).
*
* @param element - The element as a {@link Locator} to check for color contrast.
* @param minimumContrastRatio - The minimum acceptable contrast ratio (e.g., 4.5 for AA normal text, 3 for AA large text).
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* // Assert that a button's text has at least a 4.5:1 contrast ratio with its background
* await expect(buttonLocator).toHaveColorContrast(4.5);
*/
declare function toHaveColorContrast(element: Locator, minimumContrastRatio: number): Promise<MatcherReturnType>;
/**
* Asserts that the target element fits entirely within the bounds of the specified container element.
* The check ensures that all sides of the target element (top, bottom, left, right) are strictly within
* the bounds of the container, with no partial overlap allowed.
*
* - **Perfect Fit** (Pass):
* ```text
* ┌─────────────────────┐
* │┌───────────────────┐│
* ││ ││
* ││ Element ││
* ││ (Perfect Fit) ││
* ││ ││
* │└───────────────────┘│
* └─────────────────────┘
* ```
* - **Position Mismatch** (Fail):
* ```text
* ┌──────────────────────┐
* │ │
* │ ┌──────────────────┐ │
* │ │ Element │ │
* │ │ (Wrong Position) │ │
* │ └──────────────────┘ │
* └──────────────────────┘
* ```
* - **Size Mismatch** (Fail):
* ```text
* ┌─────────────────────┐
* │ ┌─────────────┐ │
* │ │ Element │ │
* │ │ (Too Small) │ │
* │ └─────────────┘ │
* └─────────────────────┘
* ```
* - **Overflow** (Fail):
* ```text
* ┌─────────────────────┐
* │┌────────────────────┼─┐
* ││ Element │ │
* ││ (Overflow) │ │
* │└────────────────────┼─┘
* └─────────────────────┘
* ```
*
* @param element - The element as a {@link Locator} to check for fitting within the container.
* @param container - The container element as a {@link Locator} within which the element is expected to fit.
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* await expect(locator).toFitContainer(parentLocator);
*/
declare function toFitContainer(element: Locator, container: Locator): Promise<MatcherReturnType>;
/**
* Asserts that the target element does not overlap with the reference element.
*
* This matcher checks whether the bounding boxes of the target element and the reference
* element intersect. If there is any overlap, the matcher fails and provides detailed
* information about the intersection area and dimensions.
*
* The function is useful for verifying layout constraints where elements should remain
* visually separated, such as avoiding collisions between buttons, modals, or other UI components.
*
* @param element - The element as a {@link Locator} whose overlap is checked.
* @param reference - The element as a {@link Locator} relative to which overlap is checked.
* @returns A {@link Promise} that resolves with the matcher result.
*
* @example
* // Checks that a tooltip does not overlap a button
* await expect(tooltip).toNotOverlapWith(button);
*/
declare function toNotOverlapWith(element: Locator, reference: Locator): Promise<MatcherReturnType>;
declare global {
namespace PlaywrightTest {
/**
* Provides a set of assertion matchers for verifying the spatial relationship and alignment
* of a target element relative to a specified container element. These matchers enable
* comprehensive checks for centering, alignment (horizontal and vertical), containment,
* and fitting within containers, with configurable tolerance levels.
*
* The interface is designed to facilitate robust UI testing by allowing precise validation
* of element positioning and layout constraints, supporting both strict and margin-based assertions.
*
* Each matcher returns a Promise that resolves with the result of the assertion, enabling
* asynchronous test flows and integration with modern testing frameworks.
*
* @template R The result type returned by each matcher, typically a Promise resolving to an assertion result.
*/
interface Matchers<R> {
toBeAbove(reference: Locator, options?: ToBeAboveOptions): Promise<R>;
toBeAlignedWith(container: Locator, axis: Axis, mode: Alignment, options?: ToBeAlignedWithOptions): Promise<R>;
toBeBelow(reference: Locator, options?: toBeBelowOptions): Promise<R>;
toBeFullyCentered(container: Locator, options?: ToBeFullyCenteredOptions): Promise<R>;
toBeHorizontallyAlignedWith(container: Locator, alignment: HorizontalAlignment, options?: ToBeHorizontallyAlignedWithOptions): Promise<R>;
toBeInside(container: Locator, options?: ToBeInsideOptions): Promise<R>;
toBeLeftOf(reference: Locator, options?: ToBeLeftOfOptions): Promise<R>;
toBeRightOf(reference: Locator, options?: ToBeRightOfOptions): Promise<R>;
toBeVerticallyAlignedWith(container: Locator, alignment: VerticalAlignment, options?: ToBeVerticallyAlignedWithOptions): Promise<R>;
toBeWithinViewport(options?: ToBeWithinViewportOptions): Promise<R>;
toFitContainer(container: Locator): Promise<R>;
toHaveAspectRatio(expectedRatio: number, options?: ToHaveAspectRatioOptions): Promise<R>;
toHaveColorContrast(minimumContrastRatio: number): Promise<R>;
toHaveDistanceFrom(reference: Locator, side: DistanceSide, expectedDistanceInPixels: number, options?: ToHaveDistanceFromOptions): Promise<R>;
toHaveSameSizeAs(container: Locator, options?: ToHaveSameSizeAsOptions): Promise<R>;
toHaveSpacingBetween(reference: Locator, expectedSpacing: number, axis: SpacingAxis, options?: ToHaveSpacingBetweenOptions): Promise<R>;
toNotOverlapWith(reference: Locator): Promise<R>;
}
}
}
export { Alignment, Axis, DistanceSide, HorizontalAlignment, SpacingAxis, ToleranceUnit, VerticalAlignment, toBeAbove, toBeAlignedWith, toBeBelow, toBeFullyCentered, toBeHorizontallyAlignedWith, toBeInside, toBeLeftOf, toBeRightOf, toBeVerticallyAlignedWith, toBeWithinViewport, toFitContainer, toHaveAspectRatio, toHaveColorContrast, toHaveDistanceFrom, toHaveSameSizeAs, toHaveSpacingBetween, toNotOverlapWith };