@wdio/image-comparison-core
Version:
Image comparison core module for @wdio/visual-service - WebdriverIO visual testing framework
430 lines (429 loc) • 18.2 kB
JavaScript
import { describe, it, expect } from 'vitest';
import { defaultOptions, methodCompareOptions, screenMethodCompareOptions, createBeforeScreenshotOptions, buildAfterScreenshotOptions } from './options.js';
describe('options', () => {
describe('defaultOptions', () => {
it('should return the default options when no options are provided', () => {
expect(defaultOptions({})).toMatchSnapshot();
});
it('should return the provided options when options are provided', () => {
const options = {
addressBarShadowPadding: 1,
autoSaveBaseline: true,
formatImageName: '{foo}-{bar}',
savePerInstance: true,
toolBarShadowPadding: 1,
disableBlinkingCursor: true,
disableCSSAnimation: true,
fullPageScrollTimeout: 12345,
hideScrollBars: true,
blockOutSideBar: true,
blockOutStatusBar: true,
blockOutToolBar: true,
createJsonReportFiles: true,
diffPixelBoundingBoxProximity: 123,
ignoreAlpha: true,
ignoreAntialiasing: true,
ignoreColors: true,
ignoreLess: true,
ignoreNothing: true,
rawMisMatchPercentage: true,
returnAllCompareData: true,
saveAboveTolerance: 12,
scaleImagesToSameSize: true,
tabbableOptions: {
circle: {
backgroundColor: 'backgroundColor',
borderColor: 'borderColor',
borderWidth: 123,
fontColor: 'fontColor',
fontFamily: 'fontFamily',
fontSize: 321,
size: 567,
showNumber: false,
},
line: {
color: 'color',
width: 987,
},
},
};
expect(defaultOptions(options)).toMatchSnapshot();
});
});
describe('methodCompareOptions', () => {
it('should not return the method options when no options are provided', () => {
expect(methodCompareOptions({})).toMatchSnapshot();
});
it('should return the provided options when options are provided', () => {
const options = {
blockOut: [{ height: 1, width: 2, x: 3, y: 4 }],
ignoreAlpha: true,
ignoreAntialiasing: true,
ignoreColors: true,
ignoreLess: true,
ignoreNothing: true,
rawMisMatchPercentage: true,
returnAllCompareData: true,
saveAboveTolerance: 12,
scaleImagesToSameSize: true,
};
expect(methodCompareOptions(options)).toMatchSnapshot();
});
});
describe('screenMethodCompareOptions', () => {
it('should not return the screen method options when no options are provided', () => {
expect(screenMethodCompareOptions({})).toMatchSnapshot();
});
it('should return the provided options when options are provided', () => {
const options = {
blockOutSideBar: false,
blockOutStatusBar: false,
blockOutToolBar: false,
blockOut: [{ height: 1, width: 2, x: 3, y: 4 }],
ignoreAlpha: true,
ignoreAntialiasing: true,
ignoreColors: true,
ignoreLess: true,
ignoreNothing: true,
rawMisMatchPercentage: true,
returnAllCompareData: true,
saveAboveTolerance: 12,
scaleImagesToSameSize: true,
};
expect(screenMethodCompareOptions(options)).toMatchSnapshot();
});
});
describe('createBeforeScreenshotOptions', () => {
const mockElement = { tagName: 'DIV' };
const baseWicOptions = {
addressBarShadowPadding: 10,
toolBarShadowPadding: 20,
};
it('should create options with defaults when minimal options are provided', () => {
const result = createBeforeScreenshotOptions('testInstance', {}, baseWicOptions);
expect(result).toEqual({
instanceData: 'testInstance',
addressBarShadowPadding: 10,
toolBarShadowPadding: 20,
disableBlinkingCursor: false,
disableCSSAnimation: false,
enableLayoutTesting: false,
hideElements: [],
noScrollBars: false,
removeElements: [],
waitForFontsLoaded: false,
});
});
it('should prioritize methodOptions over wicOptions for overlapping properties', () => {
const methodOptions = {
disableBlinkingCursor: true,
disableCSSAnimation: true,
hideScrollBars: true,
};
const wicOptions = {
...baseWicOptions,
disableBlinkingCursor: false,
disableCSSAnimation: false,
hideScrollBars: false,
};
const result = createBeforeScreenshotOptions('testInstance', methodOptions, wicOptions);
expect(result.disableBlinkingCursor).toBe(true);
expect(result.disableCSSAnimation).toBe(true);
expect(result.noScrollBars).toBe(true);
});
it('should use wicOptions when methodOptions are undefined', () => {
const wicOptions = {
...baseWicOptions,
disableBlinkingCursor: true,
enableLayoutTesting: true,
waitForFontsLoaded: true,
};
const result = createBeforeScreenshotOptions('testInstance', {}, wicOptions);
expect(result.disableBlinkingCursor).toBe(true);
expect(result.enableLayoutTesting).toBe(true);
expect(result.waitForFontsLoaded).toBe(true);
});
it('should handle element arrays from methodOptions', () => {
const hideElements = [mockElement];
const removeElements = [mockElement, mockElement];
const methodOptions = {
hideElements,
removeElements,
};
const result = createBeforeScreenshotOptions('testInstance', methodOptions, baseWicOptions);
expect(result.hideElements).toBe(hideElements);
expect(result.removeElements).toBe(removeElements);
});
it('should handle all boolean options set to true in methodOptions', () => {
const methodOptions = {
disableBlinkingCursor: true,
disableCSSAnimation: true,
enableLayoutTesting: true,
hideScrollBars: true,
waitForFontsLoaded: true,
};
const result = createBeforeScreenshotOptions('testInstance', methodOptions, baseWicOptions);
expect(result.disableBlinkingCursor).toBe(true);
expect(result.disableCSSAnimation).toBe(true);
expect(result.enableLayoutTesting).toBe(true);
expect(result.noScrollBars).toBe(true);
expect(result.waitForFontsLoaded).toBe(true);
});
it('should preserve instanceData exactly as passed', () => {
const complexInstanceData = { browser: 'chrome', version: '120', viewport: { width: 1920, height: 1080 } };
const result = createBeforeScreenshotOptions(complexInstanceData, {}, baseWicOptions);
expect(result.instanceData).toBe(complexInstanceData);
});
});
describe('buildAfterScreenshotOptions', () => {
const mockInstanceData = {
appName: 'testApp',
browserName: 'chrome',
browserVersion: '120.0.0',
deviceName: 'desktop',
devicePixelRatio: 2,
deviceRectangles: {
bottomBar: { height: 0, width: 0, x: 0, y: 0 },
homeBar: { height: 0, width: 0, x: 0, y: 0 },
leftSidePadding: { height: 0, width: 0, x: 0, y: 0 },
rightSidePadding: { height: 0, width: 0, x: 0, y: 0 },
screenSize: { height: 1080, width: 1920 },
statusBar: { height: 0, width: 0, x: 0, y: 0 },
statusBarAndAddressBar: { height: 0, width: 0, x: 0, y: 0 },
viewport: { height: 900, width: 1200, x: 0, y: 0 }
},
initialDevicePixelRatio: 2,
isAndroid: false,
isIOS: false,
isMobile: false,
logName: 'chrome',
name: 'chrome',
nativeWebScreenshot: false,
platformName: 'desktop',
platformVersion: '120.0.0'
};
const mockEnrichedInstanceData = {
...mockInstanceData,
dimensions: {
body: {
scrollHeight: 1000,
offsetHeight: 1000
},
html: {
clientWidth: 1200,
scrollWidth: 1200,
clientHeight: 900,
scrollHeight: 1000,
offsetHeight: 1000
},
window: {
devicePixelRatio: 3,
innerHeight: 800,
innerWidth: 1100,
isEmulated: false,
isLandscape: true,
outerHeight: 1000,
outerWidth: 1200,
screenHeight: 1440,
screenWidth: 2560,
}
},
isAndroidChromeDriverScreenshot: false,
isAndroidNativeWebScreenshot: false,
isTestInBrowser: true,
isTestInMobileBrowser: false,
addressBarShadowPadding: 10,
toolBarShadowPadding: 20
};
const baseInput = {
base64Image: 'test-screenshot-data',
folders: { actualFolder: '/test/actual' },
tag: 'test-element',
isNativeContext: false,
instanceData: mockInstanceData,
wicOptions: {
formatImageName: '{tag}-{browserName}-{width}x{height}',
savePerInstance: false,
alwaysSaveActualImage: true
}
};
it('should build options for native commands (no enriched data)', () => {
const input = {
...baseInput,
isNativeContext: true
};
const result = buildAfterScreenshotOptions(input);
expect(result).toMatchSnapshot();
expect(result.isNativeContext).toBe(true);
expect(result.isLandscape).toBe(false);
expect(result.disableBlinkingCursor).toBeUndefined();
expect(result.hideElements).toBeUndefined();
});
it('should build options for web commands with enriched data', () => {
const beforeOptions = {
instanceData: mockInstanceData,
addressBarShadowPadding: 10,
toolBarShadowPadding: 20,
disableBlinkingCursor: true,
disableCSSAnimation: false,
enableLayoutTesting: true,
hideElements: [],
noScrollBars: true,
removeElements: [],
waitForFontsLoaded: false
};
const input = {
...baseInput,
enrichedInstanceData: mockEnrichedInstanceData,
beforeOptions
};
const result = buildAfterScreenshotOptions(input);
expect(result).toMatchSnapshot();
expect(result.isNativeContext).toBe(false);
expect(result.isLandscape).toBe(true);
expect(result.disableBlinkingCursor).toBe(true);
expect(result.disableCSSAnimation).toBe(false);
expect(result.enableLayoutTesting).toBe(true);
expect(result.hideScrollBars).toBe(true);
expect(result.hideElements).toEqual([]);
expect(result.removeElements).toEqual([]);
});
it('should prioritize enriched data over instance data', () => {
const input = {
...baseInput,
enrichedInstanceData: mockEnrichedInstanceData
};
const result = buildAfterScreenshotOptions(input);
expect(result.fileName.devicePixelRatio).toBe(3);
expect(result.fileName.outerHeight).toBe(1000);
expect(result.fileName.screenHeight).toBe(1440);
expect(result.isLandscape).toBe(true);
});
it('should handle NaN values correctly', () => {
const enrichedWithNaN = {
...mockEnrichedInstanceData,
dimensions: {
...mockEnrichedInstanceData.dimensions,
window: {
...mockEnrichedInstanceData.dimensions.window,
devicePixelRatio: undefined,
outerHeight: undefined,
outerWidth: undefined,
screenHeight: undefined,
screenWidth: undefined,
}
}
};
const input = {
...baseInput,
enrichedInstanceData: enrichedWithNaN
};
const result = buildAfterScreenshotOptions(input);
expect(result.fileName.devicePixelRatio).toBe(2);
expect(result.fileName.outerHeight).toBeNaN();
expect(result.fileName.outerWidth).toBeNaN();
expect(result.fileName.screenHeight).toBe(1080);
expect(result.fileName.screenWidth).toBe(1920);
});
it('should handle missing enriched data gracefully', () => {
const input = {
...baseInput,
enrichedInstanceData: undefined
};
const result = buildAfterScreenshotOptions(input);
expect(result.fileName.devicePixelRatio).toBe(2);
expect(result.fileName.screenHeight).toBe(1080);
expect(result.fileName.screenWidth).toBe(1920);
expect(result.fileName.logName).toBe('chrome');
expect(result.fileName.name).toBe('chrome');
expect(result.isLandscape).toBe(false);
});
it('should handle element arrays from beforeOptions', () => {
const mockElement = { tagName: 'DIV' };
const beforeOptions = {
instanceData: mockInstanceData,
addressBarShadowPadding: 10,
toolBarShadowPadding: 20,
disableBlinkingCursor: false,
disableCSSAnimation: false,
enableLayoutTesting: false,
hideElements: [mockElement],
noScrollBars: false,
removeElements: [mockElement, mockElement],
waitForFontsLoaded: false
};
const input = {
...baseInput,
beforeOptions
};
const result = buildAfterScreenshotOptions(input);
expect(result.hideElements).toEqual([mockElement]);
expect(result.removeElements).toEqual([mockElement, mockElement]);
});
it('should build correct filePath structure', () => {
const input = {
...baseInput,
wicOptions: {
formatImageName: '{tag}-{logName}',
savePerInstance: true
}
};
const result = buildAfterScreenshotOptions(input);
expect(result.filePath).toEqual({
browserName: 'chrome',
deviceName: 'desktop',
isMobile: false,
savePerInstance: true
});
});
it('should build correct fileName structure with all properties', () => {
const input = {
...baseInput,
enrichedInstanceData: mockEnrichedInstanceData
};
const result = buildAfterScreenshotOptions(input);
expect(result.fileName).toEqual({
browserName: 'chrome',
browserVersion: '120.0.0',
deviceName: 'desktop',
devicePixelRatio: 3,
formatImageName: '{tag}-{browserName}-{width}x{height}',
isMobile: false,
isTestInBrowser: true,
logName: 'chrome',
name: 'chrome',
outerHeight: 1000,
outerWidth: 1200,
platformName: 'desktop',
platformVersion: '120.0.0',
screenHeight: 1440,
screenWidth: 2560,
tag: 'test-element'
});
});
it('should handle mobile device correctly', () => {
const mobileInstanceData = {
...mockInstanceData,
isMobile: true,
deviceName: 'iPhone',
platformName: 'iOS'
};
const mobileEnrichedData = {
...mockEnrichedInstanceData,
isMobile: true,
deviceName: 'iPhone',
platformName: 'iOS'
};
const input = {
...baseInput,
instanceData: mobileInstanceData,
enrichedInstanceData: mobileEnrichedData
};
const result = buildAfterScreenshotOptions(input);
expect(result.filePath.isMobile).toBe(true);
expect(result.fileName.isMobile).toBe(true);
expect(result.fileName.deviceName).toBe('iPhone');
expect(result.platformName).toBe('iOS');
});
});
});