@applitools/screenshoter 3.3.1 → 3.3.2
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/.bongo/dry-run/package-lock.json +11 -11
- package/.bongo/dry-run.tgz +0 -0
- package/CHANGELOG.md +5 -0
- package/package.json +3 -3
- package/src/find-image-pattern.js +2 -1
- package/src/take-viewport-screenshot.js +8 -8
- package/test/e2e/android.spec.js +44 -1
- package/test/e2e/ios.spec.js +82 -5
- 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/web-ios/page-fully.png +0 -0
- package/test/fixtures/web-ios/page.png +0 -0
- package/test/it/find-pattern.spec.js +1 -1
- package/logs/screenshot_2021_12_16_19_06_06_332Z_full_app_failed_1639681566332.png +0 -0
- package/logs/screenshot_2021_12_16_19_15_59_935Z_full_app_failed_1639682159935.png +0 -0
- package/logs/screenshot_2021_12_16_19_33_20_679Z_full_app_failed_1639683200679.png +0 -0
- package/logs/screenshot_2021_12_16_19_37_22_120Z_ios_viewport_failed.png +0 -0
- package/logs/screenshot_2021_12_16_19_38_09_461Z_ios_full_page_failed.png +0 -0
- package/logs/screenshot_2021_12_16_19_59_45_182Z_ios_viewport_failed.png +0 -0
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
11
|
"node_modules/@applitools/screenshoter": {
|
|
12
|
-
"version": "3.3.
|
|
12
|
+
"version": "3.3.1",
|
|
13
13
|
"resolved": "file:../dry-run.tgz",
|
|
14
|
-
"integrity": "sha512-
|
|
14
|
+
"integrity": "sha512-Nn4m2tV2g1+ECbNzbJ4NJzvpx02lYAZ6MM4HXuT16ShCZPXi2fCuvnJEZX3D5j/EkZjEB6yFZWXrKT70m2Djew==",
|
|
15
15
|
"license": "SEE LICENSE IN LICENSE",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@applitools/snippets": "2.1.
|
|
17
|
+
"@applitools/snippets": "2.1.10",
|
|
18
18
|
"@applitools/utils": "1.2.4",
|
|
19
19
|
"png-async": "0.9.4"
|
|
20
20
|
},
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"node_modules/@applitools/snippets": {
|
|
26
|
-
"version": "2.1.
|
|
27
|
-
"resolved": "https://registry.npmjs.org/@applitools/snippets/-/snippets-2.1.
|
|
28
|
-
"integrity": "sha512-
|
|
26
|
+
"version": "2.1.10",
|
|
27
|
+
"resolved": "https://registry.npmjs.org/@applitools/snippets/-/snippets-2.1.10.tgz",
|
|
28
|
+
"integrity": "sha512-LGjtd8IZOwbhETqKRDX9CX85+BskkFUkuMuLvriSDEEQiSm0MpFbbcJVMjYaVL2qobaJbY+3WvK0g7+gkZuuqA==",
|
|
29
29
|
"engines": {
|
|
30
30
|
"node": ">=8.9.0"
|
|
31
31
|
}
|
|
@@ -47,17 +47,17 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@applitools/screenshoter": {
|
|
49
49
|
"version": "file:../dry-run.tgz",
|
|
50
|
-
"integrity": "sha512-
|
|
50
|
+
"integrity": "sha512-Nn4m2tV2g1+ECbNzbJ4NJzvpx02lYAZ6MM4HXuT16ShCZPXi2fCuvnJEZX3D5j/EkZjEB6yFZWXrKT70m2Djew==",
|
|
51
51
|
"requires": {
|
|
52
|
-
"@applitools/snippets": "2.1.
|
|
52
|
+
"@applitools/snippets": "2.1.10",
|
|
53
53
|
"@applitools/utils": "1.2.4",
|
|
54
54
|
"png-async": "0.9.4"
|
|
55
55
|
}
|
|
56
56
|
},
|
|
57
57
|
"@applitools/snippets": {
|
|
58
|
-
"version": "2.1.
|
|
59
|
-
"resolved": "https://registry.npmjs.org/@applitools/snippets/-/snippets-2.1.
|
|
60
|
-
"integrity": "sha512-
|
|
58
|
+
"version": "2.1.10",
|
|
59
|
+
"resolved": "https://registry.npmjs.org/@applitools/snippets/-/snippets-2.1.10.tgz",
|
|
60
|
+
"integrity": "sha512-LGjtd8IZOwbhETqKRDX9CX85+BskkFUkuMuLvriSDEEQiSm0MpFbbcJVMjYaVL2qobaJbY+3WvK0g7+gkZuuqA=="
|
|
61
61
|
},
|
|
62
62
|
"@applitools/utils": {
|
|
63
63
|
"version": "1.2.4",
|
package/.bongo/dry-run.tgz
CHANGED
|
Binary file
|
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applitools/screenshoter",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.2",
|
|
4
4
|
"description": "Applitools universal screenshoter for web and native applications",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"applitools",
|
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
}
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@applitools/snippets": "2.1.
|
|
52
|
+
"@applitools/snippets": "2.1.10",
|
|
53
53
|
"@applitools/utils": "1.2.4",
|
|
54
54
|
"png-async": "0.9.4"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@applitools/driver": "1.4.
|
|
57
|
+
"@applitools/driver": "1.4.5",
|
|
58
58
|
"@applitools/sdk-release-kit": "0.13.4",
|
|
59
59
|
"@applitools/spec-driver-webdriverio": "1.2.2",
|
|
60
60
|
"@applitools/test-utils": "1.0.10",
|
|
@@ -1,7 +1,8 @@
|
|
|
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
|
-
|
|
4
|
+
const patterOffset = pattern.offset * pattern.pixelRatio
|
|
5
|
+
return {x: (pixel % image.width) - patterOffset, y: Math.floor(pixel / image.width) - patterOffset}
|
|
5
6
|
}
|
|
6
7
|
}
|
|
7
8
|
return null
|
|
@@ -7,6 +7,9 @@ function makeTakeViewportScreenshot(options) {
|
|
|
7
7
|
const {driver} = options
|
|
8
8
|
if (driver.isNative) {
|
|
9
9
|
return makeTakeNativeScreenshot(options)
|
|
10
|
+
} else if (driver.isIOS) {
|
|
11
|
+
// safari on ios takes screenshot with browser and os interfaces
|
|
12
|
+
return makeTakeMarkedScreenshot(options)
|
|
10
13
|
} else if (driver.browserName === 'Firefox') {
|
|
11
14
|
try {
|
|
12
15
|
const browserVersion = Number.parseInt(driver.browserVersion, 10)
|
|
@@ -15,14 +18,9 @@ function makeTakeViewportScreenshot(options) {
|
|
|
15
18
|
return makeTakeMainContextScreenshot(options)
|
|
16
19
|
}
|
|
17
20
|
} catch (ignored) {}
|
|
18
|
-
} else if (driver.browserName === 'Safari') {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return makeTakeMarkedScreenshot(options)
|
|
22
|
-
} else if (driver.browserVersion === '11') {
|
|
23
|
-
// safari 11 on macs takes full page screenshot
|
|
24
|
-
return makeTakeSafari11Screenshot(options)
|
|
25
|
-
}
|
|
21
|
+
} else if (driver.browserName === 'Safari' && driver.browserVersion === '11') {
|
|
22
|
+
// safari 11 on macs takes full page screenshot
|
|
23
|
+
return makeTakeSafari11Screenshot(options)
|
|
26
24
|
}
|
|
27
25
|
|
|
28
26
|
return makeTakeDefaultScreenshot(options)
|
|
@@ -119,6 +117,8 @@ function makeTakeMarkedScreenshot({driver, stabilization = {}, debug, logger}) {
|
|
|
119
117
|
|
|
120
118
|
async function getViewportRegion() {
|
|
121
119
|
const marker = await driver.mainContext.execute(snippets.addPageMarker)
|
|
120
|
+
await utils.general.sleep(100)
|
|
121
|
+
|
|
122
122
|
try {
|
|
123
123
|
const image = makeImage(await driver.takeScreenshot())
|
|
124
124
|
|
package/test/e2e/android.spec.js
CHANGED
|
@@ -20,6 +20,17 @@ const env = {
|
|
|
20
20
|
username: process.env.SAUCE_USERNAME,
|
|
21
21
|
accessKey: process.env.SAUCE_ACCESS_KEY,
|
|
22
22
|
},
|
|
23
|
+
|
|
24
|
+
// url: 'http://0.0.0.0:4723/wd/hub',
|
|
25
|
+
// capabilities: {
|
|
26
|
+
// deviceName: 'Google Pixel 3a XL',
|
|
27
|
+
// platformName: 'Android',
|
|
28
|
+
// platformVersion: '10.0',
|
|
29
|
+
// automationName: 'uiautomator2',
|
|
30
|
+
// nativeWebScreenshot: true,
|
|
31
|
+
// avd: 'Pixel_3a_XL',
|
|
32
|
+
// app: 'https://applitools.jfrog.io/artifactory/Examples/android/1.3/app-debug.apk',
|
|
33
|
+
// },
|
|
23
34
|
},
|
|
24
35
|
androidx: {
|
|
25
36
|
url: 'https://ondemand.saucelabs.com/wd/hub',
|
|
@@ -100,6 +111,10 @@ describe('screenshoter', () => {
|
|
|
100
111
|
return fullApp({type: 'non-scrollable'})
|
|
101
112
|
})
|
|
102
113
|
|
|
114
|
+
it.skip('take webview screenshot', () => {
|
|
115
|
+
return webview()
|
|
116
|
+
})
|
|
117
|
+
|
|
103
118
|
it('take region screenshot', () => {
|
|
104
119
|
return region()
|
|
105
120
|
})
|
|
@@ -136,6 +151,10 @@ describe('screenshoter', () => {
|
|
|
136
151
|
return fullApp({type: 'collapsing', x: true})
|
|
137
152
|
})
|
|
138
153
|
|
|
154
|
+
it.skip('take full app screenshot (pager)', () => {
|
|
155
|
+
return fullApp({type: 'pager', x: true})
|
|
156
|
+
})
|
|
157
|
+
|
|
139
158
|
it.skip('take full app screenshot (overlapped status bar)', () => {
|
|
140
159
|
return fullApp({type: 'overlapped', x: true})
|
|
141
160
|
})
|
|
@@ -161,7 +180,10 @@ describe('screenshoter', () => {
|
|
|
161
180
|
}
|
|
162
181
|
async function fullApp({type, x, ...options} = {}) {
|
|
163
182
|
let buttonSelector, expectedPath, scrollingElementSelector
|
|
164
|
-
if (type === '
|
|
183
|
+
if (type === 'pager') {
|
|
184
|
+
buttonSelector = {type: 'id', selector: 'btn_view_pager_2_activity'}
|
|
185
|
+
expectedPath = `./test/fixtures/android/x-app-fully-pager${options.withStatusBar ? '-statusbar' : ''}.png`
|
|
186
|
+
} else if (type === 'overlapped') {
|
|
165
187
|
buttonSelector = {type: 'id', selector: 'btn_recycler_view_under_status_bar_activity'}
|
|
166
188
|
expectedPath = `./test/fixtures/android/x-app-fully-overlapped${options.withStatusBar ? '-statusbar' : ''}.png`
|
|
167
189
|
} else if (type === 'collapsing') {
|
|
@@ -212,6 +234,27 @@ describe('screenshoter', () => {
|
|
|
212
234
|
throw err
|
|
213
235
|
}
|
|
214
236
|
}
|
|
237
|
+
async function webview(options) {
|
|
238
|
+
const expectedPath = `./test/fixtures/android/webview.png`
|
|
239
|
+
const buttonSelector = {type: 'id', selector: 'btn_web_view'}
|
|
240
|
+
|
|
241
|
+
const button = await driver.element(buttonSelector)
|
|
242
|
+
await button.click()
|
|
243
|
+
console.log(await driver.target.getContexts())
|
|
244
|
+
await driver.target.switchContext('WEBVIEW')
|
|
245
|
+
|
|
246
|
+
await driver.init()
|
|
247
|
+
|
|
248
|
+
const screenshot = await takeScreenshot({logger, driver, wait: 1500, ...options})
|
|
249
|
+
try {
|
|
250
|
+
const actual = await screenshot.image.toObject()
|
|
251
|
+
const expected = await makeImage(expectedPath).toObject()
|
|
252
|
+
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0)
|
|
253
|
+
} catch (err) {
|
|
254
|
+
await screenshot.image.debug({path: './logs', name: 'webview_failed', suffix: Date.now()})
|
|
255
|
+
throw err
|
|
256
|
+
}
|
|
257
|
+
}
|
|
215
258
|
async function region(options) {
|
|
216
259
|
const screenshot = await takeScreenshot({
|
|
217
260
|
logger,
|
package/test/e2e/ios.spec.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const assert = require('assert')
|
|
2
2
|
const pixelmatch = require('pixelmatch')
|
|
3
|
+
const utils = require('@applitools/utils')
|
|
3
4
|
const {Driver} = require('@applitools/driver')
|
|
4
5
|
const spec = require('@applitools/spec-driver-webdriverio')
|
|
5
6
|
const makeImage = require('../../src/image')
|
|
@@ -11,10 +12,10 @@ const env = {
|
|
|
11
12
|
name: 'iOS Screenshoter Test',
|
|
12
13
|
deviceName: 'iPhone 11 Pro Simulator',
|
|
13
14
|
platformName: 'iOS',
|
|
14
|
-
platformVersion: '
|
|
15
|
-
appiumVersion: '1.
|
|
15
|
+
platformVersion: '14.5',
|
|
16
|
+
appiumVersion: '1.21.0',
|
|
16
17
|
automationName: 'XCUITest',
|
|
17
|
-
app: 'https://applitools.jfrog.io/artifactory/Examples/IOSTestApp/1.
|
|
18
|
+
app: 'https://applitools.jfrog.io/artifactory/Examples/IOSTestApp/1.9/app/IOSTestApp.zip',
|
|
18
19
|
username: process.env.SAUCE_USERNAME,
|
|
19
20
|
accessKey: process.env.SAUCE_ACCESS_KEY,
|
|
20
21
|
},
|
|
@@ -24,7 +25,8 @@ const env = {
|
|
|
24
25
|
// deviceName: 'iPhone 11 Pro',
|
|
25
26
|
// platformName: 'iOS',
|
|
26
27
|
// platformVersion: '14.5',
|
|
27
|
-
//
|
|
28
|
+
// automationName: 'XCUITest',
|
|
29
|
+
// app: 'https://applitools.jfrog.io/artifactory/Examples/IOSTestApp/1.9/app/IOSTestApp.zip',
|
|
28
30
|
// },
|
|
29
31
|
}
|
|
30
32
|
|
|
@@ -101,6 +103,14 @@ describe('screenshoter ios', () => {
|
|
|
101
103
|
return fullApp({type: 'superview'})
|
|
102
104
|
})
|
|
103
105
|
|
|
106
|
+
it('take webview screenshot', () => {
|
|
107
|
+
return webview()
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
it('take full webview screenshot', () => {
|
|
111
|
+
return fullWebview()
|
|
112
|
+
})
|
|
113
|
+
|
|
104
114
|
it('take region screenshot', () => {
|
|
105
115
|
return region()
|
|
106
116
|
})
|
|
@@ -119,6 +129,10 @@ describe('screenshoter ios', () => {
|
|
|
119
129
|
|
|
120
130
|
async function app(options = {}) {
|
|
121
131
|
const expectedPath = `./test/fixtures/ios/app${options.withStatusBar ? '-statusbar' : ''}.png`
|
|
132
|
+
const buttonSelector = {type: 'accessibility id', selector: 'Empty table view'}
|
|
133
|
+
|
|
134
|
+
const button = await driver.element(buttonSelector)
|
|
135
|
+
await button.click()
|
|
122
136
|
|
|
123
137
|
const screenshot = await takeScreenshot({logger, driver, ...options})
|
|
124
138
|
try {
|
|
@@ -180,7 +194,70 @@ describe('screenshoter ios', () => {
|
|
|
180
194
|
throw err
|
|
181
195
|
}
|
|
182
196
|
}
|
|
197
|
+
async function webview(options) {
|
|
198
|
+
const expectedPath = `./test/fixtures/ios/webview.png`
|
|
199
|
+
const buttonSelector = {type: 'accessibility id', selector: 'Web view'}
|
|
200
|
+
|
|
201
|
+
const button = await driver.element(buttonSelector)
|
|
202
|
+
await button.click()
|
|
203
|
+
await driver.target.getContexts()
|
|
204
|
+
await utils.general.sleep(500)
|
|
205
|
+
const [, webview] = await driver.target.getContexts()
|
|
206
|
+
await driver.target.switchContext(webview)
|
|
207
|
+
|
|
208
|
+
await driver.init()
|
|
209
|
+
|
|
210
|
+
const screenshot = await takeScreenshot({logger, driver, wait: 1500, ...options})
|
|
211
|
+
try {
|
|
212
|
+
const actual = await screenshot.image.toObject()
|
|
213
|
+
const expected = await makeImage(expectedPath).toObject()
|
|
214
|
+
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0)
|
|
215
|
+
} catch (err) {
|
|
216
|
+
await screenshot.image.debug({path: './logs', name: 'webview_failed', suffix: Date.now()})
|
|
217
|
+
throw err
|
|
218
|
+
} finally {
|
|
219
|
+
await driver.target.switchContext('NATIVE_APP')
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
async function fullWebview(options) {
|
|
223
|
+
const expectedPath = `./test/fixtures/ios/webview-fully.png`
|
|
224
|
+
const buttonSelector = {type: 'accessibility id', selector: 'Web view'}
|
|
225
|
+
|
|
226
|
+
const button = await driver.element(buttonSelector)
|
|
227
|
+
await button.click()
|
|
228
|
+
await driver.target.getContexts()
|
|
229
|
+
await utils.general.sleep(500)
|
|
230
|
+
const [, webview] = await driver.target.getContexts()
|
|
231
|
+
await driver.target.switchContext(webview)
|
|
232
|
+
|
|
233
|
+
await driver.init()
|
|
234
|
+
const screenshot = await takeScreenshot({
|
|
235
|
+
logger,
|
|
236
|
+
driver,
|
|
237
|
+
wait: 1500,
|
|
238
|
+
fully: true,
|
|
239
|
+
scrollingMode: 'scroll',
|
|
240
|
+
...options,
|
|
241
|
+
})
|
|
242
|
+
try {
|
|
243
|
+
const actual = await screenshot.image.toObject()
|
|
244
|
+
const expected = await makeImage(expectedPath).toObject()
|
|
245
|
+
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0)
|
|
246
|
+
} catch (err) {
|
|
247
|
+
await screenshot.image.debug({path: './logs', name: 'full_webview_failed', suffix: Date.now()})
|
|
248
|
+
throw err
|
|
249
|
+
} finally {
|
|
250
|
+
await driver.target.switchContext('NATIVE_APP')
|
|
251
|
+
}
|
|
252
|
+
}
|
|
183
253
|
async function region(options) {
|
|
254
|
+
const expectedPath = `./test/fixtures/ios/region.png`
|
|
255
|
+
const buttonSelector = {type: 'accessibility id', selector: 'Empty table view'}
|
|
256
|
+
|
|
257
|
+
const button = await driver.element(buttonSelector)
|
|
258
|
+
await button.click()
|
|
259
|
+
|
|
260
|
+
await driver.init()
|
|
184
261
|
const screenshot = await takeScreenshot({
|
|
185
262
|
logger,
|
|
186
263
|
driver,
|
|
@@ -191,7 +268,7 @@ describe('screenshoter ios', () => {
|
|
|
191
268
|
})
|
|
192
269
|
try {
|
|
193
270
|
const actual = await screenshot.image.toObject()
|
|
194
|
-
const expected = await makeImage(
|
|
271
|
+
const expected = await makeImage(expectedPath).toObject()
|
|
195
272
|
assert.strictEqual(pixelmatch(actual.data, expected.data, null, expected.width, expected.height), 0)
|
|
196
273
|
} catch (err) {
|
|
197
274
|
await screenshot.image.debug({path: './logs', name: 'region_failed'})
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -13,7 +13,7 @@ describe('pattern', () => {
|
|
|
13
13
|
{name: 'iPad_5th_portrait', position: {x: 0, y: 140}, offset: 0, pixelRatio: 2},
|
|
14
14
|
{name: 'iPad_5th_landscape', position: {x: 0, y: 140}, offset: 0, pixelRatio: 2},
|
|
15
15
|
{name: 'iPad_9th_portrait', position: {x: 0, y: 136}, offset: 0, pixelRatio: 2},
|
|
16
|
-
{name: 'iPad_9th_landscape', position: {x:
|
|
16
|
+
{name: 'iPad_9th_landscape', position: {x: 640, y: 136}, offset: 1, pixelRatio: 2},
|
|
17
17
|
{name: 'iPhone_XS_portrait_noviewport', position: {x: 0, y: 282}, offset: 0, pixelRatio: 3},
|
|
18
18
|
{name: 'iPhone_XS_portrait_nomarker', position: null, pixelRatio: 3},
|
|
19
19
|
]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|