1 | "use strict";
|
2 |
|
3 | const Promise = require('bluebird');
|
4 |
|
5 | const {timeoutMessages} = require('../commons/constants');
|
6 | const BaseWorker = require('./BaseWorker');
|
7 | const logger = require('../commons/logger').getLogger("worker-selenium");
|
8 | const reporter = require("../reports/reporter");
|
9 | const SeleniumTestPlayer = require('../player/seleniumTestPlayer');
|
10 | const WindowUtils = require('../player/utils/windowUtils');
|
11 | const sessionPlayerInit = require('../commons/getSessionPlayerRequire');
|
12 | const perf = require('../commons/performance-logger');
|
13 |
|
14 | class WorkerSelenium extends BaseWorker {
|
15 | constructor(...args) {
|
16 | super(...args);
|
17 | this.getBrowserOnce = Promise.method(this.getBrowserOnce);
|
18 | }
|
19 |
|
20 | initPlayer(testRunHandler) {
|
21 | return new SeleniumTestPlayer(this.id, testRunHandler.getRunParams(), this.options.shouldMonitorPerformance, testRunHandler.getAutomationMode());
|
22 | }
|
23 |
|
24 | async getBrowserOnce(testRunHandler, customExtensionLocalLocation, seleniumTestPlayer) {
|
25 | perf.log('in WorkerSelenium getBrowserOnce');
|
26 | reporter.onGetSession(this.id, this.testName, testRunHandler.getRunMode());
|
27 | const { driver } = seleniumTestPlayer;
|
28 |
|
29 |
|
30 | const NO_NAVIGATION_TIME_LIMIT = 1e9;
|
31 |
|
32 | this.windowUtils = new WindowUtils(this.id, driver);
|
33 | seleniumTestPlayer.clearSessionTabs();
|
34 |
|
35 | const {browserValue} = this.testRunConfig;
|
36 |
|
37 | try {
|
38 | perf.log('in WorkerSelenium before getGridSlot');
|
39 | const gridInfo = await this.getGridSlot(browserValue, testRunHandler);
|
40 | perf.log('in WorkerSelenium after getGridSlot');
|
41 | let fastInit = this.options.useLocalChromeDriver;
|
42 | await driver.init(this.options, this.testName, this.testRunConfig, gridInfo, customExtensionLocalLocation, this.testResultId, fastInit);
|
43 | perf.log('in WorkerSelenium after driver.init');
|
44 | await seleniumTestPlayer.addTab(undefined, {skipLoadInfo: fastInit});
|
45 | perf.log('in WorkerSelenium after addTab');
|
46 | if (!fastInit) {
|
47 | await this.windowUtils.navigate(testRunHandler.getBaseUrl(), NO_NAVIGATION_TIME_LIMIT);
|
48 | }
|
49 | perf.log('in WorkerSelenium after navigate');
|
50 | } catch (err) {
|
51 | logger.error("failed to navigate to page", { err });
|
52 | throw err;
|
53 | }
|
54 | }
|
55 |
|
56 | runTestOnce(testRunHandler, seleniumTestPlayer) {
|
57 | const { driver, sessionPlayer } = seleniumTestPlayer;
|
58 | const version = sessionPlayerInit.manifestVersion || "runner";
|
59 |
|
60 | reporter.onWaitToTestComplete(this.id, this.isCodeMode);
|
61 |
|
62 | setupCliPerformanceMonitoring(sessionPlayer);
|
63 |
|
64 | async function runSeleniumTest() {
|
65 | if (testRunHandler.getAutomationMode() === 'codeful') {
|
66 |
|
67 | if (!sessionPlayer.callOrderScheduler) {
|
68 | await testRunHandler.waitForExecutionStartedFinished();
|
69 | } else {
|
70 | sessionPlayer.callOrderScheduler.schedule(() => {
|
71 |
|
72 | testRunHandler.waitForExecutionStartedFinished;
|
73 | }, { key: `test-result:${this.userData.projectId}:${this.testResultId}`});
|
74 | }
|
75 | perf.log('right before playTestByCode');
|
76 | return new Promise((resolve,reject) => sessionPlayer.playTestByCode(
|
77 | this.testId,
|
78 | this.executionId,
|
79 | this.testResultId,
|
80 | this.baseUrl,
|
81 | this.userData,
|
82 | version,
|
83 | resolve,
|
84 | false,
|
85 | this.overrideTestConfigId,
|
86 | this.branch,
|
87 | testRunHandler.getCode(),
|
88 | testRunHandler.getTestName()
|
89 | ).catch(reject))
|
90 | .log('right after playTestByCode')
|
91 | .timeout(this.testRunTimeout, timeoutMessages.TEST_COMPLETE_TIMEOUT_MSG)
|
92 | .catch(Promise.TimeoutError, err => {
|
93 | sessionPlayer.stopPlayingOnTestTimeout && sessionPlayer.stopPlayingOnTestTimeout();
|
94 | throw err;
|
95 | })
|
96 | .then(testResult => {
|
97 | testResult.resultId = this.testResultId;
|
98 | return testResult;
|
99 | });
|
100 | }
|
101 | const INCOGNITO = false;
|
102 |
|
103 | return new Promise((resolve,reject) =>
|
104 | sessionPlayer.playByTestId(
|
105 | this.testId,
|
106 | this.executionId,
|
107 | this.testResultId,
|
108 | this.baseUrl,
|
109 | this.userData,
|
110 | version,
|
111 | resolve,
|
112 | false,
|
113 | this.overrideTestConfigId,
|
114 | this.branch,
|
115 | INCOGNITO,
|
116 | testRunHandler.getRemoteRunId()
|
117 | ).catch(reject))
|
118 | .timeout(this.testRunTimeout, timeoutMessages.TEST_COMPLETE_TIMEOUT_MSG)
|
119 | .catch(Promise.TimeoutError, err => {
|
120 | sessionPlayer.stopPlayingOnTestTimeout && sessionPlayer.stopPlayingOnTestTimeout();
|
121 | throw err;
|
122 | })
|
123 | .then(testResult => {
|
124 | testResult.stepsResults = null;
|
125 | testResult.resultId = this.testResultId;
|
126 | if(!driver.isAlive()){
|
127 | logger.warn(`possible grid unresponsive for test ${this.testId}, result ${this.testResultId} (execution: ${this.executionId})`);
|
128 | testResult.gridIssues = `could not validate grid is alive`;
|
129 | }
|
130 | return testResult;
|
131 | });
|
132 | }
|
133 |
|
134 | driver.start();
|
135 |
|
136 | perf.log('right before super.runTestOnce in workerSelenium');
|
137 | return super.runTestOnce(testRunHandler, seleniumTestPlayer)
|
138 | .log('right after super.runTestOnce in workerSelenium')
|
139 | .then(runSeleniumTest.bind(this))
|
140 | .log('right after runSeleniumTest')
|
141 | .catch(err => {
|
142 | logger.error("failed to run test once", {err});
|
143 | throw err;
|
144 | });
|
145 | }
|
146 |
|
147 |
|
148 | }
|
149 | function setupCliPerformanceMonitoring(sessionPlayer) {
|
150 | const { playback } = sessionPlayerInit.commonConstants;
|
151 | function monitorEvent(event) {
|
152 | sessionPlayer.playbackManager.on(event, (...args) => {
|
153 | perf.log(`Got event ${event}`);
|
154 | });
|
155 | }
|
156 | Object.values(playback).forEach(monitorEvent);
|
157 | }
|
158 | module.exports = WorkerSelenium;
|