diff --git a/.gitignore b/.gitignore index 7cc05ab7a..2faf936e4 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ build # folders .tmp +.pixelmatch-tmp/ /__snapshots__/ .idea/ localBaseline/ diff --git a/packages/image-comparison-core/package.json b/packages/image-comparison-core/package.json index 5894a620f..5d535be60 100644 --- a/packages/image-comparison-core/package.json +++ b/packages/image-comparison-core/package.json @@ -35,6 +35,7 @@ }, "dependencies": { "jimp": "^1.6.1", + "pixelmatch": "^7.2.0", "@wdio/logger": "^9.18.0", "@wdio/types": "^9.27.0" }, diff --git a/packages/image-comparison-core/src/__snapshots__/base.test.ts.snap b/packages/image-comparison-core/src/__snapshots__/base.test.ts.snap index 9c059396c..5adbfa7c9 100644 --- a/packages/image-comparison-core/src/__snapshots__/base.test.ts.snap +++ b/packages/image-comparison-core/src/__snapshots__/base.test.ts.snap @@ -12,6 +12,7 @@ exports[`BaseClass > initializes default options correctly 1`] = ` "blockOutSideBar": true, "blockOutStatusBar": true, "blockOutToolBar": true, + "compareEngine": "resemble", "createJsonReportFiles": false, "diffPixelBoundingBoxProximity": 5, "ignoreAlpha": false, diff --git a/packages/image-comparison-core/src/helpers/__snapshots__/options.test.ts.snap b/packages/image-comparison-core/src/helpers/__snapshots__/options.test.ts.snap index c23771b92..8264bd4de 100644 --- a/packages/image-comparison-core/src/helpers/__snapshots__/options.test.ts.snap +++ b/packages/image-comparison-core/src/helpers/__snapshots__/options.test.ts.snap @@ -88,6 +88,7 @@ exports[`options > defaultOptions > should return the default options when no op "blockOutSideBar": true, "blockOutStatusBar": true, "blockOutToolBar": true, + "compareEngine": "resemble", "createJsonReportFiles": false, "diffPixelBoundingBoxProximity": 5, "ignoreAlpha": false, @@ -143,6 +144,7 @@ exports[`options > defaultOptions > should return the provided options when opti "blockOutSideBar": true, "blockOutStatusBar": true, "blockOutToolBar": true, + "compareEngine": "resemble", "createJsonReportFiles": true, "diffPixelBoundingBoxProximity": 123, "ignoreAlpha": true, diff --git a/packages/image-comparison-core/src/helpers/constants.ts b/packages/image-comparison-core/src/helpers/constants.ts index 5776b1db7..0390a5265 100644 --- a/packages/image-comparison-core/src/helpers/constants.ts +++ b/packages/image-comparison-core/src/helpers/constants.ts @@ -7,6 +7,7 @@ export const DEFAULT_COMPARE_OPTIONS = { blockOutSideBar: true, blockOutStatusBar: true, blockOutToolBar: true, + compareEngine: 'resemble' as const, createJsonReportFiles: false, diffPixelBoundingBoxProximity: 5, ignoreAlpha: false, diff --git a/packages/image-comparison-core/src/helpers/options.interfaces.ts b/packages/image-comparison-core/src/helpers/options.interfaces.ts index 6d4394001..31c90d8b0 100644 --- a/packages/image-comparison-core/src/helpers/options.interfaces.ts +++ b/packages/image-comparison-core/src/helpers/options.interfaces.ts @@ -205,6 +205,15 @@ export interface ClassOptions { */ scaleImagesToSameSize?: boolean; + /** + * The image comparison engine to use. + * 'pixelmatch' is a beta alternative that uses the YIQ color space and is + * more robust against font rendering noise and anti-aliasing differences. + * Prefer setting this inside compareOptions. + * @default 'resemble' + */ + compareEngine?: 'resemble' | 'pixelmatch'; + /** * Options object passed to the underlying image comparison engine. */ @@ -482,5 +491,12 @@ export interface CompareOptions { * Scale images to the same size before comparing them. */ scaleImagesToSameSize: boolean; + /** + * The image comparison engine to use. + * 'pixelmatch' is a beta alternative that uses the YIQ color space and is + * more robust against font rendering noise and anti-aliasing differences. + * @default 'resemble' + */ + compareEngine?: 'resemble' | 'pixelmatch'; } diff --git a/packages/image-comparison-core/src/helpers/options.ts b/packages/image-comparison-core/src/helpers/options.ts index bbd5209d7..d80dc1f0e 100644 --- a/packages/image-comparison-core/src/helpers/options.ts +++ b/packages/image-comparison-core/src/helpers/options.ts @@ -62,11 +62,13 @@ export function defaultOptions(options: ClassOptions): DefaultOptions { * Compare options (merged sequentially): * 1. Default options (fallback) * 2. Root compareOptions (deprecated but supported) - * 3. User-provided compareOptions + * 3. Root-level compareEngine shorthand (convenience alias) + * 4. User-provided compareOptions (highest precedence) */ compareOptions: { ...DEFAULT_COMPARE_OPTIONS, ...logAllDeprecatedCompareOptions(options), + ...(options.compareEngine ? { compareEngine: options.compareEngine } : {}), ...options.compareOptions, }, diff --git a/packages/image-comparison-core/src/methods/createCompareReport.test.ts b/packages/image-comparison-core/src/methods/createCompareReport.test.ts index f0a39b053..438a8e1d7 100644 --- a/packages/image-comparison-core/src/methods/createCompareReport.test.ts +++ b/packages/image-comparison-core/src/methods/createCompareReport.test.ts @@ -19,7 +19,7 @@ describe('createCompareReport', () => { const createMockData = (misMatchPercentage = 0): CompareData => ({ misMatchPercentage, rawMisMatchPercentage: misMatchPercentage, - getBuffer: () => Buffer.from(''), + getBuffer: () => Promise.resolve(Buffer.from('')), diffBounds: { top: 0, left: 0, bottom: 0, right: 0 }, analysisTime: 0, diffPixels: [], @@ -144,7 +144,7 @@ describe('createJsonReportIfNeeded', () => { const createMockData = (misMatchPercentage = 0): CompareData => ({ misMatchPercentage, rawMisMatchPercentage: misMatchPercentage, - getBuffer: () => Buffer.from(''), + getBuffer: () => Promise.resolve(Buffer.from('')), diffBounds: { top: 0, left: 0, bottom: 0, right: 0 }, analysisTime: 0, diffPixels: [], diff --git a/packages/image-comparison-core/src/methods/images.executeImageCompare.test.ts b/packages/image-comparison-core/src/methods/images.executeImageCompare.test.ts index fa16e368f..51f28b3ec 100644 --- a/packages/image-comparison-core/src/methods/images.executeImageCompare.test.ts +++ b/packages/image-comparison-core/src/methods/images.executeImageCompare.test.ts @@ -7,6 +7,7 @@ import * as rectangles from './rectangles.js' import * as processDiffPixels from './processDiffPixels.js' import * as createCompareReport from './createCompareReport.js' import * as compareImages from '../resemble/compareImages.js' +import * as compareImagesPixelmatch from '../pixelmatch/compareImages.js' const log = logger('test') @@ -82,6 +83,9 @@ vi.mock('./createCompareReport.js', () => ({ vi.mock('../resemble/compareImages.js', () => ({ default: vi.fn() })) +vi.mock('../pixelmatch/compareImages.js', () => ({ + default: vi.fn() +})) vi.mock('../helpers/constants.js', () => ({ DEFAULT_RESIZE_DIMENSIONS: { top: 0, right: 0, bottom: 0, left: 0 } })) @@ -217,14 +221,16 @@ describe('executeImageCompare', () => { }) vi.mocked(createCompareReport.createCompareReport).mockReturnValue(undefined) vi.mocked(createCompareReport.createJsonReportIfNeeded).mockResolvedValue(undefined) - vi.mocked(compareImages.default).mockResolvedValue({ + const mockCompareData = { rawMisMatchPercentage: 0.5, misMatchPercentage: 0.5, getBuffer: vi.fn().mockResolvedValue(Buffer.from('diff-image-data')), diffBounds: { left: 0, top: 0, right: 100, bottom: 200 }, analysisTime: 100, diffPixels: [] - }) + } + vi.mocked(compareImages.default).mockResolvedValue(mockCompareData) + vi.mocked(compareImagesPixelmatch.default).mockResolvedValue(mockCompareData) vi.mocked(images.checkBaselineImageExists).mockResolvedValue(undefined) vi.mocked(images.removeDiffImageIfExists).mockResolvedValue(undefined) vi.mocked(images.saveBase64Image).mockResolvedValue(undefined) @@ -268,6 +274,29 @@ describe('executeImageCompare', () => { ) }) + it('should use the pixelmatch adapter when compareEngine is pixelmatch', async () => { + const pixelmatchOptions = { + ...mockOptions, + compareOptions: { + ...mockOptions.compareOptions, + wic: { + ...mockOptions.compareOptions.wic, + compareEngine: 'pixelmatch' as const + } + } + } + + await executeImageCompare({ + isViewPortScreenshot: true, + isNativeContext: false, + options: pixelmatchOptions, + testContext: mockTestContext + }) + + expect(compareImagesPixelmatch.default).toHaveBeenCalledTimes(1) + expect(compareImages.default).not.toHaveBeenCalled() + }) + it('should handle mobile context with status/address/toolbar rectangles', async () => { const mobileOptions = { ...mockOptions, diff --git a/packages/image-comparison-core/src/methods/images.interfaces.ts b/packages/image-comparison-core/src/methods/images.interfaces.ts index 2e6e6f35c..cfa2ecdc8 100644 --- a/packages/image-comparison-core/src/methods/images.interfaces.ts +++ b/packages/image-comparison-core/src/methods/images.interfaces.ts @@ -60,6 +60,10 @@ export interface WicImageCompareOptions extends BaseImageCompareOptions, BaseMob * the higher the number the more pixels will be grouped, the lower the number the less pixels will be grouped due to accuracy. * Default is 5 pixels */ diffPixelBoundingBoxProximity: number; + /** The image comparison engine to use. + * @default 'resemble' + */ + compareEngine?: 'resemble' | 'pixelmatch'; } export interface DefaultImageCompareCompareOptions extends MethodImageCompareCompareOptions { diff --git a/packages/image-comparison-core/src/methods/images.ts b/packages/image-comparison-core/src/methods/images.ts index 34ca9b16d..9b736efc6 100644 --- a/packages/image-comparison-core/src/methods/images.ts +++ b/packages/image-comparison-core/src/methods/images.ts @@ -3,7 +3,8 @@ import { readFileSync, writeFileSync, promises as fsPromises, constants } from ' import { dirname, join } from 'node:path' import { Jimp, JimpMime } from 'jimp' import logger from '@wdio/logger' -import compareImages from '../resemble/compareImages.js' +import compareImagesResemble from '../resemble/compareImages.js' +import compareImagesPixelmatch from '../pixelmatch/compareImages.js' import { calculateDprData, getIosBezelImageNames, getBase64ScreenshotSize, prepareComparisonFilePaths, updateVisualBaseline } from '../helpers/utils.js' import { prepareIgnoreOptions } from '../helpers/options.js' import { DEFAULT_RESIZE_DIMENSIONS, supportedIosBezelDevices } from '../helpers/constants.js' @@ -446,7 +447,10 @@ export async function executeImageCompare( } // 5. Execute the compare and retrieve the data - const data: CompareData = await compareImages(readFileSync(baselineFilePath), actualImageBuffer, compareOptions) + const engine = imageCompareOptions.compareEngine === 'pixelmatch' ? 'pixelmatch' : 'resemble' + log.info(`Using comparison engine: ${engine}`) + const engineFn = engine === 'pixelmatch' ? compareImagesPixelmatch : compareImagesResemble + const data: CompareData = await engineFn(readFileSync(baselineFilePath), actualImageBuffer, compareOptions) const rawMisMatchPercentage = data.rawMisMatchPercentage const reportMisMatchPercentage = imageCompareOptions.rawMisMatchPercentage ? rawMisMatchPercentage diff --git a/packages/image-comparison-core/src/methods/rectangles.ts b/packages/image-comparison-core/src/methods/rectangles.ts index 8d98a258b..a7d691ba7 100644 --- a/packages/image-comparison-core/src/methods/rectangles.ts +++ b/packages/image-comparison-core/src/methods/rectangles.ts @@ -505,10 +505,14 @@ export async function determineWebElementIgnoreRegions( // to reduce 1px boundary differences on high-DPR / BiDi. let result = [...regions, ...regionsFromElements] .map((region: RectanglesOutput) => { + // Floor position (x/y) to include the start pixel, ceil size (width/height) + // to include the end pixel. Flooring size can lose 1px when CSS * DPR has + // a fractional part, causing the last row or column of an element to fall + // outside the ignored region. let x = Math.floor(region.x * devicePixelRatio) let y = Math.floor(region.y * devicePixelRatio) - let width = Math.floor(region.width * devicePixelRatio) - let height = Math.floor(region.height * devicePixelRatio) + let width = Math.ceil(region.width * devicePixelRatio) + let height = Math.ceil(region.height * devicePixelRatio) if (padding > 0) { x = Math.max(0, x - padding) y = Math.max(0, y - padding) diff --git a/packages/image-comparison-core/src/pixelmatch/compareImages.test.ts b/packages/image-comparison-core/src/pixelmatch/compareImages.test.ts new file mode 100644 index 000000000..24f481400 --- /dev/null +++ b/packages/image-comparison-core/src/pixelmatch/compareImages.test.ts @@ -0,0 +1,305 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest' + +vi.mock('pixelmatch', () => ({ + default: vi.fn() +})) + +vi.mock('jimp', () => { + const makeImageMock = (width = 100, height = 100) => ({ + bitmap: { + data: Buffer.alloc(width * height * 4, 128), + width, + height, + }, + resize: vi.fn(), + contain: vi.fn(), + getBuffer: vi.fn().mockResolvedValue(Buffer.from('png-data')), + }) + + const JimpMock = vi.fn().mockImplementation(() => makeImageMock()) as any + JimpMock.read = vi.fn().mockImplementation(() => Promise.resolve(makeImageMock())) + + return { + Jimp: JimpMock, + JimpMime: { png: 'image/png' }, + } +}) + +import compareImages from './compareImages.js' +import pixelmatch from 'pixelmatch' + +const pixelmatchFn = vi.mocked(pixelmatch) + +describe('pixelmatch adapter - compareImages', () => { + beforeEach(() => { + vi.clearAllMocks() + }) + + describe('basic comparison', () => { + it('returns zero mismatch percentage when images are identical', async () => { + pixelmatchFn.mockImplementation(() => 0) + + const result = await compareImages( + Buffer.from('img1'), + Buffer.from('img2'), + {} + ) + + expect(result.rawMisMatchPercentage).toBe(0) + expect(result.misMatchPercentage).toBe(0) + expect(result.diffPixels).toHaveLength(0) + }) + + it('returns correct mismatch percentage for a known diff count', async () => { + // 100x100 = 10000 total pixels, 100 diff pixels = 1% + pixelmatchFn.mockImplementation(() => 100) + + const result = await compareImages( + Buffer.from('img1'), + Buffer.from('img2'), + {} + ) + + expect(result.rawMisMatchPercentage).toBeCloseTo(1, 5) + expect(result.misMatchPercentage).toBe(1) + }) + + it('returns analysisTime greater than or equal to 0', async () => { + pixelmatchFn.mockImplementation(() => 0) + + const result = await compareImages(Buffer.from('img1'), Buffer.from('img2'), {}) + + expect(result.analysisTime).toBeGreaterThanOrEqual(0) + }) + + it('resolves getBuffer to a Buffer', async () => { + pixelmatchFn.mockImplementation(() => 0) + + const result = await compareImages(Buffer.from('img1'), Buffer.from('img2'), {}) + const buf = await result.getBuffer() + + expect(Buffer.isBuffer(buf)).toBe(true) + }) + }) + + describe('diffPixels and diffBounds', () => { + it('collects magenta pixels as diff pixel coordinates', async () => { + pixelmatchFn.mockImplementation((_img1, _img2, output: Uint8Array, width: number) => { + // Place a magenta pixel at x=5, y=3 (offset = (3*100 + 5) * 4 = 1220) + const pos = (3 * width + 5) * 4 + output[pos] = 255 + output[pos + 1] = 0 + output[pos + 2] = 255 + output[pos + 3] = 255 + return 1 + }) + + const result = await compareImages(Buffer.from('img1'), Buffer.from('img2'), {}) + + expect(result.diffPixels).toHaveLength(1) + expect(result.diffPixels[0]).toEqual({ x: 5, y: 3 }) + }) + + it('does not count grayscale matching pixels as diff pixels', async () => { + pixelmatchFn.mockImplementation((_img1, _img2, output: Uint8Array, width: number) => { + // Grayscale pixel (matching pixel rendered at low opacity) + const pos = (2 * width + 10) * 4 + output[pos] = 200 + output[pos + 1] = 200 + output[pos + 2] = 200 + output[pos + 3] = 255 + return 0 + }) + + const result = await compareImages(Buffer.from('img1'), Buffer.from('img2'), {}) + + expect(result.diffPixels).toHaveLength(0) + }) + + it('computes correct diffBounds from multiple diff pixels', async () => { + pixelmatchFn.mockImplementation((_img1, _img2, output: Uint8Array, width: number) => { + const mark = (x: number, y: number) => { + const pos = (y * width + x) * 4 + output[pos] = 255 + output[pos + 1] = 0 + output[pos + 2] = 255 + output[pos + 3] = 255 + } + mark(10, 5) + mark(30, 20) + mark(20, 10) + return 3 + }) + + const result = await compareImages(Buffer.from('img1'), Buffer.from('img2'), {}) + + expect(result.diffBounds).toEqual({ left: 10, top: 5, right: 30, bottom: 20 }) + }) + + it('returns sentinel diffBounds when there are no diff pixels', async () => { + pixelmatchFn.mockImplementation(() => 0) + + const result = await compareImages(Buffer.from('img1'), Buffer.from('img2'), {}) + + // Sentinel: left=width, top=height, right=0, bottom=0 + expect(result.diffBounds.left).toBeGreaterThan(result.diffBounds.right) + expect(result.diffBounds.top).toBeGreaterThan(result.diffBounds.bottom) + }) + }) + + describe('ignore option mapping', () => { + it('passes threshold=0 and includeAA=true for ignore: nothing', async () => { + pixelmatchFn.mockImplementation(() => 0) + + await compareImages(Buffer.from('img1'), Buffer.from('img2'), { ignore: 'nothing' }) + + expect(pixelmatchFn).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + expect.anything(), + expect.any(Number), + expect.any(Number), + expect.objectContaining({ threshold: 0, includeAA: true }) + ) + }) + + it('passes threshold=0.063 and includeAA=false for ignore: less', async () => { + pixelmatchFn.mockImplementation(() => 0) + + await compareImages(Buffer.from('img1'), Buffer.from('img2'), { ignore: 'less' }) + + expect(pixelmatchFn).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + expect.anything(), + expect.any(Number), + expect.any(Number), + expect.objectContaining({ threshold: 0.063, includeAA: false }) + ) + }) + + it('passes threshold=0.13 and includeAA=false for ignore: antialiasing', async () => { + pixelmatchFn.mockImplementation(() => 0) + + await compareImages(Buffer.from('img1'), Buffer.from('img2'), { ignore: 'antialiasing' }) + + expect(pixelmatchFn).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + expect.anything(), + expect.any(Number), + expect.any(Number), + expect.objectContaining({ threshold: 0.13, includeAA: false }) + ) + }) + + it('passes threshold=0.13 and includeAA=false when no ignore option is given', async () => { + pixelmatchFn.mockImplementation(() => 0) + + await compareImages(Buffer.from('img1'), Buffer.from('img2'), {}) + + expect(pixelmatchFn).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + expect.anything(), + expect.any(Number), + expect.any(Number), + expect.objectContaining({ threshold: 0.13, includeAA: false }) + ) + }) + + it('accepts ignore as an array and uses the highest-priority mode', async () => { + pixelmatchFn.mockImplementation(() => 0) + + await compareImages(Buffer.from('img1'), Buffer.from('img2'), { + ignore: ['antialiasing', 'less'] + }) + + // 'less' wins over 'antialiasing' in the priority check + expect(pixelmatchFn).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + expect.anything(), + expect.any(Number), + expect.any(Number), + expect.objectContaining({ threshold: 0.063 }) + ) + }) + }) + + describe('ignoredBoxes', () => { + it('zeroes out the specified box regions in both pixel arrays before comparison', async () => { + let capturedImg1: Uint8Array | undefined + let capturedImg2: Uint8Array | undefined + + pixelmatchFn.mockImplementation((img1: Uint8Array, img2: Uint8Array) => { + capturedImg1 = new Uint8Array(img1) + capturedImg2 = new Uint8Array(img2) + return 0 + }) + + await compareImages(Buffer.from('img1'), Buffer.from('img2'), { + output: { + ignoredBoxes: [{ left: 0, top: 0, right: 0, bottom: 0 }] + } + }) + + // Pixel at (0,0) should be zeroed in both arrays + expect(capturedImg1![0]).toBe(0) + expect(capturedImg1![1]).toBe(0) + expect(capturedImg1![2]).toBe(0) + expect(capturedImg1![3]).toBe(0) + expect(capturedImg2![0]).toBe(0) + }) + }) + + describe('scaleToSameSize', () => { + it('calls resize on the smaller image when scaleToSameSize is true and images differ in size', async () => { + const jimp = await import('jimp') + const smallImage = { + bitmap: { data: Buffer.alloc(50 * 50 * 4, 0), width: 50, height: 50 }, + resize: vi.fn(), + contain: vi.fn(), + getBuffer: vi.fn().mockResolvedValue(Buffer.from('png')), + } + const largeImage = { + bitmap: { data: Buffer.alloc(100 * 100 * 4, 0), width: 100, height: 100 }, + resize: vi.fn(), + contain: vi.fn(), + getBuffer: vi.fn().mockResolvedValue(Buffer.from('png')), + } + + vi.mocked(jimp.Jimp.read) + .mockResolvedValueOnce(largeImage as any) + .mockResolvedValueOnce(smallImage as any) + + pixelmatchFn.mockImplementation(() => 0) + + await compareImages(Buffer.from('img1'), Buffer.from('img2'), { + scaleToSameSize: true + }) + + expect(smallImage.resize).toHaveBeenCalledWith({ w: 100, h: 100 }) + expect(largeImage.resize).not.toHaveBeenCalled() + }) + + it('does not call resize when scaleToSameSize is false', async () => { + const jimp = await import('jimp') + const img = { + bitmap: { data: Buffer.alloc(100 * 100 * 4, 0), width: 100, height: 100 }, + resize: vi.fn(), + contain: vi.fn(), + getBuffer: vi.fn().mockResolvedValue(Buffer.from('png')), + } + + vi.mocked(jimp.Jimp.read).mockResolvedValue(img as any) + pixelmatchFn.mockImplementation(() => 0) + + await compareImages(Buffer.from('img1'), Buffer.from('img2'), { + scaleToSameSize: false + }) + + expect(img.resize).not.toHaveBeenCalled() + }) + }) +}) diff --git a/packages/image-comparison-core/src/pixelmatch/compareImages.ts b/packages/image-comparison-core/src/pixelmatch/compareImages.ts new file mode 100644 index 000000000..1fd742903 --- /dev/null +++ b/packages/image-comparison-core/src/pixelmatch/compareImages.ts @@ -0,0 +1,179 @@ +import pixelmatch from 'pixelmatch' +import { Jimp, JimpMime } from 'jimp' +import type { CompareData, ComparisonOptions, ComparisonIgnoreOption } from '../resemble/compare.interfaces.js' + +function resolveIgnoreList(ignore: ComparisonOptions['ignore']): ComparisonIgnoreOption[] { + if (!ignore) { + return [] + } + + return Array.isArray(ignore) ? ignore : [ignore] +} + +function toPixelmatchOptions(ignoreList: ComparisonIgnoreOption[]): { threshold: number; includeAA: boolean } { + if (ignoreList.includes('nothing')) { + return { threshold: 0, includeAA: true } + } + if (ignoreList.includes('less')) { + // 16/255 per channel in resemble maps roughly to ~6.3% of max YIQ distance + return { threshold: 0.063, includeAA: false } + } + // 'antialiasing', 'alpha', 'colors' and the default. + // Resemble's ignoreAntialiasing uses 32/255 per-channel tolerance which + // corresponds to ~0.13 in YIQ perceptual distance. Using 0.1 is stricter + // and causes invisible sub-pixel differences to register as failures. + return { threshold: 0.13, includeAA: false } +} + +function grayscalePixels(pixels: Buffer, totalPixels: number): void { + for (let i = 0; i < totalPixels * 4; i += 4) { + const luma = Math.round(0.299 * pixels[i] + 0.587 * pixels[i + 1] + 0.114 * pixels[i + 2]) + pixels[i] = luma + pixels[i + 1] = luma + pixels[i + 2] = luma + } +} + +function opaqueAlphaChannel(pixels: Buffer, totalPixels: number): void { + for (let i = 3; i < totalPixels * 4; i += 4) { + pixels[i] = 255 + } +} + +// Pad a raw RGBA pixel buffer to a larger canvas size, placing the source at +// position (0, 0) and filling the remaining area with opaque white. +// This matches resemble's normalise() intent without using Jimp's contain() +// which centers the image and shifts content by a pixel. +function padToSize(src: Buffer, srcW: number, srcH: number, dstW: number, dstH: number): Buffer { + const dst = Buffer.alloc(dstW * dstH * 4, 255) // opaque white + for (let y = 0; y < srcH; y++) { + src.copy(dst, y * dstW * 4, y * srcW * 4, (y + 1) * srcW * 4) + } + return dst +} + +function zeroIgnoredBoxes( + pixels: Buffer, + width: number, + boxes: Array<{ left: number; top: number; right: number; bottom: number }> +): void { + for (const box of boxes) { + for (let y = box.top; y <= box.bottom; y++) { + for (let x = box.left; x <= box.right; x++) { + const offset = (y * width + x) * 4 + pixels[offset] = 0 + pixels[offset + 1] = 0 + pixels[offset + 2] = 0 + pixels[offset + 3] = 0 + } + } + } +} + +export default async function compareImages( + image1: Buffer, + image2: Buffer, + options: ComparisonOptions +): Promise { + const start = Date.now() + + const img1 = await Jimp.read(image1) + const img2 = await Jimp.read(image2) + + if (options.scaleToSameSize) { + const size1 = img1.bitmap.width * img1.bitmap.height + const size2 = img2.bitmap.width * img2.bitmap.height + if (size1 > size2) { + img2.resize({ w: img1.bitmap.width, h: img1.bitmap.height }) + } else if (size2 > size1) { + img1.resize({ w: img2.bitmap.width, h: img2.bitmap.height }) + } + } + + // Determine the target canvas size (max of both dimensions). + const width = Math.max(img1.bitmap.width, img2.bitmap.width) + const height = Math.max(img1.bitmap.height, img2.bitmap.height) + const totalPixels = width * height + + // Copy bitmap data into mutable buffers, padding at (0,0) when sizes differ. + // Using padToSize instead of Jimp's contain() avoids centering which shifts + // content by a pixel and creates false diffs along the top edge. + const pixels1 = img1.bitmap.width === width && img1.bitmap.height === height + ? Buffer.from(img1.bitmap.data) + : padToSize(Buffer.from(img1.bitmap.data), img1.bitmap.width, img1.bitmap.height, width, height) + const pixels2 = img2.bitmap.width === width && img2.bitmap.height === height + ? Buffer.from(img2.bitmap.data) + : padToSize(Buffer.from(img2.bitmap.data), img2.bitmap.width, img2.bitmap.height, width, height) + + const ignoreList = resolveIgnoreList(options.ignore) + + if (ignoreList.includes('colors')) { + grayscalePixels(pixels1, totalPixels) + grayscalePixels(pixels2, totalPixels) + } + + if (ignoreList.includes('alpha')) { + opaqueAlphaChannel(pixels1, totalPixels) + opaqueAlphaChannel(pixels2, totalPixels) + } + + const ignoredBoxes = options.output?.ignoredBoxes ?? [] + if (ignoredBoxes.length > 0) { + zeroIgnoredBoxes(pixels1, width, ignoredBoxes) + zeroIgnoredBoxes(pixels2, width, ignoredBoxes) + } + + const { threshold, includeAA } = toPixelmatchOptions(ignoreList) + const outputPixels = new Uint8Array(totalPixels * 4) + + // Use resemble's magenta [255, 0, 255] for both diff and AA pixels so the + // diff image output is visually consistent with the resemble engine. + const diffCount: number = pixelmatch(pixels1, pixels2, outputPixels, width, height, { + threshold, + includeAA, + diffColor: [255, 0, 255], + aaColor: [255, 0, 255], + }) + + // Collect diff pixel coordinates from the output buffer. + // Both diff and AA pixels are drawn in magenta [255, 0, 255]; grayscale pixels are matches. + const diffPixels: Array<{ x: number; y: number }> = [] + let left = width + let top = height + let right = 0 + let bottom = 0 + + for (let i = 0; i < outputPixels.length; i += 4) { + if (outputPixels[i] === 255 && outputPixels[i + 1] === 0 && outputPixels[i + 2] === 255) { + const pixelIndex = i / 4 + const x = pixelIndex % width + const y = Math.floor(pixelIndex / width) + diffPixels.push({ x, y }) + if (x < left) { left = x } + if (x > right) { right = x } + if (y < top) { top = y } + if (y > bottom) { bottom = y } + } + } + + const diffBounds = diffPixels.length > 0 + ? { left, top, right, bottom } + : { left: width, top: height, right: 0, bottom: 0 } + + const getBuffer = async (): Promise => { + const diffImage = new Jimp({ width, height }) + Buffer.from(outputPixels).copy(diffImage.bitmap.data) + return diffImage.getBuffer(JimpMime.png) + } + + const rawMisMatchPercentage = (diffCount / totalPixels) * 100 + + return { + rawMisMatchPercentage, + misMatchPercentage: Number(rawMisMatchPercentage.toFixed(2)), + getBuffer, + diffBounds, + analysisTime: Date.now() - start, + diffPixels, + } +} diff --git a/packages/image-comparison-core/src/resemble/compare.interfaces.ts b/packages/image-comparison-core/src/resemble/compare.interfaces.ts index 54cc72bdb..3b4cca17c 100644 --- a/packages/image-comparison-core/src/resemble/compare.interfaces.ts +++ b/packages/image-comparison-core/src/resemble/compare.interfaces.ts @@ -6,7 +6,7 @@ export interface CompareData { /** The mismatch percentage like 0.12 */ misMatchPercentage: number; /** The image buffer */ - getBuffer: () => Buffer; + getBuffer: () => Promise; /** The bounds of the diff area */ diffBounds: BaseBoundingBox; /** The analysis time in milliseconds */ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3ba125cba..cd36116be 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -134,6 +134,9 @@ importers: jimp: specifier: ^1.6.1 version: 1.6.1 + pixelmatch: + specifier: ^7.2.0 + version: 7.2.0 devDependencies: webdriverio: specifier: ^9.27.0 @@ -5862,6 +5865,10 @@ packages: resolution: {integrity: sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==} hasBin: true + pixelmatch@7.2.0: + resolution: {integrity: sha512-xhcb4yHu9sM/G7foGzoLtXYcC0zHEaOXXjRKhGup0fw78Nf2Tkiapv4EQyMzrbcmQPsllAI7DbFY2UT7PlI9Pg==} + hasBin: true + pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} @@ -14260,6 +14267,10 @@ snapshots: dependencies: pngjs: 6.0.0 + pixelmatch@7.2.0: + dependencies: + pngjs: 7.0.0 + pkg-types@1.3.1: dependencies: confbox: 0.1.8 diff --git a/tests/configs/sauce.android.emus.app.ts b/tests/configs/sauce.android.emus.app.ts index 2de8f3d06..58c058e89 100644 --- a/tests/configs/sauce.android.emus.app.ts +++ b/tests/configs/sauce.android.emus.app.ts @@ -8,11 +8,10 @@ export function sauceAndroidEmusApp({ buildName }: { buildName: string }) { ) .map((orientation) => [ - { deviceName:'Google Pixel 4 XL GoogleAPI Emulator', platformVersion:'11.0' }, - { deviceName:'Google Pixel 4 XL GoogleAPI Emulator', platformVersion:'12.0' }, - { deviceName:'Google Pixel 4 XL GoogleAPI Emulator', platformVersion:'13.0' }, - { deviceName:'Google Pixel 4 XL GoogleAPI Emulator', platformVersion:'14.0' }, - { deviceName:'Google Pixel 4 XL GoogleAPI Emulator', platformVersion:'15.0' }, + // @TODO: new list + { deviceName:'Google Pixel 8a Emulator', platformVersion:'14.0' }, + { deviceName:'Google Pixel 8a Emulator', platformVersion:'15.0' }, + { deviceName:'Google Pixel 8a Emulator', platformVersion:'16.0' }, ].map( (cap) => createCaps({ @@ -22,7 +21,8 @@ export function sauceAndroidEmusApp({ buildName }: { buildName: string }) { mobileSpecs, sauceOptions: { build: buildName, - deviceOrientation: orientation + deviceOrientation: orientation, + appiumVersion: '2.11.0', }, }) ) diff --git a/tests/lambdaTestBaseline/desktop_safari/fullPage-SafariLatest-1366x768.png b/tests/lambdaTestBaseline/desktop_safari/fullPage-SafariLatest-1366x768.png index 969b7b077..a7e949535 100644 Binary files a/tests/lambdaTestBaseline/desktop_safari/fullPage-SafariLatest-1366x768.png and b/tests/lambdaTestBaseline/desktop_safari/fullPage-SafariLatest-1366x768.png differ diff --git a/tests/lambdaTestBaseline/desktop_safari/tabbable-SafariLatest-1366x768.png b/tests/lambdaTestBaseline/desktop_safari/tabbable-SafariLatest-1366x768.png index bc0b87c67..26307e783 100644 Binary files a/tests/lambdaTestBaseline/desktop_safari/tabbable-SafariLatest-1366x768.png and b/tests/lambdaTestBaseline/desktop_safari/tabbable-SafariLatest-1366x768.png differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x2872.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x2872.png deleted file mode 100644 index e0a97bf87..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x2872.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x3040.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x3040.png deleted file mode 100644 index 7c309293c..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x3040.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x2872.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x2872.png deleted file mode 100644 index 7e4a687a5..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x2872.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x3040.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x3040.png deleted file mode 100644 index 97e9a11c5..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x3040.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x2956.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x2956.png deleted file mode 100644 index c03fbc82c..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x2956.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x3040.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x3040.png deleted file mode 100644 index dbf199796..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x3040.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x2956.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x2956.png deleted file mode 100644 index 8aa5612d3..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x2956.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x3040.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x3040.png deleted file mode 100644 index 3f234085f..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x3040.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait15.0-1440x3040.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait15.0-1440x3040.png deleted file mode 100644 index 94a3d4001..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-forms-app-EmulatorGooglePixel4XLGoogleAPIPortrait15.0-1440x3040.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x2872.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x2872.png deleted file mode 100644 index 70db4afb4..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x2872.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x3040.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x3040.png deleted file mode 100644 index 9007254ee..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x3040.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x2872.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x2872.png deleted file mode 100644 index 2284da332..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x2872.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x3040.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x3040.png deleted file mode 100644 index 9007254ee..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x3040.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x2956.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x2956.png deleted file mode 100644 index 52a6ba5e7..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x2956.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x3040.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x3040.png deleted file mode 100644 index 8b7c0432d..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x3040.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x2956.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x2956.png deleted file mode 100644 index 8ccd204ff..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x2956.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x3040.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x3040.png deleted file mode 100644 index 57aa24327..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x3040.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait15.0-1440x3040.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait15.0-1440x3040.png deleted file mode 100644 index 8ccd204ff..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-app-EmulatorGooglePixel4XLGoogleAPIPortrait15.0-1440x3040.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x2872.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x2872.png deleted file mode 100644 index 32877b795..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x2872.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x3040.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x3040.png deleted file mode 100644 index c0f3275d7..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait11.0-1440x3040.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x2872.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x2872.png deleted file mode 100644 index 32877b795..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x2872.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x3040.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x3040.png deleted file mode 100644 index c0f3275d7..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait12.0-1440x3040.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x2956.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x2956.png deleted file mode 100644 index 74eccdbeb..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x2956.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x3040.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x3040.png deleted file mode 100644 index 9826f49ce..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-1440x3040.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x2956.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x2956.png deleted file mode 100644 index f705e1936..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x2956.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x3040.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x3040.png deleted file mode 100644 index af2b17e58..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-1440x3040.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait15.0-1440x3040.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait15.0-1440x3040.png deleted file mode 100644 index f705e1936..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/app-login-button-resized-app-EmulatorGooglePixel4XLGoogleAPIPortrait15.0-1440x3040.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/web-app-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-412x869.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/web-app-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-412x869.png deleted file mode 100644 index bb4478407..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/web-app-app-EmulatorGooglePixel4XLGoogleAPIPortrait13.0-412x869.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/web-app-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-412x869.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/web-app-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-412x869.png deleted file mode 100644 index 454749a47..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/web-app-app-EmulatorGooglePixel4XLGoogleAPIPortrait14.0-412x869.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/web-app-app-EmulatorGooglePixel4XLGoogleAPIPortrait15.0-412x869.png b/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/web-app-app-EmulatorGooglePixel4XLGoogleAPIPortrait15.0-412x869.png deleted file mode 100644 index 8066ffc2c..000000000 Binary files a/tests/sauceLabsBaseline/google_pixel_4_xl_googleapi_emulator/web-app-app-EmulatorGooglePixel4XLGoogleAPIPortrait15.0-412x869.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-forms-app-EmulatorGooglePixel8aPortrait14.0-1080x2400.png b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-forms-app-EmulatorGooglePixel8aPortrait14.0-1080x2400.png new file mode 100644 index 000000000..154ff8af6 Binary files /dev/null and b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-forms-app-EmulatorGooglePixel8aPortrait14.0-1080x2400.png differ diff --git a/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-forms-app-EmulatorGooglePixel8aPortrait15.0-1080x2400.png b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-forms-app-EmulatorGooglePixel8aPortrait15.0-1080x2400.png new file mode 100644 index 000000000..c70ad1851 Binary files /dev/null and b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-forms-app-EmulatorGooglePixel8aPortrait15.0-1080x2400.png differ diff --git a/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-forms-app-EmulatorGooglePixel8aPortrait16.0-1080x2400.png b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-forms-app-EmulatorGooglePixel8aPortrait16.0-1080x2400.png new file mode 100644 index 000000000..1b1b0ff6c Binary files /dev/null and b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-forms-app-EmulatorGooglePixel8aPortrait16.0-1080x2400.png differ diff --git a/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-app-EmulatorGooglePixel8aPortrait14.0-1080x2400.png b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-app-EmulatorGooglePixel8aPortrait14.0-1080x2400.png new file mode 100644 index 000000000..826c1f35e Binary files /dev/null and b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-app-EmulatorGooglePixel8aPortrait14.0-1080x2400.png differ diff --git a/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-app-EmulatorGooglePixel8aPortrait15.0-1080x2400.png b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-app-EmulatorGooglePixel8aPortrait15.0-1080x2400.png new file mode 100644 index 000000000..826c1f35e Binary files /dev/null and b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-app-EmulatorGooglePixel8aPortrait15.0-1080x2400.png differ diff --git a/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-app-EmulatorGooglePixel8aPortrait16.0-1080x2400.png b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-app-EmulatorGooglePixel8aPortrait16.0-1080x2400.png new file mode 100644 index 000000000..826c1f35e Binary files /dev/null and b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-app-EmulatorGooglePixel8aPortrait16.0-1080x2400.png differ diff --git a/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-resized-app-EmulatorGooglePixel8aPortrait14.0-1080x2400.png b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-resized-app-EmulatorGooglePixel8aPortrait14.0-1080x2400.png new file mode 100644 index 000000000..1bd217ff3 Binary files /dev/null and b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-resized-app-EmulatorGooglePixel8aPortrait14.0-1080x2400.png differ diff --git a/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-resized-app-EmulatorGooglePixel8aPortrait15.0-1080x2400.png b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-resized-app-EmulatorGooglePixel8aPortrait15.0-1080x2400.png new file mode 100644 index 000000000..1bd217ff3 Binary files /dev/null and b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-resized-app-EmulatorGooglePixel8aPortrait15.0-1080x2400.png differ diff --git a/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-resized-app-EmulatorGooglePixel8aPortrait16.0-1080x2400.png b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-resized-app-EmulatorGooglePixel8aPortrait16.0-1080x2400.png new file mode 100644 index 000000000..1bd217ff3 Binary files /dev/null and b/tests/sauceLabsBaseline/google_pixel_8a_emulator/app-login-button-resized-app-EmulatorGooglePixel8aPortrait16.0-1080x2400.png differ diff --git a/tests/sauceLabsBaseline/google_pixel_8a_emulator/web-app-app-EmulatorGooglePixel8aPortrait14.0-412x915.png b/tests/sauceLabsBaseline/google_pixel_8a_emulator/web-app-app-EmulatorGooglePixel8aPortrait14.0-412x915.png new file mode 100644 index 000000000..f90812bfa Binary files /dev/null and b/tests/sauceLabsBaseline/google_pixel_8a_emulator/web-app-app-EmulatorGooglePixel8aPortrait14.0-412x915.png differ diff --git a/tests/sauceLabsBaseline/google_pixel_8a_emulator/web-app-app-EmulatorGooglePixel8aPortrait15.0-412x915.png b/tests/sauceLabsBaseline/google_pixel_8a_emulator/web-app-app-EmulatorGooglePixel8aPortrait15.0-412x915.png new file mode 100644 index 000000000..a80d12704 Binary files /dev/null and b/tests/sauceLabsBaseline/google_pixel_8a_emulator/web-app-app-EmulatorGooglePixel8aPortrait15.0-412x915.png differ diff --git a/tests/sauceLabsBaseline/google_pixel_8a_emulator/web-app-app-EmulatorGooglePixel8aPortrait16.0-412x915.png b/tests/sauceLabsBaseline/google_pixel_8a_emulator/web-app-app-EmulatorGooglePixel8aPortrait16.0-412x915.png new file mode 100644 index 000000000..9485658b5 Binary files /dev/null and b/tests/sauceLabsBaseline/google_pixel_8a_emulator/web-app-app-EmulatorGooglePixel8aPortrait16.0-412x915.png differ diff --git a/tests/sauceLabsBaseline/iphone_11_simulator/app-forms-app-Iphone11Portrait15-414x896.png b/tests/sauceLabsBaseline/iphone_11_simulator/app-forms-app-Iphone11Portrait15-414x896.png deleted file mode 100644 index 85372b065..000000000 Binary files a/tests/sauceLabsBaseline/iphone_11_simulator/app-forms-app-Iphone11Portrait15-414x896.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_11_simulator/app-login-button-app-Iphone11Portrait15-414x896.png b/tests/sauceLabsBaseline/iphone_11_simulator/app-login-button-app-Iphone11Portrait15-414x896.png deleted file mode 100644 index 3ebaf62b7..000000000 Binary files a/tests/sauceLabsBaseline/iphone_11_simulator/app-login-button-app-Iphone11Portrait15-414x896.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_11_simulator/app-login-button-resized-app-Iphone11Portrait15-414x896.png b/tests/sauceLabsBaseline/iphone_11_simulator/app-login-button-resized-app-Iphone11Portrait15-414x896.png deleted file mode 100644 index fa740c624..000000000 Binary files a/tests/sauceLabsBaseline/iphone_11_simulator/app-login-button-resized-app-Iphone11Portrait15-414x896.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_11_simulator/web-app-app-Iphone11Portrait15-414x896.png b/tests/sauceLabsBaseline/iphone_11_simulator/web-app-app-Iphone11Portrait15-414x896.png deleted file mode 100644 index cf3c6c218..000000000 Binary files a/tests/sauceLabsBaseline/iphone_11_simulator/web-app-app-Iphone11Portrait15-414x896.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_12_pro_max_simulator/app-forms-app-Iphone12ProMaxPortrait16-428x926.png b/tests/sauceLabsBaseline/iphone_12_pro_max_simulator/app-forms-app-Iphone12ProMaxPortrait16-428x926.png deleted file mode 100644 index a1845bc0e..000000000 Binary files a/tests/sauceLabsBaseline/iphone_12_pro_max_simulator/app-forms-app-Iphone12ProMaxPortrait16-428x926.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_12_pro_max_simulator/app-login-button-app-Iphone12ProMaxPortrait16-428x926.png b/tests/sauceLabsBaseline/iphone_12_pro_max_simulator/app-login-button-app-Iphone12ProMaxPortrait16-428x926.png deleted file mode 100644 index 923839fac..000000000 Binary files a/tests/sauceLabsBaseline/iphone_12_pro_max_simulator/app-login-button-app-Iphone12ProMaxPortrait16-428x926.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_12_pro_max_simulator/app-login-button-resized-app-Iphone12ProMaxPortrait16-428x926.png b/tests/sauceLabsBaseline/iphone_12_pro_max_simulator/app-login-button-resized-app-Iphone12ProMaxPortrait16-428x926.png deleted file mode 100644 index 7d2dd8f76..000000000 Binary files a/tests/sauceLabsBaseline/iphone_12_pro_max_simulator/app-login-button-resized-app-Iphone12ProMaxPortrait16-428x926.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_12_pro_max_simulator/web-app-app-Iphone12ProMaxPortrait16-428x926.png b/tests/sauceLabsBaseline/iphone_12_pro_max_simulator/web-app-app-Iphone12ProMaxPortrait16-428x926.png deleted file mode 100644 index 25134bc99..000000000 Binary files a/tests/sauceLabsBaseline/iphone_12_pro_max_simulator/web-app-app-Iphone12ProMaxPortrait16-428x926.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_12_simulator/app-forms-app-Iphone12Portrait16-390x844.png b/tests/sauceLabsBaseline/iphone_12_simulator/app-forms-app-Iphone12Portrait16-390x844.png deleted file mode 100644 index 66fc33f35..000000000 Binary files a/tests/sauceLabsBaseline/iphone_12_simulator/app-forms-app-Iphone12Portrait16-390x844.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_12_simulator/app-login-button-app-Iphone12Portrait16-390x844.png b/tests/sauceLabsBaseline/iphone_12_simulator/app-login-button-app-Iphone12Portrait16-390x844.png deleted file mode 100644 index 923839fac..000000000 Binary files a/tests/sauceLabsBaseline/iphone_12_simulator/app-login-button-app-Iphone12Portrait16-390x844.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_12_simulator/app-login-button-resized-app-Iphone12Portrait16-390x844.png b/tests/sauceLabsBaseline/iphone_12_simulator/app-login-button-resized-app-Iphone12Portrait16-390x844.png deleted file mode 100644 index 7d2dd8f76..000000000 Binary files a/tests/sauceLabsBaseline/iphone_12_simulator/app-login-button-resized-app-Iphone12Portrait16-390x844.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_12_simulator/web-app-app-Iphone12Portrait16-390x844.png b/tests/sauceLabsBaseline/iphone_12_simulator/web-app-app-Iphone12Portrait16-390x844.png deleted file mode 100644 index b6001fdd6..000000000 Binary files a/tests/sauceLabsBaseline/iphone_12_simulator/web-app-app-Iphone12Portrait16-390x844.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_8_plus_simulator/app-forms-app-Iphone8PlusPortrait14-414x736.png b/tests/sauceLabsBaseline/iphone_8_plus_simulator/app-forms-app-Iphone8PlusPortrait14-414x736.png deleted file mode 100644 index 9545034ec..000000000 Binary files a/tests/sauceLabsBaseline/iphone_8_plus_simulator/app-forms-app-Iphone8PlusPortrait14-414x736.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_8_plus_simulator/app-login-button-app-Iphone8PlusPortrait14-414x736.png b/tests/sauceLabsBaseline/iphone_8_plus_simulator/app-login-button-app-Iphone8PlusPortrait14-414x736.png deleted file mode 100644 index 923839fac..000000000 Binary files a/tests/sauceLabsBaseline/iphone_8_plus_simulator/app-login-button-app-Iphone8PlusPortrait14-414x736.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_8_plus_simulator/app-login-button-resized-app-Iphone8PlusPortrait14-414x736.png b/tests/sauceLabsBaseline/iphone_8_plus_simulator/app-login-button-resized-app-Iphone8PlusPortrait14-414x736.png deleted file mode 100644 index 7d2dd8f76..000000000 Binary files a/tests/sauceLabsBaseline/iphone_8_plus_simulator/app-login-button-resized-app-Iphone8PlusPortrait14-414x736.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_8_plus_simulator/web-app-app-Iphone8PlusPortrait14-414x736.png b/tests/sauceLabsBaseline/iphone_8_plus_simulator/web-app-app-Iphone8PlusPortrait14-414x736.png deleted file mode 100644 index 36a5cbbe4..000000000 Binary files a/tests/sauceLabsBaseline/iphone_8_plus_simulator/web-app-app-Iphone8PlusPortrait14-414x736.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_8_simulator/app-forms-app-Iphone8Portrait14-375x667.png b/tests/sauceLabsBaseline/iphone_8_simulator/app-forms-app-Iphone8Portrait14-375x667.png deleted file mode 100644 index 06343832e..000000000 Binary files a/tests/sauceLabsBaseline/iphone_8_simulator/app-forms-app-Iphone8Portrait14-375x667.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_8_simulator/app-login-button-app-Iphone8Portrait14-375x667.png b/tests/sauceLabsBaseline/iphone_8_simulator/app-login-button-app-Iphone8Portrait14-375x667.png deleted file mode 100644 index 3ebaf62b7..000000000 Binary files a/tests/sauceLabsBaseline/iphone_8_simulator/app-login-button-app-Iphone8Portrait14-375x667.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_8_simulator/app-login-button-resized-app-Iphone8Portrait14-375x667.png b/tests/sauceLabsBaseline/iphone_8_simulator/app-login-button-resized-app-Iphone8Portrait14-375x667.png deleted file mode 100644 index a558fe9f0..000000000 Binary files a/tests/sauceLabsBaseline/iphone_8_simulator/app-login-button-resized-app-Iphone8Portrait14-375x667.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_8_simulator/web-app-app-Iphone8Portrait14-375x667.png b/tests/sauceLabsBaseline/iphone_8_simulator/web-app-app-Iphone8Portrait14-375x667.png deleted file mode 100644 index 4ada6c029..000000000 Binary files a/tests/sauceLabsBaseline/iphone_8_simulator/web-app-app-Iphone8Portrait14-375x667.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_xs_simulator/app-forms-app-IphoneXsPortrait15-375x812.png b/tests/sauceLabsBaseline/iphone_xs_simulator/app-forms-app-IphoneXsPortrait15-375x812.png deleted file mode 100644 index 3c3c8c7a1..000000000 Binary files a/tests/sauceLabsBaseline/iphone_xs_simulator/app-forms-app-IphoneXsPortrait15-375x812.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_xs_simulator/app-login-button-app-IphoneXsPortrait15-375x812.png b/tests/sauceLabsBaseline/iphone_xs_simulator/app-login-button-app-IphoneXsPortrait15-375x812.png deleted file mode 100644 index 32c6e34a9..000000000 Binary files a/tests/sauceLabsBaseline/iphone_xs_simulator/app-login-button-app-IphoneXsPortrait15-375x812.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_xs_simulator/app-login-button-resized-app-IphoneXsPortrait15-375x812.png b/tests/sauceLabsBaseline/iphone_xs_simulator/app-login-button-resized-app-IphoneXsPortrait15-375x812.png deleted file mode 100644 index f87727c65..000000000 Binary files a/tests/sauceLabsBaseline/iphone_xs_simulator/app-login-button-resized-app-IphoneXsPortrait15-375x812.png and /dev/null differ diff --git a/tests/sauceLabsBaseline/iphone_xs_simulator/web-app-app-IphoneXsPortrait15-375x812.png b/tests/sauceLabsBaseline/iphone_xs_simulator/web-app-app-IphoneXsPortrait15-375x812.png deleted file mode 100644 index d967f8375..000000000 Binary files a/tests/sauceLabsBaseline/iphone_xs_simulator/web-app-app-IphoneXsPortrait15-375x812.png and /dev/null differ diff --git a/tests/specs/desktop.bidi.emulated.spec.ts b/tests/specs/desktop.bidi.emulated.spec.ts index 51aaa6d07..3da809f57 100644 --- a/tests/specs/desktop.bidi.emulated.spec.ts +++ b/tests/specs/desktop.bidi.emulated.spec.ts @@ -40,7 +40,7 @@ describe('@wdio/visual-service desktop bidi emulated', () => { ], // Some padding to make sure that we cover the element, // with BiDi we sometimes miss the element due to internal calculations - ignoreRegionPadding: 2, + ignoreRegionPadding: 4, // Don't comment this out, it's needed to hide the navbar hideElements: [await $('nav.navbar')] }