jsdom-testing-mocks
Version:
A set of tools for emulating browser behavior in jsdom environment
408 lines (398 loc) • 15.1 kB
TypeScript
import { PartialDeep, Writable, RequireAtLeastOne } from 'type-fest';
import { MediaValues } from 'css-mediaquery';
type IntersectionDescription = Omit<PartialDeep<Writable<IntersectionObserverEntry>>, 'target'> & {
target?: Element;
};
type NodeIntersectionDescription = {
node: HTMLElement;
desc?: IntersectionDescription;
};
declare class MockedIntersectionObserver implements IntersectionObserver {
nodes: HTMLElement[];
nodeStates: IntersectionObserverEntry[];
callback: IntersectionObserverCallback;
readonly root: Element | Document | null;
readonly rootMargin: string;
readonly thresholds: ReadonlyArray<number>;
timeOrigin: number;
constructor(callback: IntersectionObserverCallback, options?: IntersectionObserverInit | undefined);
observe(node: HTMLElement): void;
unobserve(node: HTMLElement): void;
disconnect(): void;
triggerNode(node: HTMLElement, desc: IntersectionDescription): void;
triggerNodes(nodeDescriptions: NodeIntersectionDescription[]): void;
takeRecords(): IntersectionObserverEntry[];
}
declare function mockIntersectionObserver(): {
enterAll: (desc?: IntersectionDescription) => void;
enterNode: (node: HTMLElement, desc?: IntersectionDescription) => void;
enterNodes: (nodeDescriptions: (NodeIntersectionDescription | HTMLElement)[]) => void;
leaveAll: (desc?: IntersectionDescription) => void;
leaveNode: (node: HTMLElement, desc?: IntersectionDescription) => void;
triggerNodes: (nodeDescriptions: (NodeIntersectionDescription | HTMLElement)[]) => void;
leaveNodes: (nodeDescriptions: (NodeIntersectionDescription | HTMLElement)[]) => void;
cleanup: () => void;
};
type ResizeObserverSizeInput = RequireAtLeastOne<ResizeObserverSize>;
type SizeInput = {
borderBoxSize: ResizeObserverSizeInput[] | ResizeObserverSizeInput;
contentBoxSize: ResizeObserverSizeInput[] | ResizeObserverSizeInput;
};
type Size = RequireAtLeastOne<SizeInput>;
declare class MockedResizeObserver implements ResizeObserver {
callback: ResizeObserverCallback;
observationTargets: Set<HTMLElement>;
activeTargets: Set<HTMLElement>;
constructor(callback: ResizeObserverCallback);
observe: (node: HTMLElement) => void;
unobserve: (node: HTMLElement) => void;
disconnect: () => void;
}
declare function mockResizeObserver(): {
getObservers: (element?: HTMLElement) => MockedResizeObserver[];
getObservedElements: (observer?: ResizeObserver) => HTMLElement[];
mockElementSize: (element: HTMLElement, size: Size) => void;
resize: (elements?: HTMLElement | HTMLElement[], { ignoreImplicit }?: {
ignoreImplicit?: boolean | undefined;
}) => void;
};
declare class MockedDOMRectReadOnly implements DOMRectReadOnly {
_x: number;
_y: number;
_width: number;
_height: number;
constructor(x?: number, y?: number, width?: number, height?: number);
get x(): number;
set x(_value: number);
get y(): number;
set y(_value: number);
get width(): number;
set width(_value: number);
get height(): number;
set height(_value: number);
get left(): number;
set left(_value: number);
get right(): number;
set right(_value: number);
get top(): number;
set top(_value: number);
get bottom(): number;
set bottom(_value: number);
toJSON(): {
bottom: number;
height: number;
left: number;
right: number;
top: number;
width: number;
x: number;
y: number;
};
toString(): string;
}
declare class MockedDOMRect extends MockedDOMRectReadOnly implements DOMRect {
constructor(x?: number, y?: number, width?: number, height?: number);
get x(): number;
set x(_value: number);
get y(): number;
set y(_value: number);
get width(): number;
set width(_value: number);
get height(): number;
set height(_value: number);
toString(): string;
}
declare function mockDOMRect(): void;
declare const mockElementBoundingClientRect: (element: HTMLElement, { x, y, width, height, }: Partial<Pick<DOMRect, "x" | "y" | "width" | "height">>) => () => DOMRect;
/**
* A tool that allows testing components that use js media queries (matchMedia)
* `mockViewport` must be called before rendering the component
* @example using react testing library
*
* const viewport = mockViewport({ width: '320px', height: '568px' })
*
* const { getByText, queryByText } = render(<TestComponent />)
*
* expect(getByText('Content visible only in the phone')).toBeInTheDocument()
* expect(queryByText('Content visible only on desktop')).not.toBeInTheDocument()
*
* act(() => {
* viewport.set({ width: '1440px', height: '900px' })
* })
*
* expect(queryByText('Content visible only on the phone')).not.toBeInTheDocument()
* expect(getByText('Content visible only on desktop')).toBeInTheDocument()
*
* viewport.cleanup()
*
*/
type ViewportDescription = Partial<MediaValues>;
type MockViewport = {
cleanup: () => void;
set: (newDesc: ViewportDescription) => void;
};
declare function mockViewport(desc: ViewportDescription): MockViewport;
declare function mockViewportForTestGroup(desc: ViewportDescription): void;
declare function mockAnimationsApi(): void;
/**
* CSS Typed OM Implementation
*
* A comprehensive polyfill for CSS Typed Object Model Level 1
* Based on the W3C specification: https://www.w3.org/TR/css-typed-om-1/
*
* This implementation includes:
* - CSSNumericValue (base class)
* - CSSUnitValue (single unit values)
* - CSSMathValue and subclasses (math expressions)
* - Unit conversion and type checking
* - Full arithmetic operations
*/
/**
* CSS numeric base types as defined in the specification
*/
type CSSNumericBaseType = 'length' | 'angle' | 'time' | 'frequency' | 'resolution' | 'flex' | 'percent';
/**
* CSS math operators
*/
type CSSMathOperator = 'sum' | 'product' | 'negate' | 'invert' | 'min' | 'max' | 'clamp';
/**
* CSS numeric type representing the dimensional analysis of a value
*/
interface CSSNumericType {
length: number;
angle: number;
time: number;
frequency: number;
resolution: number;
flex: number;
percent: number;
percentHint?: CSSNumericBaseType;
}
/**
* Base class for all CSS numeric values
*/
declare abstract class MockedCSSNumericValue implements CSSNumericValue {
constructor();
/**
* Returns the type of this numeric value
*/
abstract type(): CSSNumericType;
/**
* Adds one or more values to this value
*/
add(...values: CSSNumberish[]): CSSNumericValue;
/**
* Subtracts one or more values from this value
*/
sub(...values: CSSNumberish[]): CSSNumericValue;
/**
* Multiplies this value by one or more values
*/
mul(...values: CSSNumberish[]): CSSNumericValue;
/**
* Divides this value by one or more values
*/
div(...values: CSSNumberish[]): CSSNumericValue;
/**
* Returns the minimum of this value and one or more other values
*/
min(...values: CSSNumberish[]): CSSNumericValue;
/**
* Returns the maximum of this value and one or more other values
*/
max(...values: CSSNumberish[]): CSSNumericValue;
/**
* Checks if this value equals one or more other values
*/
equals(...values: CSSNumberish[]): boolean;
/**
* Converts this value to the specified unit
*/
to(unit: string): CSSUnitValue;
/**
* Converts this value to a sum of the specified units
*/
toSum(...units: string[]): CSSMathSum;
/**
* Negates this value
*/
negate(): CSSNumericValue;
/**
* Inverts this value (1/value)
*/
invert(): CSSNumericValue;
/**
* Checks if this value is equal to another
*/
protected isEqualTo(other: MockedCSSNumericValue): boolean;
static parse(_cssText: string): MockedCSSNumericValue;
}
/**
* Represents a CSS value with a single numeric value and unit
*/
declare class MockedCSSUnitValue extends MockedCSSNumericValue implements CSSUnitValue {
value: number;
unit: string;
constructor(value: number, unit: string);
type(): CSSNumericType;
toString(): string;
static parse(_cssText: string): MockedCSSUnitValue;
}
/**
* Base class for CSS math expressions
*/
declare abstract class MockedCSSMathValue extends MockedCSSNumericValue implements CSSMathValue {
abstract get operator(): CSSMathOperator;
toString(): string;
protected abstract toCSSString(): string;
}
/**
* Represents a CSS calc() sum expression
*/
declare class MockedCSSMathSum extends MockedCSSMathValue implements CSSMathSum {
values: MockedCSSNumericValue[];
readonly operator: CSSMathOperator;
constructor(values: MockedCSSNumericValue[]);
type(): CSSNumericType;
protected toCSSString(): string;
}
/**
* Represents a CSS calc() product expression
*/
declare class MockedCSSMathProduct extends MockedCSSMathValue implements CSSMathProduct {
values: MockedCSSNumericValue[];
readonly operator: CSSMathOperator;
constructor(values: MockedCSSNumericValue[]);
type(): CSSNumericType;
protected toCSSString(): string;
}
/**
* Represents a CSS calc() negation
*/
declare class MockedCSSMathNegate extends MockedCSSMathValue implements CSSMathNegate {
value: MockedCSSNumericValue;
readonly operator: CSSMathOperator;
constructor(value: MockedCSSNumericValue);
type(): CSSNumericType;
protected toCSSString(): string;
}
/**
* Represents a CSS calc() inversion (1/value)
*/
declare class MockedCSSMathInvert extends MockedCSSMathValue implements CSSMathInvert {
value: MockedCSSNumericValue;
readonly operator: CSSMathOperator;
constructor(value: MockedCSSNumericValue);
type(): CSSNumericType;
protected toCSSString(): string;
}
/**
* Represents a CSS min() expression
*/
declare class MockedCSSMathMin extends MockedCSSMathValue implements CSSMathMin {
values: MockedCSSNumericValue[];
readonly operator: CSSMathOperator;
constructor(values: MockedCSSNumericValue[]);
type(): CSSNumericType;
protected toCSSString(): string;
toString(): string;
}
/**
* Represents a CSS max() expression
*/
declare class MockedCSSMathMax extends MockedCSSMathValue implements CSSMathMax {
values: MockedCSSNumericValue[];
readonly operator: CSSMathOperator;
constructor(values: MockedCSSNumericValue[]);
type(): CSSNumericType;
protected toCSSString(): string;
toString(): string;
}
/**
* Represents a CSS clamp() expression
*/
declare class MockedCSSMathClamp extends MockedCSSMathValue implements CSSMathClamp {
lower: MockedCSSNumericValue;
value: MockedCSSNumericValue;
upper: MockedCSSNumericValue;
readonly operator: CSSMathOperator;
constructor(lower: MockedCSSNumericValue, value: MockedCSSNumericValue, upper: MockedCSSNumericValue);
type(): CSSNumericType;
protected toCSSString(): string;
toString(): string;
}
declare const MockedCSS: {
number: (value: number) => MockedCSSUnitValue;
percent: (value: number) => MockedCSSUnitValue;
px: (value: number) => MockedCSSUnitValue;
cm: (value: number) => MockedCSSUnitValue;
mm: (value: number) => MockedCSSUnitValue;
in: (value: number) => MockedCSSUnitValue;
pt: (value: number) => MockedCSSUnitValue;
pc: (value: number) => MockedCSSUnitValue;
Q: (value: number) => MockedCSSUnitValue;
em: (value: number) => MockedCSSUnitValue;
rem: (value: number) => MockedCSSUnitValue;
ex: (value: number) => MockedCSSUnitValue;
ch: (value: number) => MockedCSSUnitValue;
cap: (value: number) => MockedCSSUnitValue;
ic: (value: number) => MockedCSSUnitValue;
lh: (value: number) => MockedCSSUnitValue;
rlh: (value: number) => MockedCSSUnitValue;
vw: (value: number) => MockedCSSUnitValue;
vh: (value: number) => MockedCSSUnitValue;
vi: (value: number) => MockedCSSUnitValue;
vb: (value: number) => MockedCSSUnitValue;
vmin: (value: number) => MockedCSSUnitValue;
vmax: (value: number) => MockedCSSUnitValue;
svw: (value: number) => MockedCSSUnitValue;
svh: (value: number) => MockedCSSUnitValue;
svi: (value: number) => MockedCSSUnitValue;
svb: (value: number) => MockedCSSUnitValue;
svmin: (value: number) => MockedCSSUnitValue;
svmax: (value: number) => MockedCSSUnitValue;
lvw: (value: number) => MockedCSSUnitValue;
lvh: (value: number) => MockedCSSUnitValue;
lvi: (value: number) => MockedCSSUnitValue;
lvb: (value: number) => MockedCSSUnitValue;
lvmin: (value: number) => MockedCSSUnitValue;
lvmax: (value: number) => MockedCSSUnitValue;
dvw: (value: number) => MockedCSSUnitValue;
dvh: (value: number) => MockedCSSUnitValue;
dvi: (value: number) => MockedCSSUnitValue;
dvb: (value: number) => MockedCSSUnitValue;
dvmin: (value: number) => MockedCSSUnitValue;
dvmax: (value: number) => MockedCSSUnitValue;
cqw: (value: number) => MockedCSSUnitValue;
cqh: (value: number) => MockedCSSUnitValue;
cqi: (value: number) => MockedCSSUnitValue;
cqb: (value: number) => MockedCSSUnitValue;
cqmin: (value: number) => MockedCSSUnitValue;
cqmax: (value: number) => MockedCSSUnitValue;
deg: (value: number) => MockedCSSUnitValue;
rad: (value: number) => MockedCSSUnitValue;
grad: (value: number) => MockedCSSUnitValue;
turn: (value: number) => MockedCSSUnitValue;
s: (value: number) => MockedCSSUnitValue;
ms: (value: number) => MockedCSSUnitValue;
Hz: (value: number) => MockedCSSUnitValue;
kHz: (value: number) => MockedCSSUnitValue;
dpi: (value: number) => MockedCSSUnitValue;
dpcm: (value: number) => MockedCSSUnitValue;
dppx: (value: number) => MockedCSSUnitValue;
fr: (value: number) => MockedCSSUnitValue;
};
/**
* Initializes CSS Typed OM mocks in the global environment
*/
declare function initCSSTypedOM(): void;
type JTMConfig = {
beforeAll: (callback: () => any) => void;
afterAll: (callback: () => any) => void;
beforeEach: (callback: () => any) => void;
afterEach: (callback: () => any) => void;
act: (trigger: () => void) => void;
};
declare const getConfig: () => JTMConfig;
declare const configMocks: ({ beforeAll, afterAll, beforeEach, afterEach, act, }: Partial<JTMConfig>) => void;
export { type IntersectionDescription, type MockViewport, MockedCSS, MockedCSSMathClamp, MockedCSSMathInvert, MockedCSSMathMax, MockedCSSMathMin, MockedCSSMathNegate, MockedCSSMathProduct, MockedCSSMathSum, MockedCSSMathValue, MockedCSSNumericValue, MockedCSSUnitValue, MockedDOMRect, MockedDOMRectReadOnly, MockedIntersectionObserver, type NodeIntersectionDescription, type ViewportDescription, configMocks, getConfig, initCSSTypedOM, mockAnimationsApi, initCSSTypedOM as mockCSSTypedOM, mockDOMRect, mockElementBoundingClientRect, mockIntersectionObserver, mockResizeObserver, mockViewport, mockViewportForTestGroup };