@applitools/screenshoter 3.3.3 → 3.3.7
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/CHANGELOG.md +21 -0
- package/package.json +28 -16
- package/src/find-image-pattern.js +14 -8
- package/src/image.js +38 -23
- package/src/scroller.js +8 -3
- package/src/take-screenshot.js +2 -0
- package/src/take-viewport-screenshot.js +20 -10
- package/.bongo/dry-run/package-lock.json +0 -73
- package/.bongo/dry-run/package.json +0 -5
- package/.bongo/dry-run.tgz +0 -0
- package/.eslintrc +0 -39
- package/docker-compose.yaml +0 -29
- package/test/e2e/android.spec.js +0 -334
- package/test/e2e/external.spec.js +0 -155
- package/test/e2e/ios.spec.js +0 -339
- package/test/e2e/web-ios.spec.js +0 -107
- package/test/e2e/web.spec.js +0 -334
- package/test/fixtures/android/app-fully-non-scrollable.png +0 -0
- package/test/fixtures/android/app-fully-recycler.png +0 -0
- package/test/fixtures/android/app-fully-scroll-statusbar.png +0 -0
- package/test/fixtures/android/app-fully-scroll.png +0 -0
- package/test/fixtures/android/app-statusbar.png +0 -0
- package/test/fixtures/android/app.png +0 -0
- package/test/fixtures/android/element.png +0 -0
- package/test/fixtures/android/region.png +0 -0
- package/test/fixtures/android/x-app-fully-collapsing.png +0 -0
- package/test/fixtures/android/x-app-fully-recycler.png +0 -0
- package/test/fixtures/android/x-element-fully.png +0 -0
- package/test/fixtures/external/agl.png +0 -0
- package/test/fixtures/image/house.cropped-rect.png +0 -0
- package/test/fixtures/image/house.cropped-region.png +0 -0
- package/test/fixtures/image/house.framed-higher-wider.png +0 -0
- package/test/fixtures/image/house.framed-higher.png +0 -0
- package/test/fixtures/image/house.framed-shorter-thinner.png +0 -0
- package/test/fixtures/image/house.framed-wider.png +0 -0
- package/test/fixtures/image/house.png +0 -0
- package/test/fixtures/image/house.rotated.png +0 -0
- package/test/fixtures/image/house.scaled.png +0 -0
- package/test/fixtures/image/house.stitched.png +0 -0
- package/test/fixtures/ios/app-fully-collapsing.png +0 -0
- package/test/fixtures/ios/app-fully-collection.png +0 -0
- package/test/fixtures/ios/app-fully-overlapped-statusbar.png +0 -0
- package/test/fixtures/ios/app-fully-overlapped.png +0 -0
- package/test/fixtures/ios/app-fully-scroll-statusbar.png +0 -0
- package/test/fixtures/ios/app-fully-scroll.png +0 -0
- package/test/fixtures/ios/app-fully-superview.png +0 -0
- package/test/fixtures/ios/app-fully-table.png +0 -0
- package/test/fixtures/ios/app-statusbar.png +0 -0
- package/test/fixtures/ios/app.png +0 -0
- package/test/fixtures/ios/element-fully.png +0 -0
- package/test/fixtures/ios/element.png +0 -0
- package/test/fixtures/ios/region.png +0 -0
- package/test/fixtures/ios/webview-fully.png +0 -0
- package/test/fixtures/ios/webview.png +0 -0
- package/test/fixtures/pattern/iPad_5th_landscape.png +0 -0
- package/test/fixtures/pattern/iPad_5th_portrait.png +0 -0
- package/test/fixtures/pattern/iPad_9th_landscape.png +0 -0
- package/test/fixtures/pattern/iPad_9th_portrait.png +0 -0
- package/test/fixtures/pattern/iPhone_11_landscape.png +0 -0
- package/test/fixtures/pattern/iPhone_11_portrait.png +0 -0
- package/test/fixtures/pattern/iPhone_13_landscape.png +0 -0
- package/test/fixtures/pattern/iPhone_13_portrait.png +0 -0
- package/test/fixtures/pattern/iPhone_SE_landscape.png +0 -0
- package/test/fixtures/pattern/iPhone_SE_portrait.png +0 -0
- package/test/fixtures/pattern/iPhone_XS_portrait_nomarker.png +0 -0
- package/test/fixtures/pattern/iPhone_XS_portrait_noviewport.png +0 -0
- package/test/fixtures/web/element-fully.png +0 -0
- package/test/fixtures/web/element.png +0 -0
- package/test/fixtures/web/frame-fully.png +0 -0
- package/test/fixtures/web/frame.png +0 -0
- package/test/fixtures/web/inner-element-fully.png +0 -0
- package/test/fixtures/web/inner-element.png +0 -0
- package/test/fixtures/web/inner-frame-fully.png +0 -0
- package/test/fixtures/web/inner-frame.png +0 -0
- package/test/fixtures/web/inner-region-fully.png +0 -0
- package/test/fixtures/web/inner-region.png +0 -0
- package/test/fixtures/web/page-fully.png +0 -0
- package/test/fixtures/web/page.png +0 -0
- package/test/fixtures/web/region-fully.png +0 -0
- package/test/fixtures/web/region.png +0 -0
- package/test/fixtures/web-ios/page-fully-landscape.png +0 -0
- package/test/fixtures/web-ios/page-fully.png +0 -0
- package/test/fixtures/web-ios/page-landscape.png +0 -0
- package/test/fixtures/web-ios/page.png +0 -0
- package/test/it/find-pattern.spec.js +0 -33
- package/test/it/image.spec.js +0 -146
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,27 @@
|
|
|
4
4
|
## Unreleased
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
## 3.3.7 - 2022/2/15
|
|
8
|
+
|
|
9
|
+
- fix image scaling on pages without viewport metatag
|
|
10
|
+
- fix safari's viewport detection on iOS devices
|
|
11
|
+
- updated to @applitools/snippets@2.1.13 (from 2.1.12)
|
|
12
|
+
- updated to @applitools/utils@1.2.13 (from 1.2.12)
|
|
13
|
+
|
|
14
|
+
## 3.3.6 - 2022/2/9
|
|
15
|
+
|
|
16
|
+
- fix testing
|
|
17
|
+
- updated to @applitools/utils@1.2.12 (from 1.2.11)
|
|
18
|
+
|
|
19
|
+
## 3.3.5 - 2022/2/8
|
|
20
|
+
|
|
21
|
+
- add "files" field to the package.json to avoid unnecessary files to be published
|
|
22
|
+
- updated to @applitools/utils@1.2.11 (from 1.2.5)
|
|
23
|
+
|
|
24
|
+
## 3.3.4 - 2021/12/23
|
|
25
|
+
|
|
26
|
+
- updated to @applitools/snippets@2.1.12 (from 2.1.11)
|
|
27
|
+
|
|
7
28
|
## 3.3.3 - 2021/12/22
|
|
8
29
|
|
|
9
30
|
- improve default rotation and scaling logic
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applitools/screenshoter",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.7",
|
|
4
4
|
"description": "Applitools universal screenshoter for web and native applications",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"applitools",
|
|
@@ -26,19 +26,30 @@
|
|
|
26
26
|
"email": "team@applitools.com"
|
|
27
27
|
},
|
|
28
28
|
"main": "./index.js",
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
|
|
29
|
+
"files": [
|
|
30
|
+
"src",
|
|
31
|
+
"index.js"
|
|
32
|
+
],
|
|
33
33
|
"scripts": {
|
|
34
34
|
"lint": "eslint . --ext .js",
|
|
35
35
|
"test": "yarn test:it && yarn test:e2e",
|
|
36
|
-
"test:it": "mocha
|
|
37
|
-
"test:e2e": "mocha
|
|
36
|
+
"test:it": "mocha ./test/it/*.spec.js --no-timeouts",
|
|
37
|
+
"test:e2e": "mocha ./test/e2e/**/*.spec.js --no-timeouts --parallel --jobs ${MOCHA_JOBS:-1}",
|
|
38
|
+
"test:e2e:web": "mocha ./test/e2e/web/*.spec.js --no-timeouts -r @applitools/test-utils/mocha-hooks/docker --parallel --jobs ${MOCHA_JOBS:-15}",
|
|
39
|
+
"test:e2e:android": "mocha ./test/e2e/android*/*.spec.js --no-timeouts --parallel --jobs ${MOCHA_JOBS:-1}",
|
|
40
|
+
"test:e2e:ios": "mocha ./test/e2e/ios*/*.spec.js --no-timeouts --parallel --jobs ${MOCHA_JOBS:-1}",
|
|
41
|
+
"setup": "yarn docker:setup && yarn android:setup && yarn ios:setup && yarn appium:setup",
|
|
42
|
+
"setup:web": "yarn docker:setup",
|
|
43
|
+
"setup:android": "yarn android:setup && yarn appium:setup",
|
|
44
|
+
"setup:ios": "yarn ios:setup && yarn appium:setup",
|
|
45
|
+
"android:setup": "node ./scripts/android-emulator.js",
|
|
46
|
+
"android:shutdown": "adb -s emulator-5555 emu kill || true && adb -s emulator-5557 emu kill || true",
|
|
38
47
|
"docker:setup": "node ../scripts/scripts/generate-docker-compose-config.js && docker-compose up -d",
|
|
39
48
|
"docker:teardown": "docker-compose down",
|
|
40
|
-
"setup": "
|
|
49
|
+
"ios:setup": "node ./scripts/ios-simulator.js",
|
|
50
|
+
"appium:setup": "mkdir -p ./logs && appium --address 127.0.0.1 --port 4723 --base-path /wd/hub --log-level error:info --log ./logs/appium.log &",
|
|
41
51
|
"deps": "bongo deps",
|
|
52
|
+
"gh:publish": "gh workflow run publish-screenshoter.yml --ref $(git rev-parse --abbrev-ref HEAD)",
|
|
42
53
|
"preversion": "bongo preversion",
|
|
43
54
|
"version": "bongo version",
|
|
44
55
|
"postversion": "bongo postversion --skip-release-notification"
|
|
@@ -49,27 +60,28 @@
|
|
|
49
60
|
}
|
|
50
61
|
},
|
|
51
62
|
"dependencies": {
|
|
52
|
-
"@applitools/snippets": "2.1.
|
|
53
|
-
"@applitools/utils": "1.2.
|
|
63
|
+
"@applitools/snippets": "2.1.13",
|
|
64
|
+
"@applitools/utils": "1.2.13",
|
|
54
65
|
"png-async": "0.9.4"
|
|
55
66
|
},
|
|
56
67
|
"devDependencies": {
|
|
57
|
-
"@applitools/driver": "1.4.
|
|
58
|
-
"@applitools/sdk-release-kit": "0.13.
|
|
59
|
-
"@applitools/spec-driver-webdriverio": "1.2.
|
|
60
|
-
"@applitools/test-utils": "1.0.
|
|
68
|
+
"@applitools/driver": "1.4.14",
|
|
69
|
+
"@applitools/sdk-release-kit": "0.13.11",
|
|
70
|
+
"@applitools/spec-driver-webdriverio": "1.2.7",
|
|
71
|
+
"@applitools/test-utils": "1.0.12",
|
|
72
|
+
"appium": "^1.22.2",
|
|
61
73
|
"chromedriver": "^95.0.0",
|
|
62
74
|
"eslint": "^7.9.0",
|
|
63
75
|
"eslint-plugin-mocha-no-only": "^1.1.1",
|
|
64
76
|
"eslint-plugin-node": "^11.1.0",
|
|
65
77
|
"eslint-plugin-prettier": "^3.1.4",
|
|
66
78
|
"husky": "^4.3.8",
|
|
67
|
-
"mocha": "^
|
|
79
|
+
"mocha": "^9.2.0",
|
|
68
80
|
"pixelmatch": "^5.2.1",
|
|
69
81
|
"prettier": "1.19.0",
|
|
70
82
|
"webdriverio": "^7.16.7"
|
|
71
83
|
},
|
|
72
84
|
"engines": {
|
|
73
|
-
"node": ">=
|
|
85
|
+
"node": ">= 10.0.0"
|
|
74
86
|
}
|
|
75
87
|
}
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
function findImagePattern(image, pattern) {
|
|
2
2
|
for (let pixel = 0; pixel < image.width * image.height; ++pixel) {
|
|
3
3
|
if (isPattern(image, pixel, pattern)) {
|
|
4
|
-
const patterOffset = pattern.offset * pattern.
|
|
4
|
+
const patterOffset = Math.round(pattern.offset * pattern.scale)
|
|
5
5
|
return {x: (pixel % image.width) - patterOffset, y: Math.floor(pixel / image.width) - patterOffset}
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
return null
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
function isPattern(image,
|
|
12
|
-
const
|
|
13
|
-
for (const [
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
function isPattern(image, offset, pattern) {
|
|
12
|
+
const length = Math.round(pattern.size * pattern.scale)
|
|
13
|
+
for (const [index, color] of pattern.mask.entries()) {
|
|
14
|
+
const maxLength = index * pattern.size * pattern.scale // how many pixels actually could be occupied at this point
|
|
15
|
+
const missedPixels = Math.abs(maxLength - Math.round(maxLength)) // how many pixels were missed due to rounding
|
|
16
|
+
const skippedPixels = missedPixels >= 0.25 ? Math.ceil(missedPixels) : 0 // how many pixels should be skipped from checking in pattern (usually 1 or 0)
|
|
17
|
+
for (let pixel = index * length; pixel < (index + 1) * length - skippedPixels; ++pixel) {
|
|
18
|
+
const pixelColor = pixelColorAt(image, offset + pixel)
|
|
19
|
+
if (pixelColor !== color) return false
|
|
17
20
|
}
|
|
18
21
|
}
|
|
19
22
|
return true
|
|
@@ -27,7 +30,10 @@ function pixelColorAt(image, index) {
|
|
|
27
30
|
|
|
28
31
|
const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
// if luminance is between black and white check the color of previous pixel
|
|
34
|
+
if (luminance >= 112 && luminance <= 144) return pixelColorAt(image, index - 1)
|
|
35
|
+
else if (luminance < 128) return /* black */ 1
|
|
36
|
+
else return /* white*/ 0
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
module.exports = findImagePattern
|
package/src/image.js
CHANGED
|
@@ -22,7 +22,7 @@ function makeImage(data) {
|
|
|
22
22
|
} else if (data.isImage) {
|
|
23
23
|
transforms = data.transforms
|
|
24
24
|
image = data.toRaw()
|
|
25
|
-
size =
|
|
25
|
+
size = data.rawSize
|
|
26
26
|
} else if (utils.types.has(data, ['width', 'height'])) {
|
|
27
27
|
image = fromSize(data)
|
|
28
28
|
if (data.data) image.data = data.data
|
|
@@ -38,9 +38,18 @@ function makeImage(data) {
|
|
|
38
38
|
return true
|
|
39
39
|
},
|
|
40
40
|
get size() {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
)
|
|
41
|
+
const croppedSize = utils.geometry.size(transforms.crop || size)
|
|
42
|
+
const scaledSize = utils.geometry.scale(croppedSize, transforms.scale)
|
|
43
|
+
const rotatedSize = utils.geometry.rotate(scaledSize, transforms.rotate)
|
|
44
|
+
return utils.geometry.round(rotatedSize)
|
|
45
|
+
},
|
|
46
|
+
get unscaledSize() {
|
|
47
|
+
const croppedSize = utils.geometry.size(transforms.crop || size)
|
|
48
|
+
const rotatedSize = utils.geometry.rotate(croppedSize, transforms.rotate)
|
|
49
|
+
return utils.geometry.round(rotatedSize)
|
|
50
|
+
},
|
|
51
|
+
get rawSize() {
|
|
52
|
+
return size
|
|
44
53
|
},
|
|
45
54
|
get transforms() {
|
|
46
55
|
return {...transforms}
|
|
@@ -53,12 +62,10 @@ function makeImage(data) {
|
|
|
53
62
|
},
|
|
54
63
|
scale(ratio) {
|
|
55
64
|
transforms.scale *= ratio
|
|
56
|
-
// size = utils.geometry.scale(size, ratio)
|
|
57
65
|
return this
|
|
58
66
|
},
|
|
59
67
|
rotate(degrees) {
|
|
60
68
|
transforms.rotate = (transforms.rotate + degrees) % 360
|
|
61
|
-
// size = utils.geometry.rotate(size, degrees)
|
|
62
69
|
return this
|
|
63
70
|
},
|
|
64
71
|
crop(region) {
|
|
@@ -77,39 +84,47 @@ function makeImage(data) {
|
|
|
77
84
|
? utils.geometry.intersect(transforms.crop, utils.geometry.offset(region, transforms.crop))
|
|
78
85
|
: utils.geometry.intersect({x: 0, y: 0, ...size}, region)
|
|
79
86
|
transforms.crop = region
|
|
80
|
-
size = utils.geometry.size(transforms.crop)
|
|
81
87
|
return this
|
|
82
88
|
},
|
|
83
89
|
copy(srcImage, offset) {
|
|
84
|
-
|
|
90
|
+
// if "auto" image and this is first chunk
|
|
91
|
+
if (!image && size.width === -1 && size.height === -1) transforms.scale = srcImage.transforms.scale
|
|
92
|
+
|
|
93
|
+
const unscaledOffset = utils.geometry.scale(offset, 1 / transforms.scale)
|
|
94
|
+
|
|
85
95
|
if (!image) {
|
|
86
96
|
size = {
|
|
87
|
-
width: Math.max(Math.floor(
|
|
88
|
-
height: Math.max(Math.floor(
|
|
97
|
+
width: Math.max(Math.floor(unscaledOffset.x) + srcImage.unscaledSize.width, size.width),
|
|
98
|
+
height: Math.max(Math.floor(unscaledOffset.y) + srcImage.unscaledSize.height, size.height),
|
|
89
99
|
}
|
|
90
|
-
transforms.scale = Math.min(scale, transforms.scale)
|
|
91
100
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
101
|
+
|
|
102
|
+
const unscale =
|
|
103
|
+
srcImage.transforms.scale === transforms.scale
|
|
104
|
+
? 1 / srcImage.transforms.scale
|
|
105
|
+
: srcImage.transforms.scale / transforms.scale
|
|
106
|
+
|
|
107
|
+
transforms.modifiers.push({type: 'copy', image: srcImage.scale(unscale).toObject(), offset: unscaledOffset})
|
|
97
108
|
|
|
98
109
|
return this
|
|
99
110
|
},
|
|
100
111
|
frame(topImage, bottomImage, region) {
|
|
101
|
-
const scale = topImage.transforms.scale
|
|
102
112
|
const prevSize = size
|
|
103
|
-
|
|
113
|
+
const unscaledRegion = utils.geometry.scale(region, 1 / topImage.transforms.scale)
|
|
104
114
|
size = {
|
|
105
|
-
width: Math.floor(topImage.width
|
|
106
|
-
height: Math.floor(topImage.height
|
|
115
|
+
width: Math.floor(topImage.unscaledSize.width + Math.max(size.width - unscaledRegion.width, 0)),
|
|
116
|
+
height: Math.floor(topImage.unscaledSize.height + Math.max(size.height - unscaledRegion.height, 0)),
|
|
107
117
|
}
|
|
118
|
+
|
|
119
|
+
const unscale =
|
|
120
|
+
topImage.transforms.scale === transforms.scale
|
|
121
|
+
? 1 / topImage.transforms.scale
|
|
122
|
+
: topImage.transforms.scale / transforms.scale
|
|
108
123
|
transforms.modifiers.push({
|
|
109
124
|
type: 'frame',
|
|
110
|
-
top: topImage.scale(
|
|
111
|
-
bottom: bottomImage.scale(
|
|
112
|
-
region,
|
|
125
|
+
top: topImage.scale(unscale).toObject(),
|
|
126
|
+
bottom: bottomImage.scale(unscale).toObject(),
|
|
127
|
+
region: unscaledRegion,
|
|
113
128
|
})
|
|
114
129
|
transforms.added = {width: size.width - prevSize.width, height: size.height - prevSize.height}
|
|
115
130
|
return this
|
package/src/scroller.js
CHANGED
|
@@ -80,7 +80,6 @@ function makeScroller({logger, element, scrollingMode = 'mixed'}) {
|
|
|
80
80
|
|
|
81
81
|
async function scrollTo(offset, element = defaultElement) {
|
|
82
82
|
try {
|
|
83
|
-
// offset = {x: Math.max(offset.x, 0), y: Math.max(offset.y, 0)}
|
|
84
83
|
const scrollOffset = await element.scrollTo(offset)
|
|
85
84
|
return scrollOffset
|
|
86
85
|
} catch (err) {
|
|
@@ -92,7 +91,6 @@ function makeScroller({logger, element, scrollingMode = 'mixed'}) {
|
|
|
92
91
|
|
|
93
92
|
async function translateTo(offset, element = defaultElement) {
|
|
94
93
|
try {
|
|
95
|
-
// offset = {x: Math.max(offset.x, 0), y: Math.max(offset.y, 0)}
|
|
96
94
|
await element.scrollTo({x: 0, y: 0})
|
|
97
95
|
const translateOffset = await element.translateTo(offset)
|
|
98
96
|
return translateOffset
|
|
@@ -105,8 +103,15 @@ function makeScroller({logger, element, scrollingMode = 'mixed'}) {
|
|
|
105
103
|
|
|
106
104
|
async function shiftTo(offset, element = defaultElement) {
|
|
107
105
|
try {
|
|
108
|
-
// offset = {x: Math.max(offset.x, 0), y: Math.max(offset.y, 0)}
|
|
109
106
|
const scrollOffset = await element.scrollTo(offset)
|
|
107
|
+
if (utils.geometry.equals(scrollOffset, offset)) return scrollOffset
|
|
108
|
+
|
|
109
|
+
// there is a "bug" in iOS that will not move a root element if it already scrolled, so it should be translated all the way
|
|
110
|
+
if (element.driver.isIOS && (await element.isRoot())) {
|
|
111
|
+
const translateOffset = await element.translateTo(offset)
|
|
112
|
+
return translateOffset
|
|
113
|
+
}
|
|
114
|
+
|
|
110
115
|
const remainingOffset = utils.geometry.offsetNegative(offset, scrollOffset)
|
|
111
116
|
const translateOffset = await element.translateTo(remainingOffset)
|
|
112
117
|
|
package/src/take-screenshot.js
CHANGED
|
@@ -60,6 +60,8 @@ async function takeScreenshot({
|
|
|
60
60
|
? await takeStitchedScreenshot({...target, withStatusBar, overlap, framed, wait, stabilization, debug, logger})
|
|
61
61
|
: await takeSimpleScreenshot({...target, withStatusBar, wait, stabilization, debug, logger})
|
|
62
62
|
|
|
63
|
+
screenshot.image.scale(driver.viewportScale)
|
|
64
|
+
|
|
63
65
|
if (hooks && hooks.afterScreenshot) {
|
|
64
66
|
// imitate image-like state for the hook
|
|
65
67
|
if (window && fully && target.scroller) {
|
|
@@ -33,7 +33,7 @@ function makeTakeDefaultScreenshot({driver, stabilization = {}, debug, logger})
|
|
|
33
33
|
await image.debug({...debug, name, suffix: 'original'})
|
|
34
34
|
|
|
35
35
|
if (stabilization.scale) image.scale(stabilization.scale)
|
|
36
|
-
else image.scale(1 / driver.pixelRatio)
|
|
36
|
+
else image.scale(1 / driver.pixelRatio / driver.viewportScale)
|
|
37
37
|
|
|
38
38
|
if (stabilization.rotate) image.crop(stabilization.rotate)
|
|
39
39
|
|
|
@@ -53,7 +53,7 @@ function makeTakeMainContextScreenshot({driver, stabilization = {}, debug, logge
|
|
|
53
53
|
await image.debug({...debug, name, suffix: 'original'})
|
|
54
54
|
|
|
55
55
|
if (stabilization.scale) image.scale(stabilization.scale)
|
|
56
|
-
else image.scale(1 / driver.pixelRatio)
|
|
56
|
+
else image.scale(1 / driver.pixelRatio / driver.viewportScale)
|
|
57
57
|
|
|
58
58
|
if (stabilization.rotate) image.rotate(stabilization.rotate)
|
|
59
59
|
|
|
@@ -72,7 +72,7 @@ function makeTakeSafari11Screenshot({driver, stabilization = {}, debug, logger})
|
|
|
72
72
|
await image.debug({...debug, name, suffix: 'original'})
|
|
73
73
|
|
|
74
74
|
if (stabilization.scale) image.scale(stabilization.scale)
|
|
75
|
-
else image.scale(1 / driver.pixelRatio)
|
|
75
|
+
else image.scale(1 / driver.pixelRatio / driver.viewportScale)
|
|
76
76
|
|
|
77
77
|
if (stabilization.rotate) image.rotate(stabilization.rotate)
|
|
78
78
|
|
|
@@ -96,7 +96,7 @@ function makeTakeMarkedScreenshot({driver, stabilization = {}, debug, logger}) {
|
|
|
96
96
|
await image.debug({...debug, name, suffix: 'original'})
|
|
97
97
|
|
|
98
98
|
if (stabilization.scale) image.scale(stabilization.scale)
|
|
99
|
-
else image.scale(1 / driver.pixelRatio)
|
|
99
|
+
else image.scale(1 / driver.pixelRatio / driver.viewportScale)
|
|
100
100
|
|
|
101
101
|
if (stabilization.rotate) image.rotate(stabilization.rotate)
|
|
102
102
|
else if (driver.orientation === 'landscape' && image.width < image.height) image.rotate(-90)
|
|
@@ -113,7 +113,13 @@ function makeTakeMarkedScreenshot({driver, stabilization = {}, debug, logger}) {
|
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
async function getViewportRegion() {
|
|
116
|
-
|
|
116
|
+
// marker is -> bwb bwbb wbw bwbb wbww bbb
|
|
117
|
+
const marker = await driver.mainContext.execute(snippets.addPageMarker, [
|
|
118
|
+
{
|
|
119
|
+
mask: [1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1],
|
|
120
|
+
size: utils.math.multiplier(driver.viewportScale * driver.pixelRatio, 0.05),
|
|
121
|
+
},
|
|
122
|
+
])
|
|
117
123
|
await utils.general.sleep(100)
|
|
118
124
|
|
|
119
125
|
try {
|
|
@@ -124,12 +130,16 @@ function makeTakeMarkedScreenshot({driver, stabilization = {}, debug, logger}) {
|
|
|
124
130
|
|
|
125
131
|
await image.debug({...debug, name: 'marker'})
|
|
126
132
|
|
|
127
|
-
const markerLocation = findImagePattern(await image.toObject(), {
|
|
133
|
+
const markerLocation = findImagePattern(await image.toObject(), {
|
|
134
|
+
...marker,
|
|
135
|
+
scale: driver.viewportScale * driver.pixelRatio,
|
|
136
|
+
})
|
|
128
137
|
if (!markerLocation) return null
|
|
129
138
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
139
|
+
return utils.geometry.region(
|
|
140
|
+
utils.geometry.scale(markerLocation, 1 / driver.pixelRatio / driver.viewportScale),
|
|
141
|
+
await driver.getViewportSize(),
|
|
142
|
+
)
|
|
133
143
|
} finally {
|
|
134
144
|
await driver.mainContext.execute(snippets.cleanupPageMarker)
|
|
135
145
|
}
|
|
@@ -143,7 +153,7 @@ function makeTakeNativeScreenshot({driver, stabilization = {}, debug, logger}) {
|
|
|
143
153
|
await image.debug({...debug, name, suffix: 'original'})
|
|
144
154
|
|
|
145
155
|
if (stabilization.scale) image.scale(stabilization.scale)
|
|
146
|
-
else image.scale(1 / driver.pixelRatio)
|
|
156
|
+
else image.scale(1 / driver.pixelRatio / driver.viewportScale)
|
|
147
157
|
|
|
148
158
|
if (stabilization.rotate) image.rotate(stabilization.rotate)
|
|
149
159
|
else if (driver.orientation === 'landscape' && image.width < image.height) image.rotate(-90)
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dry-run",
|
|
3
|
-
"lockfileVersion": 2,
|
|
4
|
-
"requires": true,
|
|
5
|
-
"packages": {
|
|
6
|
-
"": {
|
|
7
|
-
"dependencies": {
|
|
8
|
-
"@applitools/screenshoter": "file:../dry-run.tgz"
|
|
9
|
-
}
|
|
10
|
-
},
|
|
11
|
-
"node_modules/@applitools/screenshoter": {
|
|
12
|
-
"version": "3.3.2",
|
|
13
|
-
"resolved": "file:../dry-run.tgz",
|
|
14
|
-
"integrity": "sha512-5epXLfRKO+64jIbxTYwUMUui0xGPQmwccz5aMlLg2V1gtgyrcZ689cn7n8jDBWPCt1Ds0MNEZCimcDjGiAXb4Q==",
|
|
15
|
-
"license": "SEE LICENSE IN LICENSE",
|
|
16
|
-
"dependencies": {
|
|
17
|
-
"@applitools/snippets": "2.1.11",
|
|
18
|
-
"@applitools/utils": "1.2.5",
|
|
19
|
-
"png-async": "0.9.4"
|
|
20
|
-
},
|
|
21
|
-
"engines": {
|
|
22
|
-
"node": ">= 8.9.0"
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
"node_modules/@applitools/snippets": {
|
|
26
|
-
"version": "2.1.11",
|
|
27
|
-
"resolved": "https://registry.npmjs.org/@applitools/snippets/-/snippets-2.1.11.tgz",
|
|
28
|
-
"integrity": "sha512-uNx2sqFACva5Lt23NvYjnxkbUoyAmoCN8dVtAFOhL2a0HyxzYKP5z0tCT/JK8QqM3gkSzeQ0rT0FdxQ9UAl7Og==",
|
|
29
|
-
"engines": {
|
|
30
|
-
"node": ">=8.9.0"
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"node_modules/@applitools/utils": {
|
|
34
|
-
"version": "1.2.5",
|
|
35
|
-
"resolved": "https://registry.npmjs.org/@applitools/utils/-/utils-1.2.5.tgz",
|
|
36
|
-
"integrity": "sha512-nETSgqGeCk5yqjFaQ7x1KURf+t5IxsY2RoeFB5w1+6lHprmHdEithMcN0tiJWeqi14QBJdUkXCzCJrMW5RcDFg==",
|
|
37
|
-
"engines": {
|
|
38
|
-
"node": ">= 8.9.0"
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
"node_modules/png-async": {
|
|
42
|
-
"version": "0.9.4",
|
|
43
|
-
"resolved": "https://registry.npmjs.org/png-async/-/png-async-0.9.4.tgz",
|
|
44
|
-
"integrity": "sha512-B//AXX9TkneKfgtOpT1mdUnnhk2BImGD+a98vImsMU8uo1dBeHyW/kM2erWZ/CsYteTPU/xKG+t6T62heHkC3A=="
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
"dependencies": {
|
|
48
|
-
"@applitools/screenshoter": {
|
|
49
|
-
"version": "file:../dry-run.tgz",
|
|
50
|
-
"integrity": "sha512-5epXLfRKO+64jIbxTYwUMUui0xGPQmwccz5aMlLg2V1gtgyrcZ689cn7n8jDBWPCt1Ds0MNEZCimcDjGiAXb4Q==",
|
|
51
|
-
"requires": {
|
|
52
|
-
"@applitools/snippets": "2.1.11",
|
|
53
|
-
"@applitools/utils": "1.2.5",
|
|
54
|
-
"png-async": "0.9.4"
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
"@applitools/snippets": {
|
|
58
|
-
"version": "2.1.11",
|
|
59
|
-
"resolved": "https://registry.npmjs.org/@applitools/snippets/-/snippets-2.1.11.tgz",
|
|
60
|
-
"integrity": "sha512-uNx2sqFACva5Lt23NvYjnxkbUoyAmoCN8dVtAFOhL2a0HyxzYKP5z0tCT/JK8QqM3gkSzeQ0rT0FdxQ9UAl7Og=="
|
|
61
|
-
},
|
|
62
|
-
"@applitools/utils": {
|
|
63
|
-
"version": "1.2.5",
|
|
64
|
-
"resolved": "https://registry.npmjs.org/@applitools/utils/-/utils-1.2.5.tgz",
|
|
65
|
-
"integrity": "sha512-nETSgqGeCk5yqjFaQ7x1KURf+t5IxsY2RoeFB5w1+6lHprmHdEithMcN0tiJWeqi14QBJdUkXCzCJrMW5RcDFg=="
|
|
66
|
-
},
|
|
67
|
-
"png-async": {
|
|
68
|
-
"version": "0.9.4",
|
|
69
|
-
"resolved": "https://registry.npmjs.org/png-async/-/png-async-0.9.4.tgz",
|
|
70
|
-
"integrity": "sha512-B//AXX9TkneKfgtOpT1mdUnnhk2BImGD+a98vImsMU8uo1dBeHyW/kM2erWZ/CsYteTPU/xKG+t6T62heHkC3A=="
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
package/.bongo/dry-run.tgz
DELETED
|
Binary file
|
package/.eslintrc
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"env": {
|
|
3
|
-
"commonjs": true,
|
|
4
|
-
"es6": true,
|
|
5
|
-
"node": true,
|
|
6
|
-
"mocha": true
|
|
7
|
-
},
|
|
8
|
-
"parserOptions": {
|
|
9
|
-
"ecmaVersion": 2018,
|
|
10
|
-
"sourceType": "module"
|
|
11
|
-
},
|
|
12
|
-
"extends": ["plugin:node/recommended"],
|
|
13
|
-
"plugins": ["prettier", "mocha-no-only", "node"],
|
|
14
|
-
"ignorePatterns": [
|
|
15
|
-
"node_modules/",
|
|
16
|
-
"dist/",
|
|
17
|
-
"screenshots/",
|
|
18
|
-
"applitools.config.js",
|
|
19
|
-
"logs",
|
|
20
|
-
"tmp/",
|
|
21
|
-
"**/test/coverage/generic/"
|
|
22
|
-
],
|
|
23
|
-
"rules": {
|
|
24
|
-
"prettier/prettier": ["error", {"allowParens": "avoid", "printWidth": 120}],
|
|
25
|
-
"no-process-exit": "off",
|
|
26
|
-
"no-const-assign": "error",
|
|
27
|
-
"no-this-before-super": "error",
|
|
28
|
-
"no-undef": "warn",
|
|
29
|
-
"no-unreachable": "warn",
|
|
30
|
-
"no-unused-vars": [
|
|
31
|
-
1,
|
|
32
|
-
{"varsIgnorePattern": "^_", "args": "all", "argsIgnorePattern": "^_"}
|
|
33
|
-
],
|
|
34
|
-
"constructor-super": "warn",
|
|
35
|
-
"valid-typeof": "warn",
|
|
36
|
-
"mocha-no-only/mocha-no-only": "error",
|
|
37
|
-
"node/no-unpublished-require": ["off"]
|
|
38
|
-
}
|
|
39
|
-
}
|
package/docker-compose.yaml
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": "3.4",
|
|
3
|
-
"services": {
|
|
4
|
-
"chrome": {
|
|
5
|
-
"image": "selenium/standalone-chrome",
|
|
6
|
-
"environment": [
|
|
7
|
-
"SE_NODE_OVERRIDE_MAX_SESSIONS=true",
|
|
8
|
-
"SE_NODE_MAX_SESSIONS=30"
|
|
9
|
-
],
|
|
10
|
-
"volumes": [
|
|
11
|
-
"/dev/shm:/dev/shm"
|
|
12
|
-
],
|
|
13
|
-
"network_mode": "host"
|
|
14
|
-
},
|
|
15
|
-
"firefox": {
|
|
16
|
-
"image": "selenium/standalone-firefox",
|
|
17
|
-
"environment": [
|
|
18
|
-
"SE_NODE_OVERRIDE_MAX_SESSIONS=true",
|
|
19
|
-
"SE_NODE_MAX_SESSIONS=30"
|
|
20
|
-
],
|
|
21
|
-
"volumes": [
|
|
22
|
-
"/dev/shm:/dev/shm"
|
|
23
|
-
],
|
|
24
|
-
"ports": [
|
|
25
|
-
"4445:4444"
|
|
26
|
-
]
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|