@testim/testim-cli 3.196.0 → 3.197.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.
Files changed (66) hide show
  1. package/README.md +1 -1
  2. package/cli/onExit.js +12 -1
  3. package/cli.js +5 -1
  4. package/commons/constants.js +0 -25
  5. package/commons/featureFlags.js +2 -0
  6. package/commons/socket/testResultService.js +4 -14
  7. package/commons/testimAnalytics.js +0 -1
  8. package/commons/testimDesiredCapabilitiesBuilder.js +0 -94
  9. package/commons/testimServicesApi.js +9 -79
  10. package/executionQueue.js +7 -4
  11. package/npm-shrinkwrap.json +948 -512
  12. package/package.json +3 -1
  13. package/player/stepActions/baseJsStepAction.js +5 -1
  14. package/player/stepActions/pixelValidationStepAction.js +28 -0
  15. package/player/stepActions/salesforceAutoLoginStepAction.js +5 -3
  16. package/player/stepActions/stepActionRegistrar.js +3 -48
  17. package/player/utils/eyeSdkService.js +230 -0
  18. package/reports/consoleReporter.js +0 -20
  19. package/reports/reporter.js +0 -21
  20. package/runOptions.js +13 -89
  21. package/runner.js +3 -44
  22. package/runners/{strategies/LocalStrategy.js → ParallelWorkerManager.js} +59 -68
  23. package/runners/TestPlanRunner.js +286 -67
  24. package/runners/runnerUtils.js +73 -0
  25. package/services/analyticsService.js +94 -0
  26. package/services/gridService.js +24 -16
  27. package/services/gridService.test.js +21 -21
  28. package/testRunHandler.js +1 -1
  29. package/testRunStatus.js +13 -9
  30. package/utils.js +5 -5
  31. package/workers/BaseWorker.js +38 -39
  32. package/workers/BaseWorker.test.js +1 -1
  33. package/workers/WorkerExtensionSingleBrowser.js +6 -3
  34. package/commons/apkUploader/apkUploader.js +0 -46
  35. package/commons/apkUploader/apkUploaderFactory.js +0 -68
  36. package/commons/apkUploader/deviceFarmApkUploader.js +0 -41
  37. package/commons/apkUploader/saucelabsApkUploader.js +0 -36
  38. package/commons/apkUploader/testObjectApkUploader.js +0 -34
  39. package/player/mobile/mobileTestPlayer.js +0 -80
  40. package/player/mobile/mobileWebDriver.js +0 -155
  41. package/player/mobile/services/frameLocatorMock.js +0 -18
  42. package/player/mobile/services/mobilePortSelector.js +0 -22
  43. package/player/mobile/services/mobileTabService.js +0 -241
  44. package/player/mobile/utils/mobileScreenshotUtils.js +0 -46
  45. package/player/mobile/utils/mobileWindowUtils.js +0 -84
  46. package/player/stepActions/mobile/android/androidLocateStepAction.js +0 -122
  47. package/player/stepActions/mobile/android/androidLongClickStepAction.js +0 -12
  48. package/player/stepActions/mobile/android/androidScrollStepAction.js +0 -134
  49. package/player/stepActions/mobile/android/androidSpecialKeyStepAction.js +0 -22
  50. package/player/stepActions/mobile/android/androidSwipeStepAction.js +0 -32
  51. package/player/stepActions/mobile/androidGlobalActionStepAction.js +0 -12
  52. package/player/stepActions/mobile/androidTapStepAction.js +0 -19
  53. package/player/stepActions/mobile/androidTextChangeStepAction.js +0 -23
  54. package/player/stepActions/mobile/ios/iosLocateStepAction.js +0 -124
  55. package/player/stepActions/mobile/ios/iosScrollStepAction.js +0 -76
  56. package/runners/AnonymousTestPlanRunner.js +0 -106
  57. package/runners/BaseRunner.js +0 -42
  58. package/runners/BaseTestPlanRunner.js +0 -194
  59. package/runners/DeviceFarmRemoteRunner.js +0 -50
  60. package/runners/SchedulerRemoteRunner.js +0 -47
  61. package/runners/strategies/BaseStrategy.js +0 -86
  62. package/runners/strategies/DeviceFarmStrategy.js +0 -195
  63. package/runners/strategies/LocalDeviceFarmStrategy.js +0 -12
  64. package/runners/strategies/LocalTestStrategy.js +0 -14
  65. package/runners/strategies/Strategy.js +0 -17
  66. package/workers/WorkerAppium.js +0 -70
