@applitools/screenshoter 3.3.22 → 3.3.25

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applitools/screenshoter",
3
- "version": "3.3.22",
3
+ "version": "3.3.25",
4
4
  "description": "Applitools universal screenshoter for web and native applications",
5
5
  "keywords": [
6
6
  "applitools",
@@ -25,6 +25,13 @@
25
25
  "name": "Applitools Team",
26
26
  "email": "team@applitools.com"
27
27
  },
28
+ "exports": {
29
+ ".": {
30
+ "default": "./index.js"
31
+ },
32
+ "./src/*": "./src/*",
33
+ "./package.json": "./package.json"
34
+ },
28
35
  "main": "./index.js",
29
36
  "files": [
30
37
  "src",
@@ -35,7 +42,7 @@
35
42
  "test": "yarn test:it && yarn test:e2e",
36
43
  "test:unit": "mocha ./test/unit/*.spec.js --no-timeouts",
37
44
  "test:it": "mocha ./test/it/*.spec.js --no-timeouts",
38
- "test:e2e": "yarn test:e2e:web && yarn && test:e2e:android && yarn test:e2e:ios",
45
+ "test:e2e": "yarn test:e2e:web && yarn && yarn test:e2e:android && yarn test:e2e:ios",
39
46
  "test:e2e:web": "mocha ./test/e2e/web/*.spec.js --no-timeouts -r @applitools/test-utils/mocha-hooks/docker",
40
47
  "test:e2e:android": "APPLITOOLS_TEST_REMOTE=sauce mocha ./test/e2e/android*/*.spec.js --no-timeouts --parallel --jobs ${MOCHA_JOBS:-2}",
41
48
  "test:e2e:ios": "APPLITOOLS_TEST_REMOTE=sauce mocha ./test/e2e/ios*/*.spec.js --no-timeouts --parallel --jobs ${MOCHA_JOBS:-2}",
@@ -60,30 +67,31 @@
60
67
  }
61
68
  },
62
69
  "dependencies": {
63
- "@applitools/logger": "1.1.5",
70
+ "@applitools/logger": "1.1.6",
64
71
  "@applitools/snippets": "2.2.3",
65
- "@applitools/utils": "1.3.0",
72
+ "@applitools/utils": "1.3.1",
73
+ "jpeg-js": "0.4.3",
66
74
  "png-async": "0.9.4"
67
75
  },
68
76
  "devDependencies": {
69
- "@applitools/bongo": "^2.0.3",
70
- "@applitools/driver": "^1.8.12",
77
+ "@applitools/bongo": "^2.1.1",
78
+ "@applitools/driver": "^1.8.14",
71
79
  "@applitools/scripts": "1.1.0",
72
- "@applitools/spec-driver-webdriverio": "1.2.9",
80
+ "@applitools/spec-driver-webdriverio": "1.2.10",
73
81
  "@applitools/test-utils": "1.3.2",
74
82
  "appium": "^1.22.3",
75
- "chromedriver": "^95.0.0",
76
- "eslint": "^7.9.0",
83
+ "chromedriver": "^101.0.0",
84
+ "eslint": "^8.16.0",
77
85
  "eslint-plugin-mocha-no-only": "^1.1.1",
78
86
  "eslint-plugin-node": "^11.1.0",
79
- "eslint-plugin-prettier": "^3.1.4",
87
+ "eslint-plugin-prettier": "^4.0.0",
80
88
  "husky": "^4.3.8",
81
- "mocha": "^9.2.0",
82
- "pixelmatch": "^5.2.1",
83
- "prettier": "1.19.0",
84
- "webdriverio": "^7.16.7"
89
+ "mocha": "^10.0.0",
90
+ "pixelmatch": "^5.3.0",
91
+ "prettier": "2.6.2",
92
+ "webdriverio": "^7.19.7"
85
93
  },
86
94
  "engines": {
87
- "node": ">= 10.0.0"
95
+ "node": ">=12.13.0"
88
96
  }
89
97
  }
package/src/image.js CHANGED
@@ -2,6 +2,7 @@ const fs = require('fs')
2
2
  const stream = require('stream')
3
3
  const path = require('path')
4
4
  const png = require('png-async')
5
+ const jpeg = require('jpeg-js')
5
6
  const utils = require('@applitools/utils')
6
7
 
