@applitools/screenshoter 3.2.6 → 3.3.0
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 +53 -10
- package/.bongo/dry-run/package.json +5 -0
- package/.bongo/dry-run.tgz +0 -0
- package/CHANGELOG.md +18 -0
- package/index.js +2 -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
- package/package.json +11 -7
- package/src/find-image-pattern.js +10 -38
- package/src/image.js +107 -64
- package/src/take-screenshot.js +136 -160
- package/src/take-simple-screenshot.js +25 -0
- package/src/take-stitched-screenshot.js +34 -40
- package/src/take-viewport-screenshot.js +179 -16
- package/test/e2e/android.spec.js +77 -13
- package/test/e2e/external.spec.js +155 -0
- package/test/e2e/ios.spec.js +64 -11
- package/test/e2e/web-ios.spec.js +19 -6
- package/test/e2e/web.spec.js +33 -21
- 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/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.combined-higher-wider.png → house.framed-higher-wider.png} +0 -0
- package/test/fixtures/image/{house.combined-higher.png → house.framed-higher.png} +0 -0
- package/test/fixtures/image/house.framed-shorter-thinner.png +0 -0
- package/test/fixtures/image/{house.combined-wider.png → house.framed-wider.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/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_noviewport.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-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.png +0 -0
- package/test/fixtures/web-ios/page.png +0 -0
- package/test/it/find-pattern.spec.js +16 -11
- package/test/it/image.spec.js +42 -15
- package/logs/screenshot_2021_10_11_13_22_59_543Z_viewport_failed_1633958579543.png +0 -0
- package/logs/screenshot_2021_10_11_13_28_41_375Z_viewport_failed_1633958921375.png +0 -0
- package/logs/screenshot_2021_10_11_13_36_46_414Z_viewport_failed_1633959406414.png +0 -0
- package/logs/screenshot_2021_10_11_13_54_21_340Z_viewport_failed_1633960461340.png +0 -0
- package/logs/screenshot_2021_10_11_14_32_39_581Z_full_app_failed_1633962759581.png +0 -0
- package/src/calculate-screenshot-regions.js +0 -31
- package/src/screenshoter.js +0 -158
- package/test/fixtures/pattern/iPad_Air_portrait.png +0 -0
- package/test/fixtures/pattern/iPhone_5S_landscape.png +0 -0
- package/test/fixtures/pattern/iPhone_XR_perfecto_landscape.png +0 -0
- package/test/fixtures/pattern/iPhone_XS_Max_perfecto_landscape.png +0 -0
- package/test/fixtures/pattern/iPhone_XS_landscape.png +0 -0
- package/test/fixtures/pattern/iPhone_XS_portrait.png +0 -0
- package/test/fixtures/pattern/iPhone_X_perfecto_portrait.png +0 -0
- package/test/util/spec-driver.js +0 -288
package/src/screenshoter.js
DELETED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
const utils = require('@applitools/utils')
|
|
2
|
-
const makeScroller = require('./scroller')
|
|
3
|
-
const scrollIntoViewport = require('./scroll-into-viewport')
|
|
4
|
-
const takeStitchedScreenshot = require('./take-stitched-screenshot')
|
|
5
|
-
const takeViewportScreenshot = require('./take-viewport-screenshot')
|
|
6
|
-
|
|
7
|
-
async function screenshoter({
|
|
8
|
-
driver,
|
|
9
|
-
frames = [],
|
|
10
|
-
region,
|
|
11
|
-
fully,
|
|
12
|
-
scrollingMode,
|
|
13
|
-
hideScrollbars,
|
|
14
|
-
hideCaret,
|
|
15
|
-
withStatusBar,
|
|
16
|
-
overlap,
|
|
17
|
-
framed,
|
|
18
|
-
wait,
|
|
19
|
-
stabilization,
|
|
20
|
-
hooks,
|
|
21
|
-
debug,
|
|
22
|
-
logger,
|
|
23
|
-
}) {
|
|
24
|
-
// screenshot of a window/app was requested (fully or viewport)
|
|
25
|
-
const window = !region && (!frames || frames.length === 0)
|
|
26
|
-
// framed screenshots could be taken only when screenshot of window/app fully was requested
|
|
27
|
-
framed = framed && fully && window
|
|
28
|
-
// screenshots with status bar could be taken only when screenshot of app or framed app fully was requested
|
|
29
|
-
withStatusBar = withStatusBar && driver.isNative && window && (!fully || framed)
|
|
30
|
-
|
|
31
|
-
const activeContext = driver.currentContext
|
|
32
|
-
const context =
|
|
33
|
-
frames.length > 0
|
|
34
|
-
? await activeContext.context(frames.reduce((parent, frame) => ({...frame, parent}), null))
|
|
35
|
-
: activeContext
|
|
36
|
-
|
|
37
|
-
// traverse from main context to target context to hide scrollbars and preserve context state (scroll/translate position)
|
|
38
|
-
for (const nextContext of context.path) {
|
|
39
|
-
const scrollingElement = await nextContext.getScrollingElement()
|
|
40
|
-
// unlike web apps, native apps do not always have scrolling element
|
|
41
|
-
if (scrollingElement) {
|
|
42
|
-
if (driver.isWeb && hideScrollbars) await scrollingElement.hideScrollbars()
|
|
43
|
-
await scrollingElement.preserveState()
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// blur active element in target context
|
|
48
|
-
const activeElement = driver.isWeb && hideCaret ? await context.blurElement() : null
|
|
49
|
-
|
|
50
|
-
const target = await getTarget({window, context, region, fully, scrollingMode, logger})
|
|
51
|
-
|
|
52
|
-
if (driver.isWeb && hideScrollbars) await target.scroller.hideScrollbars()
|
|
53
|
-
|
|
54
|
-
try {
|
|
55
|
-
if (!window) await scrollIntoViewport({...target, logger})
|
|
56
|
-
|
|
57
|
-
const screenshot =
|
|
58
|
-
fully && target.scroller
|
|
59
|
-
? await takeStitchedScreenshot({...target, withStatusBar, overlap, framed, wait, stabilization, debug, logger})
|
|
60
|
-
: await takeViewportScreenshot({...target, withStatusBar, wait, stabilization, debug, logger})
|
|
61
|
-
|
|
62
|
-
if (hooks && hooks.afterScreenshot) {
|
|
63
|
-
// imitate image-like state for the hook
|
|
64
|
-
if (window && fully) {
|
|
65
|
-
await target.scroller.moveTo({x: 0, y: 0}, await driver.mainContext.getScrollingElement())
|
|
66
|
-
}
|
|
67
|
-
await hooks.afterScreenshot({driver, scroller: target.scroller, screenshot})
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return screenshot
|
|
71
|
-
} finally {
|
|
72
|
-
if (target.scroller) {
|
|
73
|
-
await target.scroller.restoreScrollbars()
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// if there was active element and we have blurred it, then restore focus
|
|
77
|
-
if (activeElement) await context.focusElement(activeElement)
|
|
78
|
-
|
|
79
|
-
// traverse from target context to the main context to restore scrollbars and context states
|
|
80
|
-
for (const prevContext of context.path.reverse()) {
|
|
81
|
-
const scrollingElement = await prevContext.getScrollingElement()
|
|
82
|
-
if (scrollingElement) {
|
|
83
|
-
if (driver.isWeb && hideScrollbars) await scrollingElement.restoreScrollbars()
|
|
84
|
-
await scrollingElement.restoreState()
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// restore focus on original active context
|
|
89
|
-
await activeContext.focus()
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
async function getTarget({window, context, region, fully, scrollingMode, logger}) {
|
|
94
|
-
if (window) {
|
|
95
|
-
// window/app
|
|
96
|
-
const scrollingElement = await context.main.getScrollingElement()
|
|
97
|
-
return {
|
|
98
|
-
context: context.main,
|
|
99
|
-
scroller: scrollingElement ? makeScroller({element: scrollingElement, scrollingMode, logger}) : null,
|
|
100
|
-
}
|
|
101
|
-
} else if (region) {
|
|
102
|
-
if (utils.types.has(region, ['x', 'y', 'width', 'height'])) {
|
|
103
|
-
// region by coordinates
|
|
104
|
-
const scrollingElement = await context.getScrollingElement()
|
|
105
|
-
return {
|
|
106
|
-
context,
|
|
107
|
-
region,
|
|
108
|
-
scroller: scrollingElement ? makeScroller({element: scrollingElement, scrollingMode, logger}) : null,
|
|
109
|
-
}
|
|
110
|
-
} else {
|
|
111
|
-
// region by element or selector
|
|
112
|
-
const element = await context.element(region)
|
|
113
|
-
if (!element) throw new Error('Element not found!')
|
|
114
|
-
|
|
115
|
-
const elementContext = element.context
|
|
116
|
-
|
|
117
|
-
if (fully) {
|
|
118
|
-
const isScrollable = await element.isScrollable()
|
|
119
|
-
// if element is scrollable, then take screenshot of the full element content, otherwise take screenshot of full element
|
|
120
|
-
const region = isScrollable ? null : await element.getRegion()
|
|
121
|
-
const scrollingElement = isScrollable ? element : await elementContext.getScrollingElement()
|
|
122
|
-
// css stitching could be applied only to root element of its context
|
|
123
|
-
scrollingMode = scrollingMode === 'css' && !(await scrollingElement.isRoot()) ? 'mixed' : scrollingMode
|
|
124
|
-
return {
|
|
125
|
-
context: elementContext,
|
|
126
|
-
region,
|
|
127
|
-
scroller: scrollingElement ? makeScroller({element: scrollingElement, scrollingMode, logger}) : null,
|
|
128
|
-
}
|
|
129
|
-
} else {
|
|
130
|
-
const scrollingElement = await context.getScrollingElement()
|
|
131
|
-
return {
|
|
132
|
-
context: elementContext,
|
|
133
|
-
region: await element.getRegion(),
|
|
134
|
-
scroller: scrollingElement ? makeScroller({element: scrollingElement, scrollingMode, logger}) : null,
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
} else if (!context.isMain) {
|
|
139
|
-
// context
|
|
140
|
-
if (fully) {
|
|
141
|
-
const scrollingElement = await context.getScrollingElement()
|
|
142
|
-
return {
|
|
143
|
-
context,
|
|
144
|
-
scroller: scrollingElement ? makeScroller({logger, element: scrollingElement, scrollingMode}) : null,
|
|
145
|
-
}
|
|
146
|
-
} else {
|
|
147
|
-
const scrollingElement = await context.parent.getScrollingElement()
|
|
148
|
-
const element = await context.getContextElement()
|
|
149
|
-
return {
|
|
150
|
-
context: context.parent,
|
|
151
|
-
region: await element.getRegion(), // IMHO we should use CLIENT (without borders) region here
|
|
152
|
-
scroller: scrollingElement ? makeScroller({logger, element: scrollingElement, scrollingMode}) : null,
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
module.exports = screenshoter
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/test/util/spec-driver.js
DELETED
|
@@ -1,288 +0,0 @@
|
|
|
1
|
-
const webdriverio = require('webdriverio')
|
|
2
|
-
const utils = require('@applitools/utils')
|
|
3
|
-
|
|
4
|
-
// #region HELPERS
|
|
5
|
-
|
|
6
|
-
const LEGACY_ELEMENT_ID = 'ELEMENT'
|
|
7
|
-
const ELEMENT_ID = 'element-6066-11e4-a52e-4f735466cecf'
|
|
8
|
-
|
|
9
|
-
function extractElementId(element) {
|
|
10
|
-
return element.elementId || element[ELEMENT_ID] || element[LEGACY_ELEMENT_ID]
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// #endregion
|
|
14
|
-
|
|
15
|
-
// #region UTILITY
|
|
16
|
-
|
|
17
|
-
function isDriver(browser) {
|
|
18
|
-
if (!browser) return false
|
|
19
|
-
return browser.constructor.name === 'Browser'
|
|
20
|
-
}
|
|
21
|
-
function isElement(element) {
|
|
22
|
-
if (!element) return false
|
|
23
|
-
return Boolean(element.elementId || element[ELEMENT_ID] || element[LEGACY_ELEMENT_ID])
|
|
24
|
-
}
|
|
25
|
-
function isSelector(selector) {
|
|
26
|
-
return utils.types.isString(selector) || utils.types.isFunction(selector)
|
|
27
|
-
}
|
|
28
|
-
function transformElement(element) {
|
|
29
|
-
const elementId = extractElementId(element)
|
|
30
|
-
return {[ELEMENT_ID]: elementId, [LEGACY_ELEMENT_ID]: elementId}
|
|
31
|
-
}
|
|
32
|
-
function transformSelector(selector) {
|
|
33
|
-
if (utils.types.has(selector, 'selector')) {
|
|
34
|
-
if (!utils.types.has(selector, 'type')) return selector.selector
|
|
35
|
-
if (selector.type === 'css') return `css selector:${selector.selector}`
|
|
36
|
-
else return `${selector.type}:${selector.selector}`
|
|
37
|
-
}
|
|
38
|
-
return selector
|
|
39
|
-
}
|
|
40
|
-
function extractSelector(element) {
|
|
41
|
-
return element.selector
|
|
42
|
-
}
|
|
43
|
-
async function isEqualElements(browser, element1, element2) {
|
|
44
|
-
// NOTE: wdio wraps puppeteer and generate ids by itself just incrementing a counter
|
|
45
|
-
// NOTE: appium for ios could return different ids for same element
|
|
46
|
-
if (browser.isDevTools || browser.isIOS) {
|
|
47
|
-
return browser.execute((element1, element2) => element1 === element2, element1, element2).catch(() => false)
|
|
48
|
-
}
|
|
49
|
-
if (!element1 || !element2) return false
|
|
50
|
-
const elementId1 = extractElementId(element1)
|
|
51
|
-
const elementId2 = extractElementId(element2)
|
|
52
|
-
return elementId1 === elementId2
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// #endregion
|
|
56
|
-
|
|
57
|
-
// #region COMMANDS
|
|
58
|
-
|
|
59
|
-
async function executeScript(browser, script, ...args) {
|
|
60
|
-
return browser.execute(script, ...args)
|
|
61
|
-
}
|
|
62
|
-
async function mainContext(browser) {
|
|
63
|
-
await browser.switchToFrame(null)
|
|
64
|
-
return browser
|
|
65
|
-
}
|
|
66
|
-
async function parentContext(browser) {
|
|
67
|
-
await browser.switchToParentFrame()
|
|
68
|
-
return browser
|
|
69
|
-
}
|
|
70
|
-
async function childContext(browser, element) {
|
|
71
|
-
await browser.switchToFrame(element)
|
|
72
|
-
return browser
|
|
73
|
-
}
|
|
74
|
-
async function findElement(browser, selector) {
|
|
75
|
-
const element = await browser.$(selector)
|
|
76
|
-
return !element.error ? element : null
|
|
77
|
-
}
|
|
78
|
-
async function findElements(browser, selector) {
|
|
79
|
-
const elements = await browser.$$(selector)
|
|
80
|
-
return Array.from(elements)
|
|
81
|
-
}
|
|
82
|
-
async function getElementRegion(browser, element) {
|
|
83
|
-
const extendedElement = await browser.$(element)
|
|
84
|
-
if (utils.types.isFunction(extendedElement, 'getRect')) {
|
|
85
|
-
return extendedElement.getRect()
|
|
86
|
-
} else {
|
|
87
|
-
const size = await extendedElement.getSize()
|
|
88
|
-
const location = utils.types.has(size, ['x', 'y']) ? size : await extendedElement.getLocation()
|
|
89
|
-
return {x: location.x, y: location.y, width: size.width, height: size.height}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
async function getElementAttribute(browser, element, name) {
|
|
93
|
-
return browser.getElementAttribute(extractElementId(element), name)
|
|
94
|
-
}
|
|
95
|
-
async function getWindowSize(browser) {
|
|
96
|
-
if (utils.types.isFunction(browser.getWindowRect)) {
|
|
97
|
-
return browser.getWindowRect()
|
|
98
|
-
} else if (utils.types.isFunction(browser.getWindowSize)) {
|
|
99
|
-
return await browser.getWindowSize()
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
async function setWindowSize(browser, {width, height} = {}) {
|
|
103
|
-
if (utils.types.isFunction(browser.setWindowRect)) {
|
|
104
|
-
await browser.setWindowRect(0, 0, width, height)
|
|
105
|
-
} else {
|
|
106
|
-
await browser.setWindowPosition(0, 0)
|
|
107
|
-
await browser.setWindowSize(width, height)
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
async function getOrientation(browser) {
|
|
111
|
-
const orientation = await browser.getOrientation()
|
|
112
|
-
return orientation.toLowerCase()
|
|
113
|
-
}
|
|
114
|
-
async function getDriverInfo(browser) {
|
|
115
|
-
const driverInfo = {
|
|
116
|
-
sessionId: browser.sessionId,
|
|
117
|
-
isMobile: browser.isMobile,
|
|
118
|
-
isNative: browser.isMobile && !browser.capabilities.browserName,
|
|
119
|
-
deviceName: browser.capabilities.desired
|
|
120
|
-
? browser.capabilities.desired.deviceName
|
|
121
|
-
: browser.capabilities.deviceName,
|
|
122
|
-
platformName: browser.capabilities.platformName || browser.capabilities.platform,
|
|
123
|
-
platformVersion: browser.capabilities.platformVersion,
|
|
124
|
-
browserName: browser.capabilities.browserName,
|
|
125
|
-
browserVersion: browser.capabilities.browserVersion,
|
|
126
|
-
pixelRatio: browser.capabilities.pixelRatio,
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (driverInfo.isNative) {
|
|
130
|
-
const capabilities = utils.types.has(browser.capabilities, ['pixelRatio', 'viewportRect', 'statBarHeight'])
|
|
131
|
-
? browser.capabilities
|
|
132
|
-
: await browser.getSession()
|
|
133
|
-
|
|
134
|
-
driverInfo.pixelRatio = capabilities.pixelRatio
|
|
135
|
-
|
|
136
|
-
try {
|
|
137
|
-
const {statusBar, navigationBar} = await browser.getSystemBars()
|
|
138
|
-
driverInfo.statusBarHeight = statusBar.visible ? statusBar.height : 0
|
|
139
|
-
driverInfo.navigationBarHeight = navigationBar.visible ? navigationBar.height : 0
|
|
140
|
-
} catch (err) {
|
|
141
|
-
driverInfo.statusBarHeight = capabilities.statBarHeight || (capabilities.viewportRect || {}).top || 0
|
|
142
|
-
driverInfo.navigationBarHeight = 0
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return driverInfo
|
|
147
|
-
}
|
|
148
|
-
async function takeScreenshot(driver) {
|
|
149
|
-
return driver.takeScreenshot()
|
|
150
|
-
}
|
|
151
|
-
async function visit(browser, url) {
|
|
152
|
-
return browser.url(url)
|
|
153
|
-
}
|
|
154
|
-
async function click(browser, element) {
|
|
155
|
-
if (isSelector(element)) element = await findElement(browser, element)
|
|
156
|
-
const extendedElement = await browser.$(element)
|
|
157
|
-
await extendedElement.click()
|
|
158
|
-
}
|
|
159
|
-
async function performAction(browser, actions) {
|
|
160
|
-
return browser.touchAction(actions)
|
|
161
|
-
}
|
|
162
|
-
async function getElementText(browser, element) {
|
|
163
|
-
return browser.getElementText(extractElementId(element))
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// #endregion
|
|
167
|
-
|
|
168
|
-
async function build({type = 'web'} = {}) {
|
|
169
|
-
const capabilities = {
|
|
170
|
-
web: {
|
|
171
|
-
protocol: 'http',
|
|
172
|
-
hostname: 'localhost',
|
|
173
|
-
path: '/wd/hub',
|
|
174
|
-
port: 4444,
|
|
175
|
-
logLevel: 'silent',
|
|
176
|
-
capabilities: {
|
|
177
|
-
browserName: 'chrome',
|
|
178
|
-
},
|
|
179
|
-
},
|
|
180
|
-
android: {
|
|
181
|
-
protocol: 'https',
|
|
182
|
-
hostname: 'ondemand.saucelabs.com',
|
|
183
|
-
path: '/wd/hub',
|
|
184
|
-
port: 443,
|
|
185
|
-
logLevel: 'silent',
|
|
186
|
-
capabilities: {
|
|
187
|
-
name: 'Android Screenshoter Test',
|
|
188
|
-
browserName: '',
|
|
189
|
-
platformName: 'Android',
|
|
190
|
-
platformVersion: '7.0',
|
|
191
|
-
appiumVersion: '1.20.2',
|
|
192
|
-
deviceName: 'Samsung Galaxy S8 FHD GoogleAPI Emulator',
|
|
193
|
-
automationName: 'uiautomator2',
|
|
194
|
-
app: 'https://applitools.jfrog.io/artifactory/Examples/android/1.3/app-debug.apk',
|
|
195
|
-
username: process.env.SAUCE_USERNAME,
|
|
196
|
-
accessKey: process.env.SAUCE_ACCESS_KEY,
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
androidx: {
|
|
200
|
-
protocol: 'https',
|
|
201
|
-
hostname: 'ondemand.saucelabs.com',
|
|
202
|
-
path: '/wd/hub',
|
|
203
|
-
port: 443,
|
|
204
|
-
logLevel: 'silent',
|
|
205
|
-
capabilities: {
|
|
206
|
-
name: 'AndroidX Screenshoter Test',
|
|
207
|
-
browserName: '',
|
|
208
|
-
platformName: 'Android',
|
|
209
|
-
platformVersion: '10.0',
|
|
210
|
-
appiumVersion: '1.20.2',
|
|
211
|
-
deviceName: 'Google Pixel 3a XL GoogleAPI Emulator',
|
|
212
|
-
automationName: 'uiautomator2',
|
|
213
|
-
app: 'https://applitools.jfrog.io/artifactory/Examples/androidx/1.2.0/app_androidx.apk',
|
|
214
|
-
username: process.env.SAUCE_USERNAME,
|
|
215
|
-
accessKey: process.env.SAUCE_ACCESS_KEY,
|
|
216
|
-
},
|
|
217
|
-
},
|
|
218
|
-
ios: {
|
|
219
|
-
protocol: 'https',
|
|
220
|
-
hostname: 'ondemand.saucelabs.com',
|
|
221
|
-
path: '/wd/hub',
|
|
222
|
-
port: 443,
|
|
223
|
-
logLevel: 'silent',
|
|
224
|
-
capabilities: {
|
|
225
|
-
name: 'iOS Screenshoter Test',
|
|
226
|
-
deviceName: 'iPhone 11 Pro Simulator',
|
|
227
|
-
platformName: 'iOS',
|
|
228
|
-
platformVersion: '13.4',
|
|
229
|
-
appiumVersion: '1.19.2',
|
|
230
|
-
automationName: 'XCUITest',
|
|
231
|
-
app: 'https://applitools.jfrog.io/artifactory/Examples/IOSTestApp/1.5/app/IOSTestApp-1.5.zip',
|
|
232
|
-
username: process.env.SAUCE_USERNAME,
|
|
233
|
-
accessKey: process.env.SAUCE_ACCESS_KEY,
|
|
234
|
-
},
|
|
235
|
-
},
|
|
236
|
-
'web-ios': {
|
|
237
|
-
protocol: 'https',
|
|
238
|
-
hostname: 'ondemand.saucelabs.com',
|
|
239
|
-
path: '/wd/hub',
|
|
240
|
-
port: 443,
|
|
241
|
-
logLevel: 'silent',
|
|
242
|
-
capabilities: {
|
|
243
|
-
name: 'iOS Web Screenshoter Test',
|
|
244
|
-
deviceName: 'iPhone 11 Pro Simulator',
|
|
245
|
-
browserName: 'safari',
|
|
246
|
-
platformName: 'iOS',
|
|
247
|
-
platformVersion: '14.5',
|
|
248
|
-
appiumVersion: '1.20.1',
|
|
249
|
-
automationName: 'XCUITest',
|
|
250
|
-
username: process.env.SAUCE_USERNAME,
|
|
251
|
-
accessKey: process.env.SAUCE_ACCESS_KEY,
|
|
252
|
-
},
|
|
253
|
-
},
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
const browser = await webdriverio.remote(capabilities[type])
|
|
257
|
-
|
|
258
|
-
return [browser, () => browser.deleteSession()]
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
module.exports = {
|
|
262
|
-
isDriver,
|
|
263
|
-
isElement,
|
|
264
|
-
isSelector,
|
|
265
|
-
transformElement,
|
|
266
|
-
transformSelector,
|
|
267
|
-
extractSelector,
|
|
268
|
-
isEqualElements,
|
|
269
|
-
executeScript,
|
|
270
|
-
mainContext,
|
|
271
|
-
parentContext,
|
|
272
|
-
childContext,
|
|
273
|
-
findElement,
|
|
274
|
-
findElements,
|
|
275
|
-
getElementRegion,
|
|
276
|
-
getElementAttribute,
|
|
277
|
-
getWindowSize,
|
|
278
|
-
setWindowSize,
|
|
279
|
-
getOrientation,
|
|
280
|
-
getDriverInfo,
|
|
281
|
-
takeScreenshot,
|
|
282
|
-
visit,
|
|
283
|
-
click,
|
|
284
|
-
performAction,
|
|
285
|
-
getElementText,
|
|
286
|
-
|
|
287
|
-
build,
|
|
288
|
-
}
|