@@ -1,36 +0,0 @@
1
- const utils = require('../../utils');
2
- const ApkUploader = require('./apkUploader');
3
- const httpRequest = require('../httpRequest');
4
- const Promise = require('bluebird');
5
- const fs = Promise.promisifyAll(require('fs'));
6
- const path = require('path');
7
-
8
- const SAUCE_LABS_API_URL = 'https://saucelabs.com/rest';
9
-
10
- class SaucelabsApkUploader extends ApkUploader {
11
- constructor() {
12
- super();
13
- }
14
-
15
- uploadFile({ user, key }, apkFullPath, apkTimeout) {
16
- const authHeader = utils.buildBasicHeader(user, key);
17
- const fileName = `${Date.now()}_${path.basename(apkFullPath)}`;
18
- return fs.readFileAsync(apkFullPath)
19
- .then(apkBuffer => httpRequest.post({
20
- url: `${SAUCE_LABS_API_URL}/v1/storage/${user}/${fileName}?overwrite=true`,
21
- body: apkBuffer,
22
- headers: {
23
- Authorization: authHeader,
24
- 'Content-Type': 'application/octet-stream',
25
- },
26
- timeout: apkTimeout,
27
- }))
28
- .then(res => res.filename);
29
- }
30
-
31
- getAppCaps() {
32
- return { app: `sauce-storage:${this._appId}` };
33
- }
34
- }
35
-
36
- module.exports = new SaucelabsApkUploader();
@@ -1,34 +0,0 @@
1
- const utils = require('../../utils');
2
- const ApkUploader = require('./apkUploader');
3
- const httpRequest = require('../httpRequest');
4
- const Promise = require('bluebird');
5
- const fs = Promise.promisifyAll(require('fs'));
6
-
7
- const TEST_OBJECT_API_URL = 'https://app.testobject.com/api';
8
-
9
- class TestObjectApkUploader extends ApkUploader {
10
- constructor() {
11
- super();
12
- }
13
-
14
- uploadFile({ key }, apkFullPath, apkTimeout) {
15
- const authHeader = utils.buildBasicHeader('', key);
16
- return fs.readFileAsync(apkFullPath)
17
- .then(apkBuffer => httpRequest.post({
18
- url: `${TEST_OBJECT_API_URL}/storage/upload`,
19
- body: apkBuffer,
20
- headers: {
21
- Authorization: authHeader,
22
- 'Content-Type': 'application/octet-stream',
23
- 'App-Identifier': String(Date.now()),
24
- },
25
- timeout: apkTimeout,
26
- }));
27
- }
28
-
29
- getAppCaps() {
30
- return { testobject_app_id: this._appId };
31
- }
32
- }
33
-
34
- module.exports = new TestObjectApkUploader();
@@ -1,80 +0,0 @@
1
- "use strict";
2
-
3
- const MobileTabService = require('./services/mobileTabService');
4
- const MobilePortSelector = require('./services/mobilePortSelector');
5
-
6
- const windowCreationListener = require('../services/windowCreationListener');
7
- const CookieUtils = () => {};
8
- const StepActionUtils = require('../utils/stepActionUtils');
9
- const downloadsApiUtils = require('../utils/downloadsApiUtils');
10
- const FrameLocatorMock = require('./services/frameLocatorMock');
11
-
12
- const sessionPlayer = require('../../commons/getSessionPlayerRequire');
13
-
14
- const player = sessionPlayer.sessionPlayer;
15
- // delete after https://github.com/testimio/clickim/pull/3430 release to the store
16
- const assetService = sessionPlayer.assetService;
17
- const StepActionFactory = sessionPlayer.stepActionFactory;
18
- const PlaybackTimeoutCalculator = require('../services/playbackTimeoutCalculator');
19
-
20
- const MobileWebDriver = require('./mobileWebDriver');
21
- // delete after https://github.com/testimio/clickim/pull/3430 release to the store
22
- const CryptoJS = require('crypto-js');
23
-
24
- class MobileTestPlayer {
25
- constructor(id, userParamsData, projectType) {
26
- this.driver = new MobileWebDriver();
27
- this.id = id;
28
- const stepActionUtils = new StepActionUtils(this.driver);
29
- this.stepActionFactory = new StepActionFactory(stepActionUtils);
30
- require('../stepActions/stepActionRegistrar')(this.driver, this.stepActionFactory, projectType);
31
-
32
- if (assetService.setMd5) {
33
- // delete after https://github.com/testimio/clickim/pull/3430 release to the store
34
- assetService.setMd5(CryptoJS);
35
- }
36
- this.mobileTabService = MobileTabService(this.driver);
37
- this.windowCreationListener = windowCreationListener;
38
- this.playbackTimeoutCalculator = new PlaybackTimeoutCalculator();
39
-
40
- this.mobileTabService.createSession(id);
41
-
42
- this.sessionPlayer = new player(id, this.mobileTabService, CookieUtils(this.driver),
43
- windowCreationListener, FrameLocatorMock, MobilePortSelector,
44
- null, downloadsApiUtils, stepActionUtils,
45
- this.stepActionFactory, this.playbackTimeoutCalculator);
46
-
47
-
48
- this.sessionPlayer.playbackManager.isRemoteSession = true;
49
- this.sessionPlayer.playbackManager.isLocalRun = false;
50
-
51
- this.sessionPlayer.playbackManager.userParamsData = userParamsData || {};
52
- }
53
-
54
- getSessionId() {
55
- return this.driver.getSessionId();
56
- }
57
-
58
- onDone() {
59
- return this.driver.end()
60
- .finally(() => {
61
- this.sessionPlayer = null;
62
- this.mobileTabService = null;
63
- this.stepActionFactory = null;
64
- this.driver = null;
65
- });
66
- }
67
-
68
- clearSessionTabs() {
69
- this.mobileTabService.clearAllTabs(this.id);
70
- }
71
-
72
- addTab(openerStepId) {
73
- return this.mobileTabService.addNewTab(this.id, 0, openerStepId)
74
- .then(() => {
75
- return this.sessionPlayer.addPlaybackFrameHandler(0);
76
- });
77
- }
78
- }
79
-
80
- module.exports = MobileTestPlayer;
@@ -1,155 +0,0 @@
1
- "use strict";
2
-
3
- const Promise = require('bluebird');
4
- const desiredCapabilitiesBuilder = require('../../commons/testimDesiredCapabilitiesBuilder');
5
- const SeleniumError = require('../../errors').SeleniumError;
6
- const ArgError = require('../../errors').ArgError;
7
- const Webdriver = require('../webdriver');
8
- const { extractElementId } = require('../../utils');
9
- const logger = require('../../commons/logger').getLogger("mobile-web-driver");
10
-
11
- class MobileWebDriver extends Webdriver {
12
-
13
- init(browserOptions, gridInfo, nativeAppData, testName, testResultId) {
14
- const capabilities = desiredCapabilitiesBuilder.buildAppiumOptions(browserOptions, gridInfo, nativeAppData, testName);
15
- const packageName = nativeAppData.packageName;
16
-
17
- return this.initClient(capabilities, testName, testResultId)
18
- .then(() => this.switchToNativeContext())
19
- .then(() => this.isAppInstalled(packageName))
20
- .then(isInstalled => {
21
- if (!isInstalled) {
22
- return Promise.reject(new ArgError("Application not installed! " + packageName));
23
- }
24
- return this.launch();
25
- })
26
- .catch(err => {
27
- if (err.seleniumStack) {
28
- return Promise.reject(new SeleniumError(err.seleniumStack));
29
- }
30
- if (err instanceof ArgError) {
31
- return Promise.reject(err);
32
- }
33
- return Promise.reject(new Error("failed to init client driver"));
34
- });
35
- }
36
-
37
- //Override methods
38
-
39
- getElementLocation(target) {
40
- return this.elementIdLocation(extractElementId(target.seleniumElement));
41
- }
42
-
43
- setText(el, text) {
44
- return this.setImmediateValue(extractElementId(el), text);
45
- }
46
-
47
- async getTargetText(target) {
48
- return target.attributes.text || target.attributes['content-desc'] || "";
49
- }
50
-
51
- //End override methods
52
-
53
- switchToNativeContext() {
54
- return this.context("NATIVE_APP");
55
- }
56
-
57
- longClick(selector) {
58
- const attr = [{
59
- action: 'longPress',
60
- selector
61
- }];
62
-
63
- return this.touchAction(attr);
64
- }
65
-
66
- tap(selector) {
67
- let attr = [{
68
- action: 'tap',
69
- selector: selector
70
- }];
71
-
72
- return this.touchAction(attr);
73
- }
74
-
75
- touch(x, y) {
76
- let attr = {
77
- action: 'tap',
78
- x: x,
79
- y: y
80
- };
81
- return this.touchAction(attr);
82
- }
83
-
84
- scroll(start, end, duration = 1000) {
85
- // https://github.com/appium/appium-android-driver/blob/master/lib/commands/touch.js (doTouchDrag)
86
- const down = {action: 'longPress', options: {x: parseInt(start.x), y: parseInt(start.y), duration}};
87
- const move = {action: 'moveTo', options: {x: parseInt(end.x), y: parseInt(end.y)}};
88
- const up = {action: 'release'};
89
- return this.touchPerform([down, move, up]);
90
- }
91
-
92
- swipe(start, end, duration = 250) {
93
- // https://github.com/appium/appium-android-driver/blob/master/lib/commands/touch.js
94
- const down = {action: 'press', options: {x: parseInt(start.x), y: parseInt(start.y)}};
95
- const wait = {action: 'wait', options: {ms: duration}};
96
- const move = {action: 'moveTo', options: {x: parseInt(end.x), y: parseInt(end.y)}};
97
- const up = {action: 'release'};
98
- return this.touchPerform([down, wait, move, up]);
99
- }
100
-
101
- executeImeAction(action) {
102
- // Required Appium version: 1.9.2.
103
- // http://appium.io/docs/en/writing-running-appium/android/android-ime/
104
- return this.executeJS('mobile: performEditorAction', {action});
105
- }
106
-
107
- getDeviceInfo() {
108
- // http://appium.io/docs/en/commands/mobile-command/
109
- return this.executeJS('mobile:deviceInfo')
110
- .catch(err => {
111
- logger.warn(`getDeviceInfo failed`, { err });
112
- return {};
113
- })
114
- .then(deviceInfo => {
115
- if (deviceInfo.value && deviceInfo.value.model && deviceInfo.value.platformVersion && deviceInfo.value.apiVersion) {
116
- return {
117
- 'device': deviceInfo.value.model,
118
- 'os': deviceInfo.value.platformVersion + ` (API ${deviceInfo.value.apiVersion})`
119
- };
120
- }
121
- return {};
122
- })
123
- }
124
-
125
- getPackageInfo(packageName) {
126
- // http://appium.io/docs/en/commands/mobile-command/
127
- // Android only. Executes ADB shell commands (appium's "Relaxed Security" must be enabled)
128
- return this.executeJS('mobile:shell', { 'command': `dumpsys package ${packageName} | grep -E \"versionName|versionCode\"` })
129
- .catch(err => {
130
- logger.warn(`getPackageInfo failed at appium command mobile:shell`, { packageName, err });
131
- return {};
132
- })
133
- .then(shellResult => {
134
- try {
135
- // Shell result from ADB looks like `versionCode=620 minSdk=24 targetSdk=28\n versionName=0.6.2`
136
- const packageInfo = shellResult.value.split(/\s/).filter(Boolean).reduce((obj, item) => {
137
- const [key, value] = item.split('=')
138
- return { ...obj, [key]: value };
139
- }, {});
140
-
141
- if (packageInfo && packageInfo.versionName && packageInfo.versionCode){
142
- return {
143
- 'autVersion': packageInfo.versionName + ` (${packageInfo.versionCode})`
144
- };
145
- }
146
- return {};
147
- } catch (err) {
148
- logger.warn(`getPackageInfo failed parsing shell result`, { packageName, err });
149
- return {};
150
- }
151
- })
152
- }
153
- }
154
-
155
- module.exports = MobileWebDriver;
@@ -1,18 +0,0 @@
1
- "use strict";
2
- const Promise = require('bluebird');
3
-
4
- class FrameLocatorMock {
5
-
6
- constructor() {}
7
-
8
- findFrame() {
9
- return Promise.resolve({
10
- frameOffset: {top: 0, left: 0},
11
- tabId: 0,
12
- frameId: 0,
13
- testimFullFrameId: 0
14
- });
15
- }
16
- }
17
-
18
- module.exports = FrameLocatorMock;
@@ -1,22 +0,0 @@
1
- "use strict";
2
- const Promise = require('bluebird');
3
-
4
- // Legacy code not supported in selenium mode
5
- class MobilePortSelector {
6
- constructor() {
7
- }
8
-
9
- select() {
10
- return Promise.resolve({
11
- testimFullFrameId : 0
12
- });
13
- }
14
-
15
- prepare() {
16
- }
17
-
18
- handleLegacyDataCaching() {
19
- }
20
- }
21
-
22
- module.exports = new MobilePortSelector();
@@ -1,241 +0,0 @@
1
- 'use strict';
2
-
3
- const _ = require('lodash');
4
- const Promise = require('bluebird');
5
- const WindowUtils = require('../utils/mobileWindowUtils');
6
- const MobileScreenshotUtils = require('../utils/mobileScreenshotUtils');
7
- const ImageCaptureUtils = require('../../utils/imageCaptureUtils');
8
- const guid = require('../../../utils').guid;
9
-
10
- module.exports = function (driver) {
11
- class MobileTabService {
12
- constructor() {
13
- this._utils = {};
14
- this.sessionTabs = {};
15
- this.pendingTabs = {};
16
- }
17
-
18
- on(){}
19
-
20
- createSesion(sessionId) {
21
- this.pendingTabs[sessionId] = new Set();
22
- this.sessionTabs[sessionId] = {
23
- tabCount: 0,
24
- tabInfos: {}
25
- };
26
- }
27
-
28
- getAllOpenTabIds(sessionId) {
29
- const allTabInfos = this.getAllTabInfos(sessionId);
30
- return Object.keys(allTabInfos)
31
- .filter(tabId => !allTabInfos[tabId].isClosed)
32
- .map(tabId => _.isNaN(Number(tabId)) ? tabId : Number(tabId));
33
- }
34
-
35
- /**
36
- * Get last tab info for pixel validation
37
- *
38
- * @returns last tab info
39
- */
40
- getActiveTabInfo(sessionId){
41
- return this.sessionTabs[sessionId].lastActiveTabInfo;
42
- }
43
-
44
- getAllTabIds(sessionId) {
45
- return Object.keys(this.getAllTabInfos(sessionId)).map(id => id);
46
- }
47
-
48
- isSessionTab(sessionId, tabId) {
49
- return this.getAllTabIds(sessionId).includes(tabId);
50
- }
51
-
52
- createSession(sessionId) {
53
- this.pendingTabs[sessionId] = new Set();
54
- this.sessionTabs[sessionId] = {
55
- tabCount: 0,
56
- tabInfos: {}
57
- };
58
- }
59
-
60
- getAllTabInfoStrings(sessionId) {
61
- var allIds = this.getAllTabIds(sessionId);
62
- return allIds.map(tabId => {
63
- var tabInfo = this.getTabInfo(sessionId, tabId);
64
- return `tabId=${tabId}, url=${tabInfo.url}, order=${tabInfo.order}, isMain=${tabInfo.isMain}, openerStepId=${tabInfo.openerStepId}`;
65
- });
66
- }
67
-
68
- getAllTabInfos(sessionId) {
69
- return this.sessionTabs[sessionId].tabInfos;
70
- }
71
-
72
- addNewTab(sessionId, tabId, openerStepId) {
73
- var infos = this.getAllTabInfos(sessionId);
74
- if(infos && infos[tabId]){
75
- return Promise.resolve();
76
- }
77
- return this.addTab(sessionId, tabId, this.sessionTabs[sessionId].tabCount++, openerStepId);
78
- }
79
-
80
- addOpenerStepId(sessionId, tabId, openerStepId) {
81
- this.sessionTabs[sessionId].tabInfos[tabId].openerStepId = openerStepId;
82
- }
83
-
84
- buildTabInfo(sessionId, tabId, order, openerStepId) {
85
- return this.getTabDetails(tabId, sessionId)
86
- .then(tab => {
87
- var infoId = guid();
88
- var missingMainTab = !this.getMainTabInfo(sessionId);
89
-
90
- this.sessionTabs[sessionId].tabInfos[tabId] = {
91
- infoId : infoId,
92
- url: tab.url,
93
- title: tab.title,
94
- favIconUrl : tab.favIconUrl,
95
- order: order,
96
- from: this.getTabInfo(sessionId, tab.openerTabId),
97
- isMain : missingMainTab,
98
- openerStepId: openerStepId
99
- };
100
-
101
- return Promise.resolve(infoId);
102
- });
103
- }
104
-
105
- addTab(sessionId, id, order, openerStepId){
106
- return new Promise(resolve => {
107
- return this.buildTabInfo(sessionId, id, order, openerStepId)
108
- .then(infoId => {
109
- var _windowUtils = new WindowUtils(id, driver);
110
- this._utils[infoId] = {
111
- attachDebugger: () => Promise.resolve(),
112
- detachDebugger: () => Promise.resolve(),
113
- onDebuggerDetached: () => {},
114
- tabId: id,
115
- domUtils: {getDOM: () => Promise.resolve()},
116
- windowUtils : _windowUtils,
117
- imageCaptureUtils : new ImageCaptureUtils(id, _windowUtils, new MobileScreenshotUtils(id, driver))
118
- };
119
- resolve();
120
- });
121
- });
122
- }
123
-
124
- getTabUtilsByTabId(tabId) {
125
- const infoId = Object.keys(this._utils).find(uId => this._utils[uId].tabId === tabId);
126
- return this._utils[infoId];
127
- }
128
-
129
- getTabUtilsByTabIdAndSessionId(sessionId){
130
- return this.getMainTabUtils(sessionId);
131
- }
132
-
133
- getTabInfo(sessionId, id){
134
- return this.sessionTabs[sessionId].tabInfos[id];
135
- }
136
-
137
- getTabUtils(sessionId, tabInfo){
138
- if(!tabInfo){
139
- return this.getMainTabUtils(sessionId);
140
- }
141
-
142
- if(this._utils[tabInfo.infoId]){
143
- return this._utils[tabInfo.infoId];
144
- }
145
-
146
- if(tabInfo.isMain){
147
- return this.getMainTabUtils(sessionId);
148
- }
149
-
150
- var infos = this.getAllTabInfos(sessionId);
151
- var nonMainTabs = Object.keys(infos)
152
- .map(tabId => infos[tabId])
153
- .filter(info => !info.isMain);
154
- if(nonMainTabs.length === 1){
155
- return this._utils[nonMainTabs[0].infoId];
156
- }
157
-
158
- var sameTabs = Object.keys(sessionId)
159
- .map(key => sessionId[key])
160
- .filter(info => this.isSameTab(sessionId, tabInfo, info));
161
- if(sameTabs.length > 0){
162
- return this._utils[sameTabs[0].infoId];
163
- }
164
-
165
- // if nothing else
166
- return this.getMainTabUtils(sessionId);
167
- }
168
-
169
- getMainTabInfo(sessionId){
170
- var infos = this.getAllTabInfos(sessionId);
171
- return Object.keys(infos)
172
- .map(id => infos[id])
173
- .find(tabInfo => tabInfo.isMain);
174
- }
175
-
176
- getMainTabUtils(sessionId){
177
- var mainTabInfo = this.getMainTabInfo(sessionId);
178
- if(!mainTabInfo) {
179
- return {};
180
- }
181
- return this.getTabUtils(sessionId, mainTabInfo);
182
-
183
- }
184
-
185
- removeTabInfo(sessionId, tabId){
186
- let infos = this.getAllTabInfos(sessionId);
187
- let info = infos[tabId];
188
- if (info){
189
- delete this.sessionTabs[sessionId].tabInfos[tabId];
190
- delete this._utils[info.infoId];
191
- }
192
- }
193
-
194
- getMainTabId(sessionId){
195
- var infos = this.getAllTabInfos(sessionId);
196
- return Object.keys(infos).find(id => infos[id].isMain);
197
- }
198
-
199
- isMainTabExists(sessionId){
200
- var mainTabId = this.getMainTabId(sessionId);
201
- if(!mainTabId){
202
- return Promise.resolve(false);
203
- }
204
- return Promise.resolve(true);
205
- }
206
-
207
- clearAllTabs(sessionId){
208
- var infos = this.getAllTabInfos(sessionId);
209
-
210
- this.sessionTabs[sessionId].tabCount = 0;
211
- Object.keys(infos)
212
- .forEach(tabId => this.removeTabInfo(sessionId, tabId));
213
- }
214
-
215
- clearNonMainTabs(sessionId){
216
- var infos = this.getAllTabInfos(sessionId);
217
-
218
- this.sessionTabs[sessionId].tabCount = 1;
219
- Object.keys(infos)
220
- .filter(tabId => !infos[tabId].isMain)
221
- .forEach(tabId => this.removeTabInfo(sessionId, tabId));
222
- }
223
-
224
- getTabDetails(){
225
- return Promise.resolve({
226
- title: "Dummy title",
227
- url: "Dummy url"
228
- });
229
- }
230
-
231
- isMainTabIncognito() {
232
- return Promise.resolve(false);
233
- }
234
-
235
- getTabIdByTabInfo() {
236
- return Promise.resolve(0);
237
- }
238
- }
239
-
240
- return new MobileTabService();
241
- };
@@ -1,46 +0,0 @@
1
- "use strict";
2
-
3
- const Promise = require('bluebird');
4
- const utils = require('../../../utils');
5
-
6
- class MobileScreenshotUtils {
7
- constructor(tabId, driver){
8
- this.tabId = tabId;
9
- this.driver = driver;
10
- }
11
-
12
- base64AddPadding(str) {
13
- return str + Array((4 - str.length % 4) % 4 + 1).join('=');
14
- }
15
-
16
- takeScreenshot() {
17
- const MAX_RETRY_COUNT = 3;
18
- const SCREENSHOT_RETRY_DELAY = 2000;
19
- const devicePixelRatioPromise = this.currentDevicePixelRatio ? Promise.resolve(this.currentDevicePixelRatio) : this.getDevicePixelRatio();
20
- const getScreenshot = () => Promise.all([devicePixelRatioPromise, this.driver.takeScreenshot()]);
21
- return utils.runWithRetries(getScreenshot, MAX_RETRY_COUNT, SCREENSHOT_RETRY_DELAY)
22
- .spread((devicePixelRatio, image) => {
23
- const base64 = image ? image.value : '';
24
- const dataUrl = "data:image/png;base64," + this.base64AddPadding(base64.replace(/[\r\n]/g, ''));
25
- return Promise.resolve({
26
- image: dataUrl,
27
- devicePixelRatio: devicePixelRatio
28
- });
29
- });
30
- }
31
-
32
- getDevicePixelRatio() {
33
- return Promise.resolve(1);
34
- }
35
-
36
- getCurrentDevicePixelRatio() {
37
- return 1;
38
- }
39
-
40
- forcePixelRatio(forceRatio = 1){
41
- this.currentDevicePixelRatio = forceRatio;
42
- return Promise.resolve();
43
- }
44
- }
45
-
46
- module.exports = MobileScreenshotUtils;