@applitools/screenshoter 3.3.19 → 3.3.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +2 -5
- package/package.json +5 -5
- package/src/{getTarget.js → get-target.js} +19 -8
- package/src/scroll-into-viewport.js +1 -5
- package/src/scroller.js +2 -0
- package/src/take-screenshot.js +19 -20
- package/src/take-stitched-screenshot.js +3 -4
- package/src/take-viewport-screenshot.js +12 -15
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applitools/screenshoter",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.20",
|
|
4
4
|
"description": "Applitools universal screenshoter for web and native applications",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"applitools",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"test:unit": "mocha ./test/unit/*.spec.js --no-timeouts",
|
|
37
37
|
"test:it": "mocha ./test/it/*.spec.js --no-timeouts",
|
|
38
38
|
"test:e2e": "yarn test:e2e:web && yarn && test:e2e:android && yarn test:e2e:ios",
|
|
39
|
-
"test:e2e:web": "
|
|
39
|
+
"test:e2e:web": "mocha ./test/e2e/web/*.spec.js --no-timeouts -r @applitools/test-utils/mocha-hooks/docker",
|
|
40
40
|
"test:e2e:android": "APPLITOOLS_TEST_REMOTE=sauce mocha ./test/e2e/android*/*.spec.js --no-timeouts --parallel --jobs ${MOCHA_JOBS:-2}",
|
|
41
41
|
"test:e2e:ios": "APPLITOOLS_TEST_REMOTE=sauce mocha ./test/e2e/ios*/*.spec.js --no-timeouts --parallel --jobs ${MOCHA_JOBS:-2}",
|
|
42
42
|
"setup:web": "yarn docker:setup",
|
|
@@ -60,18 +60,18 @@
|
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
+
"@applitools/logger": "1.1.5",
|
|
63
64
|
"@applitools/snippets": "2.2.3",
|
|
64
65
|
"@applitools/utils": "1.3.0",
|
|
65
66
|
"png-async": "0.9.4"
|
|
66
67
|
},
|
|
67
68
|
"devDependencies": {
|
|
68
69
|
"@applitools/bongo": "^2.0.3",
|
|
69
|
-
"@applitools/driver": "^1.8.
|
|
70
|
-
"@applitools/logger": "^1.1.4",
|
|
70
|
+
"@applitools/driver": "^1.8.10",
|
|
71
71
|
"@applitools/scripts": "1.1.0",
|
|
72
72
|
"@applitools/spec-driver-webdriverio": "1.2.9",
|
|
73
73
|
"@applitools/test-utils": "1.3.2",
|
|
74
|
-
"appium": "^1.22.
|
|
74
|
+
"appium": "^1.22.3",
|
|
75
75
|
"chromedriver": "^95.0.0",
|
|
76
76
|
"eslint": "^7.9.0",
|
|
77
77
|
"eslint-plugin-mocha-no-only": "^1.1.1",
|
|
@@ -1,29 +1,39 @@
|
|
|
1
1
|
const utils = require('@applitools/utils')
|
|
2
|
+
const makeScroller = require('./scroller')
|
|
2
3
|
|
|
3
|
-
async function getTarget({window, context, region, fully, scrollingMode}) {
|
|
4
|
+
async function getTarget({window, context, region, fully, scrollingMode, logger}) {
|
|
4
5
|
if (window) {
|
|
5
6
|
// window/app
|
|
7
|
+
logger.log('Window screenshot target detected')
|
|
6
8
|
const scrollingElement = await context.main.getScrollingElement()
|
|
7
9
|
return {
|
|
8
10
|
context: context.main,
|
|
9
|
-
scrollingElement,
|
|
11
|
+
scroller: makeScroller({element: scrollingElement, scrollingMode, logger}),
|
|
10
12
|
}
|
|
11
13
|
} else if (region) {
|
|
12
14
|
if (utils.types.has(region, ['x', 'y', 'width', 'height'])) {
|
|
13
15
|
// region by coordinates
|
|
16
|
+
logger.log('Region screenshot target detected with static region:', region)
|
|
14
17
|
const scrollingElement = await context.getScrollingElement()
|
|
15
18
|
return {
|
|
16
19
|
context,
|
|
17
20
|
region,
|
|
18
|
-
scrollingElement,
|
|
21
|
+
scroller: makeScroller({element: scrollingElement, scrollingMode, logger}),
|
|
19
22
|
}
|
|
20
23
|
} else {
|
|
21
24
|
// region by element or selector
|
|
25
|
+
logger.log('Region screenshot target detected with element:', region)
|
|
22
26
|
const element = await context.element(region)
|
|
23
27
|
if (!element) throw new Error('Element not found!')
|
|
24
28
|
|
|
25
29
|
const elementContext = element.context
|
|
26
30
|
|
|
31
|
+
if (element.driver.isNative) {
|
|
32
|
+
// if element is in a native context, then scroll it to the top, otherwise, it will be not possible to get all of its size
|
|
33
|
+
const scrollingElement = await elementContext.getScrollingElement()
|
|
34
|
+
if (scrollingElement) await scrollingElement.scrollTo(await element.getRegion())
|
|
35
|
+
}
|
|
36
|
+
|
|
27
37
|
if (fully) {
|
|
28
38
|
const isScrollable = await element.isScrollable()
|
|
29
39
|
// if element is scrollable, then take screenshot of the full element content, otherwise take screenshot of full element
|
|
@@ -34,25 +44,25 @@ async function getTarget({window, context, region, fully, scrollingMode}) {
|
|
|
34
44
|
return {
|
|
35
45
|
context: elementContext,
|
|
36
46
|
region,
|
|
37
|
-
scrollingMode,
|
|
38
|
-
scrollingElement,
|
|
47
|
+
scroller: makeScroller({element: scrollingElement, scrollingMode, logger}),
|
|
39
48
|
}
|
|
40
49
|
} else {
|
|
41
50
|
const scrollingElement = await context.getScrollingElement()
|
|
42
51
|
return {
|
|
43
52
|
context: elementContext,
|
|
44
53
|
region: await element.getRegion(),
|
|
45
|
-
scrollingElement,
|
|
54
|
+
scroller: makeScroller({element: scrollingElement, scrollingMode, logger}),
|
|
46
55
|
}
|
|
47
56
|
}
|
|
48
57
|
}
|
|
49
58
|
} else if (!context.isMain) {
|
|
50
59
|
// context
|
|
60
|
+
logger.log('Context screenshot target detected')
|
|
51
61
|
if (fully) {
|
|
52
62
|
const scrollingElement = await context.getScrollingElement()
|
|
53
63
|
return {
|
|
54
64
|
context,
|
|
55
|
-
scrollingElement,
|
|
65
|
+
scroller: makeScroller({element: scrollingElement, scrollingMode, logger}),
|
|
56
66
|
}
|
|
57
67
|
} else {
|
|
58
68
|
const scrollingElement = await context.parent.getScrollingElement()
|
|
@@ -60,9 +70,10 @@ async function getTarget({window, context, region, fully, scrollingMode}) {
|
|
|
60
70
|
return {
|
|
61
71
|
context: context.parent,
|
|
62
72
|
region: await element.getRegion(), // IMHO we should use CLIENT (without borders) region here
|
|
63
|
-
scrollingElement,
|
|
73
|
+
scroller: makeScroller({element: scrollingElement, scrollingMode, logger}),
|
|
64
74
|
}
|
|
65
75
|
}
|
|
66
76
|
}
|
|
67
77
|
}
|
|
78
|
+
|
|
68
79
|
module.exports = getTarget
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
const utils = require('@applitools/utils')
|
|
2
2
|
|
|
3
|
-
async function scrollIntoViewport({context, scroller, region
|
|
4
|
-
if (context.driver.isNative) {
|
|
5
|
-
logger.verbose(`NATIVE context identified, skipping 'ensure element visible'`)
|
|
6
|
-
return
|
|
7
|
-
}
|
|
3
|
+
async function scrollIntoViewport({context, scroller, region}) {
|
|
8
4
|
const elementContextRegion = region ? {...region} : await scroller.getClientRegion()
|
|
9
5
|
const contextViewportLocation = await context.getLocationInViewport()
|
|
10
6
|
const elementViewportRegion = utils.geometry.offset(elementContextRegion, contextViewportLocation)
|
package/src/scroller.js
CHANGED
package/src/take-screenshot.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
const {makeLogger} = require('@applitools/logger')
|
|
2
|
+
const getTarget = require('./get-target')
|
|
1
3
|
const scrollIntoViewport = require('./scroll-into-viewport')
|
|
2
|
-
const getTarget = require('./getTarget')
|
|
3
|
-
const makeScroller = require('./scroller')
|
|
4
4
|
const takeStitchedScreenshot = require('./take-stitched-screenshot')
|
|
5
5
|
const takeSimpleScreenshot = require('./take-simple-screenshot')
|
|
6
6
|
|
|
@@ -21,6 +21,10 @@ async function takeScreenshot({
|
|
|
21
21
|
debug,
|
|
22
22
|
logger,
|
|
23
23
|
}) {
|
|
24
|
+
debug =
|
|
25
|
+
debug ||
|
|
26
|
+
(process.env.APPLITOOLS_DEBUG_SCREENSHOTS_DIR ? {path: process.env.APPLITOOLS_DEBUG_SCREENSHOTS_DIR} : debug)
|
|
27
|
+
logger = logger ? logger.extend({label: 'screenshoter'}) : makeLogger({label: 'screenshoter'})
|
|
24
28
|
// screenshot of a window/app was requested (fully or viewport)
|
|
25
29
|
const window = !region && (!frames || frames.length === 0)
|
|
26
30
|
// framed screenshots could be taken only when screenshot of window/app fully was requested
|
|
@@ -48,27 +52,22 @@ async function takeScreenshot({
|
|
|
48
52
|
// blur active element in target context
|
|
49
53
|
const activeElement = driver.isWeb && hideCaret ? await context.blurElement() : null
|
|
50
54
|
|
|
51
|
-
const target = await getTarget({window, context, region, fully, scrollingMode})
|
|
52
|
-
// in some cases getTarget logic manipulates the 'scrollingMode'
|
|
53
|
-
scrollingMode = target.scrollingMode || scrollingMode
|
|
55
|
+
const target = await getTarget({window, context, region, fully, scrollingMode, logger})
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (scroller) {
|
|
60
|
-
await scroller.preserveState()
|
|
61
|
-
if (driver.isWeb && hideScrollbars) await scroller.hideScrollbars()
|
|
57
|
+
if (target.scroller) {
|
|
58
|
+
await target.scroller.preserveState()
|
|
59
|
+
if (driver.isWeb && hideScrollbars) await target.scroller.hideScrollbars()
|
|
62
60
|
}
|
|
63
61
|
|
|
64
62
|
try {
|
|
65
|
-
if (!window
|
|
63
|
+
if (!window && !driver.isNative) {
|
|
64
|
+
await scrollIntoViewport({context: target.context, region: target.region, scroller: target.scroller, logger})
|
|
65
|
+
}
|
|
66
66
|
|
|
67
67
|
const screenshot =
|
|
68
|
-
fully && scroller
|
|
68
|
+
fully && target.scroller
|
|
69
69
|
? await takeStitchedScreenshot({
|
|
70
70
|
...target,
|
|
71
|
-
scroller,
|
|
72
71
|
withStatusBar,
|
|
73
72
|
overlap,
|
|
74
73
|
framed,
|
|
@@ -77,19 +76,19 @@ async function takeScreenshot({
|
|
|
77
76
|
debug,
|
|
78
77
|
logger,
|
|
79
78
|
})
|
|
80
|
-
: await takeSimpleScreenshot({...target,
|
|
79
|
+
: await takeSimpleScreenshot({...target, withStatusBar, wait, stabilization, debug, logger})
|
|
81
80
|
|
|
82
81
|
screenshot.image.scale(driver.viewportScale)
|
|
83
82
|
|
|
84
83
|
if (hooks && hooks.afterScreenshot) {
|
|
85
|
-
await hooks.afterScreenshot({driver, scroller, screenshot})
|
|
84
|
+
await hooks.afterScreenshot({driver, scroller: target.scroller, screenshot})
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
return screenshot
|
|
89
88
|
} finally {
|
|
90
|
-
if (scroller) {
|
|
91
|
-
await scroller.restoreScrollbars()
|
|
92
|
-
await scroller.restoreState()
|
|
89
|
+
if (target.scroller) {
|
|
90
|
+
await target.scroller.restoreScrollbars()
|
|
91
|
+
await target.scroller.restoreState()
|
|
93
92
|
}
|
|
94
93
|
|
|
95
94
|
// if there was active element and we have blurred it, then restore focus
|
|
@@ -49,13 +49,12 @@ async function takeStitchedScreenshot({
|
|
|
49
49
|
const targetRegion = region
|
|
50
50
|
? utils.geometry.intersect(utils.geometry.region(postMoveOffset, scrollerRegion), region)
|
|
51
51
|
: scrollerRegion
|
|
52
|
+
logger.log('Target region calculated: ', targetRegion)
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
let cropRegion = driver.isNative ? targetRegion : await driver.getRegionInViewport(context, targetRegion)
|
|
54
|
+
const cropRegion = await driver.getRegionInViewport(context, targetRegion)
|
|
55
|
+
logger.log('Crop region calculated: ', cropRegion)
|
|
56
56
|
if (utils.geometry.isEmpty(cropRegion)) throw new Error('Screenshot region is out of viewport')
|
|
57
57
|
|
|
58
|
-
logger.verbose('cropping... cropRegion is', cropRegion)
|
|
59
58
|
image.crop(withStatusBar ? utils.geometry.offset(cropRegion, {x: 0, y: driver.statusBarHeight}) : cropRegion)
|
|
60
59
|
await image.debug({...debug, name: 'initial', suffix: 'region'})
|
|
61
60
|
|
|
@@ -161,21 +161,18 @@ function makeTakeNativeScreenshot({driver, stabilization = {}, debug, logger}) {
|
|
|
161
161
|
if (stabilization.crop) image.crop(stabilization.crop)
|
|
162
162
|
else {
|
|
163
163
|
const viewportSize = await driver.getViewportSize()
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
: 0,
|
|
177
|
-
}
|
|
178
|
-
image.crop(cropRegion)
|
|
164
|
+
if (withStatusBar) {
|
|
165
|
+
image.crop({x: 0, y: 0, width: viewportSize.width, height: viewportSize.height + driver.statusBarHeight})
|
|
166
|
+
} else if (driver.isAndroid && driver.orientation === 'landscape') {
|
|
167
|
+
image.crop({
|
|
168
|
+
top: driver.statusBarHeight,
|
|
169
|
+
bottom: driver.orientation === 'landscape' ? 0 : driver.navigationBarHeight,
|
|
170
|
+
left: driver.platformVersion > 7 ? driver.navigationBarHeight : 0,
|
|
171
|
+
right: driver.platformVersion < 8 ? driver.navigationBarHeight : 0,
|
|
172
|
+
})
|
|
173
|
+
} else {
|
|
174
|
+
image.crop({x: 0, y: driver.statusBarHeight, width: viewportSize.width, height: viewportSize.height})
|
|
175
|
+
}
|
|
179
176
|
}
|
|
180
177
|
|
|
181
178
|
await image.debug({...debug, name, suffix: `viewport${withStatusBar ? '-with-statusbar' : ''}`})
|