7
8
  function makeImage(data) {
@@ -9,16 +10,19 @@ function makeImage(data) {
9
10
  let transforms = {rotate: 0, scale: 1, crop: null, modifiers: []}
10
11
 
11
12
  if (utils.types.isBase64(data)) {
12
- const buffer = Buffer.from(data, 'base64')
13
- image = fromBuffer(buffer)
14
- size = extractPngSize(buffer)
13
+ return makeImage(Buffer.from(data, 'base64'))
15
14
  } else if (utils.types.isString(data)) {
16
- const buffer = fs.readFileSync(data)
17
- image = fromBuffer(buffer)
18
- size = extractPngSize(buffer)
15
+ return makeImage(fs.readFileSync(data))
19
16
  } else if (Buffer.isBuffer(data)) {
20
- image = fromBuffer(data)
21
- size = extractPngSize(data)
17
+ if (isPngBuffer(data)) {
18
+ image = fromPngBuffer(data)
19
+ size = extractPngSize(data)
20
+ } else if (isJpegBuffer(data)) {
21
+ image = fromJpegBuffer(data)
22
+ size = extractJpegSize(data)
23
+ } else {
24
+ throw new Error('Unable to create an image abstraction from buffer with unknown data')
25
+ }
22
26
  } else if (data.isImage) {
23
27
  transforms = data.transforms
24
28
  image = data.toRaw()
@@ -41,12 +45,12 @@ function makeImage(data) {
41
45
  const croppedSize = utils.geometry.size(transforms.crop || size)
42
46
  const scaledSize = utils.geometry.scale(croppedSize, transforms.scale)
43
47
  const rotatedSize = utils.geometry.rotate(scaledSize, transforms.rotate)
44
- return utils.geometry.round(rotatedSize)
48
+ return utils.geometry.ceil(rotatedSize)
45
49
  },
46
50
  get unscaledSize() {
47
51
  const croppedSize = utils.geometry.size(transforms.crop || size)
48
52
  const rotatedSize = utils.geometry.rotate(croppedSize, transforms.rotate)
49
- return utils.geometry.round(rotatedSize)
53
+ return utils.geometry.ceil(rotatedSize)
50
54
  },
51
55
  get rawSize() {
52
56
  return size
@@ -158,17 +162,39 @@ function makeImage(data) {
158
162
  }
159
163
  }
160
164
 
161
- function extractPngSize(buffer) {
165
+ function isPngBuffer(buffer) {
162
166
  return buffer.slice(12, 16).toString('ascii') === 'IHDR'
163
- ? {width: buffer.readUInt32BE(16), height: buffer.readUInt32BE(20)}
164
- : {width: 0, height: 0}
167
+ }
168
+
169
+ function isJpegBuffer(buffer) {
170
+ return buffer.slice(6, 10).toString('ascii') === 'JFIF'
171
+ }
172
+
173
+ function extractPngSize(buffer) {
174
+ return {width: buffer.readUInt32BE(16), height: buffer.readUInt32BE(20)}
175
+ }
176
+
177
+ function extractJpegSize(buffer) {
178
+ // skip file signature
179
+ let offset = 4
180
+ while (buffer.length > offset) {
181
+ // extract length of the block
182
+ offset += buffer.readUInt16BE(offset)
183
+ // if next segment is SOF extract size
184
+ if (buffer[offset + 1] === 0xc0) {
185
+ return {width: buffer.readUInt16BE(offset + 7), height: buffer.readUInt16BE(offset + 5)}
186
+ } else {
187
+ // skip block signature
188
+ offset += 2
189
+ }
190
+ }
165
191
  }
166
192
 
167
193
  function fromSize(size) {
168
194
  return new png.Image({width: size.width, height: size.height})
169
195
  }
170
196
 
171
- async function fromBuffer(buffer) {
197
+ async function fromPngBuffer(buffer) {
172
198
  return new Promise((resolve, reject) => {
173
199
  const image = new png.Image()
174
200
 
@@ -179,6 +205,10 @@ async function fromBuffer(buffer) {
179
205
  })
180
206
  }
181
207
 
208
+ async function fromJpegBuffer(buffer) {
209
+ return jpeg.decode(buffer, {tolerantDecoding: true, formatAsRGBA: true})
210
+ }
211
+
182
212
  async function toPng(image) {
183
213
  return new Promise((resolve, reject) => {
184
214
  let buffer = Buffer.alloc(0)
@@ -63,7 +63,9 @@ async function takeScreenshot({
63
63
  if (!window && !driver.isNative) {
64
64
  await scrollIntoViewport({context: target.context, region: target.region, scroller: target.scroller, logger})
65
65
  }
66
-
66
+ if (fully && !target.region && target.scroller) {
67
+ await target.scroller.moveTo({x: 0, y: 0})
68
+ }
67
69
  const screenshot =
68
70
  fully && target.scroller
69
71
  ? await takeStitchedScreenshot({