@applitools/screenshoter
Advanced tools
Comparing version 3.1.0 to 3.2.0
@@ -7,6 +7,6 @@ { | ||
"version": "file:../dry-run.tgz", | ||
"integrity": "sha512-FDyK0CsvbGvDngoG0ZWcaoBwko0y1SsQKnJrGzsgsw6baI/yYlA2z7V8NdhOhS+js2sQ8YblsMWd+oTj5ZPFZQ==", | ||
"integrity": "sha512-bvdZsaxQAxKmnJ8gZFCXKrDZbgDLTokO34q5EpO8fr/r2uyg7BilM6AcbrtOqOn1jNfzJxkEgUdWlfawp7wt9Q==", | ||
"requires": { | ||
"@applitools/snippets": "2.1.4", | ||
"@applitools/utils": "1.2.1", | ||
"@applitools/utils": "1.2.2", | ||
"png-async": "0.9.4" | ||
@@ -21,5 +21,5 @@ } | ||
"@applitools/utils": { | ||
"version": "1.2.1", | ||
"resolved": "https://registry.npmjs.org/@applitools/utils/-/utils-1.2.1.tgz", | ||
"integrity": "sha512-lIHYqgirhkyL+xAc9+FwidAvcI7apB/6Y7uyVimHdTRjjIwAqoazymwYiFZiia+q81F/smPLvMw2RUwU6wi13w==" | ||
"version": "1.2.2", | ||
"resolved": "https://registry.npmjs.org/@applitools/utils/-/utils-1.2.2.tgz", | ||
"integrity": "sha512-SyHY41J+hkZR9gma/M8gjbJXLXeLoVS5DQVYd/RinzWAq62Yvg9eA97+8oHDl8s+6ELK6wMcs4yajjqCPdpF0A==" | ||
}, | ||
@@ -26,0 +26,0 @@ "png-async": { |
@@ -7,2 +7,7 @@ | ||
## 3.2.0 - 2021/8/7 | ||
- change image processing order and improve general algorithm | ||
- updated to @applitools/utils@1.2.2 (from 1.2.1) | ||
## 3.1.0 - 2021/8/4 | ||
@@ -9,0 +14,0 @@ |
{ | ||
"name": "@applitools/screenshoter", | ||
"version": "3.1.0", | ||
"version": "3.2.0", | ||
"description": "Applitools universal screenshoter for web and native applications", | ||
@@ -52,7 +52,7 @@ "keywords": [ | ||
"@applitools/snippets": "2.1.4", | ||
"@applitools/utils": "1.2.1", | ||
"@applitools/utils": "1.2.2", | ||
"png-async": "0.9.4" | ||
}, | ||
"devDependencies": { | ||
"@applitools/driver": "1.1.0", | ||
"@applitools/driver": "1.1.1", | ||
"@applitools/sdk-release-kit": "0.13.0", | ||
@@ -59,0 +59,0 @@ "eslint": "^7.9.0", |
188
src/image.js
@@ -9,2 +9,4 @@ const fs = require('fs') | ||
let image, size | ||
let transforms = {rotate: 0, scale: 1, crop: null} | ||
if (utils.types.isBase64(data)) { | ||
@@ -22,4 +24,5 @@ const buffer = Buffer.from(data, 'base64') | ||
} else if (data.isImage) { | ||
image = data.toObject() | ||
image = data.toRaw() | ||
size = data.size | ||
transforms = data.transforms | ||
} else if (utils.types.has(data, ['width', 'height'])) { | ||
@@ -32,2 +35,6 @@ image = fromSize(data) | ||
if (!transforms.crop) { | ||
transforms.crop = utils.geometry.region({x: 0, y: 0}, size) | ||
} | ||
return { | ||
@@ -38,51 +45,74 @@ get isImage() { | ||
get size() { | ||
return image.width && image.height ? {width: image.width, height: image.height} : size | ||
return {...utils.geometry.scale(size, transforms.scale)} | ||
}, | ||
get transforms() { | ||
return {...transforms} | ||
}, | ||
get width() { | ||
return image.width || size.width | ||
return size.width | ||
}, | ||
get height() { | ||
return image.height || size.height | ||
return size.height | ||
}, | ||
async scale(scaleRatio) { | ||
image = await scale(await image, scaleRatio) | ||
scale(ratio) { | ||
transforms.scale *= ratio | ||
return this | ||
}, | ||
async crop(region) { | ||
image = await extract(await image, region) | ||
crop(region) { | ||
if (utils.types.has(region, ['left', 'right', 'top', 'bottom'])) { | ||
region = { | ||
x: region.left / transforms.scale, | ||
y: region.top / transforms.scale, | ||
width: image.width - (region.left + region.right) / transforms.scale, | ||
height: image.height - (region.top + region.bottom) / transforms.scale, | ||
} | ||
} else { | ||
region = utils.geometry.scale(region, 1 / transforms.scale) | ||
} | ||
region = utils.geometry.rotate(region, transforms.rotate) | ||
transforms.crop = utils.geometry.intersect(transforms.crop, region) | ||
size = utils.geometry.round(utils.geometry.size(transforms.crop)) | ||
return this | ||
}, | ||
async rotate(degree) { | ||
image = await rotate(await image, degree) | ||
rotate(degree) { | ||
transforms.rotate = (transforms.rotate + degree) % 360 | ||
return this | ||
}, | ||
async copy(image2, offset) { | ||
image = await copy(await image, image2, offset) | ||
async copy(srcImage, offset) { | ||
const [dst, src] = await Promise.all([this.toObject(), srcImage.toObject()]) | ||
image = await copy(dst, src, offset) | ||
return this | ||
}, | ||
async replace(image2, region) { | ||
image = await replace(await image, image2, region) | ||
async combine(firstImage, lastImage, region) { | ||
const [src, first, last] = await Promise.all([this.toObject(), firstImage.toObject(), lastImage.toObject()]) | ||
image = await combine(first, last, src, region) | ||
size = {width: image.width, height: image.height} | ||
return this | ||
}, | ||
async debug(debug) { | ||
if (!debug || !debug.path) return | ||
const timestamp = new Date().toISOString().replace(/[-T:.]/g, '_') | ||
const filename = | ||
['screenshot', timestamp, debug.name, debug.suffix].filter(part => part).join('_') + '.png' | ||
return toFile(await image, path.join(debug.path, filename)).catch(() => null) | ||
}, | ||
async toObject() { | ||
image = await image | ||
return image | ||
}, | ||
async toBuffer() { | ||
image = await image | ||
const image = await this.toObject() | ||
return image.data | ||
}, | ||
async toPng() { | ||
return toPng(await image) | ||
return toPng(await this.toObject()) | ||
}, | ||
async toFile(path) { | ||
return toFile(await image, path) | ||
return toFile(await this.toObject(), path) | ||
}, | ||
async toRaw() { | ||
return image | ||
}, | ||
async toObject() { | ||
image = await transform(await image, transforms) | ||
transforms = {rotate: 0, scale: 1, crop: utils.geometry.region({x: 0, y: 0}, size)} | ||
return image | ||
}, | ||
async debug(debug) { | ||
if (!debug || !debug.path) return | ||
const timestamp = new Date().toISOString().replace(/[-T:.]/g, '_') | ||
const filename = ['screenshot', timestamp, debug.name, debug.suffix].filter(part => part).join('_') + '.png' | ||
return toFile(await transform(await image, transforms), path.join(debug.path, filename)).catch(() => null) | ||
}, | ||
} | ||
@@ -99,3 +129,3 @@ } | ||
return new Promise((resolve, reject) => { | ||
const image = new png.Image({filterType: 4}) | ||
const image = new png.Image() | ||
@@ -110,3 +140,3 @@ image.parse(buffer, (err, image) => { | ||
async function fromSize(size) { | ||
return new png.Image({filterType: 4, width: size.width, height: size.height}) | ||
return new png.Image({width: size.width, height: size.height}) | ||
} | ||
@@ -140,2 +170,9 @@ | ||
async function transform(image, transforms) { | ||
const croppedImage = transforms.crop ? await extract(image, transforms.crop) : image | ||
const scaledImage = transforms.scale !== 1 ? await scale(croppedImage, transforms.scale) : croppedImage | ||
const rotatedImage = transforms.rotate > 0 ? await rotate(scaledImage, transforms.rotate) : scaledImage | ||
return rotatedImage | ||
} | ||
async function scale(image, scaleRatio) { | ||
@@ -171,11 +208,2 @@ if (scaleRatio === 1) return image | ||
async function extract(image, region) { | ||
if (utils.types.has(region, ['left', 'right', 'top', 'bottom'])) { | ||
region = { | ||
x: region.left, | ||
y: region.top, | ||
width: image.width - region.left - region.right, | ||
height: image.height - region.top - region.bottom, | ||
} | ||
} | ||
const srcX = Math.max(0, Math.round(region.x)) | ||
@@ -185,5 +213,10 @@ const srcY = Math.max(0, Math.round(region.y)) | ||
const dstHeight = Math.round(Math.min(image.height - srcY, region.height)) | ||
const dstSize = {width: dstWidth, height: dstHeight} | ||
const extracted = new png.Image({filterType: 4, width: dstWidth, height: dstHeight}) | ||
if (utils.geometry.isEmpty(dstSize)) { | ||
throw new Error(`Cannot extract empty region (${srcX};${srcY})${dstWidth}x${dstHeight} from image`) | ||
} | ||
const extracted = new png.Image(dstSize) | ||
if (srcX === 0 && dstWidth === image.width) { | ||
@@ -197,6 +230,3 @@ const srcOffset = srcY * image.width * 4 | ||
const srcOffset = ((srcY + chunk) * image.width + srcX) * 4 | ||
extracted.data.set( | ||
image.data.subarray(srcOffset, srcOffset + chunkLength), | ||
chunk * chunkLength, | ||
) | ||
extracted.data.set(image.data.subarray(srcOffset, srcOffset + chunkLength), chunk * chunkLength) | ||
} | ||
@@ -211,3 +241,3 @@ } | ||
const dstImage = new png.Image({filterType: 4, width: image.width, height: image.height}) | ||
const dstImage = new png.Image({width: image.width, height: image.height}) | ||
@@ -270,14 +300,6 @@ if (degrees === 90) { | ||
async function replace(baseImage, srcImage, region) { | ||
region = utils.geometry.intersect( | ||
{x: 0, y: 0, width: baseImage.width, height: baseImage.height}, | ||
region, | ||
) | ||
async function combine(firstImage, lastImage, srcImage, region) { | ||
region = utils.geometry.intersect({x: 0, y: 0, width: firstImage.width, height: firstImage.height}, region) | ||
if ( | ||
region.x === 0 && | ||
region.y === 0 && | ||
region.width >= baseImage.width && | ||
region.height >= baseImage.height | ||
) { | ||
if (region.x === 0 && region.y === 0 && region.width >= firstImage.width && region.height >= firstImage.height) { | ||
return srcImage | ||
@@ -287,17 +309,16 @@ } | ||
if (region.width === srcImage.width && region.height === srcImage.height) { | ||
await copy(baseImage, srcImage, {x: region.x, y: region.y}) | ||
return baseImage | ||
await copy(firstImage, srcImage, {x: region.x, y: region.y}) | ||
return firstImage | ||
} | ||
const dstImage = new png.Image({ | ||
filterType: 4, | ||
width: baseImage.width - region.width + srcImage.width, | ||
height: baseImage.height - region.height + srcImage.height, | ||
width: firstImage.width - region.width + srcImage.width, | ||
height: firstImage.height - region.height + srcImage.height, | ||
}) | ||
if (region.width === srcImage.width) { | ||
const topImage = await extract(baseImage, { | ||
const topImage = await extract(firstImage, { | ||
x: 0, | ||
y: 0, | ||
width: baseImage.width, | ||
width: firstImage.width, | ||
height: region.y + region.height, | ||
@@ -307,11 +328,11 @@ }) | ||
} else if (region.height === srcImage.height) { | ||
const leftImage = await extract(baseImage, { | ||
const leftImage = await extract(firstImage, { | ||
x: 0, | ||
y: 0, | ||
width: region.x + region.width, | ||
height: baseImage.height, | ||
height: firstImage.height, | ||
}) | ||
await copy(dstImage, leftImage, {x: 0, y: 0}) | ||
} else { | ||
const topLeftImage = await extract(baseImage, { | ||
const topLeftImage = await extract(firstImage, { | ||
x: 0, | ||
@@ -323,6 +344,6 @@ y: 0, | ||
await copy(dstImage, topLeftImage, {x: 0, y: 0}) | ||
const topRightImage = await extract(baseImage, { | ||
const topRightImage = await extract(firstImage, { | ||
x: region.x + region.width, | ||
y: 0, | ||
width: baseImage.width - (region.x + region.width), | ||
width: firstImage.width - (region.x + region.width), | ||
height: region.y + region.height, | ||
@@ -335,32 +356,32 @@ }) | ||
if (baseImage.height > region.y + region.height) { | ||
if (lastImage.height > region.y + region.height) { | ||
if (region.width === srcImage.width) { | ||
const bottomImage = await extract(baseImage, { | ||
const bottomImage = await extract(lastImage, { | ||
x: 0, | ||
y: region.y + region.height, | ||
width: baseImage.width, | ||
height: baseImage.height - (region.y + region.height), | ||
width: lastImage.width, | ||
height: lastImage.height - (region.y + region.height), | ||
}) | ||
await copy(dstImage, bottomImage, {x: 0, y: region.y + srcImage.height}) | ||
} else if (region.height === srcImage.height) { | ||
const rightImage = await extract(baseImage, { | ||
const rightImage = await extract(lastImage, { | ||
x: region.x + region.width, | ||
y: 0, | ||
width: baseImage.width - (region.x + region.width), | ||
height: baseImage.height, | ||
width: lastImage.width - (region.x + region.width), | ||
height: lastImage.height, | ||
}) | ||
await copy(dstImage, rightImage, {x: region.x + srcImage.width, y: 0}) | ||
} else { | ||
const bottomLeftImage = await extract(baseImage, { | ||
const bottomLeftImage = await extract(lastImage, { | ||
x: 0, | ||
y: region.y + region.height, | ||
width: region.x + region.width, | ||
height: baseImage.height - (region.y + region.height), | ||
height: lastImage.height - (region.y + region.height), | ||
}) | ||
await copy(dstImage, bottomLeftImage, {x: 0, y: region.y + srcImage.height}) | ||
const bottomRightImage = await extract(baseImage, { | ||
const bottomRightImage = await extract(lastImage, { | ||
x: region.x + region.width, | ||
y: region.y + region.height, | ||
width: baseImage.width - (region.x + region.width), | ||
height: baseImage.height - (region.y + region.height), | ||
width: lastImage.width - (region.x + region.width), | ||
height: lastImage.height - (region.y + region.height), | ||
}) | ||
@@ -423,4 +444,3 @@ await copy(dstImage, bottomRightImage, { | ||
const y2 = bufSrc[kPos + wDst * 4] | ||
const y3 = | ||
yPos < hSrc - 2 ? bufSrc[kPos + wDst * 8] : 2 * bufSrc[kPos + wDst * 4] - bufSrc[kPos] | ||
const y3 = yPos < hSrc - 2 ? bufSrc[kPos + wDst * 8] : 2 * bufSrc[kPos + wDst * 4] - bufSrc[kPos] | ||
@@ -519,3 +539,3 @@ buf[buf2Pos + k] = _interpolateCubic(y0, y1, y2, y3, t) | ||
if (currentWidth > targetWidth) { | ||
currentWidth -= currentWidth / fraction | ||
currentWidth -= Math.floor(currentWidth / fraction) | ||
@@ -531,3 +551,3 @@ // If we cut the width too far it means we are on our last iteration. Just set it to the target width | ||
if (currentHeight > targetHeight) { | ||
currentHeight -= currentHeight / fraction | ||
currentHeight -= Math.floor(currentHeight / fraction) | ||
@@ -534,0 +554,0 @@ // If we cut the height too far it means we are on our last iteration. Just set it to the target height |
const utils = require('@applitools/utils') | ||
const snippets = require('@applitools/snippets') | ||
const makeScroller = require('./scroller') | ||
const takeStitchedScreenshot = require('./takeStitchedScreenshot') | ||
const takeViewportScreenshot = require('./takeViewportScreenshot') | ||
const scrollIntoViewport = require('./scrollIntoViewport') | ||
const scrollIntoViewport = require('./scroll-into-viewport') | ||
const takeStitchedScreenshot = require('./take-stitched-screenshot') | ||
const takeViewportScreenshot = require('./take-viewport-screenshot') | ||
async function screenshoter({ | ||
logger, | ||
driver, | ||
frames = [], | ||
target, | ||
region, | ||
fully, | ||
scrollingMode, | ||
hideScrollbars, | ||
hideCaret, | ||
scrollingMode, | ||
overlap, | ||
framed, | ||
wait, | ||
dom, | ||
lazyRestorePageState, | ||
stabilization, | ||
hooks, | ||
debug, | ||
takeDomCapture, | ||
logger, | ||
}) { | ||
const originalContext = driver.currentContext | ||
// screenshot of a window/app was requested (fully or viewport) | ||
const window = !region && (!frames || frames.length === 0) | ||
// framed screenshots could be taken only when screenshot of window/app fully was requested | ||
framed = framed && fully && window | ||
const targetContext = | ||
const activeContext = driver.currentContext | ||
const context = | ||
frames.length > 0 | ||
? await originalContext.context(frames.reduce((parent, frame) => ({...frame, parent}), null)) | ||
: originalContext | ||
? await activeContext.context(frames.reduce((parent, frame) => ({...frame, parent}), null)) | ||
: activeContext | ||
for (const nextContext of targetContext.path) { | ||
// traverse from main context to target context to hide scrollbars and preserve context state (scroll/translate position) | ||
for (const nextContext of context.path) { | ||
const scrollingElement = await nextContext.getScrollingElement() | ||
// unlike web apps, native apps do not always have scrolling element | ||
if (scrollingElement) { | ||
@@ -41,68 +44,33 @@ if (driver.isWeb && hideScrollbars) await scrollingElement.hideScrollbars() | ||
const activeElement = hideCaret && !driver.isNative ? await targetContext.blurElement() : null | ||
// blur active element in target context | ||
const activeElement = driver.isWeb && hideCaret ? await context.blurElement() : null | ||
const window = !target && (!frames || frames.length === 0) | ||
const {context, scroller, region} = await getTargetArea({ | ||
logger, | ||
context: targetContext, | ||
window, | ||
target, | ||
fully, | ||
scrollingMode, | ||
}) | ||
const target = await getTarget({window, context, region, fully, scrollingMode, logger}) | ||
// IMHO problem with scrollbars should be solved by extracting client size of the content (without scrollbars), | ||
// here we use a historical solution | ||
if (driver.isWeb && (hideScrollbars || fully)) await scroller.element.hideScrollbars() | ||
const scrollerState = await scroller.preserveState() | ||
if (driver.isWeb && hideScrollbars) await target.scroller.hideScrollbars() | ||
if (!window) await scrollIntoViewport({logger, context, scroller, region}) | ||
try { | ||
if (!window) await scrollIntoViewport({...target, logger}) | ||
try { | ||
const screenshot = fully | ||
? await takeStitchedScreenshot({ | ||
logger, | ||
context, | ||
scroller, | ||
region, | ||
overlap, | ||
framed: framed && !region, | ||
wait, | ||
stabilization, | ||
debug, | ||
}) | ||
: await takeViewportScreenshot({logger, context, region, wait, stabilization, debug}) | ||
? await takeStitchedScreenshot({...target, overlap, framed, wait, stabilization, debug, logger}) | ||
: await takeViewportScreenshot({...target, wait, stabilization, debug, logger}) | ||
if (dom) { | ||
// temporary solution | ||
if (fully) { | ||
await context.execute(snippets.setElementAttributes, [ | ||
scroller.element, | ||
{'data-applitools-scroll': true}, | ||
]) | ||
if (hooks && hooks.afterScreenshot) { | ||
// imitate image-like state for the hook | ||
if (window && fully) { | ||
await target.scroller.moveTo({x: 0, y: 0}, await driver.mainContext.getScrollingElement()) | ||
} | ||
const scrollingElement = await context.main.getScrollingElement() | ||
await scroller.moveTo({x: 0, y: 0}, scrollingElement) | ||
screenshot.dom = await takeDomCapture() | ||
await hooks.afterScreenshot({driver, scroller: target.scroller, screenshot}) | ||
} | ||
if (lazyRestorePageState) { | ||
screenshot.restorePageState = restorePageState | ||
} | ||
return screenshot | ||
} finally { | ||
if (!lazyRestorePageState) await restorePageState() | ||
} | ||
async function restorePageState() { | ||
if (scroller.element) { | ||
await scroller.element.restoreScrollbars() | ||
await scroller.restoreState(scrollerState) | ||
} | ||
await target.scroller.restoreScrollbars() | ||
if (hideCaret && activeElement) await targetContext.focusElement(activeElement) | ||
// if there was active element and we have blurred it, then restore focus | ||
if (activeElement) await context.focusElement(activeElement) | ||
for (const prevContext of targetContext.path.reverse()) { | ||
// traverse from target context to the main context to restore scrollbars and context states | ||
for (const prevContext of context.path.reverse()) { | ||
const scrollingElement = await prevContext.getScrollingElement() | ||
@@ -115,23 +83,27 @@ if (scrollingElement) { | ||
await originalContext.focus() | ||
// restore focus on original active context | ||
await activeContext.focus() | ||
} | ||
} | ||
async function getTargetArea({logger, context, target, window, fully, scrollingMode}) { | ||
async function getTarget({window, context, region, fully, scrollingMode, logger}) { | ||
if (window) { | ||
// window/app | ||
const scrollingElement = await context.main.getScrollingElement() | ||
return { | ||
context: context.main, | ||
scroller: makeScroller({logger, element: scrollingElement, scrollingMode}), | ||
scroller: makeScroller({element: scrollingElement, scrollingMode, logger}), | ||
} | ||
} else if (target) { | ||
if (utils.types.has(target, ['x', 'y', 'width', 'height'])) { | ||
} else if (region) { | ||
if (utils.types.has(region, ['x', 'y', 'width', 'height'])) { | ||
// region by coordinates | ||
const scrollingElement = await context.getScrollingElement() | ||
return { | ||
context, | ||
region: target, | ||
scroller: makeScroller({logger, element: scrollingElement, scrollingMode}), | ||
region, | ||
scroller: makeScroller({element: scrollingElement, scrollingMode, logger}), | ||
} | ||
} else { | ||
const element = await context.element(target) | ||
// region by element or selector | ||
const element = await context.element(region) | ||
if (!element) throw new Error('Element not found!') | ||
@@ -141,14 +113,11 @@ | ||
const isScrollable = await element.isScrollable() | ||
// if element is scrollable, then take screenshot of the full element content, otherwise take screenshot of full element | ||
const region = isScrollable ? null : await element.getRegion() | ||
const scrollingElement = isScrollable ? element : await context.getScrollingElement() | ||
// css stitching could be applied only to root element of its context | ||
scrollingMode = scrollingMode === 'css' && !(await scrollingElement.isRoot()) ? 'mixed' : scrollingMode | ||
return { | ||
context, | ||
region: isScrollable ? null : await element.getRegion(), | ||
scroller: makeScroller({ | ||
logger, | ||
element: scrollingElement, | ||
scrollingMode: | ||
scrollingMode === 'css' && !(await scrollingElement.isRoot()) | ||
? 'mixed' | ||
: scrollingMode, | ||
}), | ||
region, | ||
scroller: makeScroller({element: scrollingElement, scrollingMode, logger}), | ||
} | ||
@@ -160,20 +129,23 @@ } else { | ||
region: await element.getRegion(), | ||
scroller: makeScroller({logger, element: scrollingElement, scrollingMode}), | ||
scroller: makeScroller({element: scrollingElement, scrollingMode, logger}), | ||
} | ||
} | ||
} | ||
} else if (!context.isMain && !fully) { | ||
const scrollingElement = await context.parent.getScrollingElement() | ||
const element = await context.getContextElement() | ||
return { | ||
context: context.parent, | ||
region: await element.getRegion(), // IMHO we should use CLIENT (without borders) region here | ||
scroller: makeScroller({logger, element: scrollingElement, scrollingMode}), | ||
} else if (!context.isMain) { | ||
// context | ||
if (fully) { | ||
const scrollingElement = await context.getScrollingElement() | ||
return { | ||
context, | ||
scroller: makeScroller({logger, element: scrollingElement, scrollingMode}), | ||
} | ||
} else { | ||
const scrollingElement = await context.parent.getScrollingElement() | ||
const element = await context.getContextElement() | ||
return { | ||
context: context.parent, | ||
region: await element.getRegion(), // IMHO we should use CLIENT (without borders) region here | ||
scroller: makeScroller({logger, element: scrollingElement, scrollingMode}), | ||
} | ||
} | ||
} else { | ||
const scrollingElement = await context.getScrollingElement() | ||
return { | ||
context, | ||
scroller: makeScroller({logger, element: scrollingElement, scrollingMode}), | ||
} | ||
} | ||
@@ -180,0 +152,0 @@ } |
@@ -20,2 +20,4 @@ const utils = require('@applitools/utils') | ||
restoreState, | ||
hideScrollbars, | ||
restoreScrollbars, | ||
} | ||
@@ -136,4 +138,21 @@ | ||
} | ||
async function hideScrollbars(element = defaultElement) { | ||
try { | ||
return element.hideScrollbars() | ||
} catch (err) { | ||
logger.verbose(`Failed to get current transforms!.`, err) | ||
return {} | ||
} | ||
} | ||
async function restoreScrollbars(state, element = defaultElement) { | ||
try { | ||
await element.restoreScrollbars(state) | ||
} catch (err) { | ||
logger.verbose(`Failed to restore state!.`, err) | ||
} | ||
} | ||
} | ||
module.exports = makeScroller |
@@ -56,4 +56,8 @@ const assert = require('assert') | ||
it('take full app screenshot (recycler view)', () => { | ||
return fullAppRecyclerViewX() | ||
}) | ||
it('take full element screenshot', () => { | ||
return fullElement() | ||
return fullElementX() | ||
}) | ||
@@ -64,8 +68,10 @@ }) | ||
const screenshot = await screenshoter({logger, driver, ...options}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/android/app.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/android/app.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'viewport_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -85,8 +91,10 @@ async function fullAppScrollView(options) { | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/android/app-fully.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/android/app-fully.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_app_scroll_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -106,9 +114,33 @@ async function fullAppRecyclerView(options) { | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/android/app-fully-recycler.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/android/app-fully-recycler.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_app_recycler_failed'}) | ||
throw err | ||
} | ||
} | ||
async function fullAppRecyclerViewX(options) { | ||
const button = await driver.element({type: 'id', selector: 'btn_recycler_view_activity'}) | ||
await button.click() | ||
const screenshot = await screenshoter({ | ||
logger, | ||
driver, | ||
fully: true, | ||
framed: true, | ||
scrollingMode: 'scroll', | ||
wait: 1500, | ||
...options, | ||
}) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/android/app-fully-recycler-x.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_app_recycler_x_failed'}) | ||
throw err | ||
} | ||
} | ||
async function region(options) { | ||
@@ -118,12 +150,14 @@ const screenshot = await screenshoter({ | ||
driver, | ||
target: {x: 30, y: 500, height: 100, width: 200}, | ||
region: {x: 30, y: 500, height: 100, width: 200}, | ||
scrollingMode: 'scroll', | ||
...options, | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/android/region.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/android/region.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'region_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -134,3 +168,3 @@ async function fullRegion(options) { | ||
driver, | ||
target: {x: 30, y: 10, height: 700, width: 200}, | ||
region: {x: 30, y: 10, height: 700, width: 200}, | ||
fully: true, | ||
@@ -140,8 +174,10 @@ scrollingMode: 'scroll', | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/android/region-fully.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/android/region-fully.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_region_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -152,14 +188,16 @@ async function element(options) { | ||
driver, | ||
target: {type: 'id', selector: 'btn_recycler_view'}, | ||
region: {type: 'id', selector: 'btn_recycler_view'}, | ||
scrollingMode: 'scroll', | ||
...options, | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/android/element.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/android/element.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'element_failed'}) | ||
throw err | ||
} | ||
} | ||
async function fullElement(options) { | ||
async function fullElementX(options) { | ||
const button = await driver.element({ | ||
@@ -174,3 +212,3 @@ type: 'id', | ||
driver, | ||
target: {type: 'id', selector: 'recyclerView'}, | ||
region: {type: 'id', selector: 'recyclerView'}, | ||
fully: true, | ||
@@ -181,9 +219,11 @@ scrollingMode: 'scroll', | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/android/element-fully.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/android/element-fully-x.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_element_x_failed'}) | ||
throw err | ||
} | ||
} | ||
}) |
@@ -54,8 +54,10 @@ const assert = require('assert') | ||
const screenshot = await screenshoter({logger, driver, ...options}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/ios/app.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/ios/app.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'viewport_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -75,8 +77,10 @@ async function fullAppScrollView(options) { | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/ios/app-fully.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/ios/app-fully.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_app_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -96,8 +100,10 @@ async function fullAppTableView(options) { | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/ios/app-fully-table.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/ios/app-fully-table.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_app_table_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -117,8 +123,10 @@ async function fullAppCollectionView(options) { | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/ios/app-fully-collection.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/ios/app-fully-collection.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_app_collection_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -129,3 +137,3 @@ async function region(options) { | ||
driver, | ||
target: {x: 30, y: 500, height: 100, width: 200}, | ||
region: {x: 30, y: 500, height: 100, width: 200}, | ||
scrollingMode: 'scroll', | ||
@@ -135,8 +143,10 @@ wait: 1500, | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/ios/region.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/ios/region.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'region_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -147,3 +157,3 @@ async function fullRegion(options) { | ||
driver, | ||
target: {x: 30, y: 10, height: 700, width: 200}, | ||
region: {x: 30, y: 10, height: 700, width: 200}, | ||
fully: true, | ||
@@ -153,8 +163,10 @@ scrollingMode: 'scroll', | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/ios/region-fully.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/ios/region-fully.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_region_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -165,12 +177,14 @@ async function element(options) { | ||
driver, | ||
target: {type: 'accessibility id', selector: 'Table view'}, | ||
region: {type: 'accessibility id', selector: 'Table view'}, | ||
scrollingMode: 'scroll', | ||
...options, | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/ios/element.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/ios/element.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'element_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -187,3 +201,3 @@ async function fullElement(options) { | ||
driver, | ||
target: {type: 'xpath', selector: '//XCUIElementTypeTable[1]'}, | ||
region: {type: 'xpath', selector: '//XCUIElementTypeTable[1]'}, | ||
fully: true, | ||
@@ -194,9 +208,11 @@ scrollingMode: 'scroll', | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/ios/element-fully.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/ios/element-fully.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_element_failed'}) | ||
throw err | ||
} | ||
} | ||
}) |
@@ -121,36 +121,32 @@ const assert = require('assert') | ||
const screenshot = await screenshoter({logger, driver, ...options}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/page.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/page.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'viewport_failed'}) | ||
throw err | ||
} | ||
} | ||
async function fullPage(options) { | ||
const screenshot = await screenshoter({ | ||
logger, | ||
driver, | ||
fully: true, | ||
...options, | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/page-fully.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
const screenshot = await screenshoter({logger, driver, fully: true, ...options}) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/page-fully.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_page_failed'}) | ||
throw err | ||
} | ||
} | ||
async function frame(options) { | ||
const screenshot = await screenshoter({ | ||
logger, | ||
driver, | ||
frames: [{reference: 'iframe[name="frame1"]'}], | ||
...options, | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/frame.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
const screenshot = await screenshoter({logger, driver, frames: [{reference: 'iframe[name="frame1"]'}], ...options}) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/frame.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'frame_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -165,66 +161,56 @@ async function fullFrame(options) { | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/frame-fully.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/frame-fully.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_frame_failed'}) | ||
throw err | ||
} | ||
} | ||
async function region(options) { | ||
const screenshot = await screenshoter({ | ||
logger, | ||
driver, | ||
target: {x: 30, y: 500, height: 100, width: 200}, | ||
...options, | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/region.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
const region = {x: 30, y: 500, height: 100, width: 200} | ||
const screenshot = await screenshoter({logger, driver, region, ...options}) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/region.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'region_failed'}) | ||
throw err | ||
} | ||
} | ||
async function fullRegion(options) { | ||
const screenshot = await screenshoter({ | ||
logger, | ||
driver, | ||
target: {x: 30, y: 500, height: 700, width: 200}, | ||
fully: true, | ||
...options, | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/region-fully.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
const region = {x: 30, y: 500, height: 700, width: 200} | ||
const screenshot = await screenshoter({logger, driver, region, fully: true, ...options}) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/region-fully.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_region_failed'}) | ||
throw err | ||
} | ||
} | ||
async function element(options) { | ||
const screenshot = await screenshoter({ | ||
logger, | ||
driver, | ||
target: '#overflowing-div-image', | ||
...options, | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/element.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
const screenshot = await screenshoter({logger, driver, region: '#overflowing-div-image', ...options}) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/element.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'element_failed'}) | ||
throw err | ||
} | ||
} | ||
async function fullElement(options) { | ||
const screenshot = await screenshoter({ | ||
logger, | ||
driver, | ||
target: '#overflowing-div-image', | ||
fully: true, | ||
...options, | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/element-fully.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
const screenshot = await screenshoter({logger, driver, region: '#overflowing-div-image', fully: true, ...options}) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/element-fully.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_element_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -236,11 +222,13 @@ async function regionInFrame(options) { | ||
frames: [{reference: 'iframe[name="frame1"]'}], | ||
target: {x: 10, y: 20, width: 110, height: 120}, | ||
region: {x: 10, y: 20, width: 110, height: 120}, | ||
...options, | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/inner-region.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/inner-region.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'region_in_frame_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -252,12 +240,14 @@ async function fullRegionInFrame(options) { | ||
frames: [{reference: 'iframe[name="frame1"]'}], | ||
target: {x: 10, y: 100, width: 1000, height: 120}, | ||
region: {x: 10, y: 100, width: 1000, height: 120}, | ||
fully: true, | ||
...options, | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/inner-region-fully.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/inner-region-fully.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_region_in_frame_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -269,11 +259,13 @@ async function elementInFrame(options) { | ||
frames: [{reference: 'iframe[name="frame1"]'}], | ||
target: '#inner-frame-div', | ||
region: '#inner-frame-div', | ||
...options, | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/inner-element.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/inner-element.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'element_in_frame_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -285,12 +277,14 @@ async function fullElementInFrame(options) { | ||
frames: [{reference: 'iframe[name="frame1"]'}], | ||
target: '#inner-frame-div', | ||
region: '#inner-frame-div', | ||
fully: true, | ||
...options, | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/inner-element-fully.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/inner-element-fully.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_element_in_frame_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -304,8 +298,10 @@ async function frameInFrame(options) { | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/inner-frame.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/inner-frame.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'frame_in_frame_failed'}) | ||
throw err | ||
} | ||
} | ||
@@ -320,9 +316,11 @@ async function fullFrameInFrame(options) { | ||
}) | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/inner-frame-fully.png').toObject() | ||
assert.strictEqual( | ||
pixelmatch(actual.data, expected.data, null, expected.width, expected.height), | ||
0, | ||
) | ||
try { | ||
const actual = await screenshot.image.toObject() | ||
const expected = await makeImage('./test/fixtures/web/inner-frame-fully.png').toObject() | ||
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0) | ||
} catch (err) { | ||
await screenshot.image.debug({path: './logs', name: 'full_frame_in_frame_failed'}) | ||
throw err | ||
} | ||
} | ||
}) |
const assert = require('assert') | ||
const makeImage = require('../../src/image') | ||
const findPattern = require('../../src/findPattern') | ||
const findPattern = require('../../src/find-image-pattern') | ||
@@ -5,0 +5,0 @@ describe('pattern', () => { |
@@ -86,7 +86,5 @@ const assert = require('assert') | ||
replace.data.fill(Buffer.from([0xff, 0, 0, 0xff])) | ||
await image.replace(replace, {x: 200, y: 200, width: 100, height: 100}) | ||
await replace.combine(image, image, {x: 200, y: 200, width: 100, height: 100}) | ||
const actual = await image.toObject() | ||
const expected = await makeImage( | ||
'./test/fixtures/image/house.replaced-higher-wider.png', | ||
).toObject() | ||
const expected = await makeImage('./test/fixtures/image/house.replaced-higher-wider.png').toObject() | ||
assert.ok(pixelmatch(actual.data, expected.data, null, expected.width, expected.height) === 0) | ||
@@ -99,3 +97,3 @@ }) | ||
replace.data.fill(Buffer.from([0, 0xff, 0, 0xff])) | ||
await image.replace(replace, {x: 200, y: 200, width: 200, height: 100}) | ||
await replace.combine(image, image, {x: 200, y: 200, width: 200, height: 100}) | ||
const actual = await image.toObject() | ||
@@ -110,3 +108,3 @@ const expected = await makeImage('./test/fixtures/image/house.replaced-higher.png').toObject() | ||
replace.data.fill(Buffer.from([0, 0, 0xff, 0xff])) | ||
await image.replace(replace, {x: 200, y: 200, width: 100, height: 200}) | ||
await replace.combine(image, image, {x: 200, y: 200, width: 100, height: 200}) | ||
const actual = await image.toObject() | ||
@@ -113,0 +111,0 @@ const expected = await makeImage('./test/fixtures/image/house.replaced-wider.png').toObject() |
@@ -50,5 +50,3 @@ const webdriverio = require('webdriverio') | ||
if (browser.isDevTools || browser.isIOS) { | ||
return browser | ||
.execute((element1, element2) => element1 === element2, element1, element2) | ||
.catch(() => false) | ||
return browser.execute((element1, element2) => element1 === element2, element1, element2).catch(() => false) | ||
} | ||
@@ -263,4 +261,3 @@ if (!element1 || !element2) return false | ||
automationName: 'XCUITest', | ||
app: | ||
'https://applitools.jfrog.io/artifactory/Examples/IOSTestApp/1.5/app/IOSTestApp-1.5.zip', | ||
app: 'https://applitools.jfrog.io/artifactory/Examples/IOSTestApp/1.5/app/IOSTestApp-1.5.zip', | ||
username: process.env.SAUCE_USERNAME, | ||
@@ -267,0 +264,0 @@ accessKey: process.env.SAUCE_ACCESS_KEY, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
25766578
67
2246
+ Added@applitools/utils@1.2.2(transitive)
- Removed@applitools/utils@1.2.1(transitive)
Updated@applitools/utils@1.2.2