@applitools/driver 1.2.5 → 1.3.1
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 +24 -0
- package/dist/capabilities.js +54 -0
- package/dist/context.js +7 -0
- package/dist/driver.js +43 -15
- package/dist/element.js +10 -2
- package/dist/fake/index.js +25 -0
- package/dist/fake/mock-driver.js +7 -2
- package/dist/fake/spec-driver.js +103 -65
- package/dist/index.js +0 -15
- package/package.json +20 -9
- package/types/capabilities.d.ts +4 -0
- package/types/context.d.ts +71 -0
- package/types/driver.d.ts +62 -0
- package/types/element.d.ts +55 -0
- package/types/fake/index.d.ts +3 -0
- package/types/fake/mock-driver.d.ts +35 -0
- package/types/fake/spec-driver.d.ts +29 -0
- package/types/index.d.ts +3 -0
- package/types/user-agent.d.ts +12 -0
- package/types/utils.d.ts +11 -0
- package/.bongo/dry-run/package-lock.json +0 -30
- package/.bongo/dry-run.tgz +0 -0
- package/.eslintrc +0 -36
- package/src/context.ts +0 -519
- package/src/driver.ts +0 -456
- package/src/element.ts +0 -502
- package/src/fake/mock-driver.d.ts +0 -3
- package/src/fake/mock-driver.js +0 -355
- package/src/fake/spec-driver.d.ts +0 -11
- package/src/fake/spec-driver.js +0 -66
- package/src/index.ts +0 -6
- package/src/user-agent.ts +0 -99
- package/src/utils.ts +0 -77
- package/test/unit/context.spec.ts +0 -243
- package/test/unit/driver.spec.ts +0 -482
- package/test/unit/user-agent.spec.d.ts +0 -1
- package/tsconfig.json +0 -24
package/src/driver.ts
DELETED
|
@@ -1,456 +0,0 @@
|
|
|
1
|
-
import type * as types from '@applitools/types'
|
|
2
|
-
import type {SpecUtils} from './utils'
|
|
3
|
-
import * as utils from '@applitools/utils'
|
|
4
|
-
import {Context, ContextReference} from './context'
|
|
5
|
-
import {Element} from './element'
|
|
6
|
-
import {makeSpecUtils} from './utils'
|
|
7
|
-
import {parseUserAgent} from './user-agent'
|
|
8
|
-
|
|
9
|
-
const snippets = require('@applitools/snippets')
|
|
10
|
-
|
|
11
|
-
// eslint-disable-next-line
|
|
12
|
-
export class Driver<TDriver, TContext, TElement, TSelector> {
|
|
13
|
-
private _target: TDriver
|
|
14
|
-
|
|
15
|
-
private _mainContext: Context<TDriver, TContext, TElement, TSelector>
|
|
16
|
-
private _currentContext: Context<TDriver, TContext, TElement, TSelector>
|
|
17
|
-
private _driverInfo: types.DriverInfo
|
|
18
|
-
private _logger: any
|
|
19
|
-
private _utils: SpecUtils<TDriver, TContext, TElement, TSelector>
|
|
20
|
-
|
|
21
|
-
protected readonly _spec: types.SpecDriver<TDriver, TContext, TElement, TSelector>
|
|
22
|
-
|
|
23
|
-
constructor(options: {
|
|
24
|
-
spec: types.SpecDriver<TDriver, TContext, TElement, TSelector>
|
|
25
|
-
driver: Driver<TDriver, TContext, TElement, TSelector> | TDriver
|
|
26
|
-
logger?: any
|
|
27
|
-
}) {
|
|
28
|
-
if (options.driver instanceof Driver) return options.driver
|
|
29
|
-
|
|
30
|
-
this._spec = options.spec
|
|
31
|
-
this._utils = makeSpecUtils(options.spec)
|
|
32
|
-
|
|
33
|
-
if (options.logger) this._logger = options.logger
|
|
34
|
-
|
|
35
|
-
if (this._spec.isDriver(options.driver)) {
|
|
36
|
-
this._target = this._spec.transformDriver?.(options.driver) ?? options.driver
|
|
37
|
-
} else {
|
|
38
|
-
throw new TypeError('Driver constructor called with argument of unknown type!')
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
this._mainContext = new Context({
|
|
42
|
-
spec: this._spec,
|
|
43
|
-
context: this._spec.extractContext?.(this._target) ?? ((<unknown>this._target) as TContext),
|
|
44
|
-
driver: this,
|
|
45
|
-
logger: this._logger,
|
|
46
|
-
})
|
|
47
|
-
this._currentContext = this._mainContext
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
get target(): TDriver {
|
|
51
|
-
return this._target
|
|
52
|
-
}
|
|
53
|
-
get currentContext(): Context<TDriver, TContext, TElement, TSelector> {
|
|
54
|
-
return this._currentContext
|
|
55
|
-
}
|
|
56
|
-
get mainContext(): Context<TDriver, TContext, TElement, TSelector> {
|
|
57
|
-
return this._mainContext
|
|
58
|
-
}
|
|
59
|
-
get features() {
|
|
60
|
-
return this._driverInfo?.features
|
|
61
|
-
}
|
|
62
|
-
get deviceName(): string {
|
|
63
|
-
return this._driverInfo?.deviceName
|
|
64
|
-
}
|
|
65
|
-
get platformName(): string {
|
|
66
|
-
return this._driverInfo?.platformName
|
|
67
|
-
}
|
|
68
|
-
get platformVersion(): string | number {
|
|
69
|
-
return this._driverInfo?.platformVersion
|
|
70
|
-
}
|
|
71
|
-
get browserName(): string {
|
|
72
|
-
return this._driverInfo?.browserName
|
|
73
|
-
}
|
|
74
|
-
get browserVersion(): string | number {
|
|
75
|
-
return this._driverInfo?.browserVersion
|
|
76
|
-
}
|
|
77
|
-
get userAgent(): string {
|
|
78
|
-
return this._driverInfo?.userAgent
|
|
79
|
-
}
|
|
80
|
-
get pixelRatio(): number {
|
|
81
|
-
return this._driverInfo.pixelRatio ?? 1
|
|
82
|
-
}
|
|
83
|
-
get statusBarHeight(): number {
|
|
84
|
-
return this._driverInfo.statusBarHeight ?? (this.isNative ? 0 : undefined)
|
|
85
|
-
}
|
|
86
|
-
get navigationBarHeight(): number {
|
|
87
|
-
return this._driverInfo.navigationBarHeight ?? (this.isNative ? 0 : undefined)
|
|
88
|
-
}
|
|
89
|
-
get isNative(): boolean {
|
|
90
|
-
return this._driverInfo?.isNative ?? false
|
|
91
|
-
}
|
|
92
|
-
get isWeb(): boolean {
|
|
93
|
-
return !this.isNative
|
|
94
|
-
}
|
|
95
|
-
get isMobile(): boolean {
|
|
96
|
-
return this._driverInfo?.isMobile ?? false
|
|
97
|
-
}
|
|
98
|
-
get isIOS(): boolean {
|
|
99
|
-
return this.platformName === 'iOS'
|
|
100
|
-
}
|
|
101
|
-
get isAndroid(): boolean {
|
|
102
|
-
return this.platformName === 'Android'
|
|
103
|
-
}
|
|
104
|
-
get isIE(): boolean {
|
|
105
|
-
return /(internet explorer|ie)/i.test(this.browserName)
|
|
106
|
-
}
|
|
107
|
-
get isEdgeLegacy(): boolean {
|
|
108
|
-
return /edge/i.test(this.browserName) && Number(this.browserVersion) <= 44
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
updateCurrentContext(context: Context<TDriver, TContext, TElement, TSelector>): void {
|
|
112
|
-
this._currentContext = context
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
async init(): Promise<this> {
|
|
116
|
-
this._driverInfo = await this._spec.getDriverInfo?.(this.target)
|
|
117
|
-
|
|
118
|
-
if (this.isWeb) {
|
|
119
|
-
const userAgent = this._driverInfo?.userAgent ?? (await this.execute(snippets.getUserAgent))
|
|
120
|
-
const pixelRatio = this._driverInfo?.pixelRatio ?? (await this.execute(snippets.getPixelRatio))
|
|
121
|
-
const userAgentInfo = userAgent ? parseUserAgent(userAgent) : ({} as any)
|
|
122
|
-
this._driverInfo = {
|
|
123
|
-
...this._driverInfo,
|
|
124
|
-
isMobile: this._driverInfo?.isMobile ?? ['iOS', 'Android'].includes(userAgentInfo.platformName),
|
|
125
|
-
platformName: this._driverInfo?.isMobile
|
|
126
|
-
? this._driverInfo?.platformName ?? userAgentInfo.platformName
|
|
127
|
-
: userAgentInfo.platformName ?? this._driverInfo?.platformName,
|
|
128
|
-
platformVersion: this._driverInfo?.isMobile
|
|
129
|
-
? this._driverInfo?.platformVersion ?? userAgentInfo.platformVersion
|
|
130
|
-
: userAgentInfo.platformVersion ?? this._driverInfo?.platformVersion,
|
|
131
|
-
browserName: userAgentInfo.browserName ?? this._driverInfo?.browserName,
|
|
132
|
-
browserVersion: userAgentInfo.browserVersion ?? this._driverInfo?.browserVersion,
|
|
133
|
-
userAgent,
|
|
134
|
-
pixelRatio,
|
|
135
|
-
}
|
|
136
|
-
} else {
|
|
137
|
-
if (this.isAndroid) {
|
|
138
|
-
this._driverInfo.statusBarHeight = this._driverInfo.statusBarHeight / this.pixelRatio
|
|
139
|
-
this._driverInfo.navigationBarHeight = this._driverInfo.navigationBarHeight / this.pixelRatio
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (!this._driverInfo.viewportSize) {
|
|
143
|
-
const displaySize = await this.getDisplaySize()
|
|
144
|
-
this._driverInfo.viewportSize = {
|
|
145
|
-
width: displaySize.width,
|
|
146
|
-
height: displaySize.height - this._driverInfo.statusBarHeight,
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
this._logger.log('Driver initialized', this._driverInfo)
|
|
152
|
-
|
|
153
|
-
return this
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
async refreshContexts(): Promise<Context<TDriver, TContext, TElement, TSelector>> {
|
|
157
|
-
if (this.isNative) return this.currentContext
|
|
158
|
-
|
|
159
|
-
const spec = this._spec
|
|
160
|
-
const utils = this._utils
|
|
161
|
-
|
|
162
|
-
let currentContext = this.currentContext.target
|
|
163
|
-
let contextInfo = await getContextInfo(currentContext)
|
|
164
|
-
|
|
165
|
-
const path = []
|
|
166
|
-
if (spec.parentContext) {
|
|
167
|
-
while (!contextInfo.isRoot) {
|
|
168
|
-
currentContext = await spec.parentContext(currentContext)
|
|
169
|
-
const contextReference = await findContextReference(currentContext, contextInfo)
|
|
170
|
-
if (!contextReference) throw new Error('Unable to find out the chain of frames')
|
|
171
|
-
path.unshift(contextReference)
|
|
172
|
-
contextInfo = await getContextInfo(currentContext)
|
|
173
|
-
}
|
|
174
|
-
} else {
|
|
175
|
-
currentContext = await spec.mainContext(currentContext)
|
|
176
|
-
path.push(...(await findContextPath(currentContext, contextInfo)))
|
|
177
|
-
}
|
|
178
|
-
this._currentContext = this._mainContext
|
|
179
|
-
return this.switchToChildContext(...path)
|
|
180
|
-
|
|
181
|
-
async function getContextInfo(context: TContext): Promise<any> {
|
|
182
|
-
const [documentElement, selector, isRoot, isCORS] = await spec.executeScript(context, snippets.getContextInfo)
|
|
183
|
-
return {documentElement, selector, isRoot, isCORS}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
async function getChildContextsInfo(context: TContext): Promise<any[]> {
|
|
187
|
-
const framesInfo = await spec.executeScript(context, snippets.getChildFramesInfo)
|
|
188
|
-
return framesInfo.map(([contextElement, isCORS]: [TElement, boolean]) => ({contextElement, isCORS}))
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
async function isEqualElements(context: TContext, element1: TElement, element2: TElement): Promise<boolean> {
|
|
192
|
-
return spec.executeScript(context, snippets.isEqualElements, [element1, element2]).catch(() => false)
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
async function findContextReference(context: TContext, contextInfo: any): Promise<TElement> {
|
|
196
|
-
if (contextInfo.selector) {
|
|
197
|
-
const contextElement = await spec.findElement(
|
|
198
|
-
context,
|
|
199
|
-
utils.transformSelector({type: 'xpath', selector: contextInfo.selector}),
|
|
200
|
-
)
|
|
201
|
-
if (contextElement) return contextElement
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
for (const childContextInfo of await getChildContextsInfo(context)) {
|
|
205
|
-
if (childContextInfo.isCORS !== contextInfo.isCORS) continue
|
|
206
|
-
const childContext = await spec.childContext(context, childContextInfo.contextElement)
|
|
207
|
-
const contentDocument = await spec.findElement(childContext, utils.transformSelector('html'))
|
|
208
|
-
const isWantedContext = await isEqualElements(childContext, contentDocument, contextInfo.documentElement)
|
|
209
|
-
await spec.parentContext(childContext)
|
|
210
|
-
if (isWantedContext) return childContextInfo.contextElement
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
async function findContextPath(
|
|
215
|
-
context: TContext,
|
|
216
|
-
contextInfo: any,
|
|
217
|
-
contextPath: TElement[] = [],
|
|
218
|
-
): Promise<TElement[]> {
|
|
219
|
-
const contentDocument = await spec.findElement(context, utils.transformSelector('html'))
|
|
220
|
-
|
|
221
|
-
if (await isEqualElements(context, contentDocument, contextInfo.documentElement)) {
|
|
222
|
-
return contextPath
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
for (const childContextInfo of await getChildContextsInfo(context)) {
|
|
226
|
-
const childContext = await spec.childContext(context, childContextInfo.contextElement)
|
|
227
|
-
const possibleContextPath = [...contextPath, childContextInfo.contextElement]
|
|
228
|
-
const wantedContextPath = await findContextPath(childContext, contextInfo, possibleContextPath)
|
|
229
|
-
await spec.mainContext(context)
|
|
230
|
-
|
|
231
|
-
if (wantedContextPath) return wantedContextPath
|
|
232
|
-
|
|
233
|
-
for (const contextElement of contextPath) {
|
|
234
|
-
await spec.childContext(context, contextElement)
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
async switchTo(
|
|
241
|
-
context: Context<TDriver, TContext, TElement, TSelector>,
|
|
242
|
-
): Promise<Context<TDriver, TContext, TElement, TSelector>> {
|
|
243
|
-
if (await this.currentContext.equals(context)) {
|
|
244
|
-
this._currentContext = context
|
|
245
|
-
return
|
|
246
|
-
}
|
|
247
|
-
const currentPath = this.currentContext.path
|
|
248
|
-
const requiredPath = context.path
|
|
249
|
-
|
|
250
|
-
let diffIndex = -1
|
|
251
|
-
for (const [index, context] of requiredPath.entries()) {
|
|
252
|
-
if (currentPath[index] && !(await currentPath[index].equals(context))) {
|
|
253
|
-
diffIndex = index
|
|
254
|
-
break
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
if (diffIndex === 0) {
|
|
259
|
-
throw new Error('Cannot switch to the context, because it has different main context')
|
|
260
|
-
} else if (diffIndex === -1) {
|
|
261
|
-
if (currentPath.length === requiredPath.length) {
|
|
262
|
-
// required and current paths are the same
|
|
263
|
-
return this.currentContext
|
|
264
|
-
} else if (requiredPath.length > currentPath.length) {
|
|
265
|
-
// current path is a sub-path of required path
|
|
266
|
-
return this.switchToChildContext(...requiredPath.slice(currentPath.length))
|
|
267
|
-
} else if (currentPath.length - requiredPath.length <= requiredPath.length) {
|
|
268
|
-
// required path is a sub-path of current path
|
|
269
|
-
return this.switchToParentContext(currentPath.length - requiredPath.length)
|
|
270
|
-
} else {
|
|
271
|
-
// required path is a sub-path of current path
|
|
272
|
-
await this.switchToMainContext()
|
|
273
|
-
return this.switchToChildContext(...requiredPath)
|
|
274
|
-
}
|
|
275
|
-
} else if (currentPath.length - diffIndex <= diffIndex) {
|
|
276
|
-
// required path is different from current or they are partially intersected
|
|
277
|
-
// chose an optimal way to traverse from current context to target context
|
|
278
|
-
await this.switchToParentContext(currentPath.length - diffIndex)
|
|
279
|
-
return this.switchToChildContext(...requiredPath.slice(diffIndex))
|
|
280
|
-
} else {
|
|
281
|
-
await this.switchToMainContext()
|
|
282
|
-
return this.switchToChildContext(...requiredPath)
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
async switchToMainContext(): Promise<Context<TDriver, TContext, TElement, TSelector>> {
|
|
287
|
-
if (this.isNative) throw new Error('Contexts are supported only for web drivers')
|
|
288
|
-
|
|
289
|
-
this._logger.log('Switching to the main context')
|
|
290
|
-
await this._spec.mainContext(this.currentContext.target)
|
|
291
|
-
return (this._currentContext = this._mainContext)
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
async switchToParentContext(elevation = 1): Promise<Context<TDriver, TContext, TElement, TSelector>> {
|
|
295
|
-
if (this.isNative) throw new Error('Contexts are supported only for web drivers')
|
|
296
|
-
|
|
297
|
-
this._logger.log('Switching to a parent context with elevation:', elevation)
|
|
298
|
-
if (this.currentContext.path.length <= elevation) {
|
|
299
|
-
return this.switchToMainContext()
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
try {
|
|
303
|
-
while (elevation > 0) {
|
|
304
|
-
await this._spec.parentContext(this.currentContext.target)
|
|
305
|
-
this._currentContext = this._currentContext.parent
|
|
306
|
-
elevation -= 1
|
|
307
|
-
}
|
|
308
|
-
} catch (err) {
|
|
309
|
-
this._logger.warn('Unable to switch to a parent context due to error', err)
|
|
310
|
-
this._logger.log('Applying workaround to switch to the parent frame')
|
|
311
|
-
const path = this.currentContext.path.slice(1, -elevation)
|
|
312
|
-
await this.switchToMainContext()
|
|
313
|
-
await this.switchToChildContext(...path)
|
|
314
|
-
elevation = 0
|
|
315
|
-
}
|
|
316
|
-
return this.currentContext
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
async switchToChildContext(
|
|
320
|
-
...references: ContextReference<TDriver, TContext, TElement, TSelector>[]
|
|
321
|
-
): Promise<Context<TDriver, TContext, TElement, TSelector>> {
|
|
322
|
-
if (this.isNative) throw new Error('Contexts are supported only for web drivers')
|
|
323
|
-
this._logger.log('Switching to a child context with depth:', references.length)
|
|
324
|
-
for (const reference of references) {
|
|
325
|
-
if (reference === this.mainContext) continue
|
|
326
|
-
const context = await this.currentContext.context(reference)
|
|
327
|
-
await context.focus()
|
|
328
|
-
}
|
|
329
|
-
return this.currentContext
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
async normalizeRegion(region: types.Region): Promise<types.Region> {
|
|
333
|
-
if (this.isWeb || !utils.types.has(this._driverInfo, ['viewportSize', 'statusBarHeight'])) return region
|
|
334
|
-
const scaledRegion = this.isAndroid ? utils.geometry.scale(region, 1 / this.pixelRatio) : region
|
|
335
|
-
return utils.geometry.offsetNegative(scaledRegion, {x: 0, y: this.statusBarHeight})
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
async getRegionInViewport(
|
|
339
|
-
context: Context<TDriver, TContext, TElement, TSelector>,
|
|
340
|
-
region: types.Region,
|
|
341
|
-
): Promise<types.Region> {
|
|
342
|
-
await context.focus()
|
|
343
|
-
return context.getRegionInViewport(region)
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
async element(selector: types.Selector<TSelector>): Promise<Element<TDriver, TContext, TElement, TSelector>> {
|
|
347
|
-
return this.currentContext.element(selector)
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
async elements(selector: types.Selector<TSelector>): Promise<Element<TDriver, TContext, TElement, TSelector>[]> {
|
|
351
|
-
return this.currentContext.elements(selector)
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
async execute(script: ((arg: any) => any) | string, arg?: any): Promise<any> {
|
|
355
|
-
return this.currentContext.execute(script, arg)
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
async takeScreenshot(): Promise<Buffer | string> {
|
|
359
|
-
const data = await this._spec.takeScreenshot(this.target)
|
|
360
|
-
return utils.types.isString(data) ? data.replace(/[\r\n]+/g, '') : data
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
async getViewportSize(): Promise<types.Size> {
|
|
364
|
-
let size
|
|
365
|
-
if (this.isNative) {
|
|
366
|
-
this._logger.log('Extracting viewport size from native driver')
|
|
367
|
-
if (this._driverInfo?.viewportSize) {
|
|
368
|
-
size = this._driverInfo.viewportSize
|
|
369
|
-
} else {
|
|
370
|
-
size = await this.getDisplaySize()
|
|
371
|
-
if (size.height > size.width) {
|
|
372
|
-
const orientation = await this.getOrientation()
|
|
373
|
-
if (orientation === 'landscape') {
|
|
374
|
-
size = {width: size.height, height: size.width}
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
} else if (this._spec.getViewportSize) {
|
|
379
|
-
this._logger.log('Extracting viewport size from web driver using spec method')
|
|
380
|
-
size = await this._spec.getViewportSize(this.target)
|
|
381
|
-
} else {
|
|
382
|
-
this._logger.log('Extracting viewport size from web driver using js snippet')
|
|
383
|
-
size = await this.mainContext.execute(snippets.getViewportSize)
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
this._logger.log('Extracted viewport size', size)
|
|
387
|
-
|
|
388
|
-
return size
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
async setViewportSize(size: types.Size): Promise<void> {
|
|
392
|
-
if (this.isMobile) return
|
|
393
|
-
if (this._spec.setViewportSize) {
|
|
394
|
-
this._logger.log('Setting viewport size to', size, 'using spec method')
|
|
395
|
-
await this._spec.setViewportSize(this.target, size)
|
|
396
|
-
return
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
this._logger.log('Setting viewport size to', size, 'using workaround')
|
|
400
|
-
|
|
401
|
-
const requiredViewportSize = size
|
|
402
|
-
let currentViewportSize = await this.getViewportSize()
|
|
403
|
-
if (utils.geometry.equals(currentViewportSize, requiredViewportSize)) return
|
|
404
|
-
|
|
405
|
-
let currentWindowSize = await this._spec.getWindowSize(this.target)
|
|
406
|
-
this._logger.log('Extracted window size', currentWindowSize)
|
|
407
|
-
|
|
408
|
-
let attempt = 0
|
|
409
|
-
while (attempt++ < 3) {
|
|
410
|
-
const requiredWindowSize = {
|
|
411
|
-
width: currentWindowSize.width + (requiredViewportSize.width - currentViewportSize.width),
|
|
412
|
-
height: currentWindowSize.height + (requiredViewportSize.height - currentViewportSize.height),
|
|
413
|
-
}
|
|
414
|
-
this._logger.log(`Attempt #${attempt} to set viewport size by setting window size to`, requiredWindowSize)
|
|
415
|
-
await this._spec.setWindowSize(this.target, requiredWindowSize)
|
|
416
|
-
await utils.general.sleep(3000)
|
|
417
|
-
currentWindowSize = requiredWindowSize
|
|
418
|
-
currentViewportSize = await this.getViewportSize()
|
|
419
|
-
if (utils.geometry.equals(currentViewportSize, requiredViewportSize)) return
|
|
420
|
-
this._logger.log(`Attempt #${attempt} to set viewport size failed. Current viewport:`, currentViewportSize)
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
throw new Error('Failed to set viewport size!')
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
async getDisplaySize(): Promise<types.Size> {
|
|
427
|
-
if (this.isWeb) return
|
|
428
|
-
const size = await this._spec.getWindowSize(this.target)
|
|
429
|
-
return this.isAndroid ? utils.geometry.scale(size, 1 / this.pixelRatio) : size
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
async getOrientation(): Promise<'portrait' | 'landscape'> {
|
|
433
|
-
if (this.isWeb) return
|
|
434
|
-
const orientation = this._spec.getOrientation(this.target)
|
|
435
|
-
this._logger.log('Extracted device orientation:', orientation)
|
|
436
|
-
return orientation
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
async getTitle(): Promise<string> {
|
|
440
|
-
if (this.isNative) return null
|
|
441
|
-
const title = await this._spec.getTitle(this.target)
|
|
442
|
-
this._logger.log('Extracted title:', title)
|
|
443
|
-
return title
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
async getUrl(): Promise<string> {
|
|
447
|
-
if (this.isNative) return null
|
|
448
|
-
const url = this._spec.getUrl(this.target)
|
|
449
|
-
this._logger.log('Extracted url:', url)
|
|
450
|
-
return url
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
async visit(url: string): Promise<void> {
|
|
454
|
-
await this._spec.visit(this.target, url)
|
|
455
|
-
}
|
|
456
|
-
}